Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-14 08:28:41

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