支持任意参数个数的assert类

发布时间 2023-07-02 21:53:17作者: 算你牛
#pragma once
#include <iostream> //std::cout
#include <stdlib.h> //abort

struct Assert
{
Assert& ASSERT_A;
Assert& ASSERT_B;

explicit Assert(const char* exp) : ASSERT_A(*this), ASSERT_B(*this)
{
std::cout << "Failed: " << exp << "\n";
}
~Assert()
{
abort();
}

Assert& print_context(const char* file, const char* function, const int line)
{
std::cout << "File: " << file << " Line: " << line << " Function: " << function << "\n";
std::cout << "Context Variables:\n";
return (*this);
}

template <typename type> const Assert& print_current_val(const char* name, type value)
{
std::cout << '\t' << name << " = " << value << "\n";
return (*this);
}
};

#define ASSERT_A(x) ASSERT_OP(x, B)
#define ASSERT_B(x) ASSERT_OP(x, A)
#define ASSERT_OP(x, next) ASSERT_A.print_current_val(#x, (x)).ASSERT_##next
#define ASSERT(expr) \
if (expr) \
{ \
} \
else \
Assert(#expr).print_context(__FILE__, __FUNCTION__, __LINE__).ASSERT_A

#define ASSERT_EQ(expr1, expr2) ASSERT(expr1 == expr2)(expr1)(expr2)
#define ASSERT_NE(expr1, expr2) ASSERT(expr1 != expr2)(expr1)(expr2)

#ifdef NDEBUG
#undef ASSERT
#define ASSERT(expr) \
if (true) \
{ \
} \
else \
Assert(#expr).print_context(__FILE__, __FUNCTION__, __LINE__).ASSERT_A
#endif