summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compat/attr.hpp6
-rw-r--r--src/compat/borrow.hpp1
-rw-r--r--src/compat/option.hpp12
-rw-r--r--src/compat/option_test.cpp20
-rw-r--r--src/sexpr/variant.hpp7
5 files changed, 40 insertions, 6 deletions
diff --git a/src/compat/attr.hpp b/src/compat/attr.hpp
index 238a5d5..5322a14 100644
--- a/src/compat/attr.hpp
+++ b/src/compat/attr.hpp
@@ -28,4 +28,10 @@ namespace tmwa
#else
# define FALLTHROUGH /* fallthrough */
#endif
+
+#define JOIN(a, b) a##b
+
+#define WITH_VAR(ty, var, expr) \
+ for (bool JOIN(var, _guard) = true; JOIN(var, _guard); ) \
+ for (ty var = expr; JOIN(var, _guard); JOIN(var, _guard) = false)
} // namespace tmwa
diff --git a/src/compat/borrow.hpp b/src/compat/borrow.hpp
index 8b23d7f..5cb6a7c 100644
--- a/src/compat/borrow.hpp
+++ b/src/compat/borrow.hpp
@@ -36,6 +36,7 @@ namespace tmwa
{
T *stupid;
public:
+ Borrowed() = delete;
explicit
Borrowed(T *p) : stupid(p)
{
diff --git a/src/compat/option.hpp b/src/compat/option.hpp
index 25c23eb..ad83395 100644
--- a/src/compat/option.hpp
+++ b/src/compat/option.hpp
@@ -24,6 +24,8 @@
#include <utility>
+#include "attr.hpp"
+
namespace tmwa
{
@@ -204,6 +206,10 @@ namespace option
{
return repr.is_some() ? repr.ptr() : def;
}
+ bool is_some() const
+ {
+ return repr.is_some();
+ }
template<class F>
auto move_map(F&& f) -> Option<decltype(std::forward<F>(f)(std::move(*repr.ptr())))>
@@ -365,9 +371,13 @@ namespace option
#define TRY_UNWRAP(opt, falsy) \
({ \
tmwa::option::RefWrapper<decltype((opt))> o = {(opt)}; \
- if (!o.maybe_ref.ptr_or(nullptr)) falsy; \
+ if (!o.maybe_ref.is_some()) falsy; \
tmwa::option::option_unwrap(std::move(o)); \
}).maybe_ref_fun()
+// immediately preceded by 'if'; not double-eval-safe
+#define OPTION_IS_SOME(var, expr) \
+ ((expr).is_some()) \
+ WITH_VAR(auto&, var, *(expr).ptr_or(nullptr))
} // namespace option
using option::Option;
diff --git a/src/compat/option_test.cpp b/src/compat/option_test.cpp
index e4be147..d99eda9 100644
--- a/src/compat/option_test.cpp
+++ b/src/compat/option_test.cpp
@@ -324,6 +324,26 @@ TEST(Option, unwrap)
v = None; TRY_UNWRAP(fcl(), v = Some(1));
v = None; TRY_UNWRAP(fr(), v = Some(1));
v = None; TRY_UNWRAP(fcr(), v = Some(1));
+
+ v = None;
+ if OPTION_IS_SOME(o, v)
+ {
+ EXPECT_NE(o, o);
+ }
+ else
+ {
+ SUCCEED();
+ }
+
+ v = Some(1);
+ if OPTION_IS_SOME(o, v)
+ {
+ EXPECT_EQ(o, 1);
+ }
+ else
+ {
+ FAIL();
+ }
}
TEST(Option, flatten)
diff --git a/src/sexpr/variant.hpp b/src/sexpr/variant.hpp
index fbf9345..ecf0237 100644
--- a/src/sexpr/variant.hpp
+++ b/src/sexpr/variant.hpp
@@ -23,6 +23,8 @@
#include <cstddef>
#include <utility>
+#include "../compat/attr.hpp"
+
#include "union.hpp"
#include "void.hpp"
@@ -33,11 +35,6 @@ namespace tmwa
{
namespace sexpr
{
-#define JOIN(a, b) a##b
-
-#define WITH_VAR(ty, var, expr) \
- for (bool JOIN(var, _guard) = true; JOIN(var, _guard); ) \
- for (ty var = expr; JOIN(var, _guard); JOIN(var, _guard) = false)
#define MATCH(expr) \
WITH_VAR(auto&&, _match_var, expr) \
switch (tmwa::sexpr::VariantFriend::get_state(_match_var))