]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/functional/include/boost/functional/lightweight_forward_adapter.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / functional / include / boost / functional / lightweight_forward_adapter.hpp
1 /*=============================================================================
2 Copyright (c) 2007 Tobias Schwinger
3
4 Use modification and distribution are subject to the Boost Software
5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7 ==============================================================================*/
8
9 #ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
10 # ifndef BOOST_PP_IS_ITERATING
11
12 # include <boost/config.hpp>
13 # include <boost/detail/workaround.hpp>
14
15 # include <boost/preprocessor/cat.hpp>
16 # include <boost/preprocessor/iteration/iterate.hpp>
17 # include <boost/preprocessor/repetition/enum.hpp>
18 # include <boost/preprocessor/repetition/enum_params.hpp>
19 # include <boost/preprocessor/repetition/enum_binary_params.hpp>
20 # include <boost/preprocessor/facilities/intercept.hpp>
21
22 # include <boost/utility/result_of.hpp>
23 # include <boost/ref.hpp>
24
25 # ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
26 # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 10
27 # elif BOOST_FUNCTIONAL_FORDWARD_ADAPTER_MAX_ARITY < 3
28 # undef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
29 # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 3
30 # endif
31
32 namespace boost
33 {
34 template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
35 class lightweight_forward_adapter;
36
37 //----- ---- --- -- - - - -
38
39 namespace detail
40 {
41 template< class MostDerived, typename Function, typename FunctionConst,
42 int Arity, int MinArity >
43 struct lightweight_forward_adapter_impl;
44
45 struct lightweight_forward_adapter_result
46 {
47 template< typename Sig > struct apply;
48
49 // Utility metafunction for argument transform
50 template< typename T > struct x { typedef T const& t; };
51 template< typename T > struct x< boost::reference_wrapper<T> >
52 { typedef T& t; };
53 template< typename T > struct x<T&> : x<T> { };
54 template< typename T > struct x<T const&> : x<T> { };
55 template< typename T > struct x<T const> : x<T> { };
56
57 // Utility metafunction to choose target function qualification
58 template< typename T > struct c
59 { typedef typename T::target_function_t t; };
60 template< typename T > struct c<T& >
61 { typedef typename T::target_function_t t; };
62 template< typename T > struct c<T const >
63 { typedef typename T::target_function_const_t t; };
64 template< typename T > struct c<T const&>
65 { typedef typename T::target_function_const_t t; };
66 };
67 }
68
69 # define BOOST_TMP_MACRO(f,fn,fc) \
70 boost::detail::lightweight_forward_adapter_impl< \
71 lightweight_forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
72 (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
73 :BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY), \
74 (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
75
76 template< typename Function, int Arity_Or_MinArity, int MaxArity >
77 class lightweight_forward_adapter
78 : public BOOST_TMP_MACRO(Function,Function,Function const)
79 , private Function
80 {
81 public:
82 lightweight_forward_adapter(Function const& f = Function())
83 : Function(f)
84 { }
85
86 typedef Function target_function_t;
87 typedef Function const target_function_const_t;
88
89 Function & target_function() { return *this; }
90 Function const & target_function() const { return *this; }
91
92 template< typename Sig > struct result
93 : detail::lightweight_forward_adapter_result::template apply<Sig>
94 { };
95
96 using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
97 };
98 template< typename Function, int Arity_Or_MinArity, int MaxArity >
99 class lightweight_forward_adapter< Function const, Arity_Or_MinArity,
100 MaxArity >
101 : public BOOST_TMP_MACRO(Function const, Function const, Function const)
102 , private Function
103 {
104 public:
105 lightweight_forward_adapter(Function const& f = Function())
106 : Function(f)
107 { }
108
109 typedef Function const target_function_t;
110 typedef Function const target_function_const_t;
111
112 Function const & target_function() const { return *this; }
113
114 template< typename Sig > struct result
115 : detail::lightweight_forward_adapter_result::template apply<Sig>
116 { };
117
118 using BOOST_TMP_MACRO(Function const,Function const, Function const)
119 ::operator();
120 };
121 template< typename Function, int Arity_Or_MinArity, int MaxArity >
122 class lightweight_forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
123 : public BOOST_TMP_MACRO(Function&, Function, Function)
124 {
125 Function& ref_function;
126 public:
127 lightweight_forward_adapter(Function& f)
128 : ref_function(f)
129 { }
130
131 typedef Function target_function_t;
132 typedef Function target_function_const_t;
133
134 Function & target_function() const { return this->ref_function; }
135
136 template< typename Sig > struct result
137 : detail::lightweight_forward_adapter_result::template apply<Sig>
138 { };
139
140 using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
141 };
142
143 #undef BOOST_TMP_MACRO
144
145 namespace detail
146 {
147 template< class Self >
148 struct lightweight_forward_adapter_result::apply< Self() >
149 : boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
150 { };
151
152 // When operator() doesn't have any parameters, it can't
153 // be templatized and can't use SFINAE, so intead use class
154 // template parameter SFINAE to decide whether to instantiate it.
155
156 template <typename T, typename R = void>
157 struct lightweight_forward_adapter_sfinae
158 {
159 typedef T type;
160 };
161
162 // This is the fallback for when there isn't an operator()(),
163 // need to create an operator() that will never instantiate
164 // so that using parent::operator() will work okay.
165 template< class MD, class F, class FC, class Enable = void>
166 struct lightweight_forward_adapter_impl_zero
167 : lightweight_forward_adapter_result
168 {
169 template <typename T> struct never_instantiate {};
170 template <typename T>
171 typename never_instantiate<T>::type operator()(T) const {}
172 };
173
174 template< class MD, class F, class FC>
175 struct lightweight_forward_adapter_impl_zero<MD, F, FC,
176 typename lightweight_forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
177 : lightweight_forward_adapter_result
178 {
179 inline typename boost::result_of< FC() >::type
180 operator()() const
181 {
182 return static_cast<MD const*>(this)->target_function()();
183 }
184
185 inline typename boost::result_of< F() >::type
186 operator()()
187 {
188 return static_cast<MD*>(this)->target_function()();
189 }
190 };
191
192 template< class MD, class F, class FC >
193 struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
194 : lightweight_forward_adapter_impl_zero<MD,F,FC>
195 {
196 };
197
198 # define BOOST_PP_FILENAME_1 \
199 <boost/functional/lightweight_forward_adapter.hpp>
200 # define BOOST_PP_ITERATION_LIMITS \
201 (1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY)
202 # include BOOST_PP_ITERATE()
203
204 } // namespace detail
205
206 template<class F, int A0, int A1>
207 struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const ()>
208 : boost::detail::lightweight_forward_adapter_result::template apply<
209 boost::lightweight_forward_adapter<F,A0,A1> const () >
210 { };
211 template<class F, int A0, int A1>
212 struct result_of<boost::lightweight_forward_adapter<F,A0,A1>()>
213 : boost::detail::lightweight_forward_adapter_result::template apply<
214 boost::lightweight_forward_adapter<F,A0,A1>() >
215 { };
216 template<class F, int A0, int A1>
217 struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const& ()>
218 : boost::detail::lightweight_forward_adapter_result::template apply<
219 boost::lightweight_forward_adapter<F,A0,A1> const () >
220 { };
221 template<class F, int A0, int A1>
222 struct result_of<boost::lightweight_forward_adapter<F,A0,A1>& ()>
223 : boost::detail::lightweight_forward_adapter_result::template apply<
224 boost::lightweight_forward_adapter<F,A0,A1>() >
225 { };
226 }
227
228 # define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
229
230 # else // defined(BOOST_PP_IS_ITERATING)
231 # define N BOOST_PP_ITERATION()
232
233 template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
234 struct lightweight_forward_adapter_result::apply<
235 Self (BOOST_PP_ENUM_PARAMS(N,T)) >
236 : boost::result_of<
237 BOOST_DEDUCED_TYPENAME c<Self>::t (BOOST_PP_ENUM_BINARY_PARAMS(N,
238 typename x<T,>::t BOOST_PP_INTERCEPT)) >
239 { };
240
241 template< class MD, class F, class FC >
242 struct lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
243 : lightweight_forward_adapter_result
244 {
245 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
246 inline typename boost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N,
247 T,const& BOOST_PP_INTERCEPT)) >::type
248 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
249 };
250
251 template< class MD, class F, class FC, int MinArity >
252 struct lightweight_forward_adapter_impl<MD,F,FC,N,MinArity>
253 : lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
254 {
255 using lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),
256 MinArity>::operator();
257
258 # define M(z,i,d) \
259 static_cast<typename d::template x<T##i>::t>(a##i)
260
261 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
262 inline typename lightweight_forward_adapter_result::template apply<
263 MD const (BOOST_PP_ENUM_BINARY_PARAMS(N,
264 T,const& BOOST_PP_INTERCEPT)) >::type
265 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const
266 {
267 typedef lightweight_forward_adapter_result _;
268 return static_cast<MD const*>(this)->target_function()(
269 BOOST_PP_ENUM(N,M,_));
270 }
271 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
272 inline typename lightweight_forward_adapter_result::template apply<
273 MD (BOOST_PP_ENUM_BINARY_PARAMS(N,
274 T,const& BOOST_PP_INTERCEPT)) >::type
275 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a))
276 {
277 typedef lightweight_forward_adapter_result _;
278 return static_cast<MD*>(this)->target_function()(
279 BOOST_PP_ENUM(N,M,_));
280 }
281 # undef M
282 };
283
284 # undef N
285 # endif // defined(BOOST_PP_IS_ITERATING)
286
287 #endif // include guard
288