LeechCraft 0.6.70-17793-g6e56308e78
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
visitor.h
Go to the documentation of this file.
1/**********************************************************************
2 * LeechCraft - modular cross-platform feature rich internet client.
3 * Copyright (C) 2006-2014 Georg Rudoy
4 *
5 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#pragma once
10
11#include <variant>
12#include "overloaded.h"
13#include "util.h"
14#include "void.h"
15
16namespace LC
17{
18namespace Util
19{
20 namespace detail
21 {
22 template<typename... Bases>
23 struct VisitorBase : std::decay_t<Bases>...
24 {
25 VisitorBase (Bases&&... bases)
26 : std::decay_t<Bases> { std::forward<Bases> (bases) }...
27 {
28 }
29
30 using std::decay_t<Bases>::operator()...;
31 };
32 }
33
34 template<typename... Vars, typename... Args>
35 decltype (auto) Visit (const std::variant<Vars...>& v, Args&&... args)
36 {
37 return std::visit (Overloaded { std::forward<Args> (args)... }, v);
38 }
39
40 template<typename... Vars, typename... Args>
41 decltype (auto) Visit (std::variant<Vars...>& v, Args&&... args)
42 {
43 return std::visit (Overloaded { std::forward<Args> (args)... }, v);
44 }
45
46 template<typename... Vars, typename... Args>
47 decltype (auto) Visit (std::variant<Vars...>&& v, Args&&... args)
48 {
49 return std::visit (Overloaded { std::forward<Args> (args)... }, std::move (v));
50 }
51
52 namespace detail
53 {
55 }
56
57 template<typename FinallyFunc, typename... Args>
58 class Visitor
59 {
60 detail::VisitorBase<Args...> Base_;
61
62 FinallyFunc Finally_;
63 public:
64 Visitor (Args&&... args)
65 : Base_ { std::forward<Args> (args)... }
66 {
67 }
68
69 Visitor (detail::VisitorFinallyTag, Args&&... args, FinallyFunc&& func)
70 : Base_ { std::forward<Args> (args)... }
71 , Finally_ { std::forward<FinallyFunc> (func) }
72 {
73 }
74
75 template<typename T>
76 decltype (auto) operator() (const T& var) const
77 {
78 if constexpr (std::is_same_v<FinallyFunc, Void>)
79 return Visit (var, Base_);
80 else
81 {
82 const auto guard = MakeScopeGuard (Finally_);
83 return Visit (var, Base_);
84 }
85 }
86
87 template<typename F>
88 Visitor<F, detail::VisitorBase<Args...>> Finally (F&& func)
89 {
90 return { detail::VisitorFinallyTag {}, std::move (Base_), std::forward<F> (func) };
91 }
92 };
93
94 template<typename... Args>
95 Visitor (Args&&...) -> Visitor<Void, Args...>;
96
97 template<typename T, typename... Args>
98 auto InvokeOn (T&& t, Args&&... args)
99 {
100 return detail::VisitorBase<Args...> { std::forward<Args> (args)... } (std::forward<T> (t));
101 }
102}
103}
Visitor(Args &&... args)
Definition visitor.h:64
Visitor(detail::VisitorFinallyTag, Args &&... args, FinallyFunc &&func)
Definition visitor.h:69
decltype(auto) operator()(const T &var) const
Definition visitor.h:76
Visitor< F, detail::VisitorBase< Args... > > Finally(F &&func)
Definition visitor.h:88
detail::ScopeGuard< F > MakeScopeGuard(const F &f)
Returns an object performing passed function on scope exit.
Definition util.h:155
auto InvokeOn(T &&t, Args &&... args)
Definition visitor.h:98
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition either.h:207
Visitor(Args &&...) -> Visitor< Void, Args... >
Definition constants.h:15
A proper void type, akin to unit (or ()) type in functional languages.
Definition void.h:21
VisitorBase(Bases &&... bases)
Definition visitor.h:25