Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / bimap / relation / support / member_with_tag.hpp
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) && (_MSC_VER>=1200)
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