Caffe2 - C++ API
A deep learning, cross platform ML framework
scope_guard.h
1 
6 #pragma once
7 
8 #include <cstddef>
9 #include <functional>
10 #include <new>
11 #include <type_traits>
12 #include <utility>
13 
14 namespace caffe2 {
15 
16 // Copied from folly/ScopeGuard.h
17 
18 namespace detail {
19 
21  public:
22  void dismiss() noexcept {
23  dismissed_ = true;
24  }
25 
26  protected:
27  ScopeGuardImplBase() noexcept : dismissed_(false) {}
28 
29  static ScopeGuardImplBase makeEmptyScopeGuard() noexcept {
30  return ScopeGuardImplBase{};
31  }
32 
33  template <typename T>
34  static const T& asConst(const T& t) noexcept {
35  return t;
36  }
37 
38  bool dismissed_;
39 };
40 
41 template <typename FunctionType>
43  public:
44  explicit ScopeGuardImpl(FunctionType& fn) noexcept(
45  std::is_nothrow_copy_constructible<FunctionType>::value)
47  asConst(fn),
48  makeFailsafe(std::is_nothrow_copy_constructible<FunctionType>{},
49  &fn)) {}
50 
51  explicit ScopeGuardImpl(const FunctionType& fn) noexcept(
52  std::is_nothrow_copy_constructible<FunctionType>::value)
54  fn,
55  makeFailsafe(std::is_nothrow_copy_constructible<FunctionType>{},
56  &fn)) {}
57 
58  explicit ScopeGuardImpl(FunctionType&& fn) noexcept(
59  std::is_nothrow_move_constructible<FunctionType>::value)
61  std::move_if_noexcept(fn),
62  makeFailsafe(std::is_nothrow_move_constructible<FunctionType>{},
63  &fn)) {}
64 
65  ScopeGuardImpl(ScopeGuardImpl&& other) noexcept(
66  std::is_nothrow_move_constructible<FunctionType>::value)
67  : function_(std::move_if_noexcept(other.function_)) {
68  // If the above line attempts a copy and the copy throws, other is
69  // left owning the cleanup action and will execute it (or not) depending
70  // on the value of other.dismissed_. The following lines only execute
71  // if the move/copy succeeded, in which case *this assumes ownership of
72  // the cleanup action and dismisses other.
73  dismissed_ = other.dismissed_;
74  other.dismissed_ = true;
75  }
76 
77  ~ScopeGuardImpl() noexcept {
78  if (!dismissed_) {
79  execute();
80  }
81  }
82 
83  private:
84  static ScopeGuardImplBase makeFailsafe(std::true_type, const void*) noexcept {
85  return makeEmptyScopeGuard();
86  }
87 
88  template <typename Fn>
89  static auto makeFailsafe(std::false_type, Fn* fn) noexcept
91  return ScopeGuardImpl<decltype(std::ref(*fn))>{std::ref(*fn)};
92  }
93 
94  template <typename Fn>
95  explicit ScopeGuardImpl(Fn&& fn, ScopeGuardImplBase&& failsafe)
96  : ScopeGuardImplBase{}, function_(std::forward<Fn>(fn)) {
97  failsafe.dismiss();
98  }
99 
100  void* operator new(std::size_t) = delete;
101 
102  void execute() noexcept { function_(); }
103 
104  FunctionType function_;
105 };
106 
107 template <typename F>
109 
110 } // namespace detail
111 
152 template <typename F>
154  noexcept(detail::ScopeGuardImplDecay<F>(static_cast<F&&>(f)))) {
155  return detail::ScopeGuardImplDecay<F>(static_cast<F&&>(f));
156 }
157 
158 } // namespaces
detail::ScopeGuardImplDecay< F > MakeGuard(F &&f) noexcept(noexcept(detail::ScopeGuardImplDecay< F >(static_cast< F && >(f))))
ScopeGuard is a general implementation of the "Initialization is Resource Acquisition" idiom...
Definition: scope_guard.h:153
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13