File: visit.hpp

package info (click to toggle)
reflect-cpp 0.18.0%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 12,524 kB
  • sloc: cpp: 44,484; python: 131; makefile: 30; sh: 3
file content (49 lines) | stat: -rw-r--r-- 1,547 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef RFL_VISIT_HPP_
#define RFL_VISIT_HPP_

#include <utility>

#include "Literal.hpp"
#include "TaggedUnion.hpp"
#include "internal/StringLiteral.hpp"
#include "internal/VisitTree.hpp"
#include "internal/VisitorWrapper.hpp"

namespace rfl {

template <class Visitor, internal::StringLiteral... _fields, class... Args>
inline auto visit(const Visitor& _visitor, const Literal<_fields...> _literal,
                  const Args&... _args) {
  constexpr int size = sizeof...(_fields);
  using WrapperType = internal::VisitorWrapper<Visitor, _fields...>;
  const auto wrapper = WrapperType{&_visitor};
  return internal::VisitTree::visit<0, size, WrapperType>(
      wrapper, _literal.value(), _args...);
}

template <class F, VariantBased V>
inline auto visit(F&& _f, V&& _v)
    -> decltype(std::declval<V&&>().visit(std::declval<F&&>())) {
  return std::forward<V>(_v).visit(std::forward<F>(_f));
}

template <class F, TaggedUnionBased T>
inline auto visit(F&& _f, T&& _tagged_union)
    -> decltype(std::declval<T&&>().variant().visit(std::declval<F&&>())) {
  return std::forward<T>(_tagged_union).variant().visit(std::forward<F>(_f));
}

template <class F, class Head, class... Tail>
inline auto visit(F&& _f, Head&& _head, Tail&&... _tail) {
  const auto f_outer = [&](auto& _h) {
    const auto f_inner = [&](auto&... _t) {
      return std::forward<F>(_f)(_h, _t...);
    };
    return visit(f_inner, std::forward<Tail>(_tail)...);
  };
  return std::forward<Head>(_head).visit(f_outer);
}

}  // namespace rfl

#endif  // RFL_VISIT_HPP_