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>
73 template<
typename Callable,
74 typename = std::enable_if_t<!std::is_same<std::decay_t<Callable>,
Function>::value>
77 _invoke{Invoke<std::decay_t<Callable>>{std::forward<Callable>(callable)}}
85 return _invoke.
empty();
96 template<
typename Callable,
typename... Args>
99 return Function<Storage>{meta::identity<Callable>(), std::forward<Args>(args)...};
112 template<
typename... Args>
117 AnyArg argsArray[] = {std::forward<Args>(args)...,
AnyArg(
nullptr)};
118 return _invoke.template get<InvokeInterface>().
invoke(std::begin(argsArray));
131 template<
typename... Args>
136 AnyArg argsArray[] = {std::forward<Args>(args)...,
AnyArg(
nullptr)};
137 return _invoke.template get<InvokeInterface>().
invoke(std::begin(argsArray));
148 template<
typename ArgsVector>
153 return _invoke.template get<InvokeInterface>().
invoke(std::forward<ArgsVector>(args));
164 template<
typename ArgsVector>
169 return _invoke.template get<InvokeInterface>().
invoke(std::forward<ArgsVector>(args));
184 return _invoke.template get<InvokeInterface>().
invoke(args);
199 return _invoke.template get<InvokeInterface>().
invoke(args);
205 template<
typename Callable>
208 _invoke = Invoke<std::decay_t<Callable>>{std::forward<Callable>(callable)};
218 return _invoke.template get<InvokeInterface>().
kind();
231 return _invoke.template get<InvokeInterface>().
template get<T>();
244 return _invoke.template get<InvokeInterface>().
template get<T>();
248 template<
typename Callable,
typename... Args>
249 Function(meta::identity<Callable>, Args&&... args) :
250 _invoke{Invoke<Callable>{std::forward<Args>(args)...}}
253 class InvokeInterface
256 virtual ~InvokeInterface() =
default;
270 virtual void* getObject() = 0;
271 virtual const void* getObject()
const = 0;
272 virtual cpp::FunctionKind
kind()
const = 0;
279 "Callable is of type {}, not {}",
280 typeInfo().typeName(),
281 ctti::type_id<std::decay_t<T>>().name()
284 return *
reinterpret_cast<const T*
>(getObject());
291 "Callable is of type {}, not {}",
292 typeInfo().typeName(),
293 ctti::type_id<std::decay_t<T>>().name()
296 return *
reinterpret_cast<T*
>(getObject());
300 template<
typename Callable>
301 class Invoke :
public InvokeInterface
304 template<
typename... Args>
305 Invoke(Args&&... args) :
306 _callable{std::forward<Args>(args)...}
311 return doInvoke(std::move(args));
316 return doInvoke(std::move(args));
321 return doInvoke(args);
326 return doInvoke(args);
331 return doInvoke(args);
336 return doInvoke(args);
341 return doInvoke(std::move(args));
346 return doInvoke(std::move(args));
351 return doInvoke(args);
356 return doInvoke(args);
361 return doInvoke(args);
366 return doInvoke(args);
369 template<
typename Args>
372 return doInvoke(_callable, std::forward<Args>(args));
375 template<
typename Args>
378 return doInvoke(_callable, std::forward<Args>(args));
381 #define SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION cpp::typeerasure::invoke(identity(std::forward<Callable_>(callable)), identity(std::forward<Args>(args))) 383 template<
typename Callable_,
typename Args>
386 return cpp::staticIf<!(cpp::function_kind<Callable>() == cpp::FunctionKind::MEMBER_FUNCTION && std::is_const<std::remove_reference_t<Args>>::value)>([&](
auto identity) ->
SimpleAny<ReturnStorage> 388 return cpp::staticIf<std::is_void<decltype(SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION)>::value>([&](
auto identity) ->
SimpleAny<ReturnStorage> 390 SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION;
394 return SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION;
399 throw cpp::exception<std::runtime_error>(
400 "Cannot invoke a non-const member function with a const vector of arguments" 406 #undef SIPLASPLAS_FUNCTION_INVOKE_EXPRESSION 408 void* getObject()
override 413 const void* getObject()
const override 418 cpp::FunctionKind
kind()
const override 420 return cpp::function_kind<Callable>();
425 return cpp::typeerasure::TypeInfo::get<Callable>();
463 #endif // SIPLASPLAS_TYPEERASURE_FUNCTION_HPP SimpleAny< ReturnStorage > operator()(Args &&...args)
Invokes the callable with the given arguments.
Definition: function.hpp:113
bool empty() const
Checks if the object is empty (No callable assigned)
Definition: function.hpp:83
Definition: canary_allocator.hpp:7
#define SIPLASPLAS_ASSERT_FALSE(...)
Defines a false assertion.
Definition: assert.hpp:415
static constexpr TypeInfo get()
Returns the type information of type T.
Definition: typeinfo.hpp:224
static Function< Storage > create(Args &&...args)
Creates a Function by instancing in-place the given callable.
Definition: function.hpp:97
Function & operator=(Callable &&callable)
Assigns a new callable to the function.
Definition: function.hpp:206
bool empty() const
Checks whether the any has an object hosted in or if is empty.
Definition: simpleany.hpp:388
Function(Callable &&callable)
Constructs a Function from a Callable object.
Definition: function.hpp:76
SimpleAny< ReturnStorage > invoke(AnyArg *args)
Invokes the callable with the given arguments The arguments are passed as a vector of SimpleAny...
Definition: function.hpp:180
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:165
SimpleAny< ReturnStorage > operator()(Args &&...args) const
Invokes the callable with the given arguments.
Definition: function.hpp:132
Implements a type-erased value container with minimal value semantics requirements.
Definition: simpleany.hpp:15
SimpleAny< ReturnStorage > invoke(ArgsVector &&args)
Invokes the callable with the given arguments The arguments are passed as a vector of SimpleAny...
Definition: function.hpp:149
cpp::FunctionKind kind() const
Returns the function kind (free function, pointer to member function, functor, etc) of the callable...
Definition: function.hpp:216
Contains minimal information to execute the value semantics operations of a type. ...
Definition: typeinfo.hpp:108
Stores a type-erased callable of any signature and kind.
Definition: function.hpp:58
Represents a type erased function call argument.
Definition: anyarg.hpp:31
#define SIPLASPLAS_ASSERT(...)
Defines an assertion expression.
Definition: assert.hpp:212
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:195