]> git.tdb.fi Git - ext/sigc++-2.0.git/blob - sigc++/adaptors/lambda/macros/base.h.m4
Import libsigc++ 2.10.8 sources
[ext/sigc++-2.0.git] / sigc++ / adaptors / lambda / macros / base.h.m4
1 dnl Copyright 2002, The libsigc++ Development Team
2 dnl
3 dnl This library is free software; you can redistribute it and/or
4 dnl modify it under the terms of the GNU Lesser General Public
5 dnl License as published by the Free Software Foundation; either
6 dnl version 2.1 of the License, or (at your option) any later version.
7 dnl
8 dnl This library is distributed in the hope that it will be useful,
9 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
10 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 dnl Lesser General Public License for more details.
12 dnl
13 dnl You should have received a copy of the GNU Lesser General Public
14 dnl License along with this library; if not, write to the Free Software
15 dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 dnl
17 divert(-1)
18 include(template.macros.m4)
19
20 define([LAMBDA_DO],[dnl
21   template <LOOP(class T_arg%1, $1)>
22   typename deduce_result_type<LOOP(T_arg%1,$1)>::type
23   operator ()(LOOP(T_arg%1 _A_%1, $1)) const
24     { return value_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP(_P_(T_arg%1), $1)>
25              (LOOP(_A_%1, $1));
26     }
27
28   #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
29   template <LOOP(class T_arg%1, $1)>
30   typename deduce_result_type<LOOP(T_arg%1,$1)>::type
31   sun_forte_workaround(LOOP(T_arg%1 _A_%1, $1)) const
32     { return value_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP(_P_(T_arg%1), $1)>
33              (LOOP(_A_%1, $1));
34     }
35   #endif //SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
36
37 ])dnl
38 define([LAMBDA_DO_VALUE],[dnl
39   template <LOOP(class T_arg%1, $1)>
40   result_type operator ()(LOOP(T_arg%1, $1)) const
41     { return value_; }
42
43   #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
44   template <LOOP(class T_arg%1, $1)>
45   result_type sun_forte_workaround(LOOP(T_arg%1, $1)) const
46     { return value_; }
47   #endif //SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
48
49 ])dnl
50
51 divert(0)dnl
52 #ifndef _SIGC_LAMBDA_BASE_HPP_
53 #define _SIGC_LAMBDA_BASE_HPP_
54 #include <sigc++/adaptors/adaptor_trait.h>
55 #include <sigc++/reference_wrapper.h>
56 #include <type_traits>
57
58 _DEPRECATE_IFDEF_START
59
60 namespace sigc {
61
62 #ifndef DOXYGEN_SHOULD_SKIP_THIS
63 // libsigc++'s lambda functions have been removed from the API.
64 // Some code must be kept until we can break ABI.
65 /** @defgroup lambdas Lambdas
66  * libsigc++ ships with basic lambda functionality and the sigc::group adaptor,
67  * which uses lambdas to transform a functor's parameter list.
68  *
69  * The lambda selectors sigc::_1, sigc::_2, ..., sigc::_7 are used to select the
70  * first, second, ..., seventh argument from a list.
71  *
72  * @par Examples:
73  * @code
74  * std::cout << sigc::_1(10,20,30); // returns 10
75  * std::cout << sigc::_2(10,20,30); // returns 20
76  * @endcode
77  *
78  * Operators are defined so that, for example, lambda selectors can be used as
79  * placeholders in arithmetic expressions.
80  *
81  * @par Examples:
82  * @code
83  * std::cout << (sigc::_1 + 5)(3); // returns (3 + 5)
84  * std::cout << (sigc::_1 * sigc::_2)(7,10); // returns (7 * 10)
85  * @endcode
86  *
87  * If your compiler supports C++11 lambda expressions, they are often a good
88  * alternative to libsigc++'s lambda expressions. The following examples are
89  * equivalent to the previous ones.
90  * @code
91  * [[]] (int x, int, int) -> int { return x; }(10,20,30); // returns 10
92  * [[]] (int, int y, int) -> int { return y; }(10,20,30); // returns 20
93  * [[]] (int x) -> int { return x + 5; }(3); // returns (3 + 5)
94  * [[]] (int x, int y) -> int { return x * y; }(7,10); // returns (7 * 10)
95  * @endcode
96  *
97  * @deprecated Use C++11 lambda expressions or %std::bind() instead.
98  */
99
100 /** A hint to the compiler.
101  * All lambda types publically inherit from this hint.
102  *
103  * @deprecated Use C++11 lambda expressions instead.
104  *
105  * @ingroup lambdas
106  */
107 struct lambda_base : public adaptor_base {};
108
109 // Forward declaration of lambda.
110 template <class T_type> struct lambda;
111
112 namespace internal {
113
114 /** Abstracts lambda functionality.
115  * Objects of this type store a value that may be of type lambda itself.
116  * In this case, operator()() executes the lambda (a lambda is always a functor at the same time).
117  * Otherwise, operator()() simply returns the stored value.
118  *
119  * @deprecated Use C++11 lambda expressions instead.
120  *
121  * @ingroup lambdas
122  */
123 template <class T_type, bool I_islambda = std::is_base_of<lambda_base, T_type>::value> struct lambda_core;
124
125 /** Abstracts lambda functionality (template specialization for lambda values).
126  *
127  * @deprecated Use C++11 lambda expressions instead.
128  *
129  * @ingroup lambdas
130  */
131 template <class T_type>
132 struct lambda_core<T_type, true> : public lambda_base
133 {
134   template <LOOP(class T_arg%1=void,CALL_SIZE)>
135   struct deduce_result_type
136     { typedef typename T_type::template deduce_result_type<LOOP(_P_(T_arg%1),CALL_SIZE)>::type type; };
137   typedef typename T_type::result_type result_type;
138   typedef T_type lambda_type;
139
140   result_type
141   operator()() const;
142
143 FOR(1,CALL_SIZE,[[LAMBDA_DO(%1)]])dnl
144   lambda_core() {}
145
146   explicit lambda_core(const T_type& v)
147     : value_(v) {}
148
149   T_type value_;
150 };
151
152
153 } /* namespace internal */
154
155
156 // forward declarations for lambda operators other<subscript> and other<assign>
157 template <class T_type>
158 struct other;
159 struct subscript;
160 struct assign;
161
162 template <class T_action, class T_type1, class T_type2>
163 struct lambda_operator;
164
165 template <class T_type>
166 struct unwrap_lambda_type;
167
168 /** Lambda type.
169  * Objects of this type store a value that may be of type lambda itself.
170  * In this case, operator()() executes the lambda (a lambda is always a functor at the same time).
171  * Otherwise, operator()() simply returns the stored value.
172  * The assign and subscript operators are defined to return a lambda operator.
173  *
174  * @deprecated Use C++11 lambda expressions instead.
175  *
176  * @ingroup lambdas
177  */
178 template <class T_type>
179 struct lambda : public internal::lambda_core<T_type>
180 {
181   typedef lambda<T_type> self;
182
183   lambda()
184     {}
185
186   lambda(typename type_trait<T_type>::take v)
187     : internal::lambda_core<T_type>(v)
188     {}
189
190   // operators for other<subscript>
191   template <class T_arg>
192   lambda<lambda_operator<other<subscript>, self, typename unwrap_lambda_type<T_arg>::type> >
193   operator [[]] (const T_arg& a) const
194     { typedef lambda_operator<other<subscript>, self, typename unwrap_lambda_type<T_arg>::type> lambda_operator_type;
195       return lambda<lambda_operator_type>(lambda_operator_type(this->value_, unwrap_lambda_value(a))); }
196
197   // operators for other<assign>
198   template <class T_arg>
199   lambda<lambda_operator<other<assign>, self, typename unwrap_lambda_type<T_arg>::type> >
200   operator = (const T_arg& a) const
201     { typedef lambda_operator<other<assign>, self, typename unwrap_lambda_type<T_arg>::type> lambda_operator_type;
202       return lambda<lambda_operator_type>(lambda_operator_type(this->value_, unwrap_lambda_value(a))); }
203 };
204 #endif // DOXYGEN_SHOULD_SKIP_THIS
205
206 } /* namespace sigc */
207
208 _DEPRECATE_IFDEF_END
209
210 #endif /* _SIGC_LAMBDA_BASE_HPP_ */