diff options
Diffstat (limited to 'compat')
-rw-r--r-- | compat/macros.hpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/compat/macros.hpp b/compat/macros.hpp index 0807df4c..a6f3d0e9 100644 --- a/compat/macros.hpp +++ b/compat/macros.hpp @@ -40,17 +40,26 @@ # define PP_CAT2(x,y) x ## y #endif +#ifndef PP_EXPAND +# define PP_EXPAND(x) PP_EXPAND__2(x) +# define PP_EXPAND__2(x) PP_EXPAND__3(x) x +# define PP_EXPAND__3(x) x +#endif + #if defined __cplusplus // from now only C++ #include <utility> -//#define once_only(...) do { static bool once__ = false; if (!once__) { once__ = true; __VA_ARGS__; } } while(false) -//#define once_only(expr) ([&] { static decltype(auto) ret___1132 = (expr); return (decltype(ret___1132) const&) ret___1132; }()) +// 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__2(expr, ident) (([&] { static bool ident = ((expr), true); (void)(ident); })) -#define eval_once(expr) eval_once__2(expr, PP_CAT(eval_once_init__, __COUNTER__)) +#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) \ + ([&]() -> std::decay_t<decltype(expr)> const& { static const std::decay_t<decltype(expr)> INIT##ident = (expr); return INIT##ident; }()) #include <type_traits> @@ -68,6 +77,7 @@ constexpr cc_forceinline void static_warn<true>() {} #define static_warning(cond) \ static_warn<(cond)>(); \ +#define typed_progn(type, ...) (([&] () -> type { __VA_ARGS__ })()) #define progn(...) (([&] { __VA_ARGS__ })()) #define prog1(x, ...) (([&] { decltype(auto) ret1324 = (x); __VA_ARGS__; return ret1324; })()) |