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