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
|
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::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.
|
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
|
* [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]
|
[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]
|
[endsect]
|
||||||
|
|
||||||
[section:extended_allocators Extended functionality: Extended allocators]
|
[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]
|
[section:release_notes_boost_1_71_00 Boost 1.71 Release]
|
||||||
|
|
||||||
* Fixed bugs:
|
* 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/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/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)"]].
|
* [@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.
|
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].
|
* [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]
|
[endsect]
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ namespace container {
|
|||||||
|
|
||||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
|
|
||||||
template<class T, class VoidAllocator>
|
template<class T, class VoidAllocator, class Options>
|
||||||
class small_vector_allocator;
|
class small_vector_allocator;
|
||||||
|
|
||||||
namespace allocator_traits_detail {
|
namespace allocator_traits_detail {
|
||||||
@ -99,8 +99,8 @@ template<class T>
|
|||||||
struct is_std_allocator< std::allocator<T> >
|
struct is_std_allocator< std::allocator<T> >
|
||||||
{ static const bool value = true; };
|
{ static const bool value = true; };
|
||||||
|
|
||||||
template<class T>
|
template<class T, class Options>
|
||||||
struct is_std_allocator< small_vector_allocator<T, std::allocator<T> > >
|
struct is_std_allocator< small_vector_allocator<T, std::allocator<T>, Options > >
|
||||||
{ static const bool value = true; };
|
{ static const bool value = true; };
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
|
@ -106,14 +106,20 @@ template <class T
|
|||||||
,class Allocator = void >
|
,class Allocator = void >
|
||||||
class stable_vector;
|
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;
|
class static_vector;
|
||||||
|
|
||||||
template <class T, class Allocator = void >
|
template < class T
|
||||||
|
, class Allocator = void
|
||||||
|
, class Options = void >
|
||||||
class small_vector_base;
|
class small_vector_base;
|
||||||
|
|
||||||
template < class T, std::size_t N
|
template < class T
|
||||||
, class Allocator = void >
|
, std::size_t N
|
||||||
|
, class Allocator = void
|
||||||
|
, class Options = void >
|
||||||
class small_vector;
|
class small_vector;
|
||||||
|
|
||||||
template <class T
|
template <class T
|
||||||
|
@ -45,8 +45,9 @@ namespace impl{
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct extract_version
|
struct extract_version
|
||||||
: T::version
|
{
|
||||||
{};
|
typedef typename T::version type;
|
||||||
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct has_version
|
struct has_version
|
||||||
@ -69,7 +70,7 @@ struct version
|
|||||||
template <class T>
|
template <class T>
|
||||||
struct version<T, true>
|
struct version<T, true>
|
||||||
{
|
{
|
||||||
static const unsigned value = extract_version<T>::value;
|
static const unsigned value = extract_version<T>::type::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace impl
|
} //namespace impl
|
||||||
|
@ -102,6 +102,65 @@ using tree_assoc_options_t = typename boost::container::tree_assoc_options<Optio
|
|||||||
|
|
||||||
#endif
|
#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.
|
//! A value zero represents the natural alignment.
|
||||||
//!
|
//!
|
||||||
//!\tparam Alignment An unsigned integer value. Must be power of two.
|
//!\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)
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
template<class GrowthType, std::size_t Alignment>
|
template<class GrowthType, std::size_t InplaceAlignment>
|
||||||
struct small_vector_opt
|
struct small_vector_opt
|
||||||
{
|
{
|
||||||
typedef GrowthType growth_factor_type;
|
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;
|
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
|
//! Helper metafunction to combine options into a single type to be used
|
||||||
//! by \c boost::container::small_vector.
|
//! 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)
|
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||||
template<class ...Options>
|
template<class ...Options>
|
||||||
#else
|
#else
|
||||||
@ -301,7 +360,7 @@ struct small_vector_options
|
|||||||
#endif
|
#endif
|
||||||
>::type packed_options;
|
>::type packed_options;
|
||||||
typedef small_vector_opt< typename packed_options::growth_factor_type
|
typedef small_vector_opt< typename packed_options::growth_factor_type
|
||||||
, packed_options::alignment> implementation_defined;
|
, packed_options::inplace_alignment> implementation_defined;
|
||||||
/// @endcond
|
/// @endcond
|
||||||
typedef implementation_defined type;
|
typedef implementation_defined type;
|
||||||
};
|
};
|
||||||
@ -337,11 +396,11 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(throw_on_overflow, bool, ThrowOnOverflow, throw_
|
|||||||
|
|
||||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
template<bool ThrowOnOverflow, std::size_t Alignment>
|
template<bool ThrowOnOverflow, std::size_t InplaceAlignment>
|
||||||
struct static_vector_opt
|
struct static_vector_opt
|
||||||
{
|
{
|
||||||
static const bool throw_on_overflow = ThrowOnOverflow;
|
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;
|
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
|
//! Helper metafunction to combine options into a single type to be used
|
||||||
//! by \c boost::container::static_vector.
|
//! 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)
|
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
||||||
template<class ...Options>
|
template<class ...Options>
|
||||||
#else
|
#else
|
||||||
@ -368,7 +427,7 @@ struct static_vector_options
|
|||||||
#endif
|
#endif
|
||||||
>::type packed_options;
|
>::type packed_options;
|
||||||
typedef static_vector_opt< packed_options::throw_on_overflow
|
typedef static_vector_opt< packed_options::throw_on_overflow
|
||||||
, packed_options::alignment> implementation_defined;
|
, packed_options::inplace_alignment> implementation_defined;
|
||||||
/// @endcond
|
/// @endcond
|
||||||
typedef implementation_defined type;
|
typedef implementation_defined type;
|
||||||
};
|
};
|
||||||
|
@ -48,6 +48,49 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace container {
|
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`.
|
//! A non-standard allocator used to implement `small_vector`.
|
||||||
//! Users should never use it directly. It is described here
|
//! Users should never use it directly. It is described here
|
||||||
//! for documentation purposes.
|
//! for documentation purposes.
|
||||||
@ -74,7 +117,7 @@ namespace container {
|
|||||||
//! `boost::container::vector< T, small_vector_allocator<T, Allocator> >`
|
//! `boost::container::vector< T, small_vector_allocator<T, Allocator> >`
|
||||||
//! and internal storage can be obtained downcasting that vector
|
//! and internal storage can be obtained downcasting that vector
|
||||||
//! to `small_vector_base<T>`.
|
//! 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
|
class small_vector_allocator
|
||||||
: public allocator_traits<typename real_allocator<T, VoidAllocator>::type>::template portable_rebind_alloc<T>::type
|
: 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.
|
//!Constructor from related small_vector_allocator.
|
||||||
//!Never throws
|
//!Never throws
|
||||||
template<class U, class OtherVoidAllocator>
|
template<class U, class OtherVoidAllocator, class OtherOptions>
|
||||||
BOOST_CONTAINER_FORCEINLINE small_vector_allocator
|
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())
|
: allocator_type(other.as_base())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//!Move constructor from related small_vector_allocator.
|
//!Move constructor from related small_vector_allocator.
|
||||||
//!Never throws
|
//!Never throws
|
||||||
template<class U, class OtherVoidAllocator>
|
template<class U, class OtherVoidAllocator, class OtherOptions>
|
||||||
BOOST_CONTAINER_FORCEINLINE small_vector_allocator
|
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()))
|
: allocator_type(::boost::move(other.as_base()))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -183,14 +226,14 @@ class small_vector_allocator
|
|||||||
//!Never throws
|
//!Never throws
|
||||||
template<class U, class OtherVoidAllocator>
|
template<class U, class OtherVoidAllocator>
|
||||||
BOOST_CONTAINER_FORCEINLINE small_vector_allocator &
|
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())); }
|
{ return static_cast<small_vector_allocator&>(this->allocator_type::operator=(other.as_base())); }
|
||||||
|
|
||||||
//!Move assignment from related small_vector_allocator.
|
//!Move assignment from related small_vector_allocator.
|
||||||
//!Never throws
|
//!Never throws
|
||||||
template<class U, class OtherVoidAllocator>
|
template<class U, class OtherVoidAllocator>
|
||||||
BOOST_CONTAINER_FORCEINLINE small_vector_allocator &
|
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()))); }
|
{ return static_cast<small_vector_allocator&>(this->allocator_type::operator=(::boost::move(other.as_base()))); }
|
||||||
|
|
||||||
//!Move assignment from allocator_type.
|
//!Move assignment from allocator_type.
|
||||||
@ -271,8 +314,8 @@ class small_vector_allocator
|
|||||||
using allocator_type::deallocate_many;*/
|
using allocator_type::deallocate_many;*/
|
||||||
|
|
||||||
typedef vector_alloc_holder< small_vector_allocator, size_type > vector_alloc_holder_t;
|
typedef vector_alloc_holder< small_vector_allocator, size_type > vector_alloc_holder_t;
|
||||||
typedef vector<value_type, small_vector_allocator> vector_base;
|
typedef typename dtl::vector_for_small_vector<T, allocator_type, Options>::type vector_base;
|
||||||
typedef small_vector_base<value_type, allocator_type> derived_type;
|
typedef small_vector_base<value_type, allocator_type, Options> derived_type;
|
||||||
|
|
||||||
BOOST_CONTAINER_FORCEINLINE bool is_internal_storage(const_pointer p) const
|
BOOST_CONTAINER_FORCEINLINE bool is_internal_storage(const_pointer p) const
|
||||||
{ return this->internal_storage() == p; }
|
{ 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.
|
//! 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
|
class small_vector_base
|
||||||
: public vector
|
: public dtl::vector_for_small_vector<T, SecondaryAllocator, Options>::type
|
||||||
< T
|
|
||||||
, small_vector_allocator
|
|
||||||
< T
|
|
||||||
, typename allocator_traits<typename real_allocator<T, SecondaryAllocator>::type>::template portable_rebind_alloc<void>::type
|
|
||||||
>
|
|
||||||
>
|
|
||||||
{
|
{
|
||||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKEDVECTOR
|
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKEDVECTOR
|
||||||
public:
|
public:
|
||||||
//Make it public as it will be inherited by small_vector and container
|
//Make it public as it will be inherited by small_vector and container
|
||||||
//must have this public member
|
//must have this public member
|
||||||
typedef typename real_allocator<T, SecondaryAllocator>::type secondary_allocator_t;
|
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 allocator_traits<secondary_allocator_t>::
|
||||||
typedef vector<T, small_vector_allocator<T, void_allocator_t> > base_type;
|
template portable_rebind_alloc<void>::type void_allocator_t;
|
||||||
typedef typename allocator_traits<secondary_allocator_t>::pointer pointer;
|
typedef typename dtl::get_small_vector_opt<Options>::type options_t;
|
||||||
typedef typename allocator_traits<secondary_allocator_t>::const_pointer const_pointer;
|
typedef typename dtl::vector_for_small_vector
|
||||||
typedef typename allocator_traits<secondary_allocator_t>::void_pointer void_pointer;
|
<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 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:
|
private:
|
||||||
BOOST_COPYABLE_AND_MOVABLE(small_vector_base)
|
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
|
BOOST_CONTAINER_FORCEINLINE
|
||||||
const_pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
|
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); }
|
base_type &as_base() { return static_cast<base_type&>(*this); }
|
||||||
const base_type &as_base() const { return static_cast<const 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:
|
public:
|
||||||
|
|
||||||
typedef typename dtl::aligned_storage
|
typedef typename dtl::aligned_storage
|
||||||
<sizeof(T), dtl::alignment_of<T>::value>::type storage_type;
|
<sizeof(T), final_alignment>::type storage_type;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -441,13 +484,14 @@ struct small_vector_storage_calculator_helper<Needed, Hdr, SSize, true>
|
|||||||
static const std::size_t value = 0u;
|
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
|
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 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 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_align = dtl::alignment_of<Storage>::value;
|
||||||
static const std::size_t s_size = sizeof(Storage);
|
static const std::size_t s_size = sizeof(Storage);
|
||||||
static const std::size_t svh_sizeof = sizeof(svh_type);
|
static const std::size_t svh_sizeof = sizeof(svh_type);
|
||||||
@ -474,13 +518,13 @@ template<class Storage>
|
|||||||
struct small_vector_storage<Storage, 0>
|
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
|
struct small_vector_storage_definer
|
||||||
{
|
{
|
||||||
typedef T value_type;
|
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 =
|
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;
|
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
|
//! 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.
|
//! 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.
|
//! 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.
|
//! 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 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
|
//! \tparam Allocator The allocator used for memory management when the number of elements exceeds N. Use void
|
||||||
//! for the default allocator
|
//! for the default allocator
|
||||||
template <class T, std::size_t N, class Allocator BOOST_CONTAINER_DOCONLY(= void) >
|
//! |tparam Options A type produced from \c boost::container::small_vector_options.
|
||||||
class small_vector : public small_vector_base<T, Allocator>
|
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
|
#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
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
typedef small_vector_base<T, Allocator> base_type;
|
typedef small_vector_base<T, Allocator, Options> base_type;
|
||||||
typedef typename small_vector_storage_definer<T, Allocator, N>::type remaining_storage_holder;
|
typedef typename small_vector_storage_definer
|
||||||
|
<T, Allocator, N, Options>::type remaining_storage_holder;
|
||||||
|
|
||||||
BOOST_COPYABLE_AND_MOVABLE(small_vector)
|
BOOST_COPYABLE_AND_MOVABLE(small_vector)
|
||||||
|
|
||||||
typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type;
|
typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef small_vector_storage_calculator< typename small_vector_base<T, Allocator>
|
typedef small_vector_storage_calculator
|
||||||
::storage_type, Allocator, T, N> storage_test;
|
< 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_extra_storages = storage_test::needed_extra_storages;
|
||||||
static const std::size_t needed_bytes = storage_test::needed_bytes;
|
static const std::size_t needed_bytes = storage_test::needed_bytes;
|
||||||
|
Reference in New Issue
Block a user