LeechCraft 0.6.70-14794-g33744ae6ce
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 namespace detail
52 {
54 }
55
56 template<typename FinallyFunc, typename... Args>
57 class Visitor
58 {
59 detail::VisitorBase<Args...> Base_;
60
61 FinallyFunc Finally_;
62 public:
63 Visitor (Args&&... args)
64 : Base_ { std::forward<Args> (args)... }
65 {
66 }
67
68 Visitor (const detail::VisitorFinallyTag&, Args&&... args, FinallyFunc&& func)
69 : Base_ { std::forward<Args> (args)... }
70 , Finally_ { std::forward<FinallyFunc> (func) }
71 {
72 }
73
74 template<typename T>
75 decltype (auto) operator() (const T& var) const
76 {
77 if constexpr (std::is_same_v<FinallyFunc, Void>)
78 return Visit (var, Base_);
79 else
80 {
81 const auto guard = MakeScopeGuard (Finally_);
82 return Visit (var, Base_);
83 }
84 }
85
86 template<typename F>
87 Visitor<F, detail::VisitorBase<Args...>> Finally (F&& func)
88 {
89 return { detail::VisitorFinallyTag {}, std::move (Base_), std::forward<F> (func) };
90 }
91 };
92
93 template<typename... Args>
94 Visitor (Args&&...) -> Visitor<Void, Args...>;
95
96 template<typename T, typename... Args>
97 auto InvokeOn (T&& t, Args&&... args)
98 {
99 return detail::VisitorBase<Args...> { std::forward<Args> (args)... } (std::forward<T> (t));
100 }
101}
102}
Visitor(Args &&... args)
Definition: visitor.h:63
Visitor< F, detail::VisitorBase< Args... > > Finally(F &&func)
Definition: visitor.h:87
Visitor(const detail::VisitorFinallyTag &, Args &&... args, FinallyFunc &&func)
Definition: visitor.h:68
detail::ScopeGuard< F > MakeScopeGuard(const F &f)
Returns an object performing passed function on scope exit.
Definition: util.h:136
auto InvokeOn(T &&t, Args &&... args)
Definition: visitor.h:97
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition: either.h:200
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