options.hpp 8.8 KB

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