Skip to content

Instantly share code, notes, and snippets.

@tueda
Last active December 25, 2015 18:49
Show Gist options
  • Save tueda/7022822 to your computer and use it in GitHub Desktop.
Save tueda/7022822 to your computer and use it in GitHub Desktop.
Let a variable to a value temporarily.
/*
* 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