Lambda.h
1 /*
2  * Copyright (C) 2026 by Dr. 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 Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 #ifndef PT_LAMBDA_H
30 #define PT_LAMBDA_H
31 
32 #include <Pt/Callable.h>
33 #include <Pt/Slot.h>
34 #include <Pt/Connectable.h>
35 #include <Pt/TypeTraits.h>
36 #include <utility>
37 
38 namespace Pt {
39 
48 template <typename L, typename R, typename... A>
49 class Lambda : public Callable<R, A...>
50 {
51  public:
54  template <typename T>
55  explicit Lambda(T&& lambda)
56  : _lambda(std::forward<T>(lambda))
57  { }
58 
59  // inherit doc
60  R call(A... args) const
61  {
62  return _lambda(std::forward<A>(args)...);
63  }
64 
65  // inherit doc
66  void invoke(A... args) const
67  {
68  _lambda(std::forward<A>(args)...);
69  }
70 
71  // inherit doc
72  Lambda* clone() const
73  {
74  return new Lambda(*this);
75  }
76 
77  private:
78  mutable L _lambda;
79 };
80 
89 template <typename L, typename R, typename... A>
90 class LambdaSlot : public BasicSlot<R, A...>
91 {
92  public:
93  typedef Lambda<L, R, A...> LambdaT;
94 
95  public:
98  template <typename T>
99  LambdaSlot(T&& lambda, Connectable* context = 0)
100  : _lambda(std::forward<T>(lambda))
101  , _context(context)
102  { }
103 
104  // inherit doc
105  virtual const Callback* callable() const
106  {
107  return &_lambda;
108  }
109 
110  // inherit doc
111  Slot* clone() const
112  {
113  return new LambdaSlot(*this);
114  }
115 
116  // inherit doc
117  virtual void onConnect(const Connection& connection)
118  {
119  if(_context && connection.sender() != _context)
120  {
121  _context->onConnectionOpen(connection);
122  }
123  }
124 
125  // inherit doc
126  virtual void onDisconnect(const Connection& connection)
127  {
128  if(_context && connection.sender() != _context)
129  {
130  _context->onConnectionClose(connection);
131  }
132  }
133 
134  // inherit doc
135  virtual bool equals(const Slot&) const
136  {
137  return false;
138  }
139 
140  private:
141  LambdaT _lambda;
142  Connectable* _context;
143 };
144 
147 template <typename L,
148  class C = typename TypeTraits<L>::Value,
149  typename M = decltype( &C::operator() )>
150 struct LambdaSlotTraits;
151 
154 template <typename L, class C, typename R, typename... As>
155 struct LambdaSlotTraits<L, C, R (C::*)(As...)>
156 {
157  typedef LambdaSlot<C, R, As...> Slot;
158 };
159 
162 template <typename L, class C, typename R, typename... As>
163 struct LambdaSlotTraits<L, C, R (C::*)(As...) const>
164 {
165  typedef LambdaSlot<C, R, As...> Slot;
166 };
167 
173 template <typename L,
174  typename SlotT = typename LambdaSlotTraits<L>::Slot>
175 SlotT slot(L&& lambda)
176 {
177  return SlotT( std::forward<L>(lambda) );
178 }
179 
185 template <typename L,
186  typename SlotT = typename LambdaSlotTraits<L>::Slot>
187 SlotT slot(Connectable& context, L&& lambda)
188 {
189  return SlotT( std::forward<L>(lambda), &context );
190 }
191 
197 template <typename R, typename... A, typename T,
198  typename L = typename TypeTraits<T>::Value>
199 LambdaSlot<L, R, A...> slot(T&& lambda)
200 {
201  return LambdaSlot<L, R, A...>( std::forward<T>(lambda) );
202 }
203 
209 template <typename R, typename... A, typename T,
210  typename L = typename TypeTraits<T>::Value>
211 LambdaSlot<L, R, A...> slot(Connectable& context, T&& lambda)
212 {
213  typedef typename TypeTraits<L>::Value LambdaT;
214  return LambdaSlot<L, R, A...>( std::forward<T>(lambda), &context );
215 }
216 
217 } // namespace Pt
218 
219 #endif // PT_LAMBDA_H
const Connectable * sender() const
Returns the sender.
Definition: Connection.h:115
Core module.
Definition: Allocator.h:33
virtual const Callback * callable() const
Returns the callable converted to the type-erased Callback interface.
Definition: Lambda.h:105
An interface for all callable entities.
Definition: Callable.h:48
SlotT slot(Connectable &context, L &&lambda)
Returns a deduced slot object for the given lambda.
Definition: Lambda.h:187
Adapts a lambda or function object as a callable.
Definition: Lambda.h:50
LambdaSlot< L, R, A... > slot(T &&lambda)
Returns a slot object for the given lambda.
Definition: Lambda.h:199
Base type for various "slot" types.
Definition: Slot.h:92
IMPLEMENTATION_DEFINED Value
The derived value type.
Definition: Api-TypeTraits.h:22
Slot * clone() const
Clone this object with new.
Definition: Lambda.h:111
virtual void onDisconnect(const Connection &connection)
Notifies of disconnects.
Definition: Lambda.h:126
Connection Management for Signal and Slot Objects.
Definition: Connectable.h:50
Lambda(T &&lambda)
Constructs from a lambda or function object.
Definition: Lambda.h:55
Adapts a Lambda for use as a slot.
Definition: Lambda.h:91
SlotT slot(L &&lambda)
Returns a deduced slot object for the given lambda.
Definition: Lambda.h:175
LambdaSlot< L, R, A... > slot(Connectable &context, T &&lambda)
Returns a slot object for the given lambda.
Definition: Lambda.h:211
virtual void onConnect(const Connection &connection)
Notifies of connects.
Definition: Lambda.h:117
Endpoint of a signal/slot connection.
Definition: Slot.h:55
LambdaSlot(T &&lambda, Connectable *context=0)
Constructs from a lambda and optional lifetime context.
Definition: Lambda.h:99
virtual bool equals(const Slot &) const
Returns true if two slots are equal in value.
Definition: Lambda.h:135
Represents a connection between a Signal/Delegate and a slot.
Definition: Connection.h:96