1 dnl Copyright 2002, The libsigc++ Development Team
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.
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.
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
18 include(template.macros.m4)
20 define([FUNCTOR_PTR_FUN],[dnl
21 template <LIST(LOOP(class T_arg%1, $1), class T_return)> class pointer_functor$1;
22 template <LIST(LOOP(class T_arg%1, $1), class T_return)>
23 struct functor_trait<T_return (*)(LOOP(T_arg%1, $1)), false, false>
25 typedef T_return result_type;
26 typedef pointer_functor$1<LIST(LOOP(T_arg%1, $1), T_return)> functor_type;
30 define([FUNCTOR_MEM_FUN],[dnl
31 template <LIST(class T_return, class T_obj, LOOP(class T_arg%1, $1))> class mem_functor$1;
32 template <LIST(class T_return, class T_obj, LOOP(class T_arg%1, $1))> class const_mem_functor$1;
33 template <LIST(LOOP(class T_arg%1, $1), class T_return, class T_obj)>
34 struct functor_trait<T_return (T_obj::*)(LOOP(T_arg%1, $1)), false, false>
36 typedef T_return result_type;
37 typedef mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))> functor_type;
39 template <LIST(LOOP(class T_arg%1, $1), class T_return, class T_obj)>
40 struct functor_trait<T_return (T_obj::*)(LOOP(T_arg%1, $1)) const, false, false>
42 typedef T_return result_type;
43 typedef const_mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))> functor_type;
49 _FIREWALL([FUNCTORS_FUNCTOR_TRAIT])
50 #include <sigc++/type_traits.h>
51 #include <type_traits>
55 //TODO: When we can break ABI, replace nil by something else, such as sigc_nil.
56 // nil is a keyword in Objective C++. When gcc is used for compiling Objective C++
57 // programs, nil is defined as a preprocessor macro.
58 // https://bugzilla.gnome.org/show_bug.cgi?id=695235
59 #if defined(nil) && defined(SIGC_PRAGMA_PUSH_POP_MACRO)
60 #define SIGC_NIL_HAS_BEEN_PUSHED 1
61 #pragma push_macro("nil")
66 * The nil struct type is used as default template argument in the
67 * unnumbered sigc::signal and sigc::slot templates.
72 #ifndef DOXYGEN_SHOULD_SKIP_THIS
78 #ifdef SIGC_NIL_HAS_BEEN_PUSHED
79 #undef SIGC_NIL_HAS_BEEN_PUSHED
80 #pragma pop_macro("nil")
83 /** @defgroup sigcfunctors Functors
84 * Functors are copyable types that define operator()().
86 * Types that define operator()() overloads with different return types are referred to
87 * as multi-type functors. Multi-type functors are only partially supported in libsigc++.
89 * Closures are functors that store all information needed to invoke a callback from operator()().
91 * Adaptors are functors that alter the signature of a functor's operator()().
93 * libsigc++ defines numerous functors, closures and adaptors.
94 * Since libsigc++ is a callback library, most functors are also closures.
95 * The documentation doesn't distinguish between functors and closures.
97 * The basic functor types libsigc++ provides are created with ptr_fun() and mem_fun()
98 * and can be converted into slots implicitly.
99 * The set of adaptors that ships with libsigc++ is documented in the @ref adaptors module.
101 * If you want to mix user-defined and third party functors with libsigc++,
102 * and you want them to be implicitly convertible into slots, libsigc++ must know
103 * the result type of your functors. There are different ways to achieve that.
105 * - Derive your functors from sigc::functor_base and place
106 * <tt>typedef T_return result_type;</tt> in the class definition.
107 * - Use the macro SIGC_FUNCTOR_TRAIT(T_functor,T_return) in namespace sigc.
108 * Multi-type functors are only partly supported.
109 * - For functors not derived from sigc::functor_base, and not specified with
110 * SIGC_FUNCTOR_TRAIT(), libsigc++ tries to deduce the result type with the
111 * C++11 decltype() specifier. That attempt usually succeeds if the functor
112 * has a single operator()(), but it fails if operator()() is overloaded.
113 * - Use the macro #SIGC_FUNCTORS_HAVE_RESULT_TYPE, if you want libsigc++ to assume
114 * that result_type is defined in all user-defined or third party functors,
115 * whose result type can't be deduced in any other way.
117 * If all these ways to deduce the result type fail, void is assumed.
119 * With libsigc++ versions before 2.6, the macro
120 * #SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE activated the test with
121 * decltype(). That macro is now unneccesary and deprecated.
124 /** A hint to the compiler.
125 * All functors which define @p result_type should publically inherit from this hint.
127 * @ingroup sigcfunctors
129 struct functor_base {};
131 /** Helper class, to determine if decltype() can deduce the result type of a functor.
133 * @ingroup sigcfunctors
135 template <typename T_functor>
136 class can_deduce_result_type_with_decltype
147 static biggerthanint checksize(...);
149 // If decltype(&X_functor::operator()) can't be evaluated, this checksize() overload
150 // is ignored because of the SFINAE rule (Substitution Failure Is Not An Error).
151 template <typename X_functor>
152 static int checksize(X_functor* obj, decltype(&X_functor::operator()) p = nullptr);
155 static const bool value
156 #ifndef DOXYGEN_SHOULD_SKIP_THIS
157 = sizeof(checksize(static_cast<T_functor*>(nullptr))) == sizeof(int)
163 /** Trait that specifies the return type of any type.
164 * Template specializations for functors derived from sigc::functor_base,
165 * for other functors whose result type can be deduced with decltype(),
166 * for function pointers and for class methods are provided.
168 * @tparam T_functor Functor type.
169 * @tparam I_derives_functor_base Whether @p T_functor inherits from sigc::functor_base.
170 * @tparam I_can_use_decltype Whether the result type of @p T_functor can be deduced
173 * @ingroup sigcfunctors
175 template <class T_functor,
176 bool I_derives_functor_base = std::is_base_of<functor_base,T_functor>::value,
177 bool I_can_use_decltype = can_deduce_result_type_with_decltype<T_functor>::value>
180 typedef void result_type;
181 typedef T_functor functor_type;
184 #ifndef DOXYGEN_SHOULD_SKIP_THIS
185 template <class T_functor, bool I_can_use_decltype>
186 struct functor_trait<T_functor, true, I_can_use_decltype>
188 typedef typename T_functor::result_type result_type;
189 typedef T_functor functor_type;
192 template <typename T_functor>
193 struct functor_trait<T_functor, false, true>
195 typedef typename functor_trait<decltype(&T_functor::operator()), false, false>::result_type result_type;
196 typedef T_functor functor_type;
198 #endif // DOXYGEN_SHOULD_SKIP_THIS
200 /** Helper macro, if you want to mix user-defined and third party functors with libsigc++.
202 * If you want to mix functors not derived from sigc::functor_base with libsigc++, and
203 * these functors define @p result_type, use this macro inside namespace sigc like so:
205 * namespace sigc { SIGC_FUNCTORS_HAVE_RESULT_TYPE }
208 * @ingroup sigcfunctors
210 #define SIGC_FUNCTORS_HAVE_RESULT_TYPE \
211 template <class T_functor> \
212 struct functor_trait<T_functor, false, false> \
214 typedef typename T_functor::result_type result_type; \
215 typedef T_functor functor_type; \
218 /** Helper macro, if you want to mix user-defined and third party functors with libsigc++.
220 * If you want to mix functors not derived from sigc::functor_base with libsigc++, and
221 * these functors don't define @p result_type, use this macro inside namespace sigc
222 * to expose the return type of the functors like so:
225 * SIGC_FUNCTOR_TRAIT(first_functor_type, return_type_of_first_functor_type)
226 * SIGC_FUNCTOR_TRAIT(second_functor_type, return_type_of_second_functor_type)
231 * @ingroup sigcfunctors
233 #define SIGC_FUNCTOR_TRAIT(T_functor,T_return) \
235 struct functor_trait<T_functor, false, false> \
237 typedef T_return result_type; \
238 typedef T_functor functor_type; \
241 struct functor_trait<T_functor, false, true> \
243 typedef T_return result_type; \
244 typedef T_functor functor_type; \
247 #ifndef SIGCXX_DISABLE_DEPRECATED
248 /** Helper macro, if you want to mix user-defined and third party functors with libsigc++.
250 * If you want to mix functors not derived from sigc::functor_base with libsigc++,
251 * and your compiler can deduce the result type of the functor with the C++11
252 * keyword <tt>decltype</tt>, use this macro inside namespace sigc like so:
255 * SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
259 * Functors with overloaded operator()() are not supported.
263 * @deprecated This macro does nothing. The test it activated in libsigc++
264 * versions before 2.6, is now unconditionally activated.
266 * @ingroup sigcfunctors
268 #define SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE // Empty
269 #endif // SIGCXX_DISABLE_DEPRECATED
271 #ifndef DOXYGEN_SHOULD_SKIP_THIS
272 // detect the return type and the functor version of non-functor types.
273 FOR(0,CALL_SIZE,[[FUNCTOR_PTR_FUN(%1)]])
274 FOR(0,CALL_SIZE,[[FUNCTOR_MEM_FUN(%1)]])
275 #endif // DOXYGEN_SHOULD_SKIP_THIS
277 } /* namespace sigc */