#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
This commit is contained in:
John Wellbelove 2024-11-10 10:26:24 +00:00
parent ddef6a04ff
commit 0026a8b908
3 changed files with 687 additions and 34 deletions

View File

@ -168,6 +168,22 @@ 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.
//*************************************************************************
@ -175,14 +191,19 @@ 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:
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;
//*************************************************************************
@ -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>);
}
@ -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>);
}
@ -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>);
@ -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>);
@ -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>);
@ -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>);
@ -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>);
@ -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>);
@ -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;
//*************************************************************************
@ -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>);
}
@ -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>);
}
@ -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>);
@ -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>);
@ -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>);
@ -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>);
@ -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>);
@ -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>);

View File

@ -83,16 +83,38 @@ 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>
{
};
#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 +133,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 +142,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 +161,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 +171,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 +279,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 +288,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>);
@ -348,7 +370,7 @@ namespace etl
//*************************************************************************
/// Execute the delegate if valid.
/// 'void' return.
/// 'void' return delegate.
//*************************************************************************
template <typename TRet = TReturn>
ETL_CONSTEXPR14
@ -368,7 +390,7 @@ namespace etl
//*************************************************************************
/// Execute the delegate if valid.
/// Non 'void' return.
/// Non 'void' return delegate.
//*************************************************************************
template <typename TRet = TReturn>
ETL_CONSTEXPR14
@ -427,7 +449,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 +459,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,6 +649,136 @@ namespace etl
//*************************************************************************
invocation_element invocation;
};
#if ETL_USING_CPP17
namespace private_delegate
{
//***************************************************************************
/// A template to extract the function type traits.
//***************************************************************************
template <typename T>
struct function_traits;
//***************************************************************************
/// Specialisation for function pointers
//***************************************************************************
template <typename TReturn, typename... TArgs>
struct function_traits<TReturn(*)(TArgs...)>
{
using function_type = TReturn(TArgs...);
enum : bool
{
is_const = false
};
};
//***************************************************************************
/// Specialisation for member function pointers
//***************************************************************************
template <typename TReturn, typename TObject, typename... TArgs>
struct function_traits<TReturn(TObject::*)(TArgs...)>
{
using function_type = TReturn(TArgs...);
enum : bool
{
is_const = false
};
};
//***************************************************************************
/// Specialisation for const member function pointers
//***************************************************************************
template <typename TReturn, typename TObject, typename... TArgs>
struct function_traits<TReturn(TObject::*)(TArgs...) const>
{
using function_type = TReturn(TArgs...);
enum : bool
{
is_const = true
};
};
}
//*************************************************************************
/// Make a delegate from a free function.
//*************************************************************************
template <auto Function>
constexpr auto make_delegate() ETL_NOEXCEPT
{
using function_type = typename etl::private_delegate::function_traits<decltype(Function)>::function_type;
return etl::delegate<function_type>::template create<Function>();
}
//*************************************************************************
/// Make a delegate from a functor or lambda function.
//*************************************************************************
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value, void>>
constexpr auto make_delegate(TLambda& instance) ETL_NOEXCEPT
{
using function_type = typename etl::private_delegate::function_traits<decltype(&TLambda::operator())>::function_type;
return etl::delegate<function_type>(instance);
}
//*************************************************************************
/// Make a delegate from a functor, compile time.
//*************************************************************************
template <typename T, T& Instance>
constexpr auto make_delegate() ETL_NOEXCEPT
{
using function_type = typename etl::private_delegate::function_traits<decltype(&T::operator())>::function_type;
return etl::delegate<function_type>::template create<T, Instance>();
}
//*************************************************************************
/// Make a delegate from a member function at compile time.
//*************************************************************************
template <typename T, auto Method, T& Instance, typename = etl::enable_if_t<!private_delegate::function_traits<decltype(Method)>::is_const>>
constexpr auto make_delegate() ETL_NOEXCEPT
{
using function_type = typename etl::private_delegate::function_traits<decltype(Method)>::function_type;
return etl::delegate<function_type>::template create<T, Method, Instance>();
}
//*************************************************************************
/// Make a delegate from a const member function at compile time.
//*************************************************************************
template <typename T, auto Method, const T& Instance, typename = etl::enable_if_t<private_delegate::function_traits<decltype(Method)>::is_const>>
constexpr auto make_delegate() ETL_NOEXCEPT
{
using function_type = typename etl::private_delegate::function_traits<decltype(Method)>::function_type;
return etl::delegate<function_type>::template create<T, Method, Instance>();
}
//*************************************************************************
/// Make a delegate from a member function at run time.
//*************************************************************************
template <typename T, auto Method>
constexpr auto make_delegate(T& instance) ETL_NOEXCEPT
{
using function_type = typename etl::private_delegate::function_traits<decltype(Method)>::function_type;
return etl::delegate<function_type>::template create<T, Method>(instance);
}
//*************************************************************************
/// Make a delegate from a member function at run time.
//*************************************************************************
template <typename T, auto Method>
constexpr auto make_delegate(const T& instance) ETL_NOEXCEPT
{
using function_type = typename etl::private_delegate::function_traits<decltype(Method)>::function_type;
return etl::delegate<function_type>::template create<T, Method>(instance);
}
#endif
}
#endif

View File

@ -221,8 +221,6 @@ namespace
parameter_correct = (data.d == VALUE1) && (j == VALUE2);
}
//*******************************************
// operator()
void operator()()
{
function_called = FunctionCalled::Operator_Called;
@ -234,6 +232,26 @@ namespace
}
};
//*******************************************
// Functor with non-const operator()
struct Functor
{
void operator()()
{
function_called = FunctionCalled::Operator_Called;
}
};
//*******************************************
// Functor with const operator()
struct FunctorConst
{
void operator()() const
{
function_called = FunctionCalled::Operator_Const_Called;
}
};
//*******************************************
int times_2(int a)
{
@ -242,6 +260,11 @@ namespace
Object object_static;
const Object const_object_static;
#if ETL_USING_CPP17
Functor functor_static;
const FunctorConst const_functor_static;
#endif
}
namespace
@ -314,6 +337,18 @@ namespace
CHECK(function_called == FunctionCalled::Free_Void_Called);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_free_void)
{
auto d = etl::make_delegate<&free_void>();
d();
CHECK(function_called == FunctionCalled::Free_Void_Called);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_free_void_constexpr)
@ -326,6 +361,18 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_free_void_constexpr)
{
constexpr auto d = etl::make_delegate<&free_void>();
d();
CHECK(function_called == FunctionCalled::Free_Void_Called);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_free_int)
{
@ -337,6 +384,19 @@ namespace
CHECK(parameter_correct);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_free_int)
{
auto d = etl::make_delegate<&free_int>();
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Free_Int_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_free_int_constexpr)
@ -350,6 +410,19 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_free_int_constexpr)
{
constexpr auto d = etl::make_delegate<&free_int>();
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Free_Int_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_free_reference)
{
@ -364,6 +437,22 @@ namespace
CHECK(parameter_correct);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_free_reference)
{
etl::delegate<void(const Data&, int)> d = etl::make_delegate<&free_reference>();
Data data;
data.d = VALUE1;
d(data, VALUE2);
CHECK(function_called == FunctionCalled::Free_Reference_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_free_reference_constexpr)
@ -380,6 +469,22 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_free_reference_constexpr)
{
constexpr etl::delegate<void(const Data&, int)> d = etl::make_delegate<&free_reference>();
Data data;
data.d = VALUE1;
d(data, VALUE2);
CHECK(function_called == FunctionCalled::Free_Reference_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_free_moveableonly)
{
@ -394,6 +499,22 @@ namespace
CHECK(parameter_correct);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_free_moveableonly)
{
auto d = etl::make_delegate<&free_moveableonly>();
MoveableOnlyData data;
data.d = VALUE1;
d(std::move(data));
CHECK(function_called == FunctionCalled::Free_Moveableonly_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_free_moveableonly_constexpr)
@ -410,6 +531,22 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_free_moveableonly_constexpr)
{
constexpr auto d = etl::make_delegate<&free_moveableonly>();
MoveableOnlyData data;
data.d = VALUE1;
d(std::move(data));
CHECK(function_called == FunctionCalled::Free_Moveableonly_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_lambda_int)
{
@ -434,6 +571,21 @@ namespace
CHECK(parameter_correct);
}
#if ETL_USING_CPP17
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_make_delegate_lambda_int_create)
{
auto lambda = [](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); };
auto d = etl::make_delegate(lambda);
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Lambda_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_operator_void)
{
@ -446,6 +598,20 @@ namespace
CHECK(function_called == FunctionCalled::Operator_Called);
}
#if ETL_USING_CPP17
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_make_delegate_member_operator_void)
{
Functor object;
auto d = etl::make_delegate(object);
d();
CHECK(function_called == FunctionCalled::Operator_Called);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_operator_void_create)
{
@ -459,7 +625,7 @@ namespace
}
//*************************************************************************
#if ETL_USING_CPP14
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_member_operator_void_create_constexpr)
{
static Object object;
@ -484,7 +650,21 @@ namespace
CHECK(function_called == FunctionCalled::Operator_Const_Called);
}
#if !defined(ETL_COMPILER_GCC)
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_operator_void_const)
{
const FunctorConst object;
auto d = etl::make_delegate(object);
d();
CHECK(function_called == FunctionCalled::Operator_Const_Called);
}
#endif
#if !(defined(ETL_COMPILER_GCC) && (__GNUC__ <= 8))
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_operator_void_compile_time)
{
@ -495,6 +675,18 @@ namespace
CHECK(function_called == FunctionCalled::Operator_Called);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_operator_void_compile_time)
{
auto d = etl::make_delegate<Functor, functor_static>();
d();
CHECK(function_called == FunctionCalled::Operator_Called);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_operator_void_compile_time_constexpr)
@ -507,6 +699,18 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_operator_void_compile_time_constexpr)
{
constexpr auto d = etl::make_delegate<Functor, functor_static>();
d();
CHECK(function_called == FunctionCalled::Operator_Called);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_operator_void_compile_time_const)
{
@ -517,6 +721,18 @@ namespace
CHECK(function_called == FunctionCalled::Operator_Const_Called);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_operator_void_compile_time_const)
{
auto d = etl::make_delegate<const FunctorConst, const_functor_static>();
d();
CHECK(function_called == FunctionCalled::Operator_Const_Called);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_operator_void_compile_time_const_constexpr)
@ -528,6 +744,18 @@ namespace
CHECK(function_called == FunctionCalled::Operator_Const_Called);
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_operator_void_compile_time_const_constexpr)
{
constexpr auto d = etl::make_delegate<const FunctorConst, const_functor_static>();
d();
CHECK(function_called == FunctionCalled::Operator_Const_Called);
}
#endif
#endif
//*************************************************************************
@ -556,6 +784,20 @@ namespace
CHECK(function_called == FunctionCalled::Member_Void_Called);
}
#if ETL_USING_CPP17
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_make_delegate_member_void)
{
Object object;
auto d = etl::make_delegate<Object, &Object::member_void>(object);
d();
CHECK(function_called == FunctionCalled::Member_Void_Called);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_void_constexpr)
@ -570,6 +812,20 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_void_constexpr)
{
static Object object;
constexpr auto d = etl::make_delegate<Object, &Object::member_void>(object);
d();
CHECK(function_called == FunctionCalled::Member_Void_Called);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_void_const)
{
@ -582,6 +838,20 @@ namespace
CHECK(function_called == FunctionCalled::Member_Void_Const_Called);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_void_const)
{
const Object object;
auto d = etl::make_delegate<Object, &Object::member_void_const>(object);
d();
CHECK(function_called == FunctionCalled::Member_Void_Const_Called);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_void_const_constexpr)
@ -596,6 +866,20 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_void_const_constexpr)
{
static const Object object;
constexpr auto d = etl::make_delegate<Object, &Object::member_void_const>(object);
d();
CHECK(function_called == FunctionCalled::Member_Void_Const_Called);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_int)
{
@ -609,6 +893,21 @@ namespace
CHECK(parameter_correct);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_int)
{
Object object;
auto d = etl::make_delegate<Object, &Object::member_int>(object);
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Member_Int_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_int_constexpr)
@ -624,6 +923,21 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_int_constexpr)
{
static Object object;
constexpr auto d = etl::make_delegate<Object, &Object::member_int>(object);
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Member_Int_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_int_const)
{
@ -637,6 +951,21 @@ namespace
CHECK(parameter_correct);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_int_const)
{
const Object object;
auto d = etl::make_delegate<Object, &Object::member_int_const>(object);
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Member_Int_Const_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_int_const_constexpr)
@ -652,6 +981,21 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_int_const_constexpr)
{
static const Object object;
constexpr auto d = etl::make_delegate<Object, &Object::member_int_const>(object);
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Member_Int_Const_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_reference)
{
@ -762,6 +1106,22 @@ namespace
CHECK(parameter_correct);
}
//*************************************************************************
//#if ETL_USING_CPP17
// TEST_FIXTURE(SetupFixture, test_make_delegate_member_static)
// {
// auto d = etl::make_delegate<Object::member_static>();
//
// Data data;
// data.d = VALUE1;
//
// d(data, VALUE2);
//
// CHECK(function_called == FunctionCalled::Member_Static_Called);
// CHECK(parameter_correct);
// }
//#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_static_constexpr)
@ -778,6 +1138,22 @@ namespace
}
#endif
//*************************************************************************
//#if ETL_USING_CPP17
// TEST_FIXTURE(SetupFixture, test_make_delegate_member_static_constexpr)
// {
// constexpr auto d = etl::make_delegate<Object::member_static>();
//
// Data data;
// data.d = VALUE1;
//
// d(data, VALUE2);
//
// CHECK(function_called == FunctionCalled::Member_Static_Called);
// CHECK(parameter_correct);
// }
//#endif
#if !(defined(ETL_COMPILER_GCC) && (__GNUC__ <= 5))
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_void_compile_time)
@ -799,6 +1175,18 @@ namespace
CHECK(function_called == FunctionCalled::Member_Void_Called);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_void_compile_time_new_api)
{
auto d = etl::make_delegate<Object, &Object::member_void, object_static>();
d();
CHECK(function_called == FunctionCalled::Member_Void_Called);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_void_compile_time_constexpr)
@ -823,6 +1211,18 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_void_compile_time_constexpr_new_api)
{
constexpr auto d = etl::make_delegate<Object, &Object::member_void, object_static>();
d();
CHECK(function_called == FunctionCalled::Member_Void_Called);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_void_const_compile_time)
{
@ -843,6 +1243,18 @@ namespace
CHECK(function_called == FunctionCalled::Member_Void_Const_Called);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_void_const_compile_time_new_api)
{
auto d = etl::make_delegate<Object, &Object::member_void_const, const_object_static>();
d();
CHECK(function_called == FunctionCalled::Member_Void_Const_Called);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_void_const_compile_time_constexpr)
@ -867,6 +1279,18 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_void_const_compile_time_constexpr_new_api)
{
constexpr auto d = etl::make_delegate<Object, &Object::member_void_const, const_object_static>();
d();
CHECK(function_called == FunctionCalled::Member_Void_Const_Called);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_int_compile_time)
{
@ -889,6 +1313,19 @@ namespace
CHECK(parameter_correct);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_int_compile_time_new_api)
{
auto d = etl::make_delegate<Object, &Object::member_int, object_static>();
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Member_Int_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_int_compile_time_constexpr)
@ -915,6 +1352,19 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_int_compile_time_constexpr_new_api)
{
constexpr auto d = etl::make_delegate<Object, &Object::member_int, object_static>();
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Member_Int_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_int_const_compile_time)
{
@ -937,6 +1387,19 @@ namespace
CHECK(parameter_correct);
}
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_int_const_compile_tim1e_new_api)
{
auto d = etl::make_delegate<Object, &Object::member_int_const, const_object_static>();
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Member_Int_Const_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
#if ETL_USING_CPP14
TEST_FIXTURE(SetupFixture, test_member_int_const_compile_time_constexpr)
@ -963,6 +1426,19 @@ namespace
}
#endif
//*************************************************************************
#if ETL_USING_CPP17
TEST_FIXTURE(SetupFixture, test_make_delegate_member_int_const_compile_time_constexpr_new_api)
{
constexpr auto d = etl::make_delegate<Object, &Object::member_int_const, const_object_static>();
d(VALUE1, VALUE2);
CHECK(function_called == FunctionCalled::Member_Int_Const_Called);
CHECK(parameter_correct);
}
#endif
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_member_reference_compile_time)
{