]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.TypeErasure library |
2 | // | |
3 | // Copyright 2011 Steven Watanabe | |
4 | // | |
5 | // Distributed under the Boost Software License Version 1.0. (See | |
6 | // accompanying file LICENSE_1_0.txt or copy at | |
7 | // http://www.boost.org/LICENSE_1_0.txt) | |
8 | // | |
9 | // $Id$ | |
10 | ||
11 | #if !defined(BOOST_PP_IS_ITERATING) | |
12 | ||
13 | #ifndef BOOST_TYPE_ERASURE_CONSTRUCTIBLE_HPP_INCLUDED | |
14 | #define BOOST_TYPE_ERASURE_CONSTRUCTIBLE_HPP_INCLUDED | |
15 | ||
16 | #include <boost/detail/workaround.hpp> | |
17 | #include <boost/preprocessor/iteration/iterate.hpp> | |
18 | #include <boost/preprocessor/repetition/enum_params.hpp> | |
19 | #include <boost/preprocessor/repetition/enum_binary_params.hpp> | |
20 | #include <boost/preprocessor/repetition/enum_trailing_params.hpp> | |
21 | #include <boost/type_erasure/detail/storage.hpp> | |
22 | #include <boost/type_erasure/call.hpp> | |
23 | #include <boost/type_erasure/concept_interface.hpp> | |
24 | #include <boost/type_erasure/config.hpp> | |
25 | #include <boost/type_erasure/param.hpp> | |
26 | ||
27 | namespace boost { | |
28 | namespace type_erasure { | |
29 | ||
30 | template<class Sig> | |
31 | struct constructible; | |
32 | ||
33 | namespace detail { | |
34 | ||
35 | template<class Sig> | |
36 | struct null_construct; | |
37 | ||
38 | template<class C> | |
39 | struct get_null_vtable_entry; | |
40 | ||
41 | template<class C, class Sig> | |
42 | struct vtable_adapter; | |
43 | ||
44 | }; | |
45 | ||
46 | #ifdef BOOST_TYPE_ERASURE_DOXYGEN | |
47 | ||
48 | /** | |
49 | * The @ref constructible concept enables calling the | |
50 | * constructor of a type contained by an @ref any. | |
51 | * @c Sig should be a function signature. The return | |
52 | * type is the placeholder specifying the type to | |
53 | * be constructed. The arguments are the argument | |
54 | * types of the constructor. The arguments of | |
55 | * @c Sig may be placeholders. | |
56 | * | |
57 | * \note @ref constructible may not be specialized and | |
58 | * may not be passed to \call as it depends on the | |
59 | * implementation details of @ref any. | |
60 | */ | |
61 | template<class Sig> | |
62 | struct constructible {}; | |
63 | ||
64 | #elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ | |
65 | !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ | |
66 | !BOOST_WORKAROUND(BOOST_MSVC, == 1800) | |
67 | ||
68 | template<class R, class... T> | |
69 | struct constructible<R(T...)> | |
70 | { | |
71 | static ::boost::type_erasure::detail::storage | |
72 | apply(T... arg) | |
73 | { | |
74 | ::boost::type_erasure::detail::storage result; | |
75 | result.data = new R(::std::forward<T>(arg)...); | |
76 | return result; | |
77 | } | |
78 | }; | |
79 | ||
80 | /// INTERNAL ONLY | |
81 | template<class Base, class Tag, class... T> | |
82 | struct concept_interface< | |
83 | ::boost::type_erasure::constructible<Tag(T...)>, | |
84 | Base, | |
85 | Tag | |
86 | > : Base | |
87 | { | |
88 | using Base::_boost_type_erasure_deduce_constructor; | |
89 | ::boost::type_erasure::constructible<Tag(T...)>* | |
90 | _boost_type_erasure_deduce_constructor( | |
91 | typename ::boost::type_erasure::as_param<Base, T>::type...) | |
92 | { | |
93 | return 0; | |
94 | } | |
95 | }; | |
96 | ||
97 | namespace detail { | |
98 | ||
99 | template<class... T> | |
100 | struct null_construct<void(T...)> | |
101 | { | |
102 | static ::boost::type_erasure::detail::storage | |
103 | value(T...) | |
104 | { | |
105 | ::boost::type_erasure::detail::storage result; | |
106 | result.data = 0; | |
107 | return result; | |
108 | } | |
109 | }; | |
110 | ||
111 | template<class T, class R, class... U> | |
112 | struct get_null_vtable_entry<vtable_adapter<constructible<T(const T&)>, R(U...)> > | |
113 | { | |
114 | typedef null_construct<void(U...)> type; | |
115 | }; | |
116 | ||
117 | } | |
118 | ||
119 | #else | |
120 | ||
121 | #define BOOST_PP_FILENAME_1 <boost/type_erasure/constructible.hpp> | |
122 | #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY) | |
123 | #include BOOST_PP_ITERATE() | |
124 | ||
125 | #endif | |
126 | ||
127 | } | |
128 | } | |
129 | ||
130 | #endif | |
131 | ||
132 | #else | |
133 | ||
134 | #define N BOOST_PP_ITERATION() | |
135 | ||
136 | #define BOOST_TYPE_ERASURE_ARG_DECL(z, n, data) \ | |
137 | typename ::boost::type_erasure::as_param< \ | |
138 | Base, \ | |
139 | BOOST_PP_CAT(T, n) \ | |
140 | >::type | |
141 | ||
142 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
143 | #define BOOST_TYPE_ERASURE_FORWARD_I(z, n, data) ::std::forward<BOOST_PP_CAT(T, n)>(BOOST_PP_CAT(arg, n)) | |
144 | #define BOOST_TYPE_ERASURE_FORWARD(n) BOOST_PP_ENUM(n, BOOST_TYPE_ERASURE_FORWARD_I, ~) | |
145 | #else | |
146 | #define BOOST_TYPE_ERASURE_FORWARD(n) BOOST_PP_ENUM_PARAMS(n, arg) | |
147 | #endif | |
148 | ||
149 | template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> | |
150 | struct constructible<R(BOOST_PP_ENUM_PARAMS(N, T))> | |
151 | { | |
152 | static ::boost::type_erasure::detail::storage | |
153 | apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg)) | |
154 | { | |
155 | ::boost::type_erasure::detail::storage result; | |
156 | result.data = new R(BOOST_TYPE_ERASURE_FORWARD(N)); | |
157 | return result; | |
158 | } | |
159 | }; | |
160 | ||
161 | template<class Base BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class Tag> | |
162 | struct concept_interface< | |
163 | ::boost::type_erasure::constructible<Tag(BOOST_PP_ENUM_PARAMS(N, T))>, | |
164 | Base, | |
165 | Tag | |
166 | > : Base | |
167 | { | |
168 | using Base::_boost_type_erasure_deduce_constructor; | |
169 | ::boost::type_erasure::constructible<Tag(BOOST_PP_ENUM_PARAMS(N, T))>* | |
170 | _boost_type_erasure_deduce_constructor( | |
171 | BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_ARG_DECL, ~)) | |
172 | { | |
173 | return 0; | |
174 | } | |
175 | }; | |
176 | ||
177 | namespace detail { | |
178 | ||
179 | template<BOOST_PP_ENUM_PARAMS(N, class T)> | |
180 | struct null_construct<void(BOOST_PP_ENUM_PARAMS(N, T))> | |
181 | { | |
182 | static ::boost::type_erasure::detail::storage | |
183 | value(BOOST_PP_ENUM_PARAMS(N, T)) | |
184 | { | |
185 | ::boost::type_erasure::detail::storage result; | |
186 | result.data = 0; | |
187 | return result; | |
188 | } | |
189 | }; | |
190 | ||
191 | template<class T, class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> | |
192 | struct get_null_vtable_entry<vtable_adapter<constructible<T(const T&)>, R(BOOST_PP_ENUM_PARAMS(N, T))> > | |
193 | { | |
194 | typedef null_construct<void(BOOST_PP_ENUM_PARAMS(N, T))> type; | |
195 | }; | |
196 | ||
197 | } | |
198 | ||
199 | #undef BOOST_TYPE_ERASURE_FORWARD | |
200 | #undef BOOST_TYPE_ERASURE_FORWARD_I | |
201 | ||
202 | #undef BOOST_TYPE_ERASURE_ARG_DECL | |
203 | #undef N | |
204 | ||
205 | #endif |