Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 

120 rindas
3.2 KiB

  1. #pragma once
  2. // #include <functional>
  3. #define proc auto
  4. #ifdef _DEBUG
  5. # define if_debug if constexpr (true)
  6. #else
  7. # define if_debug if constexpr (false)
  8. #endif
  9. #ifdef _MSC_VER
  10. # define debug_break() if_debug __debugbreak()
  11. # define if_windows if constexpr (true)
  12. # define if_linux if constexpr (false)
  13. #else
  14. # define debug_break() if_debug raise(SIGTRAP)
  15. # define if_windows if constexpr (false)
  16. # define if_linux if constexpr (true)
  17. #endif
  18. #define TOKENPASTE(x, y) x ## y
  19. #define TOKENPASTE2(x, y) TOKENPASTE(x, y)
  20. /**
  21. * Defer *
  22. */
  23. template<typename F>
  24. class defer_finalizer {
  25. F f;
  26. bool moved;
  27. public:
  28. template<typename T>
  29. defer_finalizer(T && f_) : f(std::forward<T>(f_)), moved(false) { }
  30. defer_finalizer(const defer_finalizer &) = delete;
  31. defer_finalizer(defer_finalizer && other) : f(std::move(other.f)), moved(other.moved) {
  32. other.moved = true;
  33. }
  34. ~defer_finalizer() {
  35. if (!moved) f();
  36. }
  37. };
  38. static struct {
  39. template<typename F>
  40. defer_finalizer<F> operator<<(F && f) {
  41. return defer_finalizer<F>(std::forward<F>(f));
  42. }
  43. } deferrer;
  44. #define defer auto TOKENPASTE2(__deferred_lambda_call, __COUNTER__) = deferrer << [&]
  45. #define defer_free(var) defer { free(var); }
  46. /*
  47. defer {
  48. call();
  49. };
  50. expands to:
  51. auto __deferred_lambda_call0 = deferrer << [&] {
  52. call();
  53. };
  54. */
  55. /*****************
  56. * fluid-let *
  57. *****************/
  58. #define fluid_let(var, val) \
  59. if (0) \
  60. TOKENPASTE2(finished,__LINE__): ; \
  61. else \
  62. for (auto TOKENPASTE2(fluid_let_, __LINE__) = var;;) \
  63. for (defer{var = TOKENPASTE2(fluid_let_, __LINE__);};;) \
  64. for(var = val;;) \
  65. if (1) { \
  66. goto TOKENPASTE2(body,__LINE__); \
  67. } \
  68. else \
  69. while (1) \
  70. if (1) { \
  71. goto TOKENPASTE2(finished, __LINE__); \
  72. } \
  73. else TOKENPASTE2(body,__LINE__):
  74. /**
  75. fluid_let(var, val) {
  76. call1(var);
  77. call2(var);
  78. }
  79. expands to
  80. if (0)
  81. finished98:;
  82. else
  83. for (auto fluid_let_98 = var;;)
  84. for (auto __deferred_lambda_call0 = deferrer << [&] { var = fluid_let_98; };;)
  85. for (var = val;;)
  86. if (1) {
  87. goto body98;
  88. } else
  89. while (1)
  90. if (1) {
  91. goto finished98;
  92. } else
  93. body98 : {
  94. call1(var);
  95. call2(var);
  96. }
  97. */