1 | // Boost Lambda Library - operator_lambda_func_base.hpp ----------------- |
2 | // |
3 | // Copyright (C) 1999, 2000 Jaakko Jarvi (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 | |
272 | |