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 | |
---|