1 #ifndef SIPLASPLAS_TYPEERASURE_FUNCTION_HPP 2 #define SIPLASPLAS_TYPEERASURE_FUNCTION_HPP 4 #include "simpleany.hpp" 7 #include "anystorage/deadpool.hpp" 8 #include "anystorage/fixedsize.hpp" 9 #include <siplasplas/utility/function_traits.hpp> 10 #include <siplasplas/utility/staticif.hpp> 11 #include <siplasplas/utility/compiles.hpp> 12 #include <siplasplas/utility/exception.hpp> 57 template<
typename Storage,
typename ArgsStorage = Storage,
typename ReturnStorage = Storage>
74 template<
typename Callable,
typename = std::enable_if_t<
75 !std::is_same<std::decay_t<Callable>,
Function>::value
78 _invoke{Invoke<std::decay_t<Callable>>{std::forward<Callable>(callable)}}
86 return _invoke.
empty();
97 template<
typename Callable,
typename... Args>
113 template<
typename... Args>
118 AnyArg argsArray[] = {std::forward<Args>(args)...,
AnyArg(
nullptr)};
119 return _invoke.template get<InvokeInterface>().
invoke(
std::begin(argsArray));
132 template<
typename... Args>
137 AnyArg argsArray[] = {std::forward<Args>(args)...,
AnyArg(
nullptr)};
138 return _invoke.template get<InvokeInterface>().
invoke(
std::begin(argsArray));
149 template<
typename ArgsVector>
154 return _invoke.template get<InvokeInterface>().
invoke(std::forward<ArgsVector>(args));
165 template<
typename ArgsVector>
170 return _invoke.template get<InvokeInterface>().
invoke(std::forward<ArgsVector>(args));
185 return _invoke.template get<InvokeInterface>().
invoke(args);
200 return _invoke.template get<InvokeInterface>().
invoke(args);
209 template<
typename Callable,
typename = std::enable_if_t<
210 !std::is_same<std::decay_t<Callable>,
Function>::value
214 _invoke = Invoke<std::decay_t<Callable>>{std::forward<Callable>(callable)};
224 return _invoke.template get<InvokeInterface>().
kind();
237 return _invoke.template get<InvokeInterface>().
template get<T>();
250 return _invoke.template get<InvokeInterface>().
template get<T>();
254 template<
typename Callable,
typename... Args>
256 _invoke{Invoke<Callable>{std::forward<Args>(args)...}}
259 class InvokeInterface
262 virtual ~InvokeInterface() =
default;
276 virtual void* getObject() = 0;
277 virtual const void* getObject()
const = 0;
278 virtual cpp::FunctionKind
kind()
const = 0;
285 "Callable is of type {}, not {}",
286 typeInfo().typeName(),
287 ctti::type_id<std::decay_t<T>>().name()
290 return *
reinterpret_cast<const T*
>(getObject());
297 "Callable is of type {}, not {}",
298 typeInfo().typeName(),
299 ctti::type_id<std::decay_t<T>>().name()
302 return *
reinterpret_cast<T*
>(getObject());
306 template<
typename Callable>
307 class Invoke :
public InvokeInterface
316 template<
typename... Args>
317 Invoke(Args&&... args) :
318 _callable{std::forward<Args>(args)...}
323 return doInvoke(std::move(args));
328 return doInvoke(std::move(args));
333 return doInvoke(args);
338 return doInvoke(args);
343 return doInvoke(args);
348 return doInvoke(args);
353 return doInvoke(std::move(args));
358 return doInvoke(std::move(args));
363 return doInvoke(args);
368 return doInvoke(args);
373 return doInvoke(args);
378 return doInvoke(args);
381 template<
typename Args>
384 return doInvoke(_callable, std::forward<Args>(args));
387 template<
typename Args>
390 return doInvoke(_callable, std::forward<Args>(args));
393 #define SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION cpp::typeerasure::invoke(identity(std::forward<Callable_>(callable)), identity(std::forward<Args>(args))) 395 template<
typename Callable_,
typename Args>
398 return cpp::staticIf<!(cpp::function_kind<Callable>() == cpp::FunctionKind::MEMBER_FUNCTION && std::is_const<std::remove_reference_t<Args>>::value)>([&](
auto identity) ->
SimpleAny<ReturnStorage> 400 return cpp::staticIf<std::is_void<decltype(SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION)>::value>([&](
auto identity) ->
SimpleAny<ReturnStorage> 402 SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION;
406 return SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION;
411 throw cpp::exception<std::runtime_error>(
412 "Cannot invoke a non-const member function with a const vector of arguments" 418 #undef SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION 420 void* getObject()
override 425 const void* getObject()
const override 430 cpp::FunctionKind
kind()
const override 432 return cpp::function_kind<Callable>();
437 return cpp::typeerasure::TypeInfo::get<Callable>();
475 #endif // SIPLASPLAS_TYPEERASURE_FUNCTION_HPP Function(Callable &&callable)
Constructs a Function from a Callable object.
Definition: function.hpp:77
Definition: messaging.hpp:8
#define SIPLASPLAS_ASSERT_FALSE(...)
Defines a false assertion.
Definition: assert.hpp:432
Represents a type erased function call argument.
Definition: anyarg.hpp:31
bool empty() const
Checks if the object is empty (No callable assigned)
Definition: function.hpp:84
constexpr auto begin(const Sequence &sequence)
Returns an iterator pointing to the beginning of a sequence.
Definition: algorithm.hpp:62
SimpleAny< ReturnStorage > invoke(ArgsVector &&args)
Invokes the callable with the given arguments The arguments are passed as a vector of SimpleAny...
Definition: function.hpp:150
Implements a type-erased value container with minimal value semantics requirements.
Definition: simpleany.hpp:15
Contains minimal information to execute the value semantics operations of a type. ...
Definition: typeinfo.hpp:115
bool empty() const
Checks whether the any has an object hosted in or if is empty.
Definition: simpleany.hpp:401
SimpleAny< ReturnStorage > invoke(AnyArg *args) const
Invokes the callable with the given arguments The arguments are passed as a vector of SimpleAny...
Definition: function.hpp:196
SimpleAny< ReturnStorage > operator()(Args &&... args) const
Invokes the callable with the given arguments.
Definition: function.hpp:133
Function & operator=(Callable &&callable)
Assigns a new callable to the function.
Definition: function.hpp:212
static Function< Storage > create(Args &&... args)
Creates a Function by instancing in-place the given callable.
Definition: function.hpp:98
SimpleAny< ReturnStorage > invoke(ArgsVector &&args) const
Invokes the callable with the given arguments The arguments are passed as a vector of SimpleAny...
Definition: function.hpp:166
static constexpr TypeInfo get()
Returns the type information of type T.
Definition: typeinfo.hpp:232
#define SIPLASPLAS_ASSERT(...)
Defines an assertion expression.
Definition: assert.hpp:229
SimpleAny< ReturnStorage > invoke(AnyArg *args)
Invokes the callable with the given arguments The arguments are passed as a vector of SimpleAny...
Definition: function.hpp:181
cpp::FunctionKind kind() const
Returns the function kind (free function, pointer to member function, functor, etc) of the callable...
Definition: function.hpp:222
Stores a type-erased callable of any signature and kind.
Definition: function.hpp:58
SimpleAny< ReturnStorage > operator()(Args &&... args)
Invokes the callable with the given arguments.
Definition: function.hpp:114