1 2 #if !defined(BOOST_PP_IS_ITERATING) 3 4 ///// header body 5 6 //----------------------------------------------------------------------------- 7 // boost variant/detail/substitute.hpp header file 8 // See http://www.boost.org for updates, documentation, and revision history. 9 //----------------------------------------------------------------------------- 10 // 11 // Copyright (c) 2003 12 // Eric Friedman 13 // 14 // Distributed under the Boost Software License, Version 1.0. (See 15 // accompanying file LICENSE_1_0.txt or copy at 16 // http://www.boost.org/LICENSE_1_0.txt) 17 18 #ifndef BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP 19 #define BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP 20 21 #include <boost/mpl/aux_/config/ctps.hpp> 22 23 #include <boost/variant/detail/substitute_fwd.hpp> 24 #include <boost/variant/variant_fwd.hpp> // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES 25 #include <boost/mpl/aux_/lambda_arity_param.hpp> 26 #include <boost/mpl/aux_/preprocessor/params.hpp> 27 #include <boost/mpl/aux_/preprocessor/repeat.hpp> 28 #include <boost/mpl/int_fwd.hpp> 29 #include <boost/mpl/limits/arity.hpp> 30 #include <boost/preprocessor/cat.hpp> 31 #include <boost/preprocessor/empty.hpp> 32 #include <boost/preprocessor/arithmetic/inc.hpp> 33 #include <boost/preprocessor/iterate.hpp> 34 35 namespace boost { 36 namespace detail { namespace variant { 37 38 #if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) 39 40 /////////////////////////////////////////////////////////////////////////////// 41 // (detail) metafunction substitute 42 // 43 // Substitutes one type for another in the given type expression. 44 // 45 46 // 47 // primary template 48 // 49 template < 50 typename T, typename Dest, typename Source 51 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM( 52 typename Arity /* = ... (see substitute_fwd.hpp) */ 53 ) 54 > 55 struct substitute 56 { 57 typedef T type; 58 }; 59 60 // 61 // tag substitution specializations 62 // 63 64 #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(CV_) \ 65 template <typename Dest, typename Source> \ 66 struct substitute< \ 67 CV_ Source \ 68 , Dest \ 69 , Source \ 70 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \ 71 > \ 72 { \ 73 typedef CV_ Dest type; \ 74 }; \ 75 /**/ 76 77 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG( BOOST_PP_EMPTY() ) 78 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const) 79 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(volatile) 80 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const volatile) 81 82 #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG 83 84 // 85 // pointer specializations 86 // 87 #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(CV_) \ 88 template <typename T, typename Dest, typename Source> \ 89 struct substitute< \ 90 T * CV_ \ 91 , Dest \ 92 , Source \ 93 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \ 94 > \ 95 { \ 96 typedef typename substitute< \ 97 T, Dest, Source \ 98 >::type * CV_ type; \ 99 }; \ 100 /**/ 101 102 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER( BOOST_PP_EMPTY() ) 103 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const) 104 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(volatile) 105 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const volatile) 106 107 #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER 108 109 // 110 // reference specializations 111 // 112 template <typename T, typename Dest, typename Source> 113 struct substitute< 114 T& 115 , Dest 116 , Source 117 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) 118 > 119 { 120 typedef typename substitute< 121 T, Dest, Source 122 >::type & type; 123 }; 124 125 // 126 // template expression (i.e., F<...>) specializations 127 // 128 129 #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) 130 template < 131 template <typename...> class F 132 , typename... Ts 133 , typename Dest 134 , typename Source 135 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity) 136 > 137 struct substitute< 138 F<Ts...> 139 , Dest 140 , Source 141 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity) 142 > 143 { 144 typedef F<typename substitute< 145 Ts, Dest, Source 146 >::type...> type; 147 }; 148 149 // 150 // function specializations 151 // 152 template < 153 typename R 154 , typename... A 155 , typename Dest 156 , typename Source 157 > 158 struct substitute< 159 R (*)(A...) 160 , Dest 161 , Source 162 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) 163 > 164 { 165 private: 166 typedef typename substitute< R, Dest, Source >::type r; 167 168 public: 169 typedef r (*type)(typename substitute< 170 A, Dest, Source 171 >::type...); 172 }; 173 #else 174 175 #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL(N) \ 176 typedef typename substitute< \ 177 BOOST_PP_CAT(U,N), Dest, Source \ 178 >::type BOOST_PP_CAT(u,N); \ 179 /**/ 180 181 #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF(z, N, _) \ 182 BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL( BOOST_PP_INC(N) ) \ 183 /**/ 184 185 #define BOOST_PP_ITERATION_LIMITS (0,BOOST_MPL_LIMIT_METAFUNCTION_ARITY) 186 #define BOOST_PP_FILENAME_1 <boost/variant/detail/substitute.hpp> 187 #include BOOST_PP_ITERATE() 188 189 #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL 190 #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF 191 192 #endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) 193 #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) 194 195 }} // namespace detail::variant 196 } // namespace boost 197 198 #endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP 199 200 ///// iteration, depth == 1 201 202 #elif BOOST_PP_ITERATION_DEPTH() == 1 203 #define i BOOST_PP_FRAME_ITERATION(1) 204 205 #if i > 0 206 207 // 208 // template specializations 209 // 210 template < 211 template < BOOST_MPL_PP_PARAMS(i,typename P) > class T 212 , BOOST_MPL_PP_PARAMS(i,typename U) 213 , typename Dest 214 , typename Source 215 > 216 struct substitute< 217 T< BOOST_MPL_PP_PARAMS(i,U) > 218 , Dest 219 , Source 220 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<( i )>) 221 > 222 { 223 private: 224 BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _) 225 226 public: 227 typedef T< BOOST_MPL_PP_PARAMS(i,u) > type; 228 }; 229 230 // 231 // function specializations 232 // 233 template < 234 typename R 235 , BOOST_MPL_PP_PARAMS(i,typename U) 236 , typename Dest 237 , typename Source 238 > 239 struct substitute< 240 R (*)( BOOST_MPL_PP_PARAMS(i,U) ) 241 , Dest 242 , Source 243 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) 244 > 245 { 246 private: 247 typedef typename substitute< R, Dest, Source >::type r; 248 BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _) 249 250 public: 251 typedef r (*type)( BOOST_MPL_PP_PARAMS(i,u) ); 252 }; 253 254 #elif i == 0 255 256 // 257 // zero-arg function specialization 258 // 259 template < 260 typename R, typename Dest, typename Source 261 > 262 struct substitute< 263 R (*)( void ) 264 , Dest 265 , Source 266 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) 267 > 268 { 269 private: 270 typedef typename substitute< R, Dest, Source >::type r; 271 272 public: 273 typedef r (*type)( void ); 274 }; 275 276 #endif // i 277 278 #undef i 279 #endif // BOOST_PP_IS_ITERATING 280