diff --git a/bench/detail/varray.hpp b/bench/detail/varray.hpp
new file mode 100644
index 0000000..ca29c14
--- /dev/null
+++ b/bench/detail/varray.hpp
@@ -0,0 +1,2242 @@
+// Boost.Container varray
+//
+// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2013 Andrew Hundt.
+// Copyright (c) 2014-2014 Ion Gaztanaga
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_CONTAINER_DETAIL_VARRAY_HPP
+#define BOOST_CONTAINER_DETAIL_VARRAY_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/container/detail/addressof.hpp>
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/move/adl_move_swap.hpp> //adl_move_swap
+
+
+#include "varray_util.hpp"
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/static_assert.hpp>
+
+#ifndef BOOST_NO_EXCEPTIONS
+#include <stdexcept>
+#endif // BOOST_NO_EXCEPTIONS
+
+
+/**
+ * @defgroup varray_non_member varray non-member functions
+ */
+
+namespace boost { namespace container { namespace dtl {
+
+// Forward declaration
+template <typename Value, std::size_t Capacity, typename Strategy>
+class varray;
+
+namespace strategy {
+
+// TODO: Improve error messages
+//       possibly include N in the strategy, and provide size as an optoinal allocate_failed parameter?
+//       Example of current error with reserve(4) when capacity is 3:
+//          "boost/container/varray.hpp(66): size can't exceed the capacity"
+//       Could say
+//          "cannot reserve(4) due to fixed capacity of 3 elements"
+
+//! @brief The default strategy.
+//!
+//! @tparam Value Type of element stored in the container.
+template <typename Value>
+struct def
+{
+    typedef Value value_type;
+    typedef std::size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+    typedef Value* pointer;
+    typedef const Value* const_pointer;
+    typedef Value& reference;
+    typedef const Value& const_reference;
+
+    static void allocate_failed()
+    {
+        BOOST_ASSERT_MSG(false, "size can't exceed the capacity");
+    }
+};
+
+//! @brief The strategy adapting info from passed Allocator.
+//!
+//! This strategy defines the same types that are defined in the Allocator.
+//!
+//! @tparam Allocator The Allocator which will be adapted.
+template <typename Allocator>
+struct allocator_adaptor
+{
+    typedef typename Allocator::value_type value_type;
+    typedef typename Allocator::size_type size_type;
+    typedef typename Allocator::difference_type difference_type;
+    typedef typename Allocator::pointer pointer;
+    typedef typename Allocator::const_pointer const_pointer;
+    typedef typename Allocator::reference reference;
+    typedef typename Allocator::const_reference const_reference;
+
+    static void allocate_failed()
+    {
+        BOOST_ASSERT_MSG(false, "size can't exceed the capacity");
+    }
+};
+
+} // namespace strategy
+
+struct varray_error_handler
+{
+    template <typename V, std::size_t Capacity, typename S>
+    static void check_capacity(varray<V, Capacity, S> const&, std::size_t s)
+    {
+        if ( Capacity < s )
+            S::allocate_failed();
+    }
+
+    template <typename V, std::size_t C, typename S>
+    static void check_at(varray<V, C, S> const& v,
+                         typename varray<V, C, S>::size_type i)
+    {
+        (void)v;
+        (void)i;
+// TODO - use BOOST_THROW_EXCEPTION here?
+#ifndef BOOST_NO_EXCEPTIONS
+        if ( v.size() <= i )
+            throw std::out_of_range("index out of bounds");
+#else // BOOST_NO_EXCEPTIONS
+        BOOST_ASSERT_MSG(i < v.size(), "index out of bounds");
+#endif // BOOST_NO_EXCEPTIONS
+    }
+
+    template <typename V, std::size_t C, typename S>
+    static void check_operator_brackets(varray<V, C, S> const& v,
+                                        typename varray<V, C, S>::size_type i)
+    {
+        (void)v;
+        (void)i;
+        BOOST_ASSERT_MSG(i < v.size(), "index out of bounds");
+    }
+
+    template <typename V, std::size_t C, typename S>
+    static void check_empty(varray<V, C, S> const& v)
+    {
+        (void)v;
+        BOOST_ASSERT_MSG(0 < v.size(), "the container is empty");
+    }
+
+    template <typename V, std::size_t C, typename S>
+    static void check_iterator_end_neq(varray<V, C, S> const& v,
+                                       typename varray<V, C, S>::const_iterator position)
+    {
+        (void)v;
+        (void)position;
+        BOOST_ASSERT_MSG(v.begin() <= position && position < v.end(), "iterator out of bounds");
+    }
+
+    template <typename V, std::size_t C, typename S>
+    static void check_iterator_end_eq(varray<V, C, S> const& v,
+                                      typename varray<V, C, S>::const_iterator position)
+    {
+        (void)v;
+        (void)position;
+        BOOST_ASSERT_MSG(v.begin() <= position && position <= v.end(), "iterator out of bounds");
+    }
+};
+
+template <typename Value, std::size_t Capacity, typename Strategy>
+struct varray_traits
+{
+    typedef typename Strategy::value_type value_type;
+    typedef typename Strategy::size_type size_type;
+    typedef typename Strategy::difference_type difference_type;
+    typedef typename Strategy::pointer pointer;
+    typedef typename Strategy::const_pointer const_pointer;
+    typedef typename Strategy::reference reference;
+    typedef typename Strategy::const_reference const_reference;
+
+    typedef varray_error_handler error_handler;
+
+    typedef false_type use_memop_in_swap_and_move;
+    typedef false_type use_optimized_swap;
+    typedef false_type disable_trivial_init;
+};
+
+/**
+ * @brief A variable-size array container with fixed capacity.
+ *
+ * varray is a sequence container like boost::container::vector with contiguous storage that can
+ * change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
+ *
+ * A varray is a sequence that supports random access to elements, constant time insertion and
+ * removal of elements at the end, and linear time insertion and removal of elements at the beginning or
+ * in the middle. The number of elements in a varray may vary dynamically up to a fixed capacity
+ * because elements are stored within the object itself similarly to an array. However, objects are
+ * initialized as they are inserted into varray unlike C arrays or std::array which must construct
+ * all elements on instantiation. The behavior of varray enables the use of statically allocated
+ * elements in cases with complex object lifetime requirements that would otherwise not be trivially
+ * possible.
+ *
+ * @par Error Handling
+ *  Insertion beyond the capacity and out of bounds errors result in undefined behavior unless
+ *  otherwise specified. In this respect if size() == capacity(), then varray::push_back()
+ *  behaves like std::vector pop_front() if size() == empty(). The reason for this difference
+ *  is because unlike vectors, varray does not perform allocation.
+ *
+ * @par Advanced Usage
+ *  Error handling behavior can be modified to more closely match std::vector exception behavior
+ *  when exceeding bounds by providing an alternate Strategy and varray_traits instantiation.
+ *
+ * @tparam Value    The type of element that will be stored.
+ * @tparam Capacity The maximum number of elements varray can store, fixed at compile time.
+ * @tparam Strategy Defines the public typedefs and error handlers,
+ *         implements StaticVectorStrategy and has some similarities
+ *         to an Allocator.
+ */
+template <typename Value, std::size_t Capacity, typename Strategy = strategy::def<Value> >
+class varray
+{
+    typedef dtl::varray_traits<
+        Value, Capacity, Strategy
+    > vt;
+
+    typedef typename vt::error_handler errh;
+    typedef typename aligned_storage<
+        sizeof(Value[Capacity]),
+        boost::container::dtl::alignment_of<Value[Capacity]>::value
+    >::type aligned_storage_type;
+
+    template <typename V, std::size_t C, typename S>
+    friend class varray;
+
+    BOOST_COPYABLE_AND_MOVABLE(varray)
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+public:
+    template <std::size_t C, typename S>
+    varray & operator=(varray<Value, C, S> & sv)
+    {
+        typedef varray<Value, C, S> other;
+        this->operator=(static_cast<const ::boost::rv<other> &>(const_cast<const other &>(sv)));
+        return *this;
+    }
+#endif
+
+public:
+    //! @brief The type of elements stored in the container.
+    typedef typename vt::value_type value_type;
+    //! @brief The unsigned integral type used by the container.
+    typedef typename vt::size_type size_type;
+    //! @brief The pointers difference type.
+    typedef typename vt::difference_type difference_type;
+    //! @brief The pointer type.
+    typedef typename vt::pointer pointer;
+    //! @brief The const pointer type.
+    typedef typename vt::const_pointer const_pointer;
+    //! @brief The value reference type.
+    typedef typename vt::reference reference;
+    //! @brief The value const reference type.
+    typedef typename vt::const_reference const_reference;
+
+    //! @brief The iterator type.
+    typedef pointer iterator;
+    //! @brief The const iterator type.
+    typedef const_pointer const_iterator;
+    //! @brief The reverse iterator type.
+    typedef boost::container::reverse_iterator<iterator> reverse_iterator;
+    //! @brief The const reverse iterator.
+    typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    //! @brief The type of a strategy used by the varray.
+    typedef Strategy strategy_type;
+
+    //! @brief Constructs an empty varray.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    varray()
+        : m_size(0)
+    {}
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Constructs a varray containing count value initialized Values.
+    //!
+    //! @param count    The number of values which will be contained in the container.
+    //!
+    //! @par Throws
+    //!   If Value's value initialization throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    explicit varray(size_type count)
+        : m_size(0)
+    {
+        this->resize(count);                                                        // may throw
+    }
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Constructs a varray containing count copies of value.
+    //!
+    //! @param count    The number of copies of a values that will be contained in the container.
+    //! @param value    The value which will be used to copy construct values.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    varray(size_type count, value_type const& value)
+        : m_size(0)
+    {
+        this->resize(count, value);                                                 // may throw
+    }
+
+    //! @pre
+    //!  @li <tt>distance(first, last) <= capacity()</tt>
+    //!  @li Iterator must meet the \c ForwardIterator.
+    //!
+    //! @brief Constructs a varray containing copy of a range <tt>[first, last)</tt>.
+    //!
+    //! @param first    The iterator to the first element in range.
+    //! @param last     The iterator to the one after the last element in range.
+    //!
+    //! @par Throws
+    //!   If Value's constructor taking a dereferenced Iterator throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <typename Iterator>
+    varray(Iterator first, Iterator last)
+        : m_size(0)
+    {
+        this->assign(first, last);                                                    // may throw
+    }
+
+    //! @brief Constructs a copy of other varray.
+    //!
+    //! @param other    The varray which content will be copied to this one.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    varray(varray const& other)
+        : m_size(other.size())
+    {
+        namespace sv = varray_detail;
+        sv::uninitialized_copy(other.begin(), other.end(), this->begin());          // may throw
+    }
+
+    //! @pre <tt>other.size() <= capacity()</tt>.
+    //!
+    //! @brief Constructs a copy of other varray.
+    //!
+    //! @param other    The varray which content will be copied to this one.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C, typename S>
+    varray(varray<value_type, C, S> const& other)
+        : m_size(other.size())
+    {
+        errh::check_capacity(*this, other.size());                                  // may throw
+
+        namespace sv = varray_detail;
+        sv::uninitialized_copy(other.begin(), other.end(), this->begin());          // may throw
+    }
+
+    //! @brief Copy assigns Values stored in the other varray to this one.
+    //!
+    //! @param other    The varray which content will be copied to this one.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws.
+    //!
+    //! @par Complexity
+    //! Linear O(N).
+    varray & operator=(BOOST_COPY_ASSIGN_REF(varray) other)
+    {
+        this->assign(other.begin(), other.end());                                     // may throw
+
+        return *this;
+    }
+
+    //! @pre <tt>other.size() <= capacity()</tt>
+    //!
+    //! @brief Copy assigns Values stored in the other varray to this one.
+    //!
+    //! @param other    The varray which content will be copied to this one.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C, typename S>
+// TEMPORARY WORKAROUND
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+    varray & operator=(::boost::rv< varray<value_type, C, S> > const& other)
+#else
+    varray & operator=(varray<value_type, C, S> const& other)
+#endif
+    {
+        this->assign(other.begin(), other.end());                                     // may throw
+
+        return *this;
+    }
+
+    //! @brief Move constructor. Moves Values stored in the other varray to this one.
+    //!
+    //! @param other    The varray which content will be moved to this one.
+    //!
+    //! @par Throws
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
+    //! @internal
+    //!   @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    varray(BOOST_RV_REF(varray) other)
+    {
+        typedef typename
+        vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+        this->move_ctor_dispatch(other, use_memop_in_swap_and_move());
+    }
+
+    //! @pre <tt>other.size() <= capacity()</tt>
+    //!
+    //! @brief Move constructor. Moves Values stored in the other varray to this one.
+    //!
+    //! @param other    The varray which content will be moved to this one.
+    //!
+    //! @par Throws
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
+    //! @internal
+    //!   @li It throws only if \c use_memop_in_swap_and_move is false_type - default.
+    //! @endinternal
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C, typename S>
+    varray(BOOST_RV_REF_3_TEMPL_ARGS(varray, value_type, C, S) other)
+        : m_size(other.m_size)
+    {
+        errh::check_capacity(*this, other.size());                                  // may throw
+
+        typedef typename
+        vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+        this->move_ctor_dispatch(other, use_memop_in_swap_and_move());
+    }
+
+    //! @brief Move assignment. Moves Values stored in the other varray to this one.
+    //!
+    //! @param other    The varray which content will be moved to this one.
+    //!
+    //! @par Throws
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
+    //! @internal
+    //!   @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    varray & operator=(BOOST_RV_REF(varray) other)
+    {
+        if ( &other == this )
+            return *this;
+
+        typedef typename
+        vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+        this->move_assign_dispatch(other, use_memop_in_swap_and_move());
+
+        return *this;
+    }
+
+    //! @pre <tt>other.size() <= capacity()</tt>
+    //!
+    //! @brief Move assignment. Moves Values stored in the other varray to this one.
+    //!
+    //! @param other    The varray which content will be moved to this one.
+    //!
+    //! @par Throws
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
+    //! @internal
+    //!   @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
+    //! @endinternal
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C, typename S>
+    varray & operator=(BOOST_RV_REF_3_TEMPL_ARGS(varray, value_type, C, S) other)
+    {
+        errh::check_capacity(*this, other.size());                                  // may throw
+
+        typedef typename
+        vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+        this->move_assign_dispatch(other, use_memop_in_swap_and_move());
+
+        return *this;
+    }
+
+    //! @brief Destructor. Destroys Values stored in this container.
+    //!
+    //! @par Throws
+    //!   Nothing
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    ~varray()
+    {
+        namespace sv = varray_detail;
+        sv::destroy(this->begin(), this->end());
+    }
+
+    //! @brief Swaps contents of the other varray and this one.
+    //!
+    //! @param other    The varray which content will be swapped with this one's content.
+    //!
+    //! @par Throws
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
+    //! @internal
+    //!   @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void swap(varray & other)
+    {
+        typedef typename
+        vt::use_optimized_swap use_optimized_swap;
+
+        this->swap_dispatch(other, use_optimized_swap());
+    }
+
+    //! @pre <tt>other.size() <= capacity() && size() <= other.capacity()</tt>
+    //!
+    //! @brief Swaps contents of the other varray and this one.
+    //!
+    //! @param other    The varray which content will be swapped with this one's content.
+    //!
+    //! @par Throws
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
+    //!   @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
+    //! @internal
+    //!   @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
+    //! @endinternal
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <std::size_t C, typename S>
+    void swap(varray<value_type, C, S> & other)
+    {
+        errh::check_capacity(*this, other.size());
+        errh::check_capacity(other, this->size());
+
+        typedef typename
+        vt::use_optimized_swap use_optimized_swap;
+
+        this->swap_dispatch(other, use_optimized_swap());
+    }
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Inserts or erases elements at the end such that
+    //!   the size becomes count. New elements are value initialized.
+    //!
+    //! @param count    The number of elements which will be stored in the container.
+    //!
+    //! @par Throws
+    //!   If Value's value initialization throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void resize(size_type count)
+    {
+        namespace sv = varray_detail;
+        typedef typename vt::disable_trivial_init dti;
+
+        if ( count < m_size )
+        {
+            sv::destroy(this->begin() + count, this->end());
+        }
+        else
+        {
+            errh::check_capacity(*this, count);                                     // may throw
+
+            sv::uninitialized_fill(this->end(), this->begin() + count, dti()); // may throw
+        }
+        m_size = count; // update end
+    }
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Inserts or erases elements at the end such that
+    //!   the size becomes count. New elements are copy constructed from value.
+    //!
+    //! @param count    The number of elements which will be stored in the container.
+    //! @param value    The value used to copy construct the new element.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void resize(size_type count, value_type const& value)
+    {
+        if ( count < m_size )
+        {
+            namespace sv = varray_detail;
+            sv::destroy(this->begin() + count, this->end());
+        }
+        else
+        {
+            errh::check_capacity(*this, count);                                     // may throw
+
+            std::uninitialized_fill(this->end(), this->begin() + count, value);     // may throw
+        }
+        m_size = count; // update end
+    }
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief This call has no effect because the Capacity of this container is constant.
+    //!
+    //! @param count    The number of elements which the container should be able to contain.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void reserve(size_type count)
+    {
+        errh::check_capacity(*this, count);                                         // may throw
+    }
+
+    //! @pre <tt>size() < capacity()</tt>
+    //!
+    //! @brief Adds a copy of value at the end.
+    //!
+    //! @param value    The value used to copy construct the new element.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    void push_back(value_type const& value)
+    {
+        typedef typename vt::disable_trivial_init dti;
+
+        errh::check_capacity(*this, m_size + 1);                                    // may throw
+
+        namespace sv = varray_detail;
+        sv::construct(dti(), this->end(), value);                                          // may throw
+        ++m_size; // update end
+    }
+
+    //! @pre <tt>size() < capacity()</tt>
+    //!
+    //! @brief Moves value to the end.
+    //!
+    //! @param value    The value to move construct the new element.
+    //!
+    //! @par Throws
+    //!   If Value's move constructor throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    void push_back(BOOST_RV_REF(value_type) value)
+    {
+        typedef typename vt::disable_trivial_init dti;
+
+        errh::check_capacity(*this, m_size + 1);                                    // may throw
+
+        namespace sv = varray_detail;
+        sv::construct(dti(), this->end(), ::boost::move(value));                                          // may throw
+        ++m_size; // update end
+    }
+
+    //! @pre <tt>!empty()</tt>
+    //!
+    //! @brief Destroys last value and decreases the size.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    void pop_back()
+    {
+        errh::check_empty(*this);
+
+        namespace sv = varray_detail;
+        sv::destroy(this->end() - 1);
+        --m_size; // update end
+    }
+
+    //! @pre
+    //!  @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+    //!  @li <tt>size() < capacity()</tt>
+    //!
+    //! @brief Inserts a copy of element at position.
+    //!
+    //! @param position    The position at which the new value will be inserted.
+    //! @param value       The value used to copy construct the new element.
+    //!
+    //! @par Throws
+    //!   @li If Value's copy constructor or copy assignment throws
+    //!   @li If Value's move constructor or move assignment throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Constant or linear.
+    iterator insert(iterator position, value_type const& value)
+    {
+        return this->priv_insert(position, value);
+    }
+
+    //! @pre
+    //!  @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+    //!  @li <tt>size() < capacity()</tt>
+    //!
+    //! @brief Inserts a move-constructed element at position.
+    //!
+    //! @param position    The position at which the new value will be inserted.
+    //! @param value       The value used to move construct the new element.
+    //!
+    //! @par Throws
+    //!   If Value's move constructor or move assignment throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Constant or linear.
+    iterator insert(iterator position, BOOST_RV_REF(value_type) value)
+    {
+        return this->priv_insert(position, boost::move(value));
+    }
+
+    //! @pre
+    //!  @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+    //!  @li <tt>size() + count <= capacity()</tt>
+    //!
+    //! @brief Inserts a count copies of value at position.
+    //!
+    //! @param position    The position at which new elements will be inserted.
+    //! @param count       The number of new elements which will be inserted.
+    //! @param value       The value used to copy construct new elements.
+    //!
+    //! @par Throws
+    //!   @li If Value's copy constructor or copy assignment throws.
+    //!   @li If Value's move constructor or move assignment throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    iterator insert(iterator position, size_type count, value_type const& value)
+    {
+        errh::check_iterator_end_eq(*this, position);
+        errh::check_capacity(*this, m_size + count);                                // may throw
+
+        if ( position == this->end() )
+        {
+            std::uninitialized_fill(position, position + count, value);             // may throw
+            m_size += count; // update end
+        }
+        else
+        {
+            namespace sv = varray_detail;
+
+            difference_type to_move = boost::container::iterator_distance(position, this->end());
+
+            // TODO - should following lines check for exception and revert to the old size?
+
+            if ( count < static_cast<size_type>(to_move) )
+            {
+                sv::uninitialized_move(this->end() - count, this->end(), this->end());          // may throw
+                m_size += count; // update end
+                sv::move_backward(position, position + to_move - count, this->end() - count);   // may throw
+                std::fill_n(position, count, value);                                            // may throw
+            }
+            else
+            {
+                std::uninitialized_fill(this->end(), position + count, value);                  // may throw
+                m_size += count - to_move; // update end
+                sv::uninitialized_move(position, position + to_move, position + count);         // may throw
+                m_size += to_move; // update end
+                std::fill_n(position, to_move, value);                                          // may throw
+            }
+        }
+
+        return position;
+    }
+
+    //! @pre
+    //!  @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
+    //!  @li <tt>distance(first, last) <= capacity()</tt>
+    //!  @li \c Iterator must meet the \c ForwardIterator.
+    //!
+    //! @brief Inserts a copy of a range <tt>[first, last)</tt> at position.
+    //!
+    //! @param position    The position at which new elements will be inserted.
+    //! @param first       The iterator to the first element of a range used to construct new elements.
+    //! @param last        The iterator to the one after the last element of a range used to construct new elements.
+    //!
+    //! @par Throws
+    //!   @li If Value's constructor and assignment taking a dereferenced \c Iterator.
+    //!   @li If Value's move constructor or move assignment throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <typename Iterator>
+    iterator insert(iterator position, Iterator first, Iterator last)
+    {
+        this->insert_dispatch(position, first, last);
+        return position;
+    }
+
+    //! @pre \c position must be a valid iterator of \c *this in range <tt>[begin(), end())</tt>
+    //!
+    //! @brief Erases Value from position.
+    //!
+    //! @param position    The position of the element which will be erased from the container.
+    //!
+    //! @par Throws
+    //!   If Value's move assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    iterator erase(iterator position)
+    {
+        namespace sv = varray_detail;
+
+        errh::check_iterator_end_neq(*this, position);
+
+        //TODO - add empty check?
+        //errh::check_empty(*this);
+
+        sv::move(position + 1, this->end(), position);                              // may throw
+        sv::destroy(this->end() - 1);
+        --m_size;
+
+        return position;
+    }
+
+    //! @pre
+    //!  @li \c first and \c last must define a valid range
+    //!  @li iterators must be in range <tt>[begin(), end()]</tt>
+    //!
+    //! @brief Erases Values from a range <tt>[first, last)</tt>.
+    //!
+    //! @param first    The position of the first element of a range which will be erased from the container.
+    //! @param last     The position of the one after the last element of a range which will be erased from the container.
+    //!
+    //! @par Throws
+    //!   If Value's move assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    iterator erase(iterator first, iterator last)
+    {
+        namespace sv = varray_detail;
+
+        errh::check_iterator_end_eq(*this, first);
+        errh::check_iterator_end_eq(*this, last);
+
+        difference_type n = boost::container::iterator_distance(first, last);
+
+        //TODO - add invalid range check?
+        //BOOST_ASSERT_MSG(0 <= n, "invalid range");
+        //TODO - add this->size() check?
+        //BOOST_ASSERT_MSG(n <= this->size(), "invalid range");
+
+        sv::move(last, this->end(), first);                                         // may throw
+        sv::destroy(this->end() - n, this->end());
+        m_size -= n;
+
+        return first;
+    }
+
+    //! @pre <tt>distance(first, last) <= capacity()</tt>
+    //!
+    //! @brief Assigns a range <tt>[first, last)</tt> of Values to this container.
+    //!
+    //! @param first       The iterator to the first element of a range used to construct new content of this container.
+    //! @param last        The iterator to the one after the last element of a range used to construct new content of this container.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws,
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    template <typename Iterator>
+    void assign(Iterator first, Iterator last)
+    {
+        this->assign_dispatch(first, last);                            // may throw
+    }
+
+    //! @pre <tt>count <= capacity()</tt>
+    //!
+    //! @brief Assigns a count copies of value to this container.
+    //!
+    //! @param count       The new number of elements which will be container in the container.
+    //! @param value       The value which will be used to copy construct the new content.
+    //!
+    //! @par Throws
+    //!   If Value's copy constructor or copy assignment throws.
+    //!
+    //! @par Complexity
+    //!   Linear O(N).
+    void assign(size_type count, value_type const& value)
+    {
+        if ( count < m_size )
+        {
+            namespace sv = varray_detail;
+
+            std::fill_n(this->begin(), count, value);                               // may throw
+            sv::destroy(this->begin() + count, this->end());
+        }
+        else
+        {
+            errh::check_capacity(*this, count);                                     // may throw
+
+            std::fill_n(this->begin(), m_size, value);                              // may throw
+            std::uninitialized_fill(this->end(), this->begin() + count, value);     // may throw
+        }
+        m_size = count; // update end
+    }
+
+#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+    //! @pre <tt>size() < capacity()</tt>
+    //!
+    //! @brief Inserts a Value constructed with
+    //!   \c std::forward<Args>(args)... in the end of the container.
+    //!
+    //! @param args     The arguments of the constructor of the new element which will be created at the end of the container.
+    //!
+    //! @par Throws
+    //!   If in-place constructor throws or Value's move constructor throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    template<class ...Args>
+    void emplace_back(BOOST_FWD_REF(Args) ...args)
+    {
+        typedef typename vt::disable_trivial_init dti;
+
+        errh::check_capacity(*this, m_size + 1);                                    // may throw
+
+        namespace sv = varray_detail;
+        sv::construct(dti(), this->end(), ::boost::forward<Args>(args)...);                // may throw
+        ++m_size; // update end
+    }
+
+    //! @pre
+    //!  @li \c position must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>
+    //!  @li <tt>size() < capacity()</tt>
+    //!
+    //! @brief Inserts a Value constructed with
+    //!   \c std::forward<Args>(args)... before position
+    //!
+    //! @param position The position at which new elements will be inserted.
+    //! @param args     The arguments of the constructor of the new element.
+    //!
+    //! @par Throws
+    //!   If in-place constructor throws or if Value's move constructor or move assignment throws.
+    //! @internal
+    //!   @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
+    //! @endinternal
+    //!
+    //! @par Complexity
+    //!   Constant or linear.
+    template<class ...Args>
+    iterator emplace(iterator position, BOOST_FWD_REF(Args) ...args)
+    {
+        typedef typename vt::disable_trivial_init dti;
+
+        namespace sv = varray_detail;
+
+        errh::check_iterator_end_eq(*this, position);
+        errh::check_capacity(*this, m_size + 1);                                    // may throw
+
+        if ( position == this->end() )
+        {
+            sv::construct(dti(), position, ::boost::forward<Args>(args)...);               // may throw
+            ++m_size; // update end
+        }
+        else
+        {
+            // TODO - should following lines check for exception and revert to the old size?
+
+            // TODO - should move be used only if it's nonthrowing?
+            value_type & r = *(this->end() - 1);
+            sv::construct(dti(), this->end(), boost::move(r));                             // may throw
+            ++m_size; // update end
+            sv::move_backward(position, this->end() - 2, this->end() - 1);          // may throw
+
+            typename aligned_storage
+               <sizeof(value_type), alignment_of<value_type>::value>::type temp_storage;
+            value_type * val_p = static_cast<value_type*>(static_cast<void*>(&temp_storage));
+            sv::construct(dti(), val_p, ::boost::forward<Args>(args)...);                  // may throw
+            sv::scoped_destructor<value_type> d(val_p);
+            sv::assign(position, ::boost::move(*val_p));                            // may throw
+        }
+
+        return position;
+    }
+
+#else //  !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   #define BOOST_CONTAINER_VARRAY_EMPLACE_CODE(N) \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   void emplace_back(BOOST_MOVE_UREF##N)\
+   {\
+      typedef typename vt::disable_trivial_init dti;\
+      errh::check_capacity(*this, m_size + 1);/*may throw*/\
+      \
+      namespace sv = varray_detail;\
+      sv::construct(dti(), this->end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
+      ++m_size; /*update end*/\
+   }\
+   \
+   BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+   iterator emplace(iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+   {\
+      typedef typename vt::disable_trivial_init dti;\
+      namespace sv = varray_detail;\
+      errh::check_iterator_end_eq(*this, position);\
+      errh::check_capacity(*this, m_size + 1); /*may throw*/\
+      if ( position == this->end() ){\
+         sv::construct(dti(), position BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
+         ++m_size; /*update end*/\
+      }\
+      else{\
+         /* TODO - should following lines check for exception and revert to the old size? */\
+         /* TODO - should move be used only if it's nonthrowing? */\
+         value_type & r = *(this->end() - 1);\
+         sv::construct(dti(), this->end(), boost::move(r));/*may throw*/\
+         ++m_size; /*update end*/\
+         sv::move_backward(position, this->end() - 2, this->end() - 1);/*may throw*/\
+         typename aligned_storage\
+            <sizeof(value_type), alignment_of<value_type>::value>::type temp_storage;\
+         value_type * val_p = static_cast<value_type*>(static_cast<void*>(&temp_storage));\
+         sv::construct(dti(), val_p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
+         sv::scoped_destructor<value_type> d(val_p);\
+         sv::assign(position, ::boost::move(*val_p));/*may throw*/\
+      }\
+      return position;\
+   }\
+   BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VARRAY_EMPLACE_CODE)
+   #undef BOOST_CONTAINER_VARRAY_EMPLACE_CODE
+
+#endif //  !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || BOOST_CONTAINER_DOXYGEN_INVOKED
+#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
+
+    //! @brief Removes all elements from the container.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    void clear()
+    {
+        namespace sv = varray_detail;
+        sv::destroy(this->begin(), this->end());
+        m_size = 0; // update end
+    }
+
+    //! @pre <tt>i < size()</tt>
+    //!
+    //! @brief Returns reference to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return reference to the i-th element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   \c std::out_of_range exception by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reference at(size_type i)
+    {
+        errh::check_at(*this, i);                                   // may throw
+        return *(this->begin() + i);
+    }
+
+    //! @pre <tt>i < size()</tt>
+    //!
+    //! @brief Returns const reference to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return const reference to the i-th element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   \c std::out_of_range exception by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reference at(size_type i) const
+    {
+        errh::check_at(*this, i);                                   // may throw
+        return *(this->begin() + i);
+    }
+
+    //! @pre <tt>i < size()</tt>
+    //!
+    //! @brief Returns reference to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return reference to the i-th element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reference operator[](size_type i)
+    {
+        // TODO: Remove bounds check? std::vector and std::array operator[] don't check.
+        errh::check_operator_brackets(*this, i);
+        return *(this->begin() + i);
+    }
+
+    //! @pre <tt>i < size()</tt>
+    //!
+    //! @brief Returns const reference to the i-th element.
+    //!
+    //! @param i    The element's index.
+    //!
+    //! @return const reference to the i-th element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reference operator[](size_type i) const
+    {
+        errh::check_operator_brackets(*this, i);
+        return *(this->begin() + i);
+    }
+
+    //! @pre \c !empty()
+    //!
+    //! @brief Returns reference to the first element.
+    //!
+    //! @return reference to the first element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reference front()
+    {
+        errh::check_empty(*this);
+        return *(this->begin());
+    }
+
+    //! @pre \c !empty()
+    //!
+    //! @brief Returns const reference to the first element.
+    //!
+    //! @return const reference to the first element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reference front() const
+    {
+        errh::check_empty(*this);
+        return *(this->begin());
+    }
+
+    //! @pre \c !empty()
+    //!
+    //! @brief Returns reference to the last element.
+    //!
+    //! @return reference to the last element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reference back()
+    {
+        errh::check_empty(*this);
+        return *(this->end() - 1);
+    }
+
+    //! @pre \c !empty()
+    //!
+    //! @brief Returns const reference to the first element.
+    //!
+    //! @return const reference to the last element
+    //!   from the beginning of the container.
+    //!
+    //! @par Throws
+    //!   Nothing by default.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reference back() const
+    {
+        errh::check_empty(*this);
+        return *(this->end() - 1);
+    }
+
+    //! @brief Pointer such that <tt>[data(), data() + size())</tt> is a valid range.
+    //!   For a non-empty vector <tt>data() == &front()</tt>.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    Value * data()
+    {
+        return (addressof)(*(this->ptr()));
+    }
+
+    //! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
+    //!   For a non-empty vector <tt>data() == &front()</tt>.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const Value * data() const
+    {
+        return (addressof)(*(this->ptr()));
+    }
+
+
+    //! @brief Returns iterator to the first element.
+    //!
+    //! @return iterator to the first element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    iterator begin() { return this->ptr(); }
+
+    //! @brief Returns const iterator to the first element.
+    //!
+    //! @return const_iterator to the first element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_iterator begin() const { return this->ptr(); }
+
+    //! @brief Returns const iterator to the first element.
+    //!
+    //! @return const_iterator to the first element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_iterator cbegin() const { return this->ptr(); }
+
+    //! @brief Returns iterator to the one after the last element.
+    //!
+    //! @return iterator pointing to the one after the last element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    iterator end() { return this->begin() + m_size; }
+
+    //! @brief Returns const iterator to the one after the last element.
+    //!
+    //! @return const_iterator pointing to the one after the last element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_iterator end() const { return this->begin() + m_size; }
+
+    //! @brief Returns const iterator to the one after the last element.
+    //!
+    //! @return const_iterator pointing to the one after the last element contained in the vector.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_iterator cend() const { return this->cbegin() + m_size; }
+
+    //! @brief Returns reverse iterator to the first element of the reversed container.
+    //!
+    //! @return reverse_iterator pointing to the beginning
+    //! of the reversed varray.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reverse_iterator rbegin() { return reverse_iterator(this->end()); }
+
+    //! @brief Returns const reverse iterator to the first element of the reversed container.
+    //!
+    //! @return const_reverse_iterator pointing to the beginning
+    //! of the reversed varray.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reverse_iterator rbegin() const { return reverse_iterator(this->end()); }
+
+    //! @brief Returns const reverse iterator to the first element of the reversed container.
+    //!
+    //! @return const_reverse_iterator pointing to the beginning
+    //! of the reversed varray.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reverse_iterator crbegin() const { return reverse_iterator(this->end()); }
+
+    //! @brief Returns reverse iterator to the one after the last element of the reversed container.
+    //!
+    //! @return reverse_iterator pointing to the one after the last element
+    //! of the reversed varray.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    reverse_iterator rend() { return reverse_iterator(this->begin()); }
+
+    //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
+    //!
+    //! @return const_reverse_iterator pointing to the one after the last element
+    //! of the reversed varray.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reverse_iterator rend() const { return reverse_iterator(this->begin()); }
+
+    //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
+    //!
+    //! @return const_reverse_iterator pointing to the one after the last element
+    //! of the reversed varray.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    const_reverse_iterator crend() const { return reverse_iterator(this->begin()); }
+
+    //! @brief Returns container's capacity.
+    //!
+    //! @return container's capacity.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    static size_type capacity() { return Capacity; }
+
+    //! @brief Returns container's capacity.
+    //!
+    //! @return container's capacity.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    static size_type max_size() { return Capacity; }
+
+    //! @brief Returns the number of stored elements.
+    //!
+    //! @return Number of elements contained in the container.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    size_type size() const { return m_size; }
+
+    //! @brief Queries if the container contains elements.
+    //!
+    //! @return true if the number of elements contained in the
+    //!   container is equal to 0.
+    //!
+    //! @par Throws
+    //!   Nothing.
+    //!
+    //! @par Complexity
+    //!   Constant O(1).
+    bool empty() const { return 0 == m_size; }
+
+private:
+
+    // @par Throws
+    //   Nothing.
+    // @par Complexity
+    //   Linear O(N).
+    template <std::size_t C, typename S>
+    void move_ctor_dispatch(varray<value_type, C, S> & other, true_type /*use_memop*/)
+    {
+        ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
+        m_size = other.m_size;
+    }
+
+    // @par Throws
+    //   @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor throws
+    //   @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor throws.
+    // @par Complexity
+    //   Linear O(N).
+    template <std::size_t C, typename S>
+    void move_ctor_dispatch(varray<value_type, C, S> & other, false_type /*use_memop*/)
+    {
+        namespace sv = varray_detail;
+        sv::uninitialized_move_if_noexcept(other.begin(), other.end(), this->begin());                  // may throw
+        m_size = other.m_size;
+    }
+
+    // @par Throws
+    //   Nothing.
+    // @par Complexity
+    //   Linear O(N).
+    template <std::size_t C, typename S>
+    void move_assign_dispatch(varray<value_type, C, S> & other, true_type /*use_memop*/)
+    {
+        this->clear();
+
+        ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
+        boost::adl_move_swap(m_size, other.m_size);
+    }
+
+    // @par Throws
+    //   @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor or move assignment throws
+    //   @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor or move assignment throws.
+    // @par Complexity
+    //   Linear O(N).
+    template <std::size_t C, typename S>
+    void move_assign_dispatch(varray<value_type, C, S> & other, false_type /*use_memop*/)
+    {
+        namespace sv = varray_detail;
+        if ( m_size <= static_cast<size_type>(other.size()) )
+        {
+            sv::move_if_noexcept(other.begin(), other.begin() + m_size, this->begin());             // may throw
+            // TODO - perform uninitialized_copy first?
+            sv::uninitialized_move_if_noexcept(other.begin() + m_size, other.end(), this->end());   // may throw
+        }
+        else
+        {
+            sv::move_if_noexcept(other.begin(), other.end(), this->begin());                        // may throw
+            sv::destroy(this->begin() + other.size(), this->end());
+        }
+        m_size = other.size(); // update end
+    }
+
+    // @par Throws
+    //   Nothing.
+    // @par Complexity
+    //   Linear O(N).
+    template <std::size_t C, typename S>
+    void swap_dispatch(varray<value_type, C, S> & other, true_type const& /*use_optimized_swap*/)
+    {
+        typedef typename
+        if_c<
+            Capacity < C,
+            aligned_storage_type,
+            typename varray<value_type, C, S>::aligned_storage_type
+        >::type
+        storage_type;
+
+        storage_type temp_storage;
+        value_type * temp_ptr = static_cast<value_type*>(static_cast<void*>(&temp_storage));
+
+        ::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size());
+        ::memcpy(this->data(), other.data(), sizeof(Value) * other.size());
+        ::memcpy(other.data(), temp_ptr, sizeof(Value) * this->size());
+
+        boost::adl_move_swap(m_size, other.m_size);
+    }
+
+    // @par Throws
+    //   If Value's move constructor or move assignment throws
+    //   but only if use_memop_in_swap_and_move is false_type - default.
+    // @par Complexity
+    //   Linear O(N).
+    template <std::size_t C, typename S>
+    void swap_dispatch(varray<value_type, C, S> & other, false_type const& /*use_optimized_swap*/)
+    {
+        namespace sv = varray_detail;
+
+        typedef typename
+        vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
+
+        if ( this->size() < other.size() )
+            swap_dispatch_impl(this->begin(), this->end(), other.begin(), other.end(), use_memop_in_swap_and_move()); // may throw
+        else
+            swap_dispatch_impl(other.begin(), other.end(), this->begin(), this->end(), use_memop_in_swap_and_move()); // may throw
+        boost::adl_move_swap(m_size, other.m_size);
+    }
+
+    // @par Throws
+    //   Nothing.
+    // @par Complexity
+    //   Linear O(N).
+    void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, true_type const& /*use_memop*/)
+    {
+        //BOOST_ASSERT_MSG(boost::container::iterator_distance(first_sm, last_sm) <= boost::container::iterator_distance(first_la, last_la));
+
+        namespace sv = varray_detail;
+        for (; first_sm != last_sm ; ++first_sm, ++first_la)
+        {
+            typename aligned_storage<
+                sizeof(value_type),
+                alignment_of<value_type>::value
+            >::type temp_storage;
+            value_type * temp_ptr = static_cast<value_type*>(static_cast<void*>(&temp_storage));
+            ::memcpy(temp_ptr, (addressof)(*first_sm), sizeof(value_type));
+            ::memcpy((addressof)(*first_sm), (addressof)(*first_la), sizeof(value_type));
+            ::memcpy((addressof)(*first_la), temp_ptr, sizeof(value_type));
+        }
+
+        ::memcpy(first_sm, first_la, sizeof(value_type) * boost::container::iterator_distance(first_la, last_la));
+    }
+
+    // @par Throws
+    //   If Value's move constructor or move assignment throws.
+    // @par Complexity
+    //   Linear O(N).
+    void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, false_type const& /*use_memop*/)
+    {
+        //BOOST_ASSERT_MSG(boost::container::iterator_distance(first_sm, last_sm) <= boost::container::iterator_distance(first_la, last_la));
+
+        namespace sv = varray_detail;
+        for (; first_sm != last_sm ; ++first_sm, ++first_la)
+        {
+            //boost::adl_move_swap(*first_sm, *first_la);                                    // may throw
+            value_type temp(boost::move(*first_sm));                                // may throw
+            *first_sm = boost::move(*first_la);                                     // may throw
+            *first_la = boost::move(temp);                                          // may throw
+        }
+        sv::uninitialized_move(first_la, last_la, first_sm);                        // may throw
+        sv::destroy(first_la, last_la);
+    }
+
+    // insert
+
+    // @par Throws
+    //   If Value's move constructor or move assignment throws
+    //   or if Value's copy assignment throws.
+    // @par Complexity
+    //   Linear O(N).
+    template <typename V>
+    iterator priv_insert(iterator position, V & value)
+    {
+        typedef typename vt::disable_trivial_init dti;
+        namespace sv = varray_detail;
+
+        errh::check_iterator_end_eq(*this, position);
+        errh::check_capacity(*this, m_size + 1);                                    // may throw
+
+        if ( position == this->end() )
+        {
+            sv::construct(dti(), position, value);                                         // may throw
+            ++m_size; // update end
+        }
+        else
+        {
+            // TODO - should following lines check for exception and revert to the old size?
+
+            // TODO - should move be used only if it's nonthrowing?
+            value_type & r = *(this->end() - 1);
+            sv::construct(dti(), this->end(), boost::move(r));                             // may throw
+            ++m_size; // update end
+            sv::move_backward(position, this->end() - 2, this->end() - 1);          // may throw
+            sv::assign(position, value);                                            // may throw
+        }
+
+        return position;
+    }
+
+    // insert
+
+    // @par Throws
+    //   If Value's move constructor, move assignment throws
+    //   or if Value's copy constructor or copy assignment throws.
+    // @par Complexity
+    //   Linear O(N).
+    template <typename Iterator>
+    typename iterator_enable_if_tag<Iterator, std::random_access_iterator_tag>::type
+       insert_dispatch(iterator position, Iterator first, Iterator last)
+    {
+        errh::check_iterator_end_eq(*this, position);
+
+        size_type count = boost::container::iterator_distance(first, last);
+
+        errh::check_capacity(*this, m_size + count);                                             // may throw
+
+        if ( position == this->end() )
+        {
+            namespace sv = varray_detail;
+
+            sv::uninitialized_copy(first, last, position);                                      // may throw
+            m_size += count; // update end
+        }
+        else
+        {
+            this->insert_in_the_middle(position, first, last, count);                           // may throw
+        }
+    }
+
+    // @par Throws
+    //   If Value's move constructor, move assignment throws
+    //   or if Value's copy constructor or copy assignment throws.
+    // @par Complexity
+    //   Linear O(N).
+    template <typename Iterator, typename Category>
+    typename iterator_disable_if_tag<Iterator, std::random_access_iterator_tag>::type
+        insert_dispatch(iterator position, Iterator first, Iterator last)
+    {
+        errh::check_iterator_end_eq(*this, position);
+
+        if ( position == this->end() )
+        {
+            namespace sv = varray_detail;
+
+            std::ptrdiff_t d = boost::container::iterator_distance(position, this->begin() + Capacity);
+            std::size_t count = sv::uninitialized_copy_s(first, last, position, d);                     // may throw
+
+            errh::check_capacity(*this, count <= static_cast<std::size_t>(d) ? m_size + count : Capacity + 1);  // may throw
+
+            m_size += count;
+        }
+        else
+        {
+            size_type count = boost::container::iterator_distance(first, last);
+
+            errh::check_capacity(*this, m_size + count);                                                // may throw
+
+            this->insert_in_the_middle(position, first, last, count);                                   // may throw
+        }
+    }
+
+    // @par Throws
+    //   If Value's move constructor, move assignment throws
+    //   or if Value's copy constructor or copy assignment throws.
+    // @par Complexity
+    //   Linear O(N).
+    template <typename Iterator>
+    void insert_in_the_middle(iterator position, Iterator first, Iterator last, difference_type count)
+    {
+        namespace sv = varray_detail;
+
+        difference_type to_move = boost::container::iterator_distance(position, this->end());
+
+        // TODO - should following lines check for exception and revert to the old size?
+
+        if ( count < to_move )
+        {
+            sv::uninitialized_move(this->end() - count, this->end(), this->end());              // may throw
+            m_size += count; // update end
+            sv::move_backward(position, position + to_move - count, this->end() - count);       // may throw
+            sv::copy(first, last, position);                                                    // may throw
+        }
+        else
+        {
+            Iterator middle_iter = first;
+            boost::container::iterator_advance(middle_iter, to_move);
+
+            sv::uninitialized_copy(middle_iter, last, this->end());                             // may throw
+            m_size += count - to_move; // update end
+            sv::uninitialized_move(position, position + to_move, position + count);             // may throw
+            m_size += to_move; // update end
+            sv::copy(first, middle_iter, position);                                             // may throw
+        }
+    }
+
+    // assign
+
+    // @par Throws
+    //   If Value's constructor or assignment taking dereferenced Iterator throws.
+    // @par Complexity
+    //   Linear O(N).
+    template <typename Iterator>
+    typename iterator_enable_if_tag<Iterator, std::random_access_iterator_tag>::type
+       assign_dispatch(Iterator first, Iterator last)
+    {
+        namespace sv = varray_detail;
+
+        size_type s = boost::container::iterator_distance(first, last);
+
+        errh::check_capacity(*this, s);                                     // may throw
+
+        if ( m_size <= static_cast<size_type>(s) )
+        {
+            sv::copy(first, first + m_size, this->begin());                 // may throw
+            // TODO - perform uninitialized_copy first?
+            sv::uninitialized_copy(first + m_size, last, this->end());      // may throw
+        }
+        else
+        {
+            sv::copy(first, last, this->begin());                           // may throw
+            sv::destroy(this->begin() + s, this->end());
+        }
+        m_size = s; // update end
+    }
+
+    // @par Throws
+    //   If Value's constructor or assignment taking dereferenced Iterator throws.
+    // @par Complexity
+    //   Linear O(N).
+    template <typename Iterator, typename Category>
+    typename iterator_disable_if_tag<Iterator, std::random_access_iterator_tag>::type
+       assign_dispatch(Iterator first, Iterator last)
+    {
+        namespace sv = varray_detail;
+
+        size_type s = 0;
+        iterator it = this->begin();
+
+        for ( ; it != this->end() && first != last ; ++it, ++first, ++s )
+            *it = *first;                                                                                   // may throw
+
+        sv::destroy(it, this->end());
+
+        std::ptrdiff_t d = boost::container::iterator_distance(it, this->begin() + Capacity);
+        std::size_t count = sv::uninitialized_copy_s(first, last, it, d);                                   // may throw
+        s += count;
+
+        errh::check_capacity(*this, count <= static_cast<std::size_t>(d) ? s : Capacity + 1);               // may throw
+
+        m_size = s; // update end
+    }
+
+    pointer ptr()
+    {
+        return pointer(static_cast<Value*>(static_cast<void*>(&m_storage)));
+    }
+
+    const_pointer ptr() const
+    {
+        return pointer(static_cast<const Value*>(static_cast<const void*>(&m_storage)));
+    }
+
+    size_type m_size;
+    aligned_storage_type m_storage;
+};
+
+#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+template<typename Value, typename Strategy>
+class varray<Value, 0, Strategy>
+{
+    typedef varray_traits<
+        Value, 0, Strategy
+    > vt;
+
+    typedef typename vt::size_type stored_size_type;
+    typedef typename vt::error_handler errh;
+
+public:
+    typedef typename vt::value_type value_type;
+    typedef stored_size_type size_type;
+    typedef typename vt::difference_type difference_type;
+    typedef typename vt::pointer pointer;
+    typedef typename vt::const_pointer const_pointer;
+    typedef typename vt::reference reference;
+    typedef typename vt::const_reference const_reference;
+
+    typedef pointer iterator;
+    typedef const_pointer const_iterator;
+    typedef boost::container::reverse_iterator<iterator> reverse_iterator;
+    typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
+
+    // nothrow
+    varray() {}
+
+    // strong
+    explicit varray(size_type count)
+    {
+        errh::check_capacity(*this, count);                                         // may throw
+    }
+
+    // strong
+    varray(size_type count, value_type const&)
+    {
+        errh::check_capacity(*this, count);                                         // may throw
+    }
+
+    // strong
+    varray(varray const& other)
+    {
+        //errh::check_capacity(*this, count);
+    }
+
+    // strong
+    template <size_t C, typename S>
+    varray(varray<value_type, C, S> const& other)
+    {
+        errh::check_capacity(*this, other.size());                                  // may throw
+    }
+
+    // strong
+    template <typename Iterator>
+    varray(Iterator first, Iterator last)
+    {
+        errh::check_capacity(*this, boost::container::iterator_distance(first, last));                    // may throw
+    }
+
+    // basic
+    varray & operator=(varray const& other)
+    {
+        //errh::check_capacity(*this, other.size());
+        return *this;
+    }
+
+    // basic
+    template <size_t C, typename S>
+    varray & operator=(varray<value_type, C, S> const& other)
+    {
+        errh::check_capacity(*this, other.size());                                  // may throw
+        return *this;
+    }
+
+    // nothrow
+    ~varray() {}
+
+    // strong
+    void resize(size_type count)
+    {
+        errh::check_capacity(*this, count);                                         // may throw
+    }
+
+    // strong
+    void resize(size_type count, value_type const&)
+    {
+        errh::check_capacity(*this, count);                                         // may throw
+    }
+
+
+    // nothrow
+    void reserve(size_type count)
+    {
+        errh::check_capacity(*this, count);                                         // may throw
+    }
+
+    // strong
+    void push_back(value_type const&)
+    {
+        errh::check_capacity(*this, 1);                                             // may throw
+    }
+
+    // nothrow
+    void pop_back()
+    {
+        errh::check_empty(*this);
+    }
+
+    // basic
+    void insert(iterator position, value_type const&)
+    {
+        errh::check_iterator_end_eq(*this, position);
+        errh::check_capacity(*this, 1);                                             // may throw
+    }
+
+    // basic
+    void insert(iterator position, size_type count, value_type const&)
+    {
+        errh::check_iterator_end_eq(*this, position);
+        errh::check_capacity(*this, count);                                         // may throw
+    }
+
+    // basic
+    template <typename Iterator>
+    void insert(iterator, Iterator first, Iterator last)
+    {
+        errh::check_capacity(*this, boost::container::iterator_distance(first, last));                    // may throw
+    }
+
+    // basic
+    void erase(iterator position)
+    {
+        errh::check_iterator_end_neq(*this, position);
+    }
+
+    // basic
+    void erase(iterator first, iterator last)
+    {
+        errh::check_iterator_end_eq(*this, first);
+        errh::check_iterator_end_eq(*this, last);
+
+        //BOOST_ASSERT_MSG(0 <= n, "invalid range");
+    }
+
+    // basic
+    template <typename Iterator>
+    void assign(Iterator first, Iterator last)
+    {
+        errh::check_capacity(*this, boost::container::iterator_distance(first, last));                    // may throw
+    }
+
+    // basic
+    void assign(size_type count, value_type const&)
+    {
+        errh::check_capacity(*this, count);                                     // may throw
+    }
+
+    // nothrow
+    void clear() {}
+
+    // strong
+    reference at(size_type i)
+    {
+        errh::check_at(*this, i);                                   // may throw
+        return *(this->begin() + i);
+    }
+
+    // strong
+    const_reference at(size_type i) const
+    {
+        errh::check_at(*this, i);                                   // may throw
+        return *(this->begin() + i);
+    }
+
+    // nothrow
+    reference operator[](size_type i)
+    {
+        errh::check_operator_brackets(*this, i);
+        return *(this->begin() + i);
+    }
+
+    // nothrow
+    const_reference operator[](size_type i) const
+    {
+        errh::check_operator_brackets(*this, i);
+        return *(this->begin() + i);
+    }
+
+    // nothrow
+    reference front()
+    {
+        errh::check_empty(*this);
+        return *(this->begin());
+    }
+
+    // nothrow
+    const_reference front() const
+    {
+        errh::check_empty(*this);
+        return *(this->begin());
+    }
+
+    // nothrow
+    reference back()
+    {
+        errh::check_empty(*this);
+        return *(this->end() - 1);
+    }
+
+    // nothrow
+    const_reference back() const
+    {
+        errh::check_empty(*this);
+        return *(this->end() - 1);
+    }
+
+    // nothrow
+    Value * data() { return (addressof)(*(this->ptr())); }
+    const Value * data() const { return (addressof)(*(this->ptr())); }
+
+    // nothrow
+    iterator begin() { return this->ptr(); }
+    const_iterator begin() const { return this->ptr(); }
+    const_iterator cbegin() const { return this->ptr(); }
+    iterator end() { return this->begin(); }
+    const_iterator end() const { return this->begin(); }
+    const_iterator cend() const { return this->cbegin(); }
+    // nothrow
+    reverse_iterator rbegin() { return reverse_iterator(this->end()); }
+    const_reverse_iterator rbegin() const { return reverse_iterator(this->end()); }
+    const_reverse_iterator crbegin() const { return reverse_iterator(this->end()); }
+    reverse_iterator rend() { return reverse_iterator(this->begin()); }
+    const_reverse_iterator rend() const { return reverse_iterator(this->begin()); }
+    const_reverse_iterator crend() const { return reverse_iterator(this->begin()); }
+
+    // nothrow
+    size_type capacity() const { return 0; }
+    size_type max_size() const { return 0; }
+    size_type size() const { return 0; }
+    bool empty() const { return true; }
+
+private:
+
+    pointer ptr()
+    {
+        return pointer(reinterpret_cast<Value*>(this));
+    }
+
+    const_pointer ptr() const
+    {
+        return const_pointer(reinterpret_cast<const Value*>(this));
+    }
+};
+
+#endif // !BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! @brief Checks if contents of two varrays are equal.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x    The first varray.
+//! @param y    The second varray.
+//!
+//! @return     \c true if containers have the same size and elements in both containers are equal.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, typename S1, std::size_t C2, typename S2>
+bool operator== (varray<V, C1, S1> const& x, varray<V, C2, S2> const& y)
+{
+    return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());
+}
+
+//! @brief Checks if contents of two varrays are not equal.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x    The first varray.
+//! @param y    The second varray.
+//!
+//! @return     \c true if containers have different size or elements in both containers are not equal.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, typename S1, std::size_t C2, typename S2>
+bool operator!= (varray<V, C1, S1> const& x, varray<V, C2, S2> const& y)
+{
+    return !(x==y);
+}
+
+//! @brief Lexicographically compares varrays.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x    The first varray.
+//! @param y    The second varray.
+//!
+//! @return     \c true if x compares lexicographically less than y.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, typename S1, std::size_t C2, typename S2>
+bool operator< (varray<V, C1, S1> const& x, varray<V, C2, S2> const& y)
+{
+    return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+//! @brief Lexicographically compares varrays.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x    The first varray.
+//! @param y    The second varray.
+//!
+//! @return     \c true if y compares lexicographically less than x.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, typename S1, std::size_t C2, typename S2>
+bool operator> (varray<V, C1, S1> const& x, varray<V, C2, S2> const& y)
+{
+    return y<x;
+}
+
+//! @brief Lexicographically compares varrays.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x    The first varray.
+//! @param y    The second varray.
+//!
+//! @return     \c true if y don't compare lexicographically less than x.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, typename S1, std::size_t C2, typename S2>
+bool operator<= (varray<V, C1, S1> const& x, varray<V, C2, S2> const& y)
+{
+    return !(y<x);
+}
+
+//! @brief Lexicographically compares varrays.
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x    The first varray.
+//! @param y    The second varray.
+//!
+//! @return     \c true if x don't compare lexicographically less than y.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, typename S1, std::size_t C2, typename S2>
+bool operator>= (varray<V, C1, S1> const& x, varray<V, C2, S2> const& y)
+{
+    return !(x<y);
+}
+
+//! @brief Swaps contents of two varrays.
+//!
+//! This function calls varray::swap().
+//!
+//! @ingroup varray_non_member
+//!
+//! @param x    The first varray.
+//! @param y    The second varray.
+//!
+//! @par Complexity
+//!   Linear O(N).
+template<typename V, std::size_t C1, typename S1, std::size_t C2, typename S2>
+inline void swap(varray<V, C1, S1> & x, varray<V, C2, S2> & y)
+{
+    x.swap(y);
+}
+
+}}} // namespace boost::container::dtl
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // BOOST_CONTAINER_DETAIL_VARRAY_HPP
diff --git a/bench/detail/varray_concept.hpp b/bench/detail/varray_concept.hpp
new file mode 100644
index 0000000..94d19bd
--- /dev/null
+++ b/bench/detail/varray_concept.hpp
@@ -0,0 +1,60 @@
+// Boost.Container varray
+//
+// Copyright (c) 2012-2013 Andrew Hundt.
+// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_CONTAINER_VARRAY_CONCEPT_HPP
+#define BOOST_CONTAINER_VARRAY_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+namespace boost { namespace container { namespace dtl { namespace concept {
+
+/**
+ * VArrayStrategyConcept
+ *
+ *  \brief Checks strategy for varray<Value,Capacity,Strategy>, which has similarities to std::allocator
+ *  \ingroup varray
+ */
+template<typename Strategy>
+struct VArrayStrategy {
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    // typedefs are the same as in std::allocator
+    typedef typename Strategy::value_type      value_type;
+    typedef typename Strategy::size_type       size_type;
+    typedef typename Strategy::difference_type difference_type;
+    typedef typename Strategy::pointer         pointer;
+    typedef typename Strategy::const_pointer   const_pointer;
+    typedef typename Strategy::reference       reference;
+    typedef typename Strategy::const_reference const_reference;
+
+    struct check_methods
+    {
+        static void apply()
+        {
+            Strategy const* str = 0;
+
+            // must implement allocate_failed
+            str->allocate_failed();
+
+            boost::ignore_unused_variable_warning(str);
+        }
+    };
+
+public :
+    BOOST_CONCEPT_USAGE(VArrayStrategy)
+    {
+        check_methods::apply();
+    }
+
+#endif
+};
+
+}}}} // namespace boost::container::dtl::concept
+
+#endif //BOOST_CONTAINER_VARRAY_CONCEPT_HPP
diff --git a/bench/detail/varray_util.hpp b/bench/detail/varray_util.hpp
new file mode 100644
index 0000000..043e9e9
--- /dev/null
+++ b/bench/detail/varray_util.hpp
@@ -0,0 +1,646 @@
+// Boost.Container
+//
+// varray details
+//
+// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2011-2013 Andrew Hundt.
+//
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_CONTAINER_DETAIL_VARRAY_UTIL_HPP
+#define BOOST_CONTAINER_DETAIL_VARRAY_UTIL_HPP
+
+#include <cstddef>
+#include <cstring>
+#include <memory>
+#include <limits>
+
+#include <boost/config.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+
+#include <boost/container/detail/addressof.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+#include <boost/move/algorithm.hpp>
+#include <boost/move/traits.hpp>
+#include <boost/move/utility_core.hpp>
+
+// TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
+
+#if defined(BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
+#include <vector>
+#include <boost/container/vector.hpp>
+#endif // BOOST_CONTAINER_VARRAY_ENABLE_ITERATORS_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
+
+namespace boost { namespace container { namespace varray_detail {
+
+namespace bcd = ::boost::container::dtl;
+
+template <typename I>
+struct are_elements_contiguous : boost::container::dtl::is_pointer<I>
+{};
+
+#if defined(BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
+
+template <typename Pointer>
+struct are_elements_contiguous<
+    bcd::vector_const_iterator<Pointer>
+> : bcd::true_type
+{};
+
+template <typename Pointer>
+struct are_elements_contiguous<
+    bcd::vector_iterator<Pointer>
+> : bcd::true_type
+{};
+
+#if defined(BOOST_DINKUMWARE_STDLIB)
+
+template <typename T>
+struct are_elements_contiguous<
+    std::_Vector_const_iterator<T>
+> : bcd::true_type
+{};
+
+template <typename T>
+struct are_elements_contiguous<
+    std::_Vector_iterator<T>
+> : bcd::true_type
+{};
+
+#elif defined(BOOST_GNU_STDLIB)
+
+template <typename P, typename T, typename Allocator>
+struct are_elements_contiguous<
+    __gnu_cxx::__normal_iterator<P, std::vector<T, Allocator> >
+> : bcd::true_type
+{};
+
+#elif defined(_LIBCPP_VERSION)
+
+// TODO - test it first
+//template <typename P>
+//struct are_elements_contiguous<
+//    __wrap_iter<P>
+//> : bcd::true_type
+//{};
+
+#else // OTHER_STDLIB
+
+// TODO - add other iterators implementations
+
+#endif // STDLIB
+
+#endif // BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
+
+template <typename I, typename O>
+struct are_corresponding :
+    bcd::bool_<
+        bcd::is_same<
+            bcd::remove_const<
+                typename ::boost::container::iterator_traits<I>::value_type
+            >,
+            bcd::remove_const<
+                typename ::boost::container::iterator_traits<O>::value_type
+            >
+        >::value &&
+        are_elements_contiguous<I>::value &&
+        are_elements_contiguous<O>::value
+    >
+{};
+
+template <typename I, typename V>
+struct is_corresponding_value :
+   bcd::bool_<
+         bcd::is_same<
+            bcd::remove_const<typename ::boost::container::iterator_traits<I>::value_type>,
+            bcd::remove_const<V>
+         >::value
+      >
+{};
+
+// destroy(I, I)
+
+template <typename I>
+void destroy_dispatch(I /*first*/, I /*last*/, bcd::true_type const& /*is_trivially_destructible*/)
+{}
+
+template <typename I>
+void destroy_dispatch(I first, I last, bcd::false_type const& /*is_trivially_destructible*/)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+    for ( ; first != last ; ++first )
+        first->~value_type();
+}
+
+template <typename I>
+void destroy(I first, I last)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+    destroy_dispatch(first, last, bcd::bool_<bcd::is_trivially_destructible<value_type>::value>());
+}
+
+// destroy(I)
+
+template <typename I>
+void destroy_dispatch(I /*pos*/,
+                      bcd::true_type const& /*is_trivially_destructible*/)
+{}
+
+template <typename I>
+void destroy_dispatch(I pos,
+                      bcd::false_type const& /*is_trivially_destructible*/)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+    pos->~value_type();
+}
+
+template <typename I>
+void destroy(I pos)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+    destroy_dispatch(pos, bcd::bool_<bcd::is_trivially_destructible<value_type>::value>());
+}
+
+// copy(I, I, O)
+
+template <typename I, typename O>
+inline O copy_dispatch(I first, I last, O dst, bcd::true_type const& /*use_memmove*/)
+{
+   typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+   const std::size_t d = boost::container::iterator_distance(first, last);
+   ::memmove(boost::container::dtl::addressof(*dst), boost::container::dtl::addressof(*first), sizeof(value_type) * d);
+   return dst + d;
+}
+
+template <typename I, typename O>
+inline O copy_dispatch(I first, I last, O dst, bcd::false_type const& /*use_memmove*/)
+{
+    return std::copy(first, last, dst);                                         // may throw
+}
+
+template <typename I, typename O>
+inline O copy(I first, I last, O dst)
+{
+   typedef bcd::bool_
+   <  are_corresponding<I, O>::value &&
+      bcd::is_trivially_copy_assignable<typename ::boost::container::iterator_traits<O>::value_type>::value
+   > use_memmove;
+
+   return copy_dispatch(first, last, dst, use_memmove());                       // may throw
+}
+
+// uninitialized_copy(I, I, O)
+
+template <typename I, typename O>
+inline
+O uninitialized_copy_dispatch(I first, I last, O dst,
+                              bcd::true_type const& /*use_memcpy*/)
+{
+   typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+   const std::size_t d = boost::container::iterator_distance(first, last);
+   ::memcpy(boost::container::dtl::addressof(*dst), boost::container::dtl::addressof(*first), sizeof(value_type) * d);
+   return dst + d;
+}
+
+template <typename I, typename F>
+inline
+F uninitialized_copy_dispatch(I first, I last, F dst,
+                              bcd::false_type const& /*use_memcpy*/)
+{
+    return std::uninitialized_copy(first, last, dst);                                       // may throw
+}
+
+template <typename I, typename F>
+inline
+F uninitialized_copy(I first, I last, F dst)
+{
+   typedef bcd::bool_
+   <  are_corresponding<I, F>::value &&
+      bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<F>::value_type>::value
+   > use_memcpy;
+   return uninitialized_copy_dispatch(first, last, dst, use_memcpy());          // may throw
+}
+
+// uninitialized_move(I, I, O)
+
+template <typename I, typename O>
+inline
+O uninitialized_move_dispatch(I first, I last, O dst,
+                              bcd::true_type const& /*use_memcpy*/)
+{
+   typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+   const std::size_t d = boost::container::iterator_distance(first, last);
+   ::memcpy(boost::container::dtl::addressof(*dst), boost::container::dtl::addressof(*first), sizeof(value_type) * d);
+   return dst + d;
+}
+
+template <typename I, typename O>
+inline
+O uninitialized_move_dispatch(I first, I last, O dst,
+                              bcd::false_type const& /*use_memcpy*/)
+{
+    //return boost::uninitialized_move(first, last, dst);                         // may throw
+
+    O o = dst;
+
+    BOOST_TRY
+    {
+        typedef typename boost::container::iterator_traits<O>::value_type value_type;
+        for (; first != last; ++first, ++o )
+            new (boost::container::dtl::addressof(*o)) value_type(boost::move(*first));
+    }
+    BOOST_CATCH(...)
+    {
+        destroy(dst, o);
+        BOOST_RETHROW;
+    }
+    BOOST_CATCH_END
+
+    return dst;
+}
+
+template <typename I, typename O>
+inline
+O uninitialized_move(I first, I last, O dst)
+{
+   typedef bcd::bool_
+   <  are_corresponding<I, O>::value &&
+      bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<O>::value_type>::value
+   > use_memcpy;
+   return uninitialized_move_dispatch(first, last, dst, use_memcpy());         // may throw
+}
+
+// TODO - move uses memmove - implement 2nd version using memcpy?
+
+// move(I, I, O)
+
+template <typename I, typename O>
+inline
+O move_dispatch(I first, I last, O dst,
+                bcd::true_type const& /*use_memmove*/)
+{
+   typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+   const std::size_t d = boost::container::iterator_distance(first, last);
+   ::memmove(boost::container::dtl::addressof(*dst), boost::container::dtl::addressof(*first), sizeof(value_type)*d );
+   return dst + d;
+}
+
+template <typename I, typename O>
+inline
+O move_dispatch(I first, I last, O dst,
+                bcd::false_type const& /*use_memmove*/)
+{
+   return boost::move(first, last, dst);                                         // may throw
+}
+
+template <typename I, typename O>
+inline
+O move(I first, I last, O dst)
+{
+   typedef bcd::bool_
+   <  are_corresponding<I, O>::value &&
+      bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<O>::value_type>::value
+   > use_memmove;
+   return move_dispatch(first, last, dst, use_memmove());                      // may throw
+}
+
+// move_backward(BDI, BDI, BDO)
+
+template <typename BDI, typename BDO>
+inline
+BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
+                           bcd::true_type const& /*use_memmove*/)
+{
+    typedef typename ::boost::container::iterator_traits<BDI>::value_type value_type;
+    const std::size_t d = boost::container::iterator_distance(first, last);
+    BDO foo(dst - d);
+    ::memmove(boost::container::dtl::addressof(*foo), boost::container::dtl::addressof(*first), sizeof(value_type) * d);
+    return foo;
+}
+
+template <typename BDI, typename BDO>
+inline
+BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
+                           bcd::false_type const& /*use_memmove*/)
+{
+    return boost::move_backward(first, last, dst);                                // may throw
+}
+
+template <typename BDI, typename BDO>
+inline
+BDO move_backward(BDI first, BDI last, BDO dst)
+{
+   typedef bcd::bool_
+   <  are_corresponding<BDI, BDO>::value &&
+      bcd::is_trivially_copy_constructible<typename ::boost::container::iterator_traits<BDO>::value_type>::value
+   > use_memmove;
+   return move_backward_dispatch(first, last, dst, use_memmove());             // may throw
+}
+
+template <typename T>
+struct has_nothrow_move : public
+    bcd::bool_<
+         ::boost::has_nothrow_move<
+               typename bcd::remove_const<T>::type
+         >::value
+        ||
+         ::boost::has_nothrow_move<T>::value
+    >
+{};
+
+// uninitialized_move_if_noexcept(I, I, O)
+
+template <typename I, typename O>
+inline
+O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, bcd::true_type const& /*use_move*/)
+{ return uninitialized_move(first, last, dst); }
+
+template <typename I, typename O>
+inline
+O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, bcd::false_type const& /*use_move*/)
+{ return uninitialized_copy(first, last, dst); }
+
+template <typename I, typename O>
+inline
+O uninitialized_move_if_noexcept(I first, I last, O dst)
+{
+    typedef has_nothrow_move<
+        typename ::boost::container::iterator_traits<O>::value_type
+    > use_move;
+
+    return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move());         // may throw
+}
+
+// move_if_noexcept(I, I, O)
+
+template <typename I, typename O>
+inline
+O move_if_noexcept_dispatch(I first, I last, O dst, bcd::true_type const& /*use_move*/)
+{ return move(first, last, dst); }
+
+template <typename I, typename O>
+inline
+O move_if_noexcept_dispatch(I first, I last, O dst, bcd::false_type const& /*use_move*/)
+{ return copy(first, last, dst); }
+
+template <typename I, typename O>
+inline
+O move_if_noexcept(I first, I last, O dst)
+{
+    typedef has_nothrow_move<
+        typename ::boost::container::iterator_traits<O>::value_type
+    > use_move;
+
+    return move_if_noexcept_dispatch(first, last, dst, use_move());         // may throw
+}
+
+// uninitialized_fill(I, I)
+
+template <typename I>
+inline
+void uninitialized_fill_dispatch(I first, I last,
+                                 bcd::true_type const& /*is_trivially_default_constructible*/,
+                                 bcd::true_type const& /*disable_trivial_init*/)
+{}
+
+template <typename I>
+inline
+void uninitialized_fill_dispatch(I first, I last,
+                                 bcd::true_type const& /*is_trivially_default_constructible*/,
+                                 bcd::false_type const& /*disable_trivial_init*/)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+    for ( ; first != last ; ++first )
+        new (boost::container::dtl::addressof(*first)) value_type();
+}
+
+template <typename I, typename DisableTrivialInit>
+inline
+void uninitialized_fill_dispatch(I first, I last,
+                                 bcd::false_type const& /*is_trivially_default_constructible*/,
+                                 DisableTrivialInit const& /*not_used*/)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+    I it = first;
+
+    BOOST_TRY
+    {
+        for ( ; it != last ; ++it )
+            new (boost::container::dtl::addressof(*it)) value_type();                           // may throw
+    }
+    BOOST_CATCH(...)
+    {
+        destroy(first, it);
+        BOOST_RETHROW;
+    }
+    BOOST_CATCH_END
+}
+
+template <typename I, typename DisableTrivialInit>
+inline
+void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+    uninitialized_fill_dispatch(first, last
+      , bcd::bool_<bcd::is_trivially_default_constructible<value_type>::value>()
+      , disable_trivial_init);     // may throw
+}
+
+// construct(I)
+
+template <typename I>
+inline
+void construct_dispatch(bcd::true_type const& /*dont_init*/, I pos)
+{}
+
+template <typename I>
+inline
+void construct_dispatch(bcd::false_type const& /*dont_init*/, I pos)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+    new (static_cast<void*>(::boost::container::dtl::addressof(*pos))) value_type();                      // may throw
+}
+
+template <typename DisableTrivialInit, typename I>
+inline
+void construct(DisableTrivialInit const&, I pos)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type value_type;
+    bcd::bool_<
+        bcd::is_trivially_default_constructible<value_type>::value &&
+        DisableTrivialInit::value
+    > dont_init;
+    construct_dispatch(dont_init(), pos);                                                // may throw
+}
+
+// construct(I, V)
+
+template <typename I, typename V>
+inline
+void construct_dispatch(I pos, V const& v, bcd::true_type const& /*use_memcpy*/)
+{
+    ::memcpy(boost::container::dtl::addressof(*pos), boost::container::dtl::addressof(v), sizeof(V));
+}
+
+template <typename I, typename P>
+inline
+void construct_dispatch(I pos, P const& p,
+                        bcd::false_type const& /*use_memcpy*/)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type V;
+    new (static_cast<void*>(boost::container::dtl::addressof(*pos))) V(p);                      // may throw
+}
+
+template <typename DisableTrivialInit, typename I, typename P>
+inline
+void construct(DisableTrivialInit const&, I pos, P const& p)
+{
+   typedef bcd::bool_
+   <  is_corresponding_value<I, P>::value &&
+      bcd::is_trivially_copy_constructible<P>::value
+   > use_memcpy;
+   construct_dispatch(pos, p, use_memcpy());                                   // may throw
+}
+
+// Needed by push_back(V &&)
+
+template <typename DisableTrivialInit, typename I, typename P>
+inline
+void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type V;
+    new (static_cast<void*>(boost::container::dtl::addressof(*pos))) V(::boost::move(p));                      // may throw
+}
+
+// Needed by emplace_back() and emplace()
+
+#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+template <typename DisableTrivialInit, typename I, class ...Args>
+inline
+void construct(DisableTrivialInit const&,
+               I pos,
+               BOOST_FWD_REF(Args) ...args)
+{
+    typedef typename ::boost::container::iterator_traits<I>::value_type V;
+    new (static_cast<void*>(boost::container::dtl::addressof(*pos))) V(::boost::forward<Args>(args)...);    // may throw
+}
+
+#else // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+// BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 const& p0
+// !BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 && p0
+// which means that version with one parameter may take V const& v
+
+#define BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE(N) \
+template <typename DisableTrivialInit, typename I, typename P BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+inline void construct(DisableTrivialInit const&, I pos, BOOST_FWD_REF(P) p BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\
+{\
+    typedef typename ::boost::container::iterator_traits<I>::value_type V;\
+    new (static_cast<void*>(boost::container::dtl::addressof(*pos)))\
+    V(::boost::forward<P>(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); /*may throw*/\
+}
+BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE)
+#undef BOOST_CONTAINER_VARRAY_UTIL_CONSTRUCT_CODE
+
+#endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
+
+// assign(I, V)
+
+template <typename I, typename V>
+inline
+void assign_dispatch(I pos, V const& v,
+                     bcd::true_type const& /*use_memcpy*/)
+{
+    ::memcpy(boost::container::dtl::addressof(*pos), boost::container::dtl::addressof(v), sizeof(V));
+}
+
+template <typename I, typename V>
+inline
+void assign_dispatch(I pos, V const& v,
+                     bcd::false_type const& /*use_memcpy*/)
+{
+    *pos = v;                                                                   // may throw
+}
+
+template <typename I, typename V>
+inline
+void assign(I pos, V const& v)
+{
+   typedef bcd::bool_
+   <  is_corresponding_value<I, V>::value &&
+      bcd::is_trivially_copy_assignable<V>::value
+   > use_memcpy;
+   assign_dispatch(pos, v, use_memcpy());                                        // may throw
+}
+
+template <typename I, typename V>
+inline
+void assign(I pos, BOOST_RV_REF(V) v)
+{
+    *pos = boost::move(v);                                                        // may throw
+}
+
+
+// uninitialized_copy_s
+
+template <typename I, typename F>
+inline std::size_t uninitialized_copy_s(I first, I last, F dest, std::size_t max_count)
+{
+    std::size_t count = 0;
+    F it = dest;
+
+    BOOST_TRY
+    {
+        for ( ; first != last ; ++it, ++first, ++count )
+        {
+            if ( max_count <= count )
+                return (std::numeric_limits<std::size_t>::max)();
+
+            // dummy 0 as DisableTrivialInit
+            construct(0, it, *first);                                              // may throw
+        }
+    }
+    BOOST_CATCH(...)
+    {
+        destroy(dest, it);
+        BOOST_RETHROW;
+    }
+    BOOST_CATCH_END
+
+    return count;
+}
+
+// scoped_destructor
+
+template<class T>
+class scoped_destructor
+{
+public:
+    scoped_destructor(T * ptr) : m_ptr(ptr) {}
+
+    ~scoped_destructor()
+    {
+        if(m_ptr)
+            destroy(m_ptr);
+    }
+
+    void release() { m_ptr = 0; }
+
+private:
+    T * m_ptr;
+};
+
+}}} // namespace boost::container::varray_detail
+
+#endif // BOOST_CONTAINER_DETAIL_VARRAY_UTIL_HPP
