Skip to content

Commit 0026a8b

Browse files
committed
#965 Fix accident creation of a delegate to an rvalue delegate when copying/assigning from delegate with mismatching signature
#966 A constructor for delegate with a freestanding function
1 parent ddef6a0 commit 0026a8b

File tree

3 files changed

+687
-34
lines changed

3 files changed

+687
-34
lines changed

include/etl/private/delegate_cpp03.h

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -168,21 +168,42 @@ namespace etl
168168
}
169169
};
170170

171+
//*****************************************************************
172+
/// The tag to identify an etl::delegate.
173+
///\ingroup delegate
174+
//*****************************************************************
175+
struct delegate_tag
176+
{
177+
};
178+
179+
//***************************************************************************
180+
/// is_delegate
181+
//***************************************************************************
182+
template <typename T>
183+
struct is_delegate : etl::bool_constant<etl::is_base_of<delegate_tag, T>::value>
184+
{
185+
};
186+
171187
//*************************************************************************
172188
/// Declaration.
173189
//*************************************************************************
174190
template <typename T>
175191
class delegate;
176192

177193
template <typename TReturn, typename TParam>
178-
class delegate<TReturn(TParam)> : public private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>
194+
class delegate<TReturn(TParam)> : public private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>,
195+
public delegate_tag
179196
{
180197
private:
181-
198+
182199
typedef delegate<TReturn(TParam)> delegate_type;
183200

184201
public:
185202

203+
typedef TReturn (*function_type)(TParam);
204+
typedef TReturn return_type;
205+
typedef TParam argument_type;
206+
186207
using private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>::call_if;
187208

188209
//*************************************************************************
@@ -204,7 +225,7 @@ namespace etl
204225
// Construct from a functor.
205226
//*************************************************************************
206227
template <typename TFunctor>
207-
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
228+
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
208229
{
209230
assign((void*)(&instance), functor_stub<TFunctor>);
210231
}
@@ -213,7 +234,7 @@ namespace etl
213234
// Construct from a const functor.
214235
//*************************************************************************
215236
template <typename TFunctor>
216-
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
237+
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
217238
{
218239
assign((void*)(&instance), const_functor_stub<TFunctor>);
219240
}
@@ -232,7 +253,7 @@ namespace etl
232253
//*************************************************************************
233254
template <typename TFunctor>
234255
static
235-
typename etl::enable_if<etl::is_class<TFunctor>::value &&!etl::is_same<delegate_type, TFunctor>::value, delegate>::type
256+
typename etl::enable_if<etl::is_class<TFunctor>::value &&!is_delegate<TFunctor>::value, delegate>::type
236257
create(TFunctor& instance)
237258
{
238259
return delegate((void*)(&instance), functor_stub<TFunctor>);
@@ -243,7 +264,7 @@ namespace etl
243264
//*************************************************************************
244265
template <typename TFunctor>
245266
static
246-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
267+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate>::type
247268
create(const TFunctor& instance)
248269
{
249270
return delegate((void*)(&instance), const_functor_stub<TFunctor>);
@@ -330,7 +351,7 @@ namespace etl
330351
/// Set from Functor.
331352
//*************************************************************************
332353
template <typename TFunctor>
333-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
354+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
334355
set(TFunctor& instance)
335356
{
336357
assign((void*)(&instance), functor_stub<TFunctor>);
@@ -340,7 +361,7 @@ namespace etl
340361
/// Set from const Functor.
341362
//*************************************************************************
342363
template <typename TFunctor>
343-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
364+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
344365
set(const TFunctor& instance)
345366
{
346367
assign((void*)(&instance), const_functor_stub<TFunctor>);
@@ -467,7 +488,7 @@ namespace etl
467488
/// Create from Functor.
468489
//*************************************************************************
469490
template <typename TFunctor>
470-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
491+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
471492
operator =(TFunctor& instance)
472493
{
473494
assign((void*)(&instance), functor_stub<TFunctor>);
@@ -478,7 +499,7 @@ namespace etl
478499
/// Create from const Functor.
479500
//*************************************************************************
480501
template <typename TFunctor>
481-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
502+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
482503
operator =(const TFunctor& instance)
483504
{
484505
assign((void*)(&instance), const_functor_stub<TFunctor>);
@@ -684,6 +705,10 @@ namespace etl
684705

685706
public:
686707

708+
typedef TReturn (*function_type)(void);
709+
typedef TReturn return_type;
710+
typedef void argument_type;
711+
687712
using private_delegate::call_if_impl< delegate<TReturn(void)>, TReturn, void>::call_if;
688713

689714
//*************************************************************************
@@ -705,7 +730,7 @@ namespace etl
705730
// Construct from functor.
706731
//*************************************************************************
707732
template <typename TFunctor>
708-
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
733+
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
709734
{
710735
assign((void*)(&instance), functor_stub<TFunctor>);
711736
}
@@ -714,7 +739,7 @@ namespace etl
714739
// Construct from const functor.
715740
//*************************************************************************
716741
template <typename TFunctor>
717-
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
742+
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
718743
{
719744
assign((void*)(&instance), const_functor_stub<TFunctor>);
720745
}
@@ -733,7 +758,7 @@ namespace etl
733758
//*************************************************************************
734759
template <typename TFunctor>
735760
static
736-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
761+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate>::type
737762
create(TFunctor& instance)
738763
{
739764
return delegate((void*)(&instance), functor_stub<TFunctor>);
@@ -744,7 +769,7 @@ namespace etl
744769
//*************************************************************************
745770
template <typename TFunctor>
746771
static
747-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
772+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate>::type
748773
create(const TFunctor& instance)
749774
{
750775
return delegate((void*)(&instance), const_functor_stub<TFunctor>);
@@ -831,7 +856,7 @@ namespace etl
831856
/// Set from Functor.
832857
//*************************************************************************
833858
template <typename TFunctor>
834-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
859+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
835860
set(TFunctor& instance)
836861
{
837862
assign((void*)(&instance), functor_stub<TFunctor>);
@@ -841,7 +866,7 @@ namespace etl
841866
/// Set from const Functor.
842867
//*************************************************************************
843868
template <typename TFunctor>
844-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
869+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
845870
set(const TFunctor& instance)
846871
{
847872
assign((void*)(&instance), const_functor_stub<TFunctor>);
@@ -968,7 +993,7 @@ namespace etl
968993
/// Create from Functor.
969994
//*************************************************************************
970995
template <typename TFunctor>
971-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
996+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
972997
operator =(TFunctor& instance)
973998
{
974999
assign((void*)(&instance), functor_stub<TFunctor>);
@@ -979,7 +1004,7 @@ namespace etl
9791004
/// Create from const Functor.
9801005
//*************************************************************************
9811006
template <typename TFunctor>
982-
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
1007+
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
9831008
operator =(const TFunctor& instance)
9841009
{
9851010
assign((void*)(&instance), const_functor_stub<TFunctor>);

0 commit comments

Comments
 (0)