Nugget
finally.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
6 // eastl::finally is an implementation of the popular cpp idiom RAII - Resource
7 // Acquisition Is Initialization. eastl::finally guarantees that the user
8 // provided callable will be executed upon whatever mechanism is used to leave
9 // the current scope. This can guard against user errors but this is a popular
10 // technique to write robust code in execution environments that have exceptions
11 // enabled.
12 //
13 // Example:
14 // void foo()
15 // {
16 // void* p = malloc(128);
17 // auto _ = eastl::make_finally([&] { free(p); });
18 //
19 // // Code that may throw an exception...
20 //
21 // } // eastl::finally guaranteed to call 'free' at scope exit.
22 //
23 // References:
24 // * https://www.bfilipek.com/2017/04/finalact.html
26 
27 #ifndef EASTL_FINALLY_H
28 #define EASTL_FINALLY_H
29 
30 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
31  #pragma once
32 #endif
33 
34 #include <EASTL/internal/config.h>
35 #include <EASTL/internal/move_help.h>
36 #include <EASTL/type_traits.h>
37 
38 namespace eastl
39 {
41  // finally
42  //
43  // finally is the type that calls the users callback on scope exit.
44  //
45  template <typename Functor>
46  class finally
47  {
48  static_assert(!eastl::is_lvalue_reference_v<Functor>, "eastl::finally requires the callable is passed as an rvalue reference.");
49 
50  Functor m_functor;
51  bool m_engaged = false;
52 
53  public:
54  finally(Functor f) : m_functor(eastl::move(f)), m_engaged(true) {}
55 
56  finally(finally&& other) : m_functor(eastl::move(other.m_functor)), m_engaged(other.m_engaged)
57  {
58  other.dismiss();
59  }
60 
61  ~finally() { execute(); }
62 
63  finally(const finally&) = delete;
64  finally& operator=(const finally&) = delete;
65  finally& operator=(finally&&) = delete;
66 
67  inline void dismiss() { m_engaged = false; }
68 
69  inline void execute()
70  {
71  if (m_engaged)
72  m_functor();
73 
74  dismiss();
75  }
76  };
77 
78 
80  // make_finally
81  //
82  // this utility function is the standard mechansim to perform the required
83  // type deduction on the users provided callback inorder to create a
84  // 'finally' object.
85  //
86  template <typename F>
87  auto make_finally(F&& f)
88  {
89  return finally<F>(eastl::forward<F>(f));
90  }
91 }
92 
93 #endif // EASTL_FINALLY_H
Definition: finally.h:47
EA Standard Template Library.
Definition: algorithm.h:288
OutputIterator move(InputIterator first, InputIterator last, OutputIterator result)
Definition: copy_help.h:170