Warning: This file is not a C or C++ file. It does not have highlighting.
1 | //===-- include/flang/Common/restorer.h -------------------------*- C++ -*-===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // Utility: before overwriting a variable, capture its value and |
10 | // ensure that it will be restored when the Restorer goes out of scope. |
11 | // |
12 | // int x{3}; |
13 | // { |
14 | // auto save{common::ScopedSet(x, 4)}; |
15 | // // x is now 4 |
16 | // } |
17 | // // x is back to 3 |
18 | |
19 | #ifndef FORTRAN_COMMON_RESTORER_H_ |
20 | #define FORTRAN_COMMON_RESTORER_H_ |
21 | #include "idioms.h" |
22 | #include "flang/Common/api-attrs.h" |
23 | namespace Fortran::common { |
24 | template <typename A> class Restorer { |
25 | public: |
26 | explicit RT_API_ATTRS Restorer(A &p, A original) |
27 | : p_{p}, original_{std::move(original)} {} |
28 | RT_API_ATTRS ~Restorer() { p_ = std::move(original_); } |
29 | |
30 | // Inhibit any recreation of this restorer that would result in two restorers |
31 | // trying to restore the same reference. |
32 | Restorer(const Restorer &) = delete; |
33 | Restorer(Restorer &&that) = delete; |
34 | const Restorer &operator=(const Restorer &) = delete; |
35 | const Restorer &operator=(Restorer &&that) = delete; |
36 | |
37 | private: |
38 | A &p_; |
39 | A original_; |
40 | }; |
41 | |
42 | template <typename A, typename B> |
43 | RT_API_ATTRS common::IfNoLvalue<Restorer<A>, B> ScopedSet(A &to, B &&from) { |
44 | A original{std::move(to)}; |
45 | to = std::move(from); |
46 | return Restorer<A>{to, std::move(original)}; |
47 | } |
48 | template <typename A, typename B> |
49 | RT_API_ATTRS common::IfNoLvalue<Restorer<A>, B> ScopedSet( |
50 | A &to, const B &from) { |
51 | A original{std::move(to)}; |
52 | to = from; |
53 | return Restorer<A>{to, std::move(original)}; |
54 | } |
55 | } // namespace Fortran::common |
56 | #endif // FORTRAN_COMMON_RESTORER_H_ |
57 |
Warning: This file is not a C or C++ file. It does not have highlighting.