1 | // Boost Lambda Library - operator_lambda_func_base.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 www.boost.org
|
---|
10 |
|
---|
11 | // ------------------------------------------------------------
|
---|
12 |
|
---|
13 | #ifndef BOOST_LAMBDA_OPERATOR_LAMBDA_FUNC_BASE_HPP
|
---|
14 | #define BOOST_LAMBDA_OPERATOR_LAMBDA_FUNC_BASE_HPP
|
---|
15 |
|
---|
16 | namespace boost {
|
---|
17 | namespace lambda {
|
---|
18 |
|
---|
19 |
|
---|
20 | // These operators cannot be implemented as apply functions of action
|
---|
21 | // templates
|
---|
22 |
|
---|
23 |
|
---|
24 | // Specialization for comma.
|
---|
25 | template<class Args>
|
---|
26 | class lambda_functor_base<other_action<comma_action>, Args> {
|
---|
27 | public:
|
---|
28 | Args args;
|
---|
29 | public:
|
---|
30 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
31 |
|
---|
32 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
33 | RET call(CALL_FORMAL_ARGS) const {
|
---|
34 | return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS),
|
---|
35 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
|
---|
36 | }
|
---|
37 |
|
---|
38 |
|
---|
39 | template<class SigArgs> struct sig {
|
---|
40 | private:
|
---|
41 | typedef typename
|
---|
42 | detail::deduce_argument_types<Args, SigArgs>::type rets_t;
|
---|
43 | public:
|
---|
44 | typedef typename return_type_2_comma< // comma needs special handling
|
---|
45 | typename detail::element_or_null<0, rets_t>::type,
|
---|
46 | typename detail::element_or_null<1, rets_t>::type
|
---|
47 | >::type type;
|
---|
48 | };
|
---|
49 |
|
---|
50 | };
|
---|
51 |
|
---|
52 | namespace detail {
|
---|
53 |
|
---|
54 | // helper traits to make the expression shorter, takes binary action
|
---|
55 | // bound argument tuple, open argument tuple and gives the return type
|
---|
56 |
|
---|
57 | template<class Action, class Bound, class Open> class binary_rt {
|
---|
58 | private:
|
---|
59 | typedef typename
|
---|
60 | detail::deduce_argument_types<Bound, Open>::type rets_t;
|
---|
61 | public:
|
---|
62 | typedef typename return_type_2_prot<
|
---|
63 | Action,
|
---|
64 | typename detail::element_or_null<0, rets_t>::type,
|
---|
65 | typename detail::element_or_null<1, rets_t>::type
|
---|
66 | >::type type;
|
---|
67 | };
|
---|
68 |
|
---|
69 |
|
---|
70 | // same for unary actions
|
---|
71 | template<class Action, class Bound, class Open> class unary_rt {
|
---|
72 | private:
|
---|
73 | typedef typename
|
---|
74 | detail::deduce_argument_types<Bound, Open>::type rets_t;
|
---|
75 | public:
|
---|
76 | typedef typename return_type_1_prot<
|
---|
77 | Action,
|
---|
78 | typename detail::element_or_null<0, rets_t>::type
|
---|
79 | >::type type;
|
---|
80 | };
|
---|
81 |
|
---|
82 |
|
---|
83 | } // end detail
|
---|
84 |
|
---|
85 | // Specialization for logical and (to preserve shortcircuiting)
|
---|
86 | // this could be done with a macro as the others, code used to be different
|
---|
87 | template<class Args>
|
---|
88 | class lambda_functor_base<logical_action<and_action>, Args> {
|
---|
89 | public:
|
---|
90 | Args args;
|
---|
91 | public:
|
---|
92 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
93 |
|
---|
94 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
95 | RET call(CALL_FORMAL_ARGS) const {
|
---|
96 | return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) &&
|
---|
97 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
|
---|
98 | }
|
---|
99 | template<class SigArgs> struct sig {
|
---|
100 | typedef typename
|
---|
101 | detail::binary_rt<logical_action<and_action>, Args, SigArgs>::type type;
|
---|
102 | };
|
---|
103 | };
|
---|
104 |
|
---|
105 | // Specialization for logical or (to preserve shortcircuiting)
|
---|
106 | // this could be done with a macro as the others, code used to be different
|
---|
107 | template<class Args>
|
---|
108 | class lambda_functor_base<logical_action< or_action>, Args> {
|
---|
109 | public:
|
---|
110 | Args args;
|
---|
111 | public:
|
---|
112 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
113 |
|
---|
114 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
115 | RET call(CALL_FORMAL_ARGS) const {
|
---|
116 | return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ||
|
---|
117 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
|
---|
118 | }
|
---|
119 |
|
---|
120 | template<class SigArgs> struct sig {
|
---|
121 | typedef typename
|
---|
122 | detail::binary_rt<logical_action<or_action>, Args, SigArgs>::type type;
|
---|
123 | };
|
---|
124 | };
|
---|
125 |
|
---|
126 | // Specialization for subscript
|
---|
127 | template<class Args>
|
---|
128 | class lambda_functor_base<other_action<subscript_action>, Args> {
|
---|
129 | public:
|
---|
130 | Args args;
|
---|
131 | public:
|
---|
132 | explicit lambda_functor_base(const Args& a) : args(a) {}
|
---|
133 |
|
---|
134 | template<class RET, CALL_TEMPLATE_ARGS>
|
---|
135 | RET call(CALL_FORMAL_ARGS) const {
|
---|
136 | return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)
|
---|
137 | [detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS)];
|
---|
138 | }
|
---|
139 |
|
---|
140 | template<class SigArgs> struct sig {
|
---|
141 | typedef typename
|
---|
142 | detail::binary_rt<other_action<subscript_action>, Args, SigArgs>::type
|
---|
143 | type;
|
---|
144 | };
|
---|
145 | };
|
---|
146 |
|
---|
147 |
|
---|
148 | #define BOOST_LAMBDA_BINARY_ACTION(SYMBOL, ACTION_CLASS) \
|
---|
149 | template<class Args> \
|
---|
150 | class lambda_functor_base<ACTION_CLASS, Args> { \
|
---|
151 | public: \
|
---|
152 | Args args; \
|
---|
153 | public: \
|
---|
154 | explicit lambda_functor_base(const Args& a) : args(a) {} \
|
---|
155 | \
|
---|
156 | template<class RET, CALL_TEMPLATE_ARGS> \
|
---|
157 | RET call(CALL_FORMAL_ARGS) const { \
|
---|
158 | return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) \
|
---|
159 | SYMBOL \
|
---|
160 | detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); \
|
---|
161 | } \
|
---|
162 | template<class SigArgs> struct sig { \
|
---|
163 | typedef typename \
|
---|
164 | detail::binary_rt<ACTION_CLASS, Args, SigArgs>::type type; \
|
---|
165 | }; \
|
---|
166 | };
|
---|
167 |
|
---|
168 | #define BOOST_LAMBDA_PREFIX_UNARY_ACTION(SYMBOL, ACTION_CLASS) \
|
---|
169 | template<class Args> \
|
---|
170 | class lambda_functor_base<ACTION_CLASS, Args> { \
|
---|
171 | public: \
|
---|
172 | Args args; \
|
---|
173 | public: \
|
---|
174 | explicit lambda_functor_base(const Args& a) : args(a) {} \
|
---|
175 | \
|
---|
176 | template<class RET, CALL_TEMPLATE_ARGS> \
|
---|
177 | RET call(CALL_FORMAL_ARGS) const { \
|
---|
178 | return SYMBOL \
|
---|
179 | detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); \
|
---|
180 | } \
|
---|
181 | template<class SigArgs> struct sig { \
|
---|
182 | typedef typename \
|
---|
183 | detail::unary_rt<ACTION_CLASS, Args, SigArgs>::type type; \
|
---|
184 | }; \
|
---|
185 | };
|
---|
186 |
|
---|
187 | #define BOOST_LAMBDA_POSTFIX_UNARY_ACTION(SYMBOL, ACTION_CLASS) \
|
---|
188 | template<class Args> \
|
---|
189 | class lambda_functor_base<ACTION_CLASS, Args> { \
|
---|
190 | public: \
|
---|
191 | Args args; \
|
---|
192 | public: \
|
---|
193 | explicit lambda_functor_base(const Args& a) : args(a) {} \
|
---|
194 | \
|
---|
195 | template<class RET, CALL_TEMPLATE_ARGS> \
|
---|
196 | RET call(CALL_FORMAL_ARGS) const { \
|
---|
197 | return \
|
---|
198 | detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) SYMBOL; \
|
---|
199 | } \
|
---|
200 | template<class SigArgs> struct sig { \
|
---|
201 | typedef typename \
|
---|
202 | detail::unary_rt<ACTION_CLASS, Args, SigArgs>::type type; \
|
---|
203 | }; \
|
---|
204 | };
|
---|
205 |
|
---|
206 | BOOST_LAMBDA_BINARY_ACTION(+,arithmetic_action<plus_action>)
|
---|
207 | BOOST_LAMBDA_BINARY_ACTION(-,arithmetic_action<minus_action>)
|
---|
208 | BOOST_LAMBDA_BINARY_ACTION(*,arithmetic_action<multiply_action>)
|
---|
209 | BOOST_LAMBDA_BINARY_ACTION(/,arithmetic_action<divide_action>)
|
---|
210 | BOOST_LAMBDA_BINARY_ACTION(%,arithmetic_action<remainder_action>)
|
---|
211 |
|
---|
212 | BOOST_LAMBDA_BINARY_ACTION(<<,bitwise_action<leftshift_action>)
|
---|
213 | BOOST_LAMBDA_BINARY_ACTION(>>,bitwise_action<rightshift_action>)
|
---|
214 | BOOST_LAMBDA_BINARY_ACTION(&,bitwise_action<and_action>)
|
---|
215 | BOOST_LAMBDA_BINARY_ACTION(|,bitwise_action<or_action>)
|
---|
216 | BOOST_LAMBDA_BINARY_ACTION(^,bitwise_action<xor_action>)
|
---|
217 |
|
---|
218 | BOOST_LAMBDA_BINARY_ACTION(<,relational_action<less_action>)
|
---|
219 | BOOST_LAMBDA_BINARY_ACTION(>,relational_action<greater_action>)
|
---|
220 | BOOST_LAMBDA_BINARY_ACTION(<=,relational_action<lessorequal_action>)
|
---|
221 | BOOST_LAMBDA_BINARY_ACTION(>=,relational_action<greaterorequal_action>)
|
---|
222 | BOOST_LAMBDA_BINARY_ACTION(==,relational_action<equal_action>)
|
---|
223 | BOOST_LAMBDA_BINARY_ACTION(!=,relational_action<notequal_action>)
|
---|
224 |
|
---|
225 | BOOST_LAMBDA_BINARY_ACTION(+=,arithmetic_assignment_action<plus_action>)
|
---|
226 | BOOST_LAMBDA_BINARY_ACTION(-=,arithmetic_assignment_action<minus_action>)
|
---|
227 | BOOST_LAMBDA_BINARY_ACTION(*=,arithmetic_assignment_action<multiply_action>)
|
---|
228 | BOOST_LAMBDA_BINARY_ACTION(/=,arithmetic_assignment_action<divide_action>)
|
---|
229 | BOOST_LAMBDA_BINARY_ACTION(%=,arithmetic_assignment_action<remainder_action>)
|
---|
230 |
|
---|
231 | BOOST_LAMBDA_BINARY_ACTION(<<=,bitwise_assignment_action<leftshift_action>)
|
---|
232 | BOOST_LAMBDA_BINARY_ACTION(>>=,bitwise_assignment_action<rightshift_action>)
|
---|
233 | BOOST_LAMBDA_BINARY_ACTION(&=,bitwise_assignment_action<and_action>)
|
---|
234 | BOOST_LAMBDA_BINARY_ACTION(|=,bitwise_assignment_action<or_action>)
|
---|
235 | BOOST_LAMBDA_BINARY_ACTION(^=,bitwise_assignment_action<xor_action>)
|
---|
236 |
|
---|
237 | BOOST_LAMBDA_BINARY_ACTION(=,other_action< assignment_action>)
|
---|
238 |
|
---|
239 |
|
---|
240 | BOOST_LAMBDA_PREFIX_UNARY_ACTION(+, unary_arithmetic_action<plus_action>)
|
---|
241 | BOOST_LAMBDA_PREFIX_UNARY_ACTION(-, unary_arithmetic_action<minus_action>)
|
---|
242 | BOOST_LAMBDA_PREFIX_UNARY_ACTION(~, bitwise_action<not_action>)
|
---|
243 | BOOST_LAMBDA_PREFIX_UNARY_ACTION(!, logical_action<not_action>)
|
---|
244 | BOOST_LAMBDA_PREFIX_UNARY_ACTION(++, pre_increment_decrement_action<increment_action>)
|
---|
245 | BOOST_LAMBDA_PREFIX_UNARY_ACTION(--, pre_increment_decrement_action<decrement_action>)
|
---|
246 |
|
---|
247 | BOOST_LAMBDA_PREFIX_UNARY_ACTION(&,other_action<addressof_action>)
|
---|
248 | BOOST_LAMBDA_PREFIX_UNARY_ACTION(*,other_action<contentsof_action>)
|
---|
249 |
|
---|
250 | BOOST_LAMBDA_POSTFIX_UNARY_ACTION(++, post_increment_decrement_action<increment_action>)
|
---|
251 | BOOST_LAMBDA_POSTFIX_UNARY_ACTION(--, post_increment_decrement_action<decrement_action>)
|
---|
252 |
|
---|
253 |
|
---|
254 | #undef BOOST_LAMBDA_POSTFIX_UNARY_ACTION
|
---|
255 | #undef BOOST_LAMBDA_PREFIX_UNARY_ACTION
|
---|
256 | #undef BOOST_LAMBDA_BINARY_ACTION
|
---|
257 |
|
---|
258 | } // namespace lambda
|
---|
259 | } // namespace boost
|
---|
260 |
|
---|
261 | #endif
|
---|
262 |
|
---|
263 |
|
---|
264 |
|
---|
265 |
|
---|
266 |
|
---|
267 |
|
---|
268 |
|
---|
269 |
|
---|
270 |
|
---|
271 |
|
---|