blob: 8312a2c41f0bacd63991fdfc51fb039c89c732fc [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001/*=============================================================================
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 <ndnboost/config.hpp>
13# include <ndnboost/detail/workaround.hpp>
14
15# include <ndnboost/preprocessor/cat.hpp>
16# include <ndnboost/preprocessor/iteration/iterate.hpp>
17# include <ndnboost/preprocessor/repetition/enum.hpp>
18# include <ndnboost/preprocessor/repetition/enum_params.hpp>
19# include <ndnboost/preprocessor/repetition/enum_binary_params.hpp>
20# include <ndnboost/preprocessor/facilities/intercept.hpp>
21
22# include <ndnboost/utility/result_of.hpp>
23# include <ndnboost/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
32namespace ndnboost
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< ndnboost::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 ndnboost::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 : ndnboost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
150 { };
151
152 template< class MD, class F, class FC >
153 struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
154 : lightweight_forward_adapter_result
155 {
156 inline typename ndnboost::result_of< FC() >::type
157 operator()() const
158 {
159 return static_cast<MD const*>(this)->target_function()();
160 }
161
162 inline typename ndnboost::result_of< F() >::type
163 operator()()
164 {
165 return static_cast<MD*>(this)->target_function()();
166 }
167 };
168
169# define BOOST_PP_FILENAME_1 \
170 <ndnboost/functional/lightweight_forward_adapter.hpp>
171# define BOOST_PP_ITERATION_LIMITS \
172 (1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY)
173# include BOOST_PP_ITERATE()
174
175 } // namespace detail
176
177 template<class F, int A0, int A1>
178 struct result_of<ndnboost::lightweight_forward_adapter<F,A0,A1> const ()>
179 : ndnboost::detail::lightweight_forward_adapter_result::template apply<
180 ndnboost::lightweight_forward_adapter<F,A0,A1> const () >
181 { };
182 template<class F, int A0, int A1>
183 struct result_of<ndnboost::lightweight_forward_adapter<F,A0,A1>()>
184 : ndnboost::detail::lightweight_forward_adapter_result::template apply<
185 ndnboost::lightweight_forward_adapter<F,A0,A1>() >
186 { };
187 template<class F, int A0, int A1>
188 struct result_of<ndnboost::lightweight_forward_adapter<F,A0,A1> const& ()>
189 : ndnboost::detail::lightweight_forward_adapter_result::template apply<
190 ndnboost::lightweight_forward_adapter<F,A0,A1> const () >
191 { };
192 template<class F, int A0, int A1>
193 struct result_of<ndnboost::lightweight_forward_adapter<F,A0,A1>& ()>
194 : ndnboost::detail::lightweight_forward_adapter_result::template apply<
195 ndnboost::lightweight_forward_adapter<F,A0,A1>() >
196 { };
197}
198
199# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
200
201# else // defined(BOOST_PP_IS_ITERATING)
202# define N BOOST_PP_ITERATION()
203
204 template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
205 struct lightweight_forward_adapter_result::apply<
206 Self (BOOST_PP_ENUM_PARAMS(N,T)) >
207 : ndnboost::result_of<
208 BOOST_DEDUCED_TYPENAME c<Self>::t (BOOST_PP_ENUM_BINARY_PARAMS(N,
209 typename x<T,>::t BOOST_PP_INTERCEPT)) >
210 { };
211
212 template< class MD, class F, class FC >
213 struct lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
214 : lightweight_forward_adapter_result
215 {
216 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
217 inline typename ndnboost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N,
218 T,const& BOOST_PP_INTERCEPT)) >::type
219 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
220 };
221
222 template< class MD, class F, class FC, int MinArity >
223 struct lightweight_forward_adapter_impl<MD,F,FC,N,MinArity>
224 : lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
225 {
226 using lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),
227 MinArity>::operator();
228
229# define M(z,i,d) \
230 static_cast<typename d::template x<T##i>::t>(a##i)
231
232 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
233 inline typename lightweight_forward_adapter_result::template apply<
234 MD const (BOOST_PP_ENUM_BINARY_PARAMS(N,
235 T,const& BOOST_PP_INTERCEPT)) >::type
236 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const
237 {
238 typedef lightweight_forward_adapter_result _;
239 return static_cast<MD const*>(this)->target_function()(
240 BOOST_PP_ENUM(N,M,_));
241 }
242 template< BOOST_PP_ENUM_PARAMS(N,typename T) >
243 inline typename lightweight_forward_adapter_result::template apply<
244 MD (BOOST_PP_ENUM_BINARY_PARAMS(N,
245 T,const& BOOST_PP_INTERCEPT)) >::type
246 operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a))
247 {
248 typedef lightweight_forward_adapter_result _;
249 return static_cast<MD*>(this)->target_function()(
250 BOOST_PP_ENUM(N,M,_));
251 }
252# undef M
253 };
254
255# undef N
256# endif // defined(BOOST_PP_IS_ITERATING)
257
258#endif // include guard
259