structured_pair.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. // Boost.Bimap
  2. //
  3. // Copyright (c) 2006-2007 Matias Capeletto
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. /// \file relation/structured_pair.hpp
  9. /// \brief Defines the structured_pair class.
  10. #ifndef BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP
  11. #define BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP
  12. #if defined(_MSC_VER)
  13. #pragma once
  14. #endif
  15. #include <boost/config.hpp>
  16. #include <utility>
  17. #include <boost/type_traits/remove_const.hpp>
  18. #include <boost/mpl/aux_/na.hpp>
  19. #include <boost/call_traits.hpp>
  20. #include <boost/utility/enable_if.hpp>
  21. #include <boost/type_traits/is_same.hpp>
  22. #include <boost/mpl/if.hpp>
  23. #include <boost/mpl/vector.hpp>
  24. #include <boost/bimap/detail/debug/static_error.hpp>
  25. #include <boost/bimap/relation/pair_layout.hpp>
  26. #include <boost/bimap/relation/symmetrical_base.hpp>
  27. #include <boost/bimap/relation/support/get.hpp>
  28. #include <boost/bimap/tags/support/value_type_of.hpp>
  29. namespace boost {
  30. namespace bimaps {
  31. namespace relation {
  32. namespace detail {
  33. /// \brief Storage definition of the left view of a mutant relation.
  34. /**
  35. See also storage_finder, mirror_storage.
  36. **/
  37. template< class FirstType, class SecondType >
  38. class normal_storage :
  39. public symmetrical_base<FirstType,SecondType>
  40. {
  41. typedef symmetrical_base<FirstType,SecondType> base_;
  42. public:
  43. typedef normal_storage storage_;
  44. typedef BOOST_DEDUCED_TYPENAME base_::left_value_type first_type;
  45. typedef BOOST_DEDUCED_TYPENAME base_::right_value_type second_type;
  46. first_type first;
  47. second_type second;
  48. normal_storage() {}
  49. normal_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits<
  50. first_type >::param_type f,
  51. BOOST_DEDUCED_TYPENAME ::boost::call_traits<
  52. second_type>::param_type s)
  53. : first(f), second(s) {}
  54. BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left() { return first; }
  55. const BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left()const { return first; }
  56. BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right() { return second; }
  57. const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return second; }
  58. };
  59. /// \brief Storage definition of the right view of a mutant relation.
  60. /**
  61. See also storage_finder, normal_storage.
  62. **/
  63. template< class FirstType, class SecondType >
  64. class mirror_storage :
  65. public symmetrical_base<SecondType,FirstType>
  66. {
  67. typedef symmetrical_base<SecondType,FirstType> base_;
  68. public:
  69. typedef mirror_storage storage_;
  70. typedef BOOST_DEDUCED_TYPENAME base_::left_value_type second_type;
  71. typedef BOOST_DEDUCED_TYPENAME base_::right_value_type first_type;
  72. second_type second;
  73. first_type first;
  74. mirror_storage() {}
  75. mirror_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits<first_type >::param_type f,
  76. BOOST_DEDUCED_TYPENAME ::boost::call_traits<second_type >::param_type s)
  77. : second(s), first(f) {}
  78. BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left() { return second; }
  79. const BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left()const { return second; }
  80. BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right() { return first; }
  81. const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return first; }
  82. };
  83. /** \struct boost::bimaps::relation::storage_finder
  84. \brief Obtain the a storage with the correct layout.
  85. \code
  86. template< class FirstType, class SecondType, class Layout >
  87. struct storage_finder
  88. {
  89. typedef {normal/mirror}_storage<FirstType,SecondType> type;
  90. };
  91. \endcode
  92. See also normal_storage, mirror_storage.
  93. **/
  94. #ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
  95. template
  96. <
  97. class FirstType,
  98. class SecondType,
  99. class Layout
  100. >
  101. struct storage_finder
  102. {
  103. typedef normal_storage<FirstType,SecondType> type;
  104. };
  105. template
  106. <
  107. class FirstType,
  108. class SecondType
  109. >
  110. struct storage_finder<FirstType,SecondType,mirror_layout>
  111. {
  112. typedef mirror_storage<FirstType,SecondType> type;
  113. };
  114. #endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
  115. template< class TA, class TB, class Info, class Layout >
  116. class pair_info_hook :
  117. public ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type
  118. {
  119. typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type base_;
  120. typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support::
  121. default_tagged<Info,member_at::info>::type tagged_info_type;
  122. public:
  123. typedef BOOST_DEDUCED_TYPENAME tagged_info_type::value_type info_type;
  124. typedef BOOST_DEDUCED_TYPENAME tagged_info_type::tag info_tag;
  125. info_type info;
  126. protected:
  127. pair_info_hook() {}
  128. pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits<
  129. BOOST_DEDUCED_TYPENAME base_::first_type
  130. >::param_type f,
  131. BOOST_DEDUCED_TYPENAME ::boost::call_traits<
  132. BOOST_DEDUCED_TYPENAME base_::second_type
  133. >::param_type s,
  134. BOOST_DEDUCED_TYPENAME ::boost::call_traits<
  135. info_type
  136. >::param_type i = info_type() )
  137. : base_(f,s), info(i) {}
  138. template< class Pair >
  139. pair_info_hook( const Pair & p) :
  140. base_(p.first,p.second),
  141. info(p.info) {}
  142. template< class Pair >
  143. void change_to( const Pair & p )
  144. {
  145. base_::first = p.first ;
  146. base_::second = p.second;
  147. info = p.info ;
  148. }
  149. void clear_info()
  150. {
  151. info = info_type();
  152. };
  153. };
  154. template< class TA, class TB, class Layout>
  155. class pair_info_hook<TA,TB,::boost::mpl::na,Layout> :
  156. public ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type
  157. {
  158. typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type base_;
  159. public:
  160. typedef ::boost::mpl::na info_type;
  161. typedef member_at::info info_tag;
  162. protected:
  163. pair_info_hook() {}
  164. pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits<
  165. BOOST_DEDUCED_TYPENAME base_::first_type
  166. >::param_type f,
  167. BOOST_DEDUCED_TYPENAME ::boost::call_traits<
  168. BOOST_DEDUCED_TYPENAME base_::second_type
  169. >::param_type s)
  170. : base_(f,s) {}
  171. template< class Pair >
  172. pair_info_hook( const Pair & p ) :
  173. base_(p.first,p.second) {}
  174. template< class Pair >
  175. void change_to( const Pair & p )
  176. {
  177. base_::first = p.first ;
  178. base_::second = p.second;
  179. }
  180. void clear_info() {};
  181. };
  182. } // namespace detail
  183. template< class TA, class TB, class Info, bool FM >
  184. class mutant_relation;
  185. /// \brief A std::pair signature compatible class that allows you to control
  186. /// the internal structure of the data.
  187. /**
  188. This class allows you to specify the order in which the two data types will be
  189. in the layout of the class.
  190. **/
  191. template< class FirstType, class SecondType, class Info, class Layout = normal_layout >
  192. class structured_pair :
  193. public ::boost::bimaps::relation::detail::pair_info_hook
  194. <
  195. FirstType, SecondType,
  196. Info,
  197. Layout
  198. >
  199. {
  200. typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::pair_info_hook
  201. <
  202. FirstType, SecondType,
  203. Info,
  204. Layout
  205. > base_;
  206. public:
  207. typedef ::boost::mpl::vector3<
  208. structured_pair< FirstType, SecondType, Info, normal_layout >,
  209. structured_pair< FirstType, SecondType, Info, mirror_layout >,
  210. BOOST_DEDUCED_TYPENAME ::boost::mpl::if_<
  211. BOOST_DEDUCED_TYPENAME ::boost::is_same<Layout, normal_layout>::type,
  212. mutant_relation< FirstType, SecondType, Info, true >,
  213. mutant_relation< SecondType, FirstType, Info, true >
  214. >::type
  215. > mutant_views;
  216. structured_pair() {}
  217. structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits<
  218. BOOST_DEDUCED_TYPENAME base_::first_type >::param_type f,
  219. BOOST_DEDUCED_TYPENAME boost::call_traits<
  220. BOOST_DEDUCED_TYPENAME base_::second_type >::param_type s)
  221. : base_(f,s) {}
  222. structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits<
  223. BOOST_DEDUCED_TYPENAME base_::first_type >::param_type f,
  224. BOOST_DEDUCED_TYPENAME boost::call_traits<
  225. BOOST_DEDUCED_TYPENAME base_::second_type >::param_type s,
  226. BOOST_DEDUCED_TYPENAME boost::call_traits<
  227. BOOST_DEDUCED_TYPENAME base_::info_type >::param_type i)
  228. : base_(f,s,i) {}
  229. template< class OtherLayout >
  230. structured_pair(
  231. const structured_pair<FirstType,SecondType,Info,OtherLayout> & p)
  232. : base_(p) {}
  233. template< class OtherLayout >
  234. structured_pair& operator=(
  235. const structured_pair<FirstType,SecondType,OtherLayout> & p)
  236. {
  237. base_::change_to(p);
  238. return *this;
  239. }
  240. template< class First, class Second >
  241. structured_pair(const std::pair<First,Second> & p) :
  242. base_(p.first,p.second)
  243. {}
  244. template< class First, class Second >
  245. structured_pair& operator=(const std::pair<First,Second> & p)
  246. {
  247. base_::first = p.first;
  248. base_::second = p.second;
  249. base_::clear_info();
  250. return *this;
  251. }
  252. template< class Tag >
  253. const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
  254. result_of::get<Tag,const structured_pair>::type
  255. get() const
  256. {
  257. return ::boost::bimaps::relation::support::get<Tag>(*this);
  258. }
  259. template< class Tag >
  260. BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
  261. result_of::get<Tag,structured_pair>::type
  262. get()
  263. {
  264. return ::boost::bimaps::relation::support::get<Tag>(*this);
  265. }
  266. };
  267. // structured_pair - structured_pair
  268. template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
  269. bool operator==(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
  270. const structured_pair<FirstType,SecondType,Info,Layout2> & b)
  271. {
  272. return ( ( a.first == b.first ) &&
  273. ( a.second == b.second ) );
  274. }
  275. template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
  276. bool operator!=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
  277. const structured_pair<FirstType,SecondType,Info,Layout2> & b)
  278. {
  279. return ! ( a == b );
  280. }
  281. template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
  282. bool operator<(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
  283. const structured_pair<FirstType,SecondType,Info,Layout2> & b)
  284. {
  285. return ( ( a.first < b.first ) ||
  286. (( a.first == b.first ) && ( a.second < b.second )));
  287. }
  288. template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
  289. bool operator<=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
  290. const structured_pair<FirstType,SecondType,Info,Layout2> & b)
  291. {
  292. return ( ( a.first < b.first ) ||
  293. (( a.first == b.first ) && ( a.second <= b.second )));
  294. }
  295. template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
  296. bool operator>(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
  297. const structured_pair<FirstType,SecondType,Info,Layout2> & b)
  298. {
  299. return ( ( a.first > b.first ) ||
  300. (( a.first == b.first ) && ( a.second > b.second )));
  301. }
  302. template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
  303. bool operator>=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
  304. const structured_pair<FirstType,SecondType,Info,Layout2> & b)
  305. {
  306. return ( ( a.first > b.first ) ||
  307. (( a.first == b.first ) && ( a.second >= b.second )));
  308. }
  309. // structured_pair - std::pair
  310. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  311. bool operator==(const structured_pair<FirstType,SecondType,Info,Layout> & a,
  312. const std::pair<F,S> & b)
  313. {
  314. return ( ( a.first == b.first ) &&
  315. ( a.second == b.second ) );
  316. }
  317. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  318. bool operator!=(const structured_pair<FirstType,SecondType,Info,Layout> & a,
  319. const std::pair<F,S> & b)
  320. {
  321. return ! ( a == b );
  322. }
  323. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  324. bool operator<(const structured_pair<FirstType,SecondType,Info,Layout> & a,
  325. const std::pair<F,S> & b)
  326. {
  327. return ( ( a.first < b.first ) ||
  328. (( a.first == b.first ) && ( a.second < b.second )));
  329. }
  330. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  331. bool operator<=(const structured_pair<FirstType,SecondType,Info,Layout> & a,
  332. const std::pair<F,S> & b)
  333. {
  334. return ( ( a.first < b.first ) ||
  335. (( a.first == b.first ) && ( a.second <= b.second )));
  336. }
  337. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  338. bool operator>(const structured_pair<FirstType,SecondType,Info,Layout> & a,
  339. const std::pair<F,S> & b)
  340. {
  341. return ( ( a.first > b.first ) ||
  342. (( a.first == b.first ) && ( a.second > b.second )));
  343. }
  344. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  345. bool operator>=(const structured_pair<FirstType,SecondType,Info,Layout> & a,
  346. const std::pair<F,S> & b)
  347. {
  348. return ( ( a.first > b.first ) ||
  349. (( a.first == b.first ) && ( a.second >= b.second )));
  350. }
  351. // std::pair - sturctured_pair
  352. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  353. bool operator==(const std::pair<F,S> & a,
  354. const structured_pair<FirstType,SecondType,Info,Layout> & b)
  355. {
  356. return ( ( a.first == b.first ) &&
  357. ( a.second == b.second ) );
  358. }
  359. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  360. bool operator!=(const std::pair<F,S> & a,
  361. const structured_pair<FirstType,SecondType,Info,Layout> & b)
  362. {
  363. return ! ( a == b );
  364. }
  365. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  366. bool operator<(const std::pair<F,S> & a,
  367. const structured_pair<FirstType,SecondType,Info,Layout> & b)
  368. {
  369. return ( ( a.first < b.first ) ||
  370. (( a.first == b.first ) && ( a.second < b.second )));
  371. }
  372. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  373. bool operator<=(const std::pair<F,S> & a,
  374. const structured_pair<FirstType,SecondType,Info,Layout> & b)
  375. {
  376. return ( ( a.first < b.first ) ||
  377. (( a.first == b.first ) && ( a.second <= b.second )));
  378. }
  379. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  380. bool operator>(const std::pair<F,S> & a,
  381. const structured_pair<FirstType,SecondType,Info,Layout> & b)
  382. {
  383. return ( ( a.first > b.first ) ||
  384. (( a.first == b.first ) && ( a.second > b.second )));
  385. }
  386. template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
  387. bool operator>=(const std::pair<F,S> & a,
  388. const structured_pair<FirstType,SecondType,Info,Layout> & b)
  389. {
  390. return ( ( a.first > b.first ) ||
  391. (( a.first == b.first ) && ( a.second >= b.second )));
  392. }
  393. namespace detail {
  394. template< class FirstType, class SecondType, class Info, class Layout>
  395. structured_pair<FirstType,SecondType,Info,Layout>
  396. copy_with_first_replaced(structured_pair<FirstType,SecondType,Info,Layout> const& p,
  397. BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME
  398. structured_pair<FirstType,SecondType,Info,Layout>::first_type>
  399. ::param_type f)
  400. {
  401. return structured_pair<FirstType,SecondType,Info,Layout>(f,p.second,p.info);
  402. }
  403. template< class FirstType, class SecondType, class Layout>
  404. structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>
  405. copy_with_first_replaced(structured_pair<FirstType,SecondType,::boost::mpl::na,Layout> const& p,
  406. BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME
  407. structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>::first_type>
  408. ::param_type f)
  409. {
  410. return structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>(f,p.second);
  411. }
  412. template< class FirstType, class SecondType, class Info, class Layout>
  413. structured_pair<FirstType,SecondType,Info,Layout>
  414. copy_with_second_replaced(structured_pair<FirstType,SecondType,Info,Layout> const& p,
  415. BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME
  416. structured_pair<FirstType,SecondType,Info,Layout>::second_type>
  417. ::param_type s)
  418. {
  419. return structured_pair<FirstType,SecondType,Info,Layout>(p.first,s,p.info);
  420. }
  421. template< class FirstType, class SecondType, class Layout>
  422. structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>
  423. copy_with_second_replaced(structured_pair<FirstType,SecondType,::boost::mpl::na,Layout> const& p,
  424. BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME
  425. structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>::second_type>
  426. ::param_type s)
  427. {
  428. return structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>(p.first,s);
  429. }
  430. } // namespace detail
  431. } // namespace relation
  432. } // namespace bimaps
  433. } // namespace boost
  434. #endif // BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP