mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-30 06:18:50 +08:00
etl/delegate: fix accident creation of a delegate to an rvalue delegate when copying/assigning from delegate with mismatching signature (#965)
* etl/delegate: fix accident creation of a delegate to an rvalue delegate when copying/assigning from delegate with mismatching signature * etl/type_traits: fix etl::is_base_of for the case when TDerived is final * add etl::is_delegate * add changes related to etl::is_delegate to c++03 implementation * add etl::is_delegate_v<T>
This commit is contained in:
parent
081e920302
commit
71b691f7fe
@ -168,6 +168,23 @@ namespace etl
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************
|
||||
/// The tag to identify an etl::delegate.
|
||||
///\ingroup delegate
|
||||
//*****************************************************************
|
||||
struct delegate_tag
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// is_delegate
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct is_delegate
|
||||
{
|
||||
static const bool value = etl::is_base_of<delegate_tag, T>::value;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Declaration.
|
||||
//*************************************************************************
|
||||
@ -175,10 +192,10 @@ namespace etl
|
||||
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:
|
||||
@ -204,7 +221,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>);
|
||||
}
|
||||
@ -213,7 +230,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>);
|
||||
}
|
||||
@ -232,7 +249,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>);
|
||||
@ -243,7 +260,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>);
|
||||
@ -330,7 +347,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>);
|
||||
@ -340,7 +357,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>);
|
||||
@ -467,7 +484,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>);
|
||||
@ -478,7 +495,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>);
|
||||
@ -705,7 +722,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>);
|
||||
}
|
||||
@ -714,7 +731,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>);
|
||||
}
|
||||
@ -733,7 +750,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>);
|
||||
@ -744,7 +761,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>);
|
||||
@ -831,7 +848,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>);
|
||||
@ -841,7 +858,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>);
|
||||
@ -968,7 +985,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>);
|
||||
@ -979,7 +996,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>);
|
||||
|
||||
@ -83,16 +83,41 @@ namespace etl
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************
|
||||
/// The tag to identify an etl::delegate.
|
||||
///\ingroup delegate
|
||||
//*****************************************************************
|
||||
struct delegate_tag
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// is_delegate
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct is_delegate
|
||||
{
|
||||
static constexpr bool value = etl::is_base_of<delegate_tag, T>::value;
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_delegate_v = is_delegate<T>::value;
|
||||
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Declaration.
|
||||
//*************************************************************************
|
||||
template <typename T> class delegate;
|
||||
template <typename T>
|
||||
class delegate;
|
||||
|
||||
//*************************************************************************
|
||||
/// Specialisation.
|
||||
//*************************************************************************
|
||||
template <typename TReturn, typename... TParams>
|
||||
class delegate<TReturn(TParams...)> final
|
||||
class delegate<TReturn(TParams...)> final : public delegate_tag
|
||||
{
|
||||
public:
|
||||
|
||||
@ -111,7 +136,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
// Construct from lambda or functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate(TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||
@ -120,7 +145,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
// Construct from const lambda or functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate(const TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
@ -139,7 +164,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Create from Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_NODISCARD
|
||||
static ETL_CONSTEXPR14 delegate create(TLambda& instance)
|
||||
{
|
||||
@ -149,7 +174,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Create from const Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_NODISCARD
|
||||
static ETL_CONSTEXPR14 delegate create(const TLambda& instance)
|
||||
{
|
||||
@ -257,7 +282,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Set from Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 void set(TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||
@ -266,7 +291,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Set from const Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 void set(const TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
@ -427,7 +452,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Create from Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate& operator =(TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||
@ -437,7 +462,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Create from const Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate& operator =(const TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
|
||||
@ -627,18 +627,13 @@ namespace etl
|
||||
struct is_base_of
|
||||
{
|
||||
private:
|
||||
|
||||
template<typename T> struct dummy {};
|
||||
struct internal: TDerived, dummy<int>{};
|
||||
|
||||
static TBase* check(TBase*) { return (TBase*)0; }
|
||||
|
||||
template<typename T>
|
||||
static char check(dummy<T>*) { return 0; }
|
||||
static char check(...) { return 0; }
|
||||
|
||||
public:
|
||||
|
||||
static const bool value = (sizeof(check((internal*)0)) == sizeof(TBase*));
|
||||
static const bool value = (sizeof(check((TDerived*)0)) == sizeof(TBase*));
|
||||
};
|
||||
|
||||
// For when TBase or TDerived is a fundamental type.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user