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 #endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) 149 150 #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL(N) \ 151 typedef typename substitute< \ 152 BOOST_PP_CAT(U,N), Dest, Source \ 153 >::type BOOST_PP_CAT(u,N); \ 154 /**/ 155 156 #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF(z, N, _) \ 157 BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL( BOOST_PP_INC(N) ) \ 158 /**/ 159 160 #define BOOST_PP_ITERATION_LIMITS (0,BOOST_MPL_LIMIT_METAFUNCTION_ARITY) 161 #define BOOST_PP_FILENAME_1 <boost/variant/detail/substitute.hpp> 162 #include BOOST_PP_ITERATE() 163 164 #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL 165 #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF 166 167 #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) 168 169 }} // namespace detail::variant 170 } // namespace boost 171 172 #endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP 173 174 ///// iteration, depth == 1 175 176 #elif BOOST_PP_ITERATION_DEPTH() == 1 177 #define i BOOST_PP_FRAME_ITERATION(1) 178 179 #if i > 0 180 181 // 182 // template specializations 183 // 184 template < 185 template < BOOST_MPL_PP_PARAMS(i,typename P) > class T 186 , BOOST_MPL_PP_PARAMS(i,typename U) 187 , typename Dest 188 , typename Source 189 > 190 struct substitute< 191 T< BOOST_MPL_PP_PARAMS(i,U) > 192 , Dest 193 , Source 194 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<( i )>) 195 > 196 { 197 private: 198 BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _) 199 200 public: 201 typedef T< BOOST_MPL_PP_PARAMS(i,u) > type; 202 }; 203 204 // 205 // function specializations 206 // 207 template < 208 typename R 209 , BOOST_MPL_PP_PARAMS(i,typename U) 210 , typename Dest 211 , typename Source 212 > 213 struct substitute< 214 R (*)( BOOST_MPL_PP_PARAMS(i,U) ) 215 , Dest 216 , Source 217 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) 218 > 219 { 220 private: 221 typedef typename substitute< R, Dest, Source >::type r; 222 BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _) 223 224 public: 225 typedef r (*type)( BOOST_MPL_PP_PARAMS(i,u) ); 226 }; 227 228 #elif i == 0 229 230 // 231 // zero-arg function specialization 232 // 233 template < 234 typename R, typename Dest, typename Source 235 > 236 struct substitute< 237 R (*)( void ) 238 , Dest 239 , Source 240 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) 241 > 242 { 243 private: 244 typedef typename substitute< R, Dest, Source >::type r; 245 246 public: 247 typedef r (*type)( void ); 248 }; 249 250 #endif // i 251 252 #undef i 253 #endif // BOOST_PP_IS_ITERATING 254