LeechCraft  0.6.70-15082-g543737046d
Modular cross-platform feature rich live environment.
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 
15 namespace LC
16 {
17 namespace 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  {
53  struct VisitorFinallyTag {};
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 (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 }
void.h
LC::Util::detail::VisitorBase
Definition: visitor.h:40
util.h
LC::Util::Visit
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition: either.h:212
LC::Util::detail::Overloaded
Definition: visitor.h:50
LC::Util::Visitor::Finally
Visitor< F, detail::VisitorBase< Args... > > Finally(F &&func)
Definition: visitor.h:99
LC::Util::InvokeOn
auto InvokeOn(T &&t, Args &&... args)
Definition: visitor.h:109
LC::Util::detail::Overloaded
Overloaded(Ts...) -> Overloaded< Ts... >
LC::Util::MakeScopeGuard
detail::ScopeGuard< F > MakeScopeGuard(const F &f)
Returns an object performing passed function on scope exit.
Definition: util.h:148
LC
Definition: constants.h:14
LC::Util::detail::VisitorFinallyTag
Definition: visitor.h:65
LC::Util::Visitor::Visitor
Visitor(Args &&... args)
Definition: visitor.h:75
LC::Util::Visitor
Definition: visitor.h:69
LC::Util::Visitor
Visitor(Args &&...) -> Visitor< Void, Args... >
LC::Util::detail::VisitorBase::VisitorBase
VisitorBase(Bases &&... bases)
Definition: visitor.h:48