#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==