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_DETAIL_TEMPLATE_PARAMS_HPP) 8 #define BOOST_TTI_DETAIL_TEMPLATE_PARAMS_HPP 9 10 #include <boost/config.hpp> 11 #include <boost/mpl/bool.hpp> 12 #include <boost/mpl/eval_if.hpp> 13 #include <boost/mpl/has_xxx.hpp> 14 #include <boost/preprocessor/arithmetic/add.hpp> 15 #include <boost/preprocessor/arithmetic/sub.hpp> 16 #include <boost/preprocessor/array/elem.hpp> 17 #include <boost/preprocessor/cat.hpp> 18 #include <boost/preprocessor/punctuation/comma_if.hpp> 19 #include <boost/preprocessor/repetition/repeat.hpp> 20 #include <boost/preprocessor/repetition/enum.hpp> 21 #include <boost/preprocessor/array/enum.hpp> 22 #include <boost/preprocessor/array/size.hpp> 23 #include <boost/tti/detail/denclosing_type.hpp> 24 #include <boost/tti/gen/namespace_gen.hpp> 25 26 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) 27 28 #define BOOST_TTI_DETAIL_TEMPLATE_PARAMETERS(z,n,args) \ 29 BOOST_PP_ARRAY_ELEM(BOOST_PP_ADD(4,n),args) \ 30 /**/ 31 32 #define BOOST_TTI_DETAIL_HAS_MEMBER_IMPLEMENTATION(args,introspect_macro) \ 33 template \ 34 < \ 35 typename BOOST_TTI_DETAIL_TP_T, \ 36 typename BOOST_TTI_DETAIL_TP_FALLBACK_ \ 37 = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \ 38 > \ 39 struct BOOST_PP_ARRAY_ELEM(0, args) \ 40 { \ 41 private: \ 42 introspect_macro(args) \ 43 public: \ 44 static const bool value \ 45 = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< BOOST_TTI_DETAIL_TP_T >::value; \ 46 typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ 47 < \ 48 BOOST_TTI_DETAIL_TP_T \ 49 >::type type; \ 50 }; \ 51 /**/ 52 53 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 54 55 #define BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE(z,n,args) \ 56 template \ 57 < \ 58 template \ 59 < \ 60 BOOST_PP_ENUM_ ## z \ 61 ( \ 62 BOOST_PP_SUB \ 63 ( \ 64 BOOST_PP_ARRAY_SIZE(args), \ 65 4 \ 66 ), \ 67 BOOST_TTI_DETAIL_TEMPLATE_PARAMETERS, \ 68 args \ 69 ) \ 70 > \ 71 class BOOST_TTI_DETAIL_TM_V \ 72 > \ 73 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \ 74 { \ 75 }; \ 76 /**/ 77 78 #define BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE(args) \ 79 BOOST_PP_REPEAT \ 80 ( \ 81 BOOST_PP_ARRAY_ELEM(2, args), \ 82 BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE, \ 83 args \ 84 ) \ 85 /**/ 86 87 #define BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT(args) \ 88 template< typename U > \ 89 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ 90 { \ 91 BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE(args) \ 92 BOOST_MPL_HAS_MEMBER_REJECT(args, BOOST_PP_NIL) \ 93 BOOST_MPL_HAS_MEMBER_ACCEPT(args, BOOST_PP_NIL) \ 94 BOOST_STATIC_CONSTANT \ 95 ( \ 96 bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \ 97 ); \ 98 typedef boost::mpl::bool_< value > type; \ 99 }; \ 100 /**/ 101 102 #define BOOST_TTI_DETAIL_HAS_MEMBER_WITH_FUNCTION_SFINAE(args) \ 103 BOOST_TTI_DETAIL_HAS_MEMBER_IMPLEMENTATION \ 104 ( \ 105 args, \ 106 BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT \ 107 ) \ 108 /**/ 109 110 #else // !!BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 111 112 #define BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE(z,n,args) \ 113 template \ 114 < \ 115 template \ 116 < \ 117 BOOST_PP_ENUM_ ## z \ 118 ( \ 119 BOOST_PP_SUB \ 120 ( \ 121 BOOST_PP_ARRAY_SIZE(args), \ 122 4 \ 123 ), \ 124 BOOST_TTI_DETAIL_TEMPLATE_PARAMETERS, \ 125 args \ 126 ) \ 127 > \ 128 class BOOST_TTI_DETAIL_TM_U \ 129 > \ 130 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE \ 131 ( \ 132 args, \ 133 n \ 134 ) \ 135 { \ 136 typedef \ 137 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ 138 type; \ 139 }; \ 140 /**/ 141 142 #define BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE(args) \ 143 typedef void \ 144 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \ 145 BOOST_PP_REPEAT \ 146 ( \ 147 BOOST_PP_ARRAY_ELEM(2, args), \ 148 BOOST_TTI_DETAIL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE, \ 149 args \ 150 ) \ 151 /**/ 152 153 #define BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE(args) \ 154 BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args,BOOST_PP_NIL) \ 155 BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args,BOOST_PP_NIL) \ 156 template< typename BOOST_TTI_DETAIL_TP_U > \ 157 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ 158 : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< BOOST_TTI_DETAIL_TP_U > { \ 159 }; \ 160 /**/ 161 162 #define BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE(args) \ 163 BOOST_TTI_DETAIL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE \ 164 ( \ 165 args \ 166 ) \ 167 BOOST_TTI_DETAIL_HAS_MEMBER_IMPLEMENTATION \ 168 ( \ 169 args, \ 170 BOOST_TTI_DETAIL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \ 171 ) \ 172 /**/ 173 174 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 175 176 #else // defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) 177 178 #define BOOST_TTI_DETAIL_SAME(trait,name) \ 179 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF \ 180 ( \ 181 trait, \ 182 name, \ 183 false \ 184 ) \ 185 /**/ 186 187 #define BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tp) \ 188 BOOST_TTI_DETAIL_SAME(trait,name) \ 189 /**/ 190 191 #endif // !BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE 192 193 #define BOOST_TTI_DETAIL_TRAIT_HAS_TEMPLATE_CHECK_PARAMS_OP(trait,name,tpArray) \ 194 BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(BOOST_PP_CAT(trait,_detail),name,tpArray) \ 195 template<class BOOST_TTI_DETAIL_TP_T> \ 196 struct BOOST_PP_CAT(trait,_detail_cp_op) : \ 197 BOOST_PP_CAT(trait,_detail)<BOOST_TTI_DETAIL_TP_T> \ 198 { \ 199 }; \ 200 /**/ 201 202 #define BOOST_TTI_DETAIL_TRAIT_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tpArray) \ 203 BOOST_TTI_DETAIL_TRAIT_HAS_TEMPLATE_CHECK_PARAMS_OP(trait,name,tpArray) \ 204 template<class BOOST_TTI_DETAIL_TP_T> \ 205 struct trait \ 206 { \ 207 typedef typename \ 208 boost::mpl::eval_if \ 209 < \ 210 BOOST_TTI_NAMESPACE::detail::enclosing_type<BOOST_TTI_DETAIL_TP_T>, \ 211 BOOST_PP_CAT(trait,_detail_cp_op)<BOOST_TTI_DETAIL_TP_T>, \ 212 boost::mpl::false_ \ 213 >::type type; \ 214 BOOST_STATIC_CONSTANT(bool,value=type::value); \ 215 }; \ 216 /**/ 217 218 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) 219 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 220 221 #define BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tpArray) \ 222 BOOST_TTI_DETAIL_HAS_MEMBER_WITH_FUNCTION_SFINAE \ 223 ( \ 224 ( BOOST_PP_ADD(BOOST_PP_ARRAY_SIZE(tpArray),4), ( trait, name, 1, false, BOOST_PP_ARRAY_ENUM(tpArray) ) ) \ 225 ) \ 226 /**/ 227 228 #else // BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 229 230 #define BOOST_TTI_DETAIL_TRAIT_CALL_HAS_TEMPLATE_CHECK_PARAMS(trait,name,tpArray) \ 231 BOOST_TTI_DETAIL_HAS_MEMBER_WITH_TEMPLATE_SFINAE \ 232 ( \ 233 ( BOOST_PP_ADD(BOOST_PP_ARRAY_SIZE(tpArray),4), ( trait, name, 1, false, BOOST_PP_ARRAY_ENUM(tpArray) ) ) \ 234 ) \ 235 /**/ 236 237 #endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 238 #endif // !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) 239 240 #endif // BOOST_TTI_DETAIL_TEMPLATE_PARAMS_HPP 241