File indexing completed on 2025-10-30 08:12:12
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 
0012 #ifndef BOOST_BIMAP_RELATION_MUTANT_RELATION_HPP
0013 #define BOOST_BIMAP_RELATION_MUTANT_RELATION_HPP
0014 
0015 #if defined(_MSC_VER)
0016 #pragma once
0017 #endif
0018 
0019 #include <boost/config.hpp>
0020 
0021 #include <boost/mpl/vector.hpp>
0022 #include <boost/operators.hpp>
0023 #include <boost/call_traits.hpp>
0024 
0025 #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
0026   #include <boost/core/serialization.hpp>
0027 #endif 
0028 
0029 #include <boost/functional/hash/hash.hpp>
0030 
0031 #include <boost/mpl/aux_/na.hpp>
0032 
0033 
0034 #include <boost/bimap/tags/tagged.hpp>
0035 #include <boost/bimap/tags/support/default_tagged.hpp>
0036 #include <boost/bimap/tags/support/tag_of.hpp>
0037 #include <boost/bimap/tags/support/value_type_of.hpp>
0038 
0039 #include <boost/bimap/relation/member_at.hpp>
0040 #include <boost/bimap/relation/detail/mutant.hpp>
0041 #include <boost/bimap/relation/structured_pair.hpp>
0042 #include <boost/bimap/relation/symmetrical_base.hpp>
0043 #include <boost/bimap/relation/support/get.hpp>
0044 
0045 namespace boost {
0046 namespace bimaps {
0047 namespace relation {
0048 
0049 namespace detail {
0050 
0051 
0052 
0053 
0054 template< class LeftType, class RightType, bool force_mutable >
0055 class relation_storage :
0056     public symmetrical_base<LeftType,RightType,force_mutable>
0057 {
0058     typedef symmetrical_base<LeftType,RightType,force_mutable> base_;
0059 
0060     typedef relation_storage storage_;
0061 
0062     public:
0063 
0064     typedef relation_storage<LeftType,RightType,false> non_mutable_storage;
0065 
0066     typedef ::boost::mpl::vector2
0067     <
0068         relation_storage< LeftType, RightType, true  >,
0069         relation_storage< LeftType, RightType, false >
0070 
0071     > mutant_views;
0072 
0073     
0074         
0075         BOOST_DEDUCED_TYPENAME base_::left_value_type  left;
0076         BOOST_DEDUCED_TYPENAME base_::right_value_type right;
0077     
0078 
0079     relation_storage() {}
0080 
0081     relation_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0082                          BOOST_DEDUCED_TYPENAME base_::left_value_type
0083                      >::param_type l,
0084                      BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0085                         BOOST_DEDUCED_TYPENAME base_::right_value_type
0086                      >::param_type r)
0087 
0088         : left(l), right(r) {}
0089 
0090           BOOST_DEDUCED_TYPENAME base_:: left_value_type &  get_left()      { return left;  }
0091     const BOOST_DEDUCED_TYPENAME base_:: left_value_type &  get_left()const { return left;  }
0092           BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()      { return right; }
0093     const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return right; }
0094 };
0095 
0096 
0097 
0098 template< class TA, class TB, class Info, bool force_mutable >
0099 class relation_info_hook : public
0100  ::boost::bimaps::relation::detail::relation_storage<TA,TB,force_mutable>
0101 {
0102     typedef ::boost::bimaps::relation::detail::
0103                 relation_storage<TA,TB,force_mutable> base_;
0104 
0105     typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support::
0106         default_tagged<Info,member_at::info>::type tagged_info_type;
0107 
0108     public:
0109     typedef BOOST_DEDUCED_TYPENAME tagged_info_type::value_type info_type;
0110     typedef BOOST_DEDUCED_TYPENAME tagged_info_type::tag        info_tag;
0111 
0112     info_type info;
0113 
0114     protected:
0115 
0116     relation_info_hook() {}
0117 
0118     relation_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0119                            BOOST_DEDUCED_TYPENAME base_::left_value_type
0120                         >::param_type l,
0121                         BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0122                             BOOST_DEDUCED_TYPENAME base_::right_value_type
0123                         >::param_type r,
0124                         BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0125                             info_type
0126                         >::param_type i = info_type() )
0127 
0128         : base_(l,r), info(i) {}
0129 
0130     template< class Relation >
0131     relation_info_hook( const Relation & rel ) :
0132         base_(rel.left,rel.right),
0133         info(rel.info) {}
0134 
0135     template< class Relation >
0136     void change_to( const Relation & rel )
0137     {
0138         base_::left  = rel.left ;
0139         base_::right = rel.right;
0140         info         = rel.info ;
0141     }
0142 
0143     #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
0144     template< class Archive >
0145     void serialize(Archive & ar, const unsigned int)
0146     {
0147         ar & ::boost::serialization::make_nvp("left" , base_::left );
0148         ar & ::boost::serialization::make_nvp("right", base_::right);
0149         ar & ::boost::serialization::make_nvp("info" , info        );
0150     }
0151     #endif 
0152 };
0153 
0154 template< class TA, class TB, bool force_mutable>
0155 class relation_info_hook<TA,TB,::boost::mpl::na,force_mutable> :
0156     public ::boost::bimaps::relation::detail::relation_storage<TA,TB,force_mutable>
0157 {
0158     typedef ::boost::bimaps::relation::detail::
0159                 relation_storage<TA,TB,force_mutable> base_;
0160 
0161     public:
0162     typedef ::boost::mpl::na info_type;
0163     typedef member_at::info info_tag;
0164 
0165     protected:
0166 
0167     relation_info_hook() {}
0168 
0169     relation_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0170                            BOOST_DEDUCED_TYPENAME base_::left_value_type
0171                         >::param_type l,
0172                         BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0173                             BOOST_DEDUCED_TYPENAME base_::right_value_type
0174                         >::param_type r)
0175 
0176         : base_(l,r) {}
0177 
0178     template< class Relation >
0179     relation_info_hook( const Relation & rel ) :
0180         base_(rel.left,rel.right) {}
0181 
0182     template< class Relation >
0183     void change_to( const Relation & rel )
0184     {
0185         base_::left  = rel.left ;
0186         base_::right = rel.right;
0187     }
0188 
0189     #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
0190     template< class Archive >
0191     void serialize(Archive & ar, const unsigned int)
0192     {
0193         ar & ::boost::serialization::make_nvp("left" , base_::left );
0194         ar & ::boost::serialization::make_nvp("right", base_::right);
0195     }
0196     #endif 
0197 };
0198 
0199 
0200 } 
0201 
0202 
0203 
0204 
0205 
0206 
0207 
0208 
0209 
0210 
0211 
0212 
0213 
0214 
0215 
0216 
0217 
0218 
0219 
0220 
0221 
0222 
0223 
0224 
0225 
0226 template< class TA, class TB, class Info = ::boost::mpl::na, bool force_mutable = false >
0227 class mutant_relation : public
0228     ::boost::bimaps::relation::detail::
0229         relation_info_hook<TA,TB,Info,force_mutable>
0230 {
0231     typedef ::boost::bimaps::relation::detail::
0232         relation_info_hook<TA,TB,Info,force_mutable> base_;
0233 
0234     public:
0235 
0236     
0237     
0238 
0239     typedef ::boost::bimaps::relation::detail::
0240                 relation_storage<TA,TB,force_mutable> storage_base;
0241 
0242     
0243 
0244     typedef mutant_relation<TA,TB,Info,false> above_view;
0245 
0246     
0247         
0248 
0249         typedef structured_pair< TA, TB, Info, normal_layout >  left_pair;
0250         typedef structured_pair< TB, TA, Info, mirror_layout > right_pair;
0251     
0252 
0253     typedef ::boost::mpl::vector4
0254     <
0255          left_pair,
0256         right_pair,
0257 
0258         mutant_relation< TA, TB, Info, true  >,
0259         mutant_relation< TA, TB, Info, false >
0260 
0261     > mutant_views;
0262 
0263     mutant_relation() {}
0264 
0265     mutant_relation(BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0266                         BOOST_DEDUCED_TYPENAME base_:: left_value_type
0267                     >::param_type l,
0268                     BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0269                         BOOST_DEDUCED_TYPENAME base_::right_value_type
0270                     >::param_type r) :
0271         base_(l,r) {}
0272 
0273     mutant_relation(BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0274                         BOOST_DEDUCED_TYPENAME base_:: left_value_type
0275                     >::param_type l,
0276                     BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0277                         BOOST_DEDUCED_TYPENAME base_::right_value_type
0278                     >::param_type r,
0279                     BOOST_DEDUCED_TYPENAME ::boost::call_traits<
0280                         BOOST_DEDUCED_TYPENAME base_::info_type
0281                     >::param_type i) :
0282         base_(l,r,i) {}
0283 
0284     mutant_relation(const mutant_relation<TA,TB,Info,false> & rel) :
0285         base_(rel) {}
0286 
0287     mutant_relation(const mutant_relation<TA,TB,Info,true> & rel) :
0288         base_(rel) {}
0289 
0290     
0291 
0292     mutant_relation& operator=(const mutant_relation & rel)
0293     {
0294         base_::change_to(rel);
0295         return *this;
0296     }
0297 
0298     mutant_relation& operator=(const mutant_relation<TA,TB,Info,
0299                                                      !force_mutable> & rel)
0300     {
0301         base_::change_to(rel);
0302         return *this;
0303     }
0304 
0305     
0306     
0307     
0308     
0309 
0310     left_pair & get_left_pair()
0311     {
0312         return ::boost::bimaps::relation::detail::mutate<left_pair>(*this);
0313     }
0314 
0315     const left_pair & get_left_pair() const
0316     {
0317         return ::boost::bimaps::relation::detail::mutate<left_pair>(*this);
0318     }
0319 
0320     right_pair & get_right_pair()
0321     {
0322         return ::boost::bimaps::relation::detail::mutate<right_pair>(*this);
0323     }
0324 
0325     const right_pair & get_right_pair() const
0326     {
0327         return ::boost::bimaps::relation::detail::mutate<right_pair>(*this);
0328     }
0329 
0330     above_view & get_view()
0331     {
0332         return ::boost::bimaps::relation::detail::mutate<above_view>(*this);
0333     }
0334 
0335     const above_view & get_view() const
0336     {
0337         return ::boost::bimaps::relation::detail::mutate<above_view>(*this);
0338     }
0339 
0340     template< class Tag >
0341     const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
0342         result_of::get<Tag,const mutant_relation>::type
0343     get() const
0344     {
0345         return ::boost::bimaps::relation::support::get<Tag>(*this);
0346     }
0347 
0348     template< class Tag >
0349     BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support::
0350         result_of::get<Tag,mutant_relation>::type
0351     get()
0352     {
0353         return ::boost::bimaps::relation::support::get<Tag>(*this);
0354     }
0355     
0356     #ifndef BOOST_BIMAP_DISABLE_SERIALIZATION
0357 
0358     private:
0359     friend class ::boost::serialization::access;
0360 
0361     template<class Archive>
0362     void serialize(Archive & ar, const unsigned int version)
0363     {
0364         base_::serialize(ar,version);
0365     }
0366 
0367     #endif 
0368 };
0369 
0370 
0371 
0372 template< class FirstType, class SecondType, bool FM >
0373 std::size_t hash_value(const detail::relation_storage<FirstType,SecondType,FM> & r)
0374 {
0375     std::size_t seed = 0;
0376     ::boost::hash_combine(seed, r. left );
0377     ::boost::hash_combine(seed, r.right );
0378 
0379     return seed;
0380 }
0381 
0382 
0383 
0384 template< class FirstType, class SecondType, bool FM1, bool FM2 >
0385 bool operator==(const detail::relation_storage<FirstType,SecondType,FM1> & a,
0386                 const detail::relation_storage<FirstType,SecondType,FM2> & b)
0387 {
0388     return ( ( a.left  == b.left  ) &&
0389              ( a.right == b.right ) );
0390 }
0391 
0392 template< class FirstType, class SecondType, bool FM1, bool FM2 >
0393 bool operator!=(const detail::relation_storage<FirstType,SecondType,FM1> & a,
0394                 const detail::relation_storage<FirstType,SecondType,FM2> & b)
0395 {
0396     return ! ( a == b );
0397 }
0398 
0399 template< class FirstType, class SecondType, bool FM1, bool FM2 >
0400 bool operator<(const detail::relation_storage<FirstType,SecondType,FM1> & a,
0401                const detail::relation_storage<FirstType,SecondType,FM2> & b)
0402 {
0403     return (  ( a.left  <  b.left  ) ||
0404              (( a.left == b.left ) && ( a.right < b.right )));
0405 }
0406 
0407 template< class FirstType, class SecondType, bool FM1, bool FM2 >
0408 bool operator<=(const detail::relation_storage<FirstType,SecondType,FM1> & a,
0409                 const detail::relation_storage<FirstType,SecondType,FM2> & b)
0410 {
0411     return (  ( a.left  <  b.left  ) ||
0412              (( a.left == b.left ) && ( a.right <= b.right )));
0413 }
0414 
0415 template< class FirstType, class SecondType, bool FM1, bool FM2 >
0416 bool operator>(const detail::relation_storage<FirstType,SecondType,FM1> & a,
0417                const detail::relation_storage<FirstType,SecondType,FM2> & b)
0418 {
0419     return ( ( a.left  >  b.left  ) ||
0420              (( a.left == b.left ) && ( a.right > b.right )));
0421 }
0422 
0423 template< class FirstType, class SecondType, bool FM1, bool FM2 >
0424 bool operator>=(const detail::relation_storage<FirstType,SecondType,FM1> & a,
0425                 const detail::relation_storage<FirstType,SecondType,FM2> & b)
0426 {
0427     return ( ( a.left  >  b.left  ) ||
0428              (( a.left == b.left ) && ( a.right >= b.right )));
0429 }
0430 
0431 namespace detail {
0432 
0433 template< class TA, class TB, class Info, bool force_mutable>
0434 mutant_relation<TA,TB,Info,force_mutable> 
0435     copy_with_left_replaced(mutant_relation<TA,TB,Info,force_mutable> const& rel,
0436         BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME 
0437             mutant_relation<TA,TB,Info,force_mutable>::left_value_type>
0438                 ::param_type l)
0439 {
0440     return mutant_relation<TA,TB,Info,force_mutable>(l,rel.right,rel.info);
0441 }
0442     
0443 template< class TA, class TB, bool force_mutable>
0444 mutant_relation<TA,TB,::boost::mpl::na,force_mutable>
0445     copy_with_left_replaced(mutant_relation<TA,TB,::boost::mpl::na,force_mutable> const& rel,
0446         BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME 
0447             mutant_relation<TA,TB,::boost::mpl::na,force_mutable>::left_value_type>
0448                 ::param_type l)
0449 {
0450     return mutant_relation<TA,TB,::boost::mpl::na,force_mutable>(l,rel.right);  
0451 }
0452     
0453 template< class TA, class TB, class Info, bool force_mutable>
0454 mutant_relation<TA,TB,Info,force_mutable> 
0455     copy_with_right_replaced(mutant_relation<TA,TB,Info,force_mutable> const& rel,
0456         BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME 
0457             mutant_relation<TA,TB,Info,force_mutable>::right_value_type>
0458                 ::param_type r)
0459 {
0460     return mutant_relation<TA,TB,Info,force_mutable>(rel.left,r,rel.info);
0461 }
0462     
0463 template< class TA, class TB, bool force_mutable>
0464 mutant_relation<TA,TB,::boost::mpl::na,force_mutable>
0465     copy_with_right_replaced(mutant_relation<TA,TB,::boost::mpl::na,force_mutable> const& rel,
0466         BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME 
0467             mutant_relation<TA,TB,::boost::mpl::na,force_mutable>::right_value_type>
0468                 ::param_type r)
0469 {
0470     return mutant_relation<TA,TB,::boost::mpl::na,force_mutable>(rel.left,r);  
0471 }
0472 
0473 } 
0474 
0475 } 
0476 } 
0477 } 
0478 
0479 
0480 #endif 
0481 
0482 
0483