Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 08:10:25

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/container for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP
0012 #define BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/container/detail/config_begin.hpp>
0023 #include <boost/container/detail/workaround.hpp>
0024 
0025 // container
0026 #include <boost/container/container_fwd.hpp>
0027 #include <boost/container/vector.hpp>
0028 #include <boost/container/allocator_traits.hpp>
0029 #include <boost/container/new_allocator.hpp> //new_allocator
0030 // container/detail
0031 #include <boost/container/detail/type_traits.hpp>
0032 #include <boost/container/detail/version_type.hpp>
0033 
0034 //move
0035 #include <boost/move/adl_move_swap.hpp>
0036 #include <boost/move/iterator.hpp>
0037 
0038 //move/detail
0039 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0040 #include <boost/move/detail/fwd_macros.hpp>
0041 #endif
0042 
0043 //std
0044 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0045 #include <initializer_list>   //for std::initializer_list
0046 #endif
0047 
0048 #include <cstddef> //offsetof
0049 
0050 namespace boost {
0051 namespace container {
0052 
0053 namespace dtl{
0054 
0055 template<class Options>
0056 struct get_small_vector_opt
0057 {
0058    typedef Options type;
0059 };
0060 
0061 template<>
0062 struct get_small_vector_opt<void>
0063 {
0064    typedef small_vector_null_opt type;
0065 };
0066 
0067 template<class Options>
0068 struct get_vopt_from_svopt
0069    : get_small_vector_opt<Options>::type
0070 {
0071    typedef typename get_small_vector_opt<Options>::type options_t;
0072    typedef vector_opt< typename options_t::growth_factor_type, void> type;
0073 };
0074 
0075 template<>
0076 struct get_vopt_from_svopt<void>
0077 {
0078    typedef void type;
0079 };
0080 
0081 template <class T, class SecAlloc, class Options>
0082 struct vector_for_small_vector
0083 {
0084    typedef vector
0085       < T
0086       , small_vector_allocator
0087          < T 
0088          , typename allocator_traits<typename real_allocator<T, SecAlloc>::type>::template portable_rebind_alloc<void>::type
0089          , Options>
0090       , typename dtl::get_vopt_from_svopt<Options>::type
0091       > type;
0092 };
0093 
0094 }  //namespace dtl
0095 
0096 //! A non-standard allocator used to implement `small_vector`.
0097 //! Users should never use it directly. It is described here
0098 //! for documentation purposes.
0099 //! 
0100 //! This allocator inherits from a standard-conforming allocator
0101 //! and forwards member functions to the standard allocator except
0102 //! when internal storage is being used as memory source.
0103 //!
0104 //! This allocator is a "partially_propagable" allocator and
0105 //! defines `is_partially_propagable` as true_type.
0106 //! 
0107 //! A partially propagable allocator means that not all storage
0108 //! allocatod by an instance of `small_vector_allocator` can be
0109 //! deallocated by another instance of this type, even if both
0110 //! instances compare equal or an instance is propagated to another
0111 //! one using the copy/move constructor or assignment. The storage that
0112 //! can never be propagated is identified by `storage_is_unpropagable(p)`.
0113 //!
0114 //! `boost::container::vector` supports partially propagable allocators
0115 //! fallbacking to deep copy/swap/move operations when internal storage
0116 //! is being used to store vector elements.
0117 //!
0118 //! `small_vector_allocator` assumes that will be instantiated as
0119 //! `boost::container::vector< T, small_vector_allocator<T, Allocator> >`
0120 //! and internal storage can be obtained downcasting that vector
0121 //! to `small_vector_base<T>`.
0122 template<class T, class VoidAlloc BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void)>
0123 class small_vector_allocator
0124    : public allocator_traits<VoidAlloc>::template portable_rebind_alloc<T>::type
0125 {
0126    typedef unsigned int allocation_type;
0127    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0128    private:
0129 
0130    typedef typename allocator_traits<VoidAlloc>::template portable_rebind_alloc<T>::type allocator_type;
0131 
0132    BOOST_COPYABLE_AND_MOVABLE(small_vector_allocator)
0133 
0134    inline const allocator_type &as_base() const BOOST_NOEXCEPT
0135    {  return static_cast<const allocator_type&>(*this);  }
0136 
0137    inline allocator_type &as_base() BOOST_NOEXCEPT
0138    {  return static_cast<allocator_type&>(*this);  }
0139 
0140    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0141 
0142    public:
0143    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0144    typedef allocator_traits<allocator_type> allocator_traits_type;
0145    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0146 
0147    typedef typename allocator_traits<allocator_type>::value_type          value_type;
0148    typedef typename allocator_traits<allocator_type>::pointer             pointer;
0149    typedef typename allocator_traits<allocator_type>::const_pointer       const_pointer;
0150    typedef typename allocator_traits<allocator_type>::reference           reference;
0151    typedef typename allocator_traits<allocator_type>::const_reference     const_reference;
0152    typedef typename allocator_traits<allocator_type>::size_type           size_type;
0153    typedef typename allocator_traits<allocator_type>::difference_type     difference_type;
0154    typedef typename allocator_traits<allocator_type>::void_pointer        void_pointer;
0155    typedef typename allocator_traits<allocator_type>::const_void_pointer  const_void_pointer;
0156 
0157    typedef typename allocator_traits<allocator_type>::propagate_on_container_copy_assignment   propagate_on_container_copy_assignment;
0158    typedef typename allocator_traits<allocator_type>::propagate_on_container_move_assignment   propagate_on_container_move_assignment;
0159    typedef typename allocator_traits<allocator_type>::propagate_on_container_swap              propagate_on_container_swap;
0160    //! An integral constant with member `value == false`
0161    typedef BOOST_CONTAINER_IMPDEF(dtl::bool_<false>)                         is_always_equal;
0162    //! An integral constant with member `value == true`
0163    typedef BOOST_CONTAINER_IMPDEF(dtl::bool_<true>)                          is_partially_propagable;
0164 
0165    BOOST_CONTAINER_DOCIGN(typedef dtl::version_type<small_vector_allocator BOOST_CONTAINER_I 1>  version;)
0166 
0167    //!Obtains an small_vector_allocator that allocates
0168    //!objects of type T2
0169    template<class T2>
0170    struct rebind
0171    {
0172       typedef typename allocator_traits<allocator_type>::template portable_rebind_alloc<T2>::type other;
0173    };
0174 
0175    inline small_vector_allocator() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value)
0176    {}
0177 
0178    //!Constructor from other small_vector_allocator.
0179    //!Never throws
0180    inline small_vector_allocator
0181       (const small_vector_allocator &other) BOOST_NOEXCEPT_OR_NOTHROW
0182       : allocator_type(other.as_base())
0183    {}
0184 
0185    //!Move constructor from small_vector_allocator.
0186    //!Never throws
0187    inline small_vector_allocator
0188       (BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
0189       : allocator_type(::boost::move(other.as_base()))
0190    {}
0191 
0192    //!Constructor from related small_vector_allocator.
0193    //!Never throws
0194    template<class U, class OtherVoidAllocator, class OtherOptions>
0195    inline small_vector_allocator
0196       (const small_vector_allocator<U, OtherVoidAllocator, OtherOptions> &other) BOOST_NOEXCEPT_OR_NOTHROW
0197       : allocator_type(other.as_base())
0198    {}
0199 
0200    //!Move constructor from related small_vector_allocator.
0201    //!Never throws
0202    template<class U, class OtherVoidAllocator, class OtherOptions>
0203    inline small_vector_allocator
0204       (BOOST_RV_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator BOOST_MOVE_I OtherOptions>) other) BOOST_NOEXCEPT_OR_NOTHROW
0205       : allocator_type(::boost::move(other.as_base()))
0206    {}
0207 
0208    //!Constructor from allocator_type.
0209    //!Never throws
0210    inline explicit small_vector_allocator
0211       (const allocator_type &other) BOOST_NOEXCEPT_OR_NOTHROW
0212       : allocator_type(other)
0213    {}
0214 
0215    //!Assignment from other small_vector_allocator.
0216    //!Never throws
0217    inline small_vector_allocator &
0218       operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
0219    {  return static_cast<small_vector_allocator&>(this->allocator_type::operator=(other.as_base()));  }
0220 
0221    //!Move assignment from other small_vector_allocator.
0222    //!Never throws
0223    inline small_vector_allocator &
0224       operator=(BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
0225    {  return static_cast<small_vector_allocator&>(this->allocator_type::operator=(::boost::move(other.as_base())));  }
0226 
0227    //!Assignment from related small_vector_allocator.
0228    //!Never throws
0229    template<class U, class OtherVoidAllocator>
0230    inline small_vector_allocator &
0231       operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator BOOST_MOVE_I Options>) other) BOOST_NOEXCEPT_OR_NOTHROW
0232    {  return static_cast<small_vector_allocator&>(this->allocator_type::operator=(other.as_base()));  }
0233 
0234    //!Move assignment from related small_vector_allocator.
0235    //!Never throws
0236    template<class U, class OtherVoidAllocator>
0237    inline small_vector_allocator &
0238       operator=(BOOST_RV_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator BOOST_MOVE_I Options>) other) BOOST_NOEXCEPT_OR_NOTHROW
0239    {  return static_cast<small_vector_allocator&>(this->allocator_type::operator=(::boost::move(other.as_base())));  }
0240 
0241    //!Move assignment from allocator_type.
0242    //!Never throws
0243    inline small_vector_allocator &
0244       operator=(const allocator_type &other) BOOST_NOEXCEPT_OR_NOTHROW
0245    {  return static_cast<small_vector_allocator&>(this->allocator_type::operator=(other));  }
0246 
0247    //!Allocates storage from the standard-conforming allocator
0248    inline pointer allocate(size_type count, const_void_pointer hint = const_void_pointer())
0249    {  return allocator_traits_type::allocate(this->as_base(), count, hint);  }
0250 
0251    //!Deallocates previously allocated memory.
0252    //!Never throws
0253    void deallocate(pointer ptr, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
0254    {
0255       if(!this->is_internal_storage(ptr))
0256          allocator_traits_type::deallocate(this->as_base(), ptr, n);
0257    }
0258 
0259    //!Returns the maximum number of elements that could be allocated.
0260    //!Never throws
0261    inline size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
0262    {  return allocator_traits_type::max_size(this->as_base());   }
0263 
0264    small_vector_allocator select_on_container_copy_construction() const
0265    {  return small_vector_allocator(allocator_traits_type::select_on_container_copy_construction(this->as_base())); }
0266 
0267    bool storage_is_unpropagable(pointer p) const
0268    {  return this->is_internal_storage(p) || allocator_traits_type::storage_is_unpropagable(this->as_base(), p);  }
0269 
0270    //!Swaps two allocators, does nothing
0271    //!because this small_vector_allocator is stateless
0272    inline friend void swap(small_vector_allocator &l, small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
0273    {  boost::adl_move_swap(l.as_base(), r.as_base());  }
0274 
0275    //!An small_vector_allocator always compares to true, as memory allocated with one
0276    //!instance can be deallocated by another instance (except for unpropagable storage)
0277    inline friend bool operator==(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
0278    {  return allocator_traits_type::equal(l.as_base(), r.as_base());  }
0279 
0280    //!An small_vector_allocator always compares to false, as memory allocated with one
0281    //!instance can be deallocated by another instance
0282    inline friend bool operator!=(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
0283    {  return !(l == r);   }
0284 
0285    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0286    public:
0287 
0288    typedef small_vector_base<value_type, allocator_type, Options>    derived_type;
0289    typedef typename dtl::vector_for_small_vector
0290       <value_type, allocator_type, Options>::type                    vector_type;
0291 
0292    inline bool is_internal_storage(const_pointer p) const
0293    {  return this->internal_storage() == p;  }
0294 
0295    public:
0296    inline const_pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW;
0297    inline pointer       internal_storage()       BOOST_NOEXCEPT_OR_NOTHROW;
0298    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0299 };
0300 
0301 template<class T, std::size_t N, std::size_t Alignment>
0302 struct small_vector_storage
0303 {
0304    typedef typename dtl::aligned_storage
0305       <sizeof(T)*N, Alignment>::type storage_type;
0306    storage_type m_storage;
0307    BOOST_STATIC_CONSTEXPR std::size_t sms_size = sizeof(storage_type)/sizeof(T);
0308 };
0309 
0310 template<class T, std::size_t Alignment>
0311 struct small_vector_storage<T, 0u, Alignment>
0312 {
0313    BOOST_STATIC_CONSTEXPR std::size_t sms_size = 0u;
0314 };
0315 
0316 //! This class consists of common code from all small_vector<T, N> types that don't depend on the
0317 //! "N" template parameter. This class is non-copyable and non-destructible, so this class typically
0318 //! used as reference argument to functions that read or write small vectors. Since `small_vector<T, N>`
0319 //! derives from `small_vector_base<T>`, the conversion to `small_vector_base` is implicit
0320 //! <pre>
0321 //!
0322 //! //Clients can pass any small_vector<Foo, N>.
0323 //! void read_any_small_vector_of_foo(const small_vector_base<Foo> &in_parameter);
0324 //!
0325 //! void modify_any_small_vector_of_foo(small_vector_base<Foo> &in_out_parameter);
0326 //!
0327 //! void some_function()
0328 //! {
0329 //! 
0330 //!    small_vector<Foo, 8> myvector;
0331 //!
0332 //!    read_any_small_vector_of_foo(myvector);   // Reads myvector
0333 //!
0334 //!    modify_any_small_vector_of_foo(myvector); // Modifies myvector
0335 //! 
0336 //! }
0337 //! </pre>
0338 //!
0339 //! All `boost::container:vector` member functions are inherited. See `vector` documentation for details.
0340 //!
0341 template <class T, class SecAlloc, class Options>
0342 class small_vector_base
0343    : public dtl::vector_for_small_vector<T, SecAlloc, Options>::type
0344 {
0345    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKEDVECTOR
0346    public:
0347    //Make it public as it will be inherited by small_vector and container
0348    //must have this public member
0349    typedef typename real_allocator<T, SecAlloc>::type                     underlying_allocator_t;
0350    typedef typename allocator_traits<underlying_allocator_t>::
0351       template portable_rebind_alloc<void>::type                          void_underlying_allocator_t;
0352    typedef small_vector_allocator<T, void_underlying_allocator_t, Options>allocator_type;
0353    typedef typename dtl::get_small_vector_opt<Options>::type              options_t;
0354    typedef typename dtl::vector_for_small_vector
0355       <T, SecAlloc, Options>::type                                        base_type;
0356    typedef typename allocator_traits<allocator_type>::pointer             pointer;
0357    typedef typename allocator_traits<allocator_type>::const_pointer       const_pointer;
0358    typedef typename allocator_traits<allocator_type>::void_pointer        void_pointer;
0359    typedef typename allocator_traits<allocator_type>::const_void_pointer  const_void_pointer;
0360    typedef typename base_type::size_type                                  size_type;
0361 
0362 
0363    private: 
0364    BOOST_COPYABLE_AND_MOVABLE(small_vector_base)
0365 
0366    friend class small_vector_allocator<T, void_underlying_allocator_t, Options>;
0367 
0368    inline
0369    const_pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
0370    {  return this->base_type::get_stored_allocator().internal_storage();   }
0371 
0372    inline
0373    pointer internal_storage() BOOST_NOEXCEPT_OR_NOTHROW
0374    {  return this->base_type::get_stored_allocator().internal_storage();   }
0375 
0376    private:
0377          base_type &as_base()       { return static_cast<base_type&>(*this); }
0378    const base_type &as_base() const { return static_cast<const base_type&>(*this); }
0379 
0380    public:
0381 
0382    BOOST_CONTAINER_ATTRIBUTE_NODISCARD bool is_small() const
0383    {  return this->internal_storage() == this->data();   }
0384 
0385    protected:
0386 
0387    inline explicit small_vector_base(initial_capacity_t, size_type initial_capacity)
0388       : base_type(initial_capacity_t(), this->internal_storage(), initial_capacity)
0389    {}
0390 
0391    template<class AllocFwd>
0392    inline explicit small_vector_base(initial_capacity_t, size_type capacity, BOOST_FWD_REF(AllocFwd) a)
0393       : base_type(initial_capacity_t(), this->internal_storage(), capacity, ::boost::forward<AllocFwd>(a))
0394    {}
0395 
0396    template<class AllocFwd>
0397    inline explicit small_vector_base(initial_capacity_t, size_type capacity, BOOST_FWD_REF(AllocFwd) a, small_vector_base &x)
0398       : base_type(initial_capacity_t(), this->internal_storage(), capacity, ::boost::forward<AllocFwd>(a), x)
0399    {}
0400 
0401    inline explicit small_vector_base(maybe_initial_capacity_t, size_type initial_capacity, size_type initial_size)
0402       : base_type( maybe_initial_capacity_t()
0403                  , (initial_capacity >= initial_size) ? this->internal_storage() : pointer()
0404                  , (initial_capacity >= initial_size) ? initial_capacity : initial_size
0405                  )
0406    {}
0407 
0408    template<class AllocFwd>
0409    inline explicit small_vector_base(maybe_initial_capacity_t, size_type initial_capacity, size_type initial_size, BOOST_FWD_REF(AllocFwd) a)
0410       : base_type(maybe_initial_capacity_t()
0411                  , (initial_capacity >= initial_size) ? this->internal_storage() : pointer()
0412                  , (initial_capacity >= initial_size) ? initial_capacity : initial_size
0413                  , ::boost::forward<AllocFwd>(a)
0414       )
0415    {}
0416 
0417    void prot_shrink_to_fit_small(const size_type small_capacity)
0418    {  this->base_type::prot_shrink_to_fit_small(this->internal_storage(), small_capacity);  }
0419 
0420    using base_type::protected_set_size;
0421 
0422    //~small_vector_base(){}
0423    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0424 
0425    inline void prot_swap(small_vector_base& other, size_type internal_capacity_value)
0426    {  this->base_type::prot_swap_small(other, internal_capacity_value);  }
0427 
0428    public:
0429    inline small_vector_base& operator=(BOOST_COPY_ASSIGN_REF(small_vector_base) other)
0430    {  return static_cast<small_vector_base&>(this->base_type::operator=(static_cast<base_type const&>(other)));  }
0431 
0432    inline small_vector_base& operator=(BOOST_RV_REF(small_vector_base) other)
0433    {  return static_cast<small_vector_base&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); }
0434 
0435    inline void swap(small_vector_base &other)
0436    {  return this->base_type::prot_swap_small(other, 0u);  }
0437 
0438 };
0439 
0440 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0441 
0442 /////////////////////////////////////////////////////
0443 //
0444 //          small_vector_storage_definer
0445 //
0446 /////////////////////////////////////////////////////
0447 template<class T, std::size_t N, class Options>
0448 struct small_vector_storage_definer
0449 {
0450    typedef typename dtl::get_small_vector_opt<Options>::type options_t;
0451    BOOST_STATIC_CONSTEXPR std::size_t final_alignment =
0452       options_t::inplace_alignment ? options_t::inplace_alignment : dtl::alignment_of<T>::value;
0453    typedef small_vector_storage<T, N, final_alignment> type;
0454 };
0455 
0456 
0457 /// Figure out the offset of the first element. Idea taken from LLVM's SmallVector
0458 template <class T, class SecAlloc, class Options>
0459 struct small_vector_storage_offset
0460 {
0461    typedef small_vector_base<T, SecAlloc, Options>                    base_type;
0462    typedef typename small_vector_storage_definer<T, 1, Options>::type storage_type;
0463    typename dtl::aligned_storage
0464       < sizeof(base_type), dtl::alignment_of<base_type>::value
0465       >::type base;
0466 
0467    typename dtl::aligned_storage
0468       < sizeof(storage_type), dtl::alignment_of<storage_type>::value
0469       > ::type storage;
0470 };
0471 
0472 template <class T, class SecAlloc, class Options>
0473 inline std::size_t get_small_vector_storage_offset()
0474 {
0475    typedef small_vector_storage_offset<T, SecAlloc, Options> struct_type;
0476    return offsetof(struct_type, storage);
0477 }
0478 
0479 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
0480 #pragma GCC diagnostic push
0481 #pragma GCC diagnostic ignored "-Wcast-align"
0482 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
0483 #endif
0484 
0485 //Internal storage hack
0486 template<class T, class VoidAlloc, class Options>
0487 inline typename small_vector_allocator<T, VoidAlloc, Options>::const_pointer
0488    small_vector_allocator<T, VoidAlloc, Options>::internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
0489 {
0490    const vector_type& v = *static_cast<const vector_type*>(static_cast<const void *>(this));
0491    BOOST_ASSERT((std::size_t(this) % dtl::alignment_of< small_vector_storage_offset<T, allocator_type, Options> >::value) == 0);
0492    const char *addr = reinterpret_cast<const char*>(&v);
0493    typedef typename boost::intrusive::pointer_traits<pointer>::template rebind_pointer<const char>::type const_char_pointer;
0494    const_void_pointer vptr = boost::intrusive::pointer_traits<const_char_pointer>::pointer_to(*addr)
0495       + get_small_vector_storage_offset<T, allocator_type, Options>();
0496    return boost::intrusive::pointer_traits<const_pointer>::static_cast_from(vptr);
0497 }
0498 
0499 template <class T, class VoidAlloc, class Options>
0500 inline typename small_vector_allocator<T, VoidAlloc, Options>::pointer
0501    small_vector_allocator<T, VoidAlloc, Options>::internal_storage() BOOST_NOEXCEPT_OR_NOTHROW
0502 {
0503    vector_type& v = *static_cast<vector_type*>(static_cast<void*>(this));
0504    BOOST_ASSERT((std::size_t(this) % dtl::alignment_of< small_vector_storage_offset<T, allocator_type, Options> >::value) == 0);
0505    char* addr = reinterpret_cast<char*>(&v);
0506    typedef typename boost::intrusive::pointer_traits<pointer>::template rebind_pointer<char>::type char_pointer;
0507    void_pointer vptr = boost::intrusive::pointer_traits<char_pointer>::pointer_to(*addr)
0508                      + get_small_vector_storage_offset<T, allocator_type, Options>();
0509    return boost::intrusive::pointer_traits<pointer>::static_cast_from(vptr);
0510 }
0511 
0512 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
0513 #pragma GCC diagnostic pop
0514 #endif
0515 
0516 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0517 
0518 //! small_vector is a vector-like container optimized for the case when it contains few elements.
0519 //! It contains some preallocated elements in-place, which can avoid the use of dynamic storage allocation
0520 //! when the actual number of elements is below that preallocated threshold.
0521 //!
0522 //! `small_vector<T, N, Allocator, Options>` is convertible to `small_vector_base<T, Allocator, Options>` that is independent
0523 //! from the preallocated element capacity, so client code does not need to be templated on that N argument.
0524 //!
0525 //! All `boost::container::vector` member functions are inherited. See `vector` documentation for details.
0526 //!
0527 //! Any change to the capacity of the vector, including decreasing its size such as with the shrink_to_fit method, will
0528 //! cause the vector to permanently switch to dynamically allocated storage.
0529 //!
0530 //! \tparam T The type of object that is stored in the small_vector
0531 //! \tparam N The number of preallocated elements stored inside small_vector. It shall be less than Allocator::max_size();
0532 //! \tparam Allocator The allocator used for memory management when the number of elements exceeds N. Use void
0533 //!   for the default allocator
0534 //! \tparam Options A type produced from \c boost::container::small_vector_options.
0535 template <class T, std::size_t N, class Allocator BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void) >
0536 class small_vector
0537    : public small_vector_base<T, Allocator, Options>
0538    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0539    , private small_vector_storage_definer<T, N, Options>::type
0540    #endif
0541 {
0542    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0543 
0544    BOOST_COPYABLE_AND_MOVABLE(small_vector)
0545 
0546    public:
0547    typedef small_vector_base<T, Allocator, Options>   base_type;
0548    typedef typename base_type::allocator_type         allocator_type;
0549    typedef typename base_type::size_type              size_type;
0550    typedef typename base_type::value_type             value_type;
0551 
0552    inline static size_type internal_capacity()
0553    {  return static_capacity;  }
0554 
0555    typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type;
0556 
0557    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0558 
0559    //! @brief The capacity/max size of the container
0560    BOOST_STATIC_CONSTEXPR size_type static_capacity = small_vector_storage_definer<T, N, Options>::type::sms_size;
0561 
0562    public:
0563    inline small_vector()
0564       BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<allocator_type>::value)
0565       : base_type(initial_capacity_t(), internal_capacity())
0566    {}
0567 
0568    inline explicit small_vector(const allocator_type &a)
0569       : base_type(initial_capacity_t(), internal_capacity(), a)
0570    {}
0571 
0572    inline explicit small_vector(size_type n)
0573       : base_type(maybe_initial_capacity_t(), internal_capacity(), n)
0574    {  this->protected_init_n(n, value_init); }
0575 
0576    inline small_vector(size_type n, const allocator_type &a)
0577       : base_type(maybe_initial_capacity_t(), internal_capacity(), n, a)
0578    {  this->protected_init_n(n, value_init); }
0579 
0580    inline small_vector(size_type n, default_init_t)
0581       : base_type(maybe_initial_capacity_t(), internal_capacity(), n)
0582    {  this->protected_init_n(n, default_init_t()); }
0583 
0584    inline small_vector(size_type n, default_init_t, const allocator_type &a)
0585       : base_type(maybe_initial_capacity_t(), internal_capacity(), n, a)
0586    {  this->protected_init_n(n, default_init_t()); }
0587 
0588    inline small_vector(size_type n, const value_type &v)
0589       : base_type(maybe_initial_capacity_t(), internal_capacity(), n)
0590    {  this->protected_init_n(n, v); }
0591 
0592    inline small_vector(size_type n, const value_type &v, const allocator_type &a)
0593       : base_type(maybe_initial_capacity_t(), internal_capacity(), n, a)
0594    {  this->protected_init_n(n, v); }
0595 
0596    template <class InIt>
0597    inline small_vector(InIt first, InIt last
0598       BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
0599          < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
0600          BOOST_MOVE_I dtl::nat >::type * = 0)
0601       )
0602       : base_type(initial_capacity_t(), internal_capacity())
0603    {  this->assign(first, last); }
0604 
0605    template <class InIt>
0606    inline small_vector(InIt first, InIt last, const allocator_type& a
0607       BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c
0608          < dtl::is_convertible<InIt BOOST_MOVE_I size_type>::value
0609          BOOST_MOVE_I dtl::nat >::type * = 0)
0610       )
0611       : base_type(initial_capacity_t(), internal_capacity(), a)
0612    {  this->assign(first, last); }
0613 
0614    inline small_vector(const small_vector &other)
0615       : base_type( initial_capacity_t(), internal_capacity()
0616                  , allocator_traits_type::select_on_container_copy_construction(other.get_stored_allocator()))
0617    {  this->assign(other.cbegin(), other.cend());  }
0618 
0619    inline small_vector(const small_vector &other, const allocator_type &a)
0620       : base_type(initial_capacity_t(), internal_capacity(), a)
0621    {  this->assign(other.cbegin(), other.cend());  }
0622 
0623    inline explicit small_vector(const base_type &other)
0624       : base_type( initial_capacity_t(), internal_capacity()
0625                  , allocator_traits_type::select_on_container_copy_construction(other.get_stored_allocator()))
0626    {  this->assign(other.cbegin(), other.cend());  }
0627 
0628    inline explicit small_vector(BOOST_RV_REF(base_type) other)
0629       : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator()), other)
0630    {}
0631 
0632    inline small_vector(BOOST_RV_REF(small_vector) other)
0633       BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<value_type>::value)
0634       : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator()), other)
0635    {}
0636 
0637    inline small_vector(BOOST_RV_REF(small_vector) other, const allocator_type &a)
0638       : base_type(initial_capacity_t(), internal_capacity(), a, other)
0639    {}
0640 
0641    #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
0642    inline small_vector(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
0643       : base_type(initial_capacity_t(), internal_capacity(), a)
0644    {
0645       this->assign(il.begin(), il.end());
0646    }
0647    #endif
0648 
0649    inline small_vector& operator=(BOOST_COPY_ASSIGN_REF(small_vector) other)
0650    {  return static_cast<small_vector&>(this->base_type::operator=(static_cast<base_type const&>(other)));  }
0651 
0652    inline small_vector& operator=(BOOST_RV_REF(small_vector) other)
0653       BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_assignable<value_type>::value
0654          && (allocator_traits_type::propagate_on_container_move_assignment::value
0655              || allocator_traits_type::is_always_equal::value))
0656    {  return static_cast<small_vector&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); }
0657 
0658    inline small_vector& operator=(const base_type &other)
0659    {  return static_cast<small_vector&>(this->base_type::operator=(other));  }
0660 
0661    inline small_vector& operator=(BOOST_RV_REF(base_type) other)
0662    {  return static_cast<small_vector&>(this->base_type::operator=(boost::move(other))); }
0663 
0664    inline void swap(small_vector &other)
0665    {  return this->base_type::prot_swap(other, static_capacity);  }
0666 
0667    inline void shrink_to_fit()
0668    {  this->base_type::prot_shrink_to_fit_small(this->internal_capacity());   }
0669 };
0670 
0671 }}
0672 
0673 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0674 /*
0675 namespace boost {
0676 
0677 //!has_trivial_destructor_after_move<> == true_type
0678 //!specialization for optimizations
0679 template <class T, class Allocator>
0680 struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
0681 {
0682    typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
0683    BOOST_STATIC_CONSTEXPR bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
0684                              ::boost::has_trivial_destructor_after_move<pointer>::value;
0685 };
0686 
0687 }
0688 */
0689 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
0690 
0691 #include <boost/container/detail/config_end.hpp>
0692 
0693 #endif //   #ifndef  BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP