AsmGrader 0.0.0
Loading...
Searching...
No Matches
tuple_matcher.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <boost/mp11/algorithm.hpp>
4#include <boost/mp11/detail/mp_rename.hpp>
5
6#include <concepts>
7#include <cstring>
8#include <functional>
9#include <optional>
10#include <string_view>
11#include <tuple>
12#include <type_traits>
13#include <utility>
14#include <variant>
15
16namespace asmgrader {
17
18namespace detail {
19
20template <typename Ret, typename Func, typename T, typename... Ts>
21constexpr Ret tuple_find_first_impl(Func&& pred, const T& val, const Ts&... rest) {
22 if (std::invoke(std::forward<Func>(pred), val)) {
23 return Ret{std::in_place, val};
24 }
25
26 if constexpr (sizeof...(Ts) > 0) {
27 return tuple_find_first_impl<Ret>(std::forward<Func>(pred), rest...);
28 }
29
30 return std::nullopt;
31}
32
33} // namespace detail
34
35template <typename Func, typename Tuple>
36constexpr auto tuple_find_first(Func&& pred, const Tuple& val) {
37 using VariantT = boost::mp11::mp_rename<boost::mp11::mp_unique<Tuple>, std::variant>;
38 using Ret = std::optional<VariantT>;
39
40 if constexpr (std::tuple_size_v<Tuple> == 0) {
41 return Ret{std::nullopt};
42 } else {
43 return std::apply(
44 [&pred](const auto&... elems) {
45 return detail::tuple_find_first_impl<Ret>(std::forward<Func>(pred), elems...);
46 },
47 val);
48 }
49}
50
51} // namespace asmgrader
constexpr Ret tuple_find_first_impl(Func &&pred, const T &val, const Ts &... rest)
Definition tuple_matcher.hpp:21
Definition asm_buffer.hpp:19
constexpr auto tuple_find_first(Func &&pred, const Tuple &val)
Definition tuple_matcher.hpp:36