Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

85 rader
2.2 KiB

  1. #pragma once
  2. #include "./arraylist.hpp"
  3. // For std::decay
  4. #include <type_traits>
  5. template<typename>
  6. struct Lambda; // intentionally not defined
  7. template<typename R, typename ...Args>
  8. struct Lambda<R(Args...)>
  9. {
  10. using Dispatcher = R(*)(void*, Args...);
  11. Dispatcher m_Dispatcher; // A pointer to the static function that will call the
  12. // wrapped invokable object
  13. void* m_Target; // A pointer to the invokable object
  14. // Dispatch() is instantiated by the Lambda constructor,
  15. // which will store a pointer to the function in m_Dispatcher.
  16. template<typename S>
  17. static R Dispatch(void* target, Args... args)
  18. {
  19. return (*(S*)target)(args...);
  20. }
  21. template<typename T>
  22. Lambda(T&& target)
  23. : m_Dispatcher(&Dispatch<typename std::decay<T>::type>)
  24. , m_Target(&target)
  25. {
  26. }
  27. // Specialize for reference-to-function, to ensure that a valid pointer is
  28. // stored.
  29. using TargetFunctionRef = R(Args...);
  30. Lambda(TargetFunctionRef target)
  31. : m_Dispatcher(Dispatch<TargetFunctionRef>)
  32. {
  33. static_assert(sizeof(void*) == sizeof target,
  34. "It will not be possible to pass functions by reference on this platform. "
  35. "Please use explicit function pointers i.e. foo(target) -> foo(&target)");
  36. m_Target = (void*)target;
  37. }
  38. R operator()(Args... args) const
  39. {
  40. return m_Dispatcher(m_Target, args...);
  41. }
  42. };
  43. struct Hook : Array_List<Lambda<void()>> {
  44. Hook() {
  45. alloc();
  46. }
  47. ~Hook () {
  48. dealloc();
  49. }
  50. void operator<<(Lambda<void()> f) {
  51. // FIXME(Felix): Why can I not call Array_List::append here??? Hallo?
  52. if (count == length) {
  53. length *= 2;
  54. data = (Lambda<void()>*)realloc(data, length * sizeof(Lambda<void()>));
  55. }
  56. data[count] = f;
  57. count++;
  58. }
  59. void operator()() {
  60. while(count --> 0) {
  61. fflush(stdout);
  62. data[count]();
  63. }
  64. count = 0;
  65. }
  66. };
  67. struct __System_Shutdown_Hook : Hook {
  68. void operator()() = delete;
  69. ~__System_Shutdown_Hook() {
  70. Hook::operator()();
  71. dealloc();
  72. }
  73. } system_shutdown_hook;