SlotBind.h
1/*
2 Copyright (C) 2008 Marc Boris Duerner
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 As a special exception, you may use this file as part of a free
10 software library without restriction. Specifically, if other files
11 instantiate templates or use macros or inline functions from this
12 file, or you compile this file and link it with other files to
13 produce an executable, this file does not by itself cause the
14 resulting executable to be covered by the GNU General Public
15 License. This exception does not however invalidate any other
16 reasons why the executable file might be covered by the GNU Library
17 General Public License.
18
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
23
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, write to the:
26 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 Boston, MA 02110-1301 USA
28*/
29
30#ifndef Pt_SlotBind_h
31#define Pt_SlotBind_h
32
33#include <Pt/Api.h>
34#include <Pt/Void.h>
35#include <Pt/Callable.h>
36#include <tuple>
37#include <type_traits>
38#include <utility>
39
40namespace Pt {
41
42template <typename T>
43class BindAdaptorBase
44{
45 public:
46 BindAdaptorBase(const Slot& s, const T& a)
47 : _slot( s.clone() )
48 , _a(a)
49 { }
50
51 BindAdaptorBase(const BindAdaptorBase& c)
52 : _slot( c._slot->clone() )
53 , _a(c._a)
54 { }
55
56 ~BindAdaptorBase()
57 { delete _slot; }
58
59 BindAdaptorBase& operator=(const BindAdaptorBase& b)
60 {
61 if(this == &b)
62 return *this;
63
64 Slot* s = b.slot().clone();
65 delete _slot;
66 _slot = s;
67
68 _a = b._a;
69 return *this;
70 }
71
72 Slot& slot()
73 {
74 return *_slot;
75 }
76
77 const Slot& slot() const
78 {
79 return *_slot;
80 }
81
82 const T& arg() const
83 {
84 return _a;
85 }
86
87 private:
88 Slot* _slot;
89 T _a;
90};
91
92namespace SigSlotDetail {
93
94template <typename R, typename Tuple, typename Indices>
95class BindAdaptor;
96
97template <typename R, typename Tuple, std::size_t... Is>
98class BindAdaptor<R, Tuple, std::index_sequence<Is...>>
99: public Callable<R, typename std::tuple_element<Is, Tuple>::type...>
100, public BindAdaptorBase<
101 typename std::tuple_element<std::tuple_size<Tuple>::value - 1, Tuple>::type>
102{
103 public:
104 typedef typename std::tuple_element<std::tuple_size<Tuple>::value - 1, Tuple>::type BoundT;
105 typedef BasicSlot<R, typename std::tuple_element<Is, Tuple>::type...> SlotBase;
106 typedef BasicSlot<R, typename std::tuple_element<Is, Tuple>::type..., BoundT> FullSlotBase;
107 typedef Callable<R, typename std::tuple_element<Is, Tuple>::type...> CallableBase;
108 typedef Callable<R, typename std::tuple_element<Is, Tuple>::type..., BoundT> FullCallable;
109
110 public:
111 BindAdaptor(const FullSlotBase& slot, const BoundT& arg)
112 : BindAdaptorBase<BoundT>(slot, arg)
113 { }
114
115 CallableBase* clone() const
116 {
117 return new BindAdaptor(*this);
118 }
119
120 // inherit doc
121 R call(typename std::tuple_element<Is, Tuple>::type... args) const
122 {
123 const FullCallable* callable =
124 static_cast<const FullCallable*>( this->slot().callable() );
125 return callable->call(args..., this->arg());
126 }
127
128 // inherit doc
129 void invoke(typename std::tuple_element<Is, Tuple>::type... args) const
130 {
131 const FullCallable* callable =
132 static_cast<const FullCallable*>( this->slot().callable() );
133 callable->call(args..., this->arg());
134 }
135};
136
137} // namespace SigSlotDetail
138
146template <typename R, typename Tuple, typename Indices>
147class BoundSlot
148: public SigSlotDetail::BindAdaptor<R, Tuple, Indices>::SlotBase
149{
150 typedef SigSlotDetail::BindAdaptor<R, Tuple, Indices> AdaptorT;
151
152 public:
153 template <typename T>
154 BoundSlot(const typename AdaptorT::FullSlotBase& slot, const T& arg)
155 : _adaptor(slot, arg)
156 { }
157
158 Slot* clone() const
159 {
160 return new BoundSlot(*this);
161 }
162
163 // inherit doc
164 virtual const Callback* callable() const
165 {
166 return &_adaptor;
167 }
168
169 virtual void onConnect(const Connection& connection)
170 {
171 _adaptor.slot().onConnect(connection);
172 }
173
174 virtual void onDisconnect(const Connection& connection)
175 {
176 _adaptor.slot().onDisconnect(connection);
177 }
178
179 virtual bool equals(const Slot& slot) const
180 {
181 return _adaptor.slot().equals(slot);
182 }
183
184 private:
185 AdaptorT _adaptor;
186};
187
188namespace SigSlotDetail {
189
190template <typename R, typename Tuple>
191struct BoundSlotTraits;
192
193template <typename R, typename A, typename... As>
194struct BoundSlotTraits<R, std::tuple<A, As...>>
195{
196 typedef BoundSlot<R,
197 std::tuple<A, As...>,
198 std::make_index_sequence<sizeof...(As)>> Type;
199};
200
201} // namespace SigSlotDetail
202
210template <typename R, typename... As, typename T>
211typename SigSlotDetail::BoundSlotTraits<R, std::tuple<As...>>::Type
212slot(const BasicSlot<R, As...>& slot, const T& arg)
213{
214 typedef typename SigSlotDetail::BoundSlotTraits<R, std::tuple<As...>>::Type BoundSlotT;
215 return BoundSlotT(slot, arg);
216}
217
218} // namespace Pt
219
220#endif
Base type for various "slot" types.
Definition Slot.h:92
Slot produced by binding a final argument to another slot.
Definition SlotBind.h:149
SigSlotDetail::BoundSlotTraits< R, std::tuple< As... > >::Type slot(const BasicSlot< R, As... > &slot, const T &arg)
Binds the final argument of a slot to a copied value.
Definition SlotBind.h:212
ConstMethod< R, ClassT, As... > callable(ClassT &object, R(BaseT::*method)(As...) const)
Returns a ConstMethod object for the given object/method pair.
Definition ConstMethod.h:161
Represents a connection between a Signal/Delegate and a slot.
Definition Connection.h:96
R call(As... args) const
Calls the callable entity and returns its result.
Definition ConstMethod.h:77
Endpoint of a signal/slot connection.
Definition Slot.h:55
ConstMethodSlot< R, ClassT, As... > slot(ClassT &object, R(BaseT::*method)(As...) const)
Returns a slot object for the given object/member pair.
Definition ConstMethod.h:172
Core module.
Definition Allocator.h:33