#include <cstdio> // for printf.
#include <type_traits> // for is_reference, remove_reference.
#include <typeinfo> // for typeid.
template<typename T>
struct mutable_value
{
mutable_value(T val = 0) : val(val) { this->p_val = &this->val; }
auto get_value() const -> T & { return *this->p_val; }
private:
T val;
T *p_val;
};
template<typename T>
struct mutable_value_for_ref
{
typedef typename std::remove_reference<T>::type ref_dropped_t;
mutable_value_for_ref(T ref) : p_val{ &ref }
{
}
auto get_value() const -> ref_dropped_t &{ return *this->p_val; }
private:
ref_dropped_t *p_val;
};
template<typename T>
struct unko_meta
{
typedef
typename std::conditional
<
std::is_reference<T>::value,
mutable_value_for_ref<T>,
mutable_value<T>
>::type type;
};
template<typename T>
struct yakitori
{
yakitori(T t) : x(t) { }
auto get() const -> T & { return this->x.get_value(); }
typename unko_meta<T>::type x;
};
auto main() -> int
{
int i1 = 100;
yakitori<int> const v1{ i1 };
std::printf("--%s\n", typeid(v1.x).name());
v1.get()++;
std::printf("org:%d , yakitori:%d\n", i1, v1.get());
int i2 = 200;
int const &r2 = i2;
yakitori<int const> const v2{ r2 };
std::printf("--%s\n", typeid(v2.x).name());
i2++;
std::printf("org:%d , yakitori:%d\n", i2, v2.get());
int i3 = 300;
yakitori<int &> const v3{ i3 };
std::printf("--%s\n", typeid(v3.x).name());
v3.get()++;
std::printf("org:%d , yakitori:%d\n", i3, v3.get());
int i4 = 400;
int const &r4 = i4;
yakitori<int const &> const v4{ r4 };
std::printf("--%s\n", typeid(v4.x).name());
i4++;
std::printf("org:%d , yakitori:%d\n", i4, v4.get());
}
I2luY2x1ZGUgPGNzdGRpbz4JLy8gZm9yIHByaW50Zi4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgkvLyBmb3IgaXNfcmVmZXJlbmNlLCByZW1vdmVfcmVmZXJlbmNlLgojaW5jbHVkZSA8dHlwZWluZm8+CQkvLyBmb3IgdHlwZWlkLgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IG11dGFibGVfdmFsdWUKewoJbXV0YWJsZV92YWx1ZShUIHZhbCA9IDApIDogdmFsKHZhbCkgeyB0aGlzLT5wX3ZhbCA9ICZ0aGlzLT52YWw7IH0KCWF1dG8gZ2V0X3ZhbHVlKCkgY29uc3QgLT4gVCAmIHsgcmV0dXJuICp0aGlzLT5wX3ZhbDsgfQpwcml2YXRlOgoJVCB2YWw7CglUICpwX3ZhbDsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBtdXRhYmxlX3ZhbHVlX2Zvcl9yZWYKewoJdHlwZWRlZiB0eXBlbmFtZSBzdGQ6OnJlbW92ZV9yZWZlcmVuY2U8VD46OnR5cGUgcmVmX2Ryb3BwZWRfdDsKCgltdXRhYmxlX3ZhbHVlX2Zvcl9yZWYoVCByZWYpIDogcF92YWx7ICZyZWYgfQoJewoJfQoKCWF1dG8gZ2V0X3ZhbHVlKCkgY29uc3QgLT4gcmVmX2Ryb3BwZWRfdCAmeyByZXR1cm4gKnRoaXMtPnBfdmFsOyB9CnByaXZhdGU6CglyZWZfZHJvcHBlZF90ICpwX3ZhbDsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCB1bmtvX21ldGEKewoJdHlwZWRlZgoJdHlwZW5hbWUgc3RkOjpjb25kaXRpb25hbAoJPAoJCXN0ZDo6aXNfcmVmZXJlbmNlPFQ+Ojp2YWx1ZSwKCQltdXRhYmxlX3ZhbHVlX2Zvcl9yZWY8VD4sCgkJbXV0YWJsZV92YWx1ZTxUPgoJPjo6dHlwZSB0eXBlOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IHlha2l0b3JpCnsKCXlha2l0b3JpKFQgdCkgOiB4KHQpIHsgfQoKCWF1dG8gZ2V0KCkgY29uc3QgLT4gVCAmIHsgcmV0dXJuIHRoaXMtPnguZ2V0X3ZhbHVlKCk7IH0KCgl0eXBlbmFtZSB1bmtvX21ldGE8VD46OnR5cGUgeDsKfTsKCgphdXRvIG1haW4oKSAtPiBpbnQKewoJCWludCBpMSA9IDEwMDsKCQl5YWtpdG9yaTxpbnQ+IGNvbnN0IHYxeyBpMSB9OwoJCXN0ZDo6cHJpbnRmKCItLSVzXG4iLCB0eXBlaWQodjEueCkubmFtZSgpKTsKCQl2MS5nZXQoKSsrOwoJCXN0ZDo6cHJpbnRmKCJvcmc6JWQgLCAgeWFraXRvcmk6JWRcbiIsIGkxLCB2MS5nZXQoKSk7CgoJCWludCBpMiA9IDIwMDsKCQlpbnQgY29uc3QgJnIyID0gaTI7CgkJeWFraXRvcmk8aW50IGNvbnN0PiBjb25zdCB2MnsgcjIgfTsKCQlzdGQ6OnByaW50ZigiLS0lc1xuIiwgdHlwZWlkKHYyLngpLm5hbWUoKSk7CgkJaTIrKzsKCQlzdGQ6OnByaW50Zigib3JnOiVkICwgIHlha2l0b3JpOiVkXG4iLCBpMiwgdjIuZ2V0KCkpOwoKCQlpbnQgaTMgPSAzMDA7CgkJeWFraXRvcmk8aW50ICY+IGNvbnN0IHYzeyBpMyB9OwoJCXN0ZDo6cHJpbnRmKCItLSVzXG4iLCB0eXBlaWQodjMueCkubmFtZSgpKTsKCQl2My5nZXQoKSsrOwoJCXN0ZDo6cHJpbnRmKCJvcmc6JWQgLCAgeWFraXRvcmk6JWRcbiIsIGkzLCB2My5nZXQoKSk7CgoJCWludCBpNCA9IDQwMDsKCQlpbnQgY29uc3QgJnI0ID0gaTQ7CgkJeWFraXRvcmk8aW50IGNvbnN0ICY+IGNvbnN0IHY0eyByNCB9OwoJCXN0ZDo6cHJpbnRmKCItLSVzXG4iLCB0eXBlaWQodjQueCkubmFtZSgpKTsKCQlpNCsrOwoJCXN0ZDo6cHJpbnRmKCJvcmc6JWQgLCAgeWFraXRvcmk6JWRcbiIsIGk0LCB2NC5nZXQoKSk7Cn0K