1 2 // Copyright (C) 2005-2011 Daniel James 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED 7 #define BOOST_UNORDERED_DETAIL_EXTRACT_KEY_HPP_INCLUDED 8 9 #include <boost/config.hpp> 10 #if defined(BOOST_HAS_PRAGMA_ONCE) 11 #pragma once 12 #endif 13 14 #include <boost/unordered/detail/table.hpp> 15 16 namespace boost { 17 namespace unordered { 18 namespace detail { 19 20 // key extractors 21 // 22 // no throw 23 // 24 // 'extract_key' is called with the emplace parameters to return a 25 // key if available or 'no_key' is one isn't and will need to be 26 // constructed. This could be done by overloading the emplace implementation 27 // for the different cases, but that's a bit tricky on compilers without 28 // variadic templates. 29 30 struct no_key { no_keyboost::unordered::detail::no_key31 no_key() {} no_keyboost::unordered::detail::no_key32 template <class T> no_key(T const&) {} 33 }; 34 35 template <typename Key, typename T> 36 struct is_key { 37 template <typename T2> 38 static choice1::type test(T2 const&); 39 static choice2::type test(Key const&); 40 41 enum { value = sizeof(test(boost::unordered::detail::make<T>())) == 42 sizeof(choice2::type) }; 43 44 typedef typename boost::detail::if_true<value>:: 45 BOOST_NESTED_TEMPLATE then<Key const&, no_key>::type type; 46 }; 47 48 template <class ValueType> 49 struct set_extractor 50 { 51 typedef ValueType value_type; 52 typedef ValueType key_type; 53 extractboost::unordered::detail::set_extractor54 static key_type const& extract(key_type const& v) 55 { 56 return v; 57 } 58 extractboost::unordered::detail::set_extractor59 static no_key extract() 60 { 61 return no_key(); 62 } 63 64 template <class Arg> extractboost::unordered::detail::set_extractor65 static no_key extract(Arg const&) 66 { 67 return no_key(); 68 } 69 70 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 71 template <class Arg1, class Arg2, class... Args> extractboost::unordered::detail::set_extractor72 static no_key extract(Arg1 const&, Arg2 const&, Args const&...) 73 { 74 return no_key(); 75 } 76 #else 77 template <class Arg1, class Arg2> extractboost::unordered::detail::set_extractor78 static no_key extract(Arg1 const&, Arg2 const&) 79 { 80 return no_key(); 81 } 82 #endif 83 }; 84 85 template <class Key, class ValueType> 86 struct map_extractor 87 { 88 typedef ValueType value_type; 89 typedef typename boost::remove_const<Key>::type key_type; 90 extractboost::unordered::detail::map_extractor91 static key_type const& extract(value_type const& v) 92 { 93 return v.first; 94 } 95 96 template <class Second> extractboost::unordered::detail::map_extractor97 static key_type const& extract(std::pair<key_type, Second> const& v) 98 { 99 return v.first; 100 } 101 102 template <class Second> extractboost::unordered::detail::map_extractor103 static key_type const& extract( 104 std::pair<key_type const, Second> const& v) 105 { 106 return v.first; 107 } 108 109 template <class Arg1> extractboost::unordered::detail::map_extractor110 static key_type const& extract(key_type const& k, Arg1 const&) 111 { 112 return k; 113 } 114 extractboost::unordered::detail::map_extractor115 static no_key extract() 116 { 117 return no_key(); 118 } 119 120 template <class Arg> extractboost::unordered::detail::map_extractor121 static no_key extract(Arg const&) 122 { 123 return no_key(); 124 } 125 126 template <class Arg1, class Arg2> extractboost::unordered::detail::map_extractor127 static no_key extract(Arg1 const&, Arg2 const&) 128 { 129 return no_key(); 130 } 131 132 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 133 template <class Arg1, class Arg2, class Arg3, class... Args> extractboost::unordered::detail::map_extractor134 static no_key extract(Arg1 const&, Arg2 const&, Arg3 const&, 135 Args const&...) 136 { 137 return no_key(); 138 } 139 #endif 140 141 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 142 143 #define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \ 144 template <typename T2> \ 145 static no_key extract(boost::unordered::piecewise_construct_t, \ 146 namespace_ tuple<> const&, T2 const&) \ 147 { \ 148 return no_key(); \ 149 } \ 150 \ 151 template <typename T, typename T2> \ 152 static typename is_key<key_type, T>::type \ 153 extract(boost::unordered::piecewise_construct_t, \ 154 namespace_ tuple<T> const& k, T2 const&) \ 155 { \ 156 return typename is_key<key_type, T>::type( \ 157 namespace_ get<0>(k)); \ 158 } 159 160 #else 161 162 #define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \ 163 static no_key extract(boost::unordered::piecewise_construct_t, \ 164 namespace_ tuple<> const&) \ 165 { \ 166 return no_key(); \ 167 } \ 168 \ 169 template <typename T> \ 170 static typename is_key<key_type, T>::type \ 171 extract(boost::unordered::piecewise_construct_t, \ 172 namespace_ tuple<T> const& k) \ 173 { \ 174 return typename is_key<key_type, T>::type( \ 175 namespace_ get<0>(k)); \ 176 } 177 178 #endif 179 180 BOOST_UNORDERED_KEY_FROM_TUPLE(boost::) 181 182 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) 183 BOOST_UNORDERED_KEY_FROM_TUPLE(std::) 184 #endif 185 }; 186 }}} 187 188 #endif 189