test_composite_key.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /* Boost.MultiIndex test for composite_key.
  2. *
  3. * Copyright 2003-2018 Joaquin M Lopez Munoz.
  4. * Distributed under the Boost Software License, Version 1.0.
  5. * (See accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * See http://www.boost.org/libs/multi_index for library home page.
  9. */
  10. #include "test_composite_key.hpp"
  11. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  12. #include <boost/detail/lightweight_test.hpp>
  13. #include "pre_multi_index.hpp"
  14. #include <boost/multi_index_container.hpp>
  15. #include <boost/multi_index/composite_key.hpp>
  16. #include <boost/multi_index/hashed_index.hpp>
  17. #include <boost/multi_index/member.hpp>
  18. #include <boost/multi_index/ordered_index.hpp>
  19. #include <boost/preprocessor/repetition/enum_binary_params.hpp>
  20. #include <boost/preprocessor/repetition/enum_params.hpp>
  21. #include <boost/preprocessor/repetition/repeat_from_to.hpp>
  22. using namespace boost::multi_index;
  23. using namespace boost::tuples;
  24. struct is_composite_key_result_helper
  25. {
  26. typedef char yes;
  27. struct no{char m[2];};
  28. static no test(void*);
  29. template<typename CompositeKey>
  30. static yes test(composite_key_result<CompositeKey>*);
  31. };
  32. template<typename T>
  33. struct is_composite_key_result
  34. {
  35. typedef is_composite_key_result_helper helper;
  36. BOOST_STATIC_CONSTANT(bool,
  37. value=(
  38. sizeof(helper::test((T*)0))==
  39. sizeof(typename helper::yes)));
  40. };
  41. template<typename CompositeKeyResult>
  42. struct composite_key_result_length
  43. {
  44. BOOST_STATIC_CONSTANT(int,
  45. value=boost::tuples::length<
  46. BOOST_DEDUCED_TYPENAME
  47. CompositeKeyResult::composite_key_type::key_extractor_tuple
  48. >::value);
  49. };
  50. #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
  51. !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  52. struct is_boost_tuple_helper
  53. {
  54. typedef char yes;
  55. struct no{char m[2];};
  56. static no test(void*);
  57. template<BOOST_PP_ENUM_PARAMS(10,typename T)>
  58. static yes test(boost::tuple<BOOST_PP_ENUM_PARAMS(10,T)>*);
  59. };
  60. template<typename T>
  61. struct is_boost_tuple
  62. {
  63. typedef is_boost_tuple_helper helper;
  64. BOOST_STATIC_CONSTANT(bool,
  65. value=(
  66. sizeof(helper::test((T*)0))==
  67. sizeof(typename helper::yes)));
  68. };
  69. template<typename T>
  70. struct composite_object_length
  71. {
  72. typedef typename boost::mpl::if_c<
  73. is_composite_key_result<T>::value,
  74. composite_key_result_length<T>,
  75. typename boost::mpl::if_c<
  76. is_boost_tuple<T>::value,
  77. boost::tuples::length<T>,
  78. std::tuple_size<T>
  79. >::type
  80. >::type type;
  81. BOOST_STATIC_CONSTANT(int,value=type::value);
  82. };
  83. #else
  84. template<typename T>
  85. struct composite_object_length
  86. {
  87. typedef typename boost::mpl::if_c<
  88. is_composite_key_result<T>::value,
  89. composite_key_result_length<T>,
  90. boost::tuples::length<T>
  91. >::type type;
  92. BOOST_STATIC_CONSTANT(int,value=type::value);
  93. };
  94. #endif
  95. template<typename CompositeKeyResult,typename T2>
  96. struct comparison_equal_length
  97. {
  98. static bool is_less(const CompositeKeyResult& x,const T2& y)
  99. {
  100. composite_key_result_equal_to<CompositeKeyResult> eq;
  101. composite_key_result_less<CompositeKeyResult> lt;
  102. composite_key_result_greater<CompositeKeyResult> gt;
  103. std::equal_to<CompositeKeyResult> std_eq;
  104. std::less<CompositeKeyResult> std_lt;
  105. std::greater<CompositeKeyResult> std_gt;
  106. return (x< y) && !(y< x)&&
  107. !(x==y) && !(y==x)&&
  108. (x!=y) && (y!=x)&&
  109. !(x> y) && (y> x)&&
  110. !(x>=y) && (y>=x)&&
  111. (x<=y) && !(y<=x)&&
  112. !eq(x,y) && !eq(y,x)&&
  113. lt(x,y) && !lt(y,x)&&
  114. !gt(x,y) && gt(y,x)&&
  115. !std_eq(x,y) && !std_eq(y,x)&&
  116. std_lt(x,y) && !std_lt(y,x)&&
  117. !std_gt(x,y) && std_gt(y,x);
  118. }
  119. static bool is_greater(const CompositeKeyResult& x,const T2& y)
  120. {
  121. composite_key_result_equal_to<CompositeKeyResult> eq;
  122. composite_key_result_less<CompositeKeyResult> lt;
  123. composite_key_result_greater<CompositeKeyResult> gt;
  124. std::equal_to<CompositeKeyResult> std_eq;
  125. std::less<CompositeKeyResult> std_lt;
  126. std::greater<CompositeKeyResult> std_gt;
  127. return !(x< y) && (y< x)&&
  128. !(x==y) && !(y==x)&&
  129. (x!=y) && (y!=x)&&
  130. (x> y) && !(y> x)&&
  131. (x>=y) && !(y>=x)&&
  132. !(x<=y) && (y<=x)&&
  133. !eq(x,y) && !eq(y,x)&&
  134. !lt(x,y) && lt(y,x)&&
  135. gt(x,y) && !gt(y,x)&&
  136. !std_eq(x,y) && !std_eq(y,x)&&
  137. !std_lt(x,y) && std_lt(y,x)&&
  138. std_gt(x,y) && !std_gt(y,x);
  139. }
  140. static bool is_equiv(const CompositeKeyResult& x,const T2& y)
  141. {
  142. composite_key_result_equal_to<CompositeKeyResult> eq;
  143. composite_key_result_less<CompositeKeyResult> lt;
  144. composite_key_result_greater<CompositeKeyResult> gt;
  145. std::equal_to<CompositeKeyResult> std_eq;
  146. std::less<CompositeKeyResult> std_lt;
  147. std::greater<CompositeKeyResult> std_gt;
  148. return !(x< y) && !(y< x)&&
  149. (x==y) && (y==x)&&
  150. !(x!=y) && !(y!=x)&&
  151. !(x> y) && !(y> x)&&
  152. (x>=y) && (y>=x)&&
  153. (x<=y) && (y<=x)&&
  154. eq(x,y) && eq(y,x)&&
  155. !lt(x,y) && !lt(y,x)&&
  156. !gt(x,y) && !gt(y,x)&&
  157. std_eq(x,y) && std_eq(y,x)&&
  158. !std_lt(x,y) && !std_lt(y,x)&&
  159. !std_gt(x,y) && !std_gt(y,x);
  160. }
  161. };
  162. template<typename CompositeKeyResult,typename T2>
  163. struct comparison_different_length
  164. {
  165. static bool is_less(const CompositeKeyResult& x,const T2& y)
  166. {
  167. composite_key_result_less<CompositeKeyResult> lt;
  168. composite_key_result_greater<CompositeKeyResult> gt;
  169. std::less<CompositeKeyResult> std_lt;
  170. std::greater<CompositeKeyResult> std_gt;
  171. return (x< y) && !(y< x)&&
  172. !(x> y) && (y> x)&&
  173. !(x>=y) && (y>=x)&&
  174. (x<=y) && !(y<=x)&&
  175. lt(x,y) && !lt(y,x)&&
  176. !gt(x,y) && gt(y,x)&&
  177. std_lt(x,y) && !std_lt(y,x)&&
  178. !std_gt(x,y) && std_gt(y,x);
  179. }
  180. static bool is_greater(const CompositeKeyResult& x,const T2& y)
  181. {
  182. composite_key_result_less<CompositeKeyResult> lt;
  183. composite_key_result_greater<CompositeKeyResult> gt;
  184. std::less<CompositeKeyResult> std_lt;
  185. std::greater<CompositeKeyResult> std_gt;
  186. return !(x< y) && (y< x)&&
  187. (x> y) && !(y> x)&&
  188. (x>=y) && !(y>=x)&&
  189. !(x<=y) && (y<=x)&&
  190. !lt(x,y) && lt(y,x)&&
  191. gt(x,y) && !gt(y,x)&&
  192. !std_lt(x,y) && std_lt(y,x)&&
  193. std_gt(x,y) && !std_gt(y,x);
  194. }
  195. static bool is_equiv(const CompositeKeyResult& x,const T2& y)
  196. {
  197. composite_key_result_less<CompositeKeyResult> lt;
  198. composite_key_result_greater<CompositeKeyResult> gt;
  199. std::less<CompositeKeyResult> std_lt;
  200. std::greater<CompositeKeyResult> std_gt;
  201. return !(x< y) && !(y< x)&&
  202. !(x> y) && !(y> x)&&
  203. (x>=y) && (y>=x)&&
  204. (x<=y) && (y<=x)&&
  205. !lt(x,y) && !lt(y,x)&&
  206. !gt(x,y) && !gt(y,x)&&
  207. !std_lt(x,y) && !std_lt(y,x)&&
  208. !std_gt(x,y) && !std_gt(y,x);
  209. }
  210. };
  211. template<typename CompositeKeyResult,typename T2>
  212. struct comparison_helper:
  213. boost::mpl::if_c<
  214. composite_key_result_length<CompositeKeyResult>::value==
  215. composite_object_length<T2>::value,
  216. comparison_equal_length<CompositeKeyResult,T2>,
  217. comparison_different_length<CompositeKeyResult,T2>
  218. >::type
  219. {
  220. };
  221. template<typename CompositeKeyResult,typename T2>
  222. static bool is_less(const CompositeKeyResult& x,const T2& y)
  223. {
  224. return comparison_helper<CompositeKeyResult,T2>::is_less(x,y);
  225. }
  226. template<typename CompositeKeyResult,typename T2>
  227. static bool is_greater(const CompositeKeyResult& x,const T2& y)
  228. {
  229. return comparison_helper<CompositeKeyResult,T2>::is_greater(x,y);
  230. }
  231. template<typename CompositeKeyResult,typename T2>
  232. static bool is_equiv(const CompositeKeyResult& x,const T2& y)
  233. {
  234. return comparison_helper<CompositeKeyResult,T2>::is_equiv(x,y);
  235. }
  236. template<typename T1,typename T2,typename Compare>
  237. static bool is_less(const T1& x,const T2& y,const Compare& c)
  238. {
  239. return c(x,y)&&!c(y,x);
  240. }
  241. template<typename T1,typename T2,typename Compare>
  242. static bool is_greater(const T1& x,const T2& y,const Compare& c)
  243. {
  244. return c(y,x)&&!c(x,y);
  245. }
  246. template<typename T1,typename T2,typename Compare>
  247. static bool is_equiv(const T1& x,const T2& y,const Compare& c)
  248. {
  249. return !c(x,y)&&!c(y,x);
  250. }
  251. template<typename T1,typename T2,typename Compare,typename Equiv>
  252. static bool is_less(
  253. const T1& x,const T2& y,const Compare& c,const Equiv& eq)
  254. {
  255. return c(x,y)&&!c(y,x)&&!eq(x,y)&&!eq(y,x);
  256. }
  257. template<typename T1,typename T2,typename Compare,typename Equiv>
  258. static bool is_greater(
  259. const T1& x,const T2& y,const Compare& c,const Equiv& eq)
  260. {
  261. return c(y,x)&&!c(x,y)&&!eq(x,y)&&!eq(y,x);
  262. }
  263. template<typename T1,typename T2,typename Compare,typename Equiv>
  264. static bool is_equiv(
  265. const T1& x,const T2& y,const Compare& c,const Equiv& eq)
  266. {
  267. return !c(x,y)&&!c(y,x)&&eq(x,y)&&eq(y,x);
  268. }
  269. struct xyz
  270. {
  271. xyz(int x_=0,int y_=0,int z_=0):x(x_),y(y_),z(z_){}
  272. int x;
  273. int y;
  274. int z;
  275. };
  276. struct modulo_equal
  277. {
  278. modulo_equal(int i):i_(i){}
  279. bool operator ()(int x,int y)const{return (x%i_)==(y%i_);}
  280. private:
  281. int i_;
  282. };
  283. struct xystr
  284. {
  285. xystr(int x_=0,int y_=0,std::string str_=0):x(x_),y(y_),str(str_){}
  286. int x;
  287. int y;
  288. std::string str;
  289. };
  290. #define TUPLE_MAKER_CREATE(z,n,tuple) \
  291. template<BOOST_PP_ENUM_PARAMS(n,typename T)> \
  292. static tuple<BOOST_PP_ENUM_PARAMS(n,T)> \
  293. create(BOOST_PP_ENUM_BINARY_PARAMS(n,const T,& t)){ \
  294. return tuple<BOOST_PP_ENUM_PARAMS(n,T)>( \
  295. BOOST_PP_ENUM_PARAMS(n,t)); \
  296. }
  297. #define DEFINE_TUPLE_MAKER(name,tuple) \
  298. struct name \
  299. { \
  300. static tuple<> create(){return tuple<>();} \
  301. BOOST_PP_REPEAT_FROM_TO(1,5,TUPLE_MAKER_CREATE,tuple) \
  302. };
  303. DEFINE_TUPLE_MAKER(boost_tuple_maker,boost::tuple)
  304. #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
  305. !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  306. DEFINE_TUPLE_MAKER(std_tuple_maker,std::tuple)
  307. #endif
  308. #undef DEFINE_TUPLE_MAKER
  309. #undef TUPLE_MAKER_CREATE
  310. template<typename TupleMaker>
  311. void test_composite_key_template()
  312. {
  313. typedef composite_key<
  314. xyz,
  315. BOOST_MULTI_INDEX_MEMBER(xyz,int,x),
  316. BOOST_MULTI_INDEX_MEMBER(xyz,int,y),
  317. BOOST_MULTI_INDEX_MEMBER(xyz,int,z)
  318. > ckey_t1;
  319. typedef multi_index_container<
  320. xyz,
  321. indexed_by<
  322. ordered_unique<ckey_t1>
  323. >
  324. > indexed_t1;
  325. indexed_t1 mc1;
  326. mc1.insert(xyz(0,0,0));
  327. mc1.insert(xyz(0,0,1));
  328. mc1.insert(xyz(0,1,0));
  329. mc1.insert(xyz(0,1,1));
  330. mc1.insert(xyz(1,0,0));
  331. mc1.insert(xyz(1,0,1));
  332. mc1.insert(xyz(1,1,0));
  333. mc1.insert(xyz(1,1,1));
  334. BOOST_TEST(mc1.size()==8);
  335. BOOST_TEST(
  336. std::distance(
  337. mc1.find(mc1.key_extractor()(xyz(0,0,0))),
  338. mc1.find(mc1.key_extractor()(xyz(1,0,0))))==4);
  339. BOOST_TEST(
  340. std::distance(
  341. mc1.find(TupleMaker::create(0,0,0)),
  342. mc1.find(TupleMaker::create(1,0,0)))==4);
  343. BOOST_TEST(
  344. std::distance(
  345. mc1.lower_bound(TupleMaker::create(0,0)),
  346. mc1.upper_bound(TupleMaker::create(1,0)))==6);
  347. #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  348. BOOST_TEST(
  349. std::distance(
  350. mc1.lower_bound(1),
  351. mc1.upper_bound(1))==4);
  352. #endif
  353. ckey_t1 ck1;
  354. ckey_t1 ck2(ck1);
  355. ckey_t1 ck3(
  356. boost::make_tuple(
  357. BOOST_MULTI_INDEX_MEMBER(xyz,int,x)(),
  358. BOOST_MULTI_INDEX_MEMBER(xyz,int,y)(),
  359. BOOST_MULTI_INDEX_MEMBER(xyz,int,z)()));
  360. ckey_t1 ck4(get<0>(ck1.key_extractors()));
  361. (void)ck3; /* prevent unused var */
  362. get<2>(ck4.key_extractors())=
  363. get<2>(ck2.key_extractors());
  364. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0))));
  365. BOOST_TEST(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0))));
  366. BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0))));
  367. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0)));
  368. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(1)));
  369. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(-1)));
  370. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0)));
  371. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,1)));
  372. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,-1)));
  373. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0)));
  374. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,1)));
  375. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1)));
  376. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0,1)));
  377. typedef composite_key_result_less<ckey_t1::result_type> ckey_comp_t1;
  378. typedef composite_key_result_equal_to<ckey_t1::result_type> ckey_eq_t1;
  379. ckey_comp_t1 cp1;
  380. ckey_eq_t1 eq1;
  381. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp1,eq1));
  382. BOOST_TEST(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp1,eq1));
  383. BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp1,eq1));
  384. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0),cp1));
  385. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(1),cp1));
  386. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(-1),cp1));
  387. #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
  388. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),0,cp1));
  389. BOOST_TEST(is_less (ck1(xyz(0,0,0)),1,cp1));
  390. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),-1,cp1));
  391. #endif
  392. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0),cp1));
  393. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,1),cp1));
  394. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,-1),cp1));
  395. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0),cp1,eq1));
  396. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,1),cp1,eq1));
  397. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1),cp1,eq1));
  398. typedef composite_key_result_greater<ckey_t1::result_type> ckey_comp_t2;
  399. ckey_comp_t2 cp2;
  400. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp2));
  401. BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp2));
  402. BOOST_TEST(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp2));
  403. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0),cp2));
  404. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(1),cp2));
  405. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(-1),cp2));
  406. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0),cp2));
  407. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,1),cp2));
  408. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,-1),cp2));
  409. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0),cp2));
  410. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,1),cp2));
  411. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1),cp2));
  412. typedef composite_key_equal_to<
  413. modulo_equal,
  414. modulo_equal,
  415. std::equal_to<int>,
  416. std::equal_to<int>
  417. > ckey_eq_t2;
  418. ckey_eq_t2 eq2(
  419. boost::make_tuple(
  420. modulo_equal(2),
  421. modulo_equal(3),
  422. std::equal_to<int>(),
  423. std::equal_to<int>()));
  424. ckey_eq_t2 eq3(eq2);
  425. ckey_eq_t2 eq4(
  426. get<0>(eq3.key_eqs()),
  427. get<1>(eq3.key_eqs()));
  428. eq3=eq4; /* prevent unused var */
  429. eq4=eq3; /* prevent unused var */
  430. BOOST_TEST( eq2(ck1(xyz(0,0,0)),ck1(xyz(0,0,0))));
  431. BOOST_TEST(!eq2(ck1(xyz(0,1,0)),ck1(xyz(0,0,0))));
  432. BOOST_TEST(!eq2(ck1(xyz(0,2,0)),ck1(xyz(0,0,0))));
  433. BOOST_TEST( eq2(ck1(xyz(0,3,0)),ck1(xyz(0,0,0))));
  434. BOOST_TEST(!eq2(ck1(xyz(1,0,0)),ck1(xyz(0,0,0))));
  435. BOOST_TEST(!eq2(ck1(xyz(1,1,0)),ck1(xyz(0,0,0))));
  436. BOOST_TEST(!eq2(ck1(xyz(1,2,0)),ck1(xyz(0,0,0))));
  437. BOOST_TEST(!eq2(ck1(xyz(1,3,0)),ck1(xyz(0,0,0))));
  438. BOOST_TEST( eq2(ck1(xyz(2,0,0)),ck1(xyz(0,0,0))));
  439. BOOST_TEST(!eq2(ck1(xyz(2,1,0)),ck1(xyz(0,0,0))));
  440. BOOST_TEST(!eq2(ck1(xyz(2,2,0)),ck1(xyz(0,0,0))));
  441. BOOST_TEST( eq2(ck1(xyz(2,3,0)),ck1(xyz(0,0,0))));
  442. BOOST_TEST( eq2(TupleMaker::create(0,0,0),ck1(xyz(0,0,0))));
  443. BOOST_TEST(!eq2(ck1(xyz(0,1,0)) ,TupleMaker::create(0,0,0)));
  444. BOOST_TEST(!eq2(TupleMaker::create(0,2,0),ck1(xyz(0,0,0))));
  445. BOOST_TEST( eq2(ck1(xyz(0,3,0)) ,TupleMaker::create(0,0,0)));
  446. BOOST_TEST(!eq2(TupleMaker::create(1,0,0),ck1(xyz(0,0,0))));
  447. BOOST_TEST(!eq2(ck1(xyz(1,1,0)) ,TupleMaker::create(0,0,0)));
  448. BOOST_TEST(!eq2(TupleMaker::create(1,2,0),ck1(xyz(0,0,0))));
  449. BOOST_TEST(!eq2(ck1(xyz(1,3,0)) ,TupleMaker::create(0,0,0)));
  450. BOOST_TEST( eq2(TupleMaker::create(2,0,0),ck1(xyz(0,0,0))));
  451. BOOST_TEST(!eq2(ck1(xyz(2,1,0)) ,TupleMaker::create(0,0,0)));
  452. BOOST_TEST(!eq2(TupleMaker::create(2,2,0),ck1(xyz(0,0,0))));
  453. BOOST_TEST( eq2(ck1(xyz(2,3,0)) ,TupleMaker::create(0,0,0)));
  454. typedef composite_key_compare<
  455. std::less<int>,
  456. std::greater<int>, /* order reversed */
  457. std::less<int>
  458. > ckey_comp_t3;
  459. ckey_comp_t3 cp3;
  460. ckey_comp_t3 cp4(cp3);
  461. ckey_comp_t3 cp5(
  462. boost::make_tuple(
  463. std::less<int>(),
  464. std::greater<int>(),
  465. std::less<int>()));
  466. ckey_comp_t3 cp6(get<0>(cp3.key_comps()));
  467. cp4=cp5; /* prevent unused var */
  468. cp5=cp6; /* prevent unused var */
  469. cp6=cp4; /* prevent unused var */
  470. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp3));
  471. BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp3));
  472. BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp3));
  473. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0),cp3));
  474. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(1),cp3));
  475. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(-1),cp3));
  476. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0),cp3));
  477. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,-1),cp3));
  478. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,1),cp3));
  479. BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0),cp3));
  480. BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,1),cp3));
  481. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1),cp3));
  482. typedef composite_key<
  483. xyz,
  484. BOOST_MULTI_INDEX_MEMBER(xyz,int,y), /* members reversed */
  485. BOOST_MULTI_INDEX_MEMBER(xyz,int,x)
  486. > ckey_t2;
  487. ckey_t2 ck5;
  488. BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0))));
  489. BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0))));
  490. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0))));
  491. BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp1));
  492. BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp1));
  493. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp1));
  494. BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp2));
  495. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp2));
  496. BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp2));
  497. BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp3));
  498. BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp3));
  499. BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp3));
  500. typedef multi_index_container<
  501. xyz,
  502. indexed_by<
  503. hashed_unique<ckey_t1>
  504. >
  505. > indexed_t2;
  506. indexed_t2 mc2;
  507. mc2.insert(xyz(0,0,0));
  508. mc2.insert(xyz(0,0,1));
  509. mc2.insert(xyz(0,1,0));
  510. mc2.insert(xyz(0,1,1));
  511. mc2.insert(xyz(1,0,0));
  512. mc2.insert(xyz(1,0,1));
  513. mc2.insert(xyz(1,1,0));
  514. mc2.insert(xyz(1,1,1));
  515. mc2.insert(xyz(0,0,0));
  516. mc2.insert(xyz(0,0,1));
  517. mc2.insert(xyz(0,1,0));
  518. mc2.insert(xyz(0,1,1));
  519. mc2.insert(xyz(1,0,0));
  520. mc2.insert(xyz(1,0,1));
  521. mc2.insert(xyz(1,1,0));
  522. mc2.insert(xyz(1,1,1));
  523. BOOST_TEST(mc2.size()==8);
  524. BOOST_TEST(mc2.find(TupleMaker::create(0,0,1))->z==1);
  525. BOOST_TEST(ck1(*(mc2.find(TupleMaker::create(1,0,1))))==
  526. TupleMaker::create(1,0,1));
  527. typedef composite_key<
  528. xystr,
  529. BOOST_MULTI_INDEX_MEMBER(xystr,std::string,str),
  530. BOOST_MULTI_INDEX_MEMBER(xystr,int,x),
  531. BOOST_MULTI_INDEX_MEMBER(xystr,int,y)
  532. > ckey_t3;
  533. ckey_t3 ck6;
  534. typedef composite_key_hash<
  535. boost::hash<std::string>,
  536. boost::hash<int>,
  537. boost::hash<int>
  538. > ckey_hash_t;
  539. ckey_hash_t ch1;
  540. ckey_hash_t ch2(ch1);
  541. ckey_hash_t ch3(
  542. boost::make_tuple(
  543. boost::hash<std::string>(),
  544. boost::hash<int>(),
  545. boost::hash<int>()));
  546. ckey_hash_t ch4(get<0>(ch1.key_hash_functions()));
  547. ch2=ch3; /* prevent unused var */
  548. ch3=ch4; /* prevent unused var */
  549. ch4=ch2; /* prevent unused var */
  550. BOOST_TEST(
  551. ch1(ck6(xystr(0,0,"hello")))==
  552. ch1(TupleMaker::create(std::string("hello"),0,0)));
  553. BOOST_TEST(
  554. ch1(ck6(xystr(4,5,"world")))==
  555. ch1(TupleMaker::create(std::string("world"),4,5)));
  556. typedef boost::hash<composite_key_result<ckey_t3> > ckeyres_hash_t;
  557. ckeyres_hash_t crh;
  558. BOOST_TEST(
  559. ch1(ck6(xystr(0,0,"hello")))==crh(ck6(xystr(0,0,"hello"))));
  560. BOOST_TEST(
  561. ch1(ck6(xystr(4,5,"world")))==crh(ck6(xystr(4,5,"world"))));
  562. }
  563. void test_composite_key()
  564. {
  565. test_composite_key_template<boost_tuple_maker>();
  566. #if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
  567. !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  568. test_composite_key_template<std_tuple_maker>();
  569. #endif
  570. }