Program Listing for File match.hpp
↰ Return to documentation for file (include/match.hpp
)
#pragma once
// ctql/match.hpp
#include <type_traits>
namespace ctql {
template <auto K, class T>
struct case_ {
static constexpr auto key = K;
using type = T;
};
template <class T>
struct default_ {
using type = T;
};
namespace detail {
// -------- matcher core (first-match wins; default if no match) --------
template <auto Key, class Default, bool Matched, class... Alts>
struct match_impl;
// End of list -> yield accumulated Default.
template <auto Key, class Default, bool Matched>
struct match_impl<Key, Default, Matched> {
using type = Default;
};
// case_ step: if not matched yet and Key == K, lock in T; otherwise keep going.
template <auto Key, class Default, bool Matched, auto K, class T, class... Rest>
struct match_impl<Key, Default, Matched, case_<K, T>, Rest...>
: match_impl<
Key,
std::conditional_t<!Matched && (Key == K), T, Default>,
(Matched || (Key == K)),
Rest...> { };
// default_ step: if not matched yet, update fallback; otherwise ignore.
template <auto Key, class Default, bool Matched, class T, class... Rest>
struct match_impl<Key, Default, Matched, default_<T>, Rest...>
: match_impl<Key, std::conditional_t<Matched, Default, T>, Matched, Rest...> { };
// Public interface wrapper.
template <auto Key, class... Alts>
struct match {
using type = typename match_impl<Key, void, false, Alts...>::type;
};
} // namespace detail
template <auto Key, class... Alts>
using match_t = typename detail::match<Key, Alts...>::type;
} // namespace ctql