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