From f747fb2afaa12168b7760f001a69b8a401cd62ca Mon Sep 17 00:00:00 2001 From: Vladimir Pinchuk Date: Thu, 10 Oct 2024 13:08:20 +0300 Subject: [PATCH 1/5] etl/delegate: fix accident creation of a delegate to an rvalue delegate when copying/assigning from delegate with mismatching signature --- include/etl/private/delegate_cpp11.h | 29 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/include/etl/private/delegate_cpp11.h b/include/etl/private/delegate_cpp11.h index 8f438602c..7e79c977b 100644 --- a/include/etl/private/delegate_cpp11.h +++ b/include/etl/private/delegate_cpp11.h @@ -83,16 +83,25 @@ namespace etl } }; + //***************************************************************** + /// The tag to identify an etl::delegate. + ///\ingroup delegate + //***************************************************************** + struct delegate_tag + { + }; + //************************************************************************* /// Declaration. //************************************************************************* - template class delegate; + template + class delegate; //************************************************************************* /// Specialisation. //************************************************************************* template - class delegate final + class delegate final : public delegate_tag { public: @@ -111,7 +120,7 @@ namespace etl //************************************************************************* // Construct from lambda or functor. //************************************************************************* - template ::value && !etl::is_same, TLambda>::value, void>> + template ::value && !etl::is_base_of::value, void>> ETL_CONSTEXPR14 delegate(TLambda& instance) { assign((void*)(&instance), lambda_stub); @@ -120,7 +129,7 @@ namespace etl //************************************************************************* // Construct from const lambda or functor. //************************************************************************* - template ::value && !etl::is_same, TLambda>::value, void>> + template ::value && !etl::is_base_of::value, void>> ETL_CONSTEXPR14 delegate(const TLambda& instance) { assign((void*)(&instance), const_lambda_stub); @@ -139,7 +148,7 @@ namespace etl //************************************************************************* /// Create from Lambda or Functor. //************************************************************************* - template ::value && !etl::is_same, TLambda>::value, void>> + template ::value && !etl::is_base_of::value, void>> ETL_NODISCARD static ETL_CONSTEXPR14 delegate create(TLambda& instance) { @@ -149,7 +158,7 @@ namespace etl //************************************************************************* /// Create from const Lambda or Functor. //************************************************************************* - template ::value && !etl::is_same, TLambda>::value, void>> + template ::value && !etl::is_base_of::value, void>> ETL_NODISCARD static ETL_CONSTEXPR14 delegate create(const TLambda& instance) { @@ -257,7 +266,7 @@ namespace etl //************************************************************************* /// Set from Lambda or Functor. //************************************************************************* - template ::value && !etl::is_same, TLambda>::value, void>> + template ::value && !etl::is_base_of::value, void>> ETL_CONSTEXPR14 void set(TLambda& instance) { assign((void*)(&instance), lambda_stub); @@ -266,7 +275,7 @@ namespace etl //************************************************************************* /// Set from const Lambda or Functor. //************************************************************************* - template ::value && !etl::is_same, TLambda>::value, void>> + template ::value && !etl::is_base_of::value, void>> ETL_CONSTEXPR14 void set(const TLambda& instance) { assign((void*)(&instance), const_lambda_stub); @@ -427,7 +436,7 @@ namespace etl //************************************************************************* /// Create from Lambda or Functor. //************************************************************************* - template ::value && !etl::is_same, TLambda>::value, void>> + template ::value && !etl::is_base_of::value, void>> ETL_CONSTEXPR14 delegate& operator =(TLambda& instance) { assign((void*)(&instance), lambda_stub); @@ -437,7 +446,7 @@ namespace etl //************************************************************************* /// Create from const Lambda or Functor. //************************************************************************* - template ::value && !etl::is_same, TLambda>::value, void>> + template ::value && !etl::is_base_of::value, void>> ETL_CONSTEXPR14 delegate& operator =(const TLambda& instance) { assign((void*)(&instance), const_lambda_stub); From 4bc0a6b116fe45aaed0af3ca33950b2e549f553e Mon Sep 17 00:00:00 2001 From: Vladimir Pinchuk Date: Thu, 10 Oct 2024 13:08:27 +0300 Subject: [PATCH 2/5] etl/type_traits: fix etl::is_base_of for the case when TDerived is final --- include/etl/type_traits.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/etl/type_traits.h b/include/etl/type_traits.h index 47489c2cc..327f164be 100644 --- a/include/etl/type_traits.h +++ b/include/etl/type_traits.h @@ -627,18 +627,13 @@ namespace etl struct is_base_of { private: - - template struct dummy {}; - struct internal: TDerived, dummy{}; - static TBase* check(TBase*) { return (TBase*)0; } - template - static char check(dummy*) { 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. From 88c8391ffe03c8e04b1f68af65b6c1ab16bed0c7 Mon Sep 17 00:00:00 2001 From: Vladimir Pinchuk Date: Thu, 10 Oct 2024 16:34:56 +0300 Subject: [PATCH 3/5] add etl::is_delegate --- include/etl/private/delegate_cpp11.h | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/include/etl/private/delegate_cpp11.h b/include/etl/private/delegate_cpp11.h index 7e79c977b..1e7ec7242 100644 --- a/include/etl/private/delegate_cpp11.h +++ b/include/etl/private/delegate_cpp11.h @@ -91,6 +91,15 @@ namespace etl { }; + //*************************************************************************** + /// is_delegate + //*************************************************************************** + template + struct is_delegate + { + static constexpr bool value = etl::is_base_of::value; + }; + //************************************************************************* /// Declaration. //************************************************************************* @@ -120,7 +129,7 @@ namespace etl //************************************************************************* // Construct from lambda or functor. //************************************************************************* - template ::value && !etl::is_base_of::value, void>> + template ::value && !is_delegate::value, void>> ETL_CONSTEXPR14 delegate(TLambda& instance) { assign((void*)(&instance), lambda_stub); @@ -129,7 +138,7 @@ namespace etl //************************************************************************* // Construct from const lambda or functor. //************************************************************************* - template ::value && !etl::is_base_of::value, void>> + template ::value && !is_delegate::value, void>> ETL_CONSTEXPR14 delegate(const TLambda& instance) { assign((void*)(&instance), const_lambda_stub); @@ -148,7 +157,7 @@ namespace etl //************************************************************************* /// Create from Lambda or Functor. //************************************************************************* - template ::value && !etl::is_base_of::value, void>> + template ::value && !is_delegate::value, void>> ETL_NODISCARD static ETL_CONSTEXPR14 delegate create(TLambda& instance) { @@ -158,7 +167,7 @@ namespace etl //************************************************************************* /// Create from const Lambda or Functor. //************************************************************************* - template ::value && !etl::is_base_of::value, void>> + template ::value && !is_delegate::value, void>> ETL_NODISCARD static ETL_CONSTEXPR14 delegate create(const TLambda& instance) { @@ -266,7 +275,7 @@ namespace etl //************************************************************************* /// Set from Lambda or Functor. //************************************************************************* - template ::value && !etl::is_base_of::value, void>> + template ::value && !is_delegate::value, void>> ETL_CONSTEXPR14 void set(TLambda& instance) { assign((void*)(&instance), lambda_stub); @@ -275,7 +284,7 @@ namespace etl //************************************************************************* /// Set from const Lambda or Functor. //************************************************************************* - template ::value && !etl::is_base_of::value, void>> + template ::value && !is_delegate::value, void>> ETL_CONSTEXPR14 void set(const TLambda& instance) { assign((void*)(&instance), const_lambda_stub); @@ -436,7 +445,7 @@ namespace etl //************************************************************************* /// Create from Lambda or Functor. //************************************************************************* - template ::value && !etl::is_base_of::value, void>> + template ::value && !is_delegate::value, void>> ETL_CONSTEXPR14 delegate& operator =(TLambda& instance) { assign((void*)(&instance), lambda_stub); @@ -446,7 +455,7 @@ namespace etl //************************************************************************* /// Create from const Lambda or Functor. //************************************************************************* - template ::value && !etl::is_base_of::value, void>> + template ::value && !is_delegate::value, void>> ETL_CONSTEXPR14 delegate& operator =(const TLambda& instance) { assign((void*)(&instance), const_lambda_stub); From c5ed00dd0e54c3b7b486e95d7294f3e22db2a2ce Mon Sep 17 00:00:00 2001 From: Vladimir Pinchuk Date: Thu, 10 Oct 2024 20:28:16 +0300 Subject: [PATCH 4/5] add changes related to etl::is_delegate to c++03 implementation --- include/etl/private/delegate_cpp03.h | 53 ++++++++++++++++++---------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/include/etl/private/delegate_cpp03.h b/include/etl/private/delegate_cpp03.h index 74da0e497..5a1798cb8 100644 --- a/include/etl/private/delegate_cpp03.h +++ b/include/etl/private/delegate_cpp03.h @@ -168,6 +168,23 @@ namespace etl } }; + //***************************************************************** + /// The tag to identify an etl::delegate. + ///\ingroup delegate + //***************************************************************** + struct delegate_tag + { + }; + + //*************************************************************************** + /// is_delegate + //*************************************************************************** + template + struct is_delegate + { + static const bool value = etl::is_base_of::value; + }; + //************************************************************************* /// Declaration. //************************************************************************* @@ -175,10 +192,10 @@ namespace etl class delegate; template - class delegate : public private_delegate::call_if_impl, TReturn, TParam> + class delegate : public private_delegate::call_if_impl, TReturn, TParam>, public delegate_tag { private: - + typedef delegate delegate_type; public: @@ -204,7 +221,7 @@ namespace etl // Construct from a functor. //************************************************************************* template - delegate(TFunctor& instance, typename etl::enable_if::value && !etl::is_same::value, int>::type = 0) + delegate(TFunctor& instance, typename etl::enable_if::value && !is_delegate::value, int>::type = 0) { assign((void*)(&instance), functor_stub); } @@ -213,7 +230,7 @@ namespace etl // Construct from a const functor. //************************************************************************* template - delegate(const TFunctor& instance, typename etl::enable_if::value && !etl::is_same::value, int>::type = 0) + delegate(const TFunctor& instance, typename etl::enable_if::value && !is_delegate::value, int>::type = 0) { assign((void*)(&instance), const_functor_stub); } @@ -232,7 +249,7 @@ namespace etl //************************************************************************* template static - typename etl::enable_if::value &&!etl::is_same::value, delegate>::type + typename etl::enable_if::value &&!is_delegate::value, delegate>::type create(TFunctor& instance) { return delegate((void*)(&instance), functor_stub); @@ -243,7 +260,7 @@ namespace etl //************************************************************************* template static - typename etl::enable_if::value && !etl::is_same::value, delegate>::type + typename etl::enable_if::value && !is_delegate::value, delegate>::type create(const TFunctor& instance) { return delegate((void*)(&instance), const_functor_stub); @@ -330,7 +347,7 @@ namespace etl /// Set from Functor. //************************************************************************* template - typename etl::enable_if::value && !etl::is_same::value, void>::type + typename etl::enable_if::value && !is_delegate::value, void>::type set(TFunctor& instance) { assign((void*)(&instance), functor_stub); @@ -340,7 +357,7 @@ namespace etl /// Set from const Functor. //************************************************************************* template - typename etl::enable_if::value && !etl::is_same::value, void>::type + typename etl::enable_if::value && !is_delegate::value, void>::type set(const TFunctor& instance) { assign((void*)(&instance), const_functor_stub); @@ -467,7 +484,7 @@ namespace etl /// Create from Functor. //************************************************************************* template - typename etl::enable_if::value && !etl::is_same::value, delegate&>::type + typename etl::enable_if::value && !is_delegate::value, delegate&>::type operator =(TFunctor& instance) { assign((void*)(&instance), functor_stub); @@ -478,7 +495,7 @@ namespace etl /// Create from const Functor. //************************************************************************* template - typename etl::enable_if::value && !etl::is_same::value, delegate&>::type + typename etl::enable_if::value && !is_delegate::value, delegate&>::type operator =(const TFunctor& instance) { assign((void*)(&instance), const_functor_stub); @@ -705,7 +722,7 @@ namespace etl // Construct from functor. //************************************************************************* template - delegate(TFunctor& instance, typename etl::enable_if::value && !etl::is_same::value, int>::type = 0) + delegate(TFunctor& instance, typename etl::enable_if::value && !is_delegate::value, int>::type = 0) { assign((void*)(&instance), functor_stub); } @@ -714,7 +731,7 @@ namespace etl // Construct from const functor. //************************************************************************* template - delegate(const TFunctor& instance, typename etl::enable_if::value && !etl::is_same::value, int>::type = 0) + delegate(const TFunctor& instance, typename etl::enable_if::value && !is_delegate::value, int>::type = 0) { assign((void*)(&instance), const_functor_stub); } @@ -733,7 +750,7 @@ namespace etl //************************************************************************* template static - typename etl::enable_if::value && !etl::is_same::value, delegate>::type + typename etl::enable_if::value && !is_delegate::value, delegate>::type create(TFunctor& instance) { return delegate((void*)(&instance), functor_stub); @@ -744,7 +761,7 @@ namespace etl //************************************************************************* template static - typename etl::enable_if::value && !etl::is_same::value, delegate>::type + typename etl::enable_if::value && !is_delegate::value, delegate>::type create(const TFunctor& instance) { return delegate((void*)(&instance), const_functor_stub); @@ -831,7 +848,7 @@ namespace etl /// Set from Functor. //************************************************************************* template - typename etl::enable_if::value && !etl::is_same::value, void>::type + typename etl::enable_if::value && !is_delegate::value, void>::type set(TFunctor& instance) { assign((void*)(&instance), functor_stub); @@ -841,7 +858,7 @@ namespace etl /// Set from const Functor. //************************************************************************* template - typename etl::enable_if::value && !etl::is_same::value, void>::type + typename etl::enable_if::value && !is_delegate::value, void>::type set(const TFunctor& instance) { assign((void*)(&instance), const_functor_stub); @@ -968,7 +985,7 @@ namespace etl /// Create from Functor. //************************************************************************* template - typename etl::enable_if::value && !etl::is_same::value, delegate&>::type + typename etl::enable_if::value && !is_delegate::value, delegate&>::type operator =(TFunctor& instance) { assign((void*)(&instance), functor_stub); @@ -979,7 +996,7 @@ namespace etl /// Create from const Functor. //************************************************************************* template - typename etl::enable_if::value && !etl::is_same::value, delegate&>::type + typename etl::enable_if::value && !is_delegate::value, delegate&>::type operator =(const TFunctor& instance) { assign((void*)(&instance), const_functor_stub); From c7817efb0decbf3428c54c97b88f4295b506ce95 Mon Sep 17 00:00:00 2001 From: Vladimir Pinchuk Date: Sat, 12 Oct 2024 15:18:46 +0300 Subject: [PATCH 5/5] add etl::is_delegate_v --- include/etl/private/delegate_cpp11.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/etl/private/delegate_cpp11.h b/include/etl/private/delegate_cpp11.h index 1e7ec7242..1a276bb3b 100644 --- a/include/etl/private/delegate_cpp11.h +++ b/include/etl/private/delegate_cpp11.h @@ -100,6 +100,13 @@ namespace etl static constexpr bool value = etl::is_base_of::value; }; +#if ETL_USING_CPP17 + + template + inline constexpr bool is_delegate_v = is_delegate::value; + +#endif + //************************************************************************* /// Declaration. //*************************************************************************