mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:28:25 +00:00
An accidental copy would cause an extra save/restore. This is meant as an RAII object to denote a save for a given scope. Also disallow move so we don't need to add branches to the dtor.
52 lines
1.5 KiB
C++
52 lines
1.5 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#ifndef CARBON_COMMON_CHECKED_SAVE_AND_RESTORE_H_
|
|
#define CARBON_COMMON_CHECKED_SAVE_AND_RESTORE_H_
|
|
|
|
#include <utility>
|
|
|
|
#include "common/check.h"
|
|
|
|
namespace Carbon {
|
|
|
|
// Sets a variable to a new value, and restores the original value when
|
|
// the CheckedSaveAndRestore is destroyed. CHECKs that the variable is still
|
|
// holding the new value when restoring the original value, to catch any data
|
|
// loss.
|
|
//
|
|
// The value must be copyable in order to compare with the new value at the time
|
|
// the CheckedSaveAndRestore is destroyed.
|
|
template <typename T>
|
|
class [[nodiscard]] CheckedSaveAndRestore {
|
|
public:
|
|
CheckedSaveAndRestore(T& var, const T& new_value)
|
|
: var_(&var),
|
|
new_value_(new_value),
|
|
orig_value_(std::exchange(var, new_value_)) {}
|
|
|
|
~CheckedSaveAndRestore() {
|
|
CARBON_CHECK(*var_ == new_value_);
|
|
*var_ = std::move(orig_value_);
|
|
}
|
|
|
|
CheckedSaveAndRestore(const CheckedSaveAndRestore&) = delete;
|
|
auto operator=(const CheckedSaveAndRestore&)
|
|
-> CheckedSaveAndRestore& = delete;
|
|
|
|
private:
|
|
T* var_;
|
|
T new_value_;
|
|
T orig_value_;
|
|
};
|
|
|
|
template <typename T>
|
|
CheckedSaveAndRestore(T&, const T&) -> CheckedSaveAndRestore<T>;
|
|
template <typename T>
|
|
CheckedSaveAndRestore(T&, T&&) -> CheckedSaveAndRestore<T>;
|
|
|
|
} // namespace Carbon
|
|
|
|
#endif // CARBON_COMMON_CHECKED_SAVE_AND_RESTORE_H_
|