Skip to content

Commit a625175

Browse files
committed
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
1 parent 5573e97 commit a625175

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

sigc++/macros/signal.h.m4

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,99 @@ ifelse($1, $2,[dnl
555555
}
556556
};
557557
558+
/**
559+
* This specialization allow use of the sigc::signal<R(Args...)> syntax,
560+
*/
561+
template <LIST(class T_return, LOOP(class T_arg%1, $1))>
562+
class signal<T_return(LIST(LOOP(T_arg%1, $1)))>
563+
: public signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>
564+
{
565+
public:
566+
ifelse($1, $2,[dnl
567+
/** Convenience wrapper for the numbered sigc::signal# templates.
568+
* Like sigc::signal but the additional template parameter @e T_accumulator
569+
* defines the accumulator type that should be used.
570+
*
571+
* An accumulator is a functor that uses a pair of special iterators
572+
* to step through a list of slots and calculate a return value
573+
* from the results of the slot invokations. The iterators' operator*()
574+
* executes the slot. The return value is buffered, so that in an expression
575+
* like @code a = (*i) * (*i); @endcode the slot is executed only once.
576+
* The accumulator must define its return value as @p result_type.
577+
*
578+
* @par Example 1:
579+
* This accumulator calculates the arithmetic mean value:
580+
* @code
581+
* struct arithmetic_mean_accumulator
582+
* {
583+
* typedef double result_type;
584+
* template<typename T_iterator>
585+
* result_type operator()(T_iterator first, T_iterator last) const
586+
* {
587+
* result_type value_ = 0;
588+
* int n_ = 0;
589+
* for (; first != last; ++first, ++n_)
590+
* value_ += *first;
591+
* return value_ / n_;
592+
* }
593+
* };
594+
* @endcode
595+
*
596+
* @par Example 2:
597+
* This accumulator stops signal emission when a slot returns zero:
598+
* @code
599+
* struct interruptable_accumulator
600+
* {
601+
* typedef bool result_type;
602+
* template<typename T_iterator>
603+
* result_type operator()(T_iterator first, T_iterator last) const
604+
* {
605+
* for (; first != last; ++first, ++n_)
606+
* if (!*first) return false;
607+
* return true;
608+
* }
609+
* };
610+
* @endcode
611+
*
612+
* @ingroup signal
613+
],[
614+
/** Convenience wrapper for the numbered sigc::signal$1 template.
615+
* Like sigc::signal but the additional template parameter @e T_accumulator
616+
* defines the accumulator type that should be used.
617+
])dnl
618+
*/
619+
template <class T_accumulator>
620+
class accumulated
621+
: public signal$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)>
622+
{
623+
public:
624+
accumulated() {}
625+
accumulated(const accumulated& src)
626+
: signal$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)>(src) {}
627+
};
628+
629+
signal() {}
630+
631+
signal(const signal& src)
632+
: signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>(src) {}
633+
634+
signal(signal&& src)
635+
: signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>(std::move(src)) {}
636+
637+
signal& operator=(const signal& src)
638+
{
639+
signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>::operator=(src);
640+
return *this;
641+
}
642+
643+
signal& operator=(signal&& src)
644+
{
645+
signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>::operator=(std::move(src));
646+
return *this;
647+
}
648+
};
649+
650+
558651
])
559652

560653
divert(0)

tests/test_signal.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,15 @@ void test_make_slot()
111111
util->check_result(result_stream, "foo(int 3) bar(float 3) foo(int 3) ");
112112
}
113113

114+
void test_std_function_style_syntax()
115+
{
116+
sigc::signal<int(int)> sig;
117+
sig.connect(sigc::ptr_fun(&foo));
118+
119+
sig(1);
120+
util->check_result(result_stream, "foo(int 1) ");
121+
}
122+
114123
} // end anonymous namespace
115124

116125
int main(int argc, char* argv[])
@@ -125,6 +134,7 @@ int main(int argc, char* argv[])
125134
test_auto_disconnection();
126135
test_reference();
127136
test_make_slot();
137+
test_std_function_style_syntax();
128138

129139
return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
130140
}

0 commit comments

Comments
 (0)