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/support/member_with_tag.hpp 10 /// \brief member_with_tag<tag,relation> metafunction 11 12 #ifndef BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP 13 #define BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP 14 15 #if defined(_MSC_VER) 16 #pragma once 17 #endif 18 19 #include <boost/config.hpp> 20 21 #include <boost/bimap/relation/member_at.hpp> 22 #include <boost/bimap/detail/debug/static_error.hpp> 23 #include <boost/utility/enable_if.hpp> 24 #include <boost/type_traits/is_same.hpp> 25 #include <boost/mpl/bool.hpp> 26 #include <boost/mpl/not.hpp> 27 #include <boost/mpl/and.hpp> 28 29 /** \struct boost::bimaps::relation::support::member_with_tag 30 31 \brief Metafunction to convert user tags to the member_at idiom. 32 33 \code 34 35 template< class Tag, class Relation > 36 struct member_with_tag 37 { 38 typedef member_at::{side} type; 39 }; 40 41 \endcode 42 43 We have to allow that all the metafunctions that works with tags 44 and retrieves data from a Relation will work with member_at idiom 45 even if the type was tagged. This will be great for the user, 46 because he can choose to tag a member after he is using the 47 relation and the code will still work. 48 49 If we perform this check in every metafunction it will be very 50 tedious and error prone, so instead of that all metafunctions 51 that works with relations first call this metafunction that 52 convert the tag to a member_at tag. 53 54 See also member_at, is_tag_of_member_at_left, is_tag_of_member_at_right. 55 \ingroup relation_group 56 **/ 57 58 #ifndef BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES 59 60 namespace boost { 61 namespace bimaps { 62 namespace relation { 63 namespace support { 64 65 template 66 < 67 class Tag, 68 class Relation, 69 class Enable = void 70 > 71 struct member_with_tag 72 { 73 BOOST_BIMAP_STATIC_ERROR( MEMBER_WITH_TAG_FAILURE, (Relation,Tag) ); 74 }; 75 76 template< class Relation > 77 struct member_with_tag 78 < 79 member_at::left, Relation, void 80 > 81 { 82 typedef member_at::left type; 83 }; 84 85 template< class Relation > 86 struct member_with_tag 87 < 88 member_at::right, Relation, void 89 > 90 { 91 typedef member_at::right type; 92 }; 93 94 template< class Relation > 95 struct member_with_tag 96 < 97 member_at::info, Relation, void 98 > 99 { 100 typedef member_at::info type; 101 }; 102 103 104 template< class Tag, class Relation > 105 struct member_with_tag 106 < 107 Tag, Relation, 108 BOOST_DEDUCED_TYPENAME enable_if 109 < 110 mpl::and_ 111 < 112 mpl::not_< is_same<Tag,member_at::left> >, 113 is_same 114 < 115 Tag, 116 BOOST_DEDUCED_TYPENAME Relation::left_tag 117 > 118 > 119 120 >::type 121 > 122 { 123 typedef member_at::left type; 124 }; 125 126 template< class Tag, class Relation > 127 struct member_with_tag 128 < 129 Tag, 130 Relation, 131 BOOST_DEDUCED_TYPENAME enable_if 132 < 133 mpl::and_ 134 < 135 mpl::not_< is_same<Tag,member_at::right> >, 136 is_same 137 < 138 Tag, 139 BOOST_DEDUCED_TYPENAME Relation::right_tag 140 > 141 > 142 143 >::type 144 > 145 { 146 typedef member_at::right type; 147 }; 148 149 template< class Tag, class Relation > 150 struct member_with_tag 151 < 152 Tag, Relation, 153 BOOST_DEDUCED_TYPENAME enable_if 154 < 155 mpl::and_ 156 < 157 mpl::not_< is_same<Tag,member_at::info> >, 158 is_same 159 < 160 Tag, 161 BOOST_DEDUCED_TYPENAME Relation::info_tag 162 > 163 > 164 165 >::type 166 > 167 { 168 typedef member_at::info type; 169 }; 170 171 } // namespace support 172 } // namespace relation 173 } // namespace bimaps 174 } // namespace boost 175 176 #endif // BOOST_BIMAP_DOXYGEN_WILL_NOT_PROCESS_THE_FOLLOWING_LINES 177 178 #endif // BOOST_BIMAP_RELATION_SUPPORT_MEMBER_WITH_TAG_HPP 179 180 181