blob: 9d4e98baad88631a02cfb78bbfc22ca7f37bd12b [file] [log] [blame]
Ryan Harrisondbc13af2022-02-21 15:19:07 +00001
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
dan sinclair22b4dd22023-07-21 00:40:07 +000016#ifndef SRC_TINT_UTILS_MACROS_SCOPED_ASSIGNMENT_H_
17#define SRC_TINT_UTILS_MACROS_SCOPED_ASSIGNMENT_H_
Ryan Harrisondbc13af2022-02-21 15:19:07 +000018
19#include <type_traits>
20
dan sinclair22b4dd22023-07-21 00:40:07 +000021#include "src/tint/utils/macros/concat.h"
Ryan Harrisondbc13af2022-02-21 15:19:07 +000022
dan sinclairbae54e72023-07-28 15:01:54 +000023namespace tint {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000024
25/// Helper class that temporarily assigns a value to a variable for the lifetime
26/// of the ScopedAssignment object. Once the ScopedAssignment is destructed, the
27/// original value is restored.
28template <typename T>
29class ScopedAssignment {
dan sinclair41e4d9a2022-05-01 14:40:55 +000030 public:
31 /// Constructor
32 /// @param var the variable to temporarily assign a new value to
33 /// @param val the value to assign to `ref` for the lifetime of this
34 /// ScopedAssignment.
35 ScopedAssignment(T& var, T val) : ref_(var) {
36 old_value_ = var;
37 var = val;
38 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000039
dan sinclair41e4d9a2022-05-01 14:40:55 +000040 /// Destructor
41 /// Restores the original value of the variable.
42 ~ScopedAssignment() { ref_ = old_value_; }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000043
dan sinclair41e4d9a2022-05-01 14:40:55 +000044 private:
45 ScopedAssignment(const ScopedAssignment&) = delete;
46 ScopedAssignment& operator=(const ScopedAssignment&) = delete;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000047
dan sinclair41e4d9a2022-05-01 14:40:55 +000048 T& ref_;
49 T old_value_;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000050};
51
dan sinclairbae54e72023-07-28 15:01:54 +000052} // namespace tint
Ryan Harrisondbc13af2022-02-21 15:19:07 +000053
54/// TINT_SCOPED_ASSIGNMENT(var, val) assigns `val` to `var`, and automatically
55/// restores the original value of `var` when exiting the current lexical scope.
dan sinclairbae54e72023-07-28 15:01:54 +000056#define TINT_SCOPED_ASSIGNMENT(var, val) \
57 ::tint::ScopedAssignment<std::remove_reference_t<decltype(var)>> TINT_CONCAT( \
58 tint_scoped_assignment_, __COUNTER__) { \
59 var, val \
dan sinclair41e4d9a2022-05-01 14:40:55 +000060 }
Ryan Harrisondbc13af2022-02-21 15:19:07 +000061
dan sinclair22b4dd22023-07-21 00:40:07 +000062#endif // SRC_TINT_UTILS_MACROS_SCOPED_ASSIGNMENT_H_