#ifndef DROPSHELL_ASSERT_HPP #define DROPSHELL_ASSERT_HPP #include #include #include // For std::exit and EXIT_FAILURE namespace ds { struct SourceLocation { const char* file_name; int line; const char* function_name; }; // Helper macro to create a SourceLocation with current context #define DS_CURRENT_LOCATION ds::SourceLocation{__FILE__, __LINE__, __func__} [[noreturn]] inline void assert_fail( const char* expression, const SourceLocation& location, const char* message = nullptr) { std::cerr << "\033[1;31mAssertion failed!\033[0m\n" << "Expression: \033[1;33m" << expression << "\033[0m\n" << "Location: \033[1;36m" << location.file_name << ":" << location.line << "\033[0m\n" << "Function: \033[1;36m" << location.function_name << "\033[0m\n"; if (message) { std::cerr << "Message: \033[1;37m" << message << "\033[0m\n"; } std::cerr << std::endl; // Exit the program without creating a core dump std::exit(EXIT_FAILURE); } } // namespace ds // Standard assertion #define ASSERT(condition) \ do { \ if (!(condition)) { \ ds::assert_fail(#condition, DS_CURRENT_LOCATION); \ } \ } while (false) // Assertion with custom message #define ASSERT_MSG(condition, message) \ do { \ if (!(condition)) { \ ds::assert_fail(#condition, DS_CURRENT_LOCATION, message); \ } \ } while (false) #endif // DROPSHELL_ASSERT_HPP