1 | |
2 | // (C) Copyright Edward Diener 2011,2012,2013 |
3 | // Use, modification and distribution are subject to the Boost Software License, |
4 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
5 | // http://www.boost.org/LICENSE_1_0.txt). |
6 | |
7 | #if !defined(BOOST_TTI_MEMBER_TYPE_HPP) |
8 | #define BOOST_TTI_MEMBER_TYPE_HPP |
9 | |
10 | #include <boost/config.hpp> |
11 | #include <boost/mpl/eval_if.hpp> |
12 | #include <boost/mpl/identity.hpp> |
13 | #include <boost/mpl/not.hpp> |
14 | #include <boost/type_traits/is_same.hpp> |
15 | #include <boost/preprocessor/cat.hpp> |
16 | #include <boost/tti/gen/member_type_gen.hpp> |
17 | #include <boost/tti/gen/namespace_gen.hpp> |
18 | #include <boost/tti/detail/dmem_type.hpp> |
19 | #include <boost/tti/detail/dnotype.hpp> |
20 | |
21 | /* |
22 | |
23 | The succeeding comments in this file are in doxygen format. |
24 | |
25 | */ |
26 | |
27 | /** \file |
28 | */ |
29 | |
30 | /// Expands to a metafunction whose typedef 'type' is either the named type or a marker type. |
31 | /** |
32 | |
33 | trait = the name of the metafunction within the tti namespace. |
34 | |
35 | name = the name of the inner type. |
36 | |
37 | generates a metafunction called "trait" where 'trait' is the macro parameter. |
38 | |
39 | template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = boost::tti::detail::notype> |
40 | struct trait |
41 | { |
42 | typedef unspecified type; |
43 | |
44 | typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; |
45 | }; |
46 | |
47 | The metafunction types and return: |
48 | |
49 | BOOST_TTI_TP_T = the enclosing type. |
50 | BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type. |
51 | defaults to the internal boost::tti::detail::notype. |
52 | |
53 | returns = 'type' is the inner type of 'name' if the inner type exists |
54 | within the enclosing type, else 'type' is a marker type. |
55 | if the end-user does not specify a marker type then |
56 | an internal boost::tti::detail::notype marker type is used. |
57 | |
58 | The metafunction also encapsulates the type of the marker type as |
59 | a nested 'boost_tti_marker_type'. |
60 | |
61 | The purpose of this macro is to encapsulate the 'name' type as the typedef 'type' |
62 | of a metafunction, but only if it exists within the enclosing type. This allows for |
63 | an evaluation of inner type existence, without generating a compiler error, |
64 | which can be used by other metafunctions in this library. |
65 | |
66 | */ |
67 | #define BOOST_TTI_TRAIT_MEMBER_TYPE(trait,name) \ |
68 | BOOST_TTI_DETAIL_TRAIT_HAS_TYPE_MEMBER_TYPE(trait,name) \ |
69 | BOOST_TTI_DETAIL_TRAIT_MEMBER_TYPE(trait,name) \ |
70 | template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = BOOST_TTI_NAMESPACE::detail::notype> \ |
71 | struct trait : \ |
72 | boost::mpl::eval_if \ |
73 | < \ |
74 | BOOST_PP_CAT(trait,_detail)<BOOST_TTI_TP_T>, \ |
75 | BOOST_PP_CAT(trait,_detail_member_type)<BOOST_TTI_TP_T>, \ |
76 | boost::mpl::identity<BOOST_TTI_TP_MARKER_TYPE> \ |
77 | > \ |
78 | { \ |
79 | typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; \ |
80 | }; \ |
81 | /**/ |
82 | |
83 | /// Expands to a metafunction whose typedef 'type' is either the named type or a marker type. |
84 | /** |
85 | |
86 | name = the name of the inner type. |
87 | |
88 | generates a metafunction called "member_type_name" where 'name' is the macro parameter. |
89 | |
90 | template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = boost::tti::detail::notype> |
91 | struct member_type_name |
92 | { |
93 | typedef unspecified type; |
94 | |
95 | typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; |
96 | }; |
97 | |
98 | The metafunction types and return: |
99 | |
100 | BOOST_TTI_TP_T = the enclosing type. |
101 | BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type. |
102 | defaults to the internal boost::tti::detail::notype. |
103 | |
104 | returns = 'type' is the inner type of 'name' if the inner type exists |
105 | within the enclosing type, else 'type' is a marker type. |
106 | if the end-user does not specify a marker type then |
107 | an internal boost::tti::detail::notype marker type is used. |
108 | |
109 | The metafunction also encapsulates the type of the marker type as |
110 | a nested 'boost_tti_marker_type'. |
111 | |
112 | The purpose of this macro is to encapsulate the 'name' type as the typedef 'type' |
113 | of a metafunction, but only if it exists within the enclosing type. This allows for |
114 | an evaluation of inner type existence, without generating a compiler error, |
115 | which can be used by other metafunctions in this library. |
116 | |
117 | */ |
118 | #define BOOST_TTI_MEMBER_TYPE(name) \ |
119 | BOOST_TTI_TRAIT_MEMBER_TYPE \ |
120 | ( \ |
121 | BOOST_TTI_MEMBER_TYPE_GEN(name), \ |
122 | name \ |
123 | ) \ |
124 | /**/ |
125 | |
126 | namespace boost |
127 | { |
128 | namespace tti |
129 | { |
130 | |
131 | /// A metafunction which checks whether the member 'type' returned from invoking the macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ) is a valid type. |
132 | /** |
133 | |
134 | template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = boost::tti::detail::notype> |
135 | struct valid_member_type |
136 | { |
137 | static const value = unspecified; |
138 | typedef mpl::bool_<true-or-false> type; |
139 | }; |
140 | |
141 | The metafunction types and return: |
142 | |
143 | BOOST_TTI_TP_T = returned inner 'type' from invoking the macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ). |
144 | BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type. |
145 | defaults to the internal boost::tti::detail::notype. |
146 | |
147 | returns = 'value' is true if the type is valid, otherwise 'value' is false. |
148 | A valid type means that the returned inner 'type' is not the marker type. |
149 | |
150 | */ |
151 | template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = BOOST_TTI_NAMESPACE::detail::notype> |
152 | struct valid_member_type : |
153 | boost::mpl::not_ |
154 | < |
155 | boost::is_same<BOOST_TTI_TP_T,BOOST_TTI_TP_MARKER_TYPE> |
156 | > |
157 | { |
158 | }; |
159 | |
160 | /// A metafunction which checks whether the invoked macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ) hold a valid type. |
161 | /** |
162 | |
163 | template<class TTI_METAFUNCTION> |
164 | struct valid_member_metafunction |
165 | { |
166 | static const value = unspecified; |
167 | typedef mpl::bool_<true-or-false> type; |
168 | }; |
169 | |
170 | The metafunction types and return: |
171 | |
172 | TTI_METAFUNCTION = The invoked macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ). |
173 | |
174 | returns = 'value' is true if the nested type of the invoked metafunction is valid, otherwise 'value' is false. |
175 | A valid type means that the invoked metafunction's inner 'type' is not the marker type. |
176 | |
177 | */ |
178 | template<class TTI_METAFUNCTION> |
179 | struct valid_member_metafunction : |
180 | boost::mpl::not_ |
181 | < |
182 | boost::is_same<typename TTI_METAFUNCTION::type,typename TTI_METAFUNCTION::boost_tti_marker_type> |
183 | > |
184 | { |
185 | }; |
186 | } |
187 | } |
188 | |
189 | #endif // BOOST_TTI_MEMBER_TYPE_HPP |
190 | |