Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:16

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Benedek Thaler 2015-2016
0004 // (C) Copyright Ion Gaztanaga 2019-2020. Distributed under the Boost
0005 // Software License, Version 1.0. (See accompanying file
0006 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // See http://www.boost.org/libs/container for documentation.
0009 //
0010 //////////////////////////////////////////////////////////////////////////////
0011 
0012 #ifndef BOOST_CONTAINER_DEVECTOR_HPP
0013 #define BOOST_CONTAINER_DEVECTOR_HPP
0014 
0015 #include <boost/container/detail/config_begin.hpp>
0016 #include <boost/container/detail/workaround.hpp>
0017 
0018 #include <cstring> // memcpy
0019 
0020 #include <boost/assert.hpp>
0021 
0022 #include <boost/container/detail/copy_move_algo.hpp>
0023 #include <boost/container/new_allocator.hpp> //new_allocator
0024 #include <boost/container/allocator_traits.hpp> //allocator_traits
0025 #include <boost/container/detail/algorithm.hpp> //equal()
0026 #include <boost/container/throw_exception.hpp>
0027 #include <boost/container/options.hpp>
0028 
0029 #include <boost/container/detail/guards_dended.hpp>
0030 #include <boost/container/detail/iterator.hpp>
0031 #include <boost/container/detail/iterators.hpp>
0032 #include <boost/container/detail/destroyers.hpp>
0033 #include <boost/container/detail/min_max.hpp>
0034 #include <boost/container/detail/next_capacity.hpp>
0035 #include <boost/container/detail/alloc_helpers.hpp>
0036 #include <boost/container/detail/advanced_insert_int.hpp>
0037 
0038 // move
0039 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0040 #include <boost/move/detail/fwd_macros.hpp>
0041 #endif
0042 #include <boost/move/detail/move_helpers.hpp>
0043 #include <boost/move/adl_move_swap.hpp>
0044 #include <boost/move/iterator.hpp>
0045 #include <boost/move/traits.hpp>
0046 #include <boost/move/utility_core.hpp>
0047 #include <boost/move/detail/to_raw_pointer.hpp>
0048 #include <boost/move/algo/detail/merge.hpp>
0049 #include <boost/move/detail/force_ptr.hpp>
0050 
0051 //std
0052 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0053 #include <initializer_list>    //for std::initializer_list
0054 #endif
0055 
0056 namespace boost {
0057 namespace container {
0058 
0059 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0060 
0061 struct growth_factor_60;
0062 
0063 template<class Options, class AllocatorSizeType>
0064 struct get_devector_opt
0065 {
0066     typedef devector_opt< typename default_if_void<typename Options::growth_factor_type, growth_factor_60>::type
0067                         , typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
0068                         , default_if_zero<Options::free_fraction, relocate_on_90::value>::value
0069                         > type;
0070 };
0071 
0072 template<class AllocatorSizeType>
0073 struct get_devector_opt<void, AllocatorSizeType>
0074 {
0075     typedef devector_opt< growth_factor_60, AllocatorSizeType, relocate_on_90::value> type;
0076 };
0077 
0078 #endif    //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
0079 
0080 struct reserve_only_tag_t {};
0081 struct reserve_uninitialized_t {};
0082 struct review_implementation_t {};
0083 
0084 //struct unsafe_uninitialized_tag_t {};
0085 
0086 /**
0087  * A vector-like sequence container providing front and back operations
0088  * (e.g: `push_front`/`pop_front`/`push_back`/`pop_back`) with amortized constant complexity.
0089  *
0090  * Models the [SequenceContainer], [ReversibleContainer], and [AllocatorAwareContainer] concepts.
0091  *
0092  * **Requires**:
0093  *   - `T` shall be [MoveInsertable] into the devector.
0094  *   - `T` shall be [Erasable] from any `devector<T, allocator_type, GP>`.
0095  *   - `GrowthFactor`, and `Allocator` must model the concepts with the same names or be void.
0096  *
0097  * **Definition**: `T` is `NothrowConstructible` if it's either nothrow move constructible or
0098  * nothrow copy constructible.
0099  *
0100  * **Definition**: `T` is `NothrowAssignable` if it's either nothrow move assignable or
0101  * nothrow copy assignable.
0102  *
0103  * **Exceptions**: The exception specifications assume `T` is nothrow [Destructible].
0104  *
0105  * Most methods providing the strong exception guarantee assume `T` either has a move
0106  * constructor marked noexcept or is [CopyInsertable] into the devector. If it isn't true,
0107  * and the move constructor throws, the guarantee is waived and the effects are unspecified.
0108  *
0109  * In addition to the exceptions specified in the **Throws** clause, the following operations
0110  * of `T` can throw when any of the specified concept is required:
0111  *   - [DefaultInsertable][]: Default constructor
0112  *   - [MoveInsertable][]: Move constructor
0113  *   - [CopyInsertable][]: Copy constructor
0114  *   - [DefaultConstructible][]: Default constructor
0115  *   - [EmplaceConstructible][]: Constructor selected by the given arguments
0116  *   - [MoveAssignable][]: Move assignment operator
0117  *   - [CopyAssignable][]: Copy assignment operator
0118  *
0119  * Furthermore, not `noexcept` methods throws whatever the allocator throws
0120  * if memory allocation fails. Such methods also throw `length_error` if the capacity
0121  * exceeds `max_size()`.
0122  *
0123  * **Remark**: If a method invalidates some iterators, it also invalidates references
0124  * and pointers to the elements pointed by the invalidated iterators.
0125  *
0126  *! \tparam Options A type produced from \c boost::container::devector_options.
0127  *
0128  * [SequenceContainer]: http://en.cppreference.com/w/cpp/concept/SequenceContainer
0129  * [ReversibleContainer]: http://en.cppreference.com/w/cpp/concept/ReversibleContainer
0130  * [AllocatorAwareContainer]: http://en.cppreference.com/w/cpp/concept/AllocatorAwareContainer
0131  * [DefaultInsertable]: http://en.cppreference.com/w/cpp/concept/DefaultInsertable
0132  * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
0133  * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
0134  * [Erasable]: http://en.cppreference.com/w/cpp/concept/Erasable
0135  * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible
0136  * [Destructible]: http://en.cppreference.com/w/cpp/concept/Destructible
0137  * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible
0138  * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable
0139  * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
0140  */
0141 template < typename T, class A BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void)>
0142 class devector
0143 {
0144    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0145    typedef boost::container::allocator_traits
0146       <typename real_allocator<T, A>::type>                                      allocator_traits_type;
0147    typedef typename allocator_traits_type::size_type                             alloc_size_type;
0148    typedef typename get_devector_opt<Options, alloc_size_type>::type             options_type;
0149    typedef typename options_type::growth_factor_type                             growth_factor_type;
0150    typedef typename options_type::stored_size_type                               stored_size_type;
0151    static const std::size_t devector_min_free_fraction =
0152       options_type::free_fraction;
0153 
0154    #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0155 
0156    public:
0157    // Standard Interface Types:
0158    typedef T                                                                     value_type;
0159    typedef BOOST_CONTAINER_IMPDEF
0160       (typename real_allocator<T BOOST_MOVE_I A>::type)                          allocator_type;
0161    typedef allocator_type                                                        stored_allocator_type;
0162    typedef typename    allocator_traits<allocator_type>::pointer                 pointer;
0163    typedef typename    allocator_traits<allocator_type>::const_pointer           const_pointer;
0164    typedef typename    allocator_traits<allocator_type>::reference               reference;
0165    typedef typename    allocator_traits<allocator_type>::const_reference         const_reference;
0166    typedef typename    allocator_traits<allocator_type>::size_type               size_type;
0167    typedef typename    allocator_traits<allocator_type>::difference_type         difference_type;
0168    typedef pointer                                                               iterator;
0169    typedef const_pointer                                                         const_iterator;
0170    typedef BOOST_CONTAINER_IMPDEF
0171       (boost::container::reverse_iterator<iterator>)                             reverse_iterator;
0172    typedef BOOST_CONTAINER_IMPDEF
0173       (boost::container::reverse_iterator<const_iterator>)                       const_reverse_iterator;
0174 
0175    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0176    private:
0177    BOOST_COPYABLE_AND_MOVABLE(devector)
0178 
0179    // Guard to deallocate buffer on exception
0180    typedef typename detail::allocation_guard<allocator_type> allocation_guard;
0181 
0182    // Random access pseudo iterator always yielding to the same result
0183    typedef constant_iterator<T> cvalue_iterator;
0184 
0185    static size_type to_internal_capacity(size_type desired_capacity)
0186    {
0187       const size_type rounder = devector_min_free_fraction - 2u;
0188       const size_type divisor = devector_min_free_fraction - 1u;
0189       size_type const nc = ((desired_capacity + rounder) / divisor) * devector_min_free_fraction;
0190       BOOST_ASSERT(desired_capacity <= (nc - nc / devector_min_free_fraction));
0191       return nc;
0192    }
0193 
0194    #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0195 
0196    // Standard Interface
0197    public:
0198    // construct/copy/destroy
0199 
0200    /**
0201    * **Effects**: Constructs an empty devector.
0202    *
0203    * **Postcondition**: `empty() && front_free_capacity() == 0
0204    * && back_free_capacity() == 0`.
0205    *
0206    * **Complexity**: Constant.
0207    */
0208    devector() BOOST_NOEXCEPT
0209       : m_()
0210    {}
0211 
0212    /**
0213    * **Effects**: Constructs an empty devector, using the specified allocator.
0214    *
0215    * **Postcondition**: `empty() && front_free_capacity() == 0
0216    * && back_free_capacity() == 0`.
0217    *
0218    * **Complexity**: Constant.
0219    */
0220    explicit devector(const allocator_type& allocator) BOOST_NOEXCEPT
0221       : m_(allocator)
0222    {}
0223 
0224    /**
0225    * **Effects**: Constructs an empty devector, using the specified allocator
0226    * and reserves `n` slots as if `reserve(n)` was called.
0227    *
0228    * **Postcondition**: `empty() && capacity() >= n`.
0229    *
0230    * **Exceptions**: Strong exception guarantee.
0231    *
0232    * **Complexity**: Constant.
0233    */
0234    devector(size_type n, reserve_only_tag_t, const allocator_type& allocator = allocator_type())
0235       : m_(reserve_only_tag_t(), allocator, to_internal_capacity(n))
0236    {}
0237 
0238    /**
0239    * **Effects**: Constructs an empty devector, using the specified allocator
0240    * and reserves at least `front_free_cap + back_free_cap` slots as if `reserve_front(front_cap)` and
0241    * `reserve_back(back_cap)` was called.
0242    *
0243    * **Postcondition**: `empty() && front_free_capacity() >= front_free_cap
0244    * && back_free_capacity() >= back_free_cap`.
0245    *
0246    * **Exceptions**: Strong exception guarantee.
0247    *
0248    * **Complexity**: Constant.
0249    */
0250    devector(size_type front_free_cap, size_type back_free_cap, reserve_only_tag_t, const allocator_type& allocator = allocator_type())
0251       : m_(reserve_only_tag_t(), allocator, front_free_cap, back_free_cap)
0252    {}
0253 
0254    /**
0255    * [DefaultInsertable]: http://en.cppreference.com/w/cpp/concept/DefaultInsertable
0256    *
0257    * **Effects**: Constructs a devector with `n` value_initialized elements using the specified allocator.
0258    *
0259    * **Requires**: `T` shall be [DefaultInsertable] into `*this`.
0260    *
0261    * **Postcondition**: `size() == n`.
0262    *
0263    * **Exceptions**: Strong exception guarantee.
0264    *
0265    * **Complexity**: Linear in `n`.
0266    */
0267    explicit devector(size_type n, const allocator_type& allocator = allocator_type())
0268       : m_(reserve_uninitialized_t(), allocator, n)
0269    {
0270       allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref());
0271       boost::container::uninitialized_value_init_alloc_n(get_allocator_ref(), n, this->priv_raw_begin());
0272       buffer_guard.release();
0273       BOOST_ASSERT(invariants_ok());
0274    }
0275 
0276    /**
0277    * **Effects**: Constructs a devector with `n` default-initialized elements using the specified allocator.
0278    *
0279    * **Requires**: `T` shall be [DefaultInsertable] into `*this`.
0280    *
0281    * **Postcondition**: `size() == n`.
0282    *
0283    * **Exceptions**: Strong exception guarantee.
0284    *
0285    * **Complexity**: Linear in `n`.
0286    */
0287    explicit devector(size_type n, default_init_t, const allocator_type& allocator = allocator_type())
0288       : m_(reserve_uninitialized_t(), allocator, n)
0289    {
0290       allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref());
0291       boost::container::uninitialized_default_init_alloc_n(get_allocator_ref(), n, this->priv_raw_begin());
0292       buffer_guard.release();
0293       BOOST_ASSERT(invariants_ok());
0294    }
0295 
0296    /**
0297    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
0298    *
0299    * **Effects**: Constructs a devector with `n` copies of `value`, using the specified allocator.
0300    *
0301    * **Requires**: `T` shall be [CopyInsertable] into `*this`.
0302    *
0303    * **Postcondition**: `size() == n`.
0304    *
0305    * **Exceptions**: Strong exception guarantee.
0306    *
0307    * **Complexity**: Linear in `n`.
0308    */
0309    devector(size_type n, const T& value, const allocator_type& allocator = allocator_type())
0310       : m_(reserve_uninitialized_t(), allocator, n)
0311    {
0312       construct_from_range(cvalue_iterator(value, n), cvalue_iterator());
0313       BOOST_ASSERT(invariants_ok());
0314    }
0315 
0316    /**
0317    * **Effects**: Constructs a devector equal to the range `[first,last)`, using the specified allocator.
0318    *
0319    * **Requires**: `T` shall be [EmplaceConstructible] into `*this` from `*first`. If the specified
0320    * iterator does not meet the forward iterator requirements, `T` shall also be [MoveInsertable]
0321    * into `*this`.
0322    *
0323    * **Postcondition**: `size() == boost::container::iterator_distance(first, last)
0324    *
0325    * **Exceptions**: Strong exception guarantee.
0326    *
0327    * **Complexity**: Makes only `N` calls to the copy constructor of `T` (where `N` is the distance between `first`
0328    * and `last`), at most one allocation and no reallocations if iterators first and last are of forward,
0329    * bidirectional, or random access categories. It makes `O(N)` calls to the copy constructor of `T`
0330    * and `O(log(N)) reallocations if they are just input iterators.
0331    *
0332    * **Remarks**: Each iterator in the range `[first,last)` shall be dereferenced exactly once,
0333    * unless an exception is thrown.
0334    *
0335    * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible
0336    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
0337    */
0338    template <class InputIterator>
0339    devector(InputIterator first, InputIterator last, const allocator_type& allocator = allocator_type()
0340       //Input iterators
0341       BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
0342             < void
0343             BOOST_MOVE_I dtl::is_convertible<InputIterator BOOST_MOVE_I size_type>
0344             BOOST_MOVE_I dtl::is_not_input_iterator<InputIterator>
0345             >::type * = 0)
0346       )
0347       : m_(allocator)
0348    {
0349       BOOST_CONTAINER_TRY{
0350          while (first != last) {
0351             this->emplace_back(*first++);
0352          }
0353          BOOST_ASSERT(invariants_ok());
0354       }
0355       BOOST_CONTAINER_CATCH(...){
0356          this->destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx);
0357          this->deallocate_buffer();
0358       }
0359       BOOST_CONTAINER_CATCH_END
0360    }
0361 
0362    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0363 
0364    template <class ForwardIterator>
0365    devector(ForwardIterator first, ForwardIterator last, const allocator_type& allocator = allocator_type()
0366       //Other iterators
0367       BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
0368             < void
0369             BOOST_MOVE_I dtl::is_convertible<ForwardIterator BOOST_MOVE_I size_type>
0370             BOOST_MOVE_I dtl::is_input_iterator<ForwardIterator>
0371             >::type * = 0)
0372       )
0373       : m_(reserve_uninitialized_t(), allocator, boost::container::iterator_udistance(first, last))
0374    {
0375       this->construct_from_range(first, last);
0376       BOOST_ASSERT(invariants_ok());
0377    }
0378 
0379    #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0380 
0381    /**
0382    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
0383    *
0384    * **Effects**: Copy constructs a devector.
0385    *
0386    * **Requires**: `T` shall be [CopyInsertable] into `*this`.
0387    *
0388    * **Postcondition**: `this->size() == x.size()`.
0389    *
0390    * **Exceptions**: Strong exception guarantee.
0391    *
0392    * **Complexity**: Linear in the size of `x`.
0393    */
0394    devector(const devector& x)
0395       : m_(reserve_uninitialized_t(), allocator_traits_type::select_on_container_copy_construction(x.get_allocator_ref()), x.size())
0396    {
0397       this->construct_from_range(x.begin(), x.end());
0398       BOOST_ASSERT(invariants_ok());
0399    }
0400 
0401    /**
0402    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
0403    *
0404    * **Effects**: Copy constructs a devector, using the specified allocator.
0405    *
0406    * **Requires**: `T` shall be [CopyInsertable] into `*this`.
0407    *
0408    * **Postcondition**: `*this == x`.
0409    *
0410    * **Exceptions**: Strong exception guarantee.
0411    *
0412    * **Complexity**: Linear in the size of `x`.
0413    */
0414    devector(const devector& x, const allocator_type& allocator)
0415       : m_(reserve_uninitialized_t(), allocator, x.size())
0416    {
0417       this->construct_from_range(x.begin(), x.end());
0418       BOOST_ASSERT(invariants_ok());
0419    }
0420 
0421    /**
0422    * **Effects**: Moves `rhs`'s resources to `*this`.
0423    *
0424    * **Throws**: Nothing.
0425    *
0426    * **Postcondition**: *this has the same value `rhs` had before the operation.
0427    *                    `rhs` is left in an unspecified but valid state.
0428    *
0429    * **Exceptions**: Strong exception guarantee if not `noexcept`.
0430    *
0431    * **Complexity**: Constant.
0432    */
0433    devector(BOOST_RV_REF(devector) rhs) BOOST_NOEXCEPT_OR_NOTHROW
0434       : m_(::boost::move(rhs.m_))
0435    {
0436       BOOST_ASSERT(      invariants_ok());
0437       BOOST_ASSERT(rhs.invariants_ok());
0438    }
0439 
0440    /**
0441    * **Effects**: Moves `rhs`'s resources to `*this`, using the specified allocator.
0442    *
0443    * **Throws**: If allocation or T's move constructor throws.
0444    *
0445    * **Postcondition**: *this has the same value `rhs` had before the operation.
0446    *                    `rhs` is left in an unspecified but valid state.
0447    *
0448    * **Exceptions**: Strong exception guarantee if not `noexcept`.
0449    *
0450    * **Complexity**: Linear if allocator != rhs.get_allocator(), otherwise constant.
0451    */
0452    devector(BOOST_RV_REF(devector) rhs, const allocator_type& allocator)
0453       : m_(review_implementation_t(), allocator, rhs.m_.buffer, rhs.m_.front_idx, rhs.m_.back_idx, rhs.m_.capacity)
0454    {
0455       // TODO should move elems-by-elems if the two allocators differ
0456       // buffer is already acquired, reset rhs
0457       rhs.m_.capacity = 0u;
0458       rhs.m_.buffer = pointer();
0459       rhs.m_.front_idx = 0;
0460       rhs.m_.back_idx = 0;
0461       BOOST_ASSERT(      invariants_ok());
0462       BOOST_ASSERT(rhs.invariants_ok());
0463    }
0464 
0465    #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0466    /**
0467    * **Equivalent to**: `devector(il.begin(), il.end(), allocator)`.
0468    */
0469    devector(const std::initializer_list<T>& il, const allocator_type& allocator = allocator_type())
0470       : m_(reserve_uninitialized_t(), allocator, il.size())
0471    {
0472       this->construct_from_range(il.begin(), il.end());
0473       BOOST_ASSERT(invariants_ok());
0474    }
0475    #endif
0476 
0477 /**
0478    * **Effects**: Destroys the devector. All stored values are destroyed and
0479    * used memory, if any, deallocated.
0480    *
0481    * **Complexity**: Linear in the size of `*this`.
0482    */
0483 ~devector() BOOST_NOEXCEPT
0484 {
0485    destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx);
0486    deallocate_buffer();
0487 }
0488 
0489 /**
0490    * **Effects**: Copies elements of `x` to `*this`. Previously
0491    * held elements get copy assigned to or destroyed.
0492    *
0493    * **Requires**: `T` shall be [CopyInsertable] into `*this`.
0494    *
0495    * **Postcondition**: `this->size() == x.size()`, the elements of
0496    * `*this` are copies of elements in `x` in the same order.
0497    *
0498    * **Returns**: `*this`.
0499    *
0500    * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible`
0501    * and the allocator is allowed to be propagated
0502    * ([propagate_on_container_copy_assignment] is true),
0503    * Basic exception guarantee otherwise.
0504    *
0505    * **Complexity**: Linear in the size of `x` and `*this`.
0506    *
0507    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
0508    * [propagate_on_container_copy_assignment]: http://en.cppreference.com/w/cpp/memory/allocator_traits
0509    */
0510 
0511    BOOST_CONTAINER_FORCEINLINE devector& operator=(BOOST_COPY_ASSIGN_REF(devector) rhs)
0512    {
0513       const devector &x = rhs;
0514       if (this == &x) { return *this; } // skip self
0515 
0516       BOOST_IF_CONSTEXPR(allocator_traits_type::propagate_on_container_copy_assignment::value)
0517       {
0518             allocator_type &this_alloc = this->get_allocator_ref();
0519             const allocator_type &other_alloc = x.get_allocator_ref();
0520             if (this_alloc != other_alloc)
0521             {
0522                // new allocator cannot free existing storage
0523                this->clear();
0524                this->deallocate_buffer();
0525                m_.capacity = 0u;
0526                m_.buffer = pointer();
0527             }
0528 
0529             this_alloc = other_alloc;
0530       }
0531 
0532       size_type n = x.size();
0533       if (m_.capacity >= n)
0534       {
0535             this->overwrite_buffer(x.begin(), x.end());
0536       }
0537       else
0538       {
0539             this->allocate_and_copy_range(x.begin(), x.end());
0540       }
0541 
0542       BOOST_ASSERT(invariants_ok());
0543 
0544       return *this;
0545    }
0546 
0547    /**
0548    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
0549    *
0550    * **Effects**: Moves elements of `x` to `*this`. Previously
0551    * held elements get move/copy assigned to or destroyed.
0552    *
0553    * **Requires**: `T` shall be [MoveInsertable] into `*this`.
0554    *
0555    * **Postcondition**: `x` is left in an unspecified but valid state.
0556    *
0557    * **Returns**: `*this`.
0558    *
0559    * **Exceptions**: Basic exception guarantee if not `noexcept`.
0560    *
0561    * **Complexity**: Constant if allocator_traits_type::
0562    *   propagate_on_container_move_assignment is true or
0563    *   this->get>allocator() == x.get_allocator(). Linear otherwise.
0564    */
0565    devector& operator=(BOOST_RV_REF(devector) x)
0566       BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
0567                                  || allocator_traits_type::is_always_equal::value)
0568    {
0569       BOOST_CONSTEXPR_OR_CONST bool copy_alloc = allocator_traits_type::propagate_on_container_move_assignment::value;
0570 
0571       BOOST_IF_CONSTEXPR (copy_alloc || get_allocator_ref() == x.get_allocator_ref())
0572       {
0573          this->clear();
0574          this->deallocate_buffer();
0575 
0576          if (copy_alloc)
0577          {
0578             this->get_allocator_ref() = boost::move(x.get_allocator_ref());
0579          }
0580 
0581          m_.capacity = x.m_.capacity;
0582          m_.buffer = x.m_.buffer;
0583          m_.front_idx = x.m_.front_idx;
0584          m_.back_idx = x.m_.back_idx;
0585 
0586          // leave x in valid state
0587          x.m_.capacity = 0u;
0588          x.m_.buffer = pointer();
0589          x.m_.back_idx = x.m_.front_idx = 0;
0590       }
0591       else
0592       {
0593          // if the allocator shouldn't be copied and they do not compare equal
0594          // we can't steal memory.
0595 
0596          move_iterator<iterator> xbegin = boost::make_move_iterator(x.begin());
0597          move_iterator<iterator> xend = boost::make_move_iterator(x.end());
0598 
0599          if (copy_alloc)
0600          {
0601             get_allocator_ref() = boost::move(x.get_allocator_ref());
0602          }
0603 
0604          if (m_.capacity >= x.size())
0605          {
0606             overwrite_buffer(xbegin, xend);
0607          }
0608          else
0609          {
0610             allocate_and_copy_range(xbegin, xend);
0611          }
0612       }
0613 
0614       BOOST_ASSERT(invariants_ok());
0615 
0616       return *this;
0617    }
0618 
0619    #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0620    /**
0621    * **Effects**: Copies elements of `il` to `*this`. Previously
0622    * held elements get copy assigned to or destroyed.
0623    *
0624    * **Requires**: `T` shall be [CopyInsertable] into `*this` and [CopyAssignable].
0625    *
0626    * **Postcondition**: `this->size() == il.size()`, the elements of
0627    * `*this` are copies of elements in `il` in the same order.
0628    *
0629    * **Exceptions**: Strong exception guarantee if `T` is nothrow copy assignable
0630    * from `T` and `NothrowConstructible`, Basic exception guarantee otherwise.
0631    *
0632    * **Returns**: `*this`.
0633    *
0634    * **Complexity**: Linear in the size of `il` and `*this`.
0635    *
0636    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
0637    * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
0638    */
0639    BOOST_CONTAINER_FORCEINLINE devector& operator=(std::initializer_list<T> il)
0640    {
0641       this->assign(il.begin(), il.end());
0642       return *this;
0643    }
0644    #endif
0645 
0646    /**
0647    * **Effects**: Replaces elements of `*this` with a copy of `[first,last)`.
0648    * Previously held elements get copy assigned to or destroyed.
0649    *
0650    * **Requires**: `T` shall be [EmplaceConstructible] from `*first`. If the specified iterator
0651    * does not meet the forward iterator requirements, `T` shall be also [MoveInsertable] into `*this`.
0652    *
0653    * **Precondition**: `first` and `last` are not iterators into `*this`.
0654    *
0655    * **Postcondition**: `size() == N`, where `N` is the distance between `first` and `last`.
0656    *
0657    * **Exceptions**: Strong exception guarantee if `T` is nothrow copy assignable
0658    * from `*first` and `NothrowConstructible`, Basic exception guarantee otherwise.
0659    *
0660    * **Complexity**: Linear in the distance between `first` and `last`.
0661    * Makes a single reallocation at most if the iterators `first` and `last`
0662    * are of forward, bidirectional, or random access categories. It makes
0663    * `O(log(N))` reallocations if they are just input iterators.
0664    *
0665    * **Remarks**: Each iterator in the range `[first,last)` shall be dereferenced exactly once,
0666    * unless an exception is thrown.
0667    *
0668    * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible
0669    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
0670    */
0671    template <class InputIterator>
0672    void assign(InputIterator first, InputIterator last
0673       //Input iterators
0674       BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
0675             < void
0676             BOOST_MOVE_I dtl::is_convertible<InputIterator BOOST_MOVE_I size_type>
0677             BOOST_MOVE_I dtl::is_not_input_iterator<InputIterator>
0678             >::type * = 0)
0679       )
0680    {
0681       first = overwrite_buffer_impl(first, last, dtl::false_());
0682       while (first != last)
0683       {
0684          this->emplace_back(*first++);
0685       }
0686    }
0687 
0688    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0689 
0690    template <class ForwardIterator>
0691    void assign(ForwardIterator first, ForwardIterator last
0692       //Other iterators
0693       BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
0694             < void
0695             BOOST_MOVE_I dtl::is_convertible<ForwardIterator BOOST_MOVE_I size_type>
0696             BOOST_MOVE_I dtl::is_input_iterator<ForwardIterator>
0697             >::type * = 0)
0698       )
0699    {
0700       const size_type n = boost::container::iterator_udistance(first, last);
0701 
0702       if (m_.capacity >= n)
0703       {
0704          overwrite_buffer(first, last);
0705       }
0706       else
0707       {
0708          allocate_and_copy_range(first, last);
0709       }
0710 
0711       BOOST_ASSERT(invariants_ok());
0712    }
0713 
0714    #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0715 
0716    /**
0717     * **Effects**: Replaces elements of `*this` with `n` copies of `u`.
0718     * Previously held elements get copy assigned to or destroyed.
0719     *
0720     * **Requires**: `T` shall be [CopyInsertable] into `*this` and
0721     * [CopyAssignable].
0722     *
0723     * **Precondition**: `u` is not a reference into `*this`.
0724     *
0725     * **Postcondition**: `size() == n` and the elements of
0726     * `*this` are copies of `u`.
0727     *
0728     * **Exceptions**: Strong exception guarantee if `T` is nothrow copy assignable
0729     * from `u` and `NothrowConstructible`, Basic exception guarantee otherwise.
0730     *
0731     * **Complexity**: Linear in `n` and the size of `*this`.
0732     *
0733     * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
0734     * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
0735     */
0736    BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& u)
0737    {
0738       cvalue_iterator first(u, n);
0739       cvalue_iterator last;
0740       this->assign(first, last);
0741    }
0742 
0743     #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0744     /** **Equivalent to**: `assign(il.begin(), il.end())`. */
0745    BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list<T> il)
0746     {
0747          this->assign(il.begin(), il.end());
0748     }
0749     #endif
0750 
0751    /**
0752     * **Returns**: A copy of the allocator associated with the container.
0753     *
0754     * **Complexity**: Constant.
0755     */
0756    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0757     allocator_type get_allocator() const BOOST_NOEXCEPT
0758    {
0759       return static_cast<const allocator_type&>(m_);
0760    }
0761 
0762    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0763     const allocator_type &get_stored_allocator() const BOOST_NOEXCEPT
0764    {
0765       return static_cast<const allocator_type&>(m_);
0766    }
0767 
0768    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0769          allocator_type &get_stored_allocator() BOOST_NOEXCEPT
0770    {
0771       return static_cast<allocator_type&>(m_);
0772    }
0773 
0774    // iterators
0775 
0776    /**
0777     * **Returns**: A iterator pointing to the first element in the devector,
0778     * or the past the end iterator if the devector is empty.
0779     *
0780     * **Complexity**: Constant.
0781     */
0782    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0783          iterator begin() BOOST_NOEXCEPT
0784    {
0785       return m_.buffer + m_.front_idx;
0786    }
0787 
0788    /**
0789     * **Returns**: A constant iterator pointing to the first element in the devector,
0790     * or the past the end iterator if the devector is empty.
0791     *
0792     * **Complexity**: Constant.
0793     */
0794    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0795     const_iterator begin() const BOOST_NOEXCEPT
0796    {
0797       return m_.buffer + m_.front_idx;
0798    }
0799 
0800    /**
0801     * **Returns**: An iterator pointing past the last element of the container.
0802     *
0803     * **Complexity**: Constant.
0804     */
0805    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0806          iterator end() BOOST_NOEXCEPT
0807    {
0808       return m_.buffer + m_.back_idx;
0809    }
0810 
0811    /**
0812     * **Returns**: A constant iterator pointing past the last element of the container.
0813     *
0814     * **Complexity**: Constant.
0815     */
0816    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0817     const_iterator end() const BOOST_NOEXCEPT
0818    {
0819       return m_.buffer + m_.back_idx;
0820    }
0821 
0822    /**
0823     * **Returns**: A reverse iterator pointing to the first element in the reversed devector,
0824     * or the reverse past the end iterator if the devector is empty.
0825     *
0826     * **Complexity**: Constant.
0827     */
0828    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0829     reverse_iterator rbegin() BOOST_NOEXCEPT
0830    {
0831       return reverse_iterator(m_.buffer + m_.back_idx);
0832    }
0833 
0834    /**
0835     * **Returns**: A constant reverse iterator
0836     * pointing to the first element in the reversed devector,
0837     * or the reverse past the end iterator if the devector is empty.
0838     *
0839     * **Complexity**: Constant.
0840     */
0841    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0842     const_reverse_iterator rbegin() const BOOST_NOEXCEPT
0843    {
0844       return const_reverse_iterator(m_.buffer + m_.back_idx);
0845    }
0846 
0847    /**
0848     * **Returns**: A reverse iterator pointing past the last element in the
0849     * reversed container, or to the beginning of the reversed container if it's empty.
0850     *
0851     * **Complexity**: Constant.
0852     */
0853    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0854     reverse_iterator rend() BOOST_NOEXCEPT
0855    {
0856       return reverse_iterator(m_.buffer + m_.front_idx);
0857    }
0858 
0859    /**
0860     * **Returns**: A constant reverse iterator pointing past the last element in the
0861     * reversed container, or to the beginning of the reversed container if it's empty.
0862     *
0863     * **Complexity**: Constant.
0864     */
0865    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0866     const_reverse_iterator rend() const BOOST_NOEXCEPT
0867    {
0868       return const_reverse_iterator(m_.buffer + m_.front_idx);
0869    }
0870 
0871    /**
0872     * **Returns**: A constant iterator pointing to the first element in the devector,
0873     * or the past the end iterator if the devector is empty.
0874     *
0875     * **Complexity**: Constant.
0876     */
0877    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0878     const_iterator cbegin() const BOOST_NOEXCEPT
0879    {
0880       return m_.buffer + m_.front_idx;
0881    }
0882 
0883    /**
0884     * **Returns**: A constant iterator pointing past the last element of the container.
0885     *
0886     * **Complexity**: Constant.
0887     */
0888    const_iterator cend() const BOOST_NOEXCEPT
0889    {
0890       return m_.buffer + m_.back_idx;
0891    }
0892 
0893    /**
0894     * **Returns**: A constant reverse iterator
0895     * pointing to the first element in the reversed devector,
0896     * or the reverse past the end iterator if the devector is empty.
0897     *
0898     * **Complexity**: Constant.
0899     */
0900    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0901     const_reverse_iterator crbegin() const BOOST_NOEXCEPT
0902    {
0903       return const_reverse_iterator(m_.buffer + m_.back_idx);
0904    }
0905 
0906    /**
0907     * **Returns**: A constant reverse iterator pointing past the last element in the
0908     * reversed container, or to the beginning of the reversed container if it's empty.
0909     *
0910     * **Complexity**: Constant.
0911     */
0912    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0913     const_reverse_iterator crend() const BOOST_NOEXCEPT
0914    {
0915       return const_reverse_iterator(m_.buffer + m_.front_idx);
0916    }
0917 
0918    // capacity
0919 
0920    /**
0921     * **Returns**: True, if `size() == 0`, false otherwise.
0922     *
0923     * **Complexity**: Constant.
0924     */
0925    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0926     bool empty() const BOOST_NOEXCEPT
0927    {
0928       return m_.front_idx == m_.back_idx;
0929    }
0930 
0931    /**
0932     * **Returns**: The number of elements the devector contains.
0933     *
0934     * **Complexity**: Constant.
0935     */
0936    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0937     size_type size() const BOOST_NOEXCEPT
0938    {
0939       return size_type(m_.back_idx - m_.front_idx);
0940    }
0941 
0942    /**
0943     * **Returns**: The maximum number of elements the devector could possibly hold.
0944     *
0945     * **Complexity**: Constant.
0946     */
0947    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0948     size_type max_size() const BOOST_NOEXCEPT
0949    {
0950       size_type alloc_max = allocator_traits_type::max_size(get_allocator_ref());
0951       size_type size_type_max = (size_type)-1;
0952       return (alloc_max <= size_type_max) ? size_type(alloc_max) : size_type_max;
0953    }
0954 
0955    /**
0956    * **Returns**: The *minimum* number of elements that can be inserted into devector using
0957    *   position-based insertions without requiring a reallocation. Note that, unlike in 
0958    *   typical sequence containers like `vector`, `capacity()`, `capacity()` can be smaller than `size()`.
0959    *   This can happen if a user inserts elements in a particular way (usually inserting at
0960    *   front up to front_free_capacity() and at back up to back_free_capacity()).
0961    * 
0962    * **Complexity**: Constant.
0963    */
0964    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0965    size_type capacity() const BOOST_NOEXCEPT
0966    {
0967       size_type const cap_reserve = m_.capacity/devector_min_free_fraction;
0968       return m_.capacity > cap_reserve ? (m_.capacity - cap_reserve) : 0u;
0969    }
0970 
0971    /**
0972     * **Returns**: The total number of elements that can be pushed to the front of the
0973     * devector without requiring reallocation.
0974     *
0975     * **Complexity**: Constant.
0976     */
0977    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0978    size_type front_free_capacity() const BOOST_NOEXCEPT
0979    {
0980       return m_.front_idx;
0981    }
0982 
0983    /**
0984     * **Returns**: The total number of elements that can be pushed to the back of the
0985     * devector without requiring reallocation.
0986     *
0987     * **Complexity**: Constant.
0988     */
0989    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
0990     size_type back_free_capacity() const BOOST_NOEXCEPT
0991    {
0992       return size_type(m_.capacity - m_.back_idx);
0993    }
0994 
0995    /**
0996    * **Effects**: If `sz` is greater than the size of `*this`,
0997    * additional value-initialized elements are inserted. Invalidates iterators
0998    * if reallocation is needed. If `sz` is smaller than than the size of `*this`,
0999    * elements are erased from the extremes.
1000    *
1001    * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible].
1002    *
1003    * **Postcondition**: `sz == size()`.
1004    *
1005    * **Exceptions**: Strong exception guarantee.
1006    *
1007    * **Complexity**: Linear in the size of `*this` and `sz`.
1008    *
1009    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1010    * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible
1011    */
1012    BOOST_CONTAINER_FORCEINLINE void resize(size_type sz)
1013    {
1014       this->resize_back(sz);
1015    }
1016 
1017    /**
1018     * **Effects**: Same as resize(sz) but creates default-initialized
1019     * value-initialized.
1020     */
1021    BOOST_CONTAINER_FORCEINLINE void resize(size_type sz, default_init_t)
1022    {
1023       this->resize_back(sz, default_init);
1024    }
1025 
1026    /**
1027    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1028    *
1029    * **Effects**: If `sz` is greater than the size of `*this`,
1030    * copies of `c` are inserted at extremes.
1031    * If `sz` is smaller than than the size of `*this`,
1032    * elements are popped from the extremes.
1033    *
1034    * **Postcondition**: `sz == size()`.
1035    *
1036    * **Requires**: `T` shall be [CopyInsertable] into `*this`.
1037    *
1038    * **Exceptions**: Strong exception guarantee.
1039    *
1040    * **Complexity**: Linear in the size of `*this` and `sz`.
1041    */
1042    BOOST_CONTAINER_FORCEINLINE void resize(size_type sz, const T& c)
1043    {
1044       this->resize_back(sz, c);
1045    }
1046 
1047    /**
1048     * **Effects**: If `sz` is greater than the size of `*this`,
1049     * additional value-initialized elements are inserted
1050     * to the front. Invalidates iterators if reallocation is needed.
1051     * If `sz` is smaller than than the size of `*this`,
1052     * elements are popped from the front.
1053     *
1054     * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible].
1055     *
1056     * **Postcondition**: `sz == size()`.
1057     *
1058     * **Exceptions**: Strong exception guarantee.
1059     *
1060     * **Complexity**: Linear in the size of `*this` and `sz`.
1061     *
1062     * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1063     * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible
1064     */
1065    BOOST_CONTAINER_FORCEINLINE void resize_front(size_type sz)
1066    {
1067       resize_front_impl(sz);
1068       BOOST_ASSERT(invariants_ok());
1069    }
1070 
1071    /**
1072     * **Effects**: If `sz` is greater than the size of `*this`,
1073     * additional value-initialized elements are inserted
1074     * to the front. Invalidates iterators if reallocation is needed.
1075     * If `sz` is smaller than than the size of `*this`,
1076     * elements are popped from the front.
1077     *
1078     * **Requires**: T shall be [MoveInsertable] into *this and default_initializable.
1079     *
1080     * **Postcondition**: `sz == size()`.
1081     *
1082     * **Exceptions**: Strong exception guarantee.
1083     *
1084     * **Complexity**: Linear in the size of `*this` and `sz`.
1085     *
1086     * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1087     */
1088    BOOST_CONTAINER_FORCEINLINE void resize_front(size_type sz, default_init_t)
1089    {
1090       resize_front_impl(sz, default_init);
1091       BOOST_ASSERT(invariants_ok());
1092    }
1093 
1094    /**
1095     * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1096     *
1097     * **Effects**: If `sz` is greater than the size of `*this`,
1098     * copies of `c` are inserted to the front.
1099     * Invalidates iterators if reallocation is needed.
1100     * If `sz` is smaller than than the size of `*this`,
1101     * elements are popped from the front.
1102     *
1103     * **Postcondition**: `sz == size()`.
1104     *
1105     * **Requires**: `T` shall be [CopyInsertable] into `*this`.
1106     *
1107     * **Exceptions**: Strong exception guarantee.
1108     *
1109     * **Complexity**: Linear in the size of `*this` and `sz`.
1110     */
1111    BOOST_CONTAINER_FORCEINLINE void resize_front(size_type sz, const T& c)
1112    {
1113       resize_front_impl(sz, c);
1114       BOOST_ASSERT(invariants_ok());
1115    }
1116 
1117    /**
1118     * **Effects**: If `sz` is greater than the size of `*this`,
1119     * additional value-initialized elements are inserted
1120     * to the back. Invalidates iterators if reallocation is needed.
1121     * If `sz` is smaller than than the size of `*this`,
1122     * elements are popped from the back.
1123     *
1124     * **Requires**: T shall be [MoveInsertable] into *this and [DefaultConstructible].
1125     *
1126     * **Postcondition**: `sz == size()`.
1127     *
1128     * **Exceptions**: Strong exception guarantee.
1129     *
1130     * **Complexity**: Linear in the size of `*this` and `sz`.
1131     *
1132     * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1133     * [DefaultConstructible]: http://en.cppreference.com/w/cpp/concept/DefaultConstructible
1134     */
1135    BOOST_CONTAINER_FORCEINLINE void resize_back(size_type sz)
1136    {
1137       resize_back_impl(sz);
1138       BOOST_ASSERT(invariants_ok());
1139    }
1140 
1141    /**
1142     * **Effects**: If `sz` is greater than the size of `*this`,
1143     * additional value-initialized elements are inserted
1144     * to the back. Invalidates iterators if reallocation is needed.
1145     * If `sz` is smaller than than the size of `*this`,
1146     * elements are popped from the back.
1147     *
1148     * **Requires**: T shall be [MoveInsertable] into *this and default initializable.
1149     *
1150     * **Postcondition**: `sz == size()`.
1151     *
1152     * **Exceptions**: Strong exception guarantee.
1153     *
1154     * **Complexity**: Linear in the size of `*this` and `sz`.
1155     *
1156     * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1157     */
1158    BOOST_CONTAINER_FORCEINLINE void resize_back(size_type sz, default_init_t)
1159    {
1160       resize_back_impl(sz, default_init);
1161       BOOST_ASSERT(invariants_ok());
1162    }
1163 
1164    /**
1165     * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1166     *
1167     * **Effects**: If `sz` is greater than the size of `*this`,
1168     * copies of `c` are inserted to the back.
1169     * If `sz` is smaller than than the size of `*this`,
1170     * elements are popped from the back.
1171     *
1172     * **Postcondition**: `sz == size()`.
1173     *
1174     * **Requires**: `T` shall be [CopyInsertable] into `*this`.
1175     *
1176     * **Exceptions**: Strong exception guarantee.
1177     *
1178     * **Complexity**: Linear in the size of `*this` and `sz`.
1179     */
1180    BOOST_CONTAINER_FORCEINLINE void resize_back(size_type sz, const T& c)
1181    {
1182       resize_back_impl(sz, c);
1183       BOOST_ASSERT(invariants_ok());
1184    }
1185 
1186    /**
1187     * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1188     *
1189     * **Effects**: Ensures that at least `n` elements can be inserted
1190     * without requiring reallocation, where `n` is `new_capacity - size()`,
1191     * if `n` is positive. Otherwise, there are no effects.
1192     * Invalidates iterators if reallocation is needed.
1193     *
1194     * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1195     *
1196     * **Complexity**: Linear in the size of *this.
1197     *
1198     * **Exceptions**: Strong exception guarantee.
1199     *
1200     * **Throws**: length_error if `new_capacity > max_size()`.
1201     */
1202    BOOST_CONTAINER_FORCEINLINE void reserve(size_type new_capacity)
1203    {
1204       if (this->capacity() < new_capacity) {
1205          const size_type rounder = devector_min_free_fraction - 2u;
1206          const size_type divisor = devector_min_free_fraction - 1u;
1207          size_type const nc = ((new_capacity + rounder)/divisor)*devector_min_free_fraction;
1208          BOOST_ASSERT(new_capacity <= (nc - nc / devector_min_free_fraction));
1209          size_type const sz = this->size();
1210          reallocate_at(nc, (nc-sz)/2u);
1211       }
1212       BOOST_ASSERT(invariants_ok());
1213    }
1214 
1215    /**
1216     * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1217     *
1218     * **Effects**: Ensures that `n` elements can be pushed to the front
1219     * without requiring reallocation, where `n` is `new_capacity - size()`,
1220     * if `n` is positive. Otherwise, there are no effects.
1221     * Invalidates iterators if reallocation is needed.
1222     *
1223     * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1224     *
1225     * **Complexity**: Linear in the size of *this.
1226     *
1227     * **Exceptions**: Strong exception guarantee.
1228     *
1229     * **Throws**: `length_error` if `new_capacity > max_size()`.
1230     */
1231    BOOST_CONTAINER_FORCEINLINE void reserve_front(size_type new_capacity)
1232    {
1233       if (front_capacity() >= new_capacity) { return; }
1234 
1235       reallocate_at(new_capacity + back_free_capacity(), new_capacity - size());
1236 
1237       BOOST_ASSERT(invariants_ok());
1238    }
1239 
1240    /**
1241     * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1242     *
1243     * **Effects**: Ensures that `n` elements can be pushed to the back
1244     * without requiring reallocation, where `n` is `new_capacity - size()`,
1245     * if `n` is positive. Otherwise, there are no effects.
1246     * Invalidates iterators if reallocation is needed.
1247     *
1248     * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1249     *
1250     * **Complexity**: Linear in the size of *this.
1251     *
1252     * **Exceptions**: Strong exception guarantee.
1253     *
1254     * **Throws**: length_error if `new_capacity > max_size()`.
1255     */
1256    BOOST_CONTAINER_FORCEINLINE void reserve_back(size_type new_capacity)
1257    {
1258       if (back_capacity() >= new_capacity) { return; }
1259 
1260       reallocate_at(new_capacity + front_free_capacity(), m_.front_idx);
1261 
1262       BOOST_ASSERT(invariants_ok());
1263    }
1264 
1265 
1266    /**
1267     * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1268     *
1269     * **Effects**: Reduces `capacity()` to `size()`. Invalidates iterators.
1270     *
1271     * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1272     *
1273     * **Exceptions**: Strong exception guarantee.
1274     *
1275     * **Complexity**: Linear in the size of *this.
1276     */
1277    BOOST_CONTAINER_FORCEINLINE void shrink_to_fit()
1278    {
1279       if(this->front_capacity() || this->back_capacity())
1280             this->reallocate_at(size(), 0);
1281    }
1282 
1283    // element access:
1284 
1285    /**
1286     * **Returns**: A reference to the `n`th element in the devector.
1287     *
1288     * **Precondition**: `n < size()`.
1289     *
1290     * **Complexity**: Constant.
1291     */
1292    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1293    reference operator[](size_type n) BOOST_NOEXCEPT
1294    {
1295       BOOST_ASSERT(n < size());
1296       return m_.buffer[m_.front_idx + n];
1297    }
1298 
1299    /**
1300     * **Returns**: A constant reference to the `n`th element in the devector.
1301     *
1302     * **Precondition**: `n < size()`.
1303     *
1304     * **Complexity**: Constant.
1305     */
1306    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1307    const_reference operator[](size_type n) const BOOST_NOEXCEPT
1308    {
1309       BOOST_ASSERT(n < size());
1310       return m_.buffer[m_.front_idx + n];
1311    }
1312 
1313    /**
1314    * **Returns**: A reference to the `n`th element in the devector.
1315    *
1316    * **Throws**: `out_of_range`, if `n >= size()`.
1317    *
1318    * **Complexity**: Constant.
1319    */
1320    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1321       reference at(size_type n)
1322    {
1323       if (size() <= n)
1324             throw_out_of_range("devector::at out of range");
1325       return (*this)[n];
1326    }
1327 
1328    /**
1329    * **Returns**: A constant reference to the `n`th element in the devector.
1330    *
1331    * **Throws**: `out_of_range`, if `n >= size()`.
1332    *
1333    * **Complexity**: Constant.
1334    */
1335    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1336       const_reference at(size_type n) const
1337    {
1338       if (size() <= n)
1339             throw_out_of_range("devector::at out of range");
1340       return (*this)[n];
1341    }
1342 
1343    /**
1344    * **Returns**: A reference to the first element in the devector.
1345    *
1346    * **Precondition**: `!empty()`.
1347    *
1348    * **Complexity**: Constant.
1349    */
1350    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1351       reference front() BOOST_NOEXCEPT
1352    {
1353       BOOST_ASSERT(!empty());
1354 
1355       return m_.buffer[m_.front_idx];
1356    }
1357 
1358    /**
1359    * **Returns**: A constant reference to the first element in the devector.
1360    *
1361    * **Precondition**: `!empty()`.
1362    *
1363    * **Complexity**: Constant.
1364    */
1365    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1366       const_reference front() const BOOST_NOEXCEPT
1367    {
1368       BOOST_ASSERT(!empty());
1369 
1370       return m_.buffer[m_.front_idx];
1371    }
1372 
1373    /**
1374    * **Returns**: A reference to the last element in the devector.
1375    *
1376    * **Precondition**: `!empty()`.
1377    *
1378    * **Complexity**: Constant.
1379    */
1380    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1381       reference back() BOOST_NOEXCEPT
1382    {
1383       BOOST_ASSERT(!empty());
1384 
1385       return m_.buffer[m_.back_idx - 1u];
1386    }
1387 
1388    /**
1389    * **Returns**: A constant reference to the last element in the devector.
1390    *
1391    * **Precondition**: `!empty()`.
1392    *
1393    * **Complexity**: Constant.
1394    */
1395    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1396       const_reference back() const BOOST_NOEXCEPT
1397    {
1398       BOOST_ASSERT(!empty());
1399 
1400       return m_.buffer[m_.back_idx - 1u];
1401    }
1402 
1403    /**
1404    * **Returns**: A pointer to the underlying array serving as element storage.
1405    * The range `[data(); data() + size())` is always valid. For a non-empty devector,
1406    * `data() == &front()`.
1407    *
1408    * **Complexity**: Constant.
1409    */
1410    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1411       T* data() BOOST_NOEXCEPT
1412    {
1413       return boost::movelib::to_raw_pointer(m_.buffer) + m_.front_idx;
1414    }
1415 
1416    /**
1417    * **Returns**: A constant pointer to the underlying array serving as element storage.
1418    * The range `[data(); data() + size())` is always valid. For a non-empty devector,
1419    * `data() == &front()`.
1420    *
1421    * **Complexity**: Constant.
1422    */
1423    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
1424       const T* data() const BOOST_NOEXCEPT
1425    {
1426       return boost::movelib::to_raw_pointer(m_.buffer) + m_.front_idx;
1427    }
1428 
1429    // modifiers:
1430 
1431    /**
1432    * **Effects**: Pushes a new element to the front of the devector.
1433    * The element is constructed in-place, using the perfect forwarded `args`
1434    * as constructor arguments. Invalidates iterators if reallocation is needed.
1435    * (`front_free_capacity() == 0`)
1436    *
1437    * **Requires**: `T` shall be [EmplaceConstructible] from `args` and [MoveInsertable] into `*this`.
1438    *
1439    * **Exceptions**: Strong exception guarantee.
1440    *
1441    * **Complexity**: Amortized constant in the size of `*this`.
1442    * (Constant, if `front_free_capacity() > 0`)
1443    *
1444    * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible
1445    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1446    */
1447    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1448    template <class... Args>
1449    reference emplace_front(Args&&... args)
1450    {
1451       if (BOOST_LIKELY(front_free_capacity() != 0)) // fast path
1452       {
1453          pointer const p = m_.buffer + (m_.front_idx - 1u);
1454          this->alloc_construct(p, boost::forward<Args>(args)...);
1455          --m_.front_idx;
1456          BOOST_ASSERT(invariants_ok());
1457          return *p;
1458       }
1459       else
1460       {
1461          typedef dtl::insert_emplace_proxy<allocator_type, Args...> proxy_t;
1462          return *this->insert_range_slow_path(this->begin(), 1, proxy_t(::boost::forward<Args>(args)...));
1463       }
1464    }
1465 
1466    #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1467 
1468    #define BOOST_CONTAINER_DEVECTOR_EMPLACE_FRONT(N) \
1469    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1470    BOOST_CONTAINER_FORCEINLINE reference emplace_front(BOOST_MOVE_UREF##N)\
1471    {\
1472       if (front_free_capacity())\
1473       {\
1474          pointer const p = m_.buffer + (m_.front_idx - 1u);\
1475          this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1476          --m_.front_idx;\
1477          return *p;\
1478       }\
1479       else\
1480       {\
1481          typedef dtl::insert_emplace_proxy_arg##N<allocator_type BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\
1482          return *this->insert_range_slow_path(this->begin(), 1, proxy_t(BOOST_MOVE_FWD##N));\
1483       }\
1484    }\
1485    //
1486    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_EMPLACE_FRONT)
1487    #undef BOOST_CONTAINER_DEVECTOR_EMPLACE_FRONT
1488 
1489    #endif
1490 
1491    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1492    /**
1493    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1494    *
1495    * **Effects**: Pushes the copy of `x` to the front of the devector.
1496    * Invalidates iterators if reallocation is needed.
1497    * (`front_free_capacity() == 0`)
1498    *
1499    * **Requires**: `T` shall be [CopyInsertable] into `*this`.
1500    *
1501    * **Exceptions**: Strong exception guarantee.
1502    *
1503    * **Complexity**: Amortized constant in the size of `*this`.
1504    * (Constant, if `front_free_capacity() > 0`)
1505    */
1506    void push_front(const T& x);
1507 
1508    /**
1509    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1510    *
1511    * **Effects**: Move constructs a new element at the front of the devector using `x`.
1512    * Invalidates iterators if reallocation is needed.
1513    * (`front_free_capacity() == 0`)
1514    *
1515    * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1516    *
1517    * **Exceptions**: Strong exception guarantee, not regarding the state of `x`.
1518    *
1519    * **Complexity**: Amortized constant in the size of `*this`.
1520    * (Constant, if `front_free_capacity() > 0`)
1521    */
1522    void push_front(T&& x);
1523 
1524    #else
1525    BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
1526    #endif
1527 
1528    /**
1529    * **Effects**: Removes the first element of `*this`.
1530    *
1531    * **Precondition**: `!empty()`.
1532    *
1533    * **Postcondition**: `front_free_capacity()` is incremented by 1.
1534    *
1535    * **Complexity**: Constant.
1536    */
1537    void pop_front() BOOST_NOEXCEPT
1538    {
1539       BOOST_ASSERT(!empty());
1540       allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(m_.buffer + m_.front_idx));
1541       ++m_.front_idx;
1542       BOOST_ASSERT(invariants_ok());
1543    }
1544 
1545    /**
1546    * **Effects**: Pushes a new element to the back of the devector.
1547    * The element is constructed in-place, using the perfect forwarded `args`
1548    * as constructor arguments. Invalidates iterators if reallocation is needed.
1549    * (`back_free_capacity() == 0`)
1550    *
1551    * **Requires**: `T` shall be [EmplaceConstructible] from `args` and [MoveInsertable] into `*this`,
1552    * and [MoveAssignable].
1553    *
1554    * **Exceptions**: Strong exception guarantee.
1555    *
1556    * **Complexity**: Amortized constant in the size of `*this`.
1557    * (Constant, if `back_free_capacity() > 0`)
1558    *
1559    * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible
1560    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1561    * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable
1562    */
1563    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1564    template <class... Args>
1565    BOOST_CONTAINER_FORCEINLINE reference emplace_back(Args&&... args)
1566    {
1567       if (BOOST_LIKELY(this->back_free_capacity() != 0)){
1568          pointer const p = m_.buffer + m_.back_idx;
1569          this->alloc_construct(p, boost::forward<Args>(args)...);
1570          ++m_.back_idx;
1571          BOOST_ASSERT(invariants_ok());
1572          return *p;
1573       }
1574       else {
1575          typedef dtl::insert_emplace_proxy<allocator_type, Args...> proxy_t;
1576          return *this->insert_range_slow_path(this->end(), 1, proxy_t(::boost::forward<Args>(args)...));
1577       }
1578    }
1579 
1580    #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1581 
1582    #define BOOST_CONTAINER_DEVECTOR_EMPLACE_BACK(N) \
1583    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1584    BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_MOVE_UREF##N)\
1585    {\
1586       if (this->back_free_capacity()){\
1587          pointer const p = m_.buffer + m_.back_idx;\
1588          this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1589          ++m_.back_idx;\
1590          return *p;\
1591       }\
1592       else {\
1593          typedef dtl::insert_emplace_proxy_arg##N<allocator_type BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\
1594          return *this->insert_range_slow_path(this->end(), 1, proxy_t(BOOST_MOVE_FWD##N));\
1595       }\
1596    }\
1597    //
1598    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_EMPLACE_BACK)
1599    #undef BOOST_CONTAINER_DEVECTOR_EMPLACE_BACK
1600 
1601    #endif    //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1602 
1603 
1604    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1605    /**
1606    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1607    *
1608    * **Effects**: Pushes the copy of `x` to the back of the devector.
1609    * Invalidates iterators if reallocation is needed.
1610    * (`back_free_capacity() == 0`)
1611    *
1612    * **Requires**: `T` shall be [CopyInsertable] into `*this`.
1613    *
1614    * **Exceptions**: Strong exception guarantee.
1615    *
1616    * **Complexity**: Amortized constant in the size of `*this`.
1617    * (Constant, if `back_free_capacity() > 0`)
1618    */
1619    void push_back(const T& x);
1620 
1621    /**
1622    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1623    *
1624    * **Effects**: Move constructs a new element at the back of the devector using `x`.
1625    * Invalidates iterators if reallocation is needed.
1626    * (`back_free_capacity() == 0`)
1627    *
1628    * **Requires**: `T` shall be [MoveInsertable] into `*this`.
1629    *
1630    * **Exceptions**: Strong exception guarantee, not regarding the state of `x`.
1631    *
1632    * **Complexity**: Amortized constant in the size of `*this`.
1633    * (Constant, if `back_free_capacity() > 0`)
1634    */
1635    void push_back(T&& x);
1636 
1637    #else
1638    BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
1639    #endif
1640 
1641    /**
1642    * **Effects**: Removes the last element of `*this`.
1643    *
1644    * **Precondition**: `!empty()`.
1645    *
1646    * **Postcondition**: `back_free_capacity()` is incremented by 1.
1647    *
1648    * **Complexity**: Constant.
1649    */
1650    void pop_back() BOOST_NOEXCEPT
1651    {
1652       BOOST_ASSERT(! empty());
1653       --m_.back_idx;
1654       allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(m_.buffer + m_.back_idx));
1655       BOOST_ASSERT(invariants_ok());
1656    }
1657 
1658    /**
1659    * **Effects**: Constructs a new element before the element pointed by `position`.
1660    * The element is constructed in-place, using the perfect forwarded `args`
1661    * as constructor arguments. Invalidates iterators if reallocation is needed.
1662    *
1663    * **Requires**: `T` shall be [EmplaceConstructible], and [MoveInsertable] into `*this`,
1664    * and [MoveAssignable].
1665    *
1666    * **Returns**: Iterator pointing to the newly constructed element.
1667    *
1668    * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible`
1669    * and `NothrowAssignable`, Basic exception guarantee otherwise.
1670    *
1671    * **Complexity**: Linear in the size of `*this`.
1672    *
1673    * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible
1674    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1675    * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable
1676    */
1677    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1678    template <class... Args>
1679    iterator emplace(const_iterator position, Args&&... args)
1680    {
1681       BOOST_ASSERT(position >= begin());
1682       BOOST_ASSERT(position <= end());
1683       typedef dtl::insert_emplace_proxy<allocator_type, Args...> proxy_t;
1684       bool prefer_move_back;
1685       if (position == end()){
1686          if(back_free_capacity()) // fast path
1687          {
1688             pointer const p = m_.buffer + m_.back_idx;
1689             this->alloc_construct(p, boost::forward<Args>(args)...);
1690             ++m_.back_idx;
1691             return iterator(p);
1692          }
1693          prefer_move_back = true;
1694       }
1695       else if (position == begin()){
1696          if(front_free_capacity()) // secondary fast path
1697          {
1698             pointer const p = m_.buffer + (m_.front_idx - 1);
1699             this->alloc_construct(p, boost::forward<Args>(args)...);
1700             --m_.front_idx;
1701             return iterator(p);
1702          }
1703          prefer_move_back = false;
1704       }
1705       else{
1706          iterator nonconst_pos = unconst_iterator(position);
1707          prefer_move_back = should_move_back(position);
1708 
1709          if(prefer_move_back){
1710             if(back_free_capacity()){
1711                boost::container::expand_forward_and_insert_nonempty_middle_alloc
1712                   ( get_allocator_ref()
1713                   , boost::movelib::to_raw_pointer(nonconst_pos)
1714                   , this->priv_raw_end()
1715                   , 1, proxy_t(::boost::forward<Args>(args)...));
1716                ++m_.back_idx;
1717                return nonconst_pos;
1718             }
1719          }
1720          else{
1721             if (front_free_capacity()){
1722                boost::container::expand_backward_and_insert_nonempty_middle_alloc
1723                (get_allocator_ref()
1724                   , this->priv_raw_begin()
1725                   , boost::movelib::to_raw_pointer(nonconst_pos)
1726                   , 1, proxy_t(::boost::forward<Args>(args)...));
1727                --m_.front_idx;
1728                return --nonconst_pos;
1729             }
1730          }
1731       }
1732       return this->insert_range_slow_path(position, 1, proxy_t(::boost::forward<Args>(args)...));
1733    }
1734 
1735    #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1736 
1737    #define BOOST_CONTAINER_DEVECTOR_EMPLACE(N) \
1738    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
1739    iterator emplace(const_iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
1740    {\
1741       BOOST_ASSERT(position >= begin());\
1742       BOOST_ASSERT(position <= end());\
1743       typedef dtl::insert_emplace_proxy_arg##N<allocator_type  BOOST_MOVE_I##N BOOST_MOVE_TARG##N> proxy_t;\
1744       bool prefer_move_back;\
1745       if (position == end()){\
1746          if(back_free_capacity())\
1747          {\
1748             pointer const p = m_.buffer + m_.back_idx;\
1749             this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1750             ++m_.back_idx;\
1751             return iterator(p);\
1752          }\
1753          prefer_move_back = true;\
1754       }\
1755       else if (position == begin()){\
1756          if(front_free_capacity())\
1757          {\
1758             pointer const p = m_.buffer + (m_.front_idx - 1);\
1759             this->alloc_construct(p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
1760             --m_.front_idx;\
1761             return iterator(p);\
1762          }\
1763          prefer_move_back = false;\
1764       }\
1765       else{\
1766          iterator nonconst_pos = unconst_iterator(position);\
1767          prefer_move_back = should_move_back(position);\
1768          \
1769          if(prefer_move_back){\
1770             if(back_free_capacity()){\
1771                boost::container::expand_forward_and_insert_nonempty_middle_alloc\
1772                   ( get_allocator_ref()\
1773                   , boost::movelib::to_raw_pointer(nonconst_pos)\
1774                   , this->priv_raw_end()\
1775                   , 1, proxy_t(BOOST_MOVE_FWD##N));\
1776                ++m_.back_idx;\
1777                return nonconst_pos;\
1778             }\
1779          }\
1780          else{\
1781             if (front_free_capacity()){\
1782                boost::container::expand_backward_and_insert_nonempty_middle_alloc\
1783                (get_allocator_ref()\
1784                   , this->priv_raw_begin()\
1785                   , boost::movelib::to_raw_pointer(nonconst_pos)\
1786                   , 1, proxy_t(BOOST_MOVE_FWD##N));\
1787                --m_.front_idx;\
1788                return --nonconst_pos;\
1789             }\
1790          }\
1791       }\
1792       return this->insert_range_slow_path(position, 1, proxy_t(BOOST_MOVE_FWD##N));\
1793    }\
1794    //
1795    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_EMPLACE)
1796    #undef BOOST_CONTAINER_DEVECTOR_EMPLACE
1797 
1798    #endif    //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1799 
1800 
1801    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1802    /**
1803    * **Effects**: Copy constructs a new element before the element pointed by `position`,
1804    * using `x` as constructor argument. Invalidates iterators if reallocation is needed.
1805    *
1806    * **Requires**: `T` shall be [CopyInsertable] into `*this` and and [CopyAssignable].
1807    *
1808    * **Returns**: Iterator pointing to the newly constructed element.
1809    *
1810    * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible`
1811    * and `NothrowAssignable`, Basic exception guarantee otherwise.
1812    *
1813    * **Complexity**: Linear in the size of `*this`.
1814    *
1815    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1816    * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
1817    */
1818    iterator insert(const_iterator position, const T &x);
1819 
1820    /**
1821    * **Effects**: Move constructs a new element before the element pointed by `position`,
1822    * using `x` as constructor argument. Invalidates iterators if reallocation is needed.
1823    *
1824    * **Requires**: `T` shall be [MoveInsertable] into `*this` and and [CopyAssignable].
1825    *
1826    * **Returns**: Iterator pointing to the newly constructed element.
1827    *
1828    * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible`
1829    * and `NothrowAssignable` (not regarding the state of `x`),
1830    * Basic exception guarantee otherwise.
1831    *
1832    * **Complexity**: Linear in the size of `*this`.
1833    *
1834    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1835    * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
1836    */
1837    iterator insert(const_iterator position, T &&x);
1838    #else
1839    BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
1840    #endif
1841 
1842    /**
1843    * **Effects**: Copy constructs `n` elements before the element pointed by `position`,
1844    * using `x` as constructor argument. Invalidates iterators if reallocation is needed.
1845    *
1846    * **Requires**: `T` shall be [CopyInsertable] into `*this` and and [CopyAssignable].
1847    *
1848    * **Returns**: Iterator pointing to the first inserted element, or `position`, if `n` is zero.
1849    *
1850    * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible`
1851    * and `NothrowAssignable`, Basic exception guarantee otherwise.
1852    *
1853    * **Complexity**: Linear in the size of `*this` and `n`.
1854    *
1855    * [CopyInsertable]: http://en.cppreference.com/w/cpp/concept/CopyInsertable
1856    * [CopyAssignable]: http://en.cppreference.com/w/cpp/concept/CopyAssignable
1857    */
1858    BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, size_type n, const T& x)
1859    {
1860       cvalue_iterator first(x, n);
1861       cvalue_iterator last = first + n;
1862       return this->insert_range(position, first, last);
1863    }
1864 
1865    /**
1866    * **Effects**: Copy constructs elements before the element pointed by position
1867    * using each element in the range pointed by `first` and `last` as constructor arguments.
1868    * Invalidates iterators if reallocation is needed.
1869    *
1870    * **Requires**: `T` shall be [EmplaceConstructible] into `*this` from `*first`. If the specified iterator
1871    * does not meet the forward iterator requirements, `T` shall also be [MoveInsertable] into `*this`
1872    * and [MoveAssignable].
1873    *
1874    * **Precondition**: `first` and `last` are not iterators into `*this`.
1875    *
1876    * **Returns**: Iterator pointing to the first inserted element, or `position`, if `first == last`.
1877    *
1878    * **Complexity**: Linear in the size of `*this` and `N` (where `N` is the distance between `first` and `last`).
1879    * Makes only `N` calls to the constructor of `T` and no reallocations if iterators `first` and `last`
1880    * are of forward, bidirectional, or random access categories. It makes 2N calls to the copy constructor of `T`
1881    * and `O(log(N)) reallocations if they are just input iterators.
1882    *
1883    * **Exceptions**: Strong exception guarantee if `T` is `NothrowConstructible`
1884    * and `NothrowAssignable`, Basic exception guarantee otherwise.
1885    *
1886    * **Remarks**: Each iterator in the range `[first,last)` shall be dereferenced exactly once,
1887    * unless an exception is thrown.
1888    *
1889    * [EmplaceConstructible]: http://en.cppreference.com/w/cpp/concept/EmplaceConstructible
1890    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
1891    * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable
1892    */
1893    template <class InputIterator>
1894    iterator insert(const_iterator position, InputIterator first, InputIterator last
1895       //Input iterators
1896       BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
1897             < void
1898             BOOST_MOVE_I dtl::is_convertible<InputIterator BOOST_MOVE_I size_type>
1899             BOOST_MOVE_I dtl::is_not_input_iterator<InputIterator>
1900             >::type * = 0)
1901       )
1902    {
1903       if (position == end())
1904       {
1905          size_type insert_index = size();
1906 
1907          for (; first != last; ++first)
1908          {
1909             this->emplace_back(*first);
1910          }
1911 
1912          return begin() + insert_index;
1913       }
1914       else
1915       {
1916          const size_type insert_index = static_cast<size_type>(position - this->cbegin());
1917          const size_type old_size = static_cast<size_type>(this->size());
1918 
1919          for (; first != last; ++first) {
1920             this->emplace_back(*first);
1921          }
1922          iterator rit (this->begin() + insert_index);
1923          boost::movelib::rotate_gcd(rit, this->begin() + old_size, this->begin() + this->size());
1924          return rit;
1925       }
1926    }
1927 
1928    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1929 
1930    template <class ForwardIterator>
1931    BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, ForwardIterator first, ForwardIterator last
1932       //Other iterators
1933       BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or
1934             < void
1935             BOOST_MOVE_I dtl::is_convertible<ForwardIterator BOOST_MOVE_I size_type>
1936             BOOST_MOVE_I dtl::is_input_iterator<ForwardIterator>
1937             >::type * = 0)
1938       )
1939    {
1940       return insert_range(position, first, last);
1941    }
1942 
1943    #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
1944 
1945    #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
1946    /** **Equivalent to**: `insert(position, il.begin(), il.end())` */
1947    BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, std::initializer_list<T> il)
1948    {
1949       return this->insert(position, il.begin(), il.end());
1950    }
1951    #endif
1952 
1953    /**
1954    * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable
1955    *
1956    * **Effects**: Destroys the element pointed by `position` and removes it from the devector.
1957    * Invalidates iterators.
1958    *
1959    * **Requires**: `T` shall be [MoveAssignable].
1960    *
1961    * **Precondition**: `position` must be in the range of `[begin(), end())`.
1962    *
1963    * **Returns**: Iterator pointing to the element immediately following the erased element
1964    * prior to its erasure. If no such element exists, `end()` is returned.
1965    *
1966    * **Exceptions**: Strong exception guarantee if `T` is `NothrowAssignable`,
1967    * Basic exception guarantee otherwise.
1968    *
1969    * **Complexity**: Linear in half the size of `*this`.
1970    */
1971    iterator erase(const_iterator position)
1972    {
1973       return erase(position, position + 1);
1974    }
1975 
1976    /**
1977    * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable
1978    *
1979    * **Effects**: Destroys the range `[first,last)` and removes it from the devector.
1980    * Invalidates iterators.
1981    *
1982    * **Requires**: `T` shall be [MoveAssignable].
1983    *
1984    * **Precondition**: `[first,last)` must be in the range of `[begin(), end())`.
1985    *
1986    * **Returns**: Iterator pointing to the element pointed to by `last` prior to any elements
1987    * being erased. If no such element exists, `end()` is returned.
1988    *
1989    * **Exceptions**: Strong exception guarantee if `T` is `NothrowAssignable`,
1990    * Basic exception guarantee otherwise.
1991    *
1992    * **Complexity**: Linear in half the size of `*this`
1993    * plus the distance between `first` and `last`.
1994    */
1995    iterator erase(const_iterator first, const_iterator last)
1996    {
1997       iterator nc_first = unconst_iterator(first);
1998       iterator nc_last  = unconst_iterator(last);
1999       return erase(nc_first, nc_last);
2000    }
2001 
2002    /**
2003    * [MoveAssignable]: http://en.cppreference.com/w/cpp/concept/MoveAssignable
2004    *
2005    * **Effects**: Destroys the range `[first,last)` and removes it from the devector.
2006    * Invalidates iterators.
2007    *
2008    * **Requires**: `T` shall be [MoveAssignable].
2009    *
2010    * **Precondition**: `[first,last)` must be in the range of `[begin(), end())`.
2011    *
2012    * **Returns**: Iterator pointing to the element pointed to by `last` prior to any elements
2013    * being erased. If no such element exists, `end()` is returned.
2014    *
2015    * **Exceptions**: Strong exception guarantee if `T` is `NothrowAssignable`,
2016    * Basic exception guarantee otherwise.
2017    *
2018    * **Complexity**: Linear in half the size of `*this`.
2019    */
2020    iterator erase(iterator first, iterator last)
2021    {
2022       size_type front_distance = pos_to_index(last);
2023       size_type back_distance  = size_type(end() - first);
2024       size_type n = boost::container::iterator_udistance(first, last);
2025 
2026       if (front_distance < back_distance)
2027       {
2028             // move n to the right
2029             boost::container::move_backward(begin(), first, last);
2030 
2031             for (iterator i = begin(); i != begin() + n; ++i)
2032             {
2033                allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(i));
2034             }
2035             //n is always less than max stored_size_type
2036             m_.set_front_idx(m_.front_idx + n);
2037 
2038             BOOST_ASSERT(invariants_ok());
2039             return last;
2040       }
2041       else {
2042             // move n to the left
2043             boost::container::move(last, end(), first);
2044 
2045             for (iterator i = end() - n; i != end(); ++i)
2046             {
2047                allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(i));
2048             }
2049             //n is always less than max stored_size_type
2050             m_.set_back_idx(m_.back_idx - n);
2051 
2052             BOOST_ASSERT(invariants_ok());
2053             return first;
2054       }
2055    }
2056 
2057    /**
2058    * [MoveInsertable]: http://en.cppreference.com/w/cpp/concept/MoveInsertable
2059    *
2060    * **Effects**: exchanges the contents of `*this` and `b`.
2061    *
2062    * **Requires**: instances of `T` must be swappable by unqualified call of `swap`
2063    * and `T` must be [MoveInsertable] into `*this`.
2064    *
2065    * **Precondition**: The allocators should allow propagation or should compare equal.
2066    *
2067    * **Exceptions**: Basic exceptions guarantee if not `noexcept`.
2068    *
2069    * **Complexity**: Constant.
2070    */
2071    void swap(devector& b)
2072       BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
2073                                  || allocator_traits_type::is_always_equal::value)
2074    {
2075       BOOST_CONSTEXPR_OR_CONST bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value;
2076       BOOST_ASSERT(propagate_alloc || get_allocator_ref() == b.get_allocator_ref()); // else it's undefined behavior
2077 
2078       swap_big_big(*this, b);
2079 
2080       // swap indices
2081       boost::adl_move_swap(m_.front_idx, b.m_.front_idx);
2082       boost::adl_move_swap(m_.back_idx, b.m_.back_idx);
2083 
2084       //And now swap the allocator
2085       dtl::swap_alloc(this->get_allocator_ref(), b.get_allocator_ref(), dtl::bool_<propagate_alloc>());
2086 
2087       BOOST_ASSERT(   invariants_ok());
2088       BOOST_ASSERT(b.invariants_ok());
2089    }
2090 
2091    /**
2092    * **Effects**: Destroys all elements in the devector.
2093    * Invalidates all references, pointers and iterators to the
2094    * elements of the devector.
2095    *
2096    * **Postcondition**: `empty() && front_free_capacity() == 0
2097    * && back_free_capacity() == old capacity`.
2098    *
2099    * **Complexity**: Linear in the size of `*this`.
2100    *
2101    * **Remarks**: Does not free memory.
2102    */
2103    void clear() BOOST_NOEXCEPT
2104    {
2105       destroy_elements(begin(), end());
2106       m_.front_idx = m_.back_idx = 0;
2107    }
2108 
2109    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2110       friend bool operator==(const devector& x, const devector& y)
2111    {   return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());   }
2112 
2113    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2114       friend bool operator!=(const devector& x, const devector& y)
2115    {   return !(x == y); }
2116 
2117    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2118       friend bool operator< (const devector& x, const devector& y)
2119    {   return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());   }
2120 
2121    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2122       friend bool operator>(const devector& x, const devector& y)
2123    {   return y < x;   }
2124 
2125    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2126       friend bool operator<=(const devector& x, const devector& y)
2127    {   return !(y < x);   }
2128 
2129    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2130       friend bool operator>=(const devector& x, const devector& y)
2131    {   return !(x < y);   }
2132 
2133    BOOST_CONTAINER_FORCEINLINE friend void swap(devector& x, devector& y)
2134       BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
2135                                  || allocator_traits_type::is_always_equal::value)
2136    {   x.swap(y);   }
2137 
2138    private:
2139 
2140    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2141    size_type pos_to_index(const_iterator i) const 
2142    {
2143       return static_cast<size_type>(i - cbegin());
2144    }
2145 
2146    BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE
2147    bool should_move_back(const_iterator i) const 
2148    {
2149       return static_cast<size_type>(this->pos_to_index(i)) >= this->size()/2u;
2150    }
2151 
2152    BOOST_CONTAINER_FORCEINLINE static iterator unconst_iterator(const_iterator i)
2153    {
2154       return boost::intrusive::pointer_traits<pointer>::const_cast_from(i);
2155    }
2156 
2157    BOOST_CONTAINER_FORCEINLINE size_type front_capacity() const
2158    {
2159       return m_.back_idx;
2160    }
2161 
2162    BOOST_CONTAINER_FORCEINLINE size_type back_capacity() const
2163    {
2164       return size_type(m_.capacity - m_.front_idx);
2165    }
2166 
2167    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2168 
2169    BOOST_CONTAINER_FORCEINLINE T* priv_raw_begin() BOOST_NOEXCEPT
2170    {   return boost::movelib::to_raw_pointer(m_.buffer) + m_.front_idx;   }
2171 
2172    BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() BOOST_NOEXCEPT
2173    {   return boost::movelib::to_raw_pointer(m_.buffer) + m_.back_idx;    }
2174 
2175 
2176    template <class U>
2177    BOOST_CONTAINER_FORCEINLINE void priv_push_front(BOOST_FWD_REF(U) u)
2178    {
2179       this->emplace_front(boost::forward<U>(u));
2180    }
2181 
2182    template <class U>
2183    BOOST_CONTAINER_FORCEINLINE void priv_push_back(BOOST_FWD_REF(U) u)
2184    {
2185       this->emplace_back(boost::forward<U>(u));
2186    }
2187 
2188    template <class U>
2189    BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator pos, BOOST_FWD_REF(U) u)
2190    {
2191       return this->emplace(pos, boost::forward<U>(u));
2192    }
2193 
2194    // allocator_type wrappers
2195 
2196    BOOST_CONTAINER_FORCEINLINE allocator_type& get_allocator_ref() BOOST_NOEXCEPT
2197    {
2198       return static_cast<allocator_type&>(m_);
2199    }
2200 
2201    BOOST_CONTAINER_FORCEINLINE const allocator_type& get_allocator_ref() const BOOST_NOEXCEPT
2202    {
2203       return static_cast<const allocator_type&>(m_);
2204    }
2205 
2206    pointer allocate(size_type capacity)
2207    {
2208       pointer const p = impl::do_allocate(get_allocator_ref(), capacity);
2209       #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2210       ++m_.capacity_alloc_count;
2211       #endif // BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2212       return p;
2213    }
2214 
2215    void destroy_elements(pointer begin, pointer end)
2216    {
2217       for (; begin != end; ++begin)
2218       {
2219          allocator_traits_type::destroy(get_allocator_ref(), boost::movelib::to_raw_pointer(begin));
2220       }
2221    }
2222 
2223    void deallocate_buffer()
2224    {
2225       if (m_.buffer)
2226       {
2227          allocator_traits_type::deallocate(get_allocator_ref(), m_.buffer, m_.capacity);
2228       }
2229    }
2230 
2231    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2232    template <typename... Args>
2233    BOOST_CONTAINER_FORCEINLINE void alloc_construct(pointer dst, Args&&... args)
2234    {
2235       allocator_traits_type::construct(
2236             get_allocator_ref(),
2237             boost::movelib::to_raw_pointer(dst),
2238             boost::forward<Args>(args)...
2239       );
2240    }
2241 
2242    template <typename... Args>
2243    void construct_n(pointer buffer, size_type n, Args&&... args)
2244    {
2245       detail::construction_guard<allocator_type> ctr_guard(buffer, get_allocator_ref());
2246       guarded_construct_n(buffer, n, ctr_guard, boost::forward<Args>(args)...);
2247       ctr_guard.release();
2248    }
2249 
2250    template <typename... Args>
2251    void guarded_construct_n(pointer buffer, size_type n, detail::construction_guard<allocator_type>& ctr_guard, Args&&... args)
2252    {
2253       for (size_type i = 0; i < n; ++i) {
2254          this->alloc_construct(buffer + i, boost::forward<Args>(args)...);
2255          ctr_guard.extend();
2256       }
2257    }
2258 
2259    #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2260 
2261    #define BOOST_CONTAINER_DEVECTOR_ALLOC_CONSTRUCT(N) \
2262    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2263    BOOST_CONTAINER_FORCEINLINE void alloc_construct(pointer dst BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2264    {\
2265       allocator_traits_type::construct(\
2266             get_allocator_ref(), boost::movelib::to_raw_pointer(dst) BOOST_MOVE_I##N BOOST_MOVE_FWD##N );\
2267    }\
2268    \
2269    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2270    void construct_n(pointer buffer, size_type n BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2271    {\
2272       detail::construction_guard<allocator_type> ctr_guard(buffer, get_allocator_ref());\
2273       guarded_construct_n(buffer, n, ctr_guard BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2274       ctr_guard.release();\
2275    }\
2276    \
2277    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2278    void guarded_construct_n(pointer buffer, size_type n, detail::construction_guard<allocator_type>& ctr_guard BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2279    {\
2280       for (size_type i = 0; i < n; ++i) {\
2281             this->alloc_construct(buffer + i BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2282             ctr_guard.extend();\
2283       }\
2284    }
2285    //
2286    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_ALLOC_CONSTRUCT)
2287    #undef BOOST_CONTAINER_DEVECTOR_ALLOC_CONSTRUCT
2288 
2289    #endif    //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2290 
2291    size_type calculate_new_capacity(size_type requested_capacity)
2292    {
2293       size_type max = allocator_traits_type::max_size(this->get_allocator_ref());
2294       (clamp_by_stored_size_type)(max, stored_size_type());
2295       const size_type remaining_additional_cap = max - size_type(m_.capacity);
2296       const size_type min_additional_cap = requested_capacity - size_type(m_.capacity);
2297       if ( remaining_additional_cap < min_additional_cap )
2298             boost::container::throw_length_error("devector: get_next_capacity, max size exceeded");
2299 
2300       return growth_factor_type()( size_type(m_.capacity), min_additional_cap, max);
2301    }
2302 
2303    void buffer_move_or_copy(pointer dst)
2304    {
2305       detail::construction_guard<allocator_type> guard(dst, get_allocator_ref());
2306 
2307       buffer_move_or_copy(dst, guard);
2308 
2309       guard.release();
2310    }
2311 
2312    void buffer_move_or_copy(pointer dst, detail::construction_guard<allocator_type>& guard)
2313    {
2314       opt_move_or_copy(begin(), end(), dst, guard);
2315 
2316       destroy_elements(data(), data() + size());
2317       deallocate_buffer();
2318    }
2319 
2320    template <typename Guard>
2321    void opt_move_or_copy(pointer begin, pointer end, pointer dst, Guard& guard)
2322    {
2323       // if trivial copy and default allocator, memcpy
2324       boost::container::uninitialized_move_alloc(get_allocator_ref(), begin, end, dst);
2325       guard.extend();
2326    }
2327 
2328    #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2329 
2330    template <typename... Args>
2331    void resize_impl(size_type sz, Args&&... args)
2332    {
2333       const size_type old_sz = this->size();
2334       if (sz > old_sz)
2335       {
2336          const size_type n = sz - old_sz;
2337 
2338          if (sz <= m_.capacity)
2339          {
2340             //Construct at back
2341             const size_type bfc = this->back_free_capacity();
2342             const size_type b = n < bfc ? n : bfc;
2343             construct_n(m_.buffer + m_.back_idx, b, boost::forward<Args>(args)...);
2344             m_.set_back_idx(m_.back_idx + b);
2345 
2346             //Construct remaining at front
2347             const size_type f = n - b;
2348             construct_n(m_.buffer + m_.front_idx - f, f, boost::forward<Args>(args)...);
2349             m_.set_front_idx(m_.front_idx - f);
2350          }
2351          else
2352          {
2353             resize_back_slow_path(sz, n, boost::forward<Args>(args)...);
2354          }
2355       }
2356       else
2357       {
2358          const size_type n = old_sz - sz;
2359          const size_type new_bidx = m_.back_idx - n;
2360          destroy_elements(m_.buffer + new_bidx, m_.buffer + m_.back_idx);
2361          m_.set_back_idx(new_bidx);
2362       }
2363    }
2364 
2365    template <typename... Args>
2366    void resize_front_impl(size_type sz , Args&&... args)
2367    {
2368       const size_type old_sz = this->size();
2369       if (sz > old_sz)
2370       {
2371          const size_type n = sz - old_sz;
2372 
2373          if (sz <= this->front_capacity())
2374          {
2375             construct_n(m_.buffer + m_.front_idx - n, n, boost::forward<Args>(args)...);
2376             m_.set_front_idx(m_.front_idx - n);
2377          }
2378          else
2379          {
2380             resize_front_slow_path(sz, n, boost::forward<Args>(args)...);
2381          }
2382       }
2383       else {
2384          const size_type n = old_sz - sz;
2385          const size_type new_fidx = m_.front_idx + n;
2386          destroy_elements(m_.buffer + m_.front_idx, m_.buffer + new_fidx);
2387          m_.set_front_idx(new_fidx);
2388       }
2389    }
2390 
2391    template <typename... Args>
2392    void resize_front_slow_path(size_type sz, size_type n, Args&&... args)
2393    {
2394       const size_type new_capacity = calculate_new_capacity(sz + back_free_capacity());
2395       pointer new_buffer = allocate(new_capacity);
2396       allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2397 
2398       const size_type old_sz = this->size();
2399       const size_type new_old_elem_index = new_capacity - old_sz;
2400       const size_type new_elem_index = new_old_elem_index - n;
2401 
2402       detail::construction_guard<allocator_type> guard(new_buffer + new_elem_index, get_allocator_ref());
2403       guarded_construct_n(new_buffer + new_elem_index, n, guard, boost::forward<Args>(args)...);
2404 
2405       buffer_move_or_copy(new_buffer + new_old_elem_index, guard);
2406 
2407       guard.release();
2408       new_buffer_guard.release();
2409 
2410       m_.buffer = new_buffer;
2411       m_.set_capacity(new_capacity);
2412       m_.set_front_idx(new_elem_index);
2413       m_.set_back_idx(new_elem_index + old_sz + n);
2414    }
2415 
2416    template <typename... Args>
2417    void resize_back_impl(size_type sz, Args&&... args)
2418    {
2419       const size_type old_sz = this->size();
2420       if (sz > old_sz)
2421       {
2422          const size_type n = sz - old_sz;
2423 
2424          if (sz <= this->back_capacity())
2425          {
2426             construct_n(m_.buffer + m_.back_idx, n, boost::forward<Args>(args)...);
2427             m_.set_back_idx(m_.back_idx + n);
2428          }
2429          else
2430          {
2431             resize_back_slow_path(sz, n, boost::forward<Args>(args)...);
2432          }
2433       }
2434       else
2435       {
2436          const size_type n = old_sz - sz;
2437          const size_type new_bidx = m_.back_idx - n;
2438          destroy_elements(m_.buffer + new_bidx, m_.buffer + m_.back_idx);
2439          m_.set_back_idx(new_bidx);
2440       }
2441    }
2442 
2443    template <typename... Args>
2444    void resize_back_slow_path(size_type sz, size_type n, Args&&... args)
2445    {
2446       const size_type new_capacity = calculate_new_capacity(sz + front_free_capacity());
2447       pointer new_buffer = allocate(new_capacity);
2448       allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2449 
2450       detail::construction_guard<allocator_type> guard(new_buffer + m_.back_idx, get_allocator_ref());
2451       guarded_construct_n(new_buffer + m_.back_idx, n, guard, boost::forward<Args>(args)...);
2452 
2453       buffer_move_or_copy(new_buffer + m_.front_idx);
2454 
2455       guard.release();
2456       new_buffer_guard.release();
2457 
2458       m_.buffer = new_buffer;
2459       m_.set_capacity(new_capacity);
2460       m_.set_back_idx(m_.back_idx + n);
2461    }
2462 
2463    #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2464 
2465    #define BOOST_CONTAINER_DEVECTOR_SLOW_PATH(N) \
2466    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2467    void resize_front_impl(size_type sz BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2468    {\
2469       if (sz > size())\
2470       {\
2471          const size_type n = sz - size();\
2472          if (sz <= front_capacity()){\
2473             construct_n(m_.buffer + m_.front_idx - n, n BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2474             m_.set_front_idx(m_.front_idx - n);\
2475          }\
2476          else\
2477          {\
2478             resize_front_slow_path(sz, n BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2479          }\
2480       }\
2481       else {\
2482          while (this->size() > sz)\
2483          {\
2484             this->pop_front();\
2485          }\
2486       }\
2487    }\
2488    \
2489    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2490    void resize_front_slow_path(size_type sz, size_type n BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2491    {\
2492       const size_type new_capacity = calculate_new_capacity(sz + back_free_capacity());\
2493       pointer new_buffer = allocate(new_capacity);\
2494       allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());\
2495    \
2496       const size_type new_old_elem_index = new_capacity - size();\
2497       const size_type new_elem_index = new_old_elem_index - n;\
2498    \
2499       detail::construction_guard<allocator_type> guard(new_buffer + new_elem_index, get_allocator_ref());\
2500       guarded_construct_n(new_buffer + new_elem_index, n, guard BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2501    \
2502       buffer_move_or_copy(new_buffer + new_old_elem_index, guard);\
2503    \
2504       guard.release();\
2505       new_buffer_guard.release();\
2506       m_.buffer = new_buffer;\
2507       m_.set_capacity(new_capacity);\
2508       m_.set_back_idx(new_old_elem_index + m_.back_idx - m_.front_idx);\
2509       m_.set_front_idx(new_elem_index);\
2510    }\
2511    \
2512    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2513    void resize_back_impl(size_type sz BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2514    {\
2515       if (sz > size())\
2516       {\
2517          const size_type n = sz - size();\
2518       \
2519          if (sz <= back_capacity())\
2520          {\
2521             construct_n(m_.buffer + m_.back_idx, n BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2522             m_.set_back_idx(m_.back_idx + n);\
2523          }\
2524          else\
2525          {\
2526             resize_back_slow_path(sz, n BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2527          }\
2528       }\
2529       else\
2530       {\
2531          while (size() > sz)\
2532          {\
2533             pop_back();\
2534          }\
2535       }\
2536    }\
2537    \
2538    BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
2539    void resize_back_slow_path(size_type sz, size_type n BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
2540    {\
2541       const size_type new_capacity = calculate_new_capacity(sz + front_free_capacity());\
2542       pointer new_buffer = allocate(new_capacity);\
2543       allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());\
2544    \
2545       detail::construction_guard<allocator_type> guard(new_buffer + m_.back_idx, get_allocator_ref());\
2546       guarded_construct_n(new_buffer + m_.back_idx, n, guard BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
2547    \
2548       buffer_move_or_copy(new_buffer + m_.front_idx);\
2549    \
2550       guard.release();\
2551       new_buffer_guard.release();\
2552    \
2553       m_.buffer = new_buffer;\
2554       m_.set_capacity(new_capacity);\
2555       m_.set_back_idx(m_.back_idx + n);\
2556    }\
2557    \
2558    //
2559    BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEVECTOR_SLOW_PATH)
2560    #undef BOOST_CONTAINER_DEVECTOR_SLOW_PATH
2561 
2562    #endif    //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
2563 
2564    void reallocate_at(size_type new_capacity, size_type buffer_offset)
2565    {
2566       pointer new_buffer = allocate(new_capacity);
2567       {
2568          allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2569          boost::container::uninitialized_move_alloc(get_allocator_ref(), this->begin(), this->end(), new_buffer + buffer_offset);
2570          new_buffer_guard.release();
2571       }
2572       destroy_elements(m_.buffer + m_.front_idx, m_.buffer + m_.back_idx);
2573       deallocate_buffer();
2574 
2575       m_.buffer = new_buffer;
2576       //Safe cast, allocate() will handle stored_size_type overflow
2577       m_.set_capacity(new_capacity);
2578       m_.set_back_idx(size_type(m_.back_idx - m_.front_idx) + buffer_offset);
2579       m_.set_front_idx(buffer_offset);
2580 
2581       BOOST_ASSERT(invariants_ok());
2582    }
2583 
2584    template <typename ForwardIterator>
2585    iterator insert_range(const_iterator position, ForwardIterator first, ForwardIterator last)
2586    {
2587       BOOST_ASSERT(position >= begin());
2588       BOOST_ASSERT(position <= end());
2589       typedef dtl::insert_range_proxy<allocator_type, ForwardIterator> proxy_t;
2590 
2591       size_type const n = boost::container::iterator_udistance(first, last);
2592       bool prefer_move_back;
2593       if (BOOST_UNLIKELY(!n)) {
2594          return begin() + size_type(position - cbegin());
2595       }
2596       else if (position == end()) {
2597          if(back_free_capacity() >= n) // fast path
2598          {
2599             iterator r(this->end());
2600             boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->priv_raw_end());
2601             m_.set_back_idx(m_.back_idx + n);
2602             return r;
2603          }
2604          prefer_move_back = true;
2605       }
2606       else if (position == begin()) {
2607          if(front_free_capacity() >= n) {// secondary fast path
2608             boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, this->priv_raw_begin() - n);
2609             m_.set_front_idx(m_.front_idx - n);
2610             return begin();
2611          }
2612          prefer_move_back = false;
2613       }
2614       else{
2615          iterator nonconst_pos = unconst_iterator(position);
2616          prefer_move_back = should_move_back(position);
2617 
2618          if(prefer_move_back){
2619             if(back_free_capacity() >= n){
2620                boost::container::expand_forward_and_insert_nonempty_middle_alloc
2621                   ( get_allocator_ref()
2622                   , boost::movelib::to_raw_pointer(nonconst_pos)
2623                   , this->priv_raw_end()
2624                   , n, proxy_t(first));
2625                m_.set_back_idx(m_.back_idx + n);
2626                return nonconst_pos;
2627             }
2628          }
2629          else{
2630             if (front_free_capacity() >= n){
2631                boost::container::expand_backward_and_insert_nonempty_middle_alloc
2632                   ( get_allocator_ref()
2633                   , this->priv_raw_begin()
2634                   , boost::movelib::to_raw_pointer(nonconst_pos)
2635                   , n, proxy_t(first));
2636                m_.set_front_idx(m_.front_idx - n);
2637                return (nonconst_pos -= n);
2638             }
2639          }
2640       }
2641       return this->insert_range_slow_path(position, n, proxy_t(first));
2642    }
2643 
2644    template <class InsertionProxy>
2645    BOOST_CONTAINER_NOINLINE iterator insert_range_slow_path
2646       (const_iterator p, const size_type n, const InsertionProxy proxy)
2647    {
2648       size_type const back_free_cap = back_free_capacity();
2649       size_type const front_free_cap = front_free_capacity();
2650       size_type const free_cap = front_free_cap + back_free_cap;
2651       size_type const index = size_type(p - cbegin());
2652 
2653       size_type const cap = m_.capacity;
2654       //Test if enough free memory would be left
2655       if (free_cap >= n && (free_cap - n) >= cap/devector_min_free_fraction) {
2656          //Make sure relocation is happening because there was no enough space
2657          size_type const old_size = this->size();
2658          BOOST_ASSERT(should_move_back(p) ? (back_free_cap < n) : (front_free_cap < n));
2659 
2660          T* const raw_pos = const_cast<T*>(boost::movelib::to_raw_pointer(p));
2661          size_type const new_size = old_size + n;
2662          size_type const new_front_idx = (cap - new_size) / 2u;
2663 
2664          T* const raw_beg = this->priv_raw_begin();
2665          T* const new_raw_beg = raw_beg - std::ptrdiff_t(m_.front_idx - new_front_idx);
2666          m_.back_idx = 0u;
2667          m_.front_idx = 0u;
2668          boost::container::expand_backward_forward_and_insert_alloc
2669             (raw_beg, old_size, new_raw_beg, raw_pos, n, proxy, get_allocator_ref());
2670          m_.set_front_idx(new_front_idx);
2671          m_.set_back_idx(new_front_idx + new_size);
2672       }
2673       else {
2674          // reallocate
2675          const size_type new_capacity = calculate_new_capacity(m_.capacity + n);
2676          pointer new_buffer = allocate(new_capacity);
2677 
2678          // guard allocation
2679          allocation_guard new_buffer_guard(new_buffer, new_capacity, get_allocator_ref());
2680 
2681          size_type const old_size = this->size();
2682          const size_type new_front_index = (new_capacity - old_size - n) / 2u;
2683 
2684          T* const raw_pos = const_cast<T*>(boost::movelib::to_raw_pointer(p));
2685          T* const raw_new_start = const_cast<T*>(boost::movelib::to_raw_pointer(new_buffer)) + new_front_index;
2686 
2687          boost::container::uninitialized_move_and_insert_alloc
2688             (get_allocator_ref(), this->priv_raw_begin(), raw_pos, this->priv_raw_end(), raw_new_start, n, proxy);
2689          new_buffer_guard.release();
2690 
2691          // cleanup
2692          destroy_elements(begin(), end());
2693          deallocate_buffer();
2694 
2695          // rebind members
2696          m_.set_capacity(new_capacity);
2697          m_.buffer = new_buffer;
2698          m_.set_back_idx(new_front_index + old_size + n);
2699          m_.set_front_idx(new_front_index);
2700       }
2701       return begin() + index;
2702    }
2703 
2704 
2705    template <typename Iterator>
2706    void construct_from_range(Iterator begin, Iterator end)
2707    {
2708       allocation_guard buffer_guard(m_.buffer, m_.capacity, get_allocator_ref());
2709       boost::container::uninitialized_copy_alloc(get_allocator_ref(), begin, end, m_.buffer);
2710       buffer_guard.release();
2711    }
2712 
2713    template <typename ForwardIterator>
2714    void allocate_and_copy_range(ForwardIterator first, ForwardIterator last)
2715    {
2716       size_type n = boost::container::iterator_udistance(first, last);
2717 
2718       pointer new_buffer = n ? allocate(n) : pointer();
2719       allocation_guard new_buffer_guard(new_buffer, n, get_allocator_ref());
2720       boost::container::uninitialized_copy_alloc(get_allocator_ref(), first, last, new_buffer);
2721       destroy_elements(begin(), end());
2722       deallocate_buffer();
2723 
2724       m_.set_capacity(n);
2725       m_.buffer = new_buffer;
2726       m_.front_idx = 0;
2727       m_.set_back_idx(n);
2728 
2729       new_buffer_guard.release();
2730    }
2731 
2732    static void swap_big_big(devector& a, devector& b) BOOST_NOEXCEPT
2733    {
2734       boost::adl_move_swap(a.m_.capacity, b.m_.capacity);
2735       boost::adl_move_swap(a.m_.buffer, b.m_.buffer);
2736    }
2737 
2738    template <typename ForwardIterator>
2739    void overwrite_buffer_impl(ForwardIterator first, ForwardIterator last, dtl::true_)
2740    {
2741       const size_type n = boost::container::iterator_udistance(first, last);
2742 
2743       BOOST_ASSERT(m_.capacity >= n);
2744       boost::container::uninitialized_copy_alloc_n
2745             ( get_allocator_ref(), first
2746             , n, boost::movelib::to_raw_pointer(m_.buffer));
2747       m_.front_idx = 0;
2748       m_.set_back_idx(n);
2749    }
2750 
2751    template <typename InputIterator>
2752    InputIterator overwrite_buffer_impl(InputIterator first, InputIterator last, dtl::false_)
2753    {
2754       pointer pos = m_.buffer;
2755       detail::construction_guard<allocator_type> front_guard(pos, get_allocator_ref());
2756 
2757       while (first != last && pos != begin()) {
2758          this->alloc_construct(pos++, *first++);
2759          front_guard.extend();
2760       }
2761 
2762       while (first != last && pos != end()) {
2763          *pos++ = *first++;
2764       }
2765 
2766       detail::construction_guard<allocator_type> back_guard(pos, get_allocator_ref());
2767 
2768       iterator capacity_end = m_.buffer + m_.capacity;
2769       while (first != last && pos != capacity_end) {
2770          this->alloc_construct(pos++, *first++);
2771          back_guard.extend();
2772       }
2773 
2774       pointer destroy_after = dtl::min_value(dtl::max_value(begin(), pos), end());
2775       destroy_elements(destroy_after, end());
2776 
2777       front_guard.release();
2778       back_guard.release();
2779 
2780       m_.front_idx = 0;
2781       m_.set_back_idx(pos_to_index(pos));
2782       return first;
2783    }
2784 
2785    template <typename ForwardIterator>
2786    BOOST_CONTAINER_FORCEINLINE void overwrite_buffer(ForwardIterator first, ForwardIterator last)
2787    {
2788       this->overwrite_buffer_impl(first, last, 
2789             dtl::bool_<dtl::is_trivially_destructible<T>::value>());
2790    }
2791 
2792    bool invariants_ok()
2793    {
2794       return  (! m_.capacity || m_.buffer )
2795               && m_.front_idx <= m_.back_idx
2796               && m_.back_idx <= m_.capacity;
2797    }
2798 
2799    struct impl : allocator_type
2800    {
2801       BOOST_MOVABLE_BUT_NOT_COPYABLE(impl)
2802 
2803       public:
2804       allocator_type &get_al()
2805       {   return *this;   }
2806 
2807       static pointer do_allocate(allocator_type &a, size_type cap)
2808       {
2809          if (cap) {
2810             //First detect overflow on smaller stored_size_types
2811             if (cap > stored_size_type(-1)){
2812                   boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
2813             }
2814             return allocator_traits_type::allocate(a, cap);
2815          }
2816          else {
2817             return pointer();
2818          }
2819       }
2820 
2821       impl()
2822          : allocator_type(), buffer(), front_idx(), back_idx(), capacity()
2823          #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2824          , capacity_alloc_count(0)
2825          #endif
2826       {}
2827 
2828       explicit impl(const allocator_type &a)
2829          : allocator_type(a), buffer(), front_idx(), back_idx(), capacity()
2830          #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2831          , capacity_alloc_count(0)
2832          #endif
2833       {}
2834 
2835       impl(reserve_uninitialized_t, const allocator_type& a, size_type c)
2836          : allocator_type(a), buffer(do_allocate(get_al(), c) )
2837          //static cast sizes, as the allocation function will take care of overflows
2838          , front_idx(static_cast<stored_size_type>(0u))
2839          , back_idx(static_cast<stored_size_type>(c))
2840          , capacity(static_cast<stored_size_type>(c))
2841          #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2842          , capacity_alloc_count(size_type(buffer != pointer()))
2843          #endif
2844       {}
2845 
2846       impl(reserve_only_tag_t, const allocator_type &a, size_type const ffc, size_type const bfc)
2847          : allocator_type(a), buffer(do_allocate(get_al(), ffc+bfc) )
2848          //static cast sizes, as the allocation function will take care of overflows
2849          , front_idx(static_cast<stored_size_type>(ffc))
2850          , back_idx(static_cast<stored_size_type>(ffc))
2851          , capacity(static_cast<stored_size_type>(ffc + bfc))
2852          #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2853          , capacity_alloc_count(size_type(buffer != pointer()))
2854          #endif
2855       {}
2856 
2857       impl(reserve_only_tag_t, const allocator_type &a, size_type const c)
2858          : allocator_type(a), buffer(do_allocate(get_al(), c) )
2859          //static cast sizes, as the allocation function will take care of overflows
2860          , front_idx(static_cast<stored_size_type>(c/2u))
2861          , back_idx(static_cast<stored_size_type>(c/2u))
2862          , capacity(static_cast<stored_size_type>(c))
2863          #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2864          , capacity_alloc_count(size_type(buffer != pointer()))
2865          #endif
2866       {}
2867 
2868       impl(review_implementation_t, const allocator_type &a, pointer p, size_type fi, size_type bi, size_type c)
2869          : allocator_type(a), buffer(p)
2870          //static cast sizes, as the allocation function will take care of overflows
2871          , front_idx(static_cast<stored_size_type>(fi))
2872          , back_idx(static_cast<stored_size_type>(bi))
2873          , capacity(static_cast<stored_size_type>(c))
2874          #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2875          , capacity_alloc_count(0)
2876          #endif
2877       {}
2878 
2879       impl(BOOST_RV_REF(impl) m)
2880          : allocator_type(BOOST_MOVE_BASE(allocator_type, m))
2881          , buffer(static_cast<impl&>(m).buffer)
2882          , front_idx(static_cast<impl&>(m).front_idx)
2883          , back_idx(static_cast<impl&>(m).back_idx)
2884          , capacity(static_cast<impl&>(m).capacity)
2885          #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2886          , capacity_alloc_count(0)
2887          #endif
2888       {
2889          impl &i = static_cast<impl&>(m);
2890          // buffer is already acquired, reset rhs
2891          i.capacity = 0u;
2892          i.buffer = pointer();
2893          i.front_idx = 0;
2894          i.back_idx = 0;
2895       }
2896 
2897       BOOST_CONTAINER_FORCEINLINE void set_back_idx(size_type bi)
2898       {
2899          back_idx = static_cast<stored_size_type>(bi);
2900       }
2901 
2902       BOOST_CONTAINER_FORCEINLINE void set_front_idx(size_type fi)
2903       {
2904          front_idx = static_cast<stored_size_type>(fi);
2905       }
2906 
2907       BOOST_CONTAINER_FORCEINLINE void set_capacity(size_type c)
2908       {
2909          capacity = static_cast<stored_size_type>(c);
2910       }
2911 
2912       pointer           buffer;
2913       stored_size_type  front_idx;
2914       stored_size_type  back_idx;
2915       stored_size_type  capacity;
2916       #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2917       size_type capacity_alloc_count;
2918       #endif
2919    } m_;
2920 
2921    #ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2922    public:
2923    void reset_alloc_stats()
2924    {
2925       m_.capacity_alloc_count = 0;
2926    }
2927 
2928    size_type get_alloc_count() const
2929    {
2930       return m_.capacity_alloc_count;
2931    }
2932 
2933    #endif // ifdef BOOST_CONTAINER_DEVECTOR_ALLOC_STATS
2934 
2935    #endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2936 };
2937 
2938 }} // namespace boost::container
2939 
2940 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2941 
2942 namespace boost {
2943 
2944 //!has_trivial_destructor_after_move<> == true_type
2945 //!specialization for optimizations
2946 template <class T, class Allocator, class Options>
2947 struct has_trivial_destructor_after_move<boost::container::devector<T, Allocator, Options> >
2948 {
2949     typedef typename boost::container::devector<T, Allocator, Options>::allocator_type allocator_type;
2950     typedef typename ::boost::container::allocator_traits<allocator_type>::pointer pointer;
2951     static const bool value = ::boost::has_trivial_destructor_after_move<allocator_type>::value &&
2952                                            ::boost::has_trivial_destructor_after_move<pointer>::value;
2953 };
2954 
2955 }
2956 
2957 #endif    //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2958 
2959 #include <boost/container/detail/config_end.hpp>
2960 
2961 #endif // BOOST_CONTAINER_DEVECTOR_HPP