forked from boostorg/container
Added options for small_vector: inplace_alignment and growth_factor. Fixes #47
This commit is contained in:
@ -730,7 +730,7 @@ The configuration for [classref boost::container::static_vector static_vector] i
|
||||
the last template parameter and defined using the utility class
|
||||
[classref boost::container::static_vector_options static_vector_options]. The following parameters can be configured:
|
||||
|
||||
* [classref boost::container::alignment alignment]: the minimum alignment (in bytes) that the stored value type
|
||||
* [classref boost::container::inplace_alignment inplace_alignment]: the minimum alignment (in bytes) that the stored value type
|
||||
needs. This option allows static vectors that need non-default alignments, e.g., to be used in SIMD operations.
|
||||
|
||||
* [classref boost::container::throw_on_overflow throw_on_overflow]: A boolean that specifies if the
|
||||
@ -746,6 +746,33 @@ used to customize `static_vector` container:
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:configurable_small_vectors Configurable small vector]
|
||||
|
||||
The configuration for [classref boost::container::small_vector small_vector] is passed as
|
||||
the last template parameter and defined using the utility class
|
||||
[classref boost::container::small_vector_options small_vector_options]. The following parameters can be configured:
|
||||
|
||||
* [classref boost::container::inplace_alignment inplace_alignment]: the minimum alignment (in bytes) for the in-place storage
|
||||
used to build the "small" number of elements. [*The alignment of the dynamic memory must be provided by the allocator
|
||||
and it is not affected by this option].
|
||||
|
||||
* [classref boost::container::growth_factor growth_factor]: the growth policy of the vector.
|
||||
The rate at which the capacity of a vector grows is implementation dependent and
|
||||
implementations choose exponential growth in order to meet the amortized constant time requirement for push_back.
|
||||
A higher growth factor will make it faster as it will require less data movement, but it will have a greater memory
|
||||
impact (on average, more memory will be unused). A user can provide a custom implementation of the growth factor and some
|
||||
predefined policies are available: [classref boost::container::growth_factor_50 growth_factor_50],
|
||||
[classref boost::container::growth_factor_60 growth_factor_60] and
|
||||
[classref boost::container::growth_factor_50 growth_factor_100].
|
||||
|
||||
See the following example to see how [classref boost::container::small_vector_options small_vector_options] can be
|
||||
used to customize `small_vector` container:
|
||||
|
||||
[import ../example/doc_custom_small_vector.cpp]
|
||||
[doc_custom_small_vector]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:extended_allocators Extended functionality: Extended allocators]
|
||||
@ -1295,6 +1322,7 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
[section:release_notes_boost_1_71_00 Boost 1.71 Release]
|
||||
|
||||
* Fixed bugs:
|
||||
* [@https://github.com/boostorg/container/pull/47 GitHub #47: ['"added alignment specification for small_vector"]].
|
||||
* [@https://github.com/boostorg/container/issues/88 GitHub #88: ['"Implement C++17 MoveAssignable requirements for self-move assignments"]].
|
||||
* [@https://github.com/boostorg/container/issues/107 GitHub #107: ['"Alignment ignored in resource_adaptor"]].
|
||||
* [@https://github.com/boostorg/container/pull/109 GitHub #109: ['"Get rid of integer overflow in copy_move_algo.hpp (-fsanitize=integer)"]].
|
||||
@ -1309,7 +1337,10 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
The block size/bytes can be be specified.
|
||||
|
||||
* [classref boost::container::static_vector static_vector] can now have options, using [classref boost::container::static_vector_options static_vector_options].
|
||||
The alignment and throwing behaviour can be be specified.
|
||||
Alignment and throwing behaviour can be be specified.
|
||||
|
||||
* [classref boost::container::small_vector small_vector] can now have options, using [classref boost::container::small_vector_options small_vector_options].
|
||||
Alignment and growth factor can be be specified.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@ -77,7 +77,7 @@ namespace container {
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
template<class T, class VoidAllocator>
|
||||
template<class T, class VoidAllocator, class Options>
|
||||
class small_vector_allocator;
|
||||
|
||||
namespace allocator_traits_detail {
|
||||
@ -99,8 +99,8 @@ template<class T>
|
||||
struct is_std_allocator< std::allocator<T> >
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<class T>
|
||||
struct is_std_allocator< small_vector_allocator<T, std::allocator<T> > >
|
||||
template<class T, class Options>
|
||||
struct is_std_allocator< small_vector_allocator<T, std::allocator<T>, Options > >
|
||||
{ static const bool value = true; };
|
||||
|
||||
template<class Allocator>
|
||||
|
@ -106,14 +106,20 @@ template <class T
|
||||
,class Allocator = void >
|
||||
class stable_vector;
|
||||
|
||||
template <class T, std::size_t Capacity, class Options = void>
|
||||
template < class T
|
||||
, std::size_t Capacity
|
||||
, class Options = void>
|
||||
class static_vector;
|
||||
|
||||
template <class T, class Allocator = void >
|
||||
template < class T
|
||||
, class Allocator = void
|
||||
, class Options = void >
|
||||
class small_vector_base;
|
||||
|
||||
template < class T, std::size_t N
|
||||
, class Allocator = void >
|
||||
template < class T
|
||||
, std::size_t N
|
||||
, class Allocator = void
|
||||
, class Options = void >
|
||||
class small_vector;
|
||||
|
||||
template <class T
|
||||
|
@ -45,8 +45,9 @@ namespace impl{
|
||||
|
||||
template <class T>
|
||||
struct extract_version
|
||||
: T::version
|
||||
{};
|
||||
{
|
||||
typedef typename T::version type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct has_version
|
||||
@ -69,7 +70,7 @@ struct version
|
||||
template <class T>
|
||||
struct version<T, true>
|
||||
{
|
||||
static const unsigned value = extract_version<T>::value;
|
||||
static const unsigned value = extract_version<T>::type::value;
|
||||
};
|
||||
|
||||
} //namespace impl
|
||||
|
@ -102,6 +102,65 @@ using tree_assoc_options_t = typename boost::container::tree_assoc_options<Optio
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// OPTIONS FOR ASSOCIATIVE HASH-BASED CONTAINERS
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template<bool StoreHash>
|
||||
struct hash_opt
|
||||
{
|
||||
static const bool store_hash = StoreHash;
|
||||
};
|
||||
|
||||
typedef hash_opt<false> hash_assoc_defaults;
|
||||
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
//!This option setter specifies if node size is optimized
|
||||
//!storing rebalancing data masked into pointers for ordered associative containers
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash)
|
||||
|
||||
//! Helper metafunction to combine options into a single type to be used
|
||||
//! by \c boost::container::hash_set, \c boost::container::hash_multiset
|
||||
//! \c boost::container::hash_map and \c boost::container::hash_multimap.
|
||||
//! Supported options are: \c boost::container::store_hash
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct hash_assoc_options
|
||||
{
|
||||
/// @cond
|
||||
typedef typename ::boost::intrusive::pack_options
|
||||
< hash_assoc_defaults,
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type packed_options;
|
||||
typedef hash_opt<packed_options::store_hash> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
|
||||
//! Helper alias metafunction to combine options into a single type to be used
|
||||
//! by hash-based associative containers
|
||||
template<class ...Options>
|
||||
using hash_assoc_options_t = typename boost::container::hash_assoc_options<Options...>::type;
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
@ -266,15 +325,15 @@ using vector_options_t = typename boost::container::vector_options<Options...>::
|
||||
//! A value zero represents the natural alignment.
|
||||
//!
|
||||
//!\tparam Alignment An unsigned integer value. Must be power of two.
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(alignment, std::size_t, Alignment, alignment)
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(inplace_alignment, std::size_t, Alignment, inplace_alignment)
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template<class GrowthType, std::size_t Alignment>
|
||||
template<class GrowthType, std::size_t InplaceAlignment>
|
||||
struct small_vector_opt
|
||||
{
|
||||
typedef GrowthType growth_factor_type;
|
||||
static const std::size_t alignment = Alignment;
|
||||
static const std::size_t inplace_alignment = InplaceAlignment;
|
||||
};
|
||||
|
||||
typedef small_vector_opt<void, 0u> small_vector_null_opt;
|
||||
@ -283,7 +342,7 @@ typedef small_vector_opt<void, 0u> small_vector_null_opt;
|
||||
|
||||
//! Helper metafunction to combine options into a single type to be used
|
||||
//! by \c boost::container::small_vector.
|
||||
//! Supported options are: \c boost::container::growth_factor and \c boost::container::alignment
|
||||
//! Supported options are: \c boost::container::growth_factor and \c boost::container::inplace_alignment
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
@ -301,7 +360,7 @@ struct small_vector_options
|
||||
#endif
|
||||
>::type packed_options;
|
||||
typedef small_vector_opt< typename packed_options::growth_factor_type
|
||||
, packed_options::alignment> implementation_defined;
|
||||
, packed_options::inplace_alignment> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
@ -337,11 +396,11 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(throw_on_overflow, bool, ThrowOnOverflow, throw_
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template<bool ThrowOnOverflow, std::size_t Alignment>
|
||||
template<bool ThrowOnOverflow, std::size_t InplaceAlignment>
|
||||
struct static_vector_opt
|
||||
{
|
||||
static const bool throw_on_overflow = ThrowOnOverflow;
|
||||
static const std::size_t alignment = Alignment;
|
||||
static const std::size_t inplace_alignment = InplaceAlignment;
|
||||
};
|
||||
|
||||
typedef static_vector_opt<true, 0u> static_vector_null_opt;
|
||||
@ -350,7 +409,7 @@ typedef static_vector_opt<true, 0u> static_vector_null_opt;
|
||||
|
||||
//! Helper metafunction to combine options into a single type to be used
|
||||
//! by \c boost::container::static_vector.
|
||||
//! Supported options are: \c boost::container::throw_on_overflow and \c boost::container::alignment
|
||||
//! Supported options are: \c boost::container::throw_on_overflow and \c boost::container::inplace_alignment
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
@ -368,7 +427,7 @@ struct static_vector_options
|
||||
#endif
|
||||
>::type packed_options;
|
||||
typedef static_vector_opt< packed_options::throw_on_overflow
|
||||
, packed_options::alignment> implementation_defined;
|
||||
, packed_options::inplace_alignment> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
@ -48,6 +48,49 @@
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
namespace dtl{
|
||||
|
||||
template<class Options>
|
||||
struct get_small_vector_opt
|
||||
{
|
||||
typedef Options type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct get_small_vector_opt<void>
|
||||
{
|
||||
typedef small_vector_null_opt type;
|
||||
};
|
||||
|
||||
template<class Options>
|
||||
struct get_vopt_from_svopt
|
||||
: get_small_vector_opt<Options>::type
|
||||
{
|
||||
typedef typename get_small_vector_opt<Options>::type options_t;
|
||||
typedef vector_opt< typename options_t::growth_factor_type, void> type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct get_vopt_from_svopt<void>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <class T, class SecondaryAllocator, class Options>
|
||||
struct vector_for_small_vector
|
||||
{
|
||||
typedef vector
|
||||
< T
|
||||
, small_vector_allocator
|
||||
< T
|
||||
, typename allocator_traits<typename real_allocator<T, SecondaryAllocator>::type>::template portable_rebind_alloc<void>::type
|
||||
, Options>
|
||||
, typename dtl::get_vopt_from_svopt<Options>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
} //namespace dtl
|
||||
|
||||
//! A non-standard allocator used to implement `small_vector`.
|
||||
//! Users should never use it directly. It is described here
|
||||
//! for documentation purposes.
|
||||
@ -74,7 +117,7 @@ namespace container {
|
||||
//! `boost::container::vector< T, small_vector_allocator<T, Allocator> >`
|
||||
//! and internal storage can be obtained downcasting that vector
|
||||
//! to `small_vector_base<T>`.
|
||||
template<class T, class VoidAllocator BOOST_CONTAINER_DOCONLY(= void)>
|
||||
template<class T, class VoidAllocator BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void)>
|
||||
class small_vector_allocator
|
||||
: public allocator_traits<typename real_allocator<T, VoidAllocator>::type>::template portable_rebind_alloc<T>::type
|
||||
{
|
||||
@ -146,17 +189,17 @@ class small_vector_allocator
|
||||
|
||||
//!Constructor from related small_vector_allocator.
|
||||
//!Never throws
|
||||
template<class U, class OtherVoidAllocator>
|
||||
template<class U, class OtherVoidAllocator, class OtherOptions>
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector_allocator
|
||||
(const small_vector_allocator<U, OtherVoidAllocator> &other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
(const small_vector_allocator<U, OtherVoidAllocator, OtherOptions> &other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: allocator_type(other.as_base())
|
||||
{}
|
||||
|
||||
//!Move constructor from related small_vector_allocator.
|
||||
//!Never throws
|
||||
template<class U, class OtherVoidAllocator>
|
||||
template<class U, class OtherVoidAllocator, class OtherOptions>
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector_allocator
|
||||
(BOOST_RV_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
(BOOST_RV_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator BOOST_MOVE_I OtherOptions>) other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: allocator_type(::boost::move(other.as_base()))
|
||||
{}
|
||||
|
||||
@ -183,14 +226,14 @@ class small_vector_allocator
|
||||
//!Never throws
|
||||
template<class U, class OtherVoidAllocator>
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector_allocator &
|
||||
operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator BOOST_MOVE_I Options>) other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return static_cast<small_vector_allocator&>(this->allocator_type::operator=(other.as_base())); }
|
||||
|
||||
//!Move assignment from related small_vector_allocator.
|
||||
//!Never throws
|
||||
template<class U, class OtherVoidAllocator>
|
||||
BOOST_CONTAINER_FORCEINLINE small_vector_allocator &
|
||||
operator=(BOOST_RV_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
operator=(BOOST_RV_REF(small_vector_allocator<U BOOST_MOVE_I OtherVoidAllocator BOOST_MOVE_I Options>) other) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return static_cast<small_vector_allocator&>(this->allocator_type::operator=(::boost::move(other.as_base()))); }
|
||||
|
||||
//!Move assignment from allocator_type.
|
||||
@ -271,8 +314,8 @@ class small_vector_allocator
|
||||
using allocator_type::deallocate_many;*/
|
||||
|
||||
typedef vector_alloc_holder< small_vector_allocator, size_type > vector_alloc_holder_t;
|
||||
typedef vector<value_type, small_vector_allocator> vector_base;
|
||||
typedef small_vector_base<value_type, allocator_type> derived_type;
|
||||
typedef typename dtl::vector_for_small_vector<T, allocator_type, Options>::type vector_base;
|
||||
typedef small_vector_base<value_type, allocator_type, Options> derived_type;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE bool is_internal_storage(const_pointer p) const
|
||||
{ return this->internal_storage() == p; }
|
||||
@ -322,33 +365,30 @@ class small_vector_allocator
|
||||
//!
|
||||
//! All `boost::container:vector` member functions are inherited. See `vector` documentation for details.
|
||||
//!
|
||||
template <class T, class SecondaryAllocator>
|
||||
template <class T, class SecondaryAllocator, class Options>
|
||||
class small_vector_base
|
||||
: public vector
|
||||
< T
|
||||
, small_vector_allocator
|
||||
< T
|
||||
, typename allocator_traits<typename real_allocator<T, SecondaryAllocator>::type>::template portable_rebind_alloc<void>::type
|
||||
>
|
||||
>
|
||||
: public dtl::vector_for_small_vector<T, SecondaryAllocator, Options>::type
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKEDVECTOR
|
||||
public:
|
||||
//Make it public as it will be inherited by small_vector and container
|
||||
//must have this public member
|
||||
typedef typename real_allocator<T, SecondaryAllocator>::type secondary_allocator_t;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::template portable_rebind_alloc<void>::type void_allocator_t;
|
||||
typedef vector<T, small_vector_allocator<T, void_allocator_t> > base_type;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::pointer pointer;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::const_pointer const_pointer;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::void_pointer void_pointer;
|
||||
typedef typename real_allocator<T, SecondaryAllocator>::type secondary_allocator_t;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::
|
||||
template portable_rebind_alloc<void>::type void_allocator_t;
|
||||
typedef typename dtl::get_small_vector_opt<Options>::type options_t;
|
||||
typedef typename dtl::vector_for_small_vector
|
||||
<T, SecondaryAllocator, Options>::type base_type;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::pointer pointer;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::const_pointer const_pointer;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::void_pointer void_pointer;
|
||||
typedef typename allocator_traits<secondary_allocator_t>::const_void_pointer const_void_pointer;
|
||||
typedef small_vector_allocator<T, void_allocator_t> allocator_type;
|
||||
typedef small_vector_allocator<T, void_allocator_t, Options> allocator_type;
|
||||
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(small_vector_base)
|
||||
|
||||
friend class small_vector_allocator<T, void_allocator_t>;
|
||||
friend class small_vector_allocator<T, void_allocator_t, Options>;
|
||||
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
const_pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
@ -373,9 +413,12 @@ class small_vector_base
|
||||
base_type &as_base() { return static_cast<base_type&>(*this); }
|
||||
const base_type &as_base() const { return static_cast<const base_type&>(*this); }
|
||||
|
||||
static const std::size_t final_alignment =
|
||||
options_t::inplace_alignment ? options_t::inplace_alignment : dtl::alignment_of<T>::value;
|
||||
public:
|
||||
|
||||
typedef typename dtl::aligned_storage
|
||||
<sizeof(T), dtl::alignment_of<T>::value>::type storage_type;
|
||||
<sizeof(T), final_alignment>::type storage_type;
|
||||
|
||||
protected:
|
||||
|
||||
@ -441,13 +484,14 @@ struct small_vector_storage_calculator_helper<Needed, Hdr, SSize, true>
|
||||
static const std::size_t value = 0u;
|
||||
};
|
||||
|
||||
template<class Storage, class Allocator, class T, std::size_t N>
|
||||
template<class Storage, class Allocator, class T, std::size_t N, class Options>
|
||||
struct small_vector_storage_calculator
|
||||
{
|
||||
typedef small_vector_base<T, Allocator> svh_type;
|
||||
typedef small_vector_base<T, Allocator, Options> svh_type;
|
||||
typedef typename real_allocator<T, Allocator>::type value_allocator_t;
|
||||
typedef typename allocator_traits<value_allocator_t>::template portable_rebind_alloc<void>::type void_allocator_t;
|
||||
typedef vector<T, small_vector_allocator<T, void_allocator_t> > svhb_type;
|
||||
typedef typename dtl::vector_for_small_vector<T, void_allocator_t, Options>::type svhb_type;
|
||||
|
||||
static const std::size_t s_align = dtl::alignment_of<Storage>::value;
|
||||
static const std::size_t s_size = sizeof(Storage);
|
||||
static const std::size_t svh_sizeof = sizeof(svh_type);
|
||||
@ -474,13 +518,13 @@ template<class Storage>
|
||||
struct small_vector_storage<Storage, 0>
|
||||
{};
|
||||
|
||||
template<class T, class Allocator, std::size_t N>
|
||||
template<class T, class Allocator, std::size_t N, class Options>
|
||||
struct small_vector_storage_definer
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef typename small_vector_base<value_type, Allocator>::storage_type storage_type;
|
||||
typedef typename small_vector_base<value_type, Allocator, Options>::storage_type storage_type;
|
||||
static const std::size_t needed_extra_storages =
|
||||
small_vector_storage_calculator<storage_type, Allocator, value_type, N>::needed_extra_storages;
|
||||
small_vector_storage_calculator<storage_type, Allocator, value_type, N, Options>::needed_extra_storages;
|
||||
typedef small_vector_storage<storage_type, needed_extra_storages> type;
|
||||
};
|
||||
|
||||
@ -490,7 +534,7 @@ struct small_vector_storage_definer
|
||||
//! It contains some preallocated elements in-place, which can avoid the use of dynamic storage allocation
|
||||
//! when the actual number of elements is below that preallocated threshold.
|
||||
//!
|
||||
//! `small_vector<T, N, Allocator>` is convertible to `small_vector_base<T, Allocator>` that is independent
|
||||
//! `small_vector<T, N, Allocator, Options>` is convertible to `small_vector_base<T, Allocator, Options>` that is independent
|
||||
//! from the preallocated element capacity, so client code does not need to be templated on that N argument.
|
||||
//!
|
||||
//! All `boost::container::vector` member functions are inherited. See `vector` documentation for details.
|
||||
@ -499,23 +543,26 @@ struct small_vector_storage_definer
|
||||
//! \tparam N The number of preallocated elements stored inside small_vector. It shall be less than Allocator::max_size();
|
||||
//! \tparam Allocator The allocator used for memory management when the number of elements exceeds N. Use void
|
||||
//! for the default allocator
|
||||
template <class T, std::size_t N, class Allocator BOOST_CONTAINER_DOCONLY(= void) >
|
||||
class small_vector : public small_vector_base<T, Allocator>
|
||||
//! |tparam Options A type produced from \c boost::container::small_vector_options.
|
||||
template <class T, std::size_t N, class Allocator BOOST_CONTAINER_DOCONLY(= void), class Options BOOST_CONTAINER_DOCONLY(= void) >
|
||||
class small_vector : public small_vector_base<T, Allocator, Options>
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
, private small_vector_storage_definer<T, Allocator, N>::type
|
||||
, private small_vector_storage_definer<T, Allocator, N, Options>::type
|
||||
#endif
|
||||
{
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
typedef small_vector_base<T, Allocator> base_type;
|
||||
typedef typename small_vector_storage_definer<T, Allocator, N>::type remaining_storage_holder;
|
||||
typedef small_vector_base<T, Allocator, Options> base_type;
|
||||
typedef typename small_vector_storage_definer
|
||||
<T, Allocator, N, Options>::type remaining_storage_holder;
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(small_vector)
|
||||
|
||||
typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type;
|
||||
|
||||
public:
|
||||
typedef small_vector_storage_calculator< typename small_vector_base<T, Allocator>
|
||||
::storage_type, Allocator, T, N> storage_test;
|
||||
typedef small_vector_storage_calculator
|
||||
< typename small_vector_base<T, Allocator, Options>::storage_type
|
||||
, Allocator, T, N, Options> storage_test;
|
||||
|
||||
static const std::size_t needed_extra_storages = storage_test::needed_extra_storages;
|
||||
static const std::size_t needed_bytes = storage_test::needed_bytes;
|
||||
|
Reference in New Issue
Block a user