|
- #pragma once
- #include "./arraylist.hpp"
-
- // For std::decay
- #include <type_traits>
-
- template<typename>
- struct TransientFunction; // intentionally not defined
-
- template<typename R, typename ...Args>
- struct TransientFunction<R(Args...)>
- {
- using Dispatcher = R(*)(void*, Args...);
-
- Dispatcher m_Dispatcher; // A pointer to the static function that will call the
- // wrapped invokable object
- void* m_Target; // A pointer to the invokable object
-
- // Dispatch() is instantiated by the TransientFunction constructor,
- // which will store a pointer to the function in m_Dispatcher.
- template<typename S>
- static R Dispatch(void* target, Args... args)
- {
- return (*(S*)target)(args...);
- }
-
- template<typename T>
- TransientFunction(T&& target)
- : m_Dispatcher(&Dispatch<typename std::decay<T>::type>)
- , m_Target(&target)
- {
- }
-
- // Specialize for reference-to-function, to ensure that a valid pointer is
- // stored.
- using TargetFunctionRef = R(Args...);
- TransientFunction(TargetFunctionRef target)
- : m_Dispatcher(Dispatch<TargetFunctionRef>)
- {
- static_assert(sizeof(void*) == sizeof target,
- "It will not be possible to pass functions by reference on this platform. "
- "Please use explicit function pointers i.e. foo(target) -> foo(&target)");
- m_Target = (void*)target;
- }
-
- R operator()(Args... args) const
- {
- return m_Dispatcher(m_Target, args...);
- }
- };
-
-
- struct Hook : Array_List<TransientFunction<void()>> {
- Hook() {
- alloc();
- }
- ~Hook () {
- dealloc();
- }
- void operator<<(TransientFunction<void()> f) {
- // FIXME(Felix): Why can I not call Array_List::append here??? Hallo?
- if (next_index == length) {
- length *= 2;
- data = (TransientFunction<void()>*)realloc(data, length * sizeof(TransientFunction<void()>));
- }
- data[next_index] = f;
- next_index++;
- }
- void operator()() {
- while(next_index --> 0) {
- fflush(stdout);
- data[next_index]();
- }
- next_index = 0;
- }
- };
-
- struct __System_Shutdown_Hook : Hook {
- void operator()() = delete;
- ~__System_Shutdown_Hook() {
- Hook::operator()();
- dealloc();
- }
- } system_shutdown_hook;
|