Embedded Template Library 1.0
Loading...
Searching...
No Matches
closure.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2025 BMW AG
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_CLOSURE_INCLUDED
32#define ETL_CLOSURE_INCLUDED
33
34#include "platform.h"
35#include "delegate.h"
36#include "invoke.h"
37#include "tuple.h"
38#include "type_list.h"
39#include "utility.h"
40
41namespace etl
42{
43 //*************************************************************************
47 //*************************************************************************
48 template <typename TSignature, typename TCallback = etl::delegate<TSignature> >
49 class closure;
50
51#if ETL_USING_CPP11 && !defined(ETL_CLOSURE_FORCE_CPP03_IMPLEMENTATION)
52 //*************************************************************************
64 //*************************************************************************
65 template <typename TReturn, typename... TArgs, typename TCallback>
66 class closure<TReturn(TArgs...), TCallback>
67 {
68 public:
69
70 using delegate_type ETL_DEPRECATED_REASON("Use callback_type") =
71 TCallback;
72 using callback_type = TCallback;
73 using argument_types = etl::type_list<TArgs...>;
74
75 static_assert(etl::is_invocable_r<TReturn, TCallback, TArgs...>::value, "Callback is not invocable with the specified arguments");
76 static_assert(etl::is_copy_constructible<TCallback>::value, "Callback type must be copy constructible");
77
78 //*********************************************************************
82 //*********************************************************************
83 ETL_CONSTEXPR14 closure(const callback_type& f, const TArgs... args)
84 : m_f(f)
85 , m_args(args...)
86 {
87 }
88
89 //*********************************************************************
92 //*********************************************************************
93 ETL_CONSTEXPR14 TReturn operator()() const
94 {
95 return execute(etl::index_sequence_for<TArgs...>{});
96 }
97
98 //*********************************************************************
104 //*********************************************************************
105 template <size_t Index, typename UArg>
106 ETL_CONSTEXPR14 void bind(UArg arg)
107 {
108 static_assert(etl::is_convertible< UArg, etl::type_list_type_at_index_t<argument_types, Index>>::value, "Argument is not convertible");
109 static_assert(!etl::is_reference<UArg>::value, "Cannot bind reference arguments");
110
111 etl::get<Index>(m_args) = arg;
112 }
113
114 //*********************************************************************
119 template <typename... UArgs>
120 ETL_CONSTEXPR14 void bind(UArgs&&... args)
121 {
122 static_assert(sizeof...(UArgs) == sizeof...(TArgs), "Argument count mismatch");
123 bind_impl(etl::make_index_sequence<sizeof...(TArgs)>{}, etl::forward<UArgs>(args)...);
124 }
125
126 private:
127
128 //*********************************************************************
132 template <size_t... Indexes, typename... UArgs>
133 ETL_CONSTEXPR14 void bind_impl(etl::index_sequence<Indexes...>, UArgs&&... args)
134 {
135 // Expand the pack and call bind<Index>(arg) for each argument
136 int dummy[] = {0, (bind<Indexes>(etl::forward<UArgs>(args)), 0)...};
137 (void)dummy; // Suppress unused variable warning
138 }
139
140 //*********************************************************************
144 //*********************************************************************
145 template <size_t... Indexes>
146 ETL_CONSTEXPR14 TReturn execute(etl::index_sequence<Indexes...>) const
147 {
148 return m_f(etl::get<Indexes>(m_args)...);
149 }
150
151 callback_type m_f;
152 etl::tuple<TArgs...> m_args;
153 };
154#else
155 //*************************************************************************
160 //*************************************************************************
161 template <typename TReturn, typename TArg0, typename TCallback>
162 class closure<TReturn(TArg0), TCallback>
163 {
164 public:
165
167 typedef TCallback callback_type;
168
169 //*********************************************************************
173 //*********************************************************************
174 closure(const callback_type& f, const TArg0 arg0)
175 : m_f(f)
176 , m_arg0(arg0)
177 {
178 }
179
180 //*********************************************************************
183 //*********************************************************************
184 TReturn operator()() const
185 {
186 return m_f(m_arg0);
187 }
188
189 private:
190
191 callback_type m_f;
192 TArg0 m_arg0;
193 };
194
195 //*************************************************************************
201 //*************************************************************************
202 template <typename TReturn, typename TArg0, typename TArg1, typename TCallback>
203 class closure<TReturn(TArg0, TArg1), TCallback>
204 {
205 public:
206
207 typedef TCallback callback_type;
208
209 //*********************************************************************
214 //*********************************************************************
215 closure(const callback_type& f, const TArg0 arg0, const TArg1 arg1)
216 : m_f(f)
217 , m_arg0(arg0)
218 , m_arg1(arg1)
219 {
220 }
221
222 //*********************************************************************
225 //*********************************************************************
226 TReturn operator()() const
227 {
228 return m_f(m_arg0, m_arg1);
229 }
230
231 private:
232
233 callback_type m_f;
234 TArg0 m_arg0;
235 TArg1 m_arg1;
236 };
237
238 //*************************************************************************
245 //*************************************************************************
246 template <typename TReturn, typename TArg0, typename TArg1, typename TArg2, typename TCallback>
247 class closure<TReturn(TArg0, TArg1, TArg2), TCallback>
248 {
249 public:
250
251 typedef TCallback callback_type;
252
253 //*********************************************************************
259 //*********************************************************************
260 closure(const callback_type& f, const TArg0 arg0, const TArg1 arg1, const TArg2 arg2)
261 : m_f(f)
262 , m_arg0(arg0)
263 , m_arg1(arg1)
264 , m_arg2(arg2)
265 {
266 }
267
268 //*********************************************************************
271 //*********************************************************************
272 TReturn operator()() const
273 {
274 return m_f(m_arg0, m_arg1, m_arg2);
275 }
276
277 private:
278
279 callback_type m_f;
280 TArg0 m_arg0;
281 TArg1 m_arg1;
282 TArg2 m_arg2;
283 };
284
285 //*************************************************************************
293 //*************************************************************************
294 template <typename TReturn, typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TCallback>
295 class closure<TReturn(TArg0, TArg1, TArg2, TArg3), TCallback>
296 {
297 public:
298
299 typedef TCallback callback_type;
300
301 //*********************************************************************
308 //*********************************************************************
309 closure(const callback_type& f, const TArg0 arg0, const TArg1 arg1, const TArg2 arg2, const TArg3 arg3)
310 : m_f(f)
311 , m_arg0(arg0)
312 , m_arg1(arg1)
313 , m_arg2(arg2)
314 , m_arg3(arg3)
315 {
316 }
317
318 //*********************************************************************
321 //*********************************************************************
322 TReturn operator()() const
323 {
324 return m_f(m_arg0, m_arg1, m_arg2, m_arg3);
325 }
326
327 private:
328
329 callback_type m_f;
330 TArg0 m_arg0;
331 TArg1 m_arg1;
332 TArg2 m_arg2;
333 TArg3 m_arg3;
334 };
335
336 //*************************************************************************
345 //*************************************************************************
346 template <typename TReturn, typename TArg0, typename TArg1, typename TArg2, typename TArg3, typename TArg4, typename TCallback>
347 class closure<TReturn(TArg0, TArg1, TArg2, TArg3, TArg4), TCallback>
348 {
349 public:
350
351 typedef TCallback callback_type;
352
353 //*********************************************************************
361 //*********************************************************************
362 closure(const callback_type& f, const TArg0 arg0, const TArg1 arg1, const TArg2 arg2, const TArg3 arg3, const TArg4 arg4)
363 : m_f(f)
364 , m_arg0(arg0)
365 , m_arg1(arg1)
366 , m_arg2(arg2)
367 , m_arg3(arg3)
368 , m_arg4(arg4)
369 {
370 }
371
372 //*********************************************************************
375 //*********************************************************************
376 TReturn operator()() const
377 {
378 return m_f(m_arg0, m_arg1, m_arg2, m_arg3, m_arg4);
379 }
380
381 private:
382
383 callback_type m_f;
384 TArg0 m_arg0;
385 TArg1 m_arg1;
386 TArg2 m_arg2;
387 TArg3 m_arg3;
388 TArg4 m_arg4;
389 };
390#endif
391} // namespace etl
392
393#endif
closure(const callback_type &f, const TArg0 arg0, const TArg1 arg1, const TArg2 arg2, const TArg3 arg3, const TArg4 arg4)
Definition closure.h:362
TReturn operator()() const
Definition closure.h:322
closure(const callback_type &f, const TArg0 arg0, const TArg1 arg1, const TArg2 arg2, const TArg3 arg3)
Definition closure.h:309
TReturn operator()() const
Definition closure.h:272
closure(const callback_type &f, const TArg0 arg0, const TArg1 arg1, const TArg2 arg2)
Definition closure.h:260
TReturn operator()() const
Definition closure.h:226
closure(const callback_type &f, const TArg0 arg0, const TArg1 arg1)
Definition closure.h:215
closure(const callback_type &f, const TArg0 arg0)
Definition closure.h:174
TReturn operator()() const
Definition closure.h:184
TCallback callback_type
The callback type to be invoked.
Definition closure.h:167
Definition closure.h:49
Definition absolute.h:40
T & get(array< T, Size > &a)
Definition array.h:1158
ETL_DEPRECATED_REASON("Misspelt class name") typedef scheduler_policy_sequential_single scheduler_policy_sequencial_single
Typedef for backwards compatibility with miss-spelt struct name.