williamr@2
|
1 |
// Boost Lambda Library - lambda_functors.hpp -------------------------------
|
williamr@2
|
2 |
|
williamr@2
|
3 |
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
|
williamr@2
|
4 |
//
|
williamr@2
|
5 |
// Distributed under the Boost Software License, Version 1.0. (See
|
williamr@2
|
6 |
// accompanying file LICENSE_1_0.txt or copy at
|
williamr@2
|
7 |
// http://www.boost.org/LICENSE_1_0.txt)
|
williamr@2
|
8 |
//
|
williamr@2
|
9 |
// For more information, see http://www.boost.org
|
williamr@2
|
10 |
|
williamr@2
|
11 |
// ------------------------------------------------
|
williamr@2
|
12 |
|
williamr@2
|
13 |
#ifndef BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
|
williamr@2
|
14 |
#define BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
|
williamr@2
|
15 |
|
williamr@2
|
16 |
namespace boost {
|
williamr@2
|
17 |
namespace lambda {
|
williamr@2
|
18 |
|
williamr@2
|
19 |
// -- lambda_functor --------------------------------------------
|
williamr@2
|
20 |
// --------------------------------------------------------------
|
williamr@2
|
21 |
|
williamr@2
|
22 |
//inline const null_type const_null_type() { return null_type(); }
|
williamr@2
|
23 |
|
williamr@2
|
24 |
namespace detail {
|
williamr@2
|
25 |
namespace {
|
williamr@2
|
26 |
|
williamr@2
|
27 |
static const null_type constant_null_type = null_type();
|
williamr@2
|
28 |
|
williamr@2
|
29 |
} // unnamed
|
williamr@2
|
30 |
} // detail
|
williamr@2
|
31 |
|
williamr@2
|
32 |
class unused {};
|
williamr@2
|
33 |
|
williamr@2
|
34 |
#define cnull_type() detail::constant_null_type
|
williamr@2
|
35 |
|
williamr@2
|
36 |
// -- free variables types --------------------------------------------------
|
williamr@2
|
37 |
|
williamr@2
|
38 |
// helper to work around the case where the nullary return type deduction
|
williamr@2
|
39 |
// is always performed, even though the functor is not nullary
|
williamr@2
|
40 |
namespace detail {
|
williamr@2
|
41 |
template<int N, class Tuple> struct get_element_or_null_type {
|
williamr@2
|
42 |
typedef typename
|
williamr@2
|
43 |
detail::tuple_element_as_reference<N, Tuple>::type type;
|
williamr@2
|
44 |
};
|
williamr@2
|
45 |
template<int N> struct get_element_or_null_type<N, null_type> {
|
williamr@2
|
46 |
typedef null_type type;
|
williamr@2
|
47 |
};
|
williamr@2
|
48 |
}
|
williamr@2
|
49 |
|
williamr@2
|
50 |
template <int I> struct placeholder;
|
williamr@2
|
51 |
|
williamr@2
|
52 |
template<> struct placeholder<FIRST> {
|
williamr@2
|
53 |
|
williamr@2
|
54 |
template<class SigArgs> struct sig {
|
williamr@2
|
55 |
typedef typename detail::get_element_or_null_type<0, SigArgs>::type type;
|
williamr@2
|
56 |
};
|
williamr@2
|
57 |
|
williamr@2
|
58 |
template<class RET, CALL_TEMPLATE_ARGS>
|
williamr@2
|
59 |
RET call(CALL_FORMAL_ARGS) const {
|
williamr@2
|
60 |
BOOST_STATIC_ASSERT(boost::is_reference<RET>::value);
|
williamr@2
|
61 |
CALL_USE_ARGS; // does nothing, prevents warnings for unused args
|
williamr@2
|
62 |
return a;
|
williamr@2
|
63 |
}
|
williamr@2
|
64 |
};
|
williamr@2
|
65 |
|
williamr@2
|
66 |
template<> struct placeholder<SECOND> {
|
williamr@2
|
67 |
|
williamr@2
|
68 |
template<class SigArgs> struct sig {
|
williamr@2
|
69 |
typedef typename detail::get_element_or_null_type<1, SigArgs>::type type;
|
williamr@2
|
70 |
};
|
williamr@2
|
71 |
|
williamr@2
|
72 |
template<class RET, CALL_TEMPLATE_ARGS>
|
williamr@2
|
73 |
RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return b; }
|
williamr@2
|
74 |
};
|
williamr@2
|
75 |
|
williamr@2
|
76 |
template<> struct placeholder<THIRD> {
|
williamr@2
|
77 |
|
williamr@2
|
78 |
template<class SigArgs> struct sig {
|
williamr@2
|
79 |
typedef typename detail::get_element_or_null_type<2, SigArgs>::type type;
|
williamr@2
|
80 |
};
|
williamr@2
|
81 |
|
williamr@2
|
82 |
template<class RET, CALL_TEMPLATE_ARGS>
|
williamr@2
|
83 |
RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return c; }
|
williamr@2
|
84 |
};
|
williamr@2
|
85 |
|
williamr@2
|
86 |
template<> struct placeholder<EXCEPTION> {
|
williamr@2
|
87 |
|
williamr@2
|
88 |
template<class SigArgs> struct sig {
|
williamr@2
|
89 |
typedef typename detail::get_element_or_null_type<3, SigArgs>::type type;
|
williamr@2
|
90 |
};
|
williamr@2
|
91 |
|
williamr@2
|
92 |
template<class RET, CALL_TEMPLATE_ARGS>
|
williamr@2
|
93 |
RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return env; }
|
williamr@2
|
94 |
};
|
williamr@2
|
95 |
|
williamr@2
|
96 |
typedef const lambda_functor<placeholder<FIRST> > placeholder1_type;
|
williamr@2
|
97 |
typedef const lambda_functor<placeholder<SECOND> > placeholder2_type;
|
williamr@2
|
98 |
typedef const lambda_functor<placeholder<THIRD> > placeholder3_type;
|
williamr@2
|
99 |
|
williamr@2
|
100 |
|
williamr@2
|
101 |
///////////////////////////////////////////////////////////////////////////////
|
williamr@2
|
102 |
|
williamr@2
|
103 |
|
williamr@2
|
104 |
// free variables are lambda_functors. This is to allow uniform handling with
|
williamr@2
|
105 |
// other lambda_functors.
|
williamr@2
|
106 |
// -------------------------------------------------------------------
|
williamr@2
|
107 |
|
williamr@2
|
108 |
|
williamr@2
|
109 |
|
williamr@2
|
110 |
// -- lambda_functor NONE ------------------------------------------------
|
williamr@2
|
111 |
template <class T>
|
williamr@2
|
112 |
class lambda_functor : public T
|
williamr@2
|
113 |
{
|
williamr@2
|
114 |
|
williamr@2
|
115 |
BOOST_STATIC_CONSTANT(int, arity_bits = get_arity<T>::value);
|
williamr@2
|
116 |
|
williamr@2
|
117 |
public:
|
williamr@2
|
118 |
typedef T inherited;
|
williamr@2
|
119 |
|
williamr@2
|
120 |
lambda_functor() {}
|
williamr@2
|
121 |
lambda_functor(const lambda_functor& l) : inherited(l) {}
|
williamr@2
|
122 |
|
williamr@2
|
123 |
lambda_functor(const T& t) : inherited(t) {}
|
williamr@2
|
124 |
|
williamr@2
|
125 |
template <class SigArgs> struct sig {
|
williamr@2
|
126 |
typedef typename inherited::template
|
williamr@2
|
127 |
sig<typename SigArgs::tail_type>::type type;
|
williamr@2
|
128 |
};
|
williamr@2
|
129 |
|
williamr@2
|
130 |
// Note that this return type deduction template is instantiated, even
|
williamr@2
|
131 |
// if the nullary
|
williamr@2
|
132 |
// operator() is not called at all. One must make sure that it does not fail.
|
williamr@2
|
133 |
typedef typename
|
williamr@2
|
134 |
inherited::template sig<null_type>::type
|
williamr@2
|
135 |
nullary_return_type;
|
williamr@2
|
136 |
|
williamr@2
|
137 |
nullary_return_type operator()() const {
|
williamr@2
|
138 |
return inherited::template
|
williamr@2
|
139 |
call<nullary_return_type>
|
williamr@2
|
140 |
(cnull_type(), cnull_type(), cnull_type(), cnull_type());
|
williamr@2
|
141 |
}
|
williamr@2
|
142 |
|
williamr@2
|
143 |
template<class A>
|
williamr@2
|
144 |
typename inherited::template sig<tuple<A&> >::type
|
williamr@2
|
145 |
operator()(A& a) const {
|
williamr@2
|
146 |
return inherited::template call<
|
williamr@2
|
147 |
typename inherited::template sig<tuple<A&> >::type
|
williamr@2
|
148 |
>(a, cnull_type(), cnull_type(), cnull_type());
|
williamr@2
|
149 |
}
|
williamr@2
|
150 |
|
williamr@2
|
151 |
template<class A, class B>
|
williamr@2
|
152 |
typename inherited::template sig<tuple<A&, B&> >::type
|
williamr@2
|
153 |
operator()(A& a, B& b) const {
|
williamr@2
|
154 |
return inherited::template call<
|
williamr@2
|
155 |
typename inherited::template sig<tuple<A&, B&> >::type
|
williamr@2
|
156 |
>(a, b, cnull_type(), cnull_type());
|
williamr@2
|
157 |
}
|
williamr@2
|
158 |
|
williamr@2
|
159 |
template<class A, class B, class C>
|
williamr@2
|
160 |
typename inherited::template sig<tuple<A&, B&, C&> >::type
|
williamr@2
|
161 |
operator()(A& a, B& b, C& c) const
|
williamr@2
|
162 |
{
|
williamr@2
|
163 |
return inherited::template call<
|
williamr@2
|
164 |
typename inherited::template sig<tuple<A&, B&, C&> >::type
|
williamr@2
|
165 |
>(a, b, c, cnull_type());
|
williamr@2
|
166 |
}
|
williamr@2
|
167 |
|
williamr@2
|
168 |
// for internal calls with env
|
williamr@2
|
169 |
template<CALL_TEMPLATE_ARGS>
|
williamr@2
|
170 |
typename inherited::template sig<tuple<CALL_REFERENCE_TYPES> >::type
|
williamr@2
|
171 |
internal_call(CALL_FORMAL_ARGS) const {
|
williamr@2
|
172 |
return inherited::template
|
williamr@2
|
173 |
call<typename inherited::template
|
williamr@2
|
174 |
sig<tuple<CALL_REFERENCE_TYPES> >::type>(CALL_ACTUAL_ARGS);
|
williamr@2
|
175 |
}
|
williamr@2
|
176 |
|
williamr@2
|
177 |
template<class A>
|
williamr@2
|
178 |
const lambda_functor<lambda_functor_base<
|
williamr@2
|
179 |
other_action<assignment_action>,
|
williamr@2
|
180 |
boost::tuple<lambda_functor,
|
williamr@2
|
181 |
typename const_copy_argument <const A>::type> > >
|
williamr@2
|
182 |
operator=(const A& a) const {
|
williamr@2
|
183 |
return lambda_functor_base<
|
williamr@2
|
184 |
other_action<assignment_action>,
|
williamr@2
|
185 |
boost::tuple<lambda_functor,
|
williamr@2
|
186 |
typename const_copy_argument <const A>::type> >
|
williamr@2
|
187 |
( boost::tuple<lambda_functor,
|
williamr@2
|
188 |
typename const_copy_argument <const A>::type>(*this, a) );
|
williamr@2
|
189 |
}
|
williamr@2
|
190 |
|
williamr@2
|
191 |
template<class A>
|
williamr@2
|
192 |
const lambda_functor<lambda_functor_base<
|
williamr@2
|
193 |
other_action<subscript_action>,
|
williamr@2
|
194 |
boost::tuple<lambda_functor,
|
williamr@2
|
195 |
typename const_copy_argument <const A>::type> > >
|
williamr@2
|
196 |
operator[](const A& a) const {
|
williamr@2
|
197 |
return lambda_functor_base<
|
williamr@2
|
198 |
other_action<subscript_action>,
|
williamr@2
|
199 |
boost::tuple<lambda_functor,
|
williamr@2
|
200 |
typename const_copy_argument <const A>::type> >
|
williamr@2
|
201 |
( boost::tuple<lambda_functor,
|
williamr@2
|
202 |
typename const_copy_argument <const A>::type>(*this, a ) );
|
williamr@2
|
203 |
}
|
williamr@2
|
204 |
};
|
williamr@2
|
205 |
|
williamr@2
|
206 |
|
williamr@2
|
207 |
} // namespace lambda
|
williamr@2
|
208 |
} // namespace boost
|
williamr@2
|
209 |
|
williamr@2
|
210 |
#endif
|
williamr@2
|
211 |
|
williamr@2
|
212 |
|