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 operator()(A... args) const
61  {
62  return _lambda(std::forward<A>(args)...);
63  }
64 
65  // inherit doc
66  Lambda* clone() const
67  {
68  return new Lambda(*this);
69  }
70 
71  private:
72  mutable L _lambda;
73 };
74 
83 template <typename L, typename R, typename... A>
84 class LambdaSlot : public BasicSlot<R, A...>
85 {
86  public:
87  typedef Lambda<L, R, A...> LambdaT;
88 
89  public:
92  template <typename T>
93  LambdaSlot(T&& lambda, Connectable* context = 0)
94  : _lambda(std::forward<T>(lambda))
95  , _context(context)
96  { }
97 
98  // inherit doc
99  virtual const void* callable() const
100  {
101  return &_lambda;
102  }
103 
104  // inherit doc
105  Slot* clone() const
106  {
107  return new LambdaSlot(*this);
108  }
109 
110  // inherit doc
111  virtual void onConnect(const Connection& connection)
112  {
113  if(_context && connection.sender() != _context)
114  {
115  _context->onConnectionOpen(connection);
116  }
117  }
118 
119  // inherit doc
120  virtual void onDisconnect(const Connection& connection)
121  {
122  if(_context && connection.sender() != _context)
123  {
124  _context->onConnectionClose(connection);
125  }
126  }
127 
128  // inherit doc
129  virtual bool equals(const Slot&) const
130  {
131  return false;
132  }
133 
134  private:
135  LambdaT _lambda;
136  Connectable* _context;
137 };
138 
141 template <typename L,
142  class C = typename TypeTraits<L>::Value,
143  typename M = decltype( &C::operator() )>
144 struct LambdaSlotTraits;
145 
148 template <typename L, class C, typename R, typename... As>
149 struct LambdaSlotTraits<L, C, R (C::*)(As...)>
150 {
151  typedef LambdaSlot<C, R, As...> Slot;
152 };
153 
156 template <typename L, class C, typename R, typename... As>
157 struct LambdaSlotTraits<L, C, R (C::*)(As...) const>
158 {
159  typedef LambdaSlot<C, R, As...> Slot;
160 };
161 
167 template <typename L,
168  typename SlotT = typename LambdaSlotTraits<L>::Slot>
169 SlotT slot(L&& lambda)
170 {
171  return SlotT( std::forward<L>(lambda) );
172 }
173 
179 template <typename L,
180  typename SlotT = typename LambdaSlotTraits<L>::Slot>
181 SlotT slot(Connectable& context, L&& lambda)
182 {
183  return SlotT( std::forward<L>(lambda), &context );
184 }
185 
191 template <typename R, typename... A, typename T,
192  typename L = typename TypeTraits<T>::Value>
193 LambdaSlot<L, R, A...> slot(T&& lambda)
194 {
195  return LambdaSlot<L, R, A...>( std::forward<T>(lambda) );
196 }
197 
203 template <typename R, typename... A, typename T,
204  typename L = typename TypeTraits<T>::Value>
205 LambdaSlot<L, R, A...> slot(Connectable& context, T&& lambda)
206 {
207  typedef typename TypeTraits<L>::Value LambdaT;
208  return LambdaSlot<L, R, A...>( std::forward<T>(lambda), &context );
209 }
210 
211 } // namespace Pt
212 
213 #endif // PT_LAMBDA_H
const Connectable * sender() const
Returns the sender.
Definition: Connection.h:110
Core module.
Definition: Allocator.h:33
An interface for all callable entities.
Definition: Api-Callable.h:17
virtual const void * callable() const
Returns a pointer to the contained callable.
Definition: Lambda.h:99
SlotT slot(Connectable &context, L &&lambda)
Returns a deduced slot object for the given lambda.
Definition: Lambda.h:181
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:193
Base type for various "slot" types.
Definition: Api-Slot.h:51
IMPLEMENTATION_DEFINED Value
The derived value type.
Definition: Api-TypeTraits.h:22
Slot * clone() const
Clone this object with new.
Definition: Lambda.h:105
virtual void onDisconnect(const Connection &connection)
Notifies of disconnects.
Definition: Lambda.h:120
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:85
SlotT slot(L &&lambda)
Returns a deduced slot object for the given lambda.
Definition: Lambda.h:169
LambdaSlot< L, R, A... > slot(Connectable &context, T &&lambda)
Returns a slot object for the given lambda.
Definition: Lambda.h:205
R operator()(A... args) const
Call the callable entity.
Definition: Lambda.h:60
virtual void onConnect(const Connection &connection)
Notifies of connects.
Definition: Lambda.h:111
Endpoint of a signal/slot connection.
Definition: Api-Slot.h:23
LambdaSlot(T &&lambda, Connectable *context=0)
Constructs from a lambda and optional lifetime context.
Definition: Lambda.h:93
virtual bool equals(const Slot &) const
Returns true if two slots are equal in value.
Definition: Lambda.h:129
Represents a connection between a Signal/Delegate and a slot.
Definition: Connection.h:91