#include <type_traits>
#include <utility>
template <class T>
constexpr bool returns_true(const T fun) {
return decltype(fun())::value;
}
template <class T>
struct true_if_callable_t : T {
using T::operator();
template<class...P>
std::false_type operator()(P&&...) const;
};
template<class T, class... P>
[[noreturn]] auto true_if_callable(T, P&&...a)
-> decltype(std::declval<true_if_callable_t<T>>()(0, std::declval<P>()...)) {}
template<class>
struct always_true_type { using type = std::true_type; };
template <class T>
[[noreturn]] T&& declv() {}
#define FORWARD(...) __VA_ARGS__
#define IS_VALID_EXPR(decl, expr) \
::returns_true([]{ return true_if_callable( [](int,auto&& NAME(decl)) \
-> typename always_true_type<decltype(expr)>::type { \
return std::true_type{}; \
}, ::declv<TYPE(decl)>() ); })
#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 STATIC_ASSERT_VALID_(n, f, s, decl, expr) \
(n IS_VALID_EXPR(decl, expr), \
"\n\n********************\n\n" \
"Given:\n " STRINGIZE(TYPE(decl)) " " STRINGIZE(NAME(decl)) ";\n\n" \
"The following expression was expected to" f " compile but did" s ":\n " \
STRINGIZE(expr) "\n\n********************")
#define STATIC_ASSERT_VALID(decl, expr) \
static_assert \
STATIC_ASSERT_VALID_(, , " not", decl, expr)
#define STATIC_ASSERT_INVALID(decl, expr) \
static_assert \
STATIC_ASSERT_VALID_(!, " not", , decl, expr)
STATIC_ASSERT_VALID
(
(int) a,
++a
);
STATIC_ASSERT_INVALID
(
(const int) a,
++a
);
int main() {}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dXRpbGl0eT4KCnRlbXBsYXRlIDxjbGFzcyBUPgpjb25zdGV4cHIgYm9vbCByZXR1cm5zX3RydWUoY29uc3QgVCBmdW4pIHsKCXJldHVybiBkZWNsdHlwZShmdW4oKSk6OnZhbHVlOwp9Cgp0ZW1wbGF0ZSA8Y2xhc3MgVD4Kc3RydWN0IHRydWVfaWZfY2FsbGFibGVfdCA6IFQgewoJdXNpbmcgVDo6b3BlcmF0b3IoKTsKCXRlbXBsYXRlPGNsYXNzLi4uUD4KCXN0ZDo6ZmFsc2VfdHlwZSBvcGVyYXRvcigpKFAmJi4uLikgY29uc3Q7Cn07Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcy4uLiBQPgpbW25vcmV0dXJuXV0gYXV0byB0cnVlX2lmX2NhbGxhYmxlKFQsIFAmJi4uLmEpCi0+IGRlY2x0eXBlKHN0ZDo6ZGVjbHZhbDx0cnVlX2lmX2NhbGxhYmxlX3Q8VD4+KCkoMCwgc3RkOjpkZWNsdmFsPFA+KCkuLi4pKSB7fQoKdGVtcGxhdGU8Y2xhc3M+CnN0cnVjdCBhbHdheXNfdHJ1ZV90eXBlIHsgdXNpbmcgdHlwZSA9IHN0ZDo6dHJ1ZV90eXBlOyB9OwoKdGVtcGxhdGUgPGNsYXNzIFQ+Cltbbm9yZXR1cm5dXSBUJiYgZGVjbHYoKSB7fQoKI2RlZmluZSBGT1JXQVJEKC4uLikgX19WQV9BUkdTX18KCiNkZWZpbmUgSVNfVkFMSURfRVhQUihkZWNsLCBleHByKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCjo6cmV0dXJuc190cnVlKFtdeyByZXR1cm4gdHJ1ZV9pZl9jYWxsYWJsZSggW10oaW50LGF1dG8mJiBOQU1FKGRlY2wpKSAgICAgICAgICBcCi0+IHR5cGVuYW1lIGFsd2F5c190cnVlX3R5cGU8ZGVjbHR5cGUoZXhwcik+Ojp0eXBlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgcmV0dXJuIHN0ZDo6dHJ1ZV90eXBle307ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICB9LCA6OmRlY2x2PFRZUEUoZGVjbCk+KCkgKTsgICB9KQoKI2RlZmluZSBJU19JTlZBTElEX0VYUFIoZGVjbCwgZXhwcikgKCFJU19WQUxJRF9FWFBSKGRlY2wsZXhwcikpCgojZGVmaW5lIEZJUlNUX0FSR19FWFBBTkRFRF8oYSxiKSBGT1JXQVJEIGEKI2RlZmluZSBGSVJTVF9BUkdfRVhQQU5ERUQoLi4uKSBGSVJTVF9BUkdfRVhQQU5ERURfKF9fVkFfQVJHU19fKQoKI2RlZmluZSBTRUNPTkRfQVJHX0VYUEFOREVEXyhhLGIpIGIKI2RlZmluZSBTRUNPTkRfQVJHX0VYUEFOREVEKC4uLikgU0VDT05EX0FSR19FWFBBTkRFRF8oX19WQV9BUkdTX18pCgojZGVmaW5lIFBBUkVOVEhFU0laRURfUEFSVF8oLi4uKSAoX19WQV9BUkdTX18pLAojZGVmaW5lIFRZUEUoYXJnKSBGSVJTVF9BUkdfRVhQQU5ERUQoIFBBUkVOVEhFU0laRURfUEFSVF8gYXJnICkKCiNkZWZpbmUgTkFNRShhcmcpIFNFQ09ORF9BUkdfRVhQQU5ERUQoIFBBUkVOVEhFU0laRURfUEFSVF8gYXJnICkKCiNkZWZpbmUgU1RSSU5HSVpFXyguLi4pICNfX1ZBX0FSR1NfXwojZGVmaW5lIFNUUklOR0laRSguLi4pIFNUUklOR0laRV8oX19WQV9BUkdTX18pCgojZGVmaW5lIFNUQVRJQ19BU1NFUlRfVkFMSURfKG4sIGYsIHMsIGRlY2wsIGV4cHIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoobiBJU19WQUxJRF9FWFBSKGRlY2wsIGV4cHIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoiXG5cbioqKioqKioqKioqKioqKioqKioqXG5cbiIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAoiR2l2ZW46XG4gICAgIiBTVFJJTkdJWkUoVFlQRShkZWNsKSkgIiAiIFNUUklOR0laRShOQU1FKGRlY2wpKSAiO1xuXG4iICAgICAgICAgXAoiVGhlIGZvbGxvd2luZyBleHByZXNzaW9uIHdhcyBleHBlY3RlZCB0byIgZiAiIGNvbXBpbGUgYnV0IGRpZCIgcyAiOlxuICAgICIgICAgXApTVFJJTkdJWkUoZXhwcikgIlxuXG4qKioqKioqKioqKioqKioqKioqKiIpCgojZGVmaW5lIFNUQVRJQ19BU1NFUlRfVkFMSUQoZGVjbCwgZXhwcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXApzdGF0aWNfYXNzZXJ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXApTVEFUSUNfQVNTRVJUX1ZBTElEXygsICwgIiBub3QiLCBkZWNsLCBleHByKQoKI2RlZmluZSBTVEFUSUNfQVNTRVJUX0lOVkFMSUQoZGVjbCwgZXhwcikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKc3RhdGljX2Fzc2VydCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKU1RBVElDX0FTU0VSVF9WQUxJRF8oISwgIiBub3QiLCAsIGRlY2wsIGV4cHIpCgoKU1RBVElDX0FTU0VSVF9WQUxJRAooCiAgICAoaW50KSBhLAogICAgKythCik7CgoKU1RBVElDX0FTU0VSVF9JTlZBTElECigKICAgIChjb25zdCBpbnQpIGEsCiAgICArK2EKKTsKCgppbnQgbWFpbigpIHt9Cg==