#include <utility>
template <class T>
constexpr bool always_true(T&&) { return true; }
template<bool>
struct always_bool { using type = bool; };
template <class T, class U>
constexpr bool true_if_constexpr(T, U) { return false; }
template <class U>
constexpr auto true_if_constexpr(int, U)
-> typename always_bool
< ::always_true(decltype(std::declval<U>()()){}.member) >::type
{
return true;
}
struct empty {};
#define IS_CONSTEXPR(decl, expr) \
(::true_if_constexpr(0, \
[] \
{ \
TYPE(decl) NAME(decl); \
\
struct return_type \
{ \
decltype(expr)&& member = static_cast<decltype(expr)&&>(expr); \
}; \
\
return return_type{}; \
}) \
)
#define IS_INVALID_EXPR(decl, expr) (!IS_VALID_EXPR(decl,expr))
#define FIRST_ARG_EXPANDED_(a,b) FORWARD a
#define FIRST_ARG_EXPANDED(...) FIRST_ARG_EXPANDED_(__VA_ARGS__)
#define SECOND_ARG_EXPANDED_(a,b) b
#define SECOND_ARG_EXPANDED(...) SECOND_ARG_EXPANDED_(__VA_ARGS__)
#define PARENTHESIZED_PART_(...) (__VA_ARGS__),
#define TYPE(arg) FIRST_ARG_EXPANDED( PARENTHESIZED_PART_ arg )
#define NAME(arg) SECOND_ARG_EXPANDED( PARENTHESIZED_PART_ arg )
#define STRINGIZE_(...) #__VA_ARGS__
#define STRINGIZE(...) STRINGIZE_(__VA_ARGS__)
#define FORWARD(...) __VA_ARGS__
template<class T>
bool foo(T&&) { return true; }
template<class T>
constexpr bool constexpr_foo(T&&) { return true; }
#define STATIC_ASSERT_CONSTEXPR_(n, f, s, decl, expr) \
(n IS_CONSTEXPR(decl, expr), \
"\n\n********************\n\n" \
"Given:\n " STRINGIZE(TYPE(decl)) " " STRINGIZE(NAME(decl)) ";\n\n" \
"The following expression was expected to" f " be constexpr but was" s ":\n" \
" " STRINGIZE(expr) "\n\n********************")
#define STATIC_ASSERT_CONSTEXPR(decl, expr) \
static_assert \
STATIC_ASSERT_CONSTEXPR_(, , " not", decl, expr)
#define STATIC_ASSERT_NOT_CONSTEXPR(decl, expr) \
static_assert \
STATIC_ASSERT_CONSTEXPR_(!, " not", , decl, expr)
STATIC_ASSERT_CONSTEXPR
(
(constexpr int) var = 5,
constexpr_foo(var)
);
STATIC_ASSERT_NOT_CONSTEXPR
(
(constexpr int) var = 5,
foo(var)
);
int main() {}
I2luY2x1ZGUgPHV0aWxpdHk+Cgp0ZW1wbGF0ZSA8Y2xhc3MgVD4KY29uc3RleHByIGJvb2wgYWx3YXlzX3RydWUoVCYmKSB7IHJldHVybiB0cnVlOyB9Cgp0ZW1wbGF0ZTxib29sPgpzdHJ1Y3QgYWx3YXlzX2Jvb2wgeyB1c2luZyB0eXBlID0gYm9vbDsgfTsKCnRlbXBsYXRlIDxjbGFzcyBULCBjbGFzcyBVPgpjb25zdGV4cHIgYm9vbCB0cnVlX2lmX2NvbnN0ZXhwcihULCBVKSB7IHJldHVybiBmYWxzZTsgfQoKdGVtcGxhdGUgPGNsYXNzIFU+CmNvbnN0ZXhwciBhdXRvIHRydWVfaWZfY29uc3RleHByKGludCwgVSkKICAtPiB0eXBlbmFtZSBhbHdheXNfYm9vbAogICAgIDwgOjphbHdheXNfdHJ1ZShkZWNsdHlwZShzdGQ6OmRlY2x2YWw8VT4oKSgpKXt9Lm1lbWJlcikgPjo6dHlwZQp7CglyZXR1cm4gdHJ1ZTsKfQoKc3RydWN0IGVtcHR5IHt9OwoKI2RlZmluZSBJU19DT05TVEVYUFIoZGVjbCwgZXhwcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKDo6dHJ1ZV9pZl9jb25zdGV4cHIoMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKIFtdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKCVRZUEUoZGVjbCkgTkFNRShkZWNsKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKCXN0cnVjdCByZXR1cm5fdHlwZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKCXsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKCQlkZWNsdHlwZShleHByKSYmIG1lbWJlciA9IHN0YXRpY19jYXN0PGRlY2x0eXBlKGV4cHIpJiY+KGV4cHIpOyAgICAgICAgIFwKCX07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKCXJldHVybiByZXR1cm5fdHlwZXt9OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKIH0pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKQoKCiNkZWZpbmUgSVNfSU5WQUxJRF9FWFBSKGRlY2wsIGV4cHIpICghSVNfVkFMSURfRVhQUihkZWNsLGV4cHIpKQogCiNkZWZpbmUgRklSU1RfQVJHX0VYUEFOREVEXyhhLGIpIEZPUldBUkQgYQojZGVmaW5lIEZJUlNUX0FSR19FWFBBTkRFRCguLi4pIEZJUlNUX0FSR19FWFBBTkRFRF8oX19WQV9BUkdTX18pCiAKI2RlZmluZSBTRUNPTkRfQVJHX0VYUEFOREVEXyhhLGIpIGIKI2RlZmluZSBTRUNPTkRfQVJHX0VYUEFOREVEKC4uLikgU0VDT05EX0FSR19FWFBBTkRFRF8oX19WQV9BUkdTX18pCiAKI2RlZmluZSBQQVJFTlRIRVNJWkVEX1BBUlRfKC4uLikgKF9fVkFfQVJHU19fKSwKI2RlZmluZSBUWVBFKGFyZykgRklSU1RfQVJHX0VYUEFOREVEKCBQQVJFTlRIRVNJWkVEX1BBUlRfIGFyZyApCiAKI2RlZmluZSBOQU1FKGFyZykgU0VDT05EX0FSR19FWFBBTkRFRCggUEFSRU5USEVTSVpFRF9QQVJUXyBhcmcgKQogCiNkZWZpbmUgU1RSSU5HSVpFXyguLi4pICNfX1ZBX0FSR1NfXwojZGVmaW5lIFNUUklOR0laRSguLi4pIFNUUklOR0laRV8oX19WQV9BUkdTX18pCgojZGVmaW5lIEZPUldBUkQoLi4uKSBfX1ZBX0FSR1NfXwoKdGVtcGxhdGU8Y2xhc3MgVD4KYm9vbCBmb28oVCYmKSB7IHJldHVybiB0cnVlOyB9Cgp0ZW1wbGF0ZTxjbGFzcyBUPgpjb25zdGV4cHIgYm9vbCBjb25zdGV4cHJfZm9vKFQmJikgeyByZXR1cm4gdHJ1ZTsgfQoKI2RlZmluZSBTVEFUSUNfQVNTRVJUX0NPTlNURVhQUl8obiwgZiwgcywgZGVjbCwgZXhwcikgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKG4gSVNfQ09OU1RFWFBSKGRlY2wsIGV4cHIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKIlxuXG4qKioqKioqKioqKioqKioqKioqKlxuXG4iICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKIkdpdmVuOlxuICAgICIgU1RSSU5HSVpFKFRZUEUoZGVjbCkpICIgIiBTVFJJTkdJWkUoTkFNRShkZWNsKSkgIjtcblxuIiAgICAgICAgIFwKIlRoZSBmb2xsb3dpbmcgZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQgdG8iIGYgIiBiZSBjb25zdGV4cHIgYnV0IHdhcyIgcyAiOlxuIiAgIFwKIiAgICAiIFNUUklOR0laRShleHByKSAiXG5cbioqKioqKioqKioqKioqKioqKioqIikKIAojZGVmaW5lIFNUQVRJQ19BU1NFUlRfQ09OU1RFWFBSKGRlY2wsIGV4cHIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXApzdGF0aWNfYXNzZXJ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXApTVEFUSUNfQVNTRVJUX0NPTlNURVhQUl8oLCAsICIgbm90IiwgZGVjbCwgZXhwcikKIAojZGVmaW5lIFNUQVRJQ19BU1NFUlRfTk9UX0NPTlNURVhQUihkZWNsLCBleHByKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXApzdGF0aWNfYXNzZXJ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXApTVEFUSUNfQVNTRVJUX0NPTlNURVhQUl8oISwgIiBub3QiLCAsIGRlY2wsIGV4cHIpCgpTVEFUSUNfQVNTRVJUX0NPTlNURVhQUgooCgkoY29uc3RleHByIGludCkgdmFyID0gNSwKCWNvbnN0ZXhwcl9mb28odmFyKQopOwoKClNUQVRJQ19BU1NFUlRfTk9UX0NPTlNURVhQUgooCgkoY29uc3RleHByIGludCkgdmFyID0gNSwKCWZvbyh2YXIpCik7CgppbnQgbWFpbigpIHt9Cg==