#pragma once #include "macros1.h" #ifdef __cplusplus // from now only C++ #include #include // before C++20 namespace cxx20_compat { template struct remove_cvref { using type = std::remove_cv_t>; }; } // ns cxx20_compat template using remove_cvref_t = typename cxx20_compat::remove_cvref::type; template using to_const_cvref_t = std::add_lvalue_reference_t>>; // causes ICE in Visual Studio 2017 Preview. the ICE was reported and they handle them seriously in due time. // the ICE is caused by decltype(auto) and const& return value //#define eval_once(expr) ([&]() -> decltype(auto) { static decltype(auto) ret___1132 = (expr); return (decltype(ret___1132) const&) ret___1132; }()) #define eval_once(expr) eval_once__2(expr, PP_CAT(_EVAL_ONCE__, __COUNTER__)) #define eval_once__2(expr, ident) eval_once__3(expr, ident) #define eval_once__3(expr, ident) \ ([&]() -> decltype(auto) { \ static auto INIT##ident = (expr); \ return static_cast>(INIT##ident); \ }()) #include template using cv_qualified = std::conditional_t>, remove_cvref_t, to_const_cvref_t>; template [[deprecated]] constexpr cc_forceinline void static_warn() {} template<> constexpr cc_forceinline void static_warn() {} #define static_warning(cond) \ static_warn<(cond)>(); \ #define progn(...) ([&]() -> decltype(auto) { __VA_ARGS__ }()) // end c++-only macros #endif