#include <iostream>
#include <tuple>
namespace
{
template<typename T>
using identity = T;
template<typename T, typename... V>
struct RAII_Set_impl
{
T &t;
std::tuple<identity<V T::*>...> mop;
std::tuple<V...> ds;
RAII_Set_impl(T &t_, std::tuple<V T::*, V, V>... sets)
: t(t_)
, mop(std::get<0>(sets)...)
, ds(std::get<2>(sets)...)
{
set(std::get<1>(sets)...);
}
~RAII_Set_impl()
{
unset(typename gens<sizeof...(V)>::type());
}
template<typename... U>
void set(U... u)
{
do_set<0, U...>(u...);
}
template<std::size_t i, typename First, typename... Rest>
void do_set(First first, Rest... rest)
{
t.*std::get<i>(mop) = first;
do_set<i+1, Rest...>(rest...);
}
template<std::size_t i, typename Last>
void do_set(Last last)
{
t.*std::get<i>(mop) = last;
}
template<std::size_t i>
void do_set()
{
}
template<std::size_t...> struct seq{};
template<std::size_t N, std::size_t... S>
struct gens : gens<N-1, N-1, S...> {};
template<std::size_t... S>
struct gens<0, S...>
{
using type = seq<S...>;
};
template<std::size_t... S>
void unset(seq<S...>)
{
set(std::get<S>(ds)...);
}
};
template<typename T, typename... V>
auto RAII_Set(T &t, std::tuple<V T::*, V, V>... sets)
-> RAII_Set_impl<T, V...>
{
return RAII_Set_impl<T, V...>(t, sets...);
}
}
struct Test
{
int x, y;
double z;
~Test()
{
std::cout << "x = " << x << std::endl
<< "y = " << y << std::endl
<< "z = " << z << std::endl;
}
} t;
int main()
{
auto raii_set_t = RAII_Set(t,
std::make_tuple(&Test::x, 1, 2),
std::make_tuple(&Test::y, 3, 4),
std::make_tuple(&Test::z, 5.5, 6.6)
);
std::cout << "x = " << t.x << std::endl
<< "y = " << t.y << std::endl
<< "z = " << t.z << std::endl;
std::cout << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+CgpuYW1lc3BhY2UKewoJdGVtcGxhdGU8dHlwZW5hbWUgVD4KCXVzaW5nIGlkZW50aXR5ID0gVDsKCgl0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBWPgoJc3RydWN0IFJBSUlfU2V0X2ltcGwKCXsKCQlUICZ0OwoJCXN0ZDo6dHVwbGU8aWRlbnRpdHk8ViBUOjoqPi4uLj4gbW9wOwoJCXN0ZDo6dHVwbGU8Vi4uLj4gZHM7CgkJUkFJSV9TZXRfaW1wbChUICZ0Xywgc3RkOjp0dXBsZTxWIFQ6OiosIFYsIFY+Li4uIHNldHMpCgkJOiB0KHRfKQoJCSwgbW9wKHN0ZDo6Z2V0PDA+KHNldHMpLi4uKQoJCSwgZHMoc3RkOjpnZXQ8Mj4oc2V0cykuLi4pCgkJewoJCQlzZXQoc3RkOjpnZXQ8MT4oc2V0cykuLi4pOwoJCX0KCQl+UkFJSV9TZXRfaW1wbCgpCgkJewoJCQl1bnNldCh0eXBlbmFtZSBnZW5zPHNpemVvZi4uLihWKT46OnR5cGUoKSk7CgkJfQoJCXRlbXBsYXRlPHR5cGVuYW1lLi4uIFU+CgkJdm9pZCBzZXQoVS4uLiB1KQoJCXsKCQkJZG9fc2V0PDAsIFUuLi4+KHUuLi4pOwoJCX0KCQl0ZW1wbGF0ZTxzdGQ6OnNpemVfdCBpLCB0eXBlbmFtZSBGaXJzdCwgdHlwZW5hbWUuLi4gUmVzdD4KCQl2b2lkIGRvX3NldChGaXJzdCBmaXJzdCwgUmVzdC4uLiByZXN0KQoJCXsKCQkJdC4qc3RkOjpnZXQ8aT4obW9wKSA9IGZpcnN0OwoJCQlkb19zZXQ8aSsxLCBSZXN0Li4uPihyZXN0Li4uKTsKCQl9CgkJdGVtcGxhdGU8c3RkOjpzaXplX3QgaSwgdHlwZW5hbWUgTGFzdD4KCQl2b2lkIGRvX3NldChMYXN0IGxhc3QpCgkJewoJCQl0LipzdGQ6OmdldDxpPihtb3ApID0gbGFzdDsKCQl9CgkJdGVtcGxhdGU8c3RkOjpzaXplX3QgaT4KCQl2b2lkIGRvX3NldCgpCgkJewoJCX0KCQl0ZW1wbGF0ZTxzdGQ6OnNpemVfdC4uLj4gc3RydWN0IHNlcXt9OwoJCXRlbXBsYXRlPHN0ZDo6c2l6ZV90IE4sIHN0ZDo6c2l6ZV90Li4uIFM+CgkJc3RydWN0IGdlbnMgOiBnZW5zPE4tMSwgTi0xLCBTLi4uPiB7fTsKCQl0ZW1wbGF0ZTxzdGQ6OnNpemVfdC4uLiBTPgoJCXN0cnVjdCBnZW5zPDAsIFMuLi4+CgkJewoJCQl1c2luZyB0eXBlID0gc2VxPFMuLi4+OwoJCX07CgkJdGVtcGxhdGU8c3RkOjpzaXplX3QuLi4gUz4KCQl2b2lkIHVuc2V0KHNlcTxTLi4uPikKCQl7CgkJCXNldChzdGQ6OmdldDxTPihkcykuLi4pOwoJCX0KCX07Cgl0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBWPgoJYXV0byBSQUlJX1NldChUICZ0LCBzdGQ6OnR1cGxlPFYgVDo6KiwgViwgVj4uLi4gc2V0cykKCS0+IFJBSUlfU2V0X2ltcGw8VCwgVi4uLj4KCXsKCQlyZXR1cm4gUkFJSV9TZXRfaW1wbDxULCBWLi4uPih0LCBzZXRzLi4uKTsKCX0KfQoKc3RydWN0IFRlc3QKewoJaW50IHgsIHk7Cglkb3VibGUgejsKCX5UZXN0KCkKCXsKCQlzdGQ6OmNvdXQgPDwgInggPSAiIDw8IHggPDwgc3RkOjplbmRsCgkJICAgICAgICAgIDw8ICJ5ID0gIiA8PCB5IDw8IHN0ZDo6ZW5kbAoJCSAgICAgICAgICA8PCAieiA9ICIgPDwgeiA8PCBzdGQ6OmVuZGw7Cgl9Cn0gdDsKCmludCBtYWluKCkKewoJYXV0byByYWlpX3NldF90ID0gUkFJSV9TZXQodCwKCQlzdGQ6Om1ha2VfdHVwbGUoJlRlc3Q6OngsIDEsIDIpLAoJCXN0ZDo6bWFrZV90dXBsZSgmVGVzdDo6eSwgMywgNCksCgkJc3RkOjptYWtlX3R1cGxlKCZUZXN0Ojp6LCA1LjUsIDYuNikKCSk7CglzdGQ6OmNvdXQgPDwgInggPSAiIDw8IHQueCA8PCBzdGQ6OmVuZGwKCSAgICAgICAgICA8PCAieSA9ICIgPDwgdC55IDw8IHN0ZDo6ZW5kbAoJICAgICAgICAgIDw8ICJ6ID0gIiA8PCB0LnogPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKfQo=