45 #include <emscripten.h> 59 #define emp_assert_TO_PAIR(X) EMP_STRINGIFY(X) , X 64 constexpr
bool assert_on =
false;
71 #define emp_assert(...) 76 #define emp_emscripten_assert(...) 80 #elif defined(EMP_TDEBUG) // EMP_NDEBUG not set, but EMP_TDEBUG is! 83 constexpr
bool assert_on =
true;
84 struct AssertFailInfo {
89 AssertFailInfo assert_fail_info;
90 bool assert_last_fail =
false;
92 template <
typename... EXTRA>
93 bool assert_trigger(std::string filename,
size_t line, std::string expr) {
94 emp::assert_fail_info.filename = __FILE__;
95 emp::assert_fail_info.line_num = __LINE__;
96 emp::assert_fail_info.error = expr;
97 emp::assert_last_fail =
true;
102 void assert_clear() { emp::assert_last_fail =
false; }
107 #define emp_assert(...) \ 109 !(EMP_GET_ARG_1(__VA_ARGS__, ~)) && \ 110 emp::assert_trigger(__FILE__, __LINE__, EMP_STRINGIFY( EMP_GET_ARG_1(__VA_ARGS__, ~) )); \ 115 #define emp_emscripten_assert(...) emp_assert(__VA_ARGS__) 117 #define emp_emscripten_assert(...) 122 #elif EMSCRIPTEN // Neither EMP_NDEBUG nor EMP_TDEBUG set, but compiling with Emscripten 125 constexpr
bool assert_on =
true;
126 static int TripAssert() {
127 static int trip_count = 0;
132 void assert_print(std::stringstream &) { ; }
135 template <
typename T,
typename... EXTRA>
136 void assert_print(std::stringstream & ss, std::string name, T && val, EXTRA &&... extra) {
137 ss << name <<
": [" << val <<
"]" <<
std::endl;
138 assert_print(ss, std::forward<EXTRA>(extra)...);
141 template <
typename IGNORE,
typename... EXTRA>
142 bool assert_trigger(std::string filename,
size_t line, std::string expr, IGNORE, EXTRA &&... extra) {
143 std::stringstream ss;
144 ss <<
"Assert Error (In " << filename <<
" line " << line <<
"): " << expr <<
'\n';
145 assert_print(ss, std::forward<EXTRA>(extra)...);
146 if (emp::TripAssert() <= 3) {
147 EM_ASM_ARGS({ msg = Pointer_stringify($0); alert(msg); }, ss.str().c_str());
151 EM_ASM( console.log(
'Callstack:\n' + stackTrace()); );
158 #define emp_assert(...) \ 160 !(EMP_GET_ARG_1(__VA_ARGS__, ~)) && \ 161 emp::assert_trigger(__FILE__, __LINE__, EMP_WRAP_ARGS(emp_assert_TO_PAIR, __VA_ARGS__) ); \ 165 #define emp_emscripten_assert(...) emp_assert(__VA_ARGS__) 172 constexpr
bool assert_on =
true;
175 void assert_print() { ; }
178 template <
typename T,
typename... EXTRA>
179 void assert_print(std::string name, T && val, EXTRA &&... extra) {
180 std::cerr << name <<
": [" << val <<
"]" <<
std::endl;
181 assert_print(std::forward<EXTRA>(extra)...);
184 template <
typename IGNORE,
typename... EXTRA>
185 bool assert_trigger(std::string filename,
size_t line, std::string expr, IGNORE, EXTRA &&... extra) {
186 std::cerr <<
"Assert Error (In " << filename <<
" line " << line
188 assert_print(std::forward<EXTRA>(extra)...);
199 #define emp_assert(...) \ 201 !(EMP_GET_ARG_1(__VA_ARGS__, ~)) && \ 202 emp::assert_trigger(__FILE__, __LINE__, EMP_WRAP_ARGS(emp_assert_TO_PAIR, __VA_ARGS__) ) && \ 209 #define emp_emscripten_assert(...) emp_assert(__VA_ARGS__) 216 #endif // Include guard Generally useful macros that can perform cools tricks.
static const PrintStr endl("<br>")
Pre-define emp::endl to insert a "<br>" and thus acting like a newline.
If we are in emscripten, make sure to include the header.
Definition: array.h:37