diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2015-01-03 21:07:56 -0800 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2015-01-03 21:58:26 -0800 |
commit | 00da6b5977574a0564169172227d8aab45be188f (patch) | |
tree | dd52eee506a98e1eb9fcdea52e7db25079a7ad28 /src/sexpr/variant.hpp | |
parent | 4c91abd6a020ee030114ae3f22d8f6066e7528be (diff) | |
download | tmwa-00da6b5977574a0564169172227d8aab45be188f.tar.gz tmwa-00da6b5977574a0564169172227d8aab45be188f.tar.bz2 tmwa-00da6b5977574a0564169172227d8aab45be188f.tar.xz tmwa-00da6b5977574a0564169172227d8aab45be188f.zip |
Switch MATCH to separate begin/end macros
The for loop trick turned out to be very prone to infinite loops
at runtime. It's better to force compiler errors even if it's ugly.
Diffstat (limited to 'src/sexpr/variant.hpp')
-rw-r--r-- | src/sexpr/variant.hpp | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/src/sexpr/variant.hpp b/src/sexpr/variant.hpp index 287a5f0..0eccc5a 100644 --- a/src/sexpr/variant.hpp +++ b/src/sexpr/variant.hpp @@ -23,8 +23,6 @@ #include <cstddef> #include <utility> -#include "../compat/attr.hpp" - #include "union.hpp" #include "void.hpp" @@ -35,14 +33,42 @@ namespace tmwa { namespace sexpr { -#define MATCH(expr) \ - WITH_VAR_NOLOOP(auto&&, _match_var, expr) \ - switch (tmwa::sexpr::VariantFriend::get_state(_match_var)) -#define TYPED_CASE(ty, var, look) \ - break; \ - case tmwa::sexpr::VariantFriend::get_state_for<look, decltype(_match_var)>(): \ - WITH_VAR_INLOOP(ty, var, tmwa::sexpr::VariantFriend::unchecked_get<look>(_match_var)) -#define CASE(ty, var) TYPED_CASE(ty, var, std::remove_const<std::remove_reference<ty>::type>::type) +#define MATCH_BEGIN(expr) \ + { \ + auto&& _match_var = (expr); \ + switch (tmwa::sexpr::VariantFriend::get_state(_match_var)) \ + { \ + { \ + { \ + /* }}}} */ +#define MATCH_END() \ + /* {{{{ */ \ + } \ + } \ + } \ + (void) _match_var; \ + } + +#define MATCH_CASE(ty, v) \ + /* {{{{ */ \ + } \ + break; \ + } \ + { \ + using _match_case_type = std::remove_const<std::remove_reference<ty>::type>::type; \ + case tmwa::sexpr::VariantFriend::get_state_for<_match_case_type, decltype(_match_var)>(): \ + { \ + ty v = tmwa::sexpr::VariantFriend::unchecked_get<_match_case_type>(_match_var); + /* }}}} */ +#define MATCH_DEFAULT() \ + /* {{{{ */ \ + } \ + break; \ + } \ + { \ + default: \ + { \ + /* }}}} */ template<class... T> class Variant |