3 // Copyright (c) 2006-2007 Matias Capeletto
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)
9 /// \file relation/structured_pair.hpp
10 /// \brief Defines the structured_pair class.
12 #ifndef BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP
13 #define BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP
15 #if defined(_MSC_VER) && (_MSC_VER>=1200)
19 #include <boost/config.hpp>
23 #include <boost/type_traits/remove_const.hpp>
25 #include <boost/mpl/aux_/na.hpp>
27 #include <boost/call_traits.hpp>
29 #include <boost/utility/enable_if.hpp>
30 #include <boost/type_traits/is_same.hpp>
31 #include <boost/mpl/if.hpp>
32 #include <boost/mpl/vector.hpp>
34 #include <boost/bimap/detail/debug/static_error.hpp>
35 #include <boost/bimap/relation/pair_layout.hpp>
36 #include <boost/bimap/relation/symmetrical_base.hpp>
37 #include <boost/bimap/relation/support/get.hpp>
38 #include <boost/bimap/tags/support/value_type_of.hpp>
48 /// \brief Storage definition of the left view of a mutant relation.
51 See also storage_finder, mirror_storage.
54 template< class FirstType, class SecondType >
55 class normal_storage :
56 public symmetrical_base<FirstType,SecondType>
58 typedef symmetrical_base<FirstType,SecondType> base_;
62 typedef normal_storage storage_;
64 typedef BOOST_DEDUCED_TYPENAME base_::left_value_type first_type;
65 typedef BOOST_DEDUCED_TYPENAME base_::right_value_type second_type;
72 normal_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits<
73 first_type >::param_type f,
74 BOOST_DEDUCED_TYPENAME ::boost::call_traits<
75 second_type>::param_type s)
77 : first(f), second(s) {}
79 BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left() { return first; }
80 const BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left()const { return first; }
81 BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right() { return second; }
82 const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return second; }
85 /// \brief Storage definition of the right view of a mutant relation.
88 See also storage_finder, normal_storage.
91 template< class FirstType, class SecondType >
92 class mirror_storage :
93 public symmetrical_base<SecondType,FirstType>
95 typedef symmetrical_base<SecondType,FirstType> base_;
99 typedef mirror_storage storage_;
101 typedef BOOST_DEDUCED_TYPENAME base_::left_value_type second_type;
102 typedef BOOST_DEDUCED_TYPENAME base_::right_value_type first_type;
109 mirror_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits<first_type >::param_type f,
110 BOOST_DEDUCED_TYPENAME ::boost::call_traits<second_type >::param_type s)
112 : second(s), first(f) {}
114 BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left() { return second; }
115 const BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left()const { return second; }
116 BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right() { return first; }
117 const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return first; }
120 /** \struct boost::bimaps::relation::storage_finder
121 \brief Obtain the a storage with the correct layout.
124 template< class FirstType, class SecondType, class Layout >
125 struct storage_finder
127 typedef {normal/mirror}_storage<FirstType,SecondType> type;
131 See also normal_storage, mirror_storage.
134 #ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
142 struct storage_finder
144 typedef normal_storage<FirstType,SecondType> type;
152 struct storage_finder<FirstType,SecondType,mirror_layout>
154 typedef mirror_storage<FirstType,SecondType> type;
157 #endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
160 template< class TA, class TB, class Info, class Layout >
161 class pair_info_hook :
162 public ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type
164 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type base_;
166 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support::
167 default_tagged<Info,member_at::info>::type tagged_info_type;
170 typedef BOOST_DEDUCED_TYPENAME tagged_info_type::value_type info_type;
171 typedef BOOST_DEDUCED_TYPENAME tagged_info_type::tag info_tag;
179 pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits<
180 BOOST_DEDUCED_TYPENAME base_::first_type
182 BOOST_DEDUCED_TYPENAME ::boost::call_traits<
183 BOOST_DEDUCED_TYPENAME base_::second_type
185 BOOST_DEDUCED_TYPENAME ::boost::call_traits<
187 >::param_type i = info_type() )
188 : base_(f,s), info(i) {}
190 template< class Pair >
191 pair_info_hook( const Pair & p) :
192 base_(p.first,p.second),
195 template< class Pair >
196 void change_to( const Pair & p )
198 base_::first = p.first ;
199 base_::second = p.second;
209 template< class TA, class TB, class Layout>
210 class pair_info_hook<TA,TB,::boost::mpl::na,Layout> :
211 public ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type
213 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type base_;
216 typedef ::boost::mpl::na info_type;
217 typedef member_at::info info_tag;
223 pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits<
224 BOOST_DEDUCED_TYPENAME base_::first_type
226 BOOST_DEDUCED_TYPENAME ::boost::call_traits<
227 BOOST_DEDUCED_TYPENAME base_::second_type
232 template< class Pair >
233 pair_info_hook( const Pair & p ) :
234 base_(p.first,p.second) {}
236 template< class Pair >
237 void change_to( const Pair & p )
239 base_::first = p.first ;
240 base_::second = p.second;
243 void clear_info() {};
248 } // namespace detail
250 template< class TA, class TB, class Info, bool FM >
251 class mutant_relation;
254 /// \brief A std::pair signature compatible class that allows you to control
255 /// the internal structure of the data.
257 This class allows you to specify the order in wich the two data types will be
258 in the layout of the class.
261 template< class FirstType, class SecondType, class Info, class Layout = normal_layout >
262 class structured_pair :
264 public ::boost::bimaps::relation::detail::pair_info_hook
266 FirstType, SecondType,
273 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::pair_info_hook
275 FirstType, SecondType,
283 typedef ::boost::mpl::vector3<
284 structured_pair< FirstType, SecondType, Info, normal_layout >,
285 structured_pair< FirstType, SecondType, Info, mirror_layout >,
286 BOOST_DEDUCED_TYPENAME ::boost::mpl::if_<
287 BOOST_DEDUCED_TYPENAME ::boost::is_same<Layout, normal_layout>::type,
288 mutant_relation< FirstType, SecondType, Info, true >,
289 mutant_relation< SecondType, FirstType, Info, true >
296 structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits<
297 BOOST_DEDUCED_TYPENAME base_::first_type >::param_type f,
298 BOOST_DEDUCED_TYPENAME boost::call_traits<
299 BOOST_DEDUCED_TYPENAME base_::second_type >::param_type s)
302 structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits<
303 BOOST_DEDUCED_TYPENAME base_::first_type >::param_type f,
304 BOOST_DEDUCED_TYPENAME boost::call_traits<
305 BOOST_DEDUCED_TYPENAME base_::second_type >::param_type s,
306 BOOST_DEDUCED_TYPENAME boost::call_traits<
307 BOOST_DEDUCED_TYPENAME base_::info_type >::param_type i)
310 template< class OtherLayout >
312 const structured_pair<FirstType,SecondType,Info,OtherLayout> & p)
315 template< class OtherLayout >
316 structured_pair& operator=(
317 const structured_pair<FirstType,SecondType,OtherLayout> & p)
323 template< class First, class Second >
324 structured_pair(const std::pair<First,Second> & p) :
325 base_(p.first,p.second)
328 template< class First, class Second >
329 structured_pair& operator=(const std::pair<First,Second> & p)
331 base_::first = p.first;
332 base_::second = p.second;
337 template< class Tag >
338 const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
339 result_of::get<Tag,const structured_pair>::type
340 get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) const
342 return ::boost::bimaps::relation::support::get<Tag>(*this);
345 template< class Tag >
346 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
347 result_of::get<Tag,structured_pair>::type
348 get(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))
350 return ::boost::bimaps::relation::support::get<Tag>(*this);
354 // structured_pair - structured_pair
356 template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
357 bool operator==(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
358 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
360 return ( ( a.first == b.first ) &&
361 ( a.second == b.second ) );
364 template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
365 bool operator!=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
366 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
371 template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
372 bool operator<(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
373 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
375 return ( ( a.first < b.first ) ||
376 (( a.first == b.first ) && ( a.second < b.second )));
379 template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
380 bool operator<=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
381 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
383 return ( ( a.first < b.first ) ||
384 (( a.first == b.first ) && ( a.second <= b.second )));
387 template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
388 bool operator>(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
389 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
391 return ( ( a.first > b.first ) ||
392 (( a.first == b.first ) && ( a.second > b.second )));
395 template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
396 bool operator>=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
397 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
399 return ( ( a.first > b.first ) ||
400 (( a.first == b.first ) && ( a.second >= b.second )));
403 // structured_pair - std::pair
405 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
406 bool operator==(const structured_pair<FirstType,SecondType,Info,Layout> & a,
407 const std::pair<F,S> & b)
409 return ( ( a.first == b.first ) &&
410 ( a.second == b.second ) );
413 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
414 bool operator!=(const structured_pair<FirstType,SecondType,Info,Layout> & a,
415 const std::pair<F,S> & b)
420 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
421 bool operator<(const structured_pair<FirstType,SecondType,Info,Layout> & a,
422 const std::pair<F,S> & b)
424 return ( ( a.first < b.first ) ||
425 (( a.first == b.first ) && ( a.second < b.second )));
428 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
429 bool operator<=(const structured_pair<FirstType,SecondType,Info,Layout> & a,
430 const std::pair<F,S> & b)
432 return ( ( a.first < b.first ) ||
433 (( a.first == b.first ) && ( a.second <= b.second )));
436 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
437 bool operator>(const structured_pair<FirstType,SecondType,Info,Layout> & a,
438 const std::pair<F,S> & b)
440 return ( ( a.first > b.first ) ||
441 (( a.first == b.first ) && ( a.second > b.second )));
444 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
445 bool operator>=(const structured_pair<FirstType,SecondType,Info,Layout> & a,
446 const std::pair<F,S> & b)
448 return ( ( a.first > b.first ) ||
449 (( a.first == b.first ) && ( a.second >= b.second )));
452 // std::pair - sturctured_pair
454 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
455 bool operator==(const std::pair<F,S> & a,
456 const structured_pair<FirstType,SecondType,Info,Layout> & b)
458 return ( ( a.first == b.first ) &&
459 ( a.second == b.second ) );
462 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
463 bool operator!=(const std::pair<F,S> & a,
464 const structured_pair<FirstType,SecondType,Info,Layout> & b)
469 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
470 bool operator<(const std::pair<F,S> & a,
471 const structured_pair<FirstType,SecondType,Info,Layout> & b)
473 return ( ( a.first < b.first ) ||
474 (( a.first == b.first ) && ( a.second < b.second )));
477 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
478 bool operator<=(const std::pair<F,S> & a,
479 const structured_pair<FirstType,SecondType,Info,Layout> & b)
481 return ( ( a.first < b.first ) ||
482 (( a.first == b.first ) && ( a.second <= b.second )));
485 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
486 bool operator>(const std::pair<F,S> & a,
487 const structured_pair<FirstType,SecondType,Info,Layout> & b)
489 return ( ( a.first > b.first ) ||
490 (( a.first == b.first ) && ( a.second > b.second )));
493 template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
494 bool operator>=(const std::pair<F,S> & a,
495 const structured_pair<FirstType,SecondType,Info,Layout> & b)
497 return ( ( a.first > b.first ) ||
498 (( a.first == b.first ) && ( a.second >= b.second )));
503 } // namespace relation
504 } // namespace bimaps
507 #endif // BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP