options.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  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/container/detail/workaround.hpp>
  23. #include <boost/intrusive/pack_options.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. BOOST_STATIC_CONSTEXPR boost::container::tree_type_enum tree_type = TreeType;
  47. BOOST_STATIC_CONSTEXPR 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, bool CacheBegin, bool LinearBuckets, bool FastmodBuckets>
  96. struct hash_opt
  97. {
  98. BOOST_STATIC_CONSTEXPR bool store_hash = StoreHash;
  99. BOOST_STATIC_CONSTEXPR bool cache_begin = CacheBegin;
  100. BOOST_STATIC_CONSTEXPR bool linear_buckets = LinearBuckets;
  101. BOOST_STATIC_CONSTEXPR bool fastmod_buckets = FastmodBuckets;
  102. };
  103. typedef hash_opt<false, false, false, false> hash_assoc_defaults;
  104. //!This option setter specifies if nodes also store the hash value
  105. //!so that search and rehashing for hash-expensive types is improved.
  106. //!This option might degrade performance for easy to hash types (like integers)
  107. BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash)
  108. //!This option setter specifies if the container will cache the first
  109. //!non-empty bucket so that begin() is O(1) instead of searching for the
  110. //!first non-empty bucket (which can be O(bucket_size()))
  111. BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin)
  112. BOOST_INTRUSIVE_OPTION_CONSTANT(linear_buckets, bool, Enabled, linear_buckets)
  113. BOOST_INTRUSIVE_OPTION_CONSTANT(fastmod_buckets, bool, Enabled, fastmod_buckets)
  114. //! Helper metafunction to combine options into a single type to be used
  115. //! by \c boost::container::hash_set, \c boost::container::hash_multiset
  116. //! \c boost::container::hash_map and \c boost::container::hash_multimap.
  117. //! Supported options are: \c boost::container::store_hash
  118. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  119. template<class ...Options>
  120. #else
  121. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  122. #endif
  123. struct hash_assoc_options
  124. {
  125. /// @cond
  126. typedef typename ::boost::intrusive::pack_options
  127. < hash_assoc_defaults,
  128. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  129. O1, O2, O3, O4
  130. #else
  131. Options...
  132. #endif
  133. >::type packed_options;
  134. typedef hash_opt<packed_options::store_hash
  135. ,packed_options::cache_begin
  136. ,packed_options::linear_buckets
  137. ,packed_options::fastmod_buckets
  138. > implementation_defined;
  139. /// @endcond
  140. typedef implementation_defined type;
  141. };
  142. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  143. //! Helper alias metafunction to combine options into a single type to be used
  144. //! by hash-based associative containers
  145. template<class ...Options>
  146. using hash_assoc_options_t = typename boost::container::hash_assoc_options<Options...>::type;
  147. #endif
  148. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  149. ////////////////////////////////////////////////////////////////
  150. //
  151. //
  152. // OPTIONS FOR VECTOR-BASED CONTAINERS
  153. //
  154. //
  155. ////////////////////////////////////////////////////////////////
  156. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  157. template<class T, class Default>
  158. struct default_if_void
  159. {
  160. typedef T type;
  161. };
  162. template<class Default>
  163. struct default_if_void<void, Default>
  164. {
  165. typedef Default type;
  166. };
  167. template<std::size_t N, std::size_t DefaultN>
  168. struct default_if_zero
  169. {
  170. BOOST_STATIC_CONSTEXPR std::size_t value = N;
  171. };
  172. template<std::size_t DefaultN>
  173. struct default_if_zero<0u, DefaultN>
  174. {
  175. BOOST_STATIC_CONSTEXPR std::size_t value = DefaultN;
  176. };
  177. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  178. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  179. template<class AllocTraits, class StoredSizeType>
  180. struct get_stored_size_type_with_alloctraits
  181. {
  182. typedef StoredSizeType type;
  183. };
  184. template<class AllocTraits>
  185. struct get_stored_size_type_with_alloctraits<AllocTraits, void>
  186. {
  187. typedef typename AllocTraits::size_type type;
  188. };
  189. template<class GrowthType, class StoredSizeType>
  190. struct vector_opt
  191. {
  192. typedef GrowthType growth_factor_type;
  193. typedef StoredSizeType stored_size_type;
  194. template<class AllocTraits>
  195. struct get_stored_size_type
  196. : get_stored_size_type_with_alloctraits<AllocTraits, StoredSizeType>
  197. {};
  198. };
  199. class default_next_capacity;
  200. typedef vector_opt<void, void> vector_null_opt;
  201. #else
  202. //!This growth factor argument specifies that the container should increase its
  203. //!capacity a 50% when existing capacity is exhausted.
  204. struct growth_factor_50{};
  205. //!This growth factor argument specifies that the container should increase its
  206. //!capacity a 60% when existing capacity is exhausted.
  207. struct growth_factor_60{};
  208. //!This growth factor argument specifies that the container should increase its
  209. //!capacity a 100% (doubling its capacity) when existing capacity is exhausted.
  210. struct growth_factor_100{};
  211. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  212. //!This option setter specifies the growth factor strategy of the
  213. //!underlying vector.
  214. //!
  215. //!\tparam GrowthFactor The function object that implements the growth factor
  216. //!
  217. //! The GrowthFactor function object must offer the following interface:
  218. //!
  219. //!\code
  220. //!template<class SizeType>
  221. //!SizeType operator()(SizeType cur_cap, SizeType add_min_cap, SizeType max_cap) const;
  222. //!\endcode
  223. //!
  224. //!Where:
  225. //! * `cur_cap` is the current capacity
  226. //! * `add_min_cap` is the minimum additional capacity we want to achieve
  227. //! * `max_cap` is the maximum capacity that the allocator or other factors allow.
  228. //!
  229. //!The implementation should return a value between `cur_cap + add_min_cap`
  230. //!and `max_cap`. The implementation should handle the potential wraparound produced
  231. //!by the growth factor and always succeed with a correct value.
  232. //!
  233. //!Predefined growth factors that can be passed as arguments to this option are:
  234. //!\c boost::container::growth_factor_50,
  235. //!\c boost::container::growth_factor_60 and
  236. //!\c boost::container::growth_factor_100
  237. //!
  238. //!If this option is not specified, a default will be used by the container.
  239. BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_factor_type)
  240. //!This option specifies the unsigned integer type that a user wants the container
  241. //!to use to hold size-related information inside a container (e.g. current size, current capacity).
  242. //!
  243. //!\tparam StoredSizeType An unsigned integer type. It shall be smaller than than the size
  244. //! of the size_type deduced from `allocator_traits<A>::size_type` or the same type.
  245. //!
  246. //!If the maximum capacity() to be used is limited, a user can try to use 8-bit, 16-bit
  247. //!(e.g. in 32-bit machines), or 32-bit size types (e.g. in a 64 bit machine) to see if some
  248. //!memory can be saved, specially for empty containers. This could potentially improve performance
  249. //!due to better cache usage.
  250. //!
  251. //!Note that alignment requirements can disallow theoretical space savings. Example:
  252. //!\c vector holds a pointer and two size types (for size and capacity), in a 32 bit machine
  253. //!a 8 bit size type (total size: 4 byte pointer + 2 x 1 byte sizes = 6 bytes)
  254. //!will not save space when comparing two 16-bit size types because usually
  255. //!a 32 bit alignment is required for vector and the size will be rounded to 8 bytes. In a 64-bit
  256. //!machine a 16 bit size type does not usually save memory when comparing to a 32-bit size type.
  257. //!Measure the size of the resulting container and do not assume a smaller \c stored_size
  258. //!will always lead to a smaller sizeof(container).
  259. //!
  260. //!If a user tries to insert more elements than representable by \c stored_size, the container
  261. //!will throw a length_error.
  262. //!
  263. //!If this option is not specified, `allocator_traits<A>::size_type` (usually std::size_t) will
  264. //!be used to store size-related information inside the container.
  265. BOOST_INTRUSIVE_OPTION_TYPE(stored_size, StoredSizeType, StoredSizeType, stored_size_type)
  266. //! Helper metafunction to combine options into a single type to be used
  267. //! by \c boost::container::vector.
  268. //! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
  269. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  270. template<class ...Options>
  271. #else
  272. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  273. #endif
  274. struct vector_options
  275. {
  276. /// @cond
  277. typedef typename ::boost::intrusive::pack_options
  278. < vector_null_opt,
  279. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  280. O1, O2, O3, O4
  281. #else
  282. Options...
  283. #endif
  284. >::type packed_options;
  285. typedef vector_opt< typename packed_options::growth_factor_type
  286. , typename packed_options::stored_size_type> implementation_defined;
  287. /// @endcond
  288. typedef implementation_defined type;
  289. };
  290. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  291. //! Helper alias metafunction to combine options into a single type to be used
  292. //! by \c boost::container::vector.
  293. template<class ...Options>
  294. using vector_options_t = typename boost::container::vector_options<Options...>::type;
  295. #endif
  296. ////////////////////////////////////////////////////////////////
  297. //
  298. //
  299. // OPTIONS FOR SMALL-VECTOR CONTAINER
  300. //
  301. //
  302. ////////////////////////////////////////////////////////////////
  303. //! This option specifies the desired alignment for the value_type stored
  304. //! in the container.
  305. //! A value zero represents the natural alignment.
  306. //!
  307. //!\tparam Alignment An unsigned integer value. Must be power of two.
  308. BOOST_INTRUSIVE_OPTION_CONSTANT(inplace_alignment, std::size_t, Alignment, inplace_alignment)
  309. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  310. template<class GrowthType, std::size_t InplaceAlignment, class StoredSizeType>
  311. struct small_vector_opt
  312. {
  313. typedef GrowthType growth_factor_type;
  314. BOOST_STATIC_CONSTEXPR std::size_t inplace_alignment = InplaceAlignment;
  315. typedef StoredSizeType stored_size_type;
  316. };
  317. typedef small_vector_opt<void, 0u, void> small_vector_null_opt;
  318. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  319. //! Helper metafunction to combine options into a single type to be used
  320. //! by \c boost::container::small_vector.
  321. //! Supported options are: \c boost::container::growth_factor,
  322. //! \c boost::container::inplace_alignment and
  323. //! \c boost::container::stored_size.
  324. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  325. template<class ...Options>
  326. #else
  327. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  328. #endif
  329. struct small_vector_options
  330. {
  331. /// @cond
  332. typedef typename ::boost::intrusive::pack_options
  333. < small_vector_null_opt,
  334. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  335. O1, O2, O3, O4
  336. #else
  337. Options...
  338. #endif
  339. >::type packed_options;
  340. typedef small_vector_opt< typename packed_options::growth_factor_type
  341. , packed_options::inplace_alignment
  342. , typename packed_options::stored_size_type
  343. > implementation_defined;
  344. /// @endcond
  345. typedef implementation_defined type;
  346. };
  347. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  348. //! Helper alias metafunction to combine options into a single type to be used
  349. //! by \c boost::container::small_vector.
  350. template<class ...Options>
  351. using small_vector_options_t = typename boost::container::small_vector_options<Options...>::type;
  352. #endif
  353. ////////////////////////////////////////////////////////////////
  354. //
  355. //
  356. // OPTIONS FOR STATIC-VECTOR CONTAINER
  357. //
  358. //
  359. ////////////////////////////////////////////////////////////////
  360. //!This option specifies if the container will throw if in
  361. //!the static capacity is not sufficient to hold the required
  362. //!values. If false is specified, insufficient capacity will
  363. //!lead to BOOST_ASSERT, and if this assertion returns, to undefined behaviour,
  364. //!which potentially can lead to better static_vector performance.
  365. //!The default value is true.
  366. //!
  367. //!\tparam ThrowOnExhaustion A boolean value. True if throw is required.
  368. BOOST_INTRUSIVE_OPTION_CONSTANT(throw_on_overflow, bool, ThrowOnOverflow, throw_on_overflow)
  369. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  370. template<bool ThrowOnOverflow, std::size_t InplaceAlignment, class StoredSizeType>
  371. struct static_vector_opt
  372. {
  373. BOOST_STATIC_CONSTEXPR bool throw_on_overflow = ThrowOnOverflow;
  374. BOOST_STATIC_CONSTEXPR std::size_t inplace_alignment = InplaceAlignment;
  375. typedef StoredSizeType stored_size_type;
  376. };
  377. typedef static_vector_opt<true, 0u, void> static_vector_null_opt;
  378. #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  379. //! Helper metafunction to combine options into a single type to be used
  380. //! by \c boost::container::static_vector.
  381. //! Supported options are: \c boost::container::throw_on_overflow, \c boost::container::inplace_alignment
  382. //! and \c boost::container::stored_size.
  383. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  384. template<class ...Options>
  385. #else
  386. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  387. #endif
  388. struct static_vector_options
  389. {
  390. /// @cond
  391. typedef typename ::boost::intrusive::pack_options
  392. < static_vector_null_opt,
  393. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  394. O1, O2, O3, O4
  395. #else
  396. Options...
  397. #endif
  398. >::type packed_options;
  399. typedef static_vector_opt< packed_options::throw_on_overflow
  400. , packed_options::inplace_alignment
  401. , typename packed_options::stored_size_type
  402. > implementation_defined;
  403. /// @endcond
  404. typedef implementation_defined type;
  405. };
  406. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  407. //! Helper alias metafunction to combine options into a single type to be used
  408. //! by \c boost::container::static_vector.
  409. template<class ...Options>
  410. using static_vector_options_t = typename boost::container::static_vector_options<Options...>::type;
  411. #endif
  412. ////////////////////////////////////////////////////////////////
  413. //
  414. //
  415. // OPTIONS FOR DEVECTOR CONTAINER
  416. //
  417. //
  418. ////////////////////////////////////////////////////////////////
  419. //!Thse options specify the relocation strategy of devector.
  420. //!
  421. //!Predefined relocation limits that can be passed as arguments to this option are:
  422. //!\c boost::container::relocate_on_66
  423. //!\c boost::container::relocate_on_75
  424. //!\c boost::container::relocate_on_80
  425. //!\c boost::container::relocate_on_85
  426. //!\c boost::container::relocate_on_90
  427. //!
  428. //!If this option is not specified, a default will be used by the container.
  429. //!
  430. //!Note: Repeated insertions at only one end (only back insertions or only front insertions) usually will
  431. //!lead to a single relocation when `relocate_on_66` is used and two relocations when `relocate_on_90`
  432. //!is used.
  433. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  434. BOOST_INTRUSIVE_OPTION_CONSTANT(relocate_on, std::size_t, Fraction, free_fraction)
  435. struct relocate_on_66 : public relocate_on<3U>{};
  436. struct relocate_on_75 : public relocate_on<4U> {};
  437. struct relocate_on_80 : public relocate_on<5U> {};
  438. struct relocate_on_85 : public relocate_on<7U> {};
  439. struct relocate_on_90 : public relocate_on<10U> {};
  440. template<class GrowthType, class StoredSizeType, std::size_t FreeFraction>
  441. struct devector_opt
  442. : vector_opt<GrowthType, StoredSizeType>
  443. {
  444. BOOST_STATIC_CONSTEXPR std::size_t free_fraction = FreeFraction;
  445. };
  446. typedef devector_opt<void, void, 0u> devector_null_opt;
  447. #else
  448. //!This relocation condition option specifies that the container will never relocate
  449. //!elements when there is no space at the side the insertion should
  450. //!take place
  451. struct relocate_never;
  452. //!This relocation condition option specifies that the container will relocate
  453. //!all elements when there is no space at the side the insertion should
  454. //!take place and memory usage is below 66% (2/3)
  455. struct relocate_on_66;
  456. //!This relocation condition option specifies that the container will relocate
  457. //!all elements when there is no space at the side the insertion should
  458. //!take place and memory usage is below 75% (3/4)
  459. struct relocate_on_75;
  460. //!This relocation condition option specifies that the container will relocate
  461. //!all elements when there is no space at the side the insertion should
  462. //!take place and memory usage is below 80% (4/5)
  463. struct relocate_on_80;
  464. //!This relocation condition option specifies that the container will relocate
  465. //!all elements when there is no space at the side the insertion should
  466. //!take place and memory usage is below 85% (6/7)
  467. struct relocate_on_85;
  468. //!This relocation condition option specifies that the container will relocate
  469. //!all elements when there is no space at the side the insertion should
  470. //!take place and memory usage is below 90% (9/10)
  471. struct relocate_on_90;
  472. #endif
  473. //! Helper metafunction to combine options into a single type to be used
  474. //! by \c boost::container::devector.
  475. //! Supported options are: \c boost::container::growth_factor, \c boost::container::stored_size
  476. //! and \c boost::container::relocate_on
  477. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  478. template<class ...Options>
  479. #else
  480. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  481. #endif
  482. struct devector_options
  483. {
  484. /// @cond
  485. typedef typename ::boost::intrusive::pack_options
  486. < devector_null_opt,
  487. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  488. O1, O2, O3, O4
  489. #else
  490. Options...
  491. #endif
  492. >::type packed_options;
  493. typedef devector_opt< typename packed_options::growth_factor_type
  494. , typename packed_options::stored_size_type
  495. , packed_options::free_fraction
  496. > implementation_defined;
  497. /// @endcond
  498. typedef implementation_defined type;
  499. };
  500. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  501. //! Helper alias metafunction to combine options into a single type to be used
  502. //! by \c boost::container::devector.
  503. template<class ...Options>
  504. using devector_options_t = typename boost::container::devector_options<Options...>::type;
  505. #endif
  506. ////////////////////////////////////////////////////////////////
  507. //
  508. //
  509. // OPTIONS FOR DEQUE-BASED CONTAINERS
  510. //
  511. //
  512. ////////////////////////////////////////////////////////////////
  513. #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
  514. template<std::size_t BlockBytes, std::size_t BlockSize, class StoredSizeType, bool Reservable>
  515. struct deque_opt
  516. {
  517. BOOST_STATIC_CONSTEXPR std::size_t block_bytes = BlockBytes;
  518. BOOST_STATIC_CONSTEXPR std::size_t block_size = BlockSize;
  519. BOOST_CONTAINER_STATIC_ASSERT_MSG(!(block_bytes && block_size), "block_bytes and block_size can't be specified at the same time");
  520. BOOST_STATIC_CONSTEXPR bool reservable = Reservable;
  521. typedef StoredSizeType stored_size_type;
  522. template<class AllocTraits>
  523. struct get_stored_size_type
  524. : get_stored_size_type_with_alloctraits<AllocTraits, StoredSizeType>
  525. {};
  526. };
  527. typedef deque_opt<0u, 0u, void, false> deque_null_opt;
  528. #endif
  529. //! Helper metafunction to combine options into a single type to be used
  530. //! by \c boost::container::deque.
  531. //! Supported options are: \c boost::container::block_bytes, \c boost::container::block_size,
  532. //! \c boost::container::stored_size and \c boost::container::reservable
  533. #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  534. template<class ...Options>
  535. #else
  536. template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
  537. #endif
  538. struct deque_options
  539. {
  540. /// @cond
  541. typedef typename ::boost::intrusive::pack_options
  542. < deque_null_opt,
  543. #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
  544. O1, O2, O3, O4
  545. #else
  546. Options...
  547. #endif
  548. >::type packed_options;
  549. typedef deque_opt< packed_options::block_bytes
  550. , packed_options::block_size
  551. , typename packed_options::stored_size_type
  552. , packed_options::reservable
  553. > implementation_defined;
  554. /// @endcond
  555. typedef implementation_defined type;
  556. };
  557. #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
  558. //! Helper alias metafunction to combine options into a single type to be used
  559. //! by \c boost::container::deque.
  560. template<class ...Options>
  561. using deque_options_t = typename boost::container::deque_options<Options...>::type;
  562. #endif
  563. //!This option specifies the maximum size of a block in bytes: this delimites the number of contiguous elements
  564. //!that will be allocated by some containers as min(1u, BlockBytes/sizeof(value_type))
  565. //!A value zero represents the default value.
  566. //!
  567. //!\tparam BlockBytes An unsigned integer value.
  568. BOOST_INTRUSIVE_OPTION_CONSTANT(block_bytes, std::size_t, BlockBytes, block_bytes)
  569. //!This option specifies the size of a block, delimites the number of contiguous elements
  570. //!that will be allocated by some containersas BlockSize.
  571. //!For some containers (like deque), a power of two value can improve performance.
  572. //!A value zero represents the default value.
  573. //!
  574. //!\tparam BlockBytes An unsigned integer value.
  575. BOOST_INTRUSIVE_OPTION_CONSTANT(block_size, std::size_t, BlockSize, block_size)
  576. //!This option specifies if the container has reserve/capacity-like features
  577. //!
  578. //!For some containers (like deque) this option might change the internal representation or
  579. //!behavior so that memory for elements can be allocated in advance in
  580. //!order to improve performance.
  581. //!
  582. //!\tparam Reservable An boolean value.
  583. BOOST_INTRUSIVE_OPTION_CONSTANT(reservable, bool, Reservable, reservable)
  584. } //namespace container {
  585. } //namespace boost {
  586. #include <boost/container/detail/config_end.hpp>
  587. #endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP