Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2024 Project CHIP Authors 4 : * All rights reserved. 5 : * 6 : * Licensed under the Apache License, Version 2.0 (the "License"); 7 : * you may not use this file except in compliance with the License. 8 : * You may obtain a copy of the License at 9 : * 10 : * http://www.apache.org/licenses/LICENSE-2.0 11 : * 12 : * Unless required by applicable law or agreed to in writing, software 13 : * distributed under the License is distributed on an "AS IS" BASIS, 14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 : * See the License for the specific language governing permissions and 16 : * limitations under the License. 17 : */ 18 : #pragma once 19 : 20 : namespace chip { 21 : 22 : template <typename T> 23 : class ScopedChange; 24 : 25 : /// Allows a value to only be changed within a scope. 26 : /// 27 : /// Generally used to force determinism for unit test execution. 28 : /// 29 : /// When a variable of this type is used, it should 30 : /// only be changed via `ScopedChange`. 31 : template <typename T> 32 : class ScopedChangeOnly 33 : { 34 : public: 35 49 : explicit ScopedChangeOnly(T initial) : mValue(initial) {} 36 0 : operator T() const { return mValue; } 37 : 38 : private: 39 : T mValue; 40 : 41 : // Expected to be used only by ScopedChange<T> only 42 : T & InternalMutableValue() { return mValue; } 43 : friend class ScopedChange<T>; 44 : }; 45 : 46 : /// Allows a scoped mutation to occur on a variable. 47 : /// 48 : /// When an instance of this class goes out of scope, the variable 49 : /// will be reset to the default. 50 : /// 51 : /// Example usage 52 : /// 53 : /// int a = 123; 54 : /// ScopedChangeOnly b(234); 55 : /// 56 : /// /* a == 123, b == 234 */ 57 : /// { 58 : /// ScopedChange changeA(a, 321); 59 : /// /* a == 321, b == 234 */ 60 : /// { 61 : /// ScopedChange changeB(b, 10); 62 : /// /* a == 321, b == 10 */ 63 : /// } 64 : /// /* a == 321, b == 234 */ 65 : /// } 66 : /// /* a == 123, b == 234 */ 67 : /// 68 : template <typename T> 69 : class ScopedChange 70 : { 71 : public: 72 : ScopedChange(ScopedChangeOnly<T> & what, T value) : mValue(what.InternalMutableValue()), mOriginal(what) { mValue = value; } 73 : ScopedChange(T & what, T value) : mValue(what), mOriginal(what) { mValue = value; } 74 : ~ScopedChange() { mValue = mOriginal; } 75 : 76 : private: 77 : T & mValue; 78 : T mOriginal; 79 : }; 80 : 81 : } // namespace chip