options.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  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. #ifndef BOOST_CONTAINER_OPTIONS_HPP
  13. #define BOOST_CONTAINER_OPTIONS_HPP
  14. #ifndef BOOST_CONFIG_HPP
  15. # include <boost/config.hpp>
  16. #endif
  17. #if defined(BOOST_HAS_PRAGMA_ONCE)
  18. # pragma once
  19. #endif
  20. #include <boost/container/detail/config_begin.hpp>
  21. #include <boost/container/container_fwd.hpp>
  22. #include <boost/intrusive/pack_options.hpp>
  23. #include <boost/static_assert.hpp>
  24. namespace boost {
  25. namespace container {
  26. ////////////////////////////////////////////////////////////////
  27. //
  28. //
  29. // OPTIONS FOR ASSOCIATIVE TREE-BASED CONTAINERS
  30. //
  31. //
  32. ////////////////////////////////////////////////////////////////
  33. //! Enumeration used to configure ordered associative containers
  34. //! with a concrete tree implementation.
  35. enum tree_type_enum
  36. {
  37. red_black_tree,
  38. avl_tree,
  39. scapegoat_tree,
  40. splay_tree
  41. };
  42. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  43. template<tree_type_enum TreeType, bool OptimizeSize>
  44. struct tree_opt
  45. {
  46. static const boost::container::tree_type_enum tree_type = TreeType;
  47. static const bool optimize_size = OptimizeSize;
  48. };
  49. typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
  50. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  51. //!This option setter specifies the underlying tree type
  52. //!(red-black, AVL, Scapegoat or Splay) for ordered associative containers
  53. BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type)
  54. //!This option setter specifies if node size is optimized
  55. //!storing rebalancing data masked into pointers for ordered associative containers
  56. BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
  57. //! Helper metafunction to combine options into a single type to be used
  58. //! by \c boost::container::set, \c boost::container::multiset
  59. //! \c boost::container::map and \c boost::container::multimap.
  60. //! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type
  61. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  62. template<class ...Options>
  63. #else
  64. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  65. #endif
  66. struct tree_assoc_options
  67. {
  68. /// @cond
  69. typedef typename ::boost::intrusive::pack_options
  70. < tree_assoc_defaults,
  71. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  72. O1, O2, O3, O4
  73. #else
  74. Options...
  75. #endif
  76. >::type packed_options;
  77. typedef tree_opt<packed_options::tree_type, packed_options::optimize_size> implementation_defined;
  78. /// @endcond
  79. typedef implementation_defined type;
  80. };
  81. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  82. //! Helper alias metafunction to combine options into a single type to be used
  83. //! by tree-based associative containers
  84. template<class ...Options>
  85. using tree_assoc_options_t = typename boost::container::tree_assoc_options<Options...>::type;
  86. #endif
  87. ////////////////////////////////////////////////////////////////
  88. //
  89. //
  90. // OPTIONS FOR ASSOCIATIVE HASH-BASED CONTAINERS
  91. //
  92. //
  93. ////////////////////////////////////////////////////////////////
  94. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  95. template<bool StoreHash>
  96. struct hash_opt
  97. {
  98. static const bool store_hash = StoreHash;
  99. };
  100. typedef hash_opt<false> hash_assoc_defaults;
  101. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  102. //!This option setter specifies if node size is optimized
  103. //!storing rebalancing data masked into pointers for ordered associative containers
  104. BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash)
  105. //! Helper metafunction to combine options into a single type to be used
  106. //! by \c boost::container::hash_set, \c boost::container::hash_multiset
  107. //! \c boost::container::hash_map and \c boost::container::hash_multimap.
  108. //! Supported options are: \c boost::container::store_hash
  109. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  110. template<class ...Options>
  111. #else
  112. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  113. #endif
  114. struct hash_assoc_options
  115. {
  116. /// @cond
  117. typedef typename ::boost::intrusive::pack_options
  118. < hash_assoc_defaults,
  119. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  120. O1, O2, O3, O4
  121. #else
  122. Options...
  123. #endif
  124. >::type packed_options;
  125. typedef hash_opt<packed_options::store_hash> implementation_defined;
  126. /// @endcond
  127. typedef implementation_defined type;
  128. };
  129. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  130. //! Helper alias metafunction to combine options into a single type to be used
  131. //! by hash-based associative containers
  132. template<class ...Options>
  133. using hash_assoc_options_t = typename boost::container::hash_assoc_options<Options...>::type;
  134. #endif
  135. ////////////////////////////////////////////////////////////////
  136. //
  137. //
  138. // OPTIONS FOR VECTOR-BASED CONTAINERS
  139. //
  140. //
  141. ////////////////////////////////////////////////////////////////
  142. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  143. template<class T, class Default>
  144. struct default_if_void
  145. {
  146. typedef T type;
  147. };
  148. template<class Default>
  149. struct default_if_void<void, Default>
  150. {
  151. typedef Default type;
  152. };
  153. #endif
  154. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  155. template<class AllocTraits, class StoredSizeType>
  156. struct get_stored_size_type_with_alloctraits
  157. {
  158. typedef StoredSizeType type;
  159. };
  160. template<class AllocTraits>
  161. struct get_stored_size_type_with_alloctraits<AllocTraits, void>
  162. {
  163. typedef typename AllocTraits::size_type type;
  164. };
  165. template<class GrowthType, class StoredSizeType>
  166. struct vector_opt
  167. {
  168. typedef GrowthType growth_factor_type;
  169. typedef StoredSizeType stored_size_type;
  170. template<class AllocTraits>
  171. struct get_stored_size_type
  172. : get_stored_size_type_with_alloctraits<AllocTraits, StoredSizeType>
  173. {};
  174. };
  175. class default_next_capacity;
  176. typedef vector_opt<void, void> vector_null_opt;
  177. template<class GrowthType, class StoredSizeType>
  178. struct devector_opt
  179. : vector_opt<GrowthType, StoredSizeType>
  180. {};
  181. typedef devector_opt<void, void> devector_null_opt;
  182. #else //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  183. //!This growth factor argument specifies that the container should increase it's
  184. //!capacity a 50% when existing capacity is exhausted.
  185. struct growth_factor_50{};
  186. //!This growth factor argument specifies that the container should increase it's
  187. //!capacity a 60% when existing capacity is exhausted.
  188. struct growth_factor_60{};
  189. //!This growth factor argument specifies that the container should increase it's
  190. //!capacity a 100% (doubling its capacity) when existing capacity is exhausted.
  191. struct growth_factor_100{};
  192. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  193. //!This option setter specifies the growth factor strategy of the underlying vector.
  194. //!
  195. //!\tparam GrowthFactor A function object that has the following signature:<br/><br/>
  196. //!`template<class SizeType>`<br/>
  197. //!`SizeType operator()(SizeType cur_cap, SizeType add_min_cap, SizeType max_cap) const;`.<br/><br/>
  198. //!`cur_cap` is the current capacity, `add_min_cap` is the minimum additional capacity
  199. //!we want to achieve and `max_cap` is the maximum capacity that the allocator or other
  200. //!factors allow. The implementation should return a value between `cur_cap` + `add_min_cap`
  201. //!and `max_cap`. `cur_cap` + `add_min_cap` is guaranteed not to overflow/wraparound,
  202. //! but the implementation should handle wraparound produced by the growth factor.
  203. //!
  204. //!Predefined growth factors that can be passed as arguments to this option are:
  205. //!\c boost::container::growth_factor_50
  206. //!\c boost::container::growth_factor_60
  207. //!\c boost::container::growth_factor_100
  208. //!
  209. //!If this option is not specified, a default will be used by the container.
  210. BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_factor_type)
  211. //!This option specifies the unsigned integer type that a user wants the container
  212. //!to use to hold size-related information inside a container (e.g. current size, current capacity).
  213. //!
  214. //!\tparam StoredSizeType An unsigned integer type. It shall be smaller than than the size
  215. //! of the size_type deduced from `allocator_traits<A>::size_type` or the same type.
  216. //!
  217. //!If the maximum capacity() to be used is limited, a user can try to use 8-bit, 16-bit
  218. //!(e.g. in 32-bit machines), or 32-bit size types (e.g. in a 64 bit machine) to see if some
  219. //!memory can be saved for empty vectors. This could potentially performance benefits due to better
  220. //!cache usage.
  221. //!
  222. //!Note that alignment requirements can disallow theoretical space savings. Example:
  223. //!\c vector holds a pointer and two size types (for size and capacity), in a 32 bit machine
  224. //!a 8 bit size type (total size: 4 byte pointer + 2 x 1 byte sizes = 6 bytes)
  225. //!will not save space when comparing two 16-bit size types because usually
  226. //!a 32 bit alignment is required for vector and the size will be rounded to 8 bytes. In a 64-bit
  227. //!machine a 16 bit size type does not usually save memory when comparing to a 32-bit size type.
  228. //!Measure the size of the resulting container and do not assume a smaller \c stored_size
  229. //!will always lead to a smaller sizeof(container).
  230. //!
  231. //!If a user tries to insert more elements than representable by \c stored_size, vector
  232. //!will throw a length_error.
  233. //!
  234. //!If this option is not specified, `allocator_traits<A>::size_type` (usually std::size_t) will
  235. //!be used to store size-related information inside the container.
  236. BOOST_INTRUSIVE_OPTION_TYPE(stored_size, StoredSizeType, StoredSizeType, stored_size_type)
  237. //! Helper metafunction to combine options into a single type to be used
  238. //! by \c boost::container::vector.
  239. //! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
  240. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  241. template<class ...Options>
  242. #else
  243. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  244. #endif
  245. struct vector_options
  246. {
  247. /// @cond
  248. typedef typename ::boost::intrusive::pack_options
  249. < vector_null_opt,
  250. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  251. O1, O2, O3, O4
  252. #else
  253. Options...
  254. #endif
  255. >::type packed_options;
  256. typedef vector_opt< typename packed_options::growth_factor_type
  257. , typename packed_options::stored_size_type> implementation_defined;
  258. /// @endcond
  259. typedef implementation_defined type;
  260. };
  261. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  262. //! Helper alias metafunction to combine options into a single type to be used
  263. //! by \c boost::container::vector.
  264. //! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
  265. template<class ...Options>
  266. using vector_options_t = typename boost::container::vector_options<Options...>::type;
  267. #endif
  268. ////////////////////////////////////////////////////////////////
  269. //
  270. //
  271. // OPTIONS FOR SMALL-VECTOR CONTAINER
  272. //
  273. //
  274. ////////////////////////////////////////////////////////////////
  275. //! This option specifies the desired alignment for the value_type stored
  276. //! in the container.
  277. //! A value zero represents the natural alignment.
  278. //!
  279. //!\tparam Alignment An unsigned integer value. Must be power of two.
  280. BOOST_INTRUSIVE_OPTION_CONSTANT(inplace_alignment, std::size_t, Alignment, inplace_alignment)
  281. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  282. template<class GrowthType, std::size_t InplaceAlignment>
  283. struct small_vector_opt
  284. {
  285. typedef GrowthType growth_factor_type;
  286. static const std::size_t inplace_alignment = InplaceAlignment;
  287. };
  288. typedef small_vector_opt<void, 0u> small_vector_null_opt;
  289. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  290. //! Helper metafunction to combine options into a single type to be used
  291. //! by \c boost::container::small_vector.
  292. //! Supported options are: \c boost::container::growth_factor and \c boost::container::inplace_alignment
  293. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  294. template<class ...Options>
  295. #else
  296. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  297. #endif
  298. struct small_vector_options
  299. {
  300. /// @cond
  301. typedef typename ::boost::intrusive::pack_options
  302. < small_vector_null_opt,
  303. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  304. O1, O2, O3, O4
  305. #else
  306. Options...
  307. #endif
  308. >::type packed_options;
  309. typedef small_vector_opt< typename packed_options::growth_factor_type
  310. , packed_options::inplace_alignment> implementation_defined;
  311. /// @endcond
  312. typedef implementation_defined type;
  313. };
  314. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  315. //! Helper alias metafunction to combine options into a single type to be used
  316. //! by \c boost::container::small_vector.
  317. //! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
  318. template<class ...Options>
  319. using small_vector_options_t = typename boost::container::small_vector_options<Options...>::type;
  320. #endif
  321. ////////////////////////////////////////////////////////////////
  322. //
  323. //
  324. // OPTIONS FOR STATIC-VECTOR CONTAINER
  325. //
  326. //
  327. ////////////////////////////////////////////////////////////////
  328. //!This option specifies if the container will throw if in
  329. //!the static capacity is not sufficient to hold the required
  330. //!values. If false is specified, insufficient capacity will
  331. //!lead to BOOST_ASSERT, and if this assertion returns, to undefined behaviour,
  332. //!which potentially can lead to better static_vector performance.
  333. //!The default value is true.
  334. //!
  335. //!\tparam ThrowOnExhaustion A boolean value. True if throw is required.
  336. BOOST_INTRUSIVE_OPTION_CONSTANT(throw_on_overflow, bool, ThrowOnOverflow, throw_on_overflow)
  337. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  338. template<bool ThrowOnOverflow, std::size_t InplaceAlignment>
  339. struct static_vector_opt
  340. {
  341. static const bool throw_on_overflow = ThrowOnOverflow;
  342. static const std::size_t inplace_alignment = InplaceAlignment;
  343. };
  344. typedef static_vector_opt<true, 0u> static_vector_null_opt;
  345. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  346. //! Helper metafunction to combine options into a single type to be used
  347. //! by \c boost::container::static_vector.
  348. //! Supported options are: \c boost::container::throw_on_overflow and \c boost::container::inplace_alignment
  349. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  350. template<class ...Options>
  351. #else
  352. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  353. #endif
  354. struct static_vector_options
  355. {
  356. /// @cond
  357. typedef typename ::boost::intrusive::pack_options
  358. < static_vector_null_opt,
  359. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  360. O1, O2, O3, O4
  361. #else
  362. Options...
  363. #endif
  364. >::type packed_options;
  365. typedef static_vector_opt< packed_options::throw_on_overflow
  366. , packed_options::inplace_alignment> implementation_defined;
  367. /// @endcond
  368. typedef implementation_defined type;
  369. };
  370. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  371. //! Helper alias metafunction to combine options into a single type to be used
  372. //! by \c boost::container::static_vector.
  373. //! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
  374. template<class ...Options>
  375. using static_vector_options_t = typename boost::container::static_vector_options<Options...>::type;
  376. #endif
  377. //! Helper metafunction to combine options into a single type to be used
  378. //! by \c boost::container::devector.
  379. //! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
  380. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  381. template<class ...Options>
  382. #else
  383. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  384. #endif
  385. struct devector_options
  386. {
  387. /// @cond
  388. typedef typename ::boost::intrusive::pack_options
  389. < devector_null_opt,
  390. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  391. O1, O2, O3, O4
  392. #else
  393. Options...
  394. #endif
  395. >::type packed_options;
  396. typedef devector_opt< typename packed_options::growth_factor_type
  397. , typename packed_options::stored_size_type> implementation_defined;
  398. /// @endcond
  399. typedef implementation_defined type;
  400. };
  401. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  402. //! Helper alias metafunction to combine options into a single type to be used
  403. //! by \c boost::container::devector.
  404. //! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
  405. template<class ...Options>
  406. using devector_options_t = typename boost::container::devector_options<Options...>::type;
  407. #endif
  408. ////////////////////////////////////////////////////////////////
  409. //
  410. //
  411. // OPTIONS FOR DEQUE-BASED CONTAINERS
  412. //
  413. //
  414. ////////////////////////////////////////////////////////////////
  415. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  416. template<std::size_t BlockBytes, std::size_t BlockSize>
  417. struct deque_opt
  418. {
  419. static const std::size_t block_bytes = BlockBytes;
  420. static const std::size_t block_size = BlockSize;
  421. BOOST_STATIC_ASSERT_MSG(!(block_bytes && block_size), "block_bytes and block_size can't be specified at the same time");
  422. };
  423. typedef deque_opt<0u, 0u> deque_null_opt;
  424. #endif
  425. //! Helper metafunction to combine options into a single type to be used
  426. //! by \c boost::container::deque.
  427. //! Supported options are: \c boost::container::block_bytes
  428. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  429. template<class ...Options>
  430. #else
  431. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  432. #endif
  433. struct deque_options
  434. {
  435. /// @cond
  436. typedef typename ::boost::intrusive::pack_options
  437. < deque_null_opt,
  438. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  439. O1, O2, O3, O4
  440. #else
  441. Options...
  442. #endif
  443. >::type packed_options;
  444. typedef deque_opt< packed_options::block_bytes, packed_options::block_size > implementation_defined;
  445. /// @endcond
  446. typedef implementation_defined type;
  447. };
  448. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  449. //! Helper alias metafunction to combine options into a single type to be used
  450. //! by \c boost::container::deque.
  451. //! Supported options are: \c boost::container::block_bytes
  452. template<class ...Options>
  453. using deque_options_t = typename boost::container::deque_options<Options...>::type;
  454. #endif
  455. //!This option specifies the maximum size of a block in bytes: this delimites the number of contiguous elements
  456. //!that will be allocated by deque as min(1u, BlockBytes/sizeof(value_type))
  457. //!A value zero represents the default value.
  458. //!
  459. //!\tparam BlockBytes An unsigned integer value.
  460. BOOST_INTRUSIVE_OPTION_CONSTANT(block_bytes, std::size_t, BlockBytes, block_bytes)
  461. //!This option specifies the size of a block, delimites the number of contiguous elements
  462. //!that will be allocated by deque as BlockSize.
  463. //!A value zero represents the default value.
  464. //!
  465. //!\tparam BlockBytes An unsigned integer value.
  466. BOOST_INTRUSIVE_OPTION_CONSTANT(block_size, std::size_t, BlockSize, block_size)
  467. } //namespace container {
  468. } //namespace boost {
  469. #include <boost/container/detail/config_end.hpp>
  470. #endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP