Add Boost.Test karmic valgrind suppressions
[senf.git] / boost / bimap / relation / structured_pair.hpp
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) && (_MSC_VER>=1200)
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
42 namespace boost {
43 namespace bimaps {
44 namespace relation {
45
46 namespace detail {
47
48 /// \brief Storage definition of the left view of a mutant relation.
49 /**
50
51 See also storage_finder, mirror_storage.
52                                                                             **/
53
54 template< class FirstType, class SecondType >
55 class 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
88 See also storage_finder, normal_storage.
89                                                                             **/
90
91 template< class FirstType, class SecondType >
92 class 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
124 template< class FirstType, class SecondType, class Layout >
125 struct storage_finder
126 {
127     typedef {normal/mirror}_storage<FirstType,SecondType> type;
128 };
129 \endcode
130
131 See also normal_storage, mirror_storage.
132                                                                         **/
133
134 #ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES
135
136 template
137 <
138     class FirstType,
139     class SecondType,
140     class Layout
141 >
142 struct storage_finder
143 {
144     typedef normal_storage<FirstType,SecondType> type;
145 };
146
147 template
148 <
149     class FirstType,
150     class SecondType
151 >
152 struct 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
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
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
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
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
250 template< class TA, class TB, class Info, bool FM >
251 class 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 /**
257 This class allows you to specify the order in wich the two data types will be
258 in the layout of the class.
259                                                                                **/
260
261 template< class FirstType, class SecondType, class Info, class Layout = normal_layout >
262 class 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(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag)) 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(BOOST_EXPLICIT_TEMPLATE_TYPE(Tag))
349     {
350         return ::boost::bimaps::relation::support::get<Tag>(*this);
351     }
352 };
353
354 // structured_pair - structured_pair
355
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)
359 {
360     return ( ( a.first  == b.first  ) &&
361              ( a.second == b.second ) );
362 }
363
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)
367 {
368     return ! ( a == b );
369 }
370
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)
374 {
375     return (  ( a.first  <  b.first  ) ||
376              (( a.first == b.first ) && ( a.second < b.second )));
377 }
378
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)
382 {
383     return (  ( a.first  <  b.first  ) ||
384              (( a.first == b.first ) && ( a.second <= b.second )));
385 }
386
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)
390 {
391     return ( ( a.first  >  b.first  ) ||
392              (( a.first == b.first ) && ( a.second > b.second )));
393 }
394
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)
398 {
399     return ( ( a.first  >  b.first  ) ||
400              (( a.first == b.first ) && ( a.second >= b.second )));
401 }
402
403 // structured_pair - std::pair
404
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)
408 {
409     return ( ( a.first  == b.first  ) &&
410              ( a.second == b.second ) );
411 }
412
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)
416 {
417     return ! ( a == b );
418 }
419
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)
423 {
424     return (  ( a.first  <  b.first  ) ||
425              (( a.first == b.first ) && ( a.second < b.second )));
426 }
427
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)
431 {
432     return (  ( a.first  <  b.first  ) ||
433              (( a.first == b.first ) && ( a.second <= b.second )));
434 }
435
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)
439 {
440     return ( ( a.first  >  b.first  ) ||
441              (( a.first == b.first ) && ( a.second > b.second )));
442 }
443
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)
447 {
448     return ( ( a.first  >  b.first  ) ||
449              (( a.first == b.first ) && ( a.second >= b.second )));
450 }
451
452 // std::pair - sturctured_pair
453
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)
457 {
458     return ( ( a.first  == b.first  ) &&
459              ( a.second == b.second ) );
460 }
461
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)
465 {
466     return ! ( a == b );
467 }
468
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)
472 {
473     return (  ( a.first  <  b.first  ) ||
474              (( a.first == b.first ) && ( a.second < b.second )));
475 }
476
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)
480 {
481     return (  ( a.first  <  b.first  ) ||
482              (( a.first == b.first ) && ( a.second <= b.second )));
483 }
484
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)
488 {
489     return ( ( a.first  >  b.first  ) ||
490              (( a.first == b.first ) && ( a.second > b.second )));
491 }
492
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)
496 {
497     return ( ( a.first  >  b.first  ) ||
498              (( a.first == b.first ) && ( a.second >= b.second )));
499 }
500
501
502
503 } // namespace relation
504 } // namespace bimaps
505 } // namespace boost
506
507 #endif // BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP
508