Skip to content

Commit 3ee4d05

Browse files
committed
(:automated_merge:) Merge remote-tracking branch 'libsigcplusplus-original/master'
2 parents 681c85e + f36ec36 commit 3ee4d05

File tree

9 files changed

+223
-0
lines changed

9 files changed

+223
-0
lines changed

sigc++/filelist.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ sigc_public_h = \
2727
scoped_connection.h \
2828
signal.h \
2929
signal_base.h \
30+
signal_connect.h \
3031
slot.h \
3132
trackable.h \
3233
tuple-utils/tuple_cdr.h \

sigc++/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ sigc_h_files = [
2525
'scoped_connection.h',
2626
'signal.h',
2727
'signal_base.h',
28+
'signal_connect.h',
2829
'slot.h',
2930
'trackable.h',
3031
'type_traits.h',

sigc++/sigc++.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
#include <sigc++/connection.h>
120120
#include <sigc++/scoped_connection.h>
121121
#include <sigc++/trackable.h>
122+
#include <sigc++/signal_connect.h>
122123
#include <sigc++/adaptors/adaptors.h>
123124
#include <sigc++/functors/functors.h>
124125

sigc++/signal_base.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,22 @@ struct SIGC_API signal_impl_holder
281281
* a @ref sigc::slot<T_return(T_arg...)> "sigc::slot"
282282
* and connected to a signal. See @ref slot "Slots" and
283283
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()".
284+
*
285+
* Use @ref sigc::signal_connect() to connect a method or function to a signal
286+
* without having to explicitly write the required template parameters in case
287+
* of method or function overloading.
288+
*
289+
* @code
290+
* sigc::signal<void(int)> sig;
291+
* void fun(int);
292+
* void fun(double);
293+
* sig.connect(sigc::ptr_fun<void, int>(fun));
294+
* // or more simply:
295+
* sigc::signal_connect(sig, fun);
296+
* @endcode
297+
*
298+
* It can also be used as a replacement for calling signal::connect() with a
299+
* sigc::mem_fun() or a sigc::ptr_fun().
284300
*/
285301

286302
// TODO: When we can break ABI, let signal_base derive from trackable again,

sigc++/signal_connect.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2024, The libsigc++ Development Team
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, write to the Free Software
16+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17+
*
18+
*/
19+
20+
#ifndef SIGC_SIGNAL_CONNECT_H
21+
#define SIGC_SIGNAL_CONNECT_H
22+
23+
#include <sigc++/signal.h>
24+
#include <sigc++/functors/ptr_fun.h>
25+
#include <sigc++/functors/mem_fun.h>
26+
27+
namespace sigc
28+
{
29+
30+
/** Connect a function to a signal
31+
* @param signal The signal to connect to.
32+
* @param fun The function that should be wrapped.
33+
* @return A connection.
34+
*
35+
* @newin{3,8}
36+
* @ingroup signal
37+
*/
38+
template<typename T_return, typename... T_arg>
39+
inline connection
40+
signal_connect(signal<T_return(T_arg...)>& signal, T_return (*fun)(T_arg...))
41+
{
42+
return signal.connect(ptr_fun<T_return, T_arg...>(fun));
43+
}
44+
45+
/** Connect a non-const method to a signal
46+
* @param signal The signal to connect to.
47+
* @param obj Reference to object instance the functor should operate on.
48+
* @param fun Pointer to method that should be wrapped.
49+
* @return A connection.
50+
*
51+
* @newin{3,8}
52+
* @ingroup signal
53+
*/
54+
template<typename T_return, typename T_obj, typename... T_arg>
55+
inline connection
56+
signal_connect(signal<T_return(T_arg...)>& signal, T_obj& obj, T_return (T_obj::*fun)(T_arg...))
57+
{
58+
return signal.connect(mem_fun<T_return, T_obj, T_obj, T_arg...>(obj, fun));
59+
}
60+
61+
/** Connect a const method to a signal
62+
* @param signal The signal to connect to.
63+
* @param obj Reference to object instance the functor should operate on.
64+
* @param fun Pointer to method that should be wrapped.
65+
* @return A connection.
66+
*
67+
* @newin{3,8}
68+
* @ingroup signal
69+
*/
70+
template<typename T_return, typename T_obj, typename... T_arg>
71+
inline connection
72+
signal_connect(signal<T_return(T_arg...)>& signal, const T_obj& obj, T_return (T_obj::*fun)(T_arg...) const)
73+
{
74+
return signal.connect(mem_fun<T_return, const T_obj, const T_obj, T_arg...>(obj, fun));
75+
}
76+
77+
} /* namespace sigc */
78+
79+
#endif /* SIGC_SIGNAL_CONNECT_H */

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ set (TEST_SOURCE_FILES
4242
test_rvalue_ref.cc
4343
test_scoped_connection.cc
4444
test_signal.cc
45+
test_signal_connect.cc
4546
test_signal_move.cc
4647
test_size.cc
4748
test_slot.cc

tests/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ check_PROGRAMS = \
4949
test_rvalue_ref \
5050
test_scoped_connection \
5151
test_signal \
52+
test_signal_connect \
5253
test_signal_move \
5354
test_size \
5455
test_slot \
@@ -95,6 +96,7 @@ test_retype_return_SOURCES = test_retype_return.cc $(sigc_test_util)
9596
test_rvalue_ref_SOURCES = test_rvalue_ref.cc $(sigc_test_util)
9697
test_scoped_connection_SOURCES = test_scoped_connection.cc $(sigc_test_util)
9798
test_signal_SOURCES = test_signal.cc $(sigc_test_util)
99+
test_signal_connect_SOURCES = test_signal_connect.cc $(sigc_test_util)
98100
test_signal_move_SOURCES = test_signal_move.cc $(sigc_test_util)
99101
test_size_SOURCES = test_size.cc $(sigc_test_util)
100102
test_slot_SOURCES = test_slot.cc $(sigc_test_util)

tests/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ test_programs = [
3131
[[], 'test_rvalue_ref', ['test_rvalue_ref.cc', 'testutilities.cc']],
3232
[[], 'test_scoped_connection', ['test_scoped_connection.cc', 'testutilities.cc']],
3333
[[], 'test_signal', ['test_signal.cc', 'testutilities.cc']],
34+
[[], 'test_signal_connect', ['test_signal_connect.cc', 'testutilities.cc']],
3435
[[], 'test_signal_move', ['test_signal_move.cc', 'testutilities.cc']],
3536
[[], 'test_size', ['test_size.cc', 'testutilities.cc']],
3637
[[], 'test_slot', ['test_slot.cc', 'testutilities.cc']],

tests/test_signal_connect.cc

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/* Copyright 2024, The libsigc++ Development Team
2+
* Assigned to public domain. Use as you wish without restriction.
3+
*/
4+
5+
#include "testutilities.h"
6+
#include <sigc++/trackable.h>
7+
#include <sigc++/signal_connect.h>
8+
9+
namespace
10+
{
11+
12+
TestUtilities* util = nullptr;
13+
std::ostringstream result_stream;
14+
15+
void
16+
fun(int i)
17+
{
18+
result_stream << "fun(int " << i << ")";
19+
}
20+
21+
[[maybe_unused]]
22+
void
23+
fun(double d)
24+
{
25+
result_stream << "fun(double " << d << ")";
26+
}
27+
28+
struct foo : public sigc::trackable
29+
{
30+
void fun_nonconst(int i)
31+
{
32+
result_stream << "foo::fun_nonconst(int " << i << ")";
33+
}
34+
35+
void fun_nonconst(double d)
36+
{
37+
result_stream << "foo::fun_nonconst(double " << d << ")";
38+
}
39+
40+
void fun_const(int i) const
41+
{
42+
result_stream << "foo::fun_const(int " << i << ")";
43+
}
44+
45+
void fun_const(double d) const
46+
{
47+
result_stream << "foo::fun_const(double " << d << ")";
48+
}
49+
};
50+
51+
void
52+
test_signal_connect_fun()
53+
{
54+
sigc::signal<void(int)> signal;
55+
56+
sigc::signal_connect(signal, &fun);
57+
58+
signal.emit(42);
59+
util->check_result(result_stream, "fun(int 42)");
60+
}
61+
62+
void
63+
test_signal_connect_method_nonconst()
64+
{
65+
sigc::signal<void(int)> signal;
66+
foo f;
67+
68+
sigc::signal_connect(signal, f, &foo::fun_nonconst);
69+
70+
signal.emit(42);
71+
util->check_result(result_stream, "foo::fun_nonconst(int 42)");
72+
}
73+
74+
void
75+
test_signal_connect_method_const()
76+
{
77+
sigc::signal<void(int)> signal;
78+
foo f;
79+
80+
sigc::signal_connect(signal, f, &foo::fun_const);
81+
82+
signal.emit(42);
83+
util->check_result(result_stream, "foo::fun_const(int 42)");
84+
}
85+
86+
void
87+
test_signal_connect_method_const_with_const_object()
88+
{
89+
sigc::signal<void(int)> signal;
90+
const foo f;
91+
92+
sigc::signal_connect(signal, f, &foo::fun_const);
93+
94+
signal.emit(42);
95+
util->check_result(result_stream, "foo::fun_const(int 42)");
96+
}
97+
98+
void
99+
test_signal_connect_method()
100+
{
101+
test_signal_connect_method_nonconst();
102+
test_signal_connect_method_const();
103+
test_signal_connect_method_const_with_const_object();
104+
}
105+
106+
} // end anonymous namespace
107+
108+
int
109+
main(int argc, char* argv[])
110+
{
111+
util = TestUtilities::get_instance();
112+
113+
if (!util->check_command_args(argc, argv))
114+
return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
115+
116+
test_signal_connect_fun();
117+
118+
test_signal_connect_method();
119+
120+
return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
121+
}

0 commit comments

Comments
 (0)