Skip to content

Commit

Permalink
Merge pull request #200 from asa/asa_constexpr_match
Browse files Browse the repository at this point in the history
make match constexpr
  • Loading branch information
arximboldi authored Feb 21, 2024
2 parents 53dfad0 + b11f8ca commit f17194a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
1 change: 1 addition & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ cc_library(
"@boost//:intrusive_ptr",
"@zug//:zug",
"@cereal//:cereal",
"@immer",
],
includes = [".", "lager/"],
visibility = ["//visibility:public"],
Expand Down
15 changes: 9 additions & 6 deletions lager/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ template <typename TupleT>
struct matcher : TupleT
{
template <typename... Visitors>
decltype(auto) operator()(Visitors&&... vs) &&
constexpr decltype(auto) operator()(Visitors&&... vs) &&
{
return std::apply(
[&](auto&&... xs) {
Expand All @@ -70,7 +70,7 @@ template <typename T>
matcher(T) -> matcher<T>;

template <typename... Ts>
decltype(auto) as_variant(std::variant<Ts...> const& x)
constexpr decltype(auto) as_variant(std::variant<Ts...> const& x)
{
return x;
}
Expand Down Expand Up @@ -109,15 +109,17 @@ constexpr bool is_variant_v = is_variant<T>::value;
* value is forwarded as a variant.
*/
template <typename T>
auto forward_variant(typename std::remove_reference<T>::type& v) noexcept
constexpr auto
forward_variant(typename std::remove_reference<T>::type& v) noexcept
-> std::enable_if_t<is_variant_v<T>,
zug::detail::copy_decay_t<T, get_variant_t<T>>&&>
{
return std::forward<T>(v);
}

template <typename T>
auto forward_variant(typename std::remove_reference<T>::type& v) noexcept
constexpr auto
forward_variant(typename std::remove_reference<T>::type& v) noexcept
-> std::enable_if_t<!is_variant_v<T>, T&&>
{
static_assert(is_variant<T>::value,
Expand Down Expand Up @@ -147,7 +149,7 @@ auto forward_variant(typename std::remove_reference<T>::type& v) noexcept
* @endcode
*/
template <typename... Variants>
auto match(Variants&&... vs)
constexpr auto match(Variants&&... vs)
{
return detail::matcher{
std::forward_as_tuple(forward_variant<Variants>(vs)...)};
Expand All @@ -158,7 +160,8 @@ ZUG_INLINE_CONSTEXPR struct noop_t
{
template <typename... T>
void operator()(T&&...) const
{}
{
}
} noop{};

//! Function that returns its first arguemnt
Expand Down
24 changes: 24 additions & 0 deletions test/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, float, double>;
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);
}

0 comments on commit f17194a

Please sign in to comment.