• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
normal_storage()70     normal_storage() {}
71 
normal_storage(BOOST_DEDUCED_TYPENAME::boost::call_traits<first_type>::param_type f,BOOST_DEDUCED_TYPENAME::boost::call_traits<second_type>::param_type s)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 
get_left()79           BOOST_DEDUCED_TYPENAME base_:: left_value_type &  get_left()      { return first;  }
get_left() const80     const BOOST_DEDUCED_TYPENAME base_:: left_value_type &  get_left()const { return first;  }
get_right()81           BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()      { return second; }
get_right() const82     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 
mirror_storage()107     mirror_storage() {}
108 
mirror_storage(BOOST_DEDUCED_TYPENAME::boost::call_traits<first_type>::param_type f,BOOST_DEDUCED_TYPENAME::boost::call_traits<second_type>::param_type s)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 
get_left()114           BOOST_DEDUCED_TYPENAME base_:: left_value_type &  get_left()      { return second; }
get_left() const115     const BOOST_DEDUCED_TYPENAME base_:: left_value_type &  get_left()const { return second; }
get_right()116           BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()      { return first;  }
get_right() const117     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 
pair_info_hook()177     pair_info_hook() {}
178 
pair_info_hook(BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME base_::first_type>::param_type f,BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME base_::second_type>::param_type s,BOOST_DEDUCED_TYPENAME::boost::call_traits<info_type>::param_type i=info_type ())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 >
pair_info_hook(const Pair & p)191     pair_info_hook( const Pair & p) :
192         base_(p.first,p.second),
193         info(p.info) {}
194 
195     template< class Pair >
change_to(const Pair & p)196     void change_to( const Pair & p )
197     {
198         base_::first  = p.first ;
199         base_::second = p.second;
200         info          = p.info  ;
201     }
202 
clear_info()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 
pair_info_hook()221     pair_info_hook() {}
222 
pair_info_hook(BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME base_::first_type>::param_type f,BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME base_::second_type>::param_type s)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 >
pair_info_hook(const Pair & p)233     pair_info_hook( const Pair & p ) :
234         base_(p.first,p.second) {}
235 
236     template< class Pair >
change_to(const Pair & p)237     void change_to( const Pair & p )
238     {
239         base_::first  = p.first ;
240         base_::second = p.second;
241     }
242 
clear_info()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 which 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 
structured_pair()294     structured_pair() {}
295 
structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits<BOOST_DEDUCED_TYPENAME base_::first_type>::param_type f,BOOST_DEDUCED_TYPENAME boost::call_traits<BOOST_DEDUCED_TYPENAME base_::second_type>::param_type s)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 
structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits<BOOST_DEDUCED_TYPENAME base_::first_type>::param_type f,BOOST_DEDUCED_TYPENAME boost::call_traits<BOOST_DEDUCED_TYPENAME base_::second_type>::param_type s,BOOST_DEDUCED_TYPENAME boost::call_traits<BOOST_DEDUCED_TYPENAME base_::info_type>::param_type i)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 >
structured_pair(const structured_pair<FirstType,SecondType,Info,OtherLayout> & p)311     structured_pair(
312         const structured_pair<FirstType,SecondType,Info,OtherLayout> & p)
313         : base_(p) {}
314 
315     template< class OtherLayout >
operator =(const structured_pair<FirstType,SecondType,OtherLayout> & p)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 >
structured_pair(const std::pair<First,Second> & p)324     structured_pair(const std::pair<First,Second> & p) :
325         base_(p.first,p.second)
326     {}
327 
328     template< class First, class Second >
operator =(const std::pair<First,Second> & p)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
get() const340     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
get()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 >
operator ==(const structured_pair<FirstType,SecondType,Info,Layout1> & a,const structured_pair<FirstType,SecondType,Info,Layout2> & b)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 >
operator !=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,const structured_pair<FirstType,SecondType,Info,Layout2> & b)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 >
operator <(const structured_pair<FirstType,SecondType,Info,Layout1> & a,const structured_pair<FirstType,SecondType,Info,Layout2> & b)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 >
operator <=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,const structured_pair<FirstType,SecondType,Info,Layout2> & b)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 >
operator >(const structured_pair<FirstType,SecondType,Info,Layout1> & a,const structured_pair<FirstType,SecondType,Info,Layout2> & b)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 >
operator >=(const structured_pair<FirstType,SecondType,Info,Layout1> & a,const structured_pair<FirstType,SecondType,Info,Layout2> & b)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 >
operator ==(const structured_pair<FirstType,SecondType,Info,Layout> & a,const std::pair<F,S> & b)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 >
operator !=(const structured_pair<FirstType,SecondType,Info,Layout> & a,const std::pair<F,S> & b)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 >
operator <(const structured_pair<FirstType,SecondType,Info,Layout> & a,const std::pair<F,S> & b)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 >
operator <=(const structured_pair<FirstType,SecondType,Info,Layout> & a,const std::pair<F,S> & b)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 >
operator >(const structured_pair<FirstType,SecondType,Info,Layout> & a,const std::pair<F,S> & b)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 >
operator >=(const structured_pair<FirstType,SecondType,Info,Layout> & a,const std::pair<F,S> & b)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 >
operator ==(const std::pair<F,S> & a,const structured_pair<FirstType,SecondType,Info,Layout> & b)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 >
operator !=(const std::pair<F,S> & a,const structured_pair<FirstType,SecondType,Info,Layout> & b)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 >
operator <(const std::pair<F,S> & a,const structured_pair<FirstType,SecondType,Info,Layout> & b)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 >
operator <=(const std::pair<F,S> & a,const structured_pair<FirstType,SecondType,Info,Layout> & b)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 >
operator >(const std::pair<F,S> & a,const structured_pair<FirstType,SecondType,Info,Layout> & b)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 >
operator >=(const std::pair<F,S> & a,const structured_pair<FirstType,SecondType,Info,Layout> & b)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>
copy_with_first_replaced(structured_pair<FirstType,SecondType,Info,Layout> const & p,BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME structured_pair<FirstType,SecondType,Info,Layout>::first_type>::param_type f)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>
copy_with_first_replaced(structured_pair<FirstType,SecondType,::boost::mpl::na,Layout> const & p,BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>::first_type>::param_type f)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>
copy_with_second_replaced(structured_pair<FirstType,SecondType,Info,Layout> const & p,BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME structured_pair<FirstType,SecondType,Info,Layout>::second_type>::param_type s)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>
copy_with_second_replaced(structured_pair<FirstType,SecondType,::boost::mpl::na,Layout> const & p,BOOST_DEDUCED_TYPENAME::boost::call_traits<BOOST_DEDUCED_TYPENAME structured_pair<FirstType,SecondType,::boost::mpl::na,Layout>::second_type>::param_type s)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