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/mpl/eval_if.hpp> 11 #include <boost/mpl/identity.hpp> 12 #include <boost/mpl/not.hpp> 13 #include <boost/type_traits/is_same.hpp> 14 #include <boost/preprocessor/cat.hpp> 15 #include <boost/tti/gen/member_type_gen.hpp> 16 #include <boost/tti/gen/namespace_gen.hpp> 17 #include <boost/tti/detail/dmem_type.hpp> 18 #include <boost/tti/detail/dnotype.hpp> 19 20 /* 21 22 The succeeding comments in this file are in doxygen format. 23 24 */ 25 26 /** \file 27 */ 28 29 /// A macro expands to a metafunction whose typedef 'type' is either the named type or a marker type. 30 /** 31 32 BOOST_TTI_TRAIT_MEMBER_TYPE is a macro which expands to a metafunction. 33 The metafunction tests whether an inner type with a particular name exists 34 by returning the inner type or a marker type. 35 The macro takes the form of BOOST_TTI_TRAIT_MEMBER_TYPE(trait,name) where 36 37 trait = the name of the metafunction <br/> 38 name = the name of the inner type. 39 40 BOOST_TTI_TRAIT_MEMBER_TYPE generates a metafunction called "trait" where 'trait' is the macro parameter. 41 42 @code 43 44 template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = boost::tti::detail::notype> 45 struct trait 46 { 47 typedef unspecified type; 48 typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; 49 }; 50 51 The metafunction types and return: 52 53 BOOST_TTI_TP_T = the enclosing type. 54 The enclosing type can be a class, struct, or union. 55 56 BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type. 57 defaults to the internal boost::tti::detail::notype. 58 59 returns = 'type' is the inner type of 'name' if the inner type exists 60 within the enclosing type, else 'type' is a marker type. 61 if the end-user does not specify a marker type then 62 an internal boost::tti::detail::notype marker type, 63 which is empty, is used. 64 65 The metafunction also encapsulates the type of the marker type as 66 a nested 'boost_tti_marker_type'. 67 68 @endcode 69 70 The purpose of this macro is to encapsulate the 'name' type as the typedef 'type' 71 of a metafunction, but only if it exists within the enclosing type. This allows for 72 an evaluation of inner type existence, without generating a compiler error, 73 which can be used by other metafunctions in this library. 74 75 */ 76 #define BOOST_TTI_TRAIT_MEMBER_TYPE(trait,name) \ 77 BOOST_TTI_DETAIL_TRAIT_HAS_TYPE_MEMBER_TYPE(trait,name) \ 78 BOOST_TTI_DETAIL_TRAIT_MEMBER_TYPE(trait,name) \ 79 template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = BOOST_TTI_NAMESPACE::detail::notype> \ 80 struct trait : \ 81 boost::mpl::eval_if \ 82 < \ 83 BOOST_PP_CAT(trait,_detail_has_type_member_type)<BOOST_TTI_TP_T>, \ 84 BOOST_PP_CAT(trait,_detail_member_type)<BOOST_TTI_TP_T>, \ 85 boost::mpl::identity<BOOST_TTI_TP_MARKER_TYPE> \ 86 > \ 87 { \ 88 typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; \ 89 }; \ 90 /**/ 91 92 /// A macro which expands to a metafunction whose typedef 'type' is either the named type or a marker type. 93 /** 94 95 BOOST_TTI_MEMBER_TYPE is a macro which expands to a metafunction. 96 The metafunction tests whether an inner type with a particular name exists 97 by returning the inner type or a marker type. 98 The macro takes the form of BOOST_TTI_MEMBER_TYPE(name) where 99 100 name = the name of the inner type. 101 102 BOOST_TTI_MEMBER_TYPE generates a metafunction called "member_type_name" where 'name' is the macro parameter. 103 104 @code 105 106 template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = boost::tti::detail::notype> 107 struct member_type_'name' 108 { 109 typedef unspecified type; 110 typedef BOOST_TTI_TP_MARKER_TYPE boost_tti_marker_type; 111 }; 112 113 The metafunction types and return: 114 115 BOOST_TTI_TP_T = the enclosing type. 116 The enclosing type can be a class, struct, or union. 117 118 BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type. 119 defaults to the internal boost::tti::detail::notype. 120 121 returns = 'type' is the inner type of 'name' if the inner type exists 122 within the enclosing type, else 'type' is a marker type. 123 if the end-user does not specify a marker type then 124 an internal boost::tti::detail::notype marker type is used. 125 126 The metafunction also encapsulates the type of the marker type as 127 a nested 'boost_tti_marker_type'. 128 129 @endcode 130 131 The purpose of this macro is to encapsulate the 'name' type as the typedef 'type' 132 of a metafunction, but only if it exists within the enclosing type. This allows for 133 an evaluation of inner type existence, without generating a compiler error, 134 which can be used by other metafunctions in this library. 135 136 */ 137 #define BOOST_TTI_MEMBER_TYPE(name) \ 138 BOOST_TTI_TRAIT_MEMBER_TYPE \ 139 ( \ 140 BOOST_TTI_MEMBER_TYPE_GEN(name), \ 141 name \ 142 ) \ 143 /**/ 144 145 namespace boost 146 { 147 namespace tti 148 { 149 150 /// 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. 151 /** 152 153 The metafunction 'valid_member_type', which is in the boost::tti namespace, takes the form of: 154 155 @code 156 157 template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = boost::tti::detail::notype> 158 struct valid_member_type 159 { 160 static const value = unspecified; 161 typedef mpl::bool_<true-or-false> type; 162 }; 163 164 The metafunction types and return: 165 166 BOOST_TTI_TP_T = returned inner 'type' from invoking the macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ). 167 168 BOOST_TTI_TP_MARKER_TYPE = (optional) a type to use as the marker type. 169 defaults to the internal boost::tti::detail::notype. 170 171 returns = 'value' is true if the type is valid, otherwise 'value' is false. 172 A valid type means that the returned inner 'type' is not the marker type. 173 174 @endcode 175 176 */ 177 template<class BOOST_TTI_TP_T,class BOOST_TTI_TP_MARKER_TYPE = BOOST_TTI_NAMESPACE::detail::notype> 178 struct valid_member_type : 179 boost::mpl::not_ 180 < 181 boost::is_same<BOOST_TTI_TP_T,BOOST_TTI_TP_MARKER_TYPE> 182 > 183 { 184 }; 185 186 /// A metafunction which checks whether the invoked macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ) hold a valid type. 187 /** 188 189 The metafunction 'valid_member_metafunction', which is in the boost::tti namespace, takes the form of: 190 191 @code 192 193 template<class BOOST_TTI_METAFUNCTION> 194 struct valid_member_metafunction 195 { 196 static const value = unspecified; 197 typedef mpl::bool_<true-or-false> type; 198 }; 199 200 The metafunction types and return: 201 202 BOOST_TTI_METAFUNCTION = The invoked macro metafunction generated by BOOST_TTI_MEMBER_TYPE ( BOOST_TTI_TRAIT_MEMBER_TYPE ). 203 204 returns = 'value' is true if the nested type of the invoked metafunction is valid, otherwise 'value' is false. 205 A valid type means that the invoked metafunction's inner 'type' is not the marker type. 206 207 @endcode 208 209 */ 210 template<class BOOST_TTI_METAFUNCTION> 211 struct valid_member_metafunction : 212 boost::mpl::not_ 213 < 214 boost::is_same<typename BOOST_TTI_METAFUNCTION::type,typename BOOST_TTI_METAFUNCTION::boost_tti_marker_type> 215 > 216 { 217 }; 218 } 219 } 220 221 #endif // BOOST_TTI_MEMBER_TYPE_HPP 222