annotate DEPENDENCIES/generic/include/boost/container/small_vector.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 //////////////////////////////////////////////////////////////////////////////
Chris@102 2 //
Chris@102 3 // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
Chris@102 4 // Software License, Version 1.0. (See accompanying file
Chris@102 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@102 6 //
Chris@102 7 // See http://www.boost.org/libs/container for documentation.
Chris@102 8 //
Chris@102 9 //////////////////////////////////////////////////////////////////////////////
Chris@102 10
Chris@102 11 #ifndef BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP
Chris@102 12 #define BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP
Chris@102 13
Chris@102 14 #ifndef BOOST_CONFIG_HPP
Chris@102 15 # include <boost/config.hpp>
Chris@102 16 #endif
Chris@102 17
Chris@102 18 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@102 19 # pragma once
Chris@102 20 #endif
Chris@102 21
Chris@102 22 #include <boost/container/detail/config_begin.hpp>
Chris@102 23 #include <boost/container/detail/workaround.hpp>
Chris@102 24
Chris@102 25 // container
Chris@102 26 #include <boost/container/container_fwd.hpp>
Chris@102 27 #include <boost/container/vector.hpp>
Chris@102 28 #include <boost/container/allocator_traits.hpp>
Chris@102 29 #include <boost/container/new_allocator.hpp> //new_allocator
Chris@102 30 // container/detail
Chris@102 31 #include <boost/container/detail/type_traits.hpp>
Chris@102 32 #include <boost/container/detail/version_type.hpp>
Chris@102 33
Chris@102 34 //move
Chris@102 35 #include <boost/move/adl_move_swap.hpp>
Chris@102 36 #include <boost/move/iterator.hpp>
Chris@102 37
Chris@102 38 //move/detail
Chris@102 39 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
Chris@102 40 #include <boost/move/detail/fwd_macros.hpp>
Chris@102 41 #endif
Chris@102 42
Chris@102 43 //std
Chris@102 44 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
Chris@102 45 #include <initializer_list> //for std::initializer_list
Chris@102 46 #endif
Chris@102 47
Chris@102 48 namespace boost {
Chris@102 49 namespace container {
Chris@102 50
Chris@102 51 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 52
Chris@102 53 template <class T, class Allocator = new_allocator<T> >
Chris@102 54 class small_vector_base;
Chris@102 55
Chris@102 56 #endif
Chris@102 57
Chris@102 58 //! A non-standard allocator used to implement `small_vector`.
Chris@102 59 //! Users should never use it directly. It is described here
Chris@102 60 //! for documentation purposes.
Chris@102 61 //!
Chris@102 62 //! This allocator inherits from a standard-conforming allocator
Chris@102 63 //! and forwards member functiond to the standard allocator except
Chris@102 64 //! when internal storage is being used as memory source.
Chris@102 65 //!
Chris@102 66 //! This allocator is a "partially_propagable" allocator and
Chris@102 67 //! defines `is_partially_propagable` as true_type.
Chris@102 68 //!
Chris@102 69 //! A partially propagable allocator means that not all storage
Chris@102 70 //! allocatod by an instance of `small_vector_allocator` can be
Chris@102 71 //! deallocated by another instance of this type, even is both
Chris@102 72 //! instances compare equal or an instance is propagated to another
Chris@102 73 //! one using the copy/move constructor or assignment. The storage that
Chris@102 74 //! can never be propagated is identified by `storage_is_unpropagable(p)`.
Chris@102 75 //!
Chris@102 76 //! `boost::container::vector` supports partially propagable allocators
Chris@102 77 //! fallbacking to deep copy/swap/move operations when internal storage
Chris@102 78 //! is being used to store vector elements.
Chris@102 79 //!
Chris@102 80 //! `small_vector_allocator` assumes that will be instantiated as
Chris@102 81 //! `boost::container::vector< T, small_vector_allocator<Allocator> >`
Chris@102 82 //! and internal storage can be obtained downcasting that vector
Chris@102 83 //! to `small_vector_base<T>`.
Chris@102 84 template<class Allocator>
Chris@102 85 class small_vector_allocator
Chris@102 86 : public Allocator
Chris@102 87 {
Chris@102 88 typedef unsigned int allocation_type;
Chris@102 89 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 90 private:
Chris@102 91
Chris@102 92 BOOST_COPYABLE_AND_MOVABLE(small_vector_allocator)
Chris@102 93
Chris@102 94 const Allocator &as_base() const
Chris@102 95 { return static_cast<const Allocator&>(*this); }
Chris@102 96
Chris@102 97 Allocator &as_base()
Chris@102 98 { return static_cast<Allocator&>(*this); }
Chris@102 99
Chris@102 100 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 101
Chris@102 102 public:
Chris@102 103 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 104 typedef allocator_traits<Allocator> allocator_traits_type;
Chris@102 105 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 106
Chris@102 107 typedef typename allocator_traits<Allocator>::value_type value_type;
Chris@102 108 typedef typename allocator_traits<Allocator>::pointer pointer;
Chris@102 109 typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
Chris@102 110 typedef typename allocator_traits<Allocator>::reference reference;
Chris@102 111 typedef typename allocator_traits<Allocator>::const_reference const_reference;
Chris@102 112 typedef typename allocator_traits<Allocator>::size_type size_type;
Chris@102 113 typedef typename allocator_traits<Allocator>::difference_type difference_type;
Chris@102 114 typedef typename allocator_traits<Allocator>::void_pointer void_pointer;
Chris@102 115 typedef typename allocator_traits<Allocator>::const_void_pointer const_void_pointer;
Chris@102 116
Chris@102 117 typedef typename allocator_traits<Allocator>::propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
Chris@102 118 typedef typename allocator_traits<Allocator>::propagate_on_container_move_assignment propagate_on_container_move_assignment;
Chris@102 119 typedef typename allocator_traits<Allocator>::propagate_on_container_swap propagate_on_container_swap;
Chris@102 120 //! An integral constant with member `::value == false`
Chris@102 121 typedef BOOST_CONTAINER_IMPDEF(container_detail::bool_<false>) is_always_equal;
Chris@102 122 //! An integral constant with member `::value == true`
Chris@102 123 typedef BOOST_CONTAINER_IMPDEF(container_detail::bool_<true>) is_partially_propagable;
Chris@102 124
Chris@102 125 BOOST_CONTAINER_DOCIGN(typedef container_detail::version_type<small_vector_allocator BOOST_CONTAINER_I 1> version;)
Chris@102 126
Chris@102 127 //!Obtains an small_vector_allocator that allocates
Chris@102 128 //!objects of type T2
Chris@102 129 template<class T2>
Chris@102 130 struct rebind
Chris@102 131 {
Chris@102 132 typedef typename allocator_traits<Allocator>::template rebind_alloc<T2>::type other;
Chris@102 133 };
Chris@102 134
Chris@102 135 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@102 136 //!Constructor from arbitrary arguments
Chris@102 137 template<class ...Args>
Chris@102 138 explicit small_vector_allocator(BOOST_FWD_REF(Args) ...args)
Chris@102 139 : Allocator(::boost::forward<Args>(args)...)
Chris@102 140 {}
Chris@102 141 #else
Chris@102 142 #define BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE(N) \
Chris@102 143 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
Chris@102 144 explicit small_vector_allocator(BOOST_MOVE_UREF##N)\
Chris@102 145 : Allocator(BOOST_MOVE_FWD##N)\
Chris@102 146 {}\
Chris@102 147 //
Chris@102 148 BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE)
Chris@102 149 #undef BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE
Chris@102 150 #endif
Chris@102 151
Chris@102 152 //!Constructor from other small_vector_allocator.
Chris@102 153 //!Never throws
Chris@102 154 small_vector_allocator(const small_vector_allocator &other) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 155 : Allocator(other.as_base())
Chris@102 156 {}
Chris@102 157
Chris@102 158 //!Move constructor from small_vector_allocator.
Chris@102 159 //!Never throws
Chris@102 160 small_vector_allocator(BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 161 : Allocator(::boost::move(other.as_base()))
Chris@102 162 {}
Chris@102 163
Chris@102 164 //!Constructor from related small_vector_allocator.
Chris@102 165 //!Never throws
Chris@102 166 template<class OtherAllocator>
Chris@102 167 small_vector_allocator(const small_vector_allocator<OtherAllocator> &other) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 168 : Allocator(other.as_base())
Chris@102 169 {}
Chris@102 170
Chris@102 171 //!Move constructor from related small_vector_allocator.
Chris@102 172 //!Never throws
Chris@102 173 template<class OtherAllocator>
Chris@102 174 small_vector_allocator(BOOST_RV_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 175 : Allocator(::boost::move(other.as_base()))
Chris@102 176 {}
Chris@102 177
Chris@102 178 //!Assignment from other small_vector_allocator.
Chris@102 179 //!Never throws
Chris@102 180 small_vector_allocator & operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 181 { return static_cast<small_vector_allocator&>(this->Allocator::operator=(other.as_base())); }
Chris@102 182
Chris@102 183 //!Move constructor from other small_vector_allocator.
Chris@102 184 //!Never throws
Chris@102 185 small_vector_allocator & operator=(BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 186 { return static_cast<small_vector_allocator&>(this->Allocator::operator=(::boost::move(other.as_base()))); }
Chris@102 187
Chris@102 188 //!Assignment from related small_vector_allocator.
Chris@102 189 //!Never throws
Chris@102 190 template<class OtherAllocator>
Chris@102 191 small_vector_allocator & operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 192 { return static_cast<small_vector_allocator&>(this->Allocator::operator=(other.as_base())); }
Chris@102 193
Chris@102 194 //!Move assignment from related small_vector_allocator.
Chris@102 195 //!Never throws
Chris@102 196 template<class OtherAllocator>
Chris@102 197 small_vector_allocator & operator=(BOOST_RV_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 198 { return static_cast<small_vector_allocator&>(this->Allocator::operator=(::boost::move(other.as_base()))); }
Chris@102 199
Chris@102 200 //!Allocates storage from the standard-conforming allocator
Chris@102 201 pointer allocate(size_type count, const_void_pointer hint = const_void_pointer())
Chris@102 202 { return allocator_traits_type::allocate(this->as_base(), count, hint); }
Chris@102 203
Chris@102 204 //!Deallocates previously allocated memory.
Chris@102 205 //!Never throws
Chris@102 206 void deallocate(pointer ptr, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 207 {
Chris@102 208 if(!this->is_internal_storage(ptr))
Chris@102 209 allocator_traits_type::deallocate(this->as_base(), ptr, n);
Chris@102 210 }
Chris@102 211
Chris@102 212 //!Returns the maximum number of elements that could be allocated.
Chris@102 213 //!Never throws
Chris@102 214 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 215 { return allocator_traits_type::max_size(this->as_base()); }
Chris@102 216
Chris@102 217 small_vector_allocator select_on_container_copy_construction() const
Chris@102 218 { return small_vector_allocator(allocator_traits_type::select_on_container_copy_construction(this->as_base())); }
Chris@102 219
Chris@102 220 bool storage_is_unpropagable(pointer p) const
Chris@102 221 { return this->is_internal_storage(p) || allocator_traits_type::storage_is_unpropagable(this->as_base(), p); }
Chris@102 222
Chris@102 223 //!Swaps two allocators, does nothing
Chris@102 224 //!because this small_vector_allocator is stateless
Chris@102 225 friend void swap(small_vector_allocator &l, small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 226 { boost::adl_move_swap(l.as_base(), r.as_base()); }
Chris@102 227
Chris@102 228 //!An small_vector_allocator always compares to true, as memory allocated with one
Chris@102 229 //!instance can be deallocated by another instance (except for unpropagable storage)
Chris@102 230 friend bool operator==(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 231 { return allocator_traits_type::equal(l.as_base(), r.as_base()); }
Chris@102 232
Chris@102 233 //!An small_vector_allocator always compares to false, as memory allocated with one
Chris@102 234 //!instance can be deallocated by another instance
Chris@102 235 friend bool operator!=(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 236 { return !(l == r); }
Chris@102 237
Chris@102 238 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 239 /*
Chris@102 240 //!An advanced function that offers in-place expansion shrink to fit and new allocation
Chris@102 241 //!capabilities. Memory allocated with this function can only be deallocated with deallocate()
Chris@102 242 //!or deallocate_many().
Chris@102 243 //!This function is available only with Version == 2
Chris@102 244 pointer allocation_command(allocation_type command,
Chris@102 245 size_type limit_size,
Chris@102 246 size_type &prefer_in_recvd_out_size,
Chris@102 247 pointer &reuse)
Chris@102 248 { return allocator_traits_type::allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
Chris@102 249
Chris@102 250 //!Returns maximum the number of objects the previously allocated memory
Chris@102 251 //!pointed by p can hold.
Chris@102 252 //!Memory must not have been allocated with
Chris@102 253 //!allocate_one or allocate_individual.
Chris@102 254 //!This function is available only with Version == 2
Chris@102 255 size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 256 { return allocator_traits_type::size(p); }
Chris@102 257 */
Chris@102 258 private:
Chris@102 259 /*
Chris@102 260 //!Allocates just one object. Memory allocated with this function
Chris@102 261 //!must be deallocated only with deallocate_one().
Chris@102 262 //!Throws bad_alloc if there is no enough memory
Chris@102 263 //!This function is available only with Version == 2
Chris@102 264 using Allocator::allocate_one;
Chris@102 265 using Allocator::allocate_individual;
Chris@102 266 using Allocator::deallocate_one;
Chris@102 267 using Allocator::deallocate_individual;
Chris@102 268 using Allocator::allocate_many;
Chris@102 269 using Allocator::deallocate_many;*/
Chris@102 270
Chris@102 271 bool is_internal_storage(pointer p) const
Chris@102 272 { return this->internal_storage() == p; }
Chris@102 273
Chris@102 274 pointer internal_storage() const
Chris@102 275 {
Chris@102 276 typedef typename Allocator::value_type value_type;
Chris@102 277 typedef container_detail::vector_alloc_holder< small_vector_allocator<Allocator> > vector_alloc_holder_t;
Chris@102 278 typedef vector<value_type, small_vector_allocator<Allocator> > vector_base;
Chris@102 279 typedef small_vector_base<value_type, Allocator> derived_type;
Chris@102 280 //
Chris@102 281 const vector_alloc_holder_t &v_holder = static_cast<const vector_alloc_holder_t &>(*this);
Chris@102 282 const vector_base &v_base = reinterpret_cast<const vector_base &>(v_holder);
Chris@102 283 const derived_type &d_base = static_cast<const derived_type &>(v_base);
Chris@102 284 return d_base.internal_storage();
Chris@102 285 }
Chris@102 286 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 287 };
Chris@102 288
Chris@102 289 //! This class consists of common code from all small_vector<T, N> types that don't depend on the
Chris@102 290 //! "N" template parameter. This class is non-copyable and non-destructible, so this class tipically
Chris@102 291 //! used as reference argument to functions that read or write small vectors. Since `small_vector<T, N>`
Chris@102 292 //! derives from `small_vector_base<T>`, the conversion to `small_vector_base` is implicit:
Chris@102 293 //! <code>
Chris@102 294 //!
Chris@102 295 //! //Clients can pass any small_vector<Foo, N>.
Chris@102 296 //! void read_any_small_vector_of_foo(const small_vector_base<Foo> &in_parameter);
Chris@102 297 //! void modify_any_small_vector_of_foo(small_vector_base<Foo> &out_parameter);
Chris@102 298 //!
Chris@102 299 //! void some_function()
Chris@102 300 //! {
Chris@102 301 //! small_vector<Foo, 8> myvector;
Chris@102 302 //! read_any_small_vector_of_foo(myvector); // Reads myvector
Chris@102 303 //! modify_any_small_vector_of_foo(myvector); // Modifies myvector
Chris@102 304 //! }
Chris@102 305 //! </code>
Chris@102 306 //!
Chris@102 307 //! All `boost::container:vector` member functions are inherited. See `vector` documentation for details.
Chris@102 308 //!
Chris@102 309 template <class T, class SecondaryAllocator>
Chris@102 310 class small_vector_base
Chris@102 311 : public vector<T, small_vector_allocator<SecondaryAllocator> >
Chris@102 312 {
Chris@102 313 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 314 typedef typename allocator_traits<SecondaryAllocator>::pointer pointer;
Chris@102 315
Chris@102 316 BOOST_COPYABLE_AND_MOVABLE(small_vector_base)
Chris@102 317
Chris@102 318 friend class small_vector_allocator<SecondaryAllocator>;
Chris@102 319
Chris@102 320 pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
Chris@102 321 {
Chris@102 322 return boost::intrusive::pointer_traits<pointer>::pointer_to
Chris@102 323 (*const_cast<T*>(static_cast<const T*>(static_cast<const void*>(&m_storage_start))));
Chris@102 324 }
Chris@102 325
Chris@102 326 typedef vector<T, small_vector_allocator<SecondaryAllocator> > base_type;
Chris@102 327 base_type &as_base() { return static_cast<base_type&>(*this); }
Chris@102 328 const base_type &as_base() const { return static_cast<const base_type&>(*this); }
Chris@102 329
Chris@102 330 public:
Chris@102 331 typedef typename container_detail::aligned_storage
Chris@102 332 <sizeof(T), container_detail::alignment_of<T>::value>::type storage_type;
Chris@102 333 typedef small_vector_allocator<SecondaryAllocator> allocator_type;
Chris@102 334
Chris@102 335 protected:
Chris@102 336 typedef typename base_type::initial_capacity_t initial_capacity_t;
Chris@102 337
Chris@102 338 explicit small_vector_base(initial_capacity_t, std::size_t initial_capacity)
Chris@102 339 : base_type(initial_capacity_t(), this->internal_storage(), initial_capacity)
Chris@102 340 {}
Chris@102 341
Chris@102 342 template<class AllocFwd>
Chris@102 343 explicit small_vector_base(initial_capacity_t, std::size_t capacity, BOOST_FWD_REF(AllocFwd) a)
Chris@102 344 : base_type(initial_capacity_t(), this->internal_storage(), capacity, ::boost::forward<AllocFwd>(a))
Chris@102 345 {}
Chris@102 346
Chris@102 347 ~small_vector_base(){}
Chris@102 348
Chris@102 349 using base_type::is_propagable_from;
Chris@102 350 using base_type::steal_resources;
Chris@102 351
Chris@102 352 private:
Chris@102 353 //The only member
Chris@102 354 storage_type m_storage_start;
Chris@102 355
Chris@102 356 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 357
Chris@102 358 public:
Chris@102 359 small_vector_base& operator=(BOOST_COPY_ASSIGN_REF(small_vector_base) other)
Chris@102 360 { return static_cast<small_vector_base&>(this->base_type::operator=(static_cast<base_type const&>(other))); }
Chris@102 361
Chris@102 362 small_vector_base& operator=(BOOST_RV_REF(small_vector_base) other)
Chris@102 363 { return static_cast<small_vector_base&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); }
Chris@102 364
Chris@102 365 void swap(small_vector_base &other)
Chris@102 366 { return this->base_type::swap(other); }
Chris@102 367 };
Chris@102 368
Chris@102 369 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 370
Chris@102 371 /////////////////////////////////////////////////////
Chris@102 372 //
Chris@102 373 // small_vector_storage_calculator
Chris@102 374 //
Chris@102 375 /////////////////////////////////////////////////////
Chris@102 376 template<std::size_t Needed, std::size_t Hdr, std::size_t SSize, bool NeedsZero = (0u == Needed || Needed <= Hdr)>
Chris@102 377 struct small_vector_storage_calculator_helper
Chris@102 378 {
Chris@102 379 static const std::size_t value = (Needed - Hdr - 1u)/SSize + 1u;
Chris@102 380 };
Chris@102 381
Chris@102 382 template<std::size_t Needed, std::size_t Hdr, std::size_t SSize>
Chris@102 383 struct small_vector_storage_calculator_helper<Needed, Hdr, SSize, true>
Chris@102 384 {
Chris@102 385 static const std::size_t value = 0u;
Chris@102 386 };
Chris@102 387
Chris@102 388 template<class Storage, class Allocator, class T, std::size_t N>
Chris@102 389 struct small_vector_storage_calculator
Chris@102 390 {
Chris@102 391 typedef small_vector_base<T, Allocator> svh_type;
Chris@102 392 typedef vector<T, small_vector_allocator<Allocator> > svhb_type;
Chris@102 393 static const std::size_t s_align = container_detail::alignment_of<Storage>::value;
Chris@102 394 static const std::size_t s_size = sizeof(Storage);
Chris@102 395 static const std::size_t svh_sizeof = sizeof(svh_type);
Chris@102 396 static const std::size_t svhb_sizeof = sizeof(svhb_type);
Chris@102 397 static const std::size_t s_start = ((svhb_sizeof-1)/s_align+1)*s_align;
Chris@102 398 static const std::size_t header_bytes = svh_sizeof-s_start;
Chris@102 399 static const std::size_t needed_bytes = sizeof(T)*N;
Chris@102 400 static const std::size_t needed_extra_storages =
Chris@102 401 small_vector_storage_calculator_helper<needed_bytes, header_bytes, s_size>::value;
Chris@102 402 };
Chris@102 403
Chris@102 404 /////////////////////////////////////////////////////
Chris@102 405 //
Chris@102 406 // small_vector_storage_definer
Chris@102 407 //
Chris@102 408 /////////////////////////////////////////////////////
Chris@102 409 template<class Storage, std::size_t N>
Chris@102 410 struct small_vector_storage
Chris@102 411 {
Chris@102 412 Storage m_rest_of_storage[N];
Chris@102 413 };
Chris@102 414
Chris@102 415 template<class Storage>
Chris@102 416 struct small_vector_storage<Storage, 0>
Chris@102 417 {};
Chris@102 418
Chris@102 419 template<class Allocator, std::size_t N>
Chris@102 420 struct small_vector_storage_definer
Chris@102 421 {
Chris@102 422 typedef typename Allocator::value_type value_type;
Chris@102 423 typedef typename small_vector_base<value_type, Allocator>::storage_type storage_type;
Chris@102 424 static const std::size_t needed_extra_storages =
Chris@102 425 small_vector_storage_calculator<storage_type, Allocator, value_type, N>::needed_extra_storages;
Chris@102 426 typedef small_vector_storage<storage_type, needed_extra_storages> type;
Chris@102 427 };
Chris@102 428
Chris@102 429 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 430
Chris@102 431 //! small_vector a vector-like container optimized for the case when it contains few elements.
Chris@102 432 //! It contains some preallocated elements in-place, which allows it to avoid the use of dynamic storage allocation
Chris@102 433 //! when the actual number of elements is below that preallocated threshold.
Chris@102 434 //!
Chris@102 435 //! `small_vector<T, N, Allocator>` is convertible to `small_vector_base<T, Allocator>` that is independent
Chris@102 436 //! from the preallocated element capacity, so client code does not need to be templated on that N argument.
Chris@102 437 //!
Chris@102 438 //! All `boost::container::vector` member functions are inherited. See `vector` documentation for details.
Chris@102 439 //!
Chris@102 440 //! \tparam T The type of object that is stored in the small_vector
Chris@102 441 //! \tparam N The number of preallocated elements stored inside small_vector. It shall be less than Allocator::max_size();
Chris@102 442 //! \tparam Allocator The allocator used for memory management when the number of elements exceeds N.
Chris@102 443 template <class T, std::size_t N, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>) >
Chris@102 444 class small_vector : public small_vector_base<T, Allocator>
Chris@102 445 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 446 , private small_vector_storage_definer<Allocator, N>::type
Chris@102 447 #endif
Chris@102 448 {
Chris@102 449 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 450 typedef small_vector_base<T, Allocator> base_type;
Chris@102 451 typedef typename small_vector_storage_definer<Allocator, N>::type remaining_storage_holder;
Chris@102 452
Chris@102 453 BOOST_COPYABLE_AND_MOVABLE(small_vector)
Chris@102 454
Chris@102 455 typedef typename base_type::initial_capacity_t initial_capacity_t;
Chris@102 456 typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type;
Chris@102 457
Chris@102 458 public:
Chris@102 459 typedef small_vector_storage_calculator< typename small_vector_base<T, Allocator>
Chris@102 460 ::storage_type, Allocator, T, N> storage_test;
Chris@102 461
Chris@102 462 static const std::size_t needed_extra_storages = storage_test::needed_extra_storages;
Chris@102 463 static const std::size_t needed_bytes = storage_test::needed_bytes;
Chris@102 464 static const std::size_t header_bytes = storage_test::header_bytes;
Chris@102 465 static const std::size_t s_start = storage_test::s_start;
Chris@102 466
Chris@102 467 typedef typename base_type::allocator_type allocator_type;
Chris@102 468 typedef typename base_type::size_type size_type;
Chris@102 469 typedef typename base_type::value_type value_type;
Chris@102 470
Chris@102 471 static std::size_t internal_capacity()
Chris@102 472 { return (sizeof(small_vector) - storage_test::s_start)/sizeof(T); }
Chris@102 473
Chris@102 474 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 475
Chris@102 476 public:
Chris@102 477 small_vector()
Chris@102 478 : base_type(initial_capacity_t(), internal_capacity())
Chris@102 479 {}
Chris@102 480
Chris@102 481 explicit small_vector(size_type n)
Chris@102 482 : base_type(initial_capacity_t(), internal_capacity())
Chris@102 483 { this->resize(n); }
Chris@102 484
Chris@102 485 explicit small_vector(const allocator_type &a)
Chris@102 486 : base_type(initial_capacity_t(), internal_capacity(), a)
Chris@102 487 {}
Chris@102 488
Chris@102 489 small_vector(size_type n, const allocator_type &a)
Chris@102 490 : base_type(initial_capacity_t(), internal_capacity(), a)
Chris@102 491 { this->resize(n); }
Chris@102 492
Chris@102 493 small_vector(const small_vector &other)
Chris@102 494 : base_type( initial_capacity_t(), internal_capacity()
Chris@102 495 , allocator_traits_type::select_on_container_copy_construction(other.get_stored_allocator()))
Chris@102 496 { this->assign(other.cbegin(), other.cend()); }
Chris@102 497
Chris@102 498 small_vector(const small_vector &other, const allocator_type &a)
Chris@102 499 : base_type(initial_capacity_t(), internal_capacity(), a)
Chris@102 500 { this->assign(other.cbegin(), other.cend()); }
Chris@102 501
Chris@102 502 small_vector(BOOST_RV_REF(small_vector) other)
Chris@102 503 : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator()))
Chris@102 504 { this->move_construct_impl(other, other.get_stored_allocator()); }
Chris@102 505
Chris@102 506 small_vector(BOOST_RV_REF(small_vector) other, const allocator_type &a)
Chris@102 507 : base_type(initial_capacity_t(), internal_capacity(), a)
Chris@102 508 { this->move_construct_impl(other, a); }
Chris@102 509
Chris@102 510 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
Chris@102 511 small_vector(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
Chris@102 512 : base_type(initial_capacity_t(), internal_capacity(), a)
Chris@102 513 {
Chris@102 514 this->assign(il.begin(), il.end());
Chris@102 515 }
Chris@102 516 #endif
Chris@102 517
Chris@102 518 small_vector& operator=(BOOST_COPY_ASSIGN_REF(small_vector) other)
Chris@102 519 { return static_cast<small_vector&>(this->base_type::operator=(static_cast<base_type const&>(other))); }
Chris@102 520
Chris@102 521 small_vector& operator=(BOOST_RV_REF(small_vector) other)
Chris@102 522 { return static_cast<small_vector&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); }
Chris@102 523
Chris@102 524 void swap(small_vector &other)
Chris@102 525 { return this->base_type::swap(other); }
Chris@102 526
Chris@102 527 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 528 private:
Chris@102 529 void move_construct_impl(small_vector &x, const allocator_type &a)
Chris@102 530 {
Chris@102 531 if(base_type::is_propagable_from(x.get_stored_allocator(), x.data(), a, true)){
Chris@102 532 this->steal_resources(x);
Chris@102 533 }
Chris@102 534 else{
Chris@102 535 this->assign( boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.begin()))
Chris@102 536 , boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.end ()))
Chris@102 537 );
Chris@102 538 }
Chris@102 539 }
Chris@102 540 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 541 };
Chris@102 542
Chris@102 543 }}
Chris@102 544
Chris@102 545 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 546 /*
Chris@102 547 namespace boost {
Chris@102 548
Chris@102 549 //!has_trivial_destructor_after_move<> == true_type
Chris@102 550 //!specialization for optimizations
Chris@102 551 template <class T, class Allocator>
Chris@102 552 struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
Chris@102 553 {
Chris@102 554 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
Chris@102 555 static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
Chris@102 556 ::boost::has_trivial_destructor_after_move<pointer>::value;
Chris@102 557 };
Chris@102 558
Chris@102 559 }
Chris@102 560 */
Chris@102 561 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
Chris@102 562
Chris@102 563 #include <boost/container/detail/config_end.hpp>
Chris@102 564
Chris@102 565 #endif // #ifndef BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP