• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 namespace Fortran::common {
23 template <typename A> class Restorer {
24 public:
Restorer(A & p)25   explicit Restorer(A &p) : p_{p}, original_{std::move(p)} {}
~Restorer()26   ~Restorer() { p_ = std::move(original_); }
27 
28 private:
29   A &p_;
30   A original_;
31 };
32 
33 template <typename A, typename B>
ScopedSet(A & to,B && from)34 common::IfNoLvalue<Restorer<A>, B> ScopedSet(A &to, B &&from) {
35   Restorer<A> result{to};
36   to = std::move(from);
37   return result;
38 }
39 template <typename A, typename B>
ScopedSet(A & to,const B & from)40 common::IfNoLvalue<Restorer<A>, B> ScopedSet(A &to, const B &from) {
41   Restorer<A> result{to};
42   to = from;
43   return result;
44 }
45 } // namespace Fortran::common
46 #endif // FORTRAN_COMMON_RESTORER_H_
47