]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
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() 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 | ||
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 | namespace detail { | |
503 | ||
504 | template< class FirstType, class SecondType, class Info, class Layout> | |
505 | structured_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 | ||
514 | template< class FirstType, class SecondType, class Layout> | |
515 | structured_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 | ||
524 | template< class FirstType, class SecondType, class Info, class Layout> | |
525 | structured_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 | ||
534 | template< class FirstType, class SecondType, class Layout> | |
535 | structured_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 |