Skip to content

Commit

Permalink
#965 Fix accident creation of a delegate to an rvalue delegate when c…
Browse files Browse the repository at this point in the history
…opying/assigning from delegate with mismatching signature

#966 A constructor for delegate with a freestanding function
  • Loading branch information
jwellbelove committed Nov 10, 2024
1 parent 586ae0c commit 4b7997a
Show file tree
Hide file tree
Showing 3 changed files with 687 additions and 34 deletions.
61 changes: 43 additions & 18 deletions include/etl/private/delegate_cpp03.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,21 +168,42 @@ namespace etl
}
};

//*****************************************************************
/// The tag to identify an etl::delegate.
///\ingroup delegate
//*****************************************************************
struct delegate_tag
{
};

//***************************************************************************
/// is_delegate
//***************************************************************************
template <typename T>
struct is_delegate : etl::bool_constant<etl::is_base_of<delegate_tag, T>::value>
{
};

//*************************************************************************
/// Declaration.
//*************************************************************************
template <typename T>
class delegate;

template <typename TReturn, typename TParam>
class delegate<TReturn(TParam)> : public private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>
class delegate<TReturn(TParam)> : public private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>,
public delegate_tag
{
private:

typedef delegate<TReturn(TParam)> delegate_type;

public:

typedef TReturn (*function_type)(TParam);
typedef TReturn return_type;
typedef TParam argument_type;

using private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>::call_if;

//*************************************************************************
Expand All @@ -204,7 +225,7 @@ namespace etl
// Construct from a functor.
//*************************************************************************
template <typename TFunctor>
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
{
assign((void*)(&instance), functor_stub<TFunctor>);
}
Expand All @@ -213,7 +234,7 @@ namespace etl
// Construct from a const functor.
//*************************************************************************
template <typename TFunctor>
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
}
Expand All @@ -232,7 +253,7 @@ namespace etl
//*************************************************************************
template <typename TFunctor>
static
typename etl::enable_if<etl::is_class<TFunctor>::value &&!etl::is_same<delegate_type, TFunctor>::value, delegate>::type
typename etl::enable_if<etl::is_class<TFunctor>::value &&!is_delegate<TFunctor>::value, delegate>::type
create(TFunctor& instance)
{
return delegate((void*)(&instance), functor_stub<TFunctor>);
Expand All @@ -243,7 +264,7 @@ namespace etl
//*************************************************************************
template <typename TFunctor>
static
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate>::type
create(const TFunctor& instance)
{
return delegate((void*)(&instance), const_functor_stub<TFunctor>);
Expand Down Expand Up @@ -330,7 +351,7 @@ namespace etl
/// Set from Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
set(TFunctor& instance)
{
assign((void*)(&instance), functor_stub<TFunctor>);
Expand All @@ -340,7 +361,7 @@ namespace etl
/// Set from const Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
set(const TFunctor& instance)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
Expand Down Expand Up @@ -467,7 +488,7 @@ namespace etl
/// Create from Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
operator =(TFunctor& instance)
{
assign((void*)(&instance), functor_stub<TFunctor>);
Expand All @@ -478,7 +499,7 @@ namespace etl
/// Create from const Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
operator =(const TFunctor& instance)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
Expand Down Expand Up @@ -684,6 +705,10 @@ namespace etl

public:

typedef TReturn (*function_type)(void);
typedef TReturn return_type;
typedef void argument_type;

using private_delegate::call_if_impl< delegate<TReturn(void)>, TReturn, void>::call_if;

//*************************************************************************
Expand All @@ -705,7 +730,7 @@ namespace etl
// Construct from functor.
//*************************************************************************
template <typename TFunctor>
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
{
assign((void*)(&instance), functor_stub<TFunctor>);
}
Expand All @@ -714,7 +739,7 @@ namespace etl
// Construct from const functor.
//*************************************************************************
template <typename TFunctor>
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
}
Expand All @@ -733,7 +758,7 @@ namespace etl
//*************************************************************************
template <typename TFunctor>
static
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate>::type
create(TFunctor& instance)
{
return delegate((void*)(&instance), functor_stub<TFunctor>);
Expand All @@ -744,7 +769,7 @@ namespace etl
//*************************************************************************
template <typename TFunctor>
static
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate>::type
create(const TFunctor& instance)
{
return delegate((void*)(&instance), const_functor_stub<TFunctor>);
Expand Down Expand Up @@ -831,7 +856,7 @@ namespace etl
/// Set from Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
set(TFunctor& instance)
{
assign((void*)(&instance), functor_stub<TFunctor>);
Expand All @@ -841,7 +866,7 @@ namespace etl
/// Set from const Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
set(const TFunctor& instance)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
Expand Down Expand Up @@ -968,7 +993,7 @@ namespace etl
/// Create from Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
operator =(TFunctor& instance)
{
assign((void*)(&instance), functor_stub<TFunctor>);
Expand All @@ -979,7 +1004,7 @@ namespace etl
/// Create from const Functor.
//*************************************************************************
template <typename TFunctor>
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
operator =(const TFunctor& instance)
{
assign((void*)(&instance), const_functor_stub<TFunctor>);
Expand Down
Loading

0 comments on commit 4b7997a

Please sign in to comment.