mirror of
https://github.com/boostorg/container.git
synced 2025-07-30 04:27:17 +02:00
Added stored_size
option to small_vector
This commit is contained in:
@ -803,6 +803,12 @@ the last template parameter and defined using the utility class
|
|||||||
[classref boost::container::growth_factor_60 growth_factor_60] and
|
[classref boost::container::growth_factor_60 growth_factor_60] and
|
||||||
[classref boost::container::growth_factor_50 growth_factor_100].
|
[classref boost::container::growth_factor_50 growth_factor_100].
|
||||||
|
|
||||||
|
* [classref boost::container::stored_size stored_size]: the type that will be used to store size-related
|
||||||
|
parameters inside of the vector. Sometimes, when the maximum capacity to be used is much less than the
|
||||||
|
theoretical maximum that a vector can hold, it's interesting to use smaller unsigned integer types to represent
|
||||||
|
`size()` and `capacity()` inside vector, so that the size of an empty vector is minimized and cache
|
||||||
|
performance might be improved. See [classref boost::container::stored_size stored_size] for more details.
|
||||||
|
|
||||||
See the following example to see how [classref boost::container::small_vector_options small_vector_options] can be
|
See the following example to see how [classref boost::container::small_vector_options small_vector_options] can be
|
||||||
used to customize `small_vector`:
|
used to customize `small_vector`:
|
||||||
|
|
||||||
@ -1417,7 +1423,9 @@ use [*Boost.Container]? There are several reasons for that:
|
|||||||
|
|
||||||
[section:release_notes_boost_1_87_00 Boost 1.87 Release]
|
[section:release_notes_boost_1_87_00 Boost 1.87 Release]
|
||||||
|
|
||||||
* Added [classref boost::container::stored_size stored_size] option to [classref boost::container::static_vector static_vector].
|
* Added [classref boost::container::stored_size stored_size] option to
|
||||||
|
[classref boost::container::static_vector static_vector] and
|
||||||
|
[classref boost::container::small_vector small_vector].
|
||||||
|
|
||||||
* Fixed bugs/issues:
|
* Fixed bugs/issues:
|
||||||
* [@https://github.com/boostorg/container/issues/261 GitHub #261: ['"End iterators are not dereferencable"]].
|
* [@https://github.com/boostorg/container/issues/261 GitHub #261: ['"End iterators are not dereferencable"]].
|
||||||
|
@ -41,6 +41,14 @@ int main ()
|
|||||||
growth_50_vector.push_back(1);
|
growth_50_vector.push_back(1);
|
||||||
assert(growth_50_vector.capacity() == old_cap*3/2);
|
assert(growth_50_vector.capacity() == old_cap*3/2);
|
||||||
|
|
||||||
|
//This option specifies that a vector that will use "unsigned char" as
|
||||||
|
//the type to store capacity or size internally.
|
||||||
|
typedef small_vector_options< stored_size<unsigned char> >::type size_option_t;
|
||||||
|
|
||||||
|
//Size-optimized vector is smaller than the default one.
|
||||||
|
typedef small_vector<int, 10, new_allocator<int>, size_option_t > size_optimized_vector_t;
|
||||||
|
assert((sizeof(size_optimized_vector_t) < sizeof(small_vector<int, 10>)));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//]
|
//]
|
||||||
|
@ -359,20 +359,23 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(inplace_alignment, std::size_t, Alignment, inpla
|
|||||||
|
|
||||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
template<class GrowthType, std::size_t InplaceAlignment>
|
template<class GrowthType, std::size_t InplaceAlignment, class StoredSizeType>
|
||||||
struct small_vector_opt
|
struct small_vector_opt
|
||||||
{
|
{
|
||||||
typedef GrowthType growth_factor_type;
|
typedef GrowthType growth_factor_type;
|
||||||
BOOST_STATIC_CONSTEXPR std::size_t inplace_alignment = InplaceAlignment;
|
BOOST_STATIC_CONSTEXPR std::size_t inplace_alignment = InplaceAlignment;
|
||||||
|
typedef StoredSizeType stored_size_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef small_vector_opt<void, 0u> small_vector_null_opt;
|
typedef small_vector_opt<void, 0u, void> small_vector_null_opt;
|
||||||
|
|
||||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
//! 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::inplace_alignment
|
//! Supported options are: \c boost::container::growth_factor,
|
||||||
|
//! \c boost::container::inplace_alignment and
|
||||||
|
//! \c boost::container::stored_size.
|
||||||
#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
|
||||||
@ -390,7 +393,9 @@ 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::inplace_alignment> implementation_defined;
|
, packed_options::inplace_alignment
|
||||||
|
, typename packed_options::stored_size_type
|
||||||
|
> implementation_defined;
|
||||||
/// @endcond
|
/// @endcond
|
||||||
typedef implementation_defined type;
|
typedef implementation_defined type;
|
||||||
};
|
};
|
||||||
|
@ -69,7 +69,9 @@ struct get_vopt_from_svopt
|
|||||||
: get_small_vector_opt<Options>::type
|
: get_small_vector_opt<Options>::type
|
||||||
{
|
{
|
||||||
typedef typename get_small_vector_opt<Options>::type options_t;
|
typedef typename get_small_vector_opt<Options>::type options_t;
|
||||||
typedef vector_opt< typename options_t::growth_factor_type, void> type;
|
typedef vector_opt< typename options_t::growth_factor_type
|
||||||
|
, typename options_t::stored_size_type
|
||||||
|
> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -340,9 +342,11 @@ struct small_vector_storage<T, 0u, Alignment>
|
|||||||
//!
|
//!
|
||||||
template <class T, class SecAlloc, class Options>
|
template <class T, class SecAlloc, class Options>
|
||||||
class small_vector_base
|
class small_vector_base
|
||||||
|
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
: public dtl::vector_for_small_vector<T, SecAlloc, Options>::type
|
: public dtl::vector_for_small_vector<T, SecAlloc, Options>::type
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKEDVECTOR
|
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
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
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
#include <boost/container/allocator.hpp>
|
||||||
#include <boost/core/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
using namespace boost::container;
|
using namespace boost::container;
|
||||||
@ -100,11 +101,58 @@ void test_growth_factor_100()
|
|||||||
BOOST_TEST(new_capacity == 2*old_capacity);
|
BOOST_TEST(new_capacity == 2*old_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Unsigned, class VectorType>
|
||||||
|
void test_stored_size_type_impl()
|
||||||
|
{
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
VectorType v;
|
||||||
|
typedef typename VectorType::size_type size_type;
|
||||||
|
typedef typename VectorType::value_type value_type;
|
||||||
|
size_type const max = Unsigned(-1);
|
||||||
|
v.resize(5);
|
||||||
|
v.resize(max);
|
||||||
|
BOOST_TEST_THROWS(v.resize(max+1), std::exception);
|
||||||
|
BOOST_TEST_THROWS(v.push_back(value_type(1)), std::exception);
|
||||||
|
BOOST_TEST_THROWS(v.insert(v.begin(), value_type(1)), std::exception);
|
||||||
|
BOOST_TEST_THROWS(v.emplace(v.begin(), value_type(1)),std::exception);
|
||||||
|
BOOST_TEST_THROWS(v.reserve(max+1), std::exception);
|
||||||
|
BOOST_TEST_THROWS(VectorType v2(max+1), std::exception);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Unsigned>
|
||||||
|
void test_stored_size_type()
|
||||||
|
{
|
||||||
|
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||||
|
using options_t = small_vector_options_t< stored_size<Unsigned> >;
|
||||||
|
#else
|
||||||
|
typedef typename small_vector_options
|
||||||
|
< stored_size<Unsigned> >::type options_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef small_vector<unsigned char, Unsigned(-1)> normal_small_vector_t;
|
||||||
|
|
||||||
|
//Test first with a typical allocator
|
||||||
|
{
|
||||||
|
typedef small_vector<unsigned char, Unsigned(-1), new_allocator<unsigned char>, options_t> small_vector_t;
|
||||||
|
test_stored_size_type_impl<Unsigned, small_vector_t>();
|
||||||
|
BOOST_CONTAINER_STATIC_ASSERT(sizeof(normal_small_vector_t) > sizeof(small_vector_t));
|
||||||
|
}
|
||||||
|
//Test with a V2 allocator
|
||||||
|
{
|
||||||
|
typedef small_vector<unsigned char, Unsigned(-1), allocator<unsigned char>, options_t> small_vector_t;
|
||||||
|
test_stored_size_type_impl<Unsigned, small_vector_t>();
|
||||||
|
BOOST_CONTAINER_STATIC_ASSERT(sizeof(normal_small_vector_t) > sizeof(small_vector_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_alignment();
|
test_alignment();
|
||||||
test_growth_factor_50();
|
test_growth_factor_50();
|
||||||
test_growth_factor_60();
|
test_growth_factor_60();
|
||||||
test_growth_factor_100();
|
test_growth_factor_100();
|
||||||
|
test_stored_size_type<unsigned char>();
|
||||||
|
test_stored_size_type<unsigned short>();
|
||||||
return ::boost::report_errors();
|
return ::boost::report_errors();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user