[libsigcplusplus/libsigc++-2-10: 2/2] signal: Allow sigc::signal<R(Args...)> declaration, like std::function.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsigcplusplus/libsigc++-2-10: 2/2] signal: Allow sigc::signal<R(Args...)> declaration, like std::function.
- Date: Sat, 12 Mar 2016 15:04:49 +0000 (UTC)
commit a625175a289339da59fee39c7b22e20432f152b7
Author: Murray Cumming <murrayc murrayc com>
Date: Sat Mar 12 16:01:51 2016 +0100
signal: Allow sigc::signal<R(Args...)> declaration, like std::function.
By adding template specializations that repeats the signal*
template declarations, though it would be good to avoid the repetition.
Bug 763393
sigc++/macros/signal.h.m4 | 93 +++++++++++++++++++++++++++++++++++++++++++++
tests/test_signal.cc | 10 +++++
2 files changed, 103 insertions(+), 0 deletions(-)
---
diff --git a/sigc++/macros/signal.h.m4 b/sigc++/macros/signal.h.m4
index 157128a..98a28d5 100644
--- a/sigc++/macros/signal.h.m4
+++ b/sigc++/macros/signal.h.m4
@@ -555,6 +555,99 @@ ifelse($1, $2,[dnl
}
};
+/**
+ * This specialization allow use of the sigc::signal<R(Args...)> syntax,
+ */
+template <LIST(class T_return, LOOP(class T_arg%1, $1))>
+class signal<T_return(LIST(LOOP(T_arg%1, $1)))>
+ : public signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>
+{
+public:
+ifelse($1, $2,[dnl
+ /** Convenience wrapper for the numbered sigc::signal# templates.
+ * Like sigc::signal but the additional template parameter @e T_accumulator
+ * defines the accumulator type that should be used.
+ *
+ * An accumulator is a functor that uses a pair of special iterators
+ * to step through a list of slots and calculate a return value
+ * from the results of the slot invokations. The iterators' operator*()
+ * executes the slot. The return value is buffered, so that in an expression
+ * like @code a = (*i) * (*i); @endcode the slot is executed only once.
+ * The accumulator must define its return value as @p result_type.
+ *
+ * @par Example 1:
+ * This accumulator calculates the arithmetic mean value:
+ * @code
+ * struct arithmetic_mean_accumulator
+ * {
+ * typedef double result_type;
+ * template<typename T_iterator>
+ * result_type operator()(T_iterator first, T_iterator last) const
+ * {
+ * result_type value_ = 0;
+ * int n_ = 0;
+ * for (; first != last; ++first, ++n_)
+ * value_ += *first;
+ * return value_ / n_;
+ * }
+ * };
+ * @endcode
+ *
+ * @par Example 2:
+ * This accumulator stops signal emission when a slot returns zero:
+ * @code
+ * struct interruptable_accumulator
+ * {
+ * typedef bool result_type;
+ * template<typename T_iterator>
+ * result_type operator()(T_iterator first, T_iterator last) const
+ * {
+ * for (; first != last; ++first, ++n_)
+ * if (!*first) return false;
+ * return true;
+ * }
+ * };
+ * @endcode
+ *
+ * @ingroup signal
+],[
+ /** Convenience wrapper for the numbered sigc::signal$1 template.
+ * Like sigc::signal but the additional template parameter @e T_accumulator
+ * defines the accumulator type that should be used.
+])dnl
+ */
+ template <class T_accumulator>
+ class accumulated
+ : public signal$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)>
+ {
+ public:
+ accumulated() {}
+ accumulated(const accumulated& src)
+ : signal$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)>(src) {}
+ };
+
+ signal() {}
+
+ signal(const signal& src)
+ : signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>(src) {}
+
+ signal(signal&& src)
+ : signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>(std::move(src)) {}
+
+ signal& operator=(const signal& src)
+ {
+ signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>::operator=(src);
+ return *this;
+ }
+
+ signal& operator=(signal&& src)
+ {
+ signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>::operator=(std::move(src));
+ return *this;
+ }
+};
+
+
])
divert(0)
diff --git a/tests/test_signal.cc b/tests/test_signal.cc
index 744acbe..bdd50dc 100644
--- a/tests/test_signal.cc
+++ b/tests/test_signal.cc
@@ -111,6 +111,15 @@ void test_make_slot()
util->check_result(result_stream, "foo(int 3) bar(float 3) foo(int 3) ");
}
+void test_std_function_style_syntax()
+{
+ sigc::signal<int(int)> sig;
+ sig.connect(sigc::ptr_fun(&foo));
+
+ sig(1);
+ util->check_result(result_stream, "foo(int 1) ");
+}
+
} // end anonymous namespace
int main(int argc, char* argv[])
@@ -125,6 +134,7 @@ int main(int argc, char* argv[])
test_auto_disconnection();
test_reference();
test_make_slot();
+ test_std_function_style_syntax();
return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]