1 /* Copyright 2002, The libsigc++ Development Team
2 * Assigned to public domain. Use as you wish without restriction.
5 #include "testutilities.h"
6 #include <sigc++/trackable.h>
7 #include <sigc++/signal.h>
8 #include <sigc++/connection.h>
9 #include <sigc++/adaptors/compose.h>
10 #include <sigc++/functors/ptr_fun.h>
11 #include <sigc++/functors/mem_fun.h>
15 //The Tru64 compiler seems to need this to avoid an unresolved symbol
21 std::ostringstream result_stream;
25 result_stream << "foo(" << i << ") ";
31 result_stream << "bar(" << i << ") ";
35 struct A : public sigc::trackable
39 result_stream << "A::foo(" << i << ") ";
46 result_stream << "Good bye world!";
49 struct B : public sigc::trackable
53 sig.connect(sigc::mem_fun(*this, &B::destroy));
54 sig.connect(sigc::mem_fun(*this, &B::boom));
55 sig.connect(sigc::ptr_fun(&good_bye_world));
58 void destroy() // Calling destroy() during signal emission seems weird!
59 { // However, if this works, anything will work!
60 delete this; // valgrind reports a small memory leak, that's all.
65 result_stream << "boom!";
73 sigc::signal<void> sig;
76 } // end anonymous namespace
78 int main(int argc, char* argv[])
80 auto util = TestUtilities::get_instance();
82 if (!util->check_command_args(argc, argv))
83 return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
85 sigc::signal<int, int> sig;
86 sigc::signal<int, int>::iterator confoo;
87 sigc::signal<int, int>::iterator conbar;
88 sigc::connection cona; // connection objects are safe to use beyond the life time of a signal.
92 sig.connect(sigc::mem_fun1(a, &A::foo));
93 confoo = sig.connect(sigc::ptr_fun1(&foo));
94 conbar = sig.connect(sigc::ptr_fun1(&bar));
95 result_stream << "sig is connected to A::foo, foo, bar (size=" << sig.size() << "): ";
97 util->check_result(result_stream,
98 "sig is connected to A::foo, foo, bar (size=3): A::foo(1) foo(1) bar(1) ");
99 } // auto disconnection! iterators stay valid after disconnections.
101 result_stream << "sig is connected to foo, bar (size=" << sig.size() << "): ";
103 util->check_result(result_stream, "sig is connected to foo, bar (size=2): foo(2) bar(2) ");
105 A a; // iterators stay valid after further connections.
106 cona = sig.slots().insert(conbar, sigc::mem_fun1(a, &A::foo));
107 result_stream << "sig is connected to foo, A::foo, bar (size=" << sig.size() << "): ";
109 util->check_result(result_stream,
110 "sig is connected to foo, A::foo, bar (size=3): foo(3) A::foo(3) bar(3) ");
112 conbar->disconnect(); // manual disconnection
113 result_stream << "sig is connected to foo, A::foo (size=" << sig.size() << "): ";
115 util->check_result(result_stream, "sig is connected to foo, A::foo (size=2): foo(4) A::foo(4) ");
117 confoo->disconnect(); // manual disconnection
118 result_stream << "sig is connected to A::foo (size=" << sig.size() << "): ";
120 util->check_result(result_stream, "sig is connected to A::foo (size=1): A::foo(5) ");
122 cona.disconnect(); // manual disconnection
123 result_stream << "sig is empty (size=" << sig.size() << "): ";
125 util->check_result(result_stream, "sig is empty (size=0): ");
127 cona.disconnect(); // already disconnected -> legal with connection objects, however, nothing happens ...
131 sig.connect(sigc::compose(sigc::mem_fun(a2, &A::foo), &foo));
132 result_stream << "sig is connected to compose(A::foo, foo) (size=" << sig.size() << "): ";
134 util->check_result(result_stream, "sig is connected to compose(A::foo, foo) (size=1): foo(7) A::foo(1) ");
136 result_stream << "sig is empty (size=" << sig.size() << "): ";
138 util->check_result(result_stream, "sig is empty (size=0): ");
140 { // A slot# within a slot
142 sigc::slot1<int, int> setter = sigc::mem_fun(a2, &A::foo);
143 sig.connect(sigc::compose(setter, &foo));
144 result_stream << "sig is connected to compose(slot1(A::foo), foo) (size=" << sig.size() << "): ";
146 util->check_result(result_stream, "sig is connected to compose(slot1(A::foo), foo) (size=1): foo(9) A::foo(1) ");
148 result_stream << "sig is empty (size=" << sig.size() << "): ";
150 util->check_result(result_stream, "sig is empty (size=0): ");
152 { // A slot within a slot
154 sigc::slot<int, int> setter = sigc::mem_fun(a2, &A::foo);
155 sig.connect(sigc::compose(setter, &foo));
156 result_stream << "sig is connected to compose(slot(A::foo), foo) (size=" << sig.size() << "): ";
158 util->check_result(result_stream, "sig is connected to compose(slot(A::foo), foo) (size=1): foo(11) A::foo(1) ");
160 result_stream << "sig is empty (size=" << sig.size() << "): ";
162 util->check_result(result_stream, "sig is empty (size=0): ");
164 result_stream << "deleting a signal during emission... ";
167 util->check_result(result_stream, "deleting a signal during emission... Good bye world!");
169 return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;