extract_key.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright (C) 2005-2011 Daniel James
  2. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED
  5. #define BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED
  6. #include <boost/unordered/detail/table.hpp>
  7. namespace boost {
  8. namespace unordered {
  9. namespace detail {
  10. // key extractors
  11. //
  12. // no throw
  13. //
  14. // 'extract_key' is called with the emplace parameters to return a
  15. // key if available or 'no_key' is one isn't and will need to be
  16. // constructed. This could be done by overloading the emplace implementation
  17. // for the different cases, but that's a bit tricky on compilers without
  18. // variadic templates.
  19. struct no_key {
  20. no_key() {}
  21. template <class T> no_key(T const&) {}
  22. };
  23. template <typename Key, typename T>
  24. struct is_key {
  25. template <typename T2>
  26. static choice1::type test(T2 const&);
  27. static choice2::type test(Key const&);
  28. enum { value = sizeof(test(boost::unordered::detail::make<T>())) ==
  29. sizeof(choice2::type) };
  30. typedef typename boost::detail::if_true<value>::
  31. BOOST_NESTED_TEMPLATE then<Key const&, no_key>::type type;
  32. };
  33. template <class ValueType>
  34. struct set_extractor
  35. {
  36. typedef ValueType value_type;
  37. typedef ValueType key_type;
  38. static key_type const& extract(key_type const& v)
  39. {
  40. return v;
  41. }
  42. static no_key extract()
  43. {
  44. return no_key();
  45. }
  46. template <class Arg>
  47. static no_key extract(Arg const&)
  48. {
  49. return no_key();
  50. }
  51. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  52. template <class Arg1, class Arg2, class... Args>
  53. static no_key extract(Arg1 const&, Arg2 const&, Args const&...)
  54. {
  55. return no_key();
  56. }
  57. #else
  58. template <class Arg1, class Arg2>
  59. static no_key extract(Arg1 const&, Arg2 const&)
  60. {
  61. return no_key();
  62. }
  63. #endif
  64. };
  65. template <class Key, class ValueType>
  66. struct map_extractor
  67. {
  68. typedef ValueType value_type;
  69. typedef typename boost::remove_const<Key>::type key_type;
  70. static key_type const& extract(value_type const& v)
  71. {
  72. return v.first;
  73. }
  74. template <class Second>
  75. static key_type const& extract(std::pair<key_type, Second> const& v)
  76. {
  77. return v.first;
  78. }
  79. template <class Second>
  80. static key_type const& extract(
  81. std::pair<key_type const, Second> const& v)
  82. {
  83. return v.first;
  84. }
  85. template <class Arg1>
  86. static key_type const& extract(key_type const& k, Arg1 const&)
  87. {
  88. return k;
  89. }
  90. static no_key extract()
  91. {
  92. return no_key();
  93. }
  94. template <class Arg>
  95. static no_key extract(Arg const&)
  96. {
  97. return no_key();
  98. }
  99. template <class Arg1, class Arg2>
  100. static no_key extract(Arg1 const&, Arg2 const&)
  101. {
  102. return no_key();
  103. }
  104. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  105. template <class Arg1, class Arg2, class Arg3, class... Args>
  106. static no_key extract(Arg1 const&, Arg2 const&, Arg3 const&,
  107. Args const&...)
  108. {
  109. return no_key();
  110. }
  111. #endif
  112. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  113. #define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \
  114. template <typename T2> \
  115. static no_key extract(boost::unordered::piecewise_construct_t, \
  116. namespace_ tuple<> const&, T2 const&) \
  117. { \
  118. return no_key(); \
  119. } \
  120. \
  121. template <typename T, typename T2> \
  122. static typename is_key<key_type, T>::type \
  123. extract(boost::unordered::piecewise_construct_t, \
  124. namespace_ tuple<T> const& k, T2 const&) \
  125. { \
  126. return typename is_key<key_type, T>::type( \
  127. namespace_ get<0>(k)); \
  128. }
  129. #else
  130. #define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \
  131. static no_key extract(boost::unordered::piecewise_construct_t, \
  132. namespace_ tuple<> const&) \
  133. { \
  134. return no_key(); \
  135. } \
  136. \
  137. template <typename T> \
  138. static typename is_key<key_type, T>::type \
  139. extract(boost::unordered::piecewise_construct_t, \
  140. namespace_ tuple<T> const& k) \
  141. { \
  142. return typename is_key<key_type, T>::type( \
  143. namespace_ get<0>(k)); \
  144. }
  145. #endif
  146. BOOST_UNORDERED_KEY_FROM_TUPLE(boost::)
  147. #if !defined(BOOST_NO_CXX11_HDR_TUPLE)
  148. BOOST_UNORDERED_KEY_FROM_TUPLE(std::)
  149. #endif
  150. };
  151. }}}
  152. #endif