Last active
December 25, 2015 18:49
-
-
Save tueda/7022822 to your computer and use it in GitHub Desktop.
Let a variable to a value temporarily.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This snippet uses C++11 features. For C++03, see the previous revision. | |
* | |
* Replace idioms like | |
* | |
* struct Foo { | |
* int a; | |
* }; | |
* | |
* void func(Foo *f) { | |
* int save_a = f->a; | |
* f->a = 1; | |
* // other stuff | |
* f->a = save_a; | |
* } | |
* | |
* with | |
* | |
* void func(Foo *f) { | |
* scoped_save(f->a, 1); | |
* // other stuff | |
* } | |
* | |
* pros: | |
* - Simplifies the code in case there are many returns. | |
* - Easily enhances exception safety. | |
*/ | |
/** | |
* scoped_save(x) saves the current value of x. The value of x will be restored | |
* at the end of the scope. | |
* | |
* scoped_save(x, a) saves the current value of x and sets x = a. The value of | |
* x will be restored at the end of the scope. | |
*/ | |
#define scoped_save(...) \ | |
scoped_save_class<decltype(scoped_save_first(__VA_ARGS__))> \ | |
scoped_save_concat(scoped_save_var_, __LINE__)(__VA_ARGS__) | |
#define scoped_save_first(...) scoped_save_first2(__VA_ARGS__, x) | |
#define scoped_save_first2(first, ...) first | |
#define scoped_save_concat(a, b) scoped_save_concat2(a, b) | |
#define scoped_save_concat2(a, b) a ## b | |
template <typename T> class scoped_save_class { | |
public: | |
scoped_save_class(T &ref) : ref_(ref), old_value_(ref) {} | |
scoped_save_class(T &ref, const T &value) : ref_(ref), old_value_(ref) { | |
ref = value; | |
} | |
~scoped_save_class() { | |
ref_ = old_value_; | |
} | |
private: | |
T &ref_; | |
T old_value_; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment