97fe2054bcf27df12b79be50f06dedc2f312cb22
[platform/upstream/boost.git] / boost / variant / detail / substitute.hpp
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/mpl/aux_/lambda_arity_param.hpp"
25 #include "boost/mpl/aux_/preprocessor/params.hpp"
26 #include "boost/mpl/aux_/preprocessor/repeat.hpp"
27 #include "boost/mpl/int_fwd.hpp"
28 #include "boost/mpl/limits/arity.hpp"
29 #include "boost/preprocessor/cat.hpp"
30 #include "boost/preprocessor/empty.hpp"
31 #include "boost/preprocessor/arithmetic/inc.hpp"
32 #include "boost/preprocessor/iterate.hpp"
33
34 namespace boost {
35 namespace detail { namespace variant {
36
37 #if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
38
39 ///////////////////////////////////////////////////////////////////////////////
40 // (detail) metafunction substitute
41 //
42 // Substitutes one type for another in the given type expression.
43 //
44
45 //
46 // primary template
47 //
48 template <
49       typename T, typename Dest, typename Source
50       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(
51           typename Arity /* = ... (see substitute_fwd.hpp) */
52         )
53     >
54 struct substitute
55 {
56     typedef T type;
57 };
58
59 //
60 // tag substitution specializations
61 //
62
63 #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(CV_) \
64     template <typename Dest, typename Source> \
65     struct substitute< \
66           CV_ Source \
67         , Dest \
68         , Source \
69           BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \
70         > \
71     { \
72         typedef CV_ Dest type; \
73     }; \
74     /**/
75
76 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG( BOOST_PP_EMPTY() )
77 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const)
78 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(volatile)
79 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const volatile)
80
81 #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG
82
83 //
84 // pointer specializations
85 //
86 #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(CV_) \
87     template <typename T, typename Dest, typename Source> \
88     struct substitute< \
89           T * CV_ \
90         , Dest \
91         , Source \
92           BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \
93         > \
94     { \
95         typedef typename substitute< \
96               T, Dest, Source \
97             >::type * CV_ type; \
98     }; \
99     /**/
100
101 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER( BOOST_PP_EMPTY() )
102 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const)
103 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(volatile)
104 BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const volatile)
105
106 #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER
107
108 //
109 // reference specializations
110 //
111 template <typename T, typename Dest, typename Source>
112 struct substitute<
113       T&
114     , Dest
115     , Source
116       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
117     >
118 {
119     typedef typename substitute<
120           T, Dest, Source
121         >::type & type;
122 };
123
124 //
125 // template expression (i.e., F<...>) specializations
126 //
127
128 #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL(N) \
129     typedef typename substitute< \
130           BOOST_PP_CAT(U,N), Dest, Source \
131         >::type BOOST_PP_CAT(u,N); \
132     /**/
133
134 #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF(z, N, _) \
135     BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL( BOOST_PP_INC(N) ) \
136     /**/
137
138 #define BOOST_PP_ITERATION_LIMITS (0,BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
139 #define BOOST_PP_FILENAME_1 "boost/variant/detail/substitute.hpp"
140 #include BOOST_PP_ITERATE()
141
142 #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL
143 #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF
144
145 #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
146
147 }} // namespace detail::variant
148 } // namespace boost
149
150 #endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
151
152 ///// iteration, depth == 1
153
154 #elif BOOST_PP_ITERATION_DEPTH() == 1
155 #define i BOOST_PP_FRAME_ITERATION(1)
156
157 #if i > 0
158
159 //
160 // template specializations
161 //
162 template <
163       template < BOOST_MPL_PP_PARAMS(i,typename P) > class T
164     , BOOST_MPL_PP_PARAMS(i,typename U)
165     , typename Dest
166     , typename Source
167     >
168 struct substitute<
169       T< BOOST_MPL_PP_PARAMS(i,U) >
170     , Dest
171     , Source
172       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<( i )>)
173     >
174 {
175 private:
176     BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _)
177
178 public:
179     typedef T< BOOST_MPL_PP_PARAMS(i,u) > type;
180 };
181
182 //
183 // function specializations
184 //
185 template <
186       typename R
187     , BOOST_MPL_PP_PARAMS(i,typename U)
188     , typename Dest
189     , typename Source
190     >
191 struct substitute<
192       R (*)( BOOST_MPL_PP_PARAMS(i,U) )
193     , Dest
194     , Source
195       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
196     >
197 {
198 private:
199     typedef typename substitute< R, Dest, Source >::type r;
200     BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _)
201
202 public:
203     typedef r (*type)( BOOST_MPL_PP_PARAMS(i,u) );
204 };
205
206 #elif i == 0
207
208 //
209 // zero-arg function specialization
210 //
211 template <
212       typename R, typename Dest, typename Source
213     >
214 struct substitute<
215       R (*)( void )
216     , Dest
217     , Source
218       BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
219     >
220 {
221 private:
222     typedef typename substitute< R, Dest, Source >::type r;
223
224 public:
225     typedef r (*type)( void );
226 };
227
228 #endif // i
229
230 #undef i
231 #endif // BOOST_PP_IS_ITERATING