• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 // Copyright 2021 The Tint Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef SRC_UTILS_SCOPED_ASSIGNMENT_H_
17 #define SRC_UTILS_SCOPED_ASSIGNMENT_H_
18 
19 #include <type_traits>
20 
21 #include "src/utils/concat.h"
22 
23 namespace tint {
24 namespace utils {
25 
26 /// Helper class that temporarily assigns a value to a variable for the lifetime
27 /// of the ScopedAssignment object. Once the ScopedAssignment is destructed, the
28 /// original value is restored.
29 template <typename T>
30 class ScopedAssignment {
31  public:
32   /// Constructor
33   /// @param var the variable to temporarily assign a new value to
34   /// @param val the value to assign to `ref` for the lifetime of this
35   /// ScopedAssignment.
ScopedAssignment(T & var,T val)36   ScopedAssignment(T& var, T val) : ref_(var) {
37     old_value_ = var;
38     var = val;
39   }
40 
41   /// Destructor
42   /// Restores the original value of the variable.
~ScopedAssignment()43   ~ScopedAssignment() { ref_ = old_value_; }
44 
45  private:
46   ScopedAssignment(const ScopedAssignment&) = delete;
47   ScopedAssignment& operator=(const ScopedAssignment&) = delete;
48 
49   T& ref_;
50   T old_value_;
51 };
52 
53 }  // namespace utils
54 }  // namespace tint
55 
56 /// TINT_SCOPED_ASSIGNMENT(var, val) assigns `val` to `var`, and automatically
57 /// restores the original value of `var` when exiting the current lexical scope.
58 #define TINT_SCOPED_ASSIGNMENT(var, val)                                  \
59   ::tint::utils::ScopedAssignment<std::remove_reference_t<decltype(var)>> \
60   TINT_CONCAT(tint_scoped_assignment_, __COUNTER__) {                     \
61     var, val                                                              \
62   }
63 
64 #endif  //  SRC_UTILS_SCOPED_ASSIGNMENT_H_
65