Chris@16: // Boost.Bimap Chris@16: // Chris@16: // Copyright (c) 2006-2007 Matias Capeletto Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: /// \file relation/structured_pair.hpp Chris@16: /// \brief Defines the structured_pair class. Chris@16: Chris@16: #ifndef BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP Chris@16: #define BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP Chris@16: Chris@101: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@16: Chris@16: namespace boost { Chris@16: namespace bimaps { Chris@16: namespace relation { Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: /// \brief Storage definition of the left view of a mutant relation. Chris@16: /** Chris@16: Chris@16: See also storage_finder, mirror_storage. Chris@16: **/ Chris@16: Chris@16: template< class FirstType, class SecondType > Chris@16: class normal_storage : Chris@16: public symmetrical_base Chris@16: { Chris@16: typedef symmetrical_base base_; Chris@16: Chris@16: public: Chris@16: Chris@16: typedef normal_storage storage_; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME base_::left_value_type first_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_::right_value_type second_type; Chris@16: Chris@16: first_type first; Chris@16: second_type second; Chris@16: Chris@16: normal_storage() {} Chris@16: Chris@16: normal_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits< Chris@16: first_type >::param_type f, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::call_traits< Chris@16: second_type>::param_type s) Chris@16: Chris@16: : first(f), second(s) {} Chris@16: Chris@16: BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left() { return first; } Chris@16: const BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left()const { return first; } Chris@16: BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right() { return second; } Chris@16: const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return second; } Chris@16: }; Chris@16: Chris@16: /// \brief Storage definition of the right view of a mutant relation. Chris@16: /** Chris@16: Chris@16: See also storage_finder, normal_storage. Chris@16: **/ Chris@16: Chris@16: template< class FirstType, class SecondType > Chris@16: class mirror_storage : Chris@16: public symmetrical_base Chris@16: { Chris@16: typedef symmetrical_base base_; Chris@16: Chris@16: public: Chris@16: Chris@16: typedef mirror_storage storage_; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME base_::left_value_type second_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME base_::right_value_type first_type; Chris@16: Chris@16: second_type second; Chris@16: first_type first; Chris@16: Chris@16: mirror_storage() {} Chris@16: Chris@16: mirror_storage(BOOST_DEDUCED_TYPENAME ::boost::call_traits::param_type f, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::call_traits::param_type s) Chris@16: Chris@16: : second(s), first(f) {} Chris@16: Chris@16: BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left() { return second; } Chris@16: const BOOST_DEDUCED_TYPENAME base_:: left_value_type & get_left()const { return second; } Chris@16: BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right() { return first; } Chris@16: const BOOST_DEDUCED_TYPENAME base_::right_value_type & get_right()const { return first; } Chris@16: }; Chris@16: Chris@16: /** \struct boost::bimaps::relation::storage_finder Chris@16: \brief Obtain the a storage with the correct layout. Chris@16: Chris@16: \code Chris@16: template< class FirstType, class SecondType, class Layout > Chris@16: struct storage_finder Chris@16: { Chris@16: typedef {normal/mirror}_storage type; Chris@16: }; Chris@16: \endcode Chris@16: Chris@16: See also normal_storage, mirror_storage. Chris@16: **/ Chris@16: Chris@16: #ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES Chris@16: Chris@16: template Chris@16: < Chris@16: class FirstType, Chris@16: class SecondType, Chris@16: class Layout Chris@16: > Chris@16: struct storage_finder Chris@16: { Chris@16: typedef normal_storage type; Chris@16: }; Chris@16: Chris@16: template Chris@16: < Chris@16: class FirstType, Chris@16: class SecondType Chris@16: > Chris@16: struct storage_finder Chris@16: { Chris@16: typedef mirror_storage type; Chris@16: }; Chris@16: Chris@16: #endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES Chris@16: Chris@16: Chris@16: template< class TA, class TB, class Info, class Layout > Chris@16: class pair_info_hook : Chris@16: public ::boost::bimaps::relation::detail::storage_finder::type Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder::type base_; Chris@16: Chris@16: typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: Chris@16: default_tagged::type tagged_info_type; Chris@16: Chris@16: public: Chris@16: typedef BOOST_DEDUCED_TYPENAME tagged_info_type::value_type info_type; Chris@16: typedef BOOST_DEDUCED_TYPENAME tagged_info_type::tag info_tag; Chris@16: Chris@16: info_type info; Chris@16: Chris@16: protected: Chris@16: Chris@16: pair_info_hook() {} Chris@16: Chris@16: pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits< Chris@16: BOOST_DEDUCED_TYPENAME base_::first_type Chris@16: >::param_type f, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::call_traits< Chris@16: BOOST_DEDUCED_TYPENAME base_::second_type Chris@16: >::param_type s, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::call_traits< Chris@16: info_type Chris@16: >::param_type i = info_type() ) Chris@16: : base_(f,s), info(i) {} Chris@16: Chris@16: template< class Pair > Chris@16: pair_info_hook( const Pair & p) : Chris@16: base_(p.first,p.second), Chris@16: info(p.info) {} Chris@16: Chris@16: template< class Pair > Chris@16: void change_to( const Pair & p ) Chris@16: { Chris@16: base_::first = p.first ; Chris@16: base_::second = p.second; Chris@16: info = p.info ; Chris@16: } Chris@16: Chris@16: void clear_info() Chris@16: { Chris@16: info = info_type(); Chris@16: }; Chris@16: }; Chris@16: Chris@16: template< class TA, class TB, class Layout> Chris@16: class pair_info_hook : Chris@16: public ::boost::bimaps::relation::detail::storage_finder::type Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::storage_finder::type base_; Chris@16: Chris@16: public: Chris@16: typedef ::boost::mpl::na info_type; Chris@16: typedef member_at::info info_tag; Chris@16: Chris@16: protected: Chris@16: Chris@16: pair_info_hook() {} Chris@16: Chris@16: pair_info_hook( BOOST_DEDUCED_TYPENAME ::boost::call_traits< Chris@16: BOOST_DEDUCED_TYPENAME base_::first_type Chris@16: >::param_type f, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::call_traits< Chris@16: BOOST_DEDUCED_TYPENAME base_::second_type Chris@16: >::param_type s) Chris@16: Chris@16: : base_(f,s) {} Chris@16: Chris@16: template< class Pair > Chris@16: pair_info_hook( const Pair & p ) : Chris@16: base_(p.first,p.second) {} Chris@16: Chris@16: template< class Pair > Chris@16: void change_to( const Pair & p ) Chris@16: { Chris@16: base_::first = p.first ; Chris@16: base_::second = p.second; Chris@16: } Chris@16: Chris@16: void clear_info() {}; Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: template< class TA, class TB, class Info, bool FM > Chris@16: class mutant_relation; Chris@16: Chris@16: Chris@16: /// \brief A std::pair signature compatible class that allows you to control Chris@16: /// the internal structure of the data. Chris@16: /** Chris@16: This class allows you to specify the order in wich the two data types will be Chris@16: in the layout of the class. Chris@16: **/ Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout = normal_layout > Chris@16: class structured_pair : Chris@16: Chris@16: public ::boost::bimaps::relation::detail::pair_info_hook Chris@16: < Chris@16: FirstType, SecondType, Chris@16: Info, Chris@16: Layout Chris@16: Chris@16: > Chris@16: Chris@16: { Chris@16: typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::detail::pair_info_hook Chris@16: < Chris@16: FirstType, SecondType, Chris@16: Info, Chris@16: Layout Chris@16: Chris@16: > base_; Chris@16: Chris@16: public: Chris@16: Chris@16: typedef ::boost::mpl::vector3< Chris@16: structured_pair< FirstType, SecondType, Info, normal_layout >, Chris@16: structured_pair< FirstType, SecondType, Info, mirror_layout >, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::mpl::if_< Chris@16: BOOST_DEDUCED_TYPENAME ::boost::is_same::type, Chris@16: mutant_relation< FirstType, SecondType, Info, true >, Chris@16: mutant_relation< SecondType, FirstType, Info, true > Chris@16: >::type Chris@16: Chris@16: > mutant_views; Chris@16: Chris@16: structured_pair() {} Chris@16: Chris@16: structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits< Chris@16: BOOST_DEDUCED_TYPENAME base_::first_type >::param_type f, Chris@16: BOOST_DEDUCED_TYPENAME boost::call_traits< Chris@16: BOOST_DEDUCED_TYPENAME base_::second_type >::param_type s) Chris@16: : base_(f,s) {} Chris@16: Chris@16: structured_pair(BOOST_DEDUCED_TYPENAME boost::call_traits< Chris@16: BOOST_DEDUCED_TYPENAME base_::first_type >::param_type f, Chris@16: BOOST_DEDUCED_TYPENAME boost::call_traits< Chris@16: BOOST_DEDUCED_TYPENAME base_::second_type >::param_type s, Chris@16: BOOST_DEDUCED_TYPENAME boost::call_traits< Chris@16: BOOST_DEDUCED_TYPENAME base_::info_type >::param_type i) Chris@16: : base_(f,s,i) {} Chris@16: Chris@16: template< class OtherLayout > Chris@16: structured_pair( Chris@16: const structured_pair & p) Chris@16: : base_(p) {} Chris@16: Chris@16: template< class OtherLayout > Chris@16: structured_pair& operator=( Chris@16: const structured_pair & p) Chris@16: { Chris@16: base_::change_to(p); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template< class First, class Second > Chris@16: structured_pair(const std::pair & p) : Chris@16: base_(p.first,p.second) Chris@16: {} Chris@16: Chris@16: template< class First, class Second > Chris@16: structured_pair& operator=(const std::pair & p) Chris@16: { Chris@16: base_::first = p.first; Chris@16: base_::second = p.second; Chris@16: base_::clear_info(); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template< class Tag > Chris@16: const BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: Chris@16: result_of::get::type Chris@101: get() const Chris@16: { Chris@16: return ::boost::bimaps::relation::support::get(*this); Chris@16: } Chris@16: Chris@16: template< class Tag > Chris@16: BOOST_DEDUCED_TYPENAME ::boost::bimaps::relation::support:: Chris@16: result_of::get::type Chris@101: get() Chris@16: { Chris@16: return ::boost::bimaps::relation::support::get(*this); Chris@16: } Chris@16: }; Chris@16: Chris@16: // structured_pair - structured_pair Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > Chris@16: bool operator==(const structured_pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first == b.first ) && Chris@16: ( a.second == b.second ) ); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > Chris@16: bool operator!=(const structured_pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ! ( a == b ); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > Chris@16: bool operator<(const structured_pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first < b.first ) || Chris@16: (( a.first == b.first ) && ( a.second < b.second ))); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > Chris@16: bool operator<=(const structured_pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first < b.first ) || Chris@16: (( a.first == b.first ) && ( a.second <= b.second ))); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > Chris@16: bool operator>(const structured_pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first > b.first ) || Chris@16: (( a.first == b.first ) && ( a.second > b.second ))); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout1, class Layout2 > Chris@16: bool operator>=(const structured_pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first > b.first ) || Chris@16: (( a.first == b.first ) && ( a.second >= b.second ))); Chris@16: } Chris@16: Chris@16: // structured_pair - std::pair Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator==(const structured_pair & a, Chris@16: const std::pair & b) Chris@16: { Chris@16: return ( ( a.first == b.first ) && Chris@16: ( a.second == b.second ) ); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator!=(const structured_pair & a, Chris@16: const std::pair & b) Chris@16: { Chris@16: return ! ( a == b ); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator<(const structured_pair & a, Chris@16: const std::pair & b) Chris@16: { Chris@16: return ( ( a.first < b.first ) || Chris@16: (( a.first == b.first ) && ( a.second < b.second ))); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator<=(const structured_pair & a, Chris@16: const std::pair & b) Chris@16: { Chris@16: return ( ( a.first < b.first ) || Chris@16: (( a.first == b.first ) && ( a.second <= b.second ))); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator>(const structured_pair & a, Chris@16: const std::pair & b) Chris@16: { Chris@16: return ( ( a.first > b.first ) || Chris@16: (( a.first == b.first ) && ( a.second > b.second ))); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator>=(const structured_pair & a, Chris@16: const std::pair & b) Chris@16: { Chris@16: return ( ( a.first > b.first ) || Chris@16: (( a.first == b.first ) && ( a.second >= b.second ))); Chris@16: } Chris@16: Chris@16: // std::pair - sturctured_pair Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator==(const std::pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first == b.first ) && Chris@16: ( a.second == b.second ) ); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator!=(const std::pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ! ( a == b ); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator<(const std::pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first < b.first ) || Chris@16: (( a.first == b.first ) && ( a.second < b.second ))); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator<=(const std::pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first < b.first ) || Chris@16: (( a.first == b.first ) && ( a.second <= b.second ))); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator>(const std::pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first > b.first ) || Chris@16: (( a.first == b.first ) && ( a.second > b.second ))); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout, class F, class S > Chris@16: bool operator>=(const std::pair & a, Chris@16: const structured_pair & b) Chris@16: { Chris@16: return ( ( a.first > b.first ) || Chris@16: (( a.first == b.first ) && ( a.second >= b.second ))); Chris@16: } Chris@16: Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout> Chris@16: structured_pair Chris@16: copy_with_first_replaced(structured_pair const& p, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME Chris@16: structured_pair::first_type> Chris@16: ::param_type f) Chris@16: { Chris@16: return structured_pair(f,p.second,p.info); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Layout> Chris@16: structured_pair Chris@16: copy_with_first_replaced(structured_pair const& p, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME Chris@16: structured_pair::first_type> Chris@16: ::param_type f) Chris@16: { Chris@16: return structured_pair(f,p.second); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Info, class Layout> Chris@16: structured_pair Chris@16: copy_with_second_replaced(structured_pair const& p, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME Chris@16: structured_pair::second_type> Chris@16: ::param_type s) Chris@16: { Chris@16: return structured_pair(p.first,s,p.info); Chris@16: } Chris@16: Chris@16: template< class FirstType, class SecondType, class Layout> Chris@16: structured_pair Chris@16: copy_with_second_replaced(structured_pair const& p, Chris@16: BOOST_DEDUCED_TYPENAME ::boost::call_traits< BOOST_DEDUCED_TYPENAME Chris@16: structured_pair::second_type> Chris@16: ::param_type s) Chris@16: { Chris@16: return structured_pair(p.first,s); Chris@16: } Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: Chris@16: } // namespace relation Chris@16: } // namespace bimaps Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_BIMAP_RELATION_STRUCTURED_PAIR_HPP Chris@16: