diff --git a/BUILD b/BUILD index 90307081..ade01d7e 100644 --- a/BUILD +++ b/BUILD @@ -11,6 +11,7 @@ cc_library( "@boost//:intrusive_ptr", "@zug//:zug", "@cereal//:cereal", + "@immer", ], includes = [".", "lager/"], visibility = ["//visibility:public"], diff --git a/lager/util.hpp b/lager/util.hpp index d09339b8..7fe9f92c 100644 --- a/lager/util.hpp +++ b/lager/util.hpp @@ -55,7 +55,7 @@ template struct matcher : TupleT { template - decltype(auto) operator()(Visitors&&... vs) && + constexpr decltype(auto) operator()(Visitors&&... vs) && { return std::apply( [&](auto&&... xs) { @@ -70,7 +70,7 @@ template matcher(T) -> matcher; template -decltype(auto) as_variant(std::variant const& x) +constexpr decltype(auto) as_variant(std::variant const& x) { return x; } @@ -109,7 +109,8 @@ constexpr bool is_variant_v = is_variant::value; * value is forwarded as a variant. */ template -auto forward_variant(typename std::remove_reference::type& v) noexcept +constexpr auto +forward_variant(typename std::remove_reference::type& v) noexcept -> std::enable_if_t, zug::detail::copy_decay_t>&&> { @@ -117,7 +118,8 @@ auto forward_variant(typename std::remove_reference::type& v) noexcept } template -auto forward_variant(typename std::remove_reference::type& v) noexcept +constexpr auto +forward_variant(typename std::remove_reference::type& v) noexcept -> std::enable_if_t, T&&> { static_assert(is_variant::value, @@ -147,7 +149,7 @@ auto forward_variant(typename std::remove_reference::type& v) noexcept * @endcode */ template -auto match(Variants&&... vs) +constexpr auto match(Variants&&... vs) { return detail::matcher{ std::forward_as_tuple(forward_variant(vs)...)}; @@ -158,7 +160,8 @@ ZUG_INLINE_CONSTEXPR struct noop_t { template void operator()(T&&...) const - {} + { + } } noop{}; //! Function that returns its first arguemnt diff --git a/test/util.cpp b/test/util.cpp index 839e58e7..dbfca1fa 100644 --- a/test/util.cpp +++ b/test/util.cpp @@ -36,3 +36,27 @@ TEST_CASE("match deriv") auto y = lager::match(v)([](int x) { return x; }, [](auto) { return 0; }); CHECK(y == 42); } + +// only literal types can be used in a constexpr + +using literal_variant_t = std::variant; +struct literal_deriv_t : literal_variant_t +{ + using literal_variant_t::literal_variant_t; +}; + +TEST_CASE("match constexpr") +{ + constexpr auto v = literal_variant_t{42}; + constexpr auto y = + lager::match(v)([](int x) { return x; }, [](auto) { return 0; }); + CHECK(y == 42); +} + +TEST_CASE("match deriv constexpr ") +{ + constexpr auto v = literal_deriv_t{42}; + constexpr auto y = + lager::match(v)([](int x) { return x; }, [](auto) { return 0; }); + CHECK(y == 42); +}