Kagome
Polkadot Runtime Engine in C++17
visitor.hpp
Go to the documentation of this file.
1 
6 #ifndef KAGOME_VISITOR_HPP
7 #define KAGOME_VISITOR_HPP
8 
9 #include <type_traits> // for std::decay
10 #include <utility> // for std::forward
11 
12 #include <boost/variant/apply_visitor.hpp> // for boost::apply_visitor
13 
14 namespace kagome {
15 
16  template <typename... Lambdas>
17  struct lambda_visitor;
18 
19  template <typename Lambda, typename... Lambdas>
20  struct lambda_visitor<Lambda, Lambdas...>
21  : public Lambda, public lambda_visitor<Lambdas...> {
22  using Lambda::operator();
23  using lambda_visitor<Lambdas...>::operator();
24 
25  // NOLINTNEXTLINE(google-explicit-constructor)
26  lambda_visitor(Lambda lambda, Lambdas... lambdas)
27  : Lambda(lambda), lambda_visitor<Lambdas...>(lambdas...) {}
28  };
29 
30  template <typename Lambda>
31  struct lambda_visitor<Lambda> : public Lambda {
32  using Lambda::operator();
33 
34  // NOLINTNEXTLINE(google-explicit-constructor)
35  lambda_visitor(Lambda lambda) : Lambda(lambda) {}
36  };
37 
59  template <class... Fs>
60  constexpr auto make_visitor(Fs &&...fs) {
61  using visitor_type = lambda_visitor<std::decay_t<Fs>...>;
62  return visitor_type(std::forward<Fs>(fs)...);
63  }
64 
80  template <typename TVariant, typename... TVisitors>
81  constexpr decltype(auto) visit_in_place(TVariant &&variant,
82  TVisitors &&...visitors) {
83  return boost::apply_visitor(
84  make_visitor(std::forward<TVisitors>(visitors)...),
85  std::forward<TVariant>(variant));
86  }
87 
89  template <typename T, typename Matcher>
90  constexpr decltype(auto) match(T &&t, Matcher &&m) {
91  return std::forward<T>(t) ? std::forward<Matcher>(m)(*std::forward<T>(t))
92  : std::forward<Matcher>(m)();
93  }
94 
96  template <typename T, typename... Fs>
97  constexpr decltype(auto) match_in_place(T &&t, Fs &&...fs) {
98  return match(std::forward<T>(t), make_visitor(std::forward<Fs>(fs)...));
99  }
100 } // namespace kagome
101 
102 #endif // KAGOME_VISITOR_HPP