9#include <boost/preprocessor/seq/for_each.hpp>
11#include <initializer_list>
19#define M_CAT(X, Y) M_CAT_(X, Y)
20#define M_CAT_(X, Y) X ## Y
22#define M_DEFER1(X) X M_EMPTY()
24#define M_COMMA_PRE(X) ,X
25#define M_UNPACK(...) __VA_ARGS__
27#define M_EVAL(...) M_EVAL1(M_EVAL1(M_EVAL1(__VA_ARGS__)))
28#define M_EVAL1(...) M_EVAL2(M_EVAL2(M_EVAL2(__VA_ARGS__)))
29#define M_EVAL2(...) M_EVAL3(M_EVAL3(M_EVAL3(__VA_ARGS__)))
30#define M_EVAL3(...) M_EVAL4(M_EVAL4(M_EVAL4(__VA_ARGS__)))
31#define M_EVAL4(...) M_EVAL5(M_EVAL5(M_EVAL5(__VA_ARGS__)))
32#define M_EVAL5(...) __VA_ARGS__
36#define M_STR(X) M_STR_(X)
37#define M_STRCOMMA(X) M_STR(X),
39#define M_PASTE_(X, Y) X ## Y
40#define M_PASTE(X, Y) M_PASTE_(X, Y)
43#define M_PAIR_FIRST(A, B) A
44#define M_PAIR_SECOND(A, B) B
47#define M_HEAD(X, ...) X
48#define M_TAIL(X, ...) __VA_ARGS__
51#define M_COUNT(LIST) (std::initializer_list<const char*>{ LIST(M_STRCOMMA) }.size())
54#define M_CONSTEXPR_COND(COND, IF_TRUE, IF_FALSE) [&](){ \
55 if constexpr (COND) { return (IF_TRUE); } else { return (IF_FALSE); } \
57#define M_CONSTEXPR_COND_UNCAPTURED(COND, IF_TRUE, IF_FALSE) [](){ \
58 if constexpr (COND) { return (IF_TRUE); } else { return (IF_FALSE); } \
62#define M_PAIR_XFORM_MACRO_(_, PAIR, ELEM) \
63 M_PAIR_FIRST PAIR ( M_PAIR_SECOND PAIR (ELEM) )
64#define M_PAIR_XFORM_(PAIR, SEQ) \
65 BOOST_PP_SEQ_FOR_EACH(M_PAIR_XFORM_MACRO_, PAIR, SEQ)
67#define M_TRANSFORM_X_MACRO(X, SEQ, FUNC) M_PAIR_XFORM_((X, FUNC), SEQ())
70#define M_DECLARE_ENUM(LIST) \
73 LIST##_MAX = M_COUNT(LIST) - 1U \
75#define M_ENUM_TO_STR(LIST) LIST(M_STRCOMMA)
76#define M_DECL(NAME, TYPE) TYPE NAME;
79#define M_ARR_SIZE(ARR) (sizeof(ARR) / sizeof(*(ARR)))
85 std::cerr << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ' ' << MSG << std::endl
91#define M_LCOV_EXCL_START
92#define M_LCOV_EXCL_STOP
93#define M_LCOV_EXCL_LINE
96#define M_NOINLINE __attribute__((noinline))
106inline void _insist(
const bool cond,
const char *filename,
const unsigned line,
const char *condstr,
const char *msg)
111 std::cerr << filename <<
':' << line <<
": Condition '" << condstr <<
"' failed.";
113 std::cerr <<
" " << msg <<
'.';
114 std::cerr << std::endl;
117 __builtin_unreachable();
119#define M_INSIST2_(COND, MSG) ::m::_insist((COND), __FILE__, __LINE__, #COND, MSG)
120#define M_INSIST1_(COND) M_INSIST2_(COND, nullptr)
123#define M_INSIST2_(COND, MSG) while (0) { ((void) (COND), (void) (MSG)); }
124#define M_INSIST1_(COND) while (0) { ((void) (COND)); }
128#define M_GET_INSIST_(_1, _2, NAME, ...) NAME
129#define M_insist(...) M_GET_INSIST_(__VA_ARGS__, M_INSIST2_, M_INSIST1_, XXX)(__VA_ARGS__)
139[[noreturn]]
inline void _abort(
const char *filename,
const unsigned line,
const char *msg)
142 std::cerr << filename <<
':' << line <<
": " << msg << std::endl;
144 __builtin_unreachable();
146#define M_unreachable(MSG) m::_abort(__FILE__, __LINE__, (MSG))
149#define M_unreachable(MSG) __builtin_unreachable()
162T *
_notnull(T *arg,
const char *filename,
const unsigned line,
const char *argstr)
166 std::cerr << filename <<
':' << line <<
": " << argstr <<
" was NULL" << std::endl;
173std::unique_ptr<T>
_notnull(std::unique_ptr<T> arg,
const char *filename,
const unsigned line,
const char *argstr)
177 std::cerr << filename <<
':' << line <<
": " << argstr <<
" was NULL" << std::endl;
180 return std::move(arg);
182#define M_notnull(ARG) m::_notnull((ARG), __FILE__, __LINE__, #ARG)
185#define M_notnull(ARG) (ARG)
197#define M_nothrow(ARG) [&](){ \
200 } catch (const std::exception &e) { \
202 std::cerr << __FILE__ << ':' << __LINE__ << ": " << #ARG << " has thrown exception '" << e.what() << "'" \
209#define M_nothrow(ARG) (ARG)
213#define M_DISCARD (void)
void _abort(const char *filename, const unsigned line, const char *msg)
T * _notnull(T *arg, const char *filename, const unsigned line, const char *argstr)
void _insist(const bool cond, const char *filename, const unsigned line, const char *condstr, const char *msg)