Skip to content

Commit 720bfb6

Browse files
committed
signal: Add connect_first()
Add connect_first(const slot_base&) and connect_first(slot_base&&) in internal::signal_impl, signal_base, signal_with_accumulator and trackable_signal_with_accumulator. Replace some calls to connect() by connect_first() in test_signal and test_scoped_connection. Fixes #81
1 parent 793d066 commit 720bfb6

File tree

12 files changed

+193
-46
lines changed

12 files changed

+193
-46
lines changed

sigc++/adaptors/bind.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ namespace sigc
5353
* sigc::bind(&foo,1,2,3)(); //fixes all three arguments and calls foo(1,2,3)
5454
* @endcode
5555
*
56-
* The functor sigc::bind() returns can be passed into
57-
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()" directly.
56+
* The functor that sigc::bind() returns can be passed directly into
57+
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()" or
58+
* @ref sigc::signal_with_accumulator::connect_first() "sigc::signal::connect_first()".
5859
*
5960
* @par Example:
6061
* @code

sigc++/adaptors/compose.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ namespace sigc
3838
* square_root(9))
3939
* @endcode
4040
*
41-
* The functor sigc::compose() returns can be passed directly into
42-
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()".
41+
* The functor that sigc::compose() returns can be passed directly into
42+
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()" or
43+
* @ref sigc::signal_with_accumulator::connect_first() "sigc::signal::connect_first()".
4344
*
4445
* @par Example:
4546
* @code

sigc++/adaptors/exception_catch.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ namespace sigc
6161
* sigc::exception_catch(&foo, my_catch())();
6262
* @endcode
6363
*
64-
* The functor sigc::exception_catch() returns can be directly passed into
65-
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()".
64+
* The functor that sigc::exception_catch() returns can be passed directly into
65+
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()" or
66+
* @ref sigc::signal_with_accumulator::connect_first() "sigc::signal::connect_first()".
6667
*
6768
* @par Example:
6869
* @code

sigc++/adaptors/hide.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ namespace sigc
5050
* sigc::hide<2>(&foo)(1,2,3); // adds a dummy parameter at the back and calls foo(1,2)
5151
* @endcode
5252
*
53-
* The functor sigc::hide() returns can be directly passed into
54-
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()".
53+
* The functor that sigc::hide() returns can be passed directly into
54+
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()" or
55+
* @ref sigc::signal_with_accumulator::connect_first() "sigc::signal::connect_first()".
5556
*
5657
* @par Example:
5758
* @code

sigc++/adaptors/retype.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ namespace sigc
4141
* @endcode
4242
*
4343
* The functor that sigc::retype() returns can be passed directly into
44-
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()".
44+
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()" or
45+
* @ref sigc::signal_with_accumulator::connect_first() "sigc::signal::connect_first()".
4546
*
4647
* @par Example:
4748
* @code

sigc++/connection.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ namespace sigc
3030
/** Convenience class for safe disconnection.
3131
*
3232
* This may be used to disconnect the referred slot at any time (disconnect()).
33-
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()"
34-
* returns a %sigc::connection.
33+
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()" and
34+
* @ref sigc::signal_with_accumulator::connect_first() "sigc::signal::connect_first()"
35+
* return a %sigc::connection.
3536
*
3637
* @code
3738
* sigc::connection conn = sig.connect(sigc::mem_fun(a, &A::foo));

sigc++/scoped_connection.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ namespace sigc
3434
*
3535
* You will use sigc::scoped_connection by constructing it from a ‘normal’,
3636
* unscoped @ref sigc::connection, such as those returned by
37-
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()", thus
38-
* ‘wrapping’ the connection in a scoped_connection, adding auto-disconnection.
37+
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()" and
38+
* @ref sigc::signal_with_accumulator::connect_first() "sigc::signal::connect_first()",
39+
* thus ‘wrapping’ the connection in a scoped_connection, adding auto-disconnection.
3940
* It can also be assigned from an unscoped connection, in which case, if there
4041
* was a previous slot referred to by the scoped connection, it is disconnected.
4142
*

sigc++/signal.h

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -374,14 +374,14 @@ struct signal_emit<void, void, T_arg...>
374374
/** Signal declaration.
375375
* %signal_with_accumulator can be used to connect() slots that are invoked
376376
* during subsequent calls to emit(). Any functor or slot
377-
* can be passed into connect(). It is converted into a slot
377+
* can be passed into connect() or connect_first(). It is converted into a slot
378378
* implicitly.
379379
*
380380
* If you want to connect one signal to another, use make_slot()
381381
* to retrieve a functor that emits the signal when invoked.
382382
*
383-
* Be careful if you directly pass one signal into the connect()
384-
* method of another: a shallow copy of the signal is made and
383+
* Be careful if you directly pass one signal into the connect() or
384+
* connect_first() method of another: a shallow copy of the signal is made and
385385
* the signal's slots are not disconnected until both the signal
386386
* and its clone are destroyed, which is probably not what you want!
387387
*
@@ -401,8 +401,8 @@ class signal_with_accumulator : public signal_base
401401
public:
402402
using slot_type = slot<T_return(T_arg...)>;
403403

404-
/** Add a slot to the list of slots.
405-
* Any functor or slot may be passed into connect().
404+
/** Add a slot at the end of the list of slots.
405+
* Any functor or slot may be passed into %connect().
406406
* It will be converted into a slot implicitly.
407407
* The returned connection may be stored for disconnection
408408
* of the slot at some later point. It stays valid until
@@ -426,7 +426,7 @@ class signal_with_accumulator : public signal_base
426426
return connection(slot_base);
427427
}
428428

429-
/** Add a slot to the list of slots.
429+
/** Add a slot at the end of the list of slots.
430430
* @see connect(const slot_type& slot_).
431431
*
432432
* @newin{2,8}
@@ -438,6 +438,45 @@ class signal_with_accumulator : public signal_base
438438
return connection(slot_base);
439439
}
440440

441+
/** Add a slot at the beginning of the list of slots.
442+
* Any functor or slot may be passed into %connect_first().
443+
* It will be converted into a slot implicitly.
444+
* The returned connection may be stored for disconnection
445+
* of the slot at some later point. It stays valid until
446+
* the slot is disconnected from the signal.
447+
* std::function<> and C++11 lambda expressions are functors.
448+
* These are examples of functors that can be connected to a signal.
449+
*
450+
* %std::bind() creates a functor, but this functor typically has an
451+
* %operator()() which is a variadic template.
452+
* Our functor_trait can't deduce the result type
453+
* of such a functor. If you first assign the return value of %std::bind()
454+
* to a std::function, you can connect the std::function to a signal.
455+
*
456+
* @param slot_ The slot to add to the list of slots.
457+
* @return A connection.
458+
*
459+
* @newin{3,6}
460+
*/
461+
connection connect_first(const slot_type& slot_)
462+
{
463+
auto iter = signal_base::connect_first(slot_);
464+
auto& slot_base = *iter;
465+
return connection(slot_base);
466+
}
467+
468+
/** Add a slot at the beginning of the list of slots.
469+
* @see connect_first(const slot_type& slot_).
470+
*
471+
* @newin{3,6}
472+
*/
473+
connection connect_first(slot_type&& slot_)
474+
{
475+
auto iter = signal_base::connect_first(std::move(slot_));
476+
auto& slot_base = *iter;
477+
return connection(slot_base);
478+
}
479+
441480
/** Triggers the emission of the signal.
442481
* During signal emission all slots that have been connected
443482
* to the signal are invoked unless they are manually set into
@@ -505,14 +544,14 @@ class signal_with_accumulator : public signal_base
505544

506545
/** signal can be used to connect() slots that are invoked
507546
* during subsequent calls to emit(). Any functor or slot
508-
* can be passed into connect(). It is converted into a slot
547+
* can be passed into connect() or connect_first(). It is converted into a slot
509548
* implicitly.
510549
*
511550
* If you want to connect one signal to another, use make_slot()
512551
* to retrieve a functor that emits the signal when invoked.
513552
*
514-
* Be careful if you directly pass one signal into the connect()
515-
* method of another: a shallow copy of the signal is made and
553+
* Be careful if you directly pass one signal into the connect() or
554+
* connect_first() method of another: a shallow copy of the signal is made and
516555
* the signal's slots are not disconnected until both the signal
517556
* and its clone are destroyed, which is probably not what you want!
518557
*
@@ -634,13 +673,14 @@ class signal<T_return(T_arg...)> : public signal_with_accumulator<T_return, void
634673
/** Signal declaration.
635674
* %trackable_signal_with_accumulator can be used to connect() slots that are invoked
636675
* during subsequent calls to emit(). Any functor or slot
637-
* can be passed into connect(). It is converted into a slot implicitly.
676+
* can be passed into connect() or connect_first(). It is converted into a slot
677+
* implicitly.
638678
*
639679
* If you want to connect one signal to another, use make_slot()
640680
* to retrieve a functor that emits the signal when invoked.
641681
*
642-
* Be careful if you directly pass one signal into the connect()
643-
* method of another: a shallow copy of the signal is made and
682+
* Be careful if you directly pass one signal into the connect() or
683+
* connect_first() method of another: a shallow copy of the signal is made and
644684
* the signal's slots are not disconnected until both the signal
645685
* and its clone are destroyed, which is probably not what you want!
646686
*
@@ -664,8 +704,8 @@ class trackable_signal_with_accumulator
664704
public:
665705
using slot_type = slot<T_return(T_arg...)>;
666706

667-
/** Add a slot to the list of slots.
668-
* Any functor or slot may be passed into connect().
707+
/** Add a slot at the end of the list of slots.
708+
* Any functor or slot may be passed into %connect().
669709
* It will be converted into a slot implicitly.
670710
* The returned connection may be stored for disconnection
671711
* of the slot at some later point. It stays valid until
@@ -689,7 +729,7 @@ class trackable_signal_with_accumulator
689729
return connection(slot_base);
690730
}
691731

692-
/** Add a slot to the list of slots.
732+
/** Add a slot at the end of the list of slots.
693733
* @see connect(const slot_type& slot_).
694734
*/
695735
connection connect(slot_type&& slot_)
@@ -699,6 +739,45 @@ class trackable_signal_with_accumulator
699739
return connection(slot_base);
700740
}
701741

742+
/** Add a slot at the beginning of the list of slots.
743+
* Any functor or slot may be passed into %connect_first().
744+
* It will be converted into a slot implicitly.
745+
* The returned connection may be stored for disconnection
746+
* of the slot at some later point. It stays valid until
747+
* the slot is disconnected from the signal.
748+
* std::function<> and C++11 lambda expressions are functors.
749+
* These are examples of functors that can be connected to a signal.
750+
*
751+
* %std::bind() creates a functor, but this functor typically has an
752+
* %operator()() which is a variadic template.
753+
* Our functor_trait can't deduce the result type
754+
* of such a functor. If you first assign the return value of %std::bind()
755+
* to a std::function, you can connect the std::function to a signal.
756+
*
757+
* @param slot_ The slot to add to the list of slots.
758+
* @return A connection.
759+
*
760+
* @newin{3,6}
761+
*/
762+
connection connect_first(const slot_type& slot_)
763+
{
764+
auto iter = signal_base::connect_first(slot_);
765+
auto& slot_base = *iter;
766+
return connection(slot_base);
767+
}
768+
769+
/** Add a slot at the beginning of the list of slots.
770+
* @see connect_first(const slot_type& slot_).
771+
*
772+
* @newin{3,6}
773+
*/
774+
connection connect_first(slot_type&& slot_)
775+
{
776+
auto iter = signal_base::connect_first(std::move(slot_));
777+
auto& slot_base = *iter;
778+
return connection(slot_base);
779+
}
780+
702781
/** Triggers the emission of the signal.
703782
* During signal emission all slots that have been connected
704783
* to the signal are invoked unless they are manually set into
@@ -772,14 +851,14 @@ class trackable_signal_with_accumulator
772851

773852
/** %trackable_signal can be used to connect() slots that are invoked
774853
* during subsequent calls to emit(). Any functor or slot
775-
* can be passed into connect(). It is converted into a slot
854+
* can be passed into connect() or connect_first(). It is converted into a slot
776855
* implicitly.
777856
*
778857
* If you want to connect one signal to another, use make_slot()
779858
* to retrieve a functor that emits the signal when invoked.
780859
*
781-
* Be careful if you directly pass one signal into the connect()
782-
* method of another: a shallow copy of the signal is made and
860+
* Be careful if you directly pass one signal into the connect() or
861+
* connect_first() method of another: a shallow copy of the signal is made and
783862
* the signal's slots are not disconnected until both the signal
784863
* and its clone are destroyed, which is probably not what you want!
785864
*

sigc++/signal_base.cc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,18 @@ signal_impl::connect(slot_base&& slot_)
128128
return insert(slots_.end(), std::move(slot_));
129129
}
130130

131+
signal_impl::iterator_type
132+
signal_impl::connect_first(const slot_base& slot_)
133+
{
134+
return insert(slots_.begin(), slot_);
135+
}
136+
137+
signal_impl::iterator_type
138+
signal_impl::connect_first(slot_base&& slot_)
139+
{
140+
return insert(slots_.begin(), std::move(slot_));
141+
}
142+
131143
void
132144
signal_impl::add_notification_to_iter(const signal_impl::iterator_type& iter)
133145
{
@@ -260,6 +272,18 @@ signal_base::connect(slot_base&& slot_)
260272
return impl()->connect(std::move(slot_));
261273
}
262274

275+
signal_base::iterator_type
276+
signal_base::connect_first(const slot_base& slot_)
277+
{
278+
return impl()->connect_first(slot_);
279+
}
280+
281+
signal_base::iterator_type
282+
signal_base::connect_first(slot_base&& slot_)
283+
{
284+
return impl()->connect_first(std::move(slot_));
285+
}
286+
263287
signal_base::iterator_type
264288
signal_base::insert(iterator_type i, const slot_base& slot_)
265289
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy