LeechCraft  0.6.70-16373-g319c272718
Modular cross-platform feature rich live environment.
util.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 <memory>
12 #include <functional>
13 #include <stdexcept>
14 
15 namespace LC
16 {
17 namespace Util
18 {
19  namespace detail
20  {
21  using DefaultScopeGuardDeleter = std::function<void ()>;
22 
23  class [[nodiscard]] SharedScopeGuard
24  {
25  std::shared_ptr<void> Guard_;
26  public:
27  template<typename F>
28  SharedScopeGuard (const F& f)
29  : Guard_ { nullptr, [f] (void*) { f (); } }
30  {
31  }
32 
33  SharedScopeGuard () = delete;
34 
35  SharedScopeGuard (const SharedScopeGuard&) = default;
36  SharedScopeGuard (SharedScopeGuard&&) = default;
37 
38  SharedScopeGuard& operator= (const SharedScopeGuard&) = default;
39  SharedScopeGuard& operator= (SharedScopeGuard&&) = default;
40  };
41 
42  template<typename F>
43  class [[nodiscard]] ScopeGuard
44  {
45  F F_;
46  bool Perform_ = true;
47  public:
49  : F_ {}
50  , Perform_ { false }
51  {
52  }
53 
54  ScopeGuard (const F& f) noexcept
55  : F_ { f }
56  {
57  }
58 
59  template<typename F1, typename F2>
60  requires std::is_same_v<F, DefaultScopeGuardDeleter>
62  : F_
63  {
64  [f1 = std::move (g1.F_), p1 = g1.Perform_, f2 = std::move (g2.F_), p2 = g2.Perform_]
65  {
66  if (p1)
67  f1 ();
68  if (p2)
69  f2 ();
70  }
71  }
72  , Perform_ { g1.Perform_ || g2.Perform_ }
73  {
74  g1.Perform_ = false;
75  g2.Perform_ = false;
76  }
77 
78  ScopeGuard (const ScopeGuard&) = delete;
79  ScopeGuard& operator= (const ScopeGuard&) = delete;
80 
81  ScopeGuard& operator= (ScopeGuard&& other)
82  {
83  if (Perform_)
84  F_ ();
85 
86  F_ = other.F_;
87  Perform_ = other.Perform_;
88  other.Perform_ = false;
89  return *this;
90  }
91 
93  : F_ { other.F_ }
94  , Perform_ { other.Perform_ }
95  {
96  other.Perform_ = false;
97  }
98 
100  {
101  if (Perform_)
102  F_ ();
103  }
104 
106  {
107  Perform_ = false;
108  }
109 
111  {
112  Dismiss ();
114  }
115 
117  {
118  return EraseType ();
119  }
120 
122  {
123  if (!Perform_)
124  throw std::logic_error { "this scope guard has already been converted to a shared one" };
125 
126  Perform_ = false;
127  return { F_ };
128  }
129  };
130  }
131 
133 
154  template<typename F>
155  [[nodiscard]] detail::ScopeGuard<F> MakeScopeGuard (const F& f)
156  {
157  return { f };
158  }
159 }
160 }
void Dismiss() noexcept
Definition: util.h:105
ScopeGuard< DefaultScopeGuardDeleter > EraseType()
Definition: util.h:110
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition: oral.h:951
requires std::is_same_v< F, DefaultScopeGuardDeleter > ScopeGuard(ScopeGuard< F1 > &&g1, ScopeGuard< F2 > &&g2)
Definition: util.h:61
requires(Tup1Size==Tup2Size) const expr auto ZipWith(Tup1 &&tup1
ScopeGuard() noexcept
Definition: util.h:48
SharedScopeGuard Shared()
Definition: util.h:121
std::function< void()> DefaultScopeGuardDeleter
Definition: util.h:21
detail::ScopeGuard< F > MakeScopeGuard(const F &f)
Returns an object performing passed function on scope exit.
Definition: util.h:155
auto Tup2 &&tup2 noexcept
Definition: ctstringutils.h:41
ScopeGuard(const F &f) noexcept
Definition: util.h:54
ScopeGuard(ScopeGuard &&other) noexcept
Definition: util.h:92