Brian Silverman | fad8f55 | 2018-08-04 23:36:19 -0700 | [diff] [blame^] | 1 | ///////////////////////////////////////////////////////////////////////////// |
| 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 | |
| 28 | namespace boost { |
| 29 | namespace 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. |
| 41 | enum 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 | |
| 51 | template<tree_type_enum TreeType, bool OptimizeSize> |
| 52 | struct tree_opt |
| 53 | { |
| 54 | static const boost::container::tree_type_enum tree_type = TreeType; |
| 55 | static const bool optimize_size = OptimizeSize; |
| 56 | }; |
| 57 | |
| 58 | typedef 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 |
| 64 | BOOST_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 |
| 68 | BOOST_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) |
| 75 | template<class ...Options> |
| 76 | #else |
| 77 | template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> |
| 78 | #endif |
| 79 | struct 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 |
| 99 | template<class ...Options> |
| 100 | using 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 | |
| 114 | template<class AllocTraits, class StoredSizeType> |
| 115 | struct get_stored_size_type_with_alloctraits |
| 116 | { |
| 117 | typedef StoredSizeType type; |
| 118 | }; |
| 119 | |
| 120 | template<class AllocTraits> |
| 121 | struct get_stored_size_type_with_alloctraits<AllocTraits, void> |
| 122 | { |
| 123 | typedef typename AllocTraits::size_type type; |
| 124 | }; |
| 125 | |
| 126 | template<class GrowthType, class StoredSizeType> |
| 127 | struct 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 | |
| 138 | class default_next_capacity; |
| 139 | |
| 140 | typedef 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. |
| 146 | struct 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. |
| 150 | struct 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. |
| 154 | struct 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. |
| 175 | BOOST_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. |
| 202 | BOOST_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) |
| 208 | template<class ...Options> |
| 209 | #else |
| 210 | template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> |
| 211 | #endif |
| 212 | struct 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 |
| 234 | template<class ...Options> |
| 235 | using 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 |