Horizon
Loading...
Searching...
No Matches
scope_exit.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2017-present
5//
6// Use, modification and distribution is subject to the
7// Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//
11// Project home: https://github.com/ericniebler/range-v3
12//
13#ifndef RANGES_V3_UTILITY_SCOPE_EXIT_HPP
14#define RANGES_V3_UTILITY_SCOPE_EXIT_HPP
15
16#include <functional>
17#include <type_traits>
18#include <utility>
19
20#include <meta/meta.hpp>
21
22#include <range/v3/detail/prologue.hpp>
23
24namespace ranges
25{
26 template<typename Fun>
28 {
29 private:
30 using nothrow_move_t = std::is_nothrow_move_constructible<Fun>;
31 using nothrow_copy_t = std::is_nothrow_copy_constructible<Fun>;
32
33 Fun fun_;
34 bool dismissed_{false};
35
36 using ref_t = decltype(std::ref(std::declval<Fun const &>()));
38
39 scope_exit(Fun const & fun, guard && g)
40 : fun_(fun)
41 {
42 g.dismiss();
43 }
44
45 scope_exit(Fun const & fun, std::false_type)
46 : scope_exit(fun, guard{std::ref(fun)})
47 {}
48
49 scope_exit(Fun const & fun, std::true_type) noexcept
50 : fun_(fun)
51 {}
52
53 scope_exit(Fun && fun, std::true_type) noexcept
54 : fun_(std::move(fun))
55 {}
56
57 public:
58 explicit scope_exit(Fun const & fun) noexcept(
59 noexcept(scope_exit(fun, nothrow_copy_t{})))
60 : scope_exit(fun, nothrow_copy_t{})
61 {}
62
63 explicit scope_exit(Fun && fun) noexcept(noexcept(scope_exit(std::move(fun),
64 nothrow_move_t{})))
65 : scope_exit(std::move(fun), nothrow_move_t{})
66 {}
67
68 scope_exit(scope_exit const &) = delete;
69
70 scope_exit(scope_exit && that) noexcept(
71 std::is_nothrow_move_constructible<Fun>::value)
72 : scope_exit(std::move((that.dismiss(), that)).fun_)
73 {}
74
76 {
77 if(!dismissed_)
78 fun_();
79 }
80
81 void dismiss() noexcept
82 {
83 dismissed_ = true;
84 }
85 };
86
87 template<typename Fun, typename ScopeExit = scope_exit<meta::_t<std::decay<Fun>>>>
88 ScopeExit make_scope_exit(Fun && fun) noexcept(
89 noexcept(ScopeExit(ScopeExit((Fun &&) fun))))
90 {
91 return ScopeExit((Fun &&) fun);
92 }
93} // namespace ranges
94
95#include <range/v3/detail/epilogue.hpp>
96
97#endif
Tiny meta-programming library.
Definition scope_exit.hpp:28