/Src/Dependencies/Boost/boost/multi_index/composite_key.hpp

http://hadesmem.googlecode.com/ · C++ Header · 1324 lines · 1054 code · 188 blank · 82 comment · 9 complexity · edac9f5349509a5916d08b45e799ecff MD5 · raw file

  1. /* Copyright 2003-2011 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. */
  8. #ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
  9. #define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
  10. #if defined(_MSC_VER)&&(_MSC_VER>=1200)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <boost/functional/hash_fwd.hpp>
  15. #include <boost/multi_index/detail/access_specifier.hpp>
  16. #include <boost/multi_index/detail/prevent_eti.hpp>
  17. #include <boost/mpl/eval_if.hpp>
  18. #include <boost/mpl/identity.hpp>
  19. #include <boost/mpl/if.hpp>
  20. #include <boost/mpl/or.hpp>
  21. #include <boost/mpl/aux_/nttp_decl.hpp>
  22. #include <boost/preprocessor/cat.hpp>
  23. #include <boost/preprocessor/control/expr_if.hpp>
  24. #include <boost/preprocessor/list/at.hpp>
  25. #include <boost/preprocessor/repetition/enum.hpp>
  26. #include <boost/preprocessor/repetition/enum_params.hpp>
  27. #include <boost/static_assert.hpp>
  28. #include <boost/tuple/tuple.hpp>
  29. #include <boost/type_traits/is_same.hpp>
  30. #include <boost/utility/enable_if.hpp>
  31. #include <functional>
  32. #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  33. #include <boost/ref.hpp>
  34. #endif
  35. #if !defined(BOOST_NO_SFINAE)
  36. #include <boost/type_traits/is_convertible.hpp>
  37. #endif
  38. /* A composite key stores n key extractors and "computes" the
  39. * result on a given value as a packed reference to the value and
  40. * the composite key itself. Actual invocations to the component
  41. * key extractors are lazily performed when executing an operation
  42. * on composite_key results (equality, comparison, hashing.)
  43. * As the other key extractors in Boost.MultiIndex, composite_key<T,...>
  44. * is overloaded to work on chained pointers to T and reference_wrappers
  45. * of T.
  46. */
  47. /* This user_definable macro limits the number of elements of a composite
  48. * key; useful for shortening resulting symbol names (MSVC++ 6.0, for
  49. * instance has problems coping with very long symbol names.)
  50. * NB: This cannot exceed the maximum number of arguments of
  51. * boost::tuple. In Boost 1.32, the limit is 10.
  52. */
  53. #if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE)
  54. #if defined(BOOST_MSVC)&&(BOOST_MSVC<1300)
  55. #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 5
  56. #else
  57. #define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10
  58. #endif
  59. #endif
  60. /* maximum number of key extractors in a composite key */
  61. #if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */
  62. #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \
  63. BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE
  64. #else
  65. #define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10
  66. #endif
  67. /* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
  68. #define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \
  69. BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data)
  70. /* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */
  71. #define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \
  72. BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param)
  73. /* if n==0 -> text0
  74. * otherwise -> textn=tuples::null_type
  75. */
  76. #define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text) \
  77. typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type)
  78. /* const textn& kn=textn() */
  79. #define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text) \
  80. const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)()
  81. /* typename list(0)<list(1),n>::type */
  82. #define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list) \
  83. BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)< \
  84. BOOST_PP_LIST_AT(list,1),n \
  85. >::type
  86. namespace boost{
  87. template<class T> class reference_wrapper; /* fwd decl. */
  88. namespace multi_index{
  89. namespace detail{
  90. /* n-th key extractor of a composite key */
  91. template<typename CompositeKey,BOOST_MPL_AUX_NTTP_DECL(int, N)>
  92. struct nth_key_from_value
  93. {
  94. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  95. typedef typename prevent_eti<
  96. tuples::element<N,key_extractor_tuple>,
  97. typename mpl::eval_if_c<
  98. N<tuples::length<key_extractor_tuple>::value,
  99. tuples::element<N,key_extractor_tuple>,
  100. mpl::identity<tuples::null_type>
  101. >::type
  102. >::type type;
  103. };
  104. /* nth_composite_key_##name<CompositeKey,N>::type yields
  105. * functor<nth_key_from_value<CompositeKey,N> >, or tuples::null_type
  106. * if N exceeds the length of the composite key.
  107. */
  108. #define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \
  109. template<typename KeyFromValue> \
  110. struct BOOST_PP_CAT(key_,name) \
  111. { \
  112. typedef functor<typename KeyFromValue::result_type> type; \
  113. }; \
  114. \
  115. template<> \
  116. struct BOOST_PP_CAT(key_,name)<tuples::null_type> \
  117. { \
  118. typedef tuples::null_type type; \
  119. }; \
  120. \
  121. template<typename CompositeKey,BOOST_MPL_AUX_NTTP_DECL(int, N)> \
  122. struct BOOST_PP_CAT(nth_composite_key_,name) \
  123. { \
  124. typedef typename nth_key_from_value<CompositeKey,N>::type key_from_value; \
  125. typedef typename BOOST_PP_CAT(key_,name)<key_from_value>::type type; \
  126. };
  127. /* nth_composite_key_equal_to
  128. * nth_composite_key_less
  129. * nth_composite_key_greater
  130. * nth_composite_key_hash
  131. */
  132. BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to)
  133. BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less)
  134. BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater)
  135. BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash)
  136. /* used for defining equality and comparison ops of composite_key_result */
  137. #define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text
  138. struct generic_operator_equal
  139. {
  140. template<typename T,typename Q>
  141. bool operator()(const T& x,const Q& y)const{return x==y;}
  142. };
  143. typedef tuple<
  144. BOOST_MULTI_INDEX_CK_ENUM(
  145. BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
  146. detail::generic_operator_equal)> generic_operator_equal_tuple;
  147. struct generic_operator_less
  148. {
  149. template<typename T,typename Q>
  150. bool operator()(const T& x,const Q& y)const{return x<y;}
  151. };
  152. typedef tuple<
  153. BOOST_MULTI_INDEX_CK_ENUM(
  154. BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO,
  155. detail::generic_operator_less)> generic_operator_less_tuple;
  156. /* Metaprogramming machinery for implementing equality, comparison and
  157. * hashing operations of composite_key_result.
  158. *
  159. * equal_* checks for equality between composite_key_results and
  160. * between those and tuples, accepting a tuple of basic equality functors.
  161. * compare_* does lexicographical comparison.
  162. * hash_* computes a combination of elementwise hash values.
  163. */
  164. template
  165. <
  166. typename KeyCons1,typename Value1,
  167. typename KeyCons2, typename Value2,
  168. typename EqualCons
  169. >
  170. struct equal_ckey_ckey; /* fwd decl. */
  171. template
  172. <
  173. typename KeyCons1,typename Value1,
  174. typename KeyCons2, typename Value2,
  175. typename EqualCons
  176. >
  177. struct equal_ckey_ckey_terminal
  178. {
  179. static bool compare(
  180. const KeyCons1&,const Value1&,
  181. const KeyCons2&,const Value2&,
  182. const EqualCons&)
  183. {
  184. return true;
  185. }
  186. };
  187. template
  188. <
  189. typename KeyCons1,typename Value1,
  190. typename KeyCons2, typename Value2,
  191. typename EqualCons
  192. >
  193. struct equal_ckey_ckey_normal
  194. {
  195. static bool compare(
  196. const KeyCons1& c0,const Value1& v0,
  197. const KeyCons2& c1,const Value2& v1,
  198. const EqualCons& eq)
  199. {
  200. if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false;
  201. return equal_ckey_ckey<
  202. BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
  203. BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
  204. BOOST_DEDUCED_TYPENAME EqualCons::tail_type
  205. >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail());
  206. }
  207. };
  208. template
  209. <
  210. typename KeyCons1,typename Value1,
  211. typename KeyCons2, typename Value2,
  212. typename EqualCons
  213. >
  214. struct equal_ckey_ckey:
  215. mpl::if_<
  216. mpl::or_<
  217. is_same<KeyCons1,tuples::null_type>,
  218. is_same<KeyCons2,tuples::null_type>
  219. >,
  220. equal_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>,
  221. equal_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,EqualCons>
  222. >::type
  223. {
  224. };
  225. template
  226. <
  227. typename KeyCons,typename Value,
  228. typename ValCons,typename EqualCons
  229. >
  230. struct equal_ckey_cval; /* fwd decl. */
  231. template
  232. <
  233. typename KeyCons,typename Value,
  234. typename ValCons,typename EqualCons
  235. >
  236. struct equal_ckey_cval_terminal
  237. {
  238. static bool compare(
  239. const KeyCons&,const Value&,const ValCons&,const EqualCons&)
  240. {
  241. return true;
  242. }
  243. static bool compare(
  244. const ValCons&,const KeyCons&,const Value&,const EqualCons&)
  245. {
  246. return true;
  247. }
  248. };
  249. template
  250. <
  251. typename KeyCons,typename Value,
  252. typename ValCons,typename EqualCons
  253. >
  254. struct equal_ckey_cval_normal
  255. {
  256. static bool compare(
  257. const KeyCons& c,const Value& v,const ValCons& vc,
  258. const EqualCons& eq)
  259. {
  260. if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false;
  261. return equal_ckey_cval<
  262. BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
  263. BOOST_DEDUCED_TYPENAME ValCons::tail_type,
  264. BOOST_DEDUCED_TYPENAME EqualCons::tail_type
  265. >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail());
  266. }
  267. static bool compare(
  268. const ValCons& vc,const KeyCons& c,const Value& v,
  269. const EqualCons& eq)
  270. {
  271. if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false;
  272. return equal_ckey_cval<
  273. BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
  274. BOOST_DEDUCED_TYPENAME ValCons::tail_type,
  275. BOOST_DEDUCED_TYPENAME EqualCons::tail_type
  276. >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail());
  277. }
  278. };
  279. template
  280. <
  281. typename KeyCons,typename Value,
  282. typename ValCons,typename EqualCons
  283. >
  284. struct equal_ckey_cval:
  285. mpl::if_<
  286. mpl::or_<
  287. is_same<KeyCons,tuples::null_type>,
  288. is_same<ValCons,tuples::null_type>
  289. >,
  290. equal_ckey_cval_terminal<KeyCons,Value,ValCons,EqualCons>,
  291. equal_ckey_cval_normal<KeyCons,Value,ValCons,EqualCons>
  292. >::type
  293. {
  294. };
  295. template
  296. <
  297. typename KeyCons1,typename Value1,
  298. typename KeyCons2, typename Value2,
  299. typename CompareCons
  300. >
  301. struct compare_ckey_ckey; /* fwd decl. */
  302. template
  303. <
  304. typename KeyCons1,typename Value1,
  305. typename KeyCons2, typename Value2,
  306. typename CompareCons
  307. >
  308. struct compare_ckey_ckey_terminal
  309. {
  310. static bool compare(
  311. const KeyCons1&,const Value1&,
  312. const KeyCons2&,const Value2&,
  313. const CompareCons&)
  314. {
  315. return false;
  316. }
  317. };
  318. template
  319. <
  320. typename KeyCons1,typename Value1,
  321. typename KeyCons2, typename Value2,
  322. typename CompareCons
  323. >
  324. struct compare_ckey_ckey_normal
  325. {
  326. static bool compare(
  327. const KeyCons1& c0,const Value1& v0,
  328. const KeyCons2& c1,const Value2& v1,
  329. const CompareCons& comp)
  330. {
  331. if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true;
  332. if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false;
  333. return compare_ckey_ckey<
  334. BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1,
  335. BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2,
  336. BOOST_DEDUCED_TYPENAME CompareCons::tail_type
  337. >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail());
  338. }
  339. };
  340. template
  341. <
  342. typename KeyCons1,typename Value1,
  343. typename KeyCons2, typename Value2,
  344. typename CompareCons
  345. >
  346. struct compare_ckey_ckey:
  347. mpl::if_<
  348. mpl::or_<
  349. is_same<KeyCons1,tuples::null_type>,
  350. is_same<KeyCons2,tuples::null_type>
  351. >,
  352. compare_ckey_ckey_terminal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>,
  353. compare_ckey_ckey_normal<KeyCons1,Value1,KeyCons2,Value2,CompareCons>
  354. >::type
  355. {
  356. };
  357. template
  358. <
  359. typename KeyCons,typename Value,
  360. typename ValCons,typename CompareCons
  361. >
  362. struct compare_ckey_cval; /* fwd decl. */
  363. template
  364. <
  365. typename KeyCons,typename Value,
  366. typename ValCons,typename CompareCons
  367. >
  368. struct compare_ckey_cval_terminal
  369. {
  370. static bool compare(
  371. const KeyCons&,const Value&,const ValCons&,const CompareCons&)
  372. {
  373. return false;
  374. }
  375. static bool compare(
  376. const ValCons&,const KeyCons&,const Value&,const CompareCons&)
  377. {
  378. return false;
  379. }
  380. };
  381. template
  382. <
  383. typename KeyCons,typename Value,
  384. typename ValCons,typename CompareCons
  385. >
  386. struct compare_ckey_cval_normal
  387. {
  388. static bool compare(
  389. const KeyCons& c,const Value& v,const ValCons& vc,
  390. const CompareCons& comp)
  391. {
  392. if(comp.get_head()(c.get_head()(v),vc.get_head()))return true;
  393. if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false;
  394. return compare_ckey_cval<
  395. BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
  396. BOOST_DEDUCED_TYPENAME ValCons::tail_type,
  397. BOOST_DEDUCED_TYPENAME CompareCons::tail_type
  398. >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail());
  399. }
  400. static bool compare(
  401. const ValCons& vc,const KeyCons& c,const Value& v,
  402. const CompareCons& comp)
  403. {
  404. if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true;
  405. if(comp.get_head()(c.get_head()(v),vc.get_head()))return false;
  406. return compare_ckey_cval<
  407. BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
  408. BOOST_DEDUCED_TYPENAME ValCons::tail_type,
  409. BOOST_DEDUCED_TYPENAME CompareCons::tail_type
  410. >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail());
  411. }
  412. };
  413. template
  414. <
  415. typename KeyCons,typename Value,
  416. typename ValCons,typename CompareCons
  417. >
  418. struct compare_ckey_cval:
  419. mpl::if_<
  420. mpl::or_<
  421. is_same<KeyCons,tuples::null_type>,
  422. is_same<ValCons,tuples::null_type>
  423. >,
  424. compare_ckey_cval_terminal<KeyCons,Value,ValCons,CompareCons>,
  425. compare_ckey_cval_normal<KeyCons,Value,ValCons,CompareCons>
  426. >::type
  427. {
  428. };
  429. template<typename KeyCons,typename Value,typename HashCons>
  430. struct hash_ckey; /* fwd decl. */
  431. template<typename KeyCons,typename Value,typename HashCons>
  432. struct hash_ckey_terminal
  433. {
  434. static std::size_t hash(
  435. const KeyCons&,const Value&,const HashCons&,std::size_t carry)
  436. {
  437. return carry;
  438. }
  439. };
  440. template<typename KeyCons,typename Value,typename HashCons>
  441. struct hash_ckey_normal
  442. {
  443. static std::size_t hash(
  444. const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0)
  445. {
  446. /* same hashing formula as boost::hash_combine */
  447. carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2);
  448. return hash_ckey<
  449. BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value,
  450. BOOST_DEDUCED_TYPENAME HashCons::tail_type
  451. >::hash(c.get_tail(),v,h.get_tail(),carry);
  452. }
  453. };
  454. template<typename KeyCons,typename Value,typename HashCons>
  455. struct hash_ckey:
  456. mpl::if_<
  457. is_same<KeyCons,tuples::null_type>,
  458. hash_ckey_terminal<KeyCons,Value,HashCons>,
  459. hash_ckey_normal<KeyCons,Value,HashCons>
  460. >::type
  461. {
  462. };
  463. template<typename ValCons,typename HashCons>
  464. struct hash_cval; /* fwd decl. */
  465. template<typename ValCons,typename HashCons>
  466. struct hash_cval_terminal
  467. {
  468. static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry)
  469. {
  470. return carry;
  471. }
  472. };
  473. template<typename ValCons,typename HashCons>
  474. struct hash_cval_normal
  475. {
  476. static std::size_t hash(
  477. const ValCons& vc,const HashCons& h,std::size_t carry=0)
  478. {
  479. carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2);
  480. return hash_cval<
  481. BOOST_DEDUCED_TYPENAME ValCons::tail_type,
  482. BOOST_DEDUCED_TYPENAME HashCons::tail_type
  483. >::hash(vc.get_tail(),h.get_tail(),carry);
  484. }
  485. };
  486. template<typename ValCons,typename HashCons>
  487. struct hash_cval:
  488. mpl::if_<
  489. is_same<ValCons,tuples::null_type>,
  490. hash_cval_terminal<ValCons,HashCons>,
  491. hash_cval_normal<ValCons,HashCons>
  492. >::type
  493. {
  494. };
  495. } /* namespace multi_index::detail */
  496. /* composite_key_result */
  497. #if defined(BOOST_MSVC)
  498. #pragma warning(push)
  499. #pragma warning(disable:4512)
  500. #endif
  501. template<typename CompositeKey>
  502. struct composite_key_result
  503. {
  504. typedef CompositeKey composite_key_type;
  505. typedef typename composite_key_type::value_type value_type;
  506. composite_key_result(
  507. const composite_key_type& composite_key_,const value_type& value_):
  508. composite_key(composite_key_),value(value_)
  509. {}
  510. const composite_key_type& composite_key;
  511. const value_type& value;
  512. };
  513. #if defined(BOOST_MSVC)
  514. #pragma warning(pop)
  515. #endif
  516. /* composite_key */
  517. /* NB. Some overloads of operator() have an extra dummy parameter int=0.
  518. * This disambiguator serves several purposes:
  519. * - Without it, MSVC++ 6.0 incorrectly regards some overloads as
  520. * specializations of a previous member function template.
  521. * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
  522. * as if they have the same signature.
  523. * - If remove_const is broken due to lack of PTS, int=0 avoids the
  524. * declaration of memfuns with identical signature.
  525. */
  526. template<
  527. typename Value,
  528. BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue)
  529. >
  530. struct composite_key:
  531. private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)>
  532. {
  533. private:
  534. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(KeyFromValue)> super;
  535. public:
  536. typedef super key_extractor_tuple;
  537. typedef Value value_type;
  538. typedef composite_key_result<composite_key> result_type;
  539. composite_key(
  540. BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)):
  541. super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
  542. {}
  543. composite_key(const key_extractor_tuple& x):super(x){}
  544. const key_extractor_tuple& key_extractors()const{return *this;}
  545. key_extractor_tuple& key_extractors(){return *this;}
  546. template<typename ChainedPtr>
  547. #if !defined(BOOST_NO_SFINAE)
  548. typename disable_if<
  549. is_convertible<const ChainedPtr&,const value_type&>,result_type>::type
  550. #else
  551. result_type
  552. #endif
  553. operator()(const ChainedPtr& x)const
  554. {
  555. return operator()(*x);
  556. }
  557. result_type operator()(const value_type& x)const
  558. {
  559. return result_type(*this,x);
  560. }
  561. result_type operator()(const reference_wrapper<const value_type>& x)const
  562. {
  563. return result_type(*this,x.get());
  564. }
  565. result_type operator()(const reference_wrapper<value_type>& x,int=0)const
  566. {
  567. return result_type(*this,x.get());
  568. }
  569. };
  570. /* comparison operators */
  571. /* == */
  572. template<typename CompositeKey1,typename CompositeKey2>
  573. inline bool operator==(
  574. const composite_key_result<CompositeKey1>& x,
  575. const composite_key_result<CompositeKey2>& y)
  576. {
  577. typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
  578. typedef typename CompositeKey1::value_type value_type1;
  579. typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
  580. typedef typename CompositeKey2::value_type value_type2;
  581. BOOST_STATIC_ASSERT(
  582. tuples::length<key_extractor_tuple1>::value==
  583. tuples::length<key_extractor_tuple2>::value);
  584. return detail::equal_ckey_ckey<
  585. key_extractor_tuple1,value_type1,
  586. key_extractor_tuple2,value_type2,
  587. detail::generic_operator_equal_tuple
  588. >::compare(
  589. x.composite_key.key_extractors(),x.value,
  590. y.composite_key.key_extractors(),y.value,
  591. detail::generic_operator_equal_tuple());
  592. }
  593. template<
  594. typename CompositeKey,
  595. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
  596. >
  597. inline bool operator==(
  598. const composite_key_result<CompositeKey>& x,
  599. const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
  600. {
  601. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  602. typedef typename CompositeKey::value_type value_type;
  603. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
  604. BOOST_STATIC_ASSERT(
  605. tuples::length<key_extractor_tuple>::value==
  606. tuples::length<key_tuple>::value);
  607. return detail::equal_ckey_cval<
  608. key_extractor_tuple,value_type,
  609. key_tuple,detail::generic_operator_equal_tuple
  610. >::compare(
  611. x.composite_key.key_extractors(),x.value,
  612. y,detail::generic_operator_equal_tuple());
  613. }
  614. template
  615. <
  616. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
  617. typename CompositeKey
  618. >
  619. inline bool operator==(
  620. const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
  621. const composite_key_result<CompositeKey>& y)
  622. {
  623. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  624. typedef typename CompositeKey::value_type value_type;
  625. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
  626. BOOST_STATIC_ASSERT(
  627. tuples::length<key_extractor_tuple>::value==
  628. tuples::length<key_tuple>::value);
  629. return detail::equal_ckey_cval<
  630. key_extractor_tuple,value_type,
  631. key_tuple,detail::generic_operator_equal_tuple
  632. >::compare(
  633. x,y.composite_key.key_extractors(),
  634. y.value,detail::generic_operator_equal_tuple());
  635. }
  636. /* < */
  637. template<typename CompositeKey1,typename CompositeKey2>
  638. inline bool operator<(
  639. const composite_key_result<CompositeKey1>& x,
  640. const composite_key_result<CompositeKey2>& y)
  641. {
  642. typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
  643. typedef typename CompositeKey1::value_type value_type1;
  644. typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
  645. typedef typename CompositeKey2::value_type value_type2;
  646. return detail::compare_ckey_ckey<
  647. key_extractor_tuple1,value_type1,
  648. key_extractor_tuple2,value_type2,
  649. detail::generic_operator_less_tuple
  650. >::compare(
  651. x.composite_key.key_extractors(),x.value,
  652. y.composite_key.key_extractors(),y.value,
  653. detail::generic_operator_less_tuple());
  654. }
  655. template
  656. <
  657. typename CompositeKey,
  658. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
  659. >
  660. inline bool operator<(
  661. const composite_key_result<CompositeKey>& x,
  662. const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)
  663. {
  664. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  665. typedef typename CompositeKey::value_type value_type;
  666. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
  667. return detail::compare_ckey_cval<
  668. key_extractor_tuple,value_type,
  669. key_tuple,detail::generic_operator_less_tuple
  670. >::compare(
  671. x.composite_key.key_extractors(),x.value,
  672. y,detail::generic_operator_less_tuple());
  673. }
  674. template
  675. <
  676. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
  677. typename CompositeKey
  678. >
  679. inline bool operator<(
  680. const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
  681. const composite_key_result<CompositeKey>& y)
  682. {
  683. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  684. typedef typename CompositeKey::value_type value_type;
  685. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
  686. return detail::compare_ckey_cval<
  687. key_extractor_tuple,value_type,
  688. key_tuple,detail::generic_operator_less_tuple
  689. >::compare(
  690. x,y.composite_key.key_extractors(),
  691. y.value,detail::generic_operator_less_tuple());
  692. }
  693. /* rest of comparison operators */
  694. #define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \
  695. template<t1,t2> inline bool operator!=(const a1& x,const a2& y) \
  696. { \
  697. return !(x==y); \
  698. } \
  699. \
  700. template<t1,t2> inline bool operator>(const a1& x,const a2& y) \
  701. { \
  702. return y<x; \
  703. } \
  704. \
  705. template<t1,t2> inline bool operator>=(const a1& x,const a2& y) \
  706. { \
  707. return !(x<y); \
  708. } \
  709. \
  710. template<t1,t2> inline bool operator<=(const a1& x,const a2& y) \
  711. { \
  712. return !(y<x); \
  713. }
  714. BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
  715. typename CompositeKey1,
  716. typename CompositeKey2,
  717. composite_key_result<CompositeKey1>,
  718. composite_key_result<CompositeKey2>
  719. )
  720. BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
  721. typename CompositeKey,
  722. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
  723. composite_key_result<CompositeKey>,
  724. tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>
  725. )
  726. BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(
  727. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
  728. typename CompositeKey,
  729. tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>,
  730. composite_key_result<CompositeKey>
  731. )
  732. /* composite_key_equal_to */
  733. template
  734. <
  735. BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred)
  736. >
  737. struct composite_key_equal_to:
  738. private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)>
  739. {
  740. private:
  741. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Pred)> super;
  742. public:
  743. typedef super key_eq_tuple;
  744. composite_key_equal_to(
  745. BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)):
  746. super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
  747. {}
  748. composite_key_equal_to(const key_eq_tuple& x):super(x){}
  749. const key_eq_tuple& key_eqs()const{return *this;}
  750. key_eq_tuple& key_eqs(){return *this;}
  751. template<typename CompositeKey1,typename CompositeKey2>
  752. bool operator()(
  753. const composite_key_result<CompositeKey1> & x,
  754. const composite_key_result<CompositeKey2> & y)const
  755. {
  756. typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
  757. typedef typename CompositeKey1::value_type value_type1;
  758. typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
  759. typedef typename CompositeKey2::value_type value_type2;
  760. BOOST_STATIC_ASSERT(
  761. tuples::length<key_extractor_tuple1>::value<=
  762. tuples::length<key_eq_tuple>::value&&
  763. tuples::length<key_extractor_tuple1>::value==
  764. tuples::length<key_extractor_tuple2>::value);
  765. return detail::equal_ckey_ckey<
  766. key_extractor_tuple1,value_type1,
  767. key_extractor_tuple2,value_type2,
  768. key_eq_tuple
  769. >::compare(
  770. x.composite_key.key_extractors(),x.value,
  771. y.composite_key.key_extractors(),y.value,
  772. key_eqs());
  773. }
  774. template
  775. <
  776. typename CompositeKey,
  777. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
  778. >
  779. bool operator()(
  780. const composite_key_result<CompositeKey>& x,
  781. const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
  782. {
  783. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  784. typedef typename CompositeKey::value_type value_type;
  785. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
  786. BOOST_STATIC_ASSERT(
  787. tuples::length<key_extractor_tuple>::value<=
  788. tuples::length<key_eq_tuple>::value&&
  789. tuples::length<key_extractor_tuple>::value==
  790. tuples::length<key_tuple>::value);
  791. return detail::equal_ckey_cval<
  792. key_extractor_tuple,value_type,
  793. key_tuple,key_eq_tuple
  794. >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs());
  795. }
  796. template
  797. <
  798. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
  799. typename CompositeKey
  800. >
  801. bool operator()(
  802. const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
  803. const composite_key_result<CompositeKey>& y)const
  804. {
  805. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  806. typedef typename CompositeKey::value_type value_type;
  807. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
  808. BOOST_STATIC_ASSERT(
  809. tuples::length<key_tuple>::value<=
  810. tuples::length<key_eq_tuple>::value&&
  811. tuples::length<key_tuple>::value==
  812. tuples::length<key_extractor_tuple>::value);
  813. return detail::equal_ckey_cval<
  814. key_extractor_tuple,value_type,
  815. key_tuple,key_eq_tuple
  816. >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs());
  817. }
  818. };
  819. /* composite_key_compare */
  820. template
  821. <
  822. BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare)
  823. >
  824. struct composite_key_compare:
  825. private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)>
  826. {
  827. private:
  828. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Compare)> super;
  829. public:
  830. typedef super key_comp_tuple;
  831. composite_key_compare(
  832. BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)):
  833. super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
  834. {}
  835. composite_key_compare(const key_comp_tuple& x):super(x){}
  836. const key_comp_tuple& key_comps()const{return *this;}
  837. key_comp_tuple& key_comps(){return *this;}
  838. template<typename CompositeKey1,typename CompositeKey2>
  839. bool operator()(
  840. const composite_key_result<CompositeKey1> & x,
  841. const composite_key_result<CompositeKey2> & y)const
  842. {
  843. typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1;
  844. typedef typename CompositeKey1::value_type value_type1;
  845. typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2;
  846. typedef typename CompositeKey2::value_type value_type2;
  847. BOOST_STATIC_ASSERT(
  848. tuples::length<key_extractor_tuple1>::value<=
  849. tuples::length<key_comp_tuple>::value||
  850. tuples::length<key_extractor_tuple2>::value<=
  851. tuples::length<key_comp_tuple>::value);
  852. return detail::compare_ckey_ckey<
  853. key_extractor_tuple1,value_type1,
  854. key_extractor_tuple2,value_type2,
  855. key_comp_tuple
  856. >::compare(
  857. x.composite_key.key_extractors(),x.value,
  858. y.composite_key.key_extractors(),y.value,
  859. key_comps());
  860. }
  861. #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  862. template<typename CompositeKey,typename Value>
  863. bool operator()(
  864. const composite_key_result<CompositeKey>& x,
  865. const Value& y)const
  866. {
  867. return operator()(x,boost::make_tuple(boost::cref(y)));
  868. }
  869. #endif
  870. template
  871. <
  872. typename CompositeKey,
  873. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)
  874. >
  875. bool operator()(
  876. const composite_key_result<CompositeKey>& x,
  877. const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& y)const
  878. {
  879. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  880. typedef typename CompositeKey::value_type value_type;
  881. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
  882. BOOST_STATIC_ASSERT(
  883. tuples::length<key_extractor_tuple>::value<=
  884. tuples::length<key_comp_tuple>::value||
  885. tuples::length<key_tuple>::value<=
  886. tuples::length<key_comp_tuple>::value);
  887. return detail::compare_ckey_cval<
  888. key_extractor_tuple,value_type,
  889. key_tuple,key_comp_tuple
  890. >::compare(x.composite_key.key_extractors(),x.value,y,key_comps());
  891. }
  892. #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  893. template<typename Value,typename CompositeKey>
  894. bool operator()(
  895. const Value& x,
  896. const composite_key_result<CompositeKey>& y)const
  897. {
  898. return operator()(boost::make_tuple(boost::cref(x)),y);
  899. }
  900. #endif
  901. template
  902. <
  903. BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value),
  904. typename CompositeKey
  905. >
  906. bool operator()(
  907. const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x,
  908. const composite_key_result<CompositeKey>& y)const
  909. {
  910. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  911. typedef typename CompositeKey::value_type value_type;
  912. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
  913. BOOST_STATIC_ASSERT(
  914. tuples::length<key_tuple>::value<=
  915. tuples::length<key_comp_tuple>::value||
  916. tuples::length<key_extractor_tuple>::value<=
  917. tuples::length<key_comp_tuple>::value);
  918. return detail::compare_ckey_cval<
  919. key_extractor_tuple,value_type,
  920. key_tuple,key_comp_tuple
  921. >::compare(x,y.composite_key.key_extractors(),y.value,key_comps());
  922. }
  923. };
  924. /* composite_key_hash */
  925. template
  926. <
  927. BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash)
  928. >
  929. struct composite_key_hash:
  930. private tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)>
  931. {
  932. private:
  933. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Hash)> super;
  934. public:
  935. typedef super key_hasher_tuple;
  936. composite_key_hash(
  937. BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)):
  938. super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k))
  939. {}
  940. composite_key_hash(const key_hasher_tuple& x):super(x){}
  941. const key_hasher_tuple& key_hash_functions()const{return *this;}
  942. key_hasher_tuple& key_hash_functions(){return *this;}
  943. template<typename CompositeKey>
  944. std::size_t operator()(const composite_key_result<CompositeKey> & x)const
  945. {
  946. typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
  947. typedef typename CompositeKey::value_type value_type;
  948. BOOST_STATIC_ASSERT(
  949. tuples::length<key_extractor_tuple>::value==
  950. tuples::length<key_hasher_tuple>::value);
  951. return detail::hash_ckey<
  952. key_extractor_tuple,value_type,
  953. key_hasher_tuple
  954. >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions());
  955. }
  956. template<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value)>
  957. std::size_t operator()(
  958. const tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)>& x)const
  959. {
  960. typedef tuple<BOOST_MULTI_INDEX_CK_ENUM_PARAMS(Value)> key_tuple;
  961. BOOST_STATIC_ASSERT(
  962. tuples::length<key_tuple>::value==
  963. tuples::length<key_hasher_tuple>::value);
  964. return detail::hash_cval<
  965. key_tuple,key_hasher_tuple
  966. >::hash(x,key_hash_functions());
  967. }
  968. };
  969. /* Instantiations of the former functors with "natural" basic components:
  970. * composite_key_result_equal_to uses std::equal_to of the values.
  971. * composite_key_result_less uses std::less.
  972. * composite_key_result_greater uses std::greater.
  973. * composite_key_result_hash uses boost::hash.
  974. */
  975. #define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER \
  976. composite_key_equal_to< \
  977. BOOST_MULTI_INDEX_CK_ENUM( \
  978. BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
  979. /* the argument is a PP list */ \
  980. (detail::nth_composite_key_equal_to, \
  981. (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
  982. BOOST_PP_NIL))) \
  983. >
  984. template<typename CompositeKeyResult>
  985. struct composite_key_result_equal_to:
  986. BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
  987. BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
  988. {
  989. private:
  990. typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super;
  991. public:
  992. typedef CompositeKeyResult first_argument_type;
  993. typedef first_argument_type second_argument_type;
  994. typedef bool result_type;
  995. using super::operator();
  996. };
  997. #define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER \
  998. composite_key_compare< \
  999. BOOST_MULTI_INDEX_CK_ENUM( \
  1000. BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
  1001. /* the argument is a PP list */ \
  1002. (detail::nth_composite_key_less, \
  1003. (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
  1004. BOOST_PP_NIL))) \
  1005. >
  1006. template<typename CompositeKeyResult>
  1007. struct composite_key_result_less:
  1008. BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
  1009. BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
  1010. {
  1011. private:
  1012. typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super;
  1013. public:
  1014. typedef CompositeKeyResult first_argument_type;
  1015. typedef first_argument_type second_argument_type;
  1016. typedef bool result_type;
  1017. using super::operator();
  1018. };
  1019. #define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER \
  1020. composite_key_compare< \
  1021. BOOST_MULTI_INDEX_CK_ENUM( \
  1022. BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
  1023. /* the argument is a PP list */ \
  1024. (detail::nth_composite_key_greater, \
  1025. (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
  1026. BOOST_PP_NIL))) \
  1027. >
  1028. template<typename CompositeKeyResult>
  1029. struct composite_key_result_greater:
  1030. BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
  1031. BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
  1032. {
  1033. private:
  1034. typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super;
  1035. public:
  1036. typedef CompositeKeyResult first_argument_type;
  1037. typedef first_argument_type second_argument_type;
  1038. typedef bool result_type;
  1039. using super::operator();
  1040. };
  1041. #define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER \
  1042. composite_key_hash< \
  1043. BOOST_MULTI_INDEX_CK_ENUM( \
  1044. BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \
  1045. /* the argument is a PP list */ \
  1046. (detail::nth_composite_key_hash, \
  1047. (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \
  1048. BOOST_PP_NIL))) \
  1049. >
  1050. template<typename CompositeKeyResult>
  1051. struct composite_key_result_hash:
  1052. BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS
  1053. BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
  1054. {
  1055. private:
  1056. typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super;
  1057. public:
  1058. typedef CompositeKeyResult argument_type;
  1059. typedef std::size_t result_type;
  1060. using super::operator();
  1061. };
  1062. } /* namespace multi_index */
  1063. } /* namespace boost */
  1064. /* Specializations of std::equal_to, std::less, std::greater and boost::hash
  1065. * for composite_key_results enabling interoperation with tuples of values.
  1066. */
  1067. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  1068. namespace std{
  1069. template<typename CompositeKey>
  1070. struct equal_to<boost::multi_index::composite_key_result<CompositeKey> >:
  1071. boost::multi_index::composite_key_result_equal_to<
  1072. boost::multi_index::composite_key_result<CompositeKey>
  1073. >
  1074. {
  1075. };
  1076. template<typename CompositeKey>
  1077. struct less<boost::multi_index::composite_key_result<CompositeKey> >:
  1078. boost::multi_index::composite_key_result_less<
  1079. boost::multi_index::composite_key_result<CompositeKey>
  1080. >
  1081. {
  1082. };
  1083. template<typename CompositeKey>
  1084. struct greater<boost::multi_index::composite_key_result<CompositeKey> >:
  1085. boost::multi_index::composite_key_result_greater<
  1086. boost::multi_index::composite_key_result<CompositeKey>
  1087. >
  1088. {
  1089. };
  1090. } /* namespace std */
  1091. namespace boost{
  1092. template<typename CompositeKey>
  1093. struct hash<boost::multi_index::composite_key_result<CompositeKey> >:
  1094. boost::multi_index::composite_key_result_hash<
  1095. boost::multi_index::composite_key_result<CompositeKey>
  1096. >
  1097. {
  1098. };
  1099. } /* namespace boost */
  1100. #else
  1101. /* Lacking template partial specialization, std::equal_to, std::less and
  1102. * std::greater will still work for composite_key_results although without
  1103. * tuple interoperability. To achieve the same graceful degrading with
  1104. * boost::hash, we define the appropriate hash_value overload.
  1105. */
  1106. namespace boost{
  1107. #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
  1108. namespace multi_index{
  1109. #endif
  1110. template<typename CompositeKey>
  1111. inline std::size_t hash_value(
  1112. const boost::multi_index::composite_key_result<CompositeKey>& x)
  1113. {
  1114. boost::multi_index::composite_key_result_hash<
  1115. boost::multi_index::composite_key_result<CompositeKey> > h;
  1116. return h(x);
  1117. }
  1118. #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
  1119. } /* namespace multi_index */
  1120. #endif
  1121. } /* namespace boost */
  1122. #endif
  1123. #undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
  1124. #undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
  1125. #undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER
  1126. #undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER
  1127. #undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS
  1128. #undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO
  1129. #undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR
  1130. #undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N
  1131. #undef BOOST_MULTI_INDEX_CK_CTOR_ARG
  1132. #undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM
  1133. #undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS
  1134. #undef BOOST_MULTI_INDEX_CK_ENUM
  1135. #undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE
  1136. #endif