LeechCraft 0.6.70-16373-g319c272718
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 "void.h"
13#include "util.h"
14
15namespace LC
16{
17namespace Util
18{
19 namespace detail
20 {
21 template<typename... Bases>
22 struct VisitorBase : std::decay_t<Bases>...
23 {
24 VisitorBase (Bases&&... bases)
25 : std::decay_t<Bases> { std::forward<Bases> (bases) }...
26 {
27 }
28
29 using std::decay_t<Bases>::operator()...;
30 };
31
32 template<class... Ts> struct Overloaded : Ts...
33 {
34 using Ts::operator()...;
35 };
36 template<class... Ts> Overloaded (Ts...) -> Overloaded<Ts...>;
37 }
38
39 template<typename... Vars, typename... Args>
40 decltype (auto) Visit (const std::variant<Vars...>& v, Args&&... args)
41 {
42 return std::visit (detail::Overloaded { std::forward<Args> (args)... }, v);
43 }
44
45 template<typename... Vars, typename... Args>
46 decltype (auto) Visit (std::variant<Vars...>& v, Args&&... args)
47 {
48 return std::visit (detail::Overloaded { std::forward<Args> (args)... }, v);
49 }
50
51 template<typename... Vars, typename... Args>
52 decltype (auto) Visit (std::variant<Vars...>&& v, Args&&... args)
53 {
54 return std::visit (detail::Overloaded { std::forward<Args> (args)... }, std::move (v));
55 }
56
57 namespace detail
58 {
60 }
61
62 template<typename FinallyFunc, typename... Args>
63 class Visitor
64 {
65 detail::VisitorBase<Args...> Base_;
66
67 FinallyFunc Finally_;
68 public:
69 Visitor (Args&&... args)
70 : Base_ { std::forward<Args> (args)... }
71 {
72 }
73
74 Visitor (detail::VisitorFinallyTag, Args&&... args, FinallyFunc&& func)
75 : Base_ { std::forward<Args> (args)... }
76 , Finally_ { std::forward<FinallyFunc> (func) }
77 {
78 }
79
80 template<typename T>
81 decltype (auto) operator() (const T& var) const
82 {
83 if constexpr (std::is_same_v<FinallyFunc, Void>)
84 return Visit (var, Base_);
85 else
86 {
87 const auto guard = MakeScopeGuard (Finally_);
88 return Visit (var, Base_);
89 }
90 }
91
92 template<typename F>
93 Visitor<F, detail::VisitorBase<Args...>> Finally (F&& func)
94 {
95 return { detail::VisitorFinallyTag {}, std::move (Base_), std::forward<F> (func) };
96 }
97 };
98
99 template<typename... Args>
100 Visitor (Args&&...) -> Visitor<Void, Args...>;
101
102 template<typename T, typename... Args>
103 auto InvokeOn (T&& t, Args&&... args)
104 {
105 return detail::VisitorBase<Args...> { std::forward<Args> (args)... } (std::forward<T> (t));
106 }
107}
108}
Visitor(Args &&... args)
Definition visitor.h:69
Visitor(detail::VisitorFinallyTag, Args &&... args, FinallyFunc &&func)
Definition visitor.h:74
decltype(auto) operator()(const T &var) const
Definition visitor.h:81
Visitor< F, detail::VisitorBase< Args... > > Finally(F &&func)
Definition visitor.h:93
Overloaded(Ts...) -> Overloaded< Ts... >
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:103
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition either.h:215
Visitor(Args &&...) -> Visitor< Void, Args... >
Definition constants.h:15
STL namespace.
A proper void type, akin to unit (or ()) type in functional languages.
Definition void.h:21
VisitorBase(Bases &&... bases)
Definition visitor.h:24