Skip to content

Commit 3527ebb

Browse files
committed
slot: use pointer for functor_ member
Using pointer instead of value allows us to avoid calling destructor of functor_ directly in destroy()
1 parent cde16da commit 3527ebb

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

sigc++/functors/slot.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <sigc++/adaptors/adaptor_trait.h>
2525
#include <sigc++/functors/slot_base.h>
2626

27+
#include <memory>
28+
2729
namespace sigc
2830
{
2931

@@ -49,22 +51,22 @@ struct typed_slot_rep : public slot_rep
4951
public:
5052

5153
/** The functor contained by this slot_rep object. */
52-
adaptor_type functor_;
54+
std::unique_ptr<adaptor_type> functor_;
5355

5456
/** Constructs an invalid typed slot_rep object.
5557
* The notification callback is registered using visit_each().
5658
* @param functor The functor contained by the new slot_rep object.
5759
*/
5860
inline explicit typed_slot_rep(const T_functor& functor)
59-
: slot_rep(nullptr, &destroy, &dup), functor_(functor)
61+
: slot_rep(nullptr, &destroy, &dup), functor_(std::make_unique<adaptor_type>(functor))
6062
{
61-
sigc::visit_each_trackable(slot_do_bind(this), functor_);
63+
sigc::visit_each_trackable(slot_do_bind(this), *functor_);
6264
}
6365

6466
inline typed_slot_rep(const typed_slot_rep& cl)
65-
: slot_rep(cl.call_, &destroy, &dup), functor_(cl.functor_)
67+
: slot_rep(cl.call_, &destroy, &dup), functor_(std::make_unique<adaptor_type>(*cl.functor_))
6668
{
67-
sigc::visit_each_trackable(slot_do_bind(this), functor_);
69+
sigc::visit_each_trackable(slot_do_bind(this), *functor_);
6870
}
6971

7072
typed_slot_rep& operator=(const typed_slot_rep& src) = delete;
@@ -76,7 +78,7 @@ struct typed_slot_rep : public slot_rep
7678
{
7779
call_ = nullptr;
7880
destroy_ = nullptr;
79-
sigc::visit_each_trackable(slot_do_unbind(this), functor_);
81+
sigc::visit_each_trackable(slot_do_unbind(this), *functor_);
8082
}
8183

8284
private:
@@ -88,8 +90,8 @@ struct typed_slot_rep : public slot_rep
8890
auto self_ = static_cast<self*>(data);
8991
self_->call_ = nullptr;
9092
self_->destroy_ = nullptr;
91-
sigc::visit_each_trackable(slot_do_unbind(self_), self_->functor_);
92-
self_->functor_.~adaptor_type();
93+
sigc::visit_each_trackable(slot_do_unbind(self_), *self_->functor_);
94+
self_->functor_.reset(nullptr);
9395
/* don't call disconnect() here: destroy() is either called
9496
* a) from the parent itself (in which case disconnect() leads to a segfault) or
9597
* b) from a parentless slot (in which case disconnect() does nothing)
@@ -126,7 +128,7 @@ struct slot_call
126128
static T_return call_it(slot_rep* rep, type_trait_take_t<T_arg>... a_)
127129
{
128130
auto typed_rep = static_cast<typed_slot_rep<T_functor>*>(rep);
129-
return (typed_rep->functor_).template operator()<type_trait_take_t<T_arg>...>(a_...);
131+
return (*typed_rep->functor_).template operator()<type_trait_take_t<T_arg>...>(a_...);
130132
}
131133

132134
/** Forms a function pointer from call_it().

0 commit comments

Comments
 (0)