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
9/// \file relation/structured_pair.hpp
10/// \brief Defines the structured_pair class.
11
12#ifndef BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP
13#define BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP
14
15#if defined(_MSC_VER)
16#pragma once
17#endif
18
19#include <boost/config.hpp>
20
21#include <utility>
22
23#include <boost/type_traits/remove_const.hpp>
24
25#include <boost/mpl/aux_/na.hpp>
26
27#include <boost/call_traits.hpp>
28
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>
33
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>
39
40
41
42namespace boost {
43namespace bimaps {
44namespace relation {
45
46namespace detail {
47
48/// \brief Storage definition of the left view of a mutant relation.
49/**
50
51See also storage_finder, mirror_storage.
52 **/
53
54template< class FirstType, class SecondType >
55class normal_storage :
56 public symmetrical_base<FirstType,SecondType>
57{
58 typedef symmetrical_base<FirstType,SecondType> base_;
59
60 public:
61
62 typedef normal_storage storage_;
63
64 typedef BOOST_DEDUCED_TYPENAME base_::left_value_type first_type;
65 typedef BOOST_DEDUCED_TYPENAME base_::right_value_type second_type;
66
67 first_type first;
68 second_type second;
69
70 normal_storage() {}
71
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)
76
77 : first(f), second(s) {}
78
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; }
83};
84
85/// \brief Storage definition of the right view of a mutant relation.
86/**
87
88See also storage_finder, normal_storage.
89 **/
90
91template< class FirstType, class SecondType >
92class mirror_storage :
93 public symmetrical_base<SecondType,FirstType>
94{
95 typedef symmetrical_base<SecondType,FirstType> base_;
96
97 public:
98
99 typedef mirror_storage storage_;
100
101 typedef BOOST_DEDUCED_TYPENAME base_::left_value_type second_type;
102 typedef BOOST_DEDUCED_TYPENAME base_::right_value_type first_type;
103
104 second_type second;
105 first_type first;
106
107 mirror_storage() {}
108
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)
111
112 : second(s), first(f) {}
113
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; }
118};
119
120/** \struct boost::bimaps::relation::storage_finder
121\brief Obtain the a storage with the correct layout.
122
123\code
124template< class FirstType, class SecondType, class Layout >
125struct storage_finder
126{
127 typedef {normal/mirror}_storage<FirstType,SecondType> type;
128};
129\endcode
130
131See also normal_storage, mirror_storage.
132 **/
133
134#ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
135
136template
137<
138 class FirstType,
139 class SecondType,
140 class Layout
141>
142struct storage_finder
143{
144 typedef normal_storage<FirstType,SecondType> type;
145};
146
147template
148<
149 class FirstType,
150 class SecondType
151>
152struct storage_finder<FirstType,SecondType,mirror_layout>
153{
154 typedef mirror_storage<FirstType,SecondType> type;
155};
156
157#endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
158
159
160template< class TA, class TB, class Info, class Layout >
161class pair_info_hook :
162 public ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type
163{
164 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type base_;
165
166 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support::
167 default_tagged<Info,member_at::info>::type tagged_info_type;
168
169 public:
170 typedef BOOST_DEDUCED_TYPENAME tagged_info_type::value_type info_type;
171 typedef BOOST_DEDUCED_TYPENAME tagged_info_type::tag info_tag;
172
173 info_type info;
174
175 protected:
176
177 pair_info_hook() {}
178
179 pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits<
180 BOOST_DEDUCED_TYPENAME base_::first_type
181 >::param_type f,
182 BOOST_DEDUCED_TYPENAME ::boost::call_traits<
183 BOOST_DEDUCED_TYPENAME base_::second_type
184 >::param_type s,
185 BOOST_DEDUCED_TYPENAME ::boost::call_traits<
186 info_type
187 >::param_type i = info_type() )
188 : base_(f,s), info(i) {}
189
190 template< class Pair >
191 pair_info_hook( const Pair & p) :
192 base_(p.first,p.second),
193 info(p.info) {}
194
195 template< class Pair >
196 void change_to( const Pair & p )
197 {
198 base_::first = p.first ;
199 base_::second = p.second;
200 info = p.info ;
201 }
202
203 void clear_info()
204 {
205 info = info_type();
206 };
207};
208
209template< class TA, class TB, class Layout>
210class pair_info_hook<TA,TB,::boost::mpl::na,Layout> :
211 public ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type
212{
213 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder<TA,TB,Layout>::type base_;
214
215 public:
216 typedef ::boost::mpl::na info_type;
217 typedef member_at::info info_tag;
218
219 protected:
220
221 pair_info_hook() {}
222
223 pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits<
224 BOOST_DEDUCED_TYPENAME base_::first_type
225 >::param_type f,
226 BOOST_DEDUCED_TYPENAME ::boost::call_traits<
227 BOOST_DEDUCED_TYPENAME base_::second_type
228 >::param_type s)
229
230 : base_(f,s) {}
231
232 template< class Pair >
233 pair_info_hook( const Pair & p ) :
234 base_(p.first,p.second) {}
235
236 template< class Pair >
237 void change_to( const Pair & p )
238 {
239 base_::first = p.first ;
240 base_::second = p.second;
241 }
242
243 void clear_info() {};
244};
245
246
247
248} // namespace detail
249
250template< class TA, class TB, class Info, bool FM >
251class mutant_relation;
252
253
254/// \brief A std::pair signature compatible class that allows you to control
255/// the internal structure of the data.
256/**
257This class allows you to specify the order in wich the two data types will be
258in the layout of the class.
259 **/
260
261template< class FirstType, class SecondType, class Info, class Layout = normal_layout >
262class structured_pair :
263
264 public ::boost::bimaps::relation::detail::pair_info_hook
265 <
266 FirstType, SecondType,
267 Info,
268 Layout
269
270 >
271
272{
273 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::pair_info_hook
274 <
275 FirstType, SecondType,
276 Info,
277 Layout
278
279 > base_;
280
281 public:
282
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 >
290 >::type
291
292 > mutant_views;
293
294 structured_pair() {}
295
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)
300 : base_(f,s) {}
301
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)
308 : base_(f,s,i) {}
309
310 template< class OtherLayout >
311 structured_pair(
312 const structured_pair<FirstType,SecondType,Info,OtherLayout> & p)
313 : base_(p) {}
314
315 template< class OtherLayout >
316 structured_pair& operator=(
317 const structured_pair<FirstType,SecondType,OtherLayout> & p)
318 {
319 base_::change_to(p);
320 return *this;
321 }
322
323 template< class First, class Second >
324 structured_pair(const std::pair<First,Second> & p) :
325 base_(p.first,p.second)
326 {}
327
328 template< class First, class Second >
329 structured_pair& operator=(const std::pair<First,Second> & p)
330 {
331 base_::first = p.first;
332 base_::second = p.second;
333 base_::clear_info();
334 return *this;
335 }
336
337 template< class Tag >
338 const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
339 result_of::get<Tag,const structured_pair>::type
340 get() const
341 {
342 return ::boost::bimaps::relation::support::get<Tag>(*this);
343 }
344
345 template< class Tag >
346 BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
347 result_of::get<Tag,structured_pair>::type
348 get()
349 {
350 return ::boost::bimaps::relation::support::get<Tag>(*this);
351 }
352};
353
354// structured_pair - structured_pair
355
356template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
357bool operator==(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
358 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
359{
360 return ( ( a.first == b.first ) &&
361 ( a.second == b.second ) );
362}
363
364template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
365bool operator!=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
366 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
367{
368 return ! ( a == b );
369}
370
371template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
372bool operator<(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
373 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
374{
375 return ( ( a.first < b.first ) ||
376 (( a.first == b.first ) && ( a.second < b.second )));
377}
378
379template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
380bool operator<=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
381 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
382{
383 return ( ( a.first < b.first ) ||
384 (( a.first == b.first ) && ( a.second <= b.second )));
385}
386
387template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
388bool operator>(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
389 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
390{
391 return ( ( a.first > b.first ) ||
392 (( a.first == b.first ) && ( a.second > b.second )));
393}
394
395template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 >
396bool operator>=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,
397 const structured_pair<FirstType,SecondType,Info,Layout2> & b)
398{
399 return ( ( a.first > b.first ) ||
400 (( a.first == b.first ) && ( a.second >= b.second )));
401}
402
403// structured_pair - std::pair
404
405template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
406bool operator==(const structured_pair<FirstType,SecondType,Info,Layout> & a,
407 const std::pair<F,S> & b)
408{
409 return ( ( a.first == b.first ) &&
410 ( a.second == b.second ) );
411}
412
413template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
414bool operator!=(const structured_pair<FirstType,SecondType,Info,Layout> & a,
415 const std::pair<F,S> & b)
416{
417 return ! ( a == b );
418}
419
420template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
421bool operator<(const structured_pair<FirstType,SecondType,Info,Layout> & a,
422 const std::pair<F,S> & b)
423{
424 return ( ( a.first < b.first ) ||
425 (( a.first == b.first ) && ( a.second < b.second )));
426}
427
428template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
429bool operator<=(const structured_pair<FirstType,SecondType,Info,Layout> & a,
430 const std::pair<F,S> & b)
431{
432 return ( ( a.first < b.first ) ||
433 (( a.first == b.first ) && ( a.second <= b.second )));
434}
435
436template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
437bool operator>(const structured_pair<FirstType,SecondType,Info,Layout> & a,
438 const std::pair<F,S> & b)
439{
440 return ( ( a.first > b.first ) ||
441 (( a.first == b.first ) && ( a.second > b.second )));
442}
443
444template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
445bool operator>=(const structured_pair<FirstType,SecondType,Info,Layout> & a,
446 const std::pair<F,S> & b)
447{
448 return ( ( a.first > b.first ) ||
449 (( a.first == b.first ) && ( a.second >= b.second )));
450}
451
452// std::pair - sturctured_pair
453
454template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
455bool operator==(const std::pair<F,S> & a,
456 const structured_pair<FirstType,SecondType,Info,Layout> & b)
457{
458 return ( ( a.first == b.first ) &&
459 ( a.second == b.second ) );
460}
461
462template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
463bool operator!=(const std::pair<F,S> & a,
464 const structured_pair<FirstType,SecondType,Info,Layout> & b)
465{
466 return ! ( a == b );
467}
468
469template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
470bool operator<(const std::pair<F,S> & a,
471 const structured_pair<FirstType,SecondType,Info,Layout> & b)
472{
473 return ( ( a.first < b.first ) ||
474 (( a.first == b.first ) && ( a.second < b.second )));
475}
476
477template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
478bool operator<=(const std::pair<F,S> & a,
479 const structured_pair<FirstType,SecondType,Info,Layout> & b)
480{
481 return ( ( a.first < b.first ) ||
482 (( a.first == b.first ) && ( a.second <= b.second )));
483}
484
485template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
486bool operator>(const std::pair<F,S> & a,
487 const structured_pair<FirstType,SecondType,Info,Layout> & b)
488{
489 return ( ( a.first > b.first ) ||
490 (( a.first == b.first ) && ( a.second > b.second )));
491}
492
493template< class FirstType, class SecondType, class Info, class Layout, class F, class S >
494bool operator>=(const std::pair<F,S> & a,
495 const structured_pair<FirstType,SecondType,Info,Layout> & b)
496{
497 return ( ( a.first > b.first ) ||
498 (( a.first == b.first ) && ( a.second >= b.second )));
499}
500
501
502namespace detail {
503
504template< class FirstType, class SecondType, class Info, class Layout>
505structured_pair<FirstType,SecondType,Info,Layout>
506 copy_with_first_replaced(structured_pair<FirstType,SecondType,Info,Layout> const& p,
507 BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME
508 structured_pair<FirstType,SecondType,Info,Layout>::first_type>
509 ::param_type f)
510{
511 return structured_pair<FirstType,SecondType,Info,Layout>(f,p.second,p.info);
512}
513
514template< class FirstType, class SecondType, class Layout>
515structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>
516 copy_with_first_replaced(structured_pair<FirstType,SecondType,::boost::mpl::na,Layout> const& p,
517 BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME
518 structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>::first_type>
519 ::param_type f)
520{
521 return structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>(f,p.second);
522}
523
524template< class FirstType, class SecondType, class Info, class Layout>
525structured_pair<FirstType,SecondType,Info,Layout>
526 copy_with_second_replaced(structured_pair<FirstType,SecondType,Info,Layout> const& p,
527 BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME
528 structured_pair<FirstType,SecondType,Info,Layout>::second_type>
529 ::param_type s)
530{
531 return structured_pair<FirstType,SecondType,Info,Layout>(p.first,s,p.info);
532}
533
534template< class FirstType, class SecondType, class Layout>
535structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>
536 copy_with_second_replaced(structured_pair<FirstType,SecondType,::boost::mpl::na,Layout> const& p,
537 BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME
538 structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>::second_type>
539 ::param_type s)
540{
541 return structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>(p.first,s);
542}
543
544} // namespace detail
545
546
547} // namespace relation
548} // namespace bimaps
549} // namespace boost
550
551#endif // BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP
552
553

source code of boost/boost/bimap/relation/structured_pair.hpp