mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Changed non-capturing lambda API to runtime function pointer API
This commit is contained in:
parent
bfbb7259e1
commit
ea397ec2dd
@ -118,6 +118,11 @@ namespace etl
|
||||
template <typename TReturn, typename... TArgs>
|
||||
class delegate<TReturn(TArgs...)> final : public delegate_tag
|
||||
{
|
||||
private:
|
||||
|
||||
using object_ptr = void*;
|
||||
using function_ptr = TReturn(*)(TArgs...);
|
||||
|
||||
public:
|
||||
|
||||
using return_type = TReturn;
|
||||
@ -141,7 +146,7 @@ namespace etl
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate(TLambda& instance) ETL_NOEXCEPT
|
||||
{
|
||||
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||
assign(object_ptr(&instance), lambda_stub<TLambda>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -150,26 +155,24 @@ namespace etl
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate(const TLambda& instance) ETL_NOEXCEPT
|
||||
{
|
||||
assign((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
assign(object_ptr(&instance), const_lambda_stub<TLambda>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Delete construction from rvalue reference lambda or functor.
|
||||
// Excludes non-capturing lambdas convertible to a function pointer.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TArgs...)>, TLambda>::value && !etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value &&
|
||||
!etl::is_same<etl::delegate<TReturn(TArgs...)>, TLambda>::value &&
|
||||
!etl::is_convertible<TLambda, function_ptr>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate(TLambda&& instance) = delete;
|
||||
|
||||
//*************************************************************************
|
||||
// Construct from non-capturing rvalue lambda convertible to function pointer.
|
||||
// Converts to a function pointer to avoid storing a dangling pointer
|
||||
// to a destroyed temporary.
|
||||
// Construct from a function pointer.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, int> = 0>
|
||||
delegate(TLambda&& instance) ETL_NOEXCEPT
|
||||
delegate(function_ptr fp) ETL_NOEXCEPT
|
||||
{
|
||||
TReturn(*fp)(TArgs...) = static_cast<TReturn(*)(TArgs...)>(instance);
|
||||
assign(reinterpret_cast<void*>(fp), function_ptr_stub);
|
||||
assign(fp, function_ptr_stub);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -179,7 +182,7 @@ namespace etl
|
||||
ETL_NODISCARD
|
||||
static ETL_CONSTEXPR14 delegate create() ETL_NOEXCEPT
|
||||
{
|
||||
return delegate(ETL_NULLPTR, function_stub<Method>);
|
||||
return delegate(function_stub<Method>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -189,7 +192,7 @@ namespace etl
|
||||
ETL_NODISCARD
|
||||
static ETL_CONSTEXPR14 delegate create(TLambda& instance) ETL_NOEXCEPT
|
||||
{
|
||||
return delegate((void*)(&instance), lambda_stub<TLambda>);
|
||||
return delegate(object_ptr(&instance), lambda_stub<TLambda>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -199,20 +202,16 @@ namespace etl
|
||||
ETL_NODISCARD
|
||||
static ETL_CONSTEXPR14 delegate create(const TLambda& instance) ETL_NOEXCEPT
|
||||
{
|
||||
return delegate((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
return delegate(object_ptr(&instance), const_lambda_stub<TLambda>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Create from non-capturing rvalue lambda convertible to function pointer.
|
||||
// Converts to a function pointer to avoid storing a dangling pointer
|
||||
// to a destroyed temporary.
|
||||
// Create from a function pointer.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, int> = 0>
|
||||
ETL_NODISCARD
|
||||
static delegate create(TLambda&& instance) ETL_NOEXCEPT
|
||||
static delegate create(function_ptr fp) ETL_NOEXCEPT
|
||||
{
|
||||
TReturn(*fp)(TArgs...) = static_cast<TReturn(*)(TArgs...)>(instance);
|
||||
return delegate(reinterpret_cast<void*>(fp), function_ptr_stub);
|
||||
return delegate(fp, function_ptr_stub);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -222,7 +221,7 @@ namespace etl
|
||||
ETL_NODISCARD
|
||||
static ETL_CONSTEXPR14 delegate create(T& instance) ETL_NOEXCEPT
|
||||
{
|
||||
return delegate((void*)(&instance), method_stub<T, Method>);
|
||||
return delegate(object_ptr(&instance), method_stub<T, Method>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -240,7 +239,7 @@ namespace etl
|
||||
ETL_NODISCARD
|
||||
static ETL_CONSTEXPR14 delegate create(const T& instance) ETL_NOEXCEPT
|
||||
{
|
||||
return delegate((void*)(&instance), const_method_stub<T, Method>);
|
||||
return delegate(object_ptr(&instance), const_method_stub<T, Method>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -310,7 +309,7 @@ namespace etl
|
||||
template <TReturn(*Method)(TArgs...)>
|
||||
ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
|
||||
{
|
||||
assign(ETL_NULLPTR, function_stub<Method>);
|
||||
assign(function_stub<Method>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -319,7 +318,7 @@ namespace etl
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 void set(TLambda& instance) ETL_NOEXCEPT
|
||||
{
|
||||
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||
assign(object_ptr(&instance), lambda_stub<TLambda>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -328,19 +327,15 @@ namespace etl
|
||||
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) ETL_NOEXCEPT
|
||||
{
|
||||
assign((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
assign(object_ptr(&instance), const_lambda_stub<TLambda>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Set from non-capturing rvalue lambda convertible to function pointer.
|
||||
// Converts to a function pointer to avoid storing a dangling pointer
|
||||
// to a destroyed temporary.
|
||||
// Set from a function pointer.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, int> = 0>
|
||||
void set(TLambda&& instance) ETL_NOEXCEPT
|
||||
void set(function_ptr fp) ETL_NOEXCEPT
|
||||
{
|
||||
TReturn(*fp)(TArgs...) = static_cast<TReturn(*)(TArgs...)>(instance);
|
||||
assign(reinterpret_cast<void*>(fp), function_ptr_stub);
|
||||
assign(fp, function_ptr_stub);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -349,7 +344,7 @@ namespace etl
|
||||
template <typename T, TReturn(T::* Method)(TArgs...)>
|
||||
ETL_CONSTEXPR14 void set(T& instance) ETL_NOEXCEPT
|
||||
{
|
||||
assign((void*)(&instance), method_stub<T, Method>);
|
||||
assign(object_ptr(&instance), method_stub<T, Method>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -358,7 +353,7 @@ namespace etl
|
||||
template <typename T, TReturn(T::* Method)(TArgs...) const>
|
||||
ETL_CONSTEXPR14 void set(T& instance) ETL_NOEXCEPT
|
||||
{
|
||||
assign((void*)(&instance), const_method_stub<T, Method>);
|
||||
assign(object_ptr(&instance), const_method_stub<T, Method>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -367,7 +362,7 @@ namespace etl
|
||||
template <typename T, T& Instance, TReturn(T::* Method)(TArgs...)>
|
||||
ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
|
||||
{
|
||||
assign(ETL_NULLPTR, method_instance_stub<T, Method, Instance>);
|
||||
assign(method_instance_stub<T, Method, Instance>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -377,7 +372,7 @@ namespace etl
|
||||
template <typename T, TReturn(T::* Method)(TArgs...), T& Instance>
|
||||
ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
|
||||
{
|
||||
assign(ETL_NULLPTR, method_instance_stub<T, Method, Instance>);
|
||||
assign(method_instance_stub<T, Method, Instance>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -386,7 +381,7 @@ namespace etl
|
||||
template <typename T, T const& Instance, TReturn(T::* Method)(TArgs...) const>
|
||||
ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
|
||||
{
|
||||
assign(ETL_NULLPTR, const_method_instance_stub<T, Method, Instance>);
|
||||
assign(const_method_instance_stub<T, Method, Instance>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -396,7 +391,7 @@ namespace etl
|
||||
template <typename T, TReturn(T::* Method)(TArgs...) const, T const& Instance>
|
||||
ETL_CONSTEXPR14 void set() ETL_NOEXCEPT
|
||||
{
|
||||
assign(ETL_NULLPTR, const_method_instance_stub<T, Method, Instance>);
|
||||
assign(const_method_instance_stub<T, Method, Instance>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -419,7 +414,7 @@ namespace etl
|
||||
|
||||
ETL_ASSERT(is_valid(), ETL_ERROR(delegate_uninitialised));
|
||||
|
||||
return (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
|
||||
return (*invocation.stub)(invocation, etl::forward<TCallArgs>(args)...);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -436,7 +431,7 @@ namespace etl
|
||||
|
||||
if (is_valid())
|
||||
{
|
||||
(*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
|
||||
(*invocation.stub)(invocation, etl::forward<TCallArgs>(args)...);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -461,7 +456,7 @@ namespace etl
|
||||
|
||||
if (is_valid())
|
||||
{
|
||||
result = (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
|
||||
result = (*invocation.stub)(invocation, etl::forward<TCallArgs>(args)...);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -479,7 +474,7 @@ namespace etl
|
||||
|
||||
if (is_valid())
|
||||
{
|
||||
return (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
|
||||
return (*invocation.stub)(invocation, etl::forward<TCallArgs>(args)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -499,7 +494,7 @@ namespace etl
|
||||
|
||||
if (is_valid())
|
||||
{
|
||||
return (*invocation.stub)(invocation.object, etl::forward<TCallArgs>(args)...);
|
||||
return (*invocation.stub)(invocation, etl::forward<TCallArgs>(args)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -518,7 +513,7 @@ namespace etl
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate& operator =(TLambda& instance) ETL_NOEXCEPT
|
||||
{
|
||||
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||
assign(object_ptr(&instance), lambda_stub<TLambda>);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -528,20 +523,16 @@ namespace etl
|
||||
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) ETL_NOEXCEPT
|
||||
{
|
||||
assign((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
assign(object_ptr(&instance), const_lambda_stub<TLambda>);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Create from non-capturing rvalue lambda convertible to function pointer.
|
||||
// Converts to a function pointer to avoid storing a dangling pointer
|
||||
// to a destroyed temporary.
|
||||
// Create from a function pointer.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_reference<TLambda>::value && etl::is_convertible<TLambda, TReturn(*)(TArgs...)>::value, int> = 0>
|
||||
delegate& operator =(TLambda&& instance) ETL_NOEXCEPT
|
||||
delegate& operator =(function_ptr fp) ETL_NOEXCEPT
|
||||
{
|
||||
TReturn(*fp)(TArgs...) = static_cast<TReturn(*)(TArgs...)>(instance);
|
||||
assign(reinterpret_cast<void*>(fp), function_ptr_stub);
|
||||
assign(fp, function_ptr_stub);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -582,13 +573,11 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
using stub_type = TReturn(*)(void* object, TArgs...);
|
||||
|
||||
//*************************************************************************
|
||||
// Callable compatibility: detects if C (or const C) is invocable with (TArgs...) and returns a type
|
||||
// convertible to TReturn. Works with generic lambdas and functors.
|
||||
template <typename TCallableType, typename = void>
|
||||
struct is_invocable_with
|
||||
struct is_invocable_with
|
||||
: etl::false_type {};
|
||||
|
||||
template <typename TCallableType>
|
||||
@ -614,11 +603,32 @@ namespace etl
|
||||
//*************************************************************************
|
||||
struct invocation_element
|
||||
{
|
||||
invocation_element() = default;
|
||||
using stub_type = TReturn(*)(const invocation_element&, TArgs...);
|
||||
|
||||
//***********************************************************************
|
||||
ETL_CONSTEXPR14 invocation_element(void* object_, stub_type stub_) ETL_NOEXCEPT
|
||||
: object(object_)
|
||||
ETL_CONSTEXPR14 invocation_element() ETL_NOEXCEPT
|
||||
: ptr(object_ptr(ETL_NULLPTR))
|
||||
, stub(ETL_NULLPTR)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
ETL_CONSTEXPR14 invocation_element(stub_type stub_) ETL_NOEXCEPT
|
||||
: ptr()
|
||||
, stub(stub_)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
ETL_CONSTEXPR14 invocation_element(object_ptr object_, stub_type stub_) ETL_NOEXCEPT
|
||||
: ptr(object_)
|
||||
, stub(stub_)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
ETL_CONSTEXPR14 invocation_element(function_ptr fp_, stub_type stub_) ETL_NOEXCEPT
|
||||
: ptr(fp_)
|
||||
, stub(stub_)
|
||||
{
|
||||
}
|
||||
@ -626,59 +636,109 @@ namespace etl
|
||||
//***********************************************************************
|
||||
ETL_CONSTEXPR14 bool operator ==(const invocation_element& rhs) const ETL_NOEXCEPT
|
||||
{
|
||||
return (rhs.stub == stub) && (rhs.object == object);
|
||||
return (rhs.stub == stub) &&
|
||||
((stub == function_ptr_stub) ? (rhs.ptr.fp == ptr.fp)
|
||||
: (rhs.ptr.object == ptr.object));
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
ETL_CONSTEXPR14 bool operator !=(const invocation_element& rhs) const ETL_NOEXCEPT
|
||||
{
|
||||
return (rhs.stub != stub) || (rhs.object != object);
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
ETL_CONSTEXPR14 void clear() ETL_NOEXCEPT
|
||||
{
|
||||
object = ETL_NULLPTR;
|
||||
stub = ETL_NULLPTR;
|
||||
stub = ETL_NULLPTR;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
void* object = ETL_NULLPTR;
|
||||
stub_type stub = ETL_NULLPTR;
|
||||
union ptr_type
|
||||
{
|
||||
ETL_CONSTEXPR14 ptr_type() ETL_NOEXCEPT
|
||||
: object(ETL_NULLPTR)
|
||||
{
|
||||
}
|
||||
|
||||
ETL_CONSTEXPR14 ptr_type(object_ptr object_) ETL_NOEXCEPT
|
||||
: object(object_)
|
||||
{
|
||||
}
|
||||
|
||||
ETL_CONSTEXPR14 ptr_type(function_ptr fp_) ETL_NOEXCEPT
|
||||
: fp(fp_)
|
||||
{
|
||||
}
|
||||
|
||||
object_ptr object;
|
||||
function_ptr fp;
|
||||
};
|
||||
|
||||
ptr_type ptr;
|
||||
stub_type stub;
|
||||
};
|
||||
|
||||
using stub_type = typename invocation_element::stub_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructs a delegate from an object and stub.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 delegate(void* object, stub_type stub) ETL_NOEXCEPT
|
||||
ETL_CONSTEXPR14 delegate(object_ptr object, stub_type stub) ETL_NOEXCEPT
|
||||
: invocation(object, stub)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructs a delegate from an function and stub.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 delegate(function_ptr fp, stub_type stub) ETL_NOEXCEPT
|
||||
: invocation(fp, stub)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructs a delegate from a stub.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 delegate(stub_type stub) ETL_NOEXCEPT
|
||||
: invocation(ETL_NULLPTR, stub)
|
||||
: invocation(stub)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assign from an object and stub.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void assign(void* object, stub_type stub) ETL_NOEXCEPT
|
||||
ETL_CONSTEXPR14 void assign(object_ptr object, stub_type stub) ETL_NOEXCEPT
|
||||
{
|
||||
invocation.object = object;
|
||||
invocation.ptr.object = object;
|
||||
invocation.stub = stub;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assign from a function and stub.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void assign(function_ptr fp, stub_type stub) ETL_NOEXCEPT
|
||||
{
|
||||
invocation.ptr.fp = fp;
|
||||
invocation.stub = stub;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assign from a stub.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 void assign(stub_type stub) ETL_NOEXCEPT
|
||||
{
|
||||
invocation.ptr.object = ETL_NULLPTR;
|
||||
invocation.stub = stub;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Stub call for a member function. Run time instance.
|
||||
//*************************************************************************
|
||||
template <typename T, TReturn(T::*Method)(TArgs...)>
|
||||
static ETL_CONSTEXPR14 TReturn method_stub(void* object, TArgs... args)
|
||||
static ETL_CONSTEXPR14 TReturn method_stub(const invocation_element& invocation, TArgs... args)
|
||||
{
|
||||
T* p = static_cast<T*>(object);
|
||||
T* p = static_cast<T*>(invocation.ptr.object);
|
||||
return (p->*Method)(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
|
||||
@ -686,9 +746,9 @@ namespace etl
|
||||
/// Stub call for a const member function. Run time instance.
|
||||
//*************************************************************************
|
||||
template <typename T, TReturn(T::*Method)(TArgs...) const>
|
||||
static ETL_CONSTEXPR14 TReturn const_method_stub(void* object, TArgs... args)
|
||||
static ETL_CONSTEXPR14 TReturn const_method_stub(const invocation_element& invocation, TArgs... args)
|
||||
{
|
||||
T* const p = static_cast<T*>(object);
|
||||
T* const p = static_cast<T*>(invocation.ptr.object);
|
||||
return (p->*Method)(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
|
||||
@ -696,7 +756,7 @@ namespace etl
|
||||
/// Stub call for a member function. Compile time instance.
|
||||
//*************************************************************************
|
||||
template <typename T, TReturn(T::*Method)(TArgs...), T& Instance>
|
||||
static ETL_CONSTEXPR14 TReturn method_instance_stub(void*, TArgs... args)
|
||||
static ETL_CONSTEXPR14 TReturn method_instance_stub(const invocation_element&, TArgs... args)
|
||||
{
|
||||
return (Instance.*Method)(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
@ -705,7 +765,7 @@ namespace etl
|
||||
/// Stub call for a const member function. Compile time instance.
|
||||
//*************************************************************************
|
||||
template <typename T, TReturn(T::*Method)(TArgs...) const, const T& Instance>
|
||||
static ETL_CONSTEXPR14 TReturn const_method_instance_stub(void*, TArgs... args)
|
||||
static ETL_CONSTEXPR14 TReturn const_method_instance_stub(const invocation_element&, TArgs... args)
|
||||
{
|
||||
return (Instance.*Method)(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
@ -715,7 +775,7 @@ namespace etl
|
||||
/// Stub call for a function operator. Compile time instance.
|
||||
//*************************************************************************
|
||||
template <typename T, T& Instance>
|
||||
static ETL_CONSTEXPR14 TReturn operator_instance_stub(void*, TArgs... args)
|
||||
static ETL_CONSTEXPR14 TReturn operator_instance_stub(const invocation_element&, TArgs... args)
|
||||
{
|
||||
return Instance.operator()(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
@ -725,30 +785,28 @@ namespace etl
|
||||
/// Stub call for a free function.
|
||||
//*************************************************************************
|
||||
template <TReturn(*Method)(TArgs...)>
|
||||
static ETL_CONSTEXPR14 TReturn function_stub(void*, TArgs... args)
|
||||
static ETL_CONSTEXPR14 TReturn function_stub(const invocation_element&, TArgs... args)
|
||||
{
|
||||
return (Method)(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Stub call for a runtime function pointer stored in the object field.
|
||||
/// Stub call for a runtime function pointer stored in the invocation_element.
|
||||
//*************************************************************************
|
||||
static TReturn function_ptr_stub(void* object, TArgs... args)
|
||||
static TReturn function_ptr_stub(const invocation_element& invocation, TArgs... args)
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof(void*) >= sizeof(TReturn(*)(TArgs...)), "etl::delegate: function pointer too large to store in object field");
|
||||
TReturn(*fp)(TArgs...) = reinterpret_cast<TReturn(*)(TArgs...)>(object);
|
||||
return fp(etl::forward<TArgs>(args)...);
|
||||
return invocation.ptr.fp(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Stub call for a lambda or functor function.
|
||||
//*************************************************************************
|
||||
template <typename TLambda>
|
||||
static ETL_CONSTEXPR14 TReturn lambda_stub(void* object, TArgs... arg)
|
||||
static ETL_CONSTEXPR14 TReturn lambda_stub(const invocation_element& invocation, TArgs... arg)
|
||||
{
|
||||
ETL_STATIC_ASSERT(is_compatible_callable<TLambda>::value, "etl::delegate: bound lambda/functor is not compatible with the delegate signature");
|
||||
|
||||
TLambda* p = static_cast<TLambda*>(object);
|
||||
|
||||
TLambda* p = static_cast<TLambda*>(invocation.ptr.object);
|
||||
return (p->operator())(etl::forward<TArgs>(arg)...);
|
||||
}
|
||||
|
||||
@ -756,11 +814,11 @@ namespace etl
|
||||
/// Stub call for a const lambda or functor function.
|
||||
//*************************************************************************
|
||||
template <typename TLambda>
|
||||
static ETL_CONSTEXPR14 TReturn const_lambda_stub(void* object, TArgs... arg)
|
||||
static ETL_CONSTEXPR14 TReturn const_lambda_stub(const invocation_element& invocation, TArgs... arg)
|
||||
{
|
||||
ETL_STATIC_ASSERT(is_compatible_callable<TLambda>::value, "etl::delegate: bound lambda/functor is not compatible with the delegate signature");
|
||||
|
||||
const TLambda* p = static_cast<const TLambda*>(object);
|
||||
|
||||
const TLambda* p = static_cast<const TLambda*>(invocation.ptr.object);
|
||||
return (p->operator())(etl::forward<TArgs>(arg)...);
|
||||
}
|
||||
|
||||
|
||||
@ -274,7 +274,7 @@ namespace
|
||||
};
|
||||
|
||||
//*******************************************
|
||||
int times_2(int a)
|
||||
int times_2(int a)
|
||||
{
|
||||
return a * 2;
|
||||
}
|
||||
@ -315,7 +315,7 @@ namespace
|
||||
|
||||
// Check the return type.
|
||||
CHECK_TRUE((std::is_same<Delegate::return_type, int>::value));
|
||||
|
||||
|
||||
// Check the argument types.
|
||||
CHECK_TRUE((std::is_same<Delegate::argument_types, etl::type_list<float, long>>::value));
|
||||
}
|
||||
@ -636,7 +636,7 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_construct_from_rvalue_non_capturing_lambda)
|
||||
{
|
||||
etl::delegate<int(int, int)> d([](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j; });
|
||||
etl::delegate<int(int, int)> d(+[](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j; });
|
||||
|
||||
int result = d(VALUE1, VALUE2);
|
||||
|
||||
@ -650,7 +650,7 @@ namespace
|
||||
{
|
||||
etl::delegate<int(int, int)> d;
|
||||
|
||||
d = [](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j + 2; };
|
||||
d = +[](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j + 2; };
|
||||
|
||||
int result = d(VALUE1, VALUE2);
|
||||
|
||||
@ -662,7 +662,7 @@ namespace
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_create_from_rvalue_non_capturing_lambda)
|
||||
{
|
||||
auto d = etl::delegate<int(int, int)>::create([](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j + 5; });
|
||||
auto d = etl::delegate<int(int, int)>::create(+[](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j + 5; });
|
||||
|
||||
int result = d(VALUE1, VALUE2);
|
||||
|
||||
@ -1221,20 +1221,20 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
//#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_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
|
||||
@ -1253,20 +1253,20 @@ 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 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))
|
||||
//*************************************************************************
|
||||
@ -1677,7 +1677,7 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_set_free_int)
|
||||
{
|
||||
etl::delegate<void(int, int)> d;
|
||||
|
||||
|
||||
d.set<free_int>();
|
||||
|
||||
d(VALUE1, VALUE2);
|
||||
@ -1690,7 +1690,7 @@ namespace
|
||||
TEST_FIXTURE(SetupFixture, test_set_lambda_int)
|
||||
{
|
||||
etl::delegate<void(int, int)> d;
|
||||
|
||||
|
||||
d.set([](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); });
|
||||
|
||||
d(VALUE1, VALUE2);
|
||||
@ -1704,7 +1704,7 @@ namespace
|
||||
{
|
||||
Object object;
|
||||
etl::delegate<void(const Data&, int)> d;
|
||||
|
||||
|
||||
d.set<Object, &Object::member_reference>(object);
|
||||
|
||||
Data data;
|
||||
@ -1851,8 +1851,11 @@ namespace
|
||||
|
||||
auto d1 = etl::delegate<void(int, int)>::create<Object, &Object::member_int>(object);
|
||||
auto d2 = d1;
|
||||
auto d3 = etl::delegate<void(int, int)>::create([](int, int) { });
|
||||
auto d4 = d3;
|
||||
|
||||
CHECK(d1 == d2);
|
||||
CHECK(d3 == d4);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -1862,8 +1865,10 @@ namespace
|
||||
|
||||
auto d1 = etl::delegate<void(int, int)>::create<Object, &Object::member_int>(object);
|
||||
auto d2 = etl::delegate<void(int, int)>::create<Object, &Object::member_int_const>(object);
|
||||
auto d3 = etl::delegate<void(int, int)>::create([](int, int) { });
|
||||
|
||||
CHECK(d1 != d2);
|
||||
CHECK(d1 != d3);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user