Skip to content

Commit 0e93e46

Browse files
committed
Patch the etl patch (broken by c2usb dependency upgrade.)
1 parent b344131 commit 0e93e46

1 file changed

Lines changed: 45 additions & 73 deletions

File tree

Lines changed: 45 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,74 @@
1-
From bfbb7259e128b6fac0ac3736a8f8297533b332fd Mon Sep 17 00:00:00 2001
1+
From 33f9eca9697ebdfd4b2d751f229aada00f61cd2a Mon Sep 17 00:00:00 2001
22
From: Benedek Kupper <kupper.benedek@gmail.com>
33
Date: Mon, 9 Feb 2026 22:35:13 +0100
44
Subject: [PATCH] delegate: allow constructing from non-capturing lambdas
55

66
Signed-off-by: Benedek Kupper <kupper.benedek@gmail.com>
77
---
8-
include/etl/private/delegate_cpp11.h | 63 +++++++++++++++++++++++++++-
9-
test/test_delegate.cpp | 47 +++++++++++++++++++--
10-
2 files changed, 105 insertions(+), 5 deletions(-)
8+
include/etl/private/delegate_cpp11.h | 46 ++++++++++++++++++++++++
9+
test/test_delegate.cpp | 52 ++++++++++++++++++++++++++++
10+
2 files changed, 98 insertions(+)
1111

1212
diff --git a/include/etl/private/delegate_cpp11.h b/include/etl/private/delegate_cpp11.h
13-
index 288c3a5..c7d41e2 100644
13+
index 0770e0f0..ee51d5ce 100644
1414
--- a/include/etl/private/delegate_cpp11.h
1515
+++ b/include/etl/private/delegate_cpp11.h
16-
@@ -155,10 +155,23 @@ namespace etl
17-
18-
//*************************************************************************
19-
// Delete construction from rvalue reference lambda or functor.
20-
+ // Excludes non-capturing lambdas convertible to a function pointer.
21-
//*************************************************************************
22-
- template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TArgs...)>, TLambda>::value, void>>
23-
+ template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TArgs...)>, TLambda>::value && !etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, void>>
16+
@@ -175,6 +175,17 @@ namespace etl
17+
void>>
2418
ETL_CONSTEXPR14 delegate(TLambda&& instance) = delete;
2519

2620
+ //*************************************************************************
27-
+ // Construct from non-capturing rvalue lambda convertible to function pointer.
28-
+ // Converts to a function pointer to avoid storing a dangling pointer
29-
+ // to a destroyed temporary.
21+
+ /// Construct from a non-capturing rvalue lambda convertible to a function
22+
+ /// pointer. Converts to a function pointer to avoid storing a dangling
23+
+ /// pointer to a destroyed temporary.
3024
+ //*************************************************************************
31-
+ template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, int> = 0>
25+
+ template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, function_ptr>::value, int> = 0>
3226
+ delegate(TLambda&& instance) ETL_NOEXCEPT
27+
+ : invocation(static_cast<function_ptr>(instance), function_ptr_stub)
3328
+ {
34-
+ TReturn(*fp)(TArgs...) = static_cast<TReturn(*)(TArgs...)>(instance);
35-
+ assign(reinterpret_cast<void*>(fp), function_ptr_stub);
3629
+ }
3730
+
3831
//*************************************************************************
39-
/// Create from function (Compile time).
32+
/// Construct from a function pointer.
4033
//*************************************************************************
41-
@@ -189,6 +202,19 @@ namespace etl
42-
return delegate((void*)(&instance), const_lambda_stub<TLambda>);
34+
@@ -222,6 +233,18 @@ namespace etl
35+
return delegate(fp, function_ptr_stub);
4336
}
4437

4538
+ //*************************************************************************
4639
+ // Create from non-capturing rvalue lambda convertible to function pointer.
4740
+ // Converts to a function pointer to avoid storing a dangling pointer
4841
+ // to a destroyed temporary.
4942
+ //*************************************************************************
50-
+ template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, int> = 0>
43+
+ template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, function_ptr>::value, int> = 0>
5144
+ ETL_NODISCARD
5245
+ static delegate create(TLambda&& instance) ETL_NOEXCEPT
5346
+ {
54-
+ TReturn(*fp)(TArgs...) = static_cast<TReturn(*)(TArgs...)>(instance);
55-
+ return delegate(reinterpret_cast<void*>(fp), function_ptr_stub);
47+
+ return delegate(static_cast<function_ptr>(instance), function_ptr_stub);
5648
+ }
5749
+
5850
//*************************************************************************
5951
/// Create from instance method (Run time).
6052
//*************************************************************************
61-
@@ -305,6 +331,18 @@ namespace etl
62-
assign((void*)(&instance), const_lambda_stub<TLambda>);
53+
@@ -346,6 +369,17 @@ namespace etl
54+
assign(fp, function_ptr_stub);
6355
}
6456

6557
+ //*************************************************************************
6658
+ // Set from non-capturing rvalue lambda convertible to function pointer.
6759
+ // Converts to a function pointer to avoid storing a dangling pointer
6860
+ // to a destroyed temporary.
6961
+ //*************************************************************************
70-
+ template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, int> = 0>
62+
+ template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, function_ptr>::value, int> = 0>
7163
+ void set(TLambda&& instance) ETL_NOEXCEPT
7264
+ {
73-
+ TReturn(*fp)(TArgs...) = static_cast<TReturn(*)(TArgs...)>(instance);
74-
+ assign(reinterpret_cast<void*>(fp), function_ptr_stub);
65+
+ assign(static_cast<function_ptr>(instance), function_ptr_stub);
7566
+ }
7667
+
7768
//*************************************************************************
7869
/// Set from instance method (Run time).
7970
//*************************************************************************
80-
@@ -494,6 +532,19 @@ namespace etl
71+
@@ -551,6 +585,18 @@ namespace etl
8172
return *this;
8273
}
8374

@@ -86,59 +77,38 @@ index 288c3a5..c7d41e2 100644
8677
+ // Converts to a function pointer to avoid storing a dangling pointer
8778
+ // to a destroyed temporary.
8879
+ //*************************************************************************
89-
+ template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, int> = 0>
80+
+ template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, function_ptr>::value, int> = 0>
9081
+ delegate& operator =(TLambda&& instance) ETL_NOEXCEPT
9182
+ {
92-
+ TReturn(*fp)(TArgs...) = static_cast<TReturn(*)(TArgs...)>(instance);
93-
+ assign(reinterpret_cast<void*>(fp), function_ptr_stub);
83+
+ assign(static_cast<function_ptr>(instance), function_ptr_stub);
9484
+ return *this;
9585
+ }
9686
+
9787
//*************************************************************************
9888
/// Checks equality.
9989
//*************************************************************************
100-
@@ -679,6 +730,16 @@ namespace etl
101-
return (Method)(etl::forward<TArgs>(args)...);
102-
}
103-
104-
+ //*************************************************************************
105-
+ /// Stub call for a runtime function pointer stored in the object field.
106-
+ //*************************************************************************
107-
+ static TReturn function_ptr_stub(void* object, TArgs... args)
108-
+ {
109-
+ ETL_STATIC_ASSERT(sizeof(void*) >= sizeof(TReturn(*)(TArgs...)), "etl::delegate: function pointer too large to store in object field");
110-
+ TReturn(*fp)(TArgs...) = reinterpret_cast<TReturn(*)(TArgs...)>(object);
111-
+ return fp(etl::forward<TArgs>(args)...);
112-
+ }
113-
+
114-
//*************************************************************************
115-
/// Stub call for a lambda or functor function.
116-
//*************************************************************************
11790
diff --git a/test/test_delegate.cpp b/test/test_delegate.cpp
118-
index 57c52e8..3f6d8f5 100644
91+
index f990e115..da48ce68 100644
11992
--- a/test/test_delegate.cpp
12093
+++ b/test/test_delegate.cpp
121-
@@ -634,16 +634,55 @@ namespace
122-
#endif
94+
@@ -679,6 +679,58 @@ namespace
95+
CHECK_EQUAL(result, VALUE1 + VALUE2);
96+
}
12397

124-
//*************************************************************************
125-
- TEST_FIXTURE(SetupFixture, test_lambda_int_create)
126-
+ TEST_FIXTURE(SetupFixture, test_construct_from_rvalue_non_capturing_lambda)
127-
{
128-
- auto lambda = [](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); };
98+
+ //*************************************************************************
99+
+ TEST_FIXTURE(SetupFixture, test_construct_from_rvalue_non_capturing_lambda_implicit)
100+
+ {
129101
+ etl::delegate<int(int, int)> d([](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j; });
130-
131-
- etl::delegate<void(int, int)> d(lambda);
102+
+
132103
+ int result = d(VALUE1, VALUE2);
133-
134-
- d(VALUE1, VALUE2);
104+
+
135105
+ CHECK(function_called == FunctionCalled::Lambda_Called);
136106
+ CHECK(parameter_correct);
137107
+ CHECK_EQUAL(result, VALUE1 + VALUE2);
138108
+ }
139109
+
140110
+ //*************************************************************************
141-
+ TEST_FIXTURE(SetupFixture, test_assign_from_rvalue_non_capturing_lambda)
111+
+ TEST_FIXTURE(SetupFixture, test_assign_from_rvalue_non_capturing_lambda_implicit)
142112
+ {
143113
+ etl::delegate<int(int, int)> d;
144114
+
@@ -152,7 +122,7 @@ index 57c52e8..3f6d8f5 100644
152122
+ }
153123
+
154124
+ //*************************************************************************
155-
+ TEST_FIXTURE(SetupFixture, test_create_from_rvalue_non_capturing_lambda)
125+
+ TEST_FIXTURE(SetupFixture, test_create_from_rvalue_non_capturing_lambda_implicit)
156126
+ {
157127
+ auto d = etl::delegate<int(int, int)>::create([](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j + 5; });
158128
+
@@ -164,20 +134,22 @@ index 57c52e8..3f6d8f5 100644
164134
+ }
165135
+
166136
+ //*************************************************************************
167-
+ TEST_FIXTURE(SetupFixture, test_set_from_rvalue_non_capturing_lambda_returning_int)
137+
+ TEST_FIXTURE(SetupFixture, test_set_from_rvalue_non_capturing_lambda_implicit)
168138
+ {
169139
+ etl::delegate<int(int, int)> d;
170140
+
171141
+ d.set([](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j + 6; });
172142
+
173143
+ int result = d(VALUE1, VALUE2);
174-
175-
CHECK(function_called == FunctionCalled::Lambda_Called);
176-
CHECK(parameter_correct);
144+
+
145+
+ CHECK(function_called == FunctionCalled::Lambda_Called);
146+
+ CHECK(parameter_correct);
177147
+ CHECK_EQUAL(result, VALUE1 + VALUE2 + 6);
178-
}
179-
180-
#if ETL_USING_CPP17
148+
+ }
149+
+
150+
//*************************************************************************
151+
TEST_FIXTURE(SetupFixture, test_assign_from_rvalue_non_capturing_lambda)
152+
{
181153
--
182-
2.43.0
154+
2.51.0
183155

0 commit comments

Comments
 (0)