blob: 2ac7783e46305fc1b8c2e42da744878a1706de63 [file] [log] [blame]
Brian Silvermanfad8f552018-08-04 23:36:19 -07001/////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2013-2013
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// See http://www.boost.org/libs/container for documentation.
10//
11/////////////////////////////////////////////////////////////////////////////
12
13#ifndef BOOST_CONTAINER_OPTIONS_HPP
14#define BOOST_CONTAINER_OPTIONS_HPP
15
16#ifndef BOOST_CONFIG_HPP
17# include <boost/config.hpp>
18#endif
19
20#if defined(BOOST_HAS_PRAGMA_ONCE)
21# pragma once
22#endif
23
24#include <boost/container/detail/config_begin.hpp>
25#include <boost/container/container_fwd.hpp>
26#include <boost/intrusive/pack_options.hpp>
27
28namespace boost {
29namespace container {
30
31////////////////////////////////////////////////////////////////
32//
33//
34// OPTIONS FOR ASSOCIATIVE TREE-BASED CONTAINERS
35//
36//
37////////////////////////////////////////////////////////////////
38
39//! Enumeration used to configure ordered associative containers
40//! with a concrete tree implementation.
41enum tree_type_enum
42{
43 red_black_tree,
44 avl_tree,
45 scapegoat_tree,
46 splay_tree
47};
48
49#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
50
51template<tree_type_enum TreeType, bool OptimizeSize>
52struct tree_opt
53{
54 static const boost::container::tree_type_enum tree_type = TreeType;
55 static const bool optimize_size = OptimizeSize;
56};
57
58typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
59
60#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
61
62//!This option setter specifies the underlying tree type
63//!(red-black, AVL, Scapegoat or Splay) for ordered associative containers
64BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type)
65
66//!This option setter specifies if node size is optimized
67//!storing rebalancing data masked into pointers for ordered associative containers
68BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
69
70//! Helper metafunction to combine options into a single type to be used
71//! by \c boost::container::set, \c boost::container::multiset
72//! \c boost::container::map and \c boost::container::multimap.
73//! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type
74#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
75template<class ...Options>
76#else
77template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
78#endif
79struct tree_assoc_options
80{
81 /// @cond
82 typedef typename ::boost::intrusive::pack_options
83 < tree_assoc_defaults,
84 #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
85 O1, O2, O3, O4
86 #else
87 Options...
88 #endif
89 >::type packed_options;
90 typedef tree_opt<packed_options::tree_type, packed_options::optimize_size> implementation_defined;
91 /// @endcond
92 typedef implementation_defined type;
93};
94
95#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
96
97//! Helper alias metafunction to combine options into a single type to be used
98//! by tree-based associative containers
99template<class ...Options>
100using tree_assoc_options_t = typename boost::container::tree_assoc_options<Options...>::type;
101
102#endif
103
104////////////////////////////////////////////////////////////////
105//
106//
107// OPTIONS FOR VECTOR-BASED CONTAINERS
108//
109//
110////////////////////////////////////////////////////////////////
111
112#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
113
114template<class AllocTraits, class StoredSizeType>
115struct get_stored_size_type_with_alloctraits
116{
117 typedef StoredSizeType type;
118};
119
120template<class AllocTraits>
121struct get_stored_size_type_with_alloctraits<AllocTraits, void>
122{
123 typedef typename AllocTraits::size_type type;
124};
125
126template<class GrowthType, class StoredSizeType>
127struct vector_opt
128{
129 typedef GrowthType growth_factor_type;
130 typedef StoredSizeType stored_size_type;
131
132 template<class AllocTraits>
133 struct get_stored_size_type
134 : get_stored_size_type_with_alloctraits<AllocTraits, StoredSizeType>
135 {};
136};
137
138class default_next_capacity;
139
140typedef vector_opt<void, void> vector_null_opt;
141
142#else //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
143
144//!This growth factor argument specifies that the container should increase it's
145//!capacity a 50% when existing capacity is exhausted.
146struct growth_factor_50{};
147
148//!This growth factor argument specifies that the container should increase it's
149//!capacity a 60% when existing capacity is exhausted.
150struct growth_factor_60{};
151
152//!This growth factor argument specifies that the container should increase it's
153//!capacity a 100% (doubling its capacity) when existing capacity is exhausted.
154struct growth_factor_100{};
155
156#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
157
158//!This option setter specifies the growth factor strategy of the underlying vector.
159//!
160//!\tparam GrowthFactor A function object that has the following signature:<br/><br/>
161//!`template<class SizeType>`<br/>
162//!`SizeType operator()(SizeType cur_cap, SizeType add_min_cap, SizeType max_cap) const;`.<br/><br/>
163//!`cur_cap` is the current capacity, `add_min_cap` is the minimum additional capacity
164//!we want to achieve and `max_cap` is the maximum capacity that the allocator or other
165//!factors allow. The implementation should return a value between `cur_cap` + `add_min_cap`
166//!and `max_cap`. `cur_cap` + `add_min_cap` is guaranteed not to overflow/wraparound,
167//! but the implementation should handle wraparound produced by the growth factor.
168//!
169//!Predefined growth factors that can be passed as arguments to this option are:
170//!\c boost::container::growth_factor_50
171//!\c boost::container::growth_factor_60
172//!\c boost::container::growth_factor_100
173//!
174//!If this option is not specified, a default will be used by the container.
175BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_factor_type)
176
177//!This option specifies the unsigned integer type that a user wants the container
178//!to use to hold size-related information inside a container (e.g. current size, current capacity).
179//!
180//!\tparam StoredSizeType A unsigned integer type. It shall be smaller than than the size
181//! of the size_type deduced from `allocator_traits<A>::size_type` or the same type.
182//!
183//!If the maximum capacity() to be used is limited, a user can try to use 8-bit, 16-bit
184//!(e.g. in 32-bit machines), or 32-bit size types (e.g. in a 64 bit machine) to see if some
185//!memory can be saved for empty vectors. This could potentially performance benefits due to better
186//!cache usage.
187//!
188//!Note that alignment requirements can disallow theoritical space savings. Example:
189//!\c vector holds a pointer and two size types (for size and capacity), in a 32 bit machine
190//!a 8 bit size type (total size: 4 byte pointer + 2 x 1 byte sizes = 6 bytes)
191//!will not save space when comparing two 16-bit size types because usually
192//!a 32 bit alignment is required for vector and the size will be rounded to 8 bytes. In a 64-bit
193//!machine a 16 bit size type does not usually save memory when comparing to a 32-bit size type.
194//!Measure the size of the resulting container and do not assume a smaller \c stored_size
195//!will always lead to a smaller sizeof(container).
196//!
197//!If a user tries to insert more elements than representable by \c stored_size, vector
198//!will throw a length_error.
199//!
200//!If this option is not specified, `allocator_traits<A>::size_type` (usually std::size_t) will
201//!be used to store size-related information inside the container.
202BOOST_INTRUSIVE_OPTION_TYPE(stored_size, StoredSizeType, StoredSizeType, stored_size_type)
203
204//! Helper metafunction to combine options into a single type to be used
205//! by \c boost::container::vector.
206//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
207#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
208template<class ...Options>
209#else
210template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
211#endif
212struct vector_options
213{
214 /// @cond
215 typedef typename ::boost::intrusive::pack_options
216 < vector_null_opt,
217 #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
218 O1, O2, O3, O4
219 #else
220 Options...
221 #endif
222 >::type packed_options;
223 typedef vector_opt< typename packed_options::growth_factor_type
224 , typename packed_options::stored_size_type> implementation_defined;
225 /// @endcond
226 typedef implementation_defined type;
227};
228
229#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
230
231//! Helper alias metafunction to combine options into a single type to be used
232//! by \c boost::container::vector.
233//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
234template<class ...Options>
235using vector_options_t = typename boost::container::vector_options<Options...>::type;
236
237#endif
238
239
240} //namespace container {
241} //namespace boost {
242
243#include <boost/container/detail/config_end.hpp>
244
245#endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP