]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/proto/detail/poly_function.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / proto / detail / poly_function.hpp
CommitLineData
7c673cae
FG
1///////////////////////////////////////////////////////////////////////////////
2/// \file poly_function.hpp
3/// A wrapper that makes a tr1-style function object that handles const
4/// and non-const refs and reference_wrapper arguments, too, and forwards
5/// the arguments on to the specified implementation.
6//
7// Copyright 2008 Eric Niebler. Distributed under the Boost
8// Software License, Version 1.0. (See accompanying file
9// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10
11#ifndef BOOST_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02
12#define BOOST_PROTO_DETAIL_POLY_FUNCTION_EAN_2008_05_02
13
14#include <boost/ref.hpp>
15#include <boost/mpl/bool.hpp>
16#include <boost/mpl/void.hpp>
17#include <boost/mpl/size_t.hpp>
18#include <boost/mpl/eval_if.hpp>
19#include <boost/preprocessor/cat.hpp>
20#include <boost/preprocessor/facilities/intercept.hpp>
21#include <boost/preprocessor/iteration/iterate.hpp>
22#include <boost/preprocessor/repetition/enum.hpp>
23#include <boost/preprocessor/repetition/enum_params.hpp>
24#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
25#include <boost/preprocessor/repetition/enum_binary_params.hpp>
26#include <boost/proto/proto_fwd.hpp>
27#include <boost/proto/detail/is_noncopyable.hpp>
28
29#ifdef _MSC_VER
30# pragma warning(push)
31# pragma warning(disable: 4181) // const applied to reference type
32#endif
33
34namespace boost { namespace proto { namespace detail
35{
36
37 ////////////////////////////////////////////////////////////////////////////////////////////////
38 template<typename T>
39 struct normalize_arg
40 {
41 typedef typename mpl::if_c<is_noncopyable<T>::value, T &, T>::type type;
42 typedef T &reference;
43 };
44
45 template<typename T>
46 struct normalize_arg<T const>
47 {
48 typedef typename mpl::if_c<is_noncopyable<T>::value, T const &, T>::type type;
49 typedef T const &reference;
50 };
51
52 template<typename T>
53 struct normalize_arg<T &>
54 {
55 typedef typename mpl::if_c<is_noncopyable<T>::value, T &, T>::type type;
56 typedef T &reference;
57 };
58
59 template<typename T>
60 struct normalize_arg<T const &>
61 {
62 typedef typename mpl::if_c<is_noncopyable<T>::value, T const &, T>::type type;
63 typedef T const &reference;
64 };
65
66 template<typename T>
67 struct normalize_arg<boost::reference_wrapper<T> >
68 {
69 typedef T &type;
70 typedef T &reference;
71 };
72
73 template<typename T>
74 struct normalize_arg<boost::reference_wrapper<T> const>
75 {
76 typedef T &type;
77 typedef T &reference;
78 };
79
80 template<typename T>
81 struct normalize_arg<boost::reference_wrapper<T> &>
82 {
83 typedef T &type;
84 typedef T &reference;
85 };
86
87 template<typename T>
88 struct normalize_arg<boost::reference_wrapper<T> const &>
89 {
90 typedef T &type;
91 typedef T &reference;
92 };
93
94 ////////////////////////////////////////////////////////////////////////////////////////////////
95 template<typename T>
96 struct arg
97 {
98 typedef T const &type;
99
100 arg(type t)
101 : value(t)
102 {}
103
104 operator type() const
105 {
106 return this->value;
107 }
108
109 type operator()() const
110 {
111 return this->value;
112 }
113
20effc67 114 BOOST_DELETED_FUNCTION(arg &operator =(arg const &))
7c673cae 115 private:
7c673cae
FG
116 type value;
117 };
118
119 template<typename T>
120 struct arg<T &>
121 {
122 typedef T &type;
123
124 arg(type t)
125 : value(t)
126 {}
127
128 operator type() const
129 {
130 return this->value;
131 }
132
133 type operator()() const
134 {
135 return this->value;
136 }
137
20effc67 138 BOOST_DELETED_FUNCTION(arg &operator =(arg const &))
7c673cae 139 private:
7c673cae
FG
140 type value;
141 };
142
143 ////////////////////////////////////////////////////////////////////////////////////////////////
144 template<typename T, typename Void = void>
145 struct is_poly_function
146 : mpl::false_
147 {};
148
149 template<typename T>
150 struct is_poly_function<T, typename T::is_poly_function_base_>
151 : mpl::true_
152 {};
153
154 ////////////////////////////////////////////////////////////////////////////////////////////////
155 #define BOOST_PROTO_POLY_FUNCTION() \
156 typedef void is_poly_function_base_; \
157 /**/
158
159 ////////////////////////////////////////////////////////////////////////////////////////////////
160 struct poly_function_base
161 {
162 /// INTERNAL ONLY
163 BOOST_PROTO_POLY_FUNCTION()
164 };
165
166 ////////////////////////////////////////////////////////////////////////////////////////////////
167 template<typename Derived, typename NullaryResult = void>
168 struct poly_function
169 : poly_function_base
170 {
171 template<typename Sig>
172 struct result;
173
174 template<typename This>
175 struct result<This()>
176 : Derived::template impl<>
177 {
178 typedef typename result::result_type type;
179 };
180
181 NullaryResult operator()() const
182 {
183 result<Derived const()> impl;
184 return impl();
185 }
186
187 #include <boost/proto/detail/poly_function_funop.hpp>
188 };
189
190 template<typename T>
191 struct wrap_t;
192
193 typedef char poly_function_t;
194 typedef char (&mono_function_t)[2];
195 typedef char (&unknown_function_t)[3];
196
197 template<typename T> poly_function_t test_poly_function(T *, wrap_t<typename T::is_poly_function_base_> * = 0);
198 template<typename T> mono_function_t test_poly_function(T *, wrap_t<typename T::result_type> * = 0);
199 template<typename T> unknown_function_t test_poly_function(T *, ...);
200
201 ////////////////////////////////////////////////////////////////////////////////////////////////
202 template<typename Fun, typename Sig, typename Switch = mpl::size_t<sizeof(test_poly_function<Fun>(0,0))> >
203 struct poly_function_traits
204 {
205 typedef typename Fun::template result<Sig>::type result_type;
206 typedef Fun function_type;
207 };
208
209 ////////////////////////////////////////////////////////////////////////////////////////////////
210 template<typename Fun, typename Sig>
211 struct poly_function_traits<Fun, Sig, mpl::size_t<sizeof(mono_function_t)> >
212 {
213 typedef typename Fun::result_type result_type;
214 typedef Fun function_type;
215 };
216
217 ////////////////////////////////////////////////////////////////////////////////////////////////
218 template<typename PolyFunSig, bool IsPolyFunction>
219 struct as_mono_function_impl;
220
221 ////////////////////////////////////////////////////////////////////////////////////////////////
222 template<typename PolyFunSig>
223 struct as_mono_function;
224
225 #include <boost/proto/detail/poly_function_traits.hpp>
226
227}}} // namespace boost::proto::detail
228
229#ifdef _MSC_VER
230# pragma warning(pop)
231#endif
232
233#endif
234