Chris@101
|
1 /* Copyright 2003-2014 Joaquin M Lopez Munoz.
|
Chris@16
|
2 * Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
3 * (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5 *
|
Chris@16
|
6 * See http://www.boost.org/libs/multi_index for library home page.
|
Chris@16
|
7 */
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
|
Chris@16
|
10 #define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
|
Chris@16
|
11
|
Chris@101
|
12 #if defined(_MSC_VER)
|
Chris@16
|
13 #pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
Chris@16
|
17 #include <boost/functional/hash_fwd.hpp>
|
Chris@16
|
18 #include <boost/multi_index/detail/access_specifier.hpp>
|
Chris@16
|
19 #include <boost/mpl/eval_if.hpp>
|
Chris@16
|
20 #include <boost/mpl/identity.hpp>
|
Chris@16
|
21 #include <boost/mpl/if.hpp>
|
Chris@16
|
22 #include <boost/mpl/or.hpp>
|
Chris@16
|
23 #include <boost/preprocessor/cat.hpp>
|
Chris@16
|
24 #include <boost/preprocessor/control/expr_if.hpp>
|
Chris@16
|
25 #include <boost/preprocessor/list/at.hpp>
|
Chris@16
|
26 #include <boost/preprocessor/repetition/enum.hpp>
|
Chris@16
|
27 #include <boost/preprocessor/repetition/enum_params.hpp>
|
Chris@16
|
28 #include <boost/static_assert.hpp>
|
Chris@16
|
29 #include <boost/tuple/tuple.hpp>
|
Chris@16
|
30 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
31 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
32 #include <functional>
|
Chris@16
|
33
|
Chris@16
|
34 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
Chris@16
|
35 #include <boost/ref.hpp>
|
Chris@16
|
36 #endif
|
Chris@16
|
37
|
Chris@16
|
38 #if !defined(BOOST_NO_SFINAE)
|
Chris@16
|
39 #include <boost/type_traits/is_convertible.hpp>
|
Chris@16
|
40 #endif
|
Chris@16
|
41
|
Chris@101
|
42 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
|
Chris@101
|
43 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
44 #include <boost/multi_index/detail/cons_stdtuple.hpp>
|
Chris@101
|
45 #endif
|
Chris@101
|
46
|
Chris@16
|
47 /* A composite key stores n key extractors and "computes" the
|
Chris@16
|
48 * result on a given value as a packed reference to the value and
|
Chris@16
|
49 * the composite key itself. Actual invocations to the component
|
Chris@16
|
50 * key extractors are lazily performed when executing an operation
|
Chris@16
|
51 * on composite_key results (equality, comparison, hashing.)
|
Chris@16
|
52 * As the other key extractors in Boost.MultiIndex, composite_key<T,...>
|
Chris@16
|
53 * is overloaded to work on chained pointers to T and reference_wrappers
|
Chris@16
|
54 * of T.
|
Chris@16
|
55 */
|
Chris@16
|
56
|
Chris@16
|
57 /* This user_definable macro limits the number of elements of a composite
|
Chris@16
|
58 * key; useful for shortening resulting symbol names (MSVC++ 6.0, for
|
Chris@16
|
59 * instance has problems coping with very long symbol names.)
|
Chris@16
|
60 * NB: This cannot exceed the maximum number of arguments of
|
Chris@16
|
61 * boost::tuple. In Boost 1.32, the limit is 10.
|
Chris@16
|
62 */
|
Chris@16
|
63
|
Chris@16
|
64 #if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE)
|
Chris@16
|
65 #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10
|
Chris@16
|
66 #endif
|
Chris@16
|
67
|
Chris@16
|
68 /* maximum number of key extractors in a composite key */
|
Chris@16
|
69
|
Chris@16
|
70 #if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */
|
Chris@16
|
71 #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \
|
Chris@16
|
72 BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE
|
Chris@16
|
73 #else
|
Chris@16
|
74 #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10
|
Chris@16
|
75 #endif
|
Chris@16
|
76
|
Chris@16
|
77 /* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
|
Chris@16
|
78
|
Chris@16
|
79 #define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \
|
Chris@16
|
80 BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data)
|
Chris@16
|
81
|
Chris@16
|
82 /* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
|
Chris@16
|
83
|
Chris@16
|
84 #define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \
|
Chris@16
|
85 BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param)
|
Chris@16
|
86
|
Chris@16
|
87 /* if n==0 -> text0
|
Chris@16
|
88 * otherwise -> textn=tuples::null_type
|
Chris@16
|
89 */
|
Chris@16
|
90
|
Chris@16
|
91 #define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text) \
|
Chris@16
|
92 typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type)
|
Chris@16
|
93
|
Chris@16
|
94 /* const textn& kn=textn() */
|
Chris@16
|
95
|
Chris@16
|
96 #define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text) \
|
Chris@16
|
97 const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)()
|
Chris@16
|
98
|
Chris@16
|
99 /* typename list(0)<list(1),n>::type */
|
Chris@16
|
100
|
Chris@16
|
101 #define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list) \
|
Chris@16
|
102 BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)< \
|
Chris@16
|
103 BOOST_PP_LIST_AT(list,1),n \
|
Chris@16
|
104 >::type
|
Chris@16
|
105
|
Chris@16
|
106 namespace boost{
|
Chris@16
|
107
|
Chris@16
|
108 template<class T> class reference_wrapper; /* fwd decl. */
|
Chris@16
|
109
|
Chris@16
|
110 namespace multi_index{
|
Chris@16
|
111
|
Chris@16
|
112 namespace detail{
|
Chris@16
|
113
|
Chris@16
|
114 /* n-th key extractor of a composite key */
|
Chris@16
|
115
|
Chris@101
|
116 template<typename CompositeKey,int N>
|
Chris@16
|
117 struct nth_key_from_value
|
Chris@16
|
118 {
|
Chris@16
|
119 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@101
|
120 typedef typename mpl::eval_if_c<
|
Chris@101
|
121 N<tuples::length<key_extractor_tuple>::value,
|
Chris@16
|
122 tuples::element<N,key_extractor_tuple>,
|
Chris@101
|
123 mpl::identity<tuples::null_type>
|
Chris@16
|
124 >::type type;
|
Chris@16
|
125 };
|
Chris@16
|
126
|
Chris@16
|
127 /* nth_composite_key_##name<CompositeKey,N>::type yields
|
Chris@16
|
128 * functor<nth_key_from_value<CompositeKey,N> >, or tuples::null_type
|
Chris@16
|
129 * if N exceeds the length of the composite key.
|
Chris@16
|
130 */
|
Chris@16
|
131
|
Chris@16
|
132 #define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \
|
Chris@16
|
133 template<typename KeyFromValue> \
|
Chris@16
|
134 struct BOOST_PP_CAT(key_,name) \
|
Chris@16
|
135 { \
|
Chris@16
|
136 typedef functor<typename KeyFromValue::result_type> type; \
|
Chris@16
|
137 }; \
|
Chris@16
|
138 \
|
Chris@16
|
139 template<> \
|
Chris@16
|
140 struct BOOST_PP_CAT(key_,name)<tuples::null_type> \
|
Chris@16
|
141 { \
|
Chris@16
|
142 typedef tuples::null_type type; \
|
Chris@16
|
143 }; \
|
Chris@16
|
144 \
|
Chris@101
|
145 template<typename CompositeKey,int N> \
|
Chris@16
|
146 struct BOOST_PP_CAT(nth_composite_key_,name) \
|
Chris@16
|
147 { \
|
Chris@16
|
148 typedef typename nth_key_from_value<CompositeKey,N>::type key_from_value; \
|
Chris@16
|
149 typedef typename BOOST_PP_CAT(key_,name)<key_from_value>::type type; \
|
Chris@16
|
150 };
|
Chris@16
|
151
|
Chris@16
|
152 /* nth_composite_key_equal_to
|
Chris@16
|
153 * nth_composite_key_less
|
Chris@16
|
154 * nth_composite_key_greater
|
Chris@16
|
155 * nth_composite_key_hash
|
Chris@16
|
156 */
|
Chris@16
|
157
|
Chris@16
|
158 BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to)
|
Chris@16
|
159 BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less)
|
Chris@16
|
160 BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater)
|
Chris@16
|
161 BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash)
|
Chris@16
|
162
|
Chris@16
|
163 /* used for defining equality and comparison ops of composite_key_result */
|
Chris@16
|
164
|
Chris@16
|
165 #define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text
|
Chris@16
|
166
|
Chris@16
|
167 struct generic_operator_equal
|
Chris@16
|
168 {
|
Chris@16
|
169 template<typename T,typename Q>
|
Chris@16
|
170 bool operator()(const T& x,const Q& y)const{return x==y;}
|
Chris@16
|
171 };
|
Chris@16
|
172
|
Chris@16
|
173 typedef tuple<
|
Chris@16
|
174 BOOST_MULTI_INDEX_CK_ENUM(
|
Chris@16
|
175 BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
|
Chris@16
|
176 detail::generic_operator_equal)> generic_operator_equal_tuple;
|
Chris@16
|
177
|
Chris@16
|
178 struct generic_operator_less
|
Chris@16
|
179 {
|
Chris@16
|
180 template<typename T,typename Q>
|
Chris@16
|
181 bool operator()(const T& x,const Q& y)const{return x<y;}
|
Chris@16
|
182 };
|
Chris@16
|
183
|
Chris@16
|
184 typedef tuple<
|
Chris@16
|
185 BOOST_MULTI_INDEX_CK_ENUM(
|
Chris@16
|
186 BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
|
Chris@16
|
187 detail::generic_operator_less)> generic_operator_less_tuple;
|
Chris@16
|
188
|
Chris@16
|
189 /* Metaprogramming machinery for implementing equality, comparison and
|
Chris@16
|
190 * hashing operations of composite_key_result.
|
Chris@16
|
191 *
|
Chris@16
|
192 * equal_* checks for equality between composite_key_results and
|
Chris@16
|
193 * between those and tuples, accepting a tuple of basic equality functors.
|
Chris@16
|
194 * compare_* does lexicographical comparison.
|
Chris@16
|
195 * hash_* computes a combination of elementwise hash values.
|
Chris@16
|
196 */
|
Chris@16
|
197
|
Chris@16
|
198 template
|
Chris@16
|
199 <
|
Chris@16
|
200 typename KeyCons1,typename Value1,
|
Chris@16
|
201 typename KeyCons2, typename Value2,
|
Chris@16
|
202 typename EqualCons
|
Chris@16
|
203 >
|
Chris@16
|
204 struct equal_ckey_ckey; /* fwd decl. */
|
Chris@16
|
205
|
Chris@16
|
206 template
|
Chris@16
|
207 <
|
Chris@16
|
208 typename KeyCons1,typename Value1,
|
Chris@16
|
209 typename KeyCons2, typename Value2,
|
Chris@16
|
210 typename EqualCons
|
Chris@16
|
211 >
|
Chris@16
|
212 struct equal_ckey_ckey_terminal
|
Chris@16
|
213 {
|
Chris@16
|
214 static bool compare(
|
Chris@16
|
215 const KeyCons1&,const Value1&,
|
Chris@16
|
216 const KeyCons2&,const Value2&,
|
Chris@16
|
217 const EqualCons&)
|
Chris@16
|
218 {
|
Chris@16
|
219 return true;
|
Chris@16
|
220 }
|
Chris@16
|
221 };
|
Chris@16
|
222
|
Chris@16
|
223 template
|
Chris@16
|
224 <
|
Chris@16
|
225 typename KeyCons1,typename Value1,
|
Chris@16
|
226 typename KeyCons2, typename Value2,
|
Chris@16
|
227 typename EqualCons
|
Chris@16
|
228 >
|
Chris@16
|
229 struct equal_ckey_ckey_normal
|
Chris@16
|
230 {
|
Chris@16
|
231 static bool compare(
|
Chris@16
|
232 const KeyCons1& c0,const Value1& v0,
|
Chris@16
|
233 const KeyCons2& c1,const Value2& v1,
|
Chris@16
|
234 const EqualCons& eq)
|
Chris@16
|
235 {
|
Chris@16
|
236 if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false;
|
Chris@16
|
237 return equal_ckey_ckey<
|
Chris@16
|
238 BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
|
Chris@16
|
239 BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
|
Chris@16
|
240 BOOST_DEDUCED_TYPENAME EqualCons::tail_type
|
Chris@16
|
241 >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail());
|
Chris@16
|
242 }
|
Chris@16
|
243 };
|
Chris@16
|
244
|
Chris@16
|
245 template
|
Chris@16
|
246 <
|
Chris@16
|
247 typename KeyCons1,typename Value1,
|
Chris@16
|
248 typename KeyCons2, typename Value2,
|
Chris@16
|
249 typename EqualCons
|
Chris@16
|
250 >
|
Chris@16
|
251 struct equal_ckey_ckey:
|
Chris@16
|
252 mpl::if_<
|
Chris@16
|
253 mpl::or_<
|
Chris@16
|
254 is_same<KeyCons1,tuples::null_type>,
|
Chris@16
|
255 is_same<KeyCons2,tuples::null_type>
|
Chris@16
|
256 >,
|
Chris@16
|
257 equal_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>,
|
Chris@16
|
258 equal_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>
|
Chris@16
|
259 >::type
|
Chris@16
|
260 {
|
Chris@16
|
261 };
|
Chris@16
|
262
|
Chris@16
|
263 template
|
Chris@16
|
264 <
|
Chris@16
|
265 typename KeyCons,typename Value,
|
Chris@16
|
266 typename ValCons,typename EqualCons
|
Chris@16
|
267 >
|
Chris@16
|
268 struct equal_ckey_cval; /* fwd decl. */
|
Chris@16
|
269
|
Chris@16
|
270 template
|
Chris@16
|
271 <
|
Chris@16
|
272 typename KeyCons,typename Value,
|
Chris@16
|
273 typename ValCons,typename EqualCons
|
Chris@16
|
274 >
|
Chris@16
|
275 struct equal_ckey_cval_terminal
|
Chris@16
|
276 {
|
Chris@16
|
277 static bool compare(
|
Chris@16
|
278 const KeyCons&,const Value&,const ValCons&,const EqualCons&)
|
Chris@16
|
279 {
|
Chris@16
|
280 return true;
|
Chris@16
|
281 }
|
Chris@16
|
282
|
Chris@16
|
283 static bool compare(
|
Chris@16
|
284 const ValCons&,const KeyCons&,const Value&,const EqualCons&)
|
Chris@16
|
285 {
|
Chris@16
|
286 return true;
|
Chris@16
|
287 }
|
Chris@16
|
288 };
|
Chris@16
|
289
|
Chris@16
|
290 template
|
Chris@16
|
291 <
|
Chris@16
|
292 typename KeyCons,typename Value,
|
Chris@16
|
293 typename ValCons,typename EqualCons
|
Chris@16
|
294 >
|
Chris@16
|
295 struct equal_ckey_cval_normal
|
Chris@16
|
296 {
|
Chris@16
|
297 static bool compare(
|
Chris@16
|
298 const KeyCons& c,const Value& v,const ValCons& vc,
|
Chris@16
|
299 const EqualCons& eq)
|
Chris@16
|
300 {
|
Chris@16
|
301 if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false;
|
Chris@16
|
302 return equal_ckey_cval<
|
Chris@16
|
303 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
|
Chris@16
|
304 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
|
Chris@16
|
305 BOOST_DEDUCED_TYPENAME EqualCons::tail_type
|
Chris@16
|
306 >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail());
|
Chris@16
|
307 }
|
Chris@16
|
308
|
Chris@16
|
309 static bool compare(
|
Chris@16
|
310 const ValCons& vc,const KeyCons& c,const Value& v,
|
Chris@16
|
311 const EqualCons& eq)
|
Chris@16
|
312 {
|
Chris@16
|
313 if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false;
|
Chris@16
|
314 return equal_ckey_cval<
|
Chris@16
|
315 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
|
Chris@16
|
316 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
|
Chris@16
|
317 BOOST_DEDUCED_TYPENAME EqualCons::tail_type
|
Chris@16
|
318 >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail());
|
Chris@16
|
319 }
|
Chris@16
|
320 };
|
Chris@16
|
321
|
Chris@16
|
322 template
|
Chris@16
|
323 <
|
Chris@16
|
324 typename KeyCons,typename Value,
|
Chris@16
|
325 typename ValCons,typename EqualCons
|
Chris@16
|
326 >
|
Chris@16
|
327 struct equal_ckey_cval:
|
Chris@16
|
328 mpl::if_<
|
Chris@16
|
329 mpl::or_<
|
Chris@16
|
330 is_same<KeyCons,tuples::null_type>,
|
Chris@16
|
331 is_same<ValCons,tuples::null_type>
|
Chris@16
|
332 >,
|
Chris@16
|
333 equal_ckey_cval_terminal<KeyCons,Value,ValCons,EqualCons>,
|
Chris@16
|
334 equal_ckey_cval_normal<KeyCons,Value,ValCons,EqualCons>
|
Chris@16
|
335 >::type
|
Chris@16
|
336 {
|
Chris@16
|
337 };
|
Chris@16
|
338
|
Chris@16
|
339 template
|
Chris@16
|
340 <
|
Chris@16
|
341 typename KeyCons1,typename Value1,
|
Chris@16
|
342 typename KeyCons2, typename Value2,
|
Chris@16
|
343 typename CompareCons
|
Chris@16
|
344 >
|
Chris@16
|
345 struct compare_ckey_ckey; /* fwd decl. */
|
Chris@16
|
346
|
Chris@16
|
347 template
|
Chris@16
|
348 <
|
Chris@16
|
349 typename KeyCons1,typename Value1,
|
Chris@16
|
350 typename KeyCons2, typename Value2,
|
Chris@16
|
351 typename CompareCons
|
Chris@16
|
352 >
|
Chris@16
|
353 struct compare_ckey_ckey_terminal
|
Chris@16
|
354 {
|
Chris@16
|
355 static bool compare(
|
Chris@16
|
356 const KeyCons1&,const Value1&,
|
Chris@16
|
357 const KeyCons2&,const Value2&,
|
Chris@16
|
358 const CompareCons&)
|
Chris@16
|
359 {
|
Chris@16
|
360 return false;
|
Chris@16
|
361 }
|
Chris@16
|
362 };
|
Chris@16
|
363
|
Chris@16
|
364 template
|
Chris@16
|
365 <
|
Chris@16
|
366 typename KeyCons1,typename Value1,
|
Chris@16
|
367 typename KeyCons2, typename Value2,
|
Chris@16
|
368 typename CompareCons
|
Chris@16
|
369 >
|
Chris@16
|
370 struct compare_ckey_ckey_normal
|
Chris@16
|
371 {
|
Chris@16
|
372 static bool compare(
|
Chris@16
|
373 const KeyCons1& c0,const Value1& v0,
|
Chris@16
|
374 const KeyCons2& c1,const Value2& v1,
|
Chris@16
|
375 const CompareCons& comp)
|
Chris@16
|
376 {
|
Chris@16
|
377 if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true;
|
Chris@16
|
378 if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false;
|
Chris@16
|
379 return compare_ckey_ckey<
|
Chris@16
|
380 BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
|
Chris@16
|
381 BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
|
Chris@16
|
382 BOOST_DEDUCED_TYPENAME CompareCons::tail_type
|
Chris@16
|
383 >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail());
|
Chris@16
|
384 }
|
Chris@16
|
385 };
|
Chris@16
|
386
|
Chris@16
|
387 template
|
Chris@16
|
388 <
|
Chris@16
|
389 typename KeyCons1,typename Value1,
|
Chris@16
|
390 typename KeyCons2, typename Value2,
|
Chris@16
|
391 typename CompareCons
|
Chris@16
|
392 >
|
Chris@16
|
393 struct compare_ckey_ckey:
|
Chris@16
|
394 mpl::if_<
|
Chris@16
|
395 mpl::or_<
|
Chris@16
|
396 is_same<KeyCons1,tuples::null_type>,
|
Chris@16
|
397 is_same<KeyCons2,tuples::null_type>
|
Chris@16
|
398 >,
|
Chris@16
|
399 compare_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>,
|
Chris@16
|
400 compare_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>
|
Chris@16
|
401 >::type
|
Chris@16
|
402 {
|
Chris@16
|
403 };
|
Chris@16
|
404
|
Chris@16
|
405 template
|
Chris@16
|
406 <
|
Chris@16
|
407 typename KeyCons,typename Value,
|
Chris@16
|
408 typename ValCons,typename CompareCons
|
Chris@16
|
409 >
|
Chris@16
|
410 struct compare_ckey_cval; /* fwd decl. */
|
Chris@16
|
411
|
Chris@16
|
412 template
|
Chris@16
|
413 <
|
Chris@16
|
414 typename KeyCons,typename Value,
|
Chris@16
|
415 typename ValCons,typename CompareCons
|
Chris@16
|
416 >
|
Chris@16
|
417 struct compare_ckey_cval_terminal
|
Chris@16
|
418 {
|
Chris@16
|
419 static bool compare(
|
Chris@16
|
420 const KeyCons&,const Value&,const ValCons&,const CompareCons&)
|
Chris@16
|
421 {
|
Chris@16
|
422 return false;
|
Chris@16
|
423 }
|
Chris@16
|
424
|
Chris@16
|
425 static bool compare(
|
Chris@16
|
426 const ValCons&,const KeyCons&,const Value&,const CompareCons&)
|
Chris@16
|
427 {
|
Chris@16
|
428 return false;
|
Chris@16
|
429 }
|
Chris@16
|
430 };
|
Chris@16
|
431
|
Chris@16
|
432 template
|
Chris@16
|
433 <
|
Chris@16
|
434 typename KeyCons,typename Value,
|
Chris@16
|
435 typename ValCons,typename CompareCons
|
Chris@16
|
436 >
|
Chris@16
|
437 struct compare_ckey_cval_normal
|
Chris@16
|
438 {
|
Chris@16
|
439 static bool compare(
|
Chris@16
|
440 const KeyCons& c,const Value& v,const ValCons& vc,
|
Chris@16
|
441 const CompareCons& comp)
|
Chris@16
|
442 {
|
Chris@16
|
443 if(comp.get_head()(c.get_head()(v),vc.get_head()))return true;
|
Chris@16
|
444 if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false;
|
Chris@16
|
445 return compare_ckey_cval<
|
Chris@16
|
446 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
|
Chris@16
|
447 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
|
Chris@16
|
448 BOOST_DEDUCED_TYPENAME CompareCons::tail_type
|
Chris@16
|
449 >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail());
|
Chris@16
|
450 }
|
Chris@16
|
451
|
Chris@16
|
452 static bool compare(
|
Chris@16
|
453 const ValCons& vc,const KeyCons& c,const Value& v,
|
Chris@16
|
454 const CompareCons& comp)
|
Chris@16
|
455 {
|
Chris@16
|
456 if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true;
|
Chris@16
|
457 if(comp.get_head()(c.get_head()(v),vc.get_head()))return false;
|
Chris@16
|
458 return compare_ckey_cval<
|
Chris@16
|
459 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
|
Chris@16
|
460 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
|
Chris@16
|
461 BOOST_DEDUCED_TYPENAME CompareCons::tail_type
|
Chris@16
|
462 >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail());
|
Chris@16
|
463 }
|
Chris@16
|
464 };
|
Chris@16
|
465
|
Chris@16
|
466 template
|
Chris@16
|
467 <
|
Chris@16
|
468 typename KeyCons,typename Value,
|
Chris@16
|
469 typename ValCons,typename CompareCons
|
Chris@16
|
470 >
|
Chris@16
|
471 struct compare_ckey_cval:
|
Chris@16
|
472 mpl::if_<
|
Chris@16
|
473 mpl::or_<
|
Chris@16
|
474 is_same<KeyCons,tuples::null_type>,
|
Chris@16
|
475 is_same<ValCons,tuples::null_type>
|
Chris@16
|
476 >,
|
Chris@16
|
477 compare_ckey_cval_terminal<KeyCons,Value,ValCons,CompareCons>,
|
Chris@16
|
478 compare_ckey_cval_normal<KeyCons,Value,ValCons,CompareCons>
|
Chris@16
|
479 >::type
|
Chris@16
|
480 {
|
Chris@16
|
481 };
|
Chris@16
|
482
|
Chris@16
|
483 template<typename KeyCons,typename Value,typename HashCons>
|
Chris@16
|
484 struct hash_ckey; /* fwd decl. */
|
Chris@16
|
485
|
Chris@16
|
486 template<typename KeyCons,typename Value,typename HashCons>
|
Chris@16
|
487 struct hash_ckey_terminal
|
Chris@16
|
488 {
|
Chris@16
|
489 static std::size_t hash(
|
Chris@16
|
490 const KeyCons&,const Value&,const HashCons&,std::size_t carry)
|
Chris@16
|
491 {
|
Chris@16
|
492 return carry;
|
Chris@16
|
493 }
|
Chris@16
|
494 };
|
Chris@16
|
495
|
Chris@16
|
496 template<typename KeyCons,typename Value,typename HashCons>
|
Chris@16
|
497 struct hash_ckey_normal
|
Chris@16
|
498 {
|
Chris@16
|
499 static std::size_t hash(
|
Chris@16
|
500 const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0)
|
Chris@16
|
501 {
|
Chris@16
|
502 /* same hashing formula as boost::hash_combine */
|
Chris@16
|
503
|
Chris@16
|
504 carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2);
|
Chris@16
|
505 return hash_ckey<
|
Chris@16
|
506 BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
|
Chris@16
|
507 BOOST_DEDUCED_TYPENAME HashCons::tail_type
|
Chris@16
|
508 >::hash(c.get_tail(),v,h.get_tail(),carry);
|
Chris@16
|
509 }
|
Chris@16
|
510 };
|
Chris@16
|
511
|
Chris@16
|
512 template<typename KeyCons,typename Value,typename HashCons>
|
Chris@16
|
513 struct hash_ckey:
|
Chris@16
|
514 mpl::if_<
|
Chris@16
|
515 is_same<KeyCons,tuples::null_type>,
|
Chris@16
|
516 hash_ckey_terminal<KeyCons,Value,HashCons>,
|
Chris@16
|
517 hash_ckey_normal<KeyCons,Value,HashCons>
|
Chris@16
|
518 >::type
|
Chris@16
|
519 {
|
Chris@16
|
520 };
|
Chris@16
|
521
|
Chris@16
|
522 template<typename ValCons,typename HashCons>
|
Chris@16
|
523 struct hash_cval; /* fwd decl. */
|
Chris@16
|
524
|
Chris@16
|
525 template<typename ValCons,typename HashCons>
|
Chris@16
|
526 struct hash_cval_terminal
|
Chris@16
|
527 {
|
Chris@16
|
528 static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry)
|
Chris@16
|
529 {
|
Chris@16
|
530 return carry;
|
Chris@16
|
531 }
|
Chris@16
|
532 };
|
Chris@16
|
533
|
Chris@16
|
534 template<typename ValCons,typename HashCons>
|
Chris@16
|
535 struct hash_cval_normal
|
Chris@16
|
536 {
|
Chris@16
|
537 static std::size_t hash(
|
Chris@16
|
538 const ValCons& vc,const HashCons& h,std::size_t carry=0)
|
Chris@16
|
539 {
|
Chris@16
|
540 carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2);
|
Chris@16
|
541 return hash_cval<
|
Chris@16
|
542 BOOST_DEDUCED_TYPENAME ValCons::tail_type,
|
Chris@16
|
543 BOOST_DEDUCED_TYPENAME HashCons::tail_type
|
Chris@16
|
544 >::hash(vc.get_tail(),h.get_tail(),carry);
|
Chris@16
|
545 }
|
Chris@16
|
546 };
|
Chris@16
|
547
|
Chris@16
|
548 template<typename ValCons,typename HashCons>
|
Chris@16
|
549 struct hash_cval:
|
Chris@16
|
550 mpl::if_<
|
Chris@16
|
551 is_same<ValCons,tuples::null_type>,
|
Chris@16
|
552 hash_cval_terminal<ValCons,HashCons>,
|
Chris@16
|
553 hash_cval_normal<ValCons,HashCons>
|
Chris@16
|
554 >::type
|
Chris@16
|
555 {
|
Chris@16
|
556 };
|
Chris@16
|
557
|
Chris@16
|
558 } /* namespace multi_index::detail */
|
Chris@16
|
559
|
Chris@16
|
560 /* composite_key_result */
|
Chris@16
|
561
|
Chris@16
|
562 #if defined(BOOST_MSVC)
|
Chris@16
|
563 #pragma warning(push)
|
Chris@16
|
564 #pragma warning(disable:4512)
|
Chris@16
|
565 #endif
|
Chris@16
|
566
|
Chris@16
|
567 template<typename CompositeKey>
|
Chris@16
|
568 struct composite_key_result
|
Chris@16
|
569 {
|
Chris@16
|
570 typedef CompositeKey composite_key_type;
|
Chris@16
|
571 typedef typename composite_key_type::value_type value_type;
|
Chris@16
|
572
|
Chris@16
|
573 composite_key_result(
|
Chris@16
|
574 const composite_key_type& composite_key_,const value_type& value_):
|
Chris@16
|
575 composite_key(composite_key_),value(value_)
|
Chris@16
|
576 {}
|
Chris@16
|
577
|
Chris@16
|
578 const composite_key_type& composite_key;
|
Chris@16
|
579 const value_type& value;
|
Chris@16
|
580 };
|
Chris@16
|
581
|
Chris@16
|
582 #if defined(BOOST_MSVC)
|
Chris@16
|
583 #pragma warning(pop)
|
Chris@16
|
584 #endif
|
Chris@16
|
585
|
Chris@16
|
586 /* composite_key */
|
Chris@16
|
587
|
Chris@16
|
588 template<
|
Chris@16
|
589 typename Value,
|
Chris@16
|
590 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue)
|
Chris@16
|
591 >
|
Chris@16
|
592 struct composite_key:
|
Chris@16
|
593 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)>
|
Chris@16
|
594 {
|
Chris@16
|
595 private:
|
Chris@16
|
596 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)> super;
|
Chris@16
|
597
|
Chris@16
|
598 public:
|
Chris@16
|
599 typedef super key_extractor_tuple;
|
Chris@16
|
600 typedef Value value_type;
|
Chris@16
|
601 typedef composite_key_result<composite_key> result_type;
|
Chris@16
|
602
|
Chris@16
|
603 composite_key(
|
Chris@16
|
604 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)):
|
Chris@16
|
605 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
|
Chris@16
|
606 {}
|
Chris@16
|
607
|
Chris@16
|
608 composite_key(const key_extractor_tuple& x):super(x){}
|
Chris@16
|
609
|
Chris@16
|
610 const key_extractor_tuple& key_extractors()const{return *this;}
|
Chris@16
|
611 key_extractor_tuple& key_extractors(){return *this;}
|
Chris@16
|
612
|
Chris@16
|
613 template<typename ChainedPtr>
|
Chris@16
|
614
|
Chris@16
|
615 #if !defined(BOOST_NO_SFINAE)
|
Chris@16
|
616 typename disable_if<
|
Chris@16
|
617 is_convertible<const ChainedPtr&,const value_type&>,result_type>::type
|
Chris@16
|
618 #else
|
Chris@16
|
619 result_type
|
Chris@16
|
620 #endif
|
Chris@16
|
621
|
Chris@16
|
622 operator()(const ChainedPtr& x)const
|
Chris@16
|
623 {
|
Chris@16
|
624 return operator()(*x);
|
Chris@16
|
625 }
|
Chris@16
|
626
|
Chris@16
|
627 result_type operator()(const value_type& x)const
|
Chris@16
|
628 {
|
Chris@16
|
629 return result_type(*this,x);
|
Chris@16
|
630 }
|
Chris@16
|
631
|
Chris@16
|
632 result_type operator()(const reference_wrapper<const value_type>& x)const
|
Chris@16
|
633 {
|
Chris@16
|
634 return result_type(*this,x.get());
|
Chris@16
|
635 }
|
Chris@16
|
636
|
Chris@101
|
637 result_type operator()(const reference_wrapper<value_type>& x)const
|
Chris@16
|
638 {
|
Chris@16
|
639 return result_type(*this,x.get());
|
Chris@16
|
640 }
|
Chris@16
|
641 };
|
Chris@16
|
642
|
Chris@16
|
643 /* comparison operators */
|
Chris@16
|
644
|
Chris@16
|
645 /* == */
|
Chris@16
|
646
|
Chris@16
|
647 template<typename CompositeKey1,typename CompositeKey2>
|
Chris@16
|
648 inline bool operator==(
|
Chris@16
|
649 const composite_key_result<CompositeKey1>& x,
|
Chris@16
|
650 const composite_key_result<CompositeKey2>& y)
|
Chris@16
|
651 {
|
Chris@16
|
652 typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
|
Chris@16
|
653 typedef typename CompositeKey1::value_type value_type1;
|
Chris@16
|
654 typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
|
Chris@16
|
655 typedef typename CompositeKey2::value_type value_type2;
|
Chris@16
|
656
|
Chris@16
|
657 BOOST_STATIC_ASSERT(
|
Chris@16
|
658 tuples::length<key_extractor_tuple1>::value==
|
Chris@16
|
659 tuples::length<key_extractor_tuple2>::value);
|
Chris@16
|
660
|
Chris@16
|
661 return detail::equal_ckey_ckey<
|
Chris@16
|
662 key_extractor_tuple1,value_type1,
|
Chris@16
|
663 key_extractor_tuple2,value_type2,
|
Chris@16
|
664 detail::generic_operator_equal_tuple
|
Chris@16
|
665 >::compare(
|
Chris@16
|
666 x.composite_key.key_extractors(),x.value,
|
Chris@16
|
667 y.composite_key.key_extractors(),y.value,
|
Chris@16
|
668 detail::generic_operator_equal_tuple());
|
Chris@16
|
669 }
|
Chris@16
|
670
|
Chris@16
|
671 template<
|
Chris@16
|
672 typename CompositeKey,
|
Chris@16
|
673 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
|
Chris@16
|
674 >
|
Chris@16
|
675 inline bool operator==(
|
Chris@16
|
676 const composite_key_result<CompositeKey>& x,
|
Chris@16
|
677 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
|
Chris@16
|
678 {
|
Chris@16
|
679 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@16
|
680 typedef typename CompositeKey::value_type value_type;
|
Chris@16
|
681 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
|
Chris@16
|
682
|
Chris@16
|
683 BOOST_STATIC_ASSERT(
|
Chris@16
|
684 tuples::length<key_extractor_tuple>::value==
|
Chris@16
|
685 tuples::length<key_tuple>::value);
|
Chris@16
|
686
|
Chris@16
|
687 return detail::equal_ckey_cval<
|
Chris@16
|
688 key_extractor_tuple,value_type,
|
Chris@16
|
689 key_tuple,detail::generic_operator_equal_tuple
|
Chris@16
|
690 >::compare(
|
Chris@16
|
691 x.composite_key.key_extractors(),x.value,
|
Chris@16
|
692 y,detail::generic_operator_equal_tuple());
|
Chris@16
|
693 }
|
Chris@16
|
694
|
Chris@16
|
695 template
|
Chris@16
|
696 <
|
Chris@16
|
697 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
|
Chris@16
|
698 typename CompositeKey
|
Chris@16
|
699 >
|
Chris@16
|
700 inline bool operator==(
|
Chris@16
|
701 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
|
Chris@16
|
702 const composite_key_result<CompositeKey>& y)
|
Chris@16
|
703 {
|
Chris@16
|
704 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@16
|
705 typedef typename CompositeKey::value_type value_type;
|
Chris@16
|
706 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
|
Chris@16
|
707
|
Chris@16
|
708 BOOST_STATIC_ASSERT(
|
Chris@16
|
709 tuples::length<key_extractor_tuple>::value==
|
Chris@16
|
710 tuples::length<key_tuple>::value);
|
Chris@16
|
711
|
Chris@16
|
712 return detail::equal_ckey_cval<
|
Chris@16
|
713 key_extractor_tuple,value_type,
|
Chris@16
|
714 key_tuple,detail::generic_operator_equal_tuple
|
Chris@16
|
715 >::compare(
|
Chris@16
|
716 x,y.composite_key.key_extractors(),
|
Chris@16
|
717 y.value,detail::generic_operator_equal_tuple());
|
Chris@16
|
718 }
|
Chris@16
|
719
|
Chris@101
|
720 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
|
Chris@101
|
721 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
722 template<typename CompositeKey,typename... Values>
|
Chris@101
|
723 inline bool operator==(
|
Chris@101
|
724 const composite_key_result<CompositeKey>& x,
|
Chris@101
|
725 const std::tuple<Values...>& y)
|
Chris@101
|
726 {
|
Chris@101
|
727 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@101
|
728 typedef typename CompositeKey::value_type value_type;
|
Chris@101
|
729 typedef std::tuple<Values...> key_tuple;
|
Chris@101
|
730 typedef typename detail::cons_stdtuple_ctor<
|
Chris@101
|
731 key_tuple>::result_type cons_key_tuple;
|
Chris@101
|
732
|
Chris@101
|
733 BOOST_STATIC_ASSERT(
|
Chris@101
|
734 tuples::length<key_extractor_tuple>::value==
|
Chris@101
|
735 std::tuple_size<key_tuple>::value);
|
Chris@101
|
736
|
Chris@101
|
737 return detail::equal_ckey_cval<
|
Chris@101
|
738 key_extractor_tuple,value_type,
|
Chris@101
|
739 cons_key_tuple,detail::generic_operator_equal_tuple
|
Chris@101
|
740 >::compare(
|
Chris@101
|
741 x.composite_key.key_extractors(),x.value,
|
Chris@101
|
742 detail::make_cons_stdtuple(y),detail::generic_operator_equal_tuple());
|
Chris@101
|
743 }
|
Chris@101
|
744
|
Chris@101
|
745 template<typename CompositeKey,typename... Values>
|
Chris@101
|
746 inline bool operator==(
|
Chris@101
|
747 const std::tuple<Values...>& x,
|
Chris@101
|
748 const composite_key_result<CompositeKey>& y)
|
Chris@101
|
749 {
|
Chris@101
|
750 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@101
|
751 typedef typename CompositeKey::value_type value_type;
|
Chris@101
|
752 typedef std::tuple<Values...> key_tuple;
|
Chris@101
|
753 typedef typename detail::cons_stdtuple_ctor<
|
Chris@101
|
754 key_tuple>::result_type cons_key_tuple;
|
Chris@101
|
755
|
Chris@101
|
756 BOOST_STATIC_ASSERT(
|
Chris@101
|
757 tuples::length<key_extractor_tuple>::value==
|
Chris@101
|
758 std::tuple_size<key_tuple>::value);
|
Chris@101
|
759
|
Chris@101
|
760 return detail::equal_ckey_cval<
|
Chris@101
|
761 key_extractor_tuple,value_type,
|
Chris@101
|
762 cons_key_tuple,detail::generic_operator_equal_tuple
|
Chris@101
|
763 >::compare(
|
Chris@101
|
764 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
|
Chris@101
|
765 y.value,detail::generic_operator_equal_tuple());
|
Chris@101
|
766 }
|
Chris@101
|
767 #endif
|
Chris@101
|
768
|
Chris@16
|
769 /* < */
|
Chris@16
|
770
|
Chris@16
|
771 template<typename CompositeKey1,typename CompositeKey2>
|
Chris@16
|
772 inline bool operator<(
|
Chris@16
|
773 const composite_key_result<CompositeKey1>& x,
|
Chris@16
|
774 const composite_key_result<CompositeKey2>& y)
|
Chris@16
|
775 {
|
Chris@16
|
776 typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
|
Chris@16
|
777 typedef typename CompositeKey1::value_type value_type1;
|
Chris@16
|
778 typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
|
Chris@16
|
779 typedef typename CompositeKey2::value_type value_type2;
|
Chris@16
|
780
|
Chris@16
|
781 return detail::compare_ckey_ckey<
|
Chris@16
|
782 key_extractor_tuple1,value_type1,
|
Chris@16
|
783 key_extractor_tuple2,value_type2,
|
Chris@16
|
784 detail::generic_operator_less_tuple
|
Chris@16
|
785 >::compare(
|
Chris@16
|
786 x.composite_key.key_extractors(),x.value,
|
Chris@16
|
787 y.composite_key.key_extractors(),y.value,
|
Chris@16
|
788 detail::generic_operator_less_tuple());
|
Chris@16
|
789 }
|
Chris@16
|
790
|
Chris@16
|
791 template
|
Chris@16
|
792 <
|
Chris@16
|
793 typename CompositeKey,
|
Chris@16
|
794 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
|
Chris@16
|
795 >
|
Chris@16
|
796 inline bool operator<(
|
Chris@16
|
797 const composite_key_result<CompositeKey>& x,
|
Chris@16
|
798 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
|
Chris@16
|
799 {
|
Chris@16
|
800 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@16
|
801 typedef typename CompositeKey::value_type value_type;
|
Chris@16
|
802 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
|
Chris@16
|
803
|
Chris@16
|
804 return detail::compare_ckey_cval<
|
Chris@16
|
805 key_extractor_tuple,value_type,
|
Chris@16
|
806 key_tuple,detail::generic_operator_less_tuple
|
Chris@16
|
807 >::compare(
|
Chris@16
|
808 x.composite_key.key_extractors(),x.value,
|
Chris@16
|
809 y,detail::generic_operator_less_tuple());
|
Chris@16
|
810 }
|
Chris@16
|
811
|
Chris@16
|
812 template
|
Chris@16
|
813 <
|
Chris@16
|
814 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
|
Chris@16
|
815 typename CompositeKey
|
Chris@16
|
816 >
|
Chris@16
|
817 inline bool operator<(
|
Chris@16
|
818 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
|
Chris@16
|
819 const composite_key_result<CompositeKey>& y)
|
Chris@16
|
820 {
|
Chris@16
|
821 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@16
|
822 typedef typename CompositeKey::value_type value_type;
|
Chris@16
|
823 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
|
Chris@16
|
824
|
Chris@16
|
825 return detail::compare_ckey_cval<
|
Chris@16
|
826 key_extractor_tuple,value_type,
|
Chris@16
|
827 key_tuple,detail::generic_operator_less_tuple
|
Chris@16
|
828 >::compare(
|
Chris@16
|
829 x,y.composite_key.key_extractors(),
|
Chris@16
|
830 y.value,detail::generic_operator_less_tuple());
|
Chris@16
|
831 }
|
Chris@16
|
832
|
Chris@101
|
833 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
|
Chris@101
|
834 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
835 template<typename CompositeKey,typename... Values>
|
Chris@101
|
836 inline bool operator<(
|
Chris@101
|
837 const composite_key_result<CompositeKey>& x,
|
Chris@101
|
838 const std::tuple<Values...>& y)
|
Chris@101
|
839 {
|
Chris@101
|
840 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@101
|
841 typedef typename CompositeKey::value_type value_type;
|
Chris@101
|
842 typedef std::tuple<Values...> key_tuple;
|
Chris@101
|
843 typedef typename detail::cons_stdtuple_ctor<
|
Chris@101
|
844 key_tuple>::result_type cons_key_tuple;
|
Chris@101
|
845
|
Chris@101
|
846 return detail::compare_ckey_cval<
|
Chris@101
|
847 key_extractor_tuple,value_type,
|
Chris@101
|
848 cons_key_tuple,detail::generic_operator_less_tuple
|
Chris@101
|
849 >::compare(
|
Chris@101
|
850 x.composite_key.key_extractors(),x.value,
|
Chris@101
|
851 detail::make_cons_stdtuple(y),detail::generic_operator_less_tuple());
|
Chris@101
|
852 }
|
Chris@101
|
853
|
Chris@101
|
854 template<typename CompositeKey,typename... Values>
|
Chris@101
|
855 inline bool operator<(
|
Chris@101
|
856 const std::tuple<Values...>& x,
|
Chris@101
|
857 const composite_key_result<CompositeKey>& y)
|
Chris@101
|
858 {
|
Chris@101
|
859 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@101
|
860 typedef typename CompositeKey::value_type value_type;
|
Chris@101
|
861 typedef std::tuple<Values...> key_tuple;
|
Chris@101
|
862 typedef typename detail::cons_stdtuple_ctor<
|
Chris@101
|
863 key_tuple>::result_type cons_key_tuple;
|
Chris@101
|
864
|
Chris@101
|
865 return detail::compare_ckey_cval<
|
Chris@101
|
866 key_extractor_tuple,value_type,
|
Chris@101
|
867 cons_key_tuple,detail::generic_operator_less_tuple
|
Chris@101
|
868 >::compare(
|
Chris@101
|
869 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
|
Chris@101
|
870 y.value,detail::generic_operator_less_tuple());
|
Chris@101
|
871 }
|
Chris@101
|
872 #endif
|
Chris@101
|
873
|
Chris@16
|
874 /* rest of comparison operators */
|
Chris@16
|
875
|
Chris@16
|
876 #define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \
|
Chris@16
|
877 template<t1,t2> inline bool operator!=(const a1& x,const a2& y) \
|
Chris@16
|
878 { \
|
Chris@16
|
879 return !(x==y); \
|
Chris@16
|
880 } \
|
Chris@16
|
881 \
|
Chris@16
|
882 template<t1,t2> inline bool operator>(const a1& x,const a2& y) \
|
Chris@16
|
883 { \
|
Chris@16
|
884 return y<x; \
|
Chris@16
|
885 } \
|
Chris@16
|
886 \
|
Chris@16
|
887 template<t1,t2> inline bool operator>=(const a1& x,const a2& y) \
|
Chris@16
|
888 { \
|
Chris@16
|
889 return !(x<y); \
|
Chris@16
|
890 } \
|
Chris@16
|
891 \
|
Chris@16
|
892 template<t1,t2> inline bool operator<=(const a1& x,const a2& y) \
|
Chris@16
|
893 { \
|
Chris@16
|
894 return !(y<x); \
|
Chris@16
|
895 }
|
Chris@16
|
896
|
Chris@16
|
897 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
|
Chris@16
|
898 typename CompositeKey1,
|
Chris@16
|
899 typename CompositeKey2,
|
Chris@16
|
900 composite_key_result<CompositeKey1>,
|
Chris@16
|
901 composite_key_result<CompositeKey2>
|
Chris@16
|
902 )
|
Chris@16
|
903
|
Chris@16
|
904 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
|
Chris@16
|
905 typename CompositeKey,
|
Chris@16
|
906 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
|
Chris@16
|
907 composite_key_result<CompositeKey>,
|
Chris@16
|
908 tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>
|
Chris@16
|
909 )
|
Chris@16
|
910
|
Chris@16
|
911 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
|
Chris@16
|
912 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
|
Chris@16
|
913 typename CompositeKey,
|
Chris@16
|
914 tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>,
|
Chris@16
|
915 composite_key_result<CompositeKey>
|
Chris@16
|
916 )
|
Chris@16
|
917
|
Chris@101
|
918 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
|
Chris@101
|
919 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
920 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
|
Chris@101
|
921 typename CompositeKey,
|
Chris@101
|
922 typename... Values,
|
Chris@101
|
923 composite_key_result<CompositeKey>,
|
Chris@101
|
924 std::tuple<Values...>
|
Chris@101
|
925 )
|
Chris@101
|
926
|
Chris@101
|
927 BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
|
Chris@101
|
928 typename CompositeKey,
|
Chris@101
|
929 typename... Values,
|
Chris@101
|
930 std::tuple<Values...>,
|
Chris@101
|
931 composite_key_result<CompositeKey>
|
Chris@101
|
932 )
|
Chris@101
|
933 #endif
|
Chris@101
|
934
|
Chris@16
|
935 /* composite_key_equal_to */
|
Chris@16
|
936
|
Chris@16
|
937 template
|
Chris@16
|
938 <
|
Chris@16
|
939 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred)
|
Chris@16
|
940 >
|
Chris@16
|
941 struct composite_key_equal_to:
|
Chris@16
|
942 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)>
|
Chris@16
|
943 {
|
Chris@16
|
944 private:
|
Chris@16
|
945 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)> super;
|
Chris@16
|
946
|
Chris@16
|
947 public:
|
Chris@16
|
948 typedef super key_eq_tuple;
|
Chris@16
|
949
|
Chris@16
|
950 composite_key_equal_to(
|
Chris@16
|
951 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)):
|
Chris@16
|
952 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
|
Chris@16
|
953 {}
|
Chris@16
|
954
|
Chris@16
|
955 composite_key_equal_to(const key_eq_tuple& x):super(x){}
|
Chris@16
|
956
|
Chris@16
|
957 const key_eq_tuple& key_eqs()const{return *this;}
|
Chris@16
|
958 key_eq_tuple& key_eqs(){return *this;}
|
Chris@16
|
959
|
Chris@16
|
960 template<typename CompositeKey1,typename CompositeKey2>
|
Chris@16
|
961 bool operator()(
|
Chris@16
|
962 const composite_key_result<CompositeKey1> & x,
|
Chris@16
|
963 const composite_key_result<CompositeKey2> & y)const
|
Chris@16
|
964 {
|
Chris@16
|
965 typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
|
Chris@16
|
966 typedef typename CompositeKey1::value_type value_type1;
|
Chris@16
|
967 typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
|
Chris@16
|
968 typedef typename CompositeKey2::value_type value_type2;
|
Chris@16
|
969
|
Chris@16
|
970 BOOST_STATIC_ASSERT(
|
Chris@16
|
971 tuples::length<key_extractor_tuple1>::value<=
|
Chris@16
|
972 tuples::length<key_eq_tuple>::value&&
|
Chris@16
|
973 tuples::length<key_extractor_tuple1>::value==
|
Chris@16
|
974 tuples::length<key_extractor_tuple2>::value);
|
Chris@16
|
975
|
Chris@16
|
976 return detail::equal_ckey_ckey<
|
Chris@16
|
977 key_extractor_tuple1,value_type1,
|
Chris@16
|
978 key_extractor_tuple2,value_type2,
|
Chris@16
|
979 key_eq_tuple
|
Chris@16
|
980 >::compare(
|
Chris@16
|
981 x.composite_key.key_extractors(),x.value,
|
Chris@16
|
982 y.composite_key.key_extractors(),y.value,
|
Chris@16
|
983 key_eqs());
|
Chris@16
|
984 }
|
Chris@16
|
985
|
Chris@16
|
986 template
|
Chris@16
|
987 <
|
Chris@16
|
988 typename CompositeKey,
|
Chris@16
|
989 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
|
Chris@16
|
990 >
|
Chris@16
|
991 bool operator()(
|
Chris@16
|
992 const composite_key_result<CompositeKey>& x,
|
Chris@16
|
993 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
|
Chris@16
|
994 {
|
Chris@16
|
995 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@16
|
996 typedef typename CompositeKey::value_type value_type;
|
Chris@16
|
997 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
|
Chris@16
|
998
|
Chris@16
|
999 BOOST_STATIC_ASSERT(
|
Chris@16
|
1000 tuples::length<key_extractor_tuple>::value<=
|
Chris@16
|
1001 tuples::length<key_eq_tuple>::value&&
|
Chris@16
|
1002 tuples::length<key_extractor_tuple>::value==
|
Chris@16
|
1003 tuples::length<key_tuple>::value);
|
Chris@16
|
1004
|
Chris@16
|
1005 return detail::equal_ckey_cval<
|
Chris@16
|
1006 key_extractor_tuple,value_type,
|
Chris@16
|
1007 key_tuple,key_eq_tuple
|
Chris@16
|
1008 >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs());
|
Chris@16
|
1009 }
|
Chris@16
|
1010
|
Chris@16
|
1011 template
|
Chris@16
|
1012 <
|
Chris@16
|
1013 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
|
Chris@16
|
1014 typename CompositeKey
|
Chris@16
|
1015 >
|
Chris@16
|
1016 bool operator()(
|
Chris@16
|
1017 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
|
Chris@16
|
1018 const composite_key_result<CompositeKey>& y)const
|
Chris@16
|
1019 {
|
Chris@16
|
1020 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@16
|
1021 typedef typename CompositeKey::value_type value_type;
|
Chris@16
|
1022 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
|
Chris@16
|
1023
|
Chris@16
|
1024 BOOST_STATIC_ASSERT(
|
Chris@16
|
1025 tuples::length<key_tuple>::value<=
|
Chris@16
|
1026 tuples::length<key_eq_tuple>::value&&
|
Chris@16
|
1027 tuples::length<key_tuple>::value==
|
Chris@16
|
1028 tuples::length<key_extractor_tuple>::value);
|
Chris@16
|
1029
|
Chris@16
|
1030 return detail::equal_ckey_cval<
|
Chris@16
|
1031 key_extractor_tuple,value_type,
|
Chris@16
|
1032 key_tuple,key_eq_tuple
|
Chris@16
|
1033 >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs());
|
Chris@16
|
1034 }
|
Chris@101
|
1035
|
Chris@101
|
1036 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
|
Chris@101
|
1037 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
1038 template<typename CompositeKey,typename... Values>
|
Chris@101
|
1039 bool operator()(
|
Chris@101
|
1040 const composite_key_result<CompositeKey>& x,
|
Chris@101
|
1041 const std::tuple<Values...>& y)const
|
Chris@101
|
1042 {
|
Chris@101
|
1043 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@101
|
1044 typedef typename CompositeKey::value_type value_type;
|
Chris@101
|
1045 typedef std::tuple<Values...> key_tuple;
|
Chris@101
|
1046 typedef typename detail::cons_stdtuple_ctor<
|
Chris@101
|
1047 key_tuple>::result_type cons_key_tuple;
|
Chris@101
|
1048
|
Chris@101
|
1049 BOOST_STATIC_ASSERT(
|
Chris@101
|
1050 tuples::length<key_extractor_tuple>::value<=
|
Chris@101
|
1051 tuples::length<key_eq_tuple>::value&&
|
Chris@101
|
1052 tuples::length<key_extractor_tuple>::value==
|
Chris@101
|
1053 std::tuple_size<key_tuple>::value);
|
Chris@101
|
1054
|
Chris@101
|
1055 return detail::equal_ckey_cval<
|
Chris@101
|
1056 key_extractor_tuple,value_type,
|
Chris@101
|
1057 cons_key_tuple,key_eq_tuple
|
Chris@101
|
1058 >::compare(
|
Chris@101
|
1059 x.composite_key.key_extractors(),x.value,
|
Chris@101
|
1060 detail::make_cons_stdtuple(y),key_eqs());
|
Chris@101
|
1061 }
|
Chris@101
|
1062
|
Chris@101
|
1063 template<typename CompositeKey,typename... Values>
|
Chris@101
|
1064 bool operator()(
|
Chris@101
|
1065 const std::tuple<Values...>& x,
|
Chris@101
|
1066 const composite_key_result<CompositeKey>& y)const
|
Chris@101
|
1067 {
|
Chris@101
|
1068 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@101
|
1069 typedef typename CompositeKey::value_type value_type;
|
Chris@101
|
1070 typedef std::tuple<Values...> key_tuple;
|
Chris@101
|
1071 typedef typename detail::cons_stdtuple_ctor<
|
Chris@101
|
1072 key_tuple>::result_type cons_key_tuple;
|
Chris@101
|
1073
|
Chris@101
|
1074 BOOST_STATIC_ASSERT(
|
Chris@101
|
1075 std::tuple_size<key_tuple>::value<=
|
Chris@101
|
1076 tuples::length<key_eq_tuple>::value&&
|
Chris@101
|
1077 std::tuple_size<key_tuple>::value==
|
Chris@101
|
1078 tuples::length<key_extractor_tuple>::value);
|
Chris@101
|
1079
|
Chris@101
|
1080 return detail::equal_ckey_cval<
|
Chris@101
|
1081 key_extractor_tuple,value_type,
|
Chris@101
|
1082 cons_key_tuple,key_eq_tuple
|
Chris@101
|
1083 >::compare(
|
Chris@101
|
1084 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
|
Chris@101
|
1085 y.value,key_eqs());
|
Chris@101
|
1086 }
|
Chris@101
|
1087 #endif
|
Chris@16
|
1088 };
|
Chris@16
|
1089
|
Chris@16
|
1090 /* composite_key_compare */
|
Chris@16
|
1091
|
Chris@16
|
1092 template
|
Chris@16
|
1093 <
|
Chris@16
|
1094 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare)
|
Chris@16
|
1095 >
|
Chris@16
|
1096 struct composite_key_compare:
|
Chris@16
|
1097 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)>
|
Chris@16
|
1098 {
|
Chris@16
|
1099 private:
|
Chris@16
|
1100 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)> super;
|
Chris@16
|
1101
|
Chris@16
|
1102 public:
|
Chris@16
|
1103 typedef super key_comp_tuple;
|
Chris@16
|
1104
|
Chris@16
|
1105 composite_key_compare(
|
Chris@16
|
1106 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)):
|
Chris@16
|
1107 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
|
Chris@16
|
1108 {}
|
Chris@16
|
1109
|
Chris@16
|
1110 composite_key_compare(const key_comp_tuple& x):super(x){}
|
Chris@16
|
1111
|
Chris@16
|
1112 const key_comp_tuple& key_comps()const{return *this;}
|
Chris@16
|
1113 key_comp_tuple& key_comps(){return *this;}
|
Chris@16
|
1114
|
Chris@16
|
1115 template<typename CompositeKey1,typename CompositeKey2>
|
Chris@16
|
1116 bool operator()(
|
Chris@16
|
1117 const composite_key_result<CompositeKey1> & x,
|
Chris@16
|
1118 const composite_key_result<CompositeKey2> & y)const
|
Chris@16
|
1119 {
|
Chris@16
|
1120 typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
|
Chris@16
|
1121 typedef typename CompositeKey1::value_type value_type1;
|
Chris@16
|
1122 typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
|
Chris@16
|
1123 typedef typename CompositeKey2::value_type value_type2;
|
Chris@16
|
1124
|
Chris@16
|
1125 BOOST_STATIC_ASSERT(
|
Chris@16
|
1126 tuples::length<key_extractor_tuple1>::value<=
|
Chris@16
|
1127 tuples::length<key_comp_tuple>::value||
|
Chris@16
|
1128 tuples::length<key_extractor_tuple2>::value<=
|
Chris@16
|
1129 tuples::length<key_comp_tuple>::value);
|
Chris@16
|
1130
|
Chris@16
|
1131 return detail::compare_ckey_ckey<
|
Chris@16
|
1132 key_extractor_tuple1,value_type1,
|
Chris@16
|
1133 key_extractor_tuple2,value_type2,
|
Chris@16
|
1134 key_comp_tuple
|
Chris@16
|
1135 >::compare(
|
Chris@16
|
1136 x.composite_key.key_extractors(),x.value,
|
Chris@16
|
1137 y.composite_key.key_extractors(),y.value,
|
Chris@16
|
1138 key_comps());
|
Chris@16
|
1139 }
|
Chris@16
|
1140
|
Chris@16
|
1141 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
Chris@16
|
1142 template<typename CompositeKey,typename Value>
|
Chris@16
|
1143 bool operator()(
|
Chris@16
|
1144 const composite_key_result<CompositeKey>& x,
|
Chris@16
|
1145 const Value& y)const
|
Chris@16
|
1146 {
|
Chris@16
|
1147 return operator()(x,boost::make_tuple(boost::cref(y)));
|
Chris@16
|
1148 }
|
Chris@16
|
1149 #endif
|
Chris@16
|
1150
|
Chris@16
|
1151 template
|
Chris@16
|
1152 <
|
Chris@16
|
1153 typename CompositeKey,
|
Chris@16
|
1154 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
|
Chris@16
|
1155 >
|
Chris@16
|
1156 bool operator()(
|
Chris@16
|
1157 const composite_key_result<CompositeKey>& x,
|
Chris@16
|
1158 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
|
Chris@16
|
1159 {
|
Chris@16
|
1160 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@16
|
1161 typedef typename CompositeKey::value_type value_type;
|
Chris@16
|
1162 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
|
Chris@16
|
1163
|
Chris@16
|
1164 BOOST_STATIC_ASSERT(
|
Chris@16
|
1165 tuples::length<key_extractor_tuple>::value<=
|
Chris@16
|
1166 tuples::length<key_comp_tuple>::value||
|
Chris@16
|
1167 tuples::length<key_tuple>::value<=
|
Chris@16
|
1168 tuples::length<key_comp_tuple>::value);
|
Chris@16
|
1169
|
Chris@16
|
1170 return detail::compare_ckey_cval<
|
Chris@16
|
1171 key_extractor_tuple,value_type,
|
Chris@16
|
1172 key_tuple,key_comp_tuple
|
Chris@16
|
1173 >::compare(x.composite_key.key_extractors(),x.value,y,key_comps());
|
Chris@16
|
1174 }
|
Chris@16
|
1175
|
Chris@16
|
1176 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
Chris@16
|
1177 template<typename Value,typename CompositeKey>
|
Chris@16
|
1178 bool operator()(
|
Chris@16
|
1179 const Value& x,
|
Chris@16
|
1180 const composite_key_result<CompositeKey>& y)const
|
Chris@16
|
1181 {
|
Chris@16
|
1182 return operator()(boost::make_tuple(boost::cref(x)),y);
|
Chris@16
|
1183 }
|
Chris@16
|
1184 #endif
|
Chris@16
|
1185
|
Chris@16
|
1186 template
|
Chris@16
|
1187 <
|
Chris@16
|
1188 BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
|
Chris@16
|
1189 typename CompositeKey
|
Chris@16
|
1190 >
|
Chris@16
|
1191 bool operator()(
|
Chris@16
|
1192 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
|
Chris@16
|
1193 const composite_key_result<CompositeKey>& y)const
|
Chris@16
|
1194 {
|
Chris@16
|
1195 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@16
|
1196 typedef typename CompositeKey::value_type value_type;
|
Chris@16
|
1197 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
|
Chris@16
|
1198
|
Chris@16
|
1199 BOOST_STATIC_ASSERT(
|
Chris@16
|
1200 tuples::length<key_tuple>::value<=
|
Chris@16
|
1201 tuples::length<key_comp_tuple>::value||
|
Chris@16
|
1202 tuples::length<key_extractor_tuple>::value<=
|
Chris@16
|
1203 tuples::length<key_comp_tuple>::value);
|
Chris@16
|
1204
|
Chris@16
|
1205 return detail::compare_ckey_cval<
|
Chris@16
|
1206 key_extractor_tuple,value_type,
|
Chris@16
|
1207 key_tuple,key_comp_tuple
|
Chris@16
|
1208 >::compare(x,y.composite_key.key_extractors(),y.value,key_comps());
|
Chris@16
|
1209 }
|
Chris@101
|
1210
|
Chris@101
|
1211 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
|
Chris@101
|
1212 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
1213 template<typename CompositeKey,typename... Values>
|
Chris@101
|
1214 bool operator()(
|
Chris@101
|
1215 const composite_key_result<CompositeKey>& x,
|
Chris@101
|
1216 const std::tuple<Values...>& y)const
|
Chris@101
|
1217 {
|
Chris@101
|
1218 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@101
|
1219 typedef typename CompositeKey::value_type value_type;
|
Chris@101
|
1220 typedef std::tuple<Values...> key_tuple;
|
Chris@101
|
1221 typedef typename detail::cons_stdtuple_ctor<
|
Chris@101
|
1222 key_tuple>::result_type cons_key_tuple;
|
Chris@101
|
1223
|
Chris@101
|
1224 BOOST_STATIC_ASSERT(
|
Chris@101
|
1225 tuples::length<key_extractor_tuple>::value<=
|
Chris@101
|
1226 tuples::length<key_comp_tuple>::value||
|
Chris@101
|
1227 std::tuple_size<key_tuple>::value<=
|
Chris@101
|
1228 tuples::length<key_comp_tuple>::value);
|
Chris@101
|
1229
|
Chris@101
|
1230 return detail::compare_ckey_cval<
|
Chris@101
|
1231 key_extractor_tuple,value_type,
|
Chris@101
|
1232 cons_key_tuple,key_comp_tuple
|
Chris@101
|
1233 >::compare(
|
Chris@101
|
1234 x.composite_key.key_extractors(),x.value,
|
Chris@101
|
1235 detail::make_cons_stdtuple(y),key_comps());
|
Chris@101
|
1236 }
|
Chris@101
|
1237
|
Chris@101
|
1238 template<typename CompositeKey,typename... Values>
|
Chris@101
|
1239 bool operator()(
|
Chris@101
|
1240 const std::tuple<Values...>& x,
|
Chris@101
|
1241 const composite_key_result<CompositeKey>& y)const
|
Chris@101
|
1242 {
|
Chris@101
|
1243 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@101
|
1244 typedef typename CompositeKey::value_type value_type;
|
Chris@101
|
1245 typedef std::tuple<Values...> key_tuple;
|
Chris@101
|
1246 typedef typename detail::cons_stdtuple_ctor<
|
Chris@101
|
1247 key_tuple>::result_type cons_key_tuple;
|
Chris@101
|
1248
|
Chris@101
|
1249 BOOST_STATIC_ASSERT(
|
Chris@101
|
1250 std::tuple_size<key_tuple>::value<=
|
Chris@101
|
1251 tuples::length<key_comp_tuple>::value||
|
Chris@101
|
1252 tuples::length<key_extractor_tuple>::value<=
|
Chris@101
|
1253 tuples::length<key_comp_tuple>::value);
|
Chris@101
|
1254
|
Chris@101
|
1255 return detail::compare_ckey_cval<
|
Chris@101
|
1256 key_extractor_tuple,value_type,
|
Chris@101
|
1257 cons_key_tuple,key_comp_tuple
|
Chris@101
|
1258 >::compare(
|
Chris@101
|
1259 detail::make_cons_stdtuple(x),y.composite_key.key_extractors(),
|
Chris@101
|
1260 y.value,key_comps());
|
Chris@101
|
1261 }
|
Chris@101
|
1262 #endif
|
Chris@16
|
1263 };
|
Chris@16
|
1264
|
Chris@16
|
1265 /* composite_key_hash */
|
Chris@16
|
1266
|
Chris@16
|
1267 template
|
Chris@16
|
1268 <
|
Chris@16
|
1269 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash)
|
Chris@16
|
1270 >
|
Chris@16
|
1271 struct composite_key_hash:
|
Chris@16
|
1272 private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)>
|
Chris@16
|
1273 {
|
Chris@16
|
1274 private:
|
Chris@16
|
1275 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)> super;
|
Chris@16
|
1276
|
Chris@16
|
1277 public:
|
Chris@16
|
1278 typedef super key_hasher_tuple;
|
Chris@16
|
1279
|
Chris@16
|
1280 composite_key_hash(
|
Chris@16
|
1281 BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)):
|
Chris@16
|
1282 super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
|
Chris@16
|
1283 {}
|
Chris@16
|
1284
|
Chris@16
|
1285 composite_key_hash(const key_hasher_tuple& x):super(x){}
|
Chris@16
|
1286
|
Chris@16
|
1287 const key_hasher_tuple& key_hash_functions()const{return *this;}
|
Chris@16
|
1288 key_hasher_tuple& key_hash_functions(){return *this;}
|
Chris@16
|
1289
|
Chris@16
|
1290 template<typename CompositeKey>
|
Chris@16
|
1291 std::size_t operator()(const composite_key_result<CompositeKey> & x)const
|
Chris@16
|
1292 {
|
Chris@16
|
1293 typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
|
Chris@16
|
1294 typedef typename CompositeKey::value_type value_type;
|
Chris@16
|
1295
|
Chris@16
|
1296 BOOST_STATIC_ASSERT(
|
Chris@16
|
1297 tuples::length<key_extractor_tuple>::value==
|
Chris@16
|
1298 tuples::length<key_hasher_tuple>::value);
|
Chris@16
|
1299
|
Chris@16
|
1300 return detail::hash_ckey<
|
Chris@16
|
1301 key_extractor_tuple,value_type,
|
Chris@16
|
1302 key_hasher_tuple
|
Chris@16
|
1303 >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions());
|
Chris@16
|
1304 }
|
Chris@16
|
1305
|
Chris@16
|
1306 template<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)>
|
Chris@16
|
1307 std::size_t operator()(
|
Chris@16
|
1308 const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x)const
|
Chris@16
|
1309 {
|
Chris@16
|
1310 typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
|
Chris@16
|
1311
|
Chris@16
|
1312 BOOST_STATIC_ASSERT(
|
Chris@16
|
1313 tuples::length<key_tuple>::value==
|
Chris@16
|
1314 tuples::length<key_hasher_tuple>::value);
|
Chris@16
|
1315
|
Chris@16
|
1316 return detail::hash_cval<
|
Chris@16
|
1317 key_tuple,key_hasher_tuple
|
Chris@16
|
1318 >::hash(x,key_hash_functions());
|
Chris@16
|
1319 }
|
Chris@101
|
1320
|
Chris@101
|
1321 #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
|
Chris@101
|
1322 !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
Chris@101
|
1323 template<typename... Values>
|
Chris@101
|
1324 std::size_t operator()(const std::tuple<Values...>& x)const
|
Chris@101
|
1325 {
|
Chris@101
|
1326 typedef std::tuple<Values...> key_tuple;
|
Chris@101
|
1327 typedef typename detail::cons_stdtuple_ctor<
|
Chris@101
|
1328 key_tuple>::result_type cons_key_tuple;
|
Chris@101
|
1329
|
Chris@101
|
1330 BOOST_STATIC_ASSERT(
|
Chris@101
|
1331 std::tuple_size<key_tuple>::value==
|
Chris@101
|
1332 tuples::length<key_hasher_tuple>::value);
|
Chris@101
|
1333
|
Chris@101
|
1334 return detail::hash_cval<
|
Chris@101
|
1335 cons_key_tuple,key_hasher_tuple
|
Chris@101
|
1336 >::hash(detail::make_cons_stdtuple(x),key_hash_functions());
|
Chris@101
|
1337 }
|
Chris@101
|
1338 #endif
|
Chris@16
|
1339 };
|
Chris@16
|
1340
|
Chris@16
|
1341 /* Instantiations of the former functors with "natural" basic components:
|
Chris@16
|
1342 * composite_key_result_equal_to uses std::equal_to of the values.
|
Chris@16
|
1343 * composite_key_result_less uses std::less.
|
Chris@16
|
1344 * composite_key_result_greater uses std::greater.
|
Chris@16
|
1345 * composite_key_result_hash uses boost::hash.
|
Chris@16
|
1346 */
|
Chris@16
|
1347
|
Chris@16
|
1348 #define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER \
|
Chris@16
|
1349 composite_key_equal_to< \
|
Chris@16
|
1350 BOOST_MULTI_INDEX_CK_ENUM( \
|
Chris@16
|
1351 BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
|
Chris@16
|
1352 /* the argument is a PP list */ \
|
Chris@16
|
1353 (detail::nth_composite_key_equal_to, \
|
Chris@16
|
1354 (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
|
Chris@16
|
1355 BOOST_PP_NIL))) \
|
Chris@16
|
1356 >
|
Chris@16
|
1357
|
Chris@16
|
1358 template<typename CompositeKeyResult>
|
Chris@16
|
1359 struct composite_key_result_equal_to:
|
Chris@16
|
1360 BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
|
Chris@16
|
1361 BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
|
Chris@16
|
1362 {
|
Chris@16
|
1363 private:
|
Chris@16
|
1364 typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super;
|
Chris@16
|
1365
|
Chris@16
|
1366 public:
|
Chris@16
|
1367 typedef CompositeKeyResult first_argument_type;
|
Chris@16
|
1368 typedef first_argument_type second_argument_type;
|
Chris@16
|
1369 typedef bool result_type;
|
Chris@16
|
1370
|
Chris@16
|
1371 using super::operator();
|
Chris@16
|
1372 };
|
Chris@16
|
1373
|
Chris@16
|
1374 #define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER \
|
Chris@16
|
1375 composite_key_compare< \
|
Chris@16
|
1376 BOOST_MULTI_INDEX_CK_ENUM( \
|
Chris@16
|
1377 BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
|
Chris@16
|
1378 /* the argument is a PP list */ \
|
Chris@16
|
1379 (detail::nth_composite_key_less, \
|
Chris@16
|
1380 (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
|
Chris@16
|
1381 BOOST_PP_NIL))) \
|
Chris@16
|
1382 >
|
Chris@16
|
1383
|
Chris@16
|
1384 template<typename CompositeKeyResult>
|
Chris@16
|
1385 struct composite_key_result_less:
|
Chris@16
|
1386 BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
|
Chris@16
|
1387 BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
|
Chris@16
|
1388 {
|
Chris@16
|
1389 private:
|
Chris@16
|
1390 typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super;
|
Chris@16
|
1391
|
Chris@16
|
1392 public:
|
Chris@16
|
1393 typedef CompositeKeyResult first_argument_type;
|
Chris@16
|
1394 typedef first_argument_type second_argument_type;
|
Chris@16
|
1395 typedef bool result_type;
|
Chris@16
|
1396
|
Chris@16
|
1397 using super::operator();
|
Chris@16
|
1398 };
|
Chris@16
|
1399
|
Chris@16
|
1400 #define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER \
|
Chris@16
|
1401 composite_key_compare< \
|
Chris@16
|
1402 BOOST_MULTI_INDEX_CK_ENUM( \
|
Chris@16
|
1403 BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
|
Chris@16
|
1404 /* the argument is a PP list */ \
|
Chris@16
|
1405 (detail::nth_composite_key_greater, \
|
Chris@16
|
1406 (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
|
Chris@16
|
1407 BOOST_PP_NIL))) \
|
Chris@16
|
1408 >
|
Chris@16
|
1409
|
Chris@16
|
1410 template<typename CompositeKeyResult>
|
Chris@16
|
1411 struct composite_key_result_greater:
|
Chris@16
|
1412 BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
|
Chris@16
|
1413 BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
|
Chris@16
|
1414 {
|
Chris@16
|
1415 private:
|
Chris@16
|
1416 typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super;
|
Chris@16
|
1417
|
Chris@16
|
1418 public:
|
Chris@16
|
1419 typedef CompositeKeyResult first_argument_type;
|
Chris@16
|
1420 typedef first_argument_type second_argument_type;
|
Chris@16
|
1421 typedef bool result_type;
|
Chris@16
|
1422
|
Chris@16
|
1423 using super::operator();
|
Chris@16
|
1424 };
|
Chris@16
|
1425
|
Chris@16
|
1426 #define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER \
|
Chris@16
|
1427 composite_key_hash< \
|
Chris@16
|
1428 BOOST_MULTI_INDEX_CK_ENUM( \
|
Chris@16
|
1429 BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
|
Chris@16
|
1430 /* the argument is a PP list */ \
|
Chris@16
|
1431 (detail::nth_composite_key_hash, \
|
Chris@16
|
1432 (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
|
Chris@16
|
1433 BOOST_PP_NIL))) \
|
Chris@16
|
1434 >
|
Chris@16
|
1435
|
Chris@16
|
1436 template<typename CompositeKeyResult>
|
Chris@16
|
1437 struct composite_key_result_hash:
|
Chris@16
|
1438 BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
|
Chris@16
|
1439 BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
|
Chris@16
|
1440 {
|
Chris@16
|
1441 private:
|
Chris@16
|
1442 typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super;
|
Chris@16
|
1443
|
Chris@16
|
1444 public:
|
Chris@16
|
1445 typedef CompositeKeyResult argument_type;
|
Chris@16
|
1446 typedef std::size_t result_type;
|
Chris@16
|
1447
|
Chris@16
|
1448 using super::operator();
|
Chris@16
|
1449 };
|
Chris@16
|
1450
|
Chris@16
|
1451 } /* namespace multi_index */
|
Chris@16
|
1452
|
Chris@16
|
1453 } /* namespace boost */
|
Chris@16
|
1454
|
Chris@16
|
1455 /* Specializations of std::equal_to, std::less, std::greater and boost::hash
|
Chris@16
|
1456 * for composite_key_results enabling interoperation with tuples of values.
|
Chris@16
|
1457 */
|
Chris@16
|
1458
|
Chris@16
|
1459 namespace std{
|
Chris@16
|
1460
|
Chris@16
|
1461 template<typename CompositeKey>
|
Chris@16
|
1462 struct equal_to<boost::multi_index::composite_key_result<CompositeKey> >:
|
Chris@16
|
1463 boost::multi_index::composite_key_result_equal_to<
|
Chris@16
|
1464 boost::multi_index::composite_key_result<CompositeKey>
|
Chris@16
|
1465 >
|
Chris@16
|
1466 {
|
Chris@16
|
1467 };
|
Chris@16
|
1468
|
Chris@16
|
1469 template<typename CompositeKey>
|
Chris@16
|
1470 struct less<boost::multi_index::composite_key_result<CompositeKey> >:
|
Chris@16
|
1471 boost::multi_index::composite_key_result_less<
|
Chris@16
|
1472 boost::multi_index::composite_key_result<CompositeKey>
|
Chris@16
|
1473 >
|
Chris@16
|
1474 {
|
Chris@16
|
1475 };
|
Chris@16
|
1476
|
Chris@16
|
1477 template<typename CompositeKey>
|
Chris@16
|
1478 struct greater<boost::multi_index::composite_key_result<CompositeKey> >:
|
Chris@16
|
1479 boost::multi_index::composite_key_result_greater<
|
Chris@16
|
1480 boost::multi_index::composite_key_result<CompositeKey>
|
Chris@16
|
1481 >
|
Chris@16
|
1482 {
|
Chris@16
|
1483 };
|
Chris@16
|
1484
|
Chris@16
|
1485 } /* namespace std */
|
Chris@16
|
1486
|
Chris@16
|
1487 namespace boost{
|
Chris@16
|
1488
|
Chris@16
|
1489 template<typename CompositeKey>
|
Chris@16
|
1490 struct hash<boost::multi_index::composite_key_result<CompositeKey> >:
|
Chris@16
|
1491 boost::multi_index::composite_key_result_hash<
|
Chris@16
|
1492 boost::multi_index::composite_key_result<CompositeKey>
|
Chris@16
|
1493 >
|
Chris@16
|
1494 {
|
Chris@16
|
1495 };
|
Chris@16
|
1496
|
Chris@16
|
1497 } /* namespace boost */
|
Chris@16
|
1498
|
Chris@16
|
1499 #undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
|
Chris@16
|
1500 #undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
|
Chris@16
|
1501 #undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
|
Chris@16
|
1502 #undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
|
Chris@16
|
1503 #undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS
|
Chris@16
|
1504 #undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO
|
Chris@16
|
1505 #undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR
|
Chris@16
|
1506 #undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N
|
Chris@16
|
1507 #undef BOOST_MULTI_INDEX_CK_CTOR_ARG
|
Chris@16
|
1508 #undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM
|
Chris@16
|
1509 #undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS
|
Chris@16
|
1510 #undef BOOST_MULTI_INDEX_CK_ENUM
|
Chris@16
|
1511 #undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE
|
Chris@16
|
1512
|
Chris@16
|
1513 #endif
|