]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 { | |
31 | no_key() {} | |
32 | 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 | ||
54 | static key_type const& extract(value_type const& v) | |
55 | { | |
56 | return v; | |
57 | } | |
58 | ||
59 | static no_key extract() | |
60 | { | |
61 | return no_key(); | |
62 | } | |
63 | ||
64 | template <class Arg> | |
65 | 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> | |
72 | static no_key extract(Arg1 const&, Arg2 const&, Args const&...) | |
73 | { | |
74 | return no_key(); | |
75 | } | |
76 | #else | |
77 | template <class Arg1, class Arg2> | |
78 | 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 | ||
91 | static key_type const& extract(value_type const& v) | |
92 | { | |
93 | return v.first; | |
94 | } | |
95 | ||
96 | template <class Second> | |
97 | static key_type const& extract(std::pair<key_type, Second> const& v) | |
98 | { | |
99 | return v.first; | |
100 | } | |
101 | ||
102 | template <class Second> | |
103 | 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> | |
110 | static key_type const& extract(key_type const& k, Arg1 const&) | |
111 | { | |
112 | return k; | |
113 | } | |
114 | ||
115 | static no_key extract() | |
116 | { | |
117 | return no_key(); | |
118 | } | |
119 | ||
120 | template <class Arg> | |
121 | static no_key extract(Arg const&) | |
122 | { | |
123 | return no_key(); | |
124 | } | |
125 | ||
126 | template <class Arg1, class Arg2> | |
127 | 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> | |
134 | 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 |