You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

157 lines
5.2 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #pragma once
  13. #include <lol/base/log.h>
  14. #include <cstdlib>
  15. #if defined _WIN32
  16. # ifdef WIN32_LEAN_AND_MEAN
  17. # include <windows.h>
  18. # else
  19. # define WIN32_LEAN_AND_MEAN 1
  20. # include <windows.h>
  21. # undef WIN32_LEAN_AND_MEAN
  22. # endif
  23. #endif
  24. namespace lol
  25. {
  26. static inline void abort()
  27. {
  28. //*(uint32_t *)nullptr = 0xdead;
  29. std::abort();
  30. }
  31. /* FIXME: see http://stackoverflow.com/q/3596781/111461 for discussions
  32. * on implementing __debugbreak() on POSIX systems. */
  33. namespace debug
  34. {
  35. extern void dump_stack();
  36. static inline void abort()
  37. {
  38. dump_stack();
  39. #if defined _WIN32
  40. __debugbreak();
  41. #endif
  42. lol::abort();
  43. }
  44. }
  45. #define LOL_CALL(macro, args) macro args
  46. #define LOL_EVAL(a) a
  47. #define LOL_1ST(a, ...) a
  48. #define LOL_GET_63RD(a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, \
  49. a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, \
  50. a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, \
  51. a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, \
  52. a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, \
  53. a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, \
  54. a61, a62, a63, ...) a63
  55. #define LOL_COUNT_TO_3(...) \
  56. LOL_EVAL(LOL_GET_63RD(__VA_ARGS__, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
  57. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
  58. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
  59. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
  60. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
  61. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
  62. 2, 1, TOO_FEW_ARGUMENTS))
  63. #define LOL_COUNT_TO_8(...) \
  64. LOL_EVAL(LOL_GET_63RD(__VA_ARGS__, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
  65. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
  66. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
  67. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
  68. 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
  69. 8, 8, 8, 8, 8, 7, 6, 5, 4, 3, \
  70. 2, 1, TOO_FEW_ARGUMENTS))
  71. #define LOL_COUNT_TO_12(...) \
  72. LOL_EVAL(LOL_GET_63RD(__VA_ARGS__, 12,12,12,12,12,12,12,12,12,12,\
  73. 12,12,12,12,12,12,12,12,12,12,\
  74. 12,12,12,12,12,12,12,12,12,12,\
  75. 12,12,12,12,12,12,12,12,12,12,\
  76. 12,12,12,12,12,12,12,12,12,12,\
  77. 12,11,10,9, 8, 7, 6, 5, 4, 3, \
  78. 2, 1, TOO_FEW_ARGUMENTS))
  79. /* Three levels of dispatch are needed because of Visual Studio's bizarre
  80. * handling of __VA_ARGS__ inside macro calls */
  81. #define LOL_CAT3(a, b) a##b
  82. #define LOL_CAT2(a, b) LOL_CAT3(a,b)
  83. #define LOL_CAT(a, b) LOL_CAT2(a,b)
  84. /*
  85. * UNUSED(): declare one or several variables as unused
  86. */
  87. #define LOL_UNUSED_1(a01) \
  88. sizeof(a01)
  89. #define LOL_UNUSED_2(a01, a02) \
  90. sizeof(a01) + LOL_UNUSED_1(a02)
  91. #define LOL_UNUSED_3(a01, a02, a03) \
  92. sizeof(a01) + LOL_UNUSED_2(a02, a03)
  93. #define LOL_UNUSED_4(a01, a02, a03, a04) \
  94. sizeof(a01) + LOL_UNUSED_3(a02, a03, a04)
  95. #define LOL_UNUSED_5(a01, a02, a03, a04, a05) \
  96. sizeof(a01) + LOL_UNUSED_4(a02, a03, a04, a05)
  97. #define LOL_UNUSED_6(a01, a02, a03, a04, a05, a06) \
  98. sizeof(a01) + LOL_UNUSED_5(a02, a03, a04, a05, a06)
  99. #define LOL_UNUSED_7(a01, a02, a03, a04, a05, a06, a07) \
  100. sizeof(a01) + LOL_UNUSED_6(a02, a03, a04, a05, a06, a07)
  101. #define LOL_UNUSED_8(a01, a02, a03, a04, a05, a06, a07, a08) \
  102. sizeof(a01) + LOL_UNUSED_7(a02, a03, a04, a05, a06, a07, a08)
  103. #define UNUSED(...) (void)sizeof((void)( \
  104. LOL_CALL(LOL_CAT(LOL_UNUSED_, LOL_CALL(LOL_COUNT_TO_8, (__VA_ARGS__))), \
  105. (__VA_ARGS__))), 0) \
  106. /*
  107. * ASSERT(): test and enforce conditions at runtime
  108. */
  109. #define LOL_ERROR_1(t) \
  110. lol::msg::error("assertion at %s:%d: %s\n", __FILE__, __LINE__, #t)
  111. #define LOL_ERROR_2(t, s) \
  112. lol::msg::error("assertion at %s:%d: %s\n", __FILE__, __LINE__, s)
  113. #define LOL_ERROR_3(t, s, ...) \
  114. lol::msg::error("assertion at %s:%d: " s "\n", __FILE__, __LINE__, __VA_ARGS__)
  115. #if LOL_BUILD_RELEASE
  116. # define ASSERT(...) UNUSED(LOL_CALL(LOL_1ST, (__VA_ARGS__)))
  117. #else
  118. # define ASSERT(...) \
  119. if (LOL_CALL(LOL_1ST, (__VA_ARGS__))) \
  120. { \
  121. /* Don't use "!" so that ASSERT(x = 1) instead of ASSERT(x == 1)
  122. * triggers a compilation warning. */ \
  123. } \
  124. else \
  125. { \
  126. LOL_CALL(LOL_CAT(LOL_ERROR_, LOL_CALL(LOL_COUNT_TO_3, \
  127. (__VA_ARGS__))), \
  128. (__VA_ARGS__)); \
  129. lol::debug::abort(); \
  130. }
  131. #endif
  132. } /* namespace lol */