Pre-C++11 Static Assertions Without Boost
Update: This is now part of my assertion library.
In the implementation of my cross platform C++ assertion library I used a self-contained implementation of a STATIC_ASSERT
macro usable in pre-c++11 projects that can’t or don’t want to rely on Boost.
I originally wrote it as an answer to a question on Stackoverflow.
Usage:
STATIC_ASSERT(expression, message);
When the static assertion test fails, a compiler error message that somehow contains the “STATIC_ASSERTION_FAILED_AT_LINE_xxx_message
” string is generated.
The only restriction is that message has to be a valid C++ identifier: you need to separate words with e.g. underscores and it cannot start with a digit.
Example:
bool want_pony = true;
STATIC_ASSERT(!want_pony, no_you_cant_have_a_pony);
Which will produce a compiler error containing:
STATIC_ASSERTION_FAILED_AT_LINE_1337_no_you_cant_have_a_pony
Without much surprise, I once again learnt the technique from Andrei Alexandrescu and I iterated to make sure it’s usable anywhere in a C++ file: in a namespace, in a class definition or in a function.
#define JOIN(lhs, rhs) JOIN_1(lhs, rhs)
#define JOIN_1(lhs, rhs) JOIN_2(lhs, rhs)
#define JOIN_2(lhs, rhs) lhs##rhs
#define STATIC_ASSERT(expression, message)\
struct JOIN(__static_assertion_at_line_, __LINE__)\
{\
impl::StaticAssertion<static_cast<bool>((expression))> JOIN(JOIN(JOIN(STATIC_ASSERTION_FAILED_AT_LINE_, __LINE__), _), message);\
};\
typedef impl::StaticAssertionTest<sizeof(JOIN(__static_assertion_at_line_, __LINE__))> JOIN(__static_assertion_test_at_line_, __LINE__)
// note that we wrap the non existing type inside a struct to avoid warning
// messages about unused variables when static assertions are used at function
// scope
// the use of sizeof makes sure the assertion error is not ignored by SFINAE
namespace impl {
template <bool>
struct StaticAssertion;
template <>
struct StaticAssertion<true>
{
}; // StaticAssertion<true>
template<int i>
struct StaticAssertionTest
{
}; // StaticAssertionTest<int>
} // namespace impl