#include <iostream>
#include <stdexcept>
#include <typeinfo>
class Committer
{
public:
template <typename T>
void mark_var_change(T *var)
{
mPointer = var;
mTypeInfo = &typeid(T*);
}
template <typename T>
void commit_change(T new_value)
{
if (*mTypeInfo != typeid(T*)) {
throw std::runtime_error("Bad type");
}
if (mPointer == nullptr) {
throw std::runtime_error("nullptr was stocked");
}
*reinterpret_cast<T*>(mPointer) = new_value;
}
private:
void* mPointer = nullptr;
const std::type_info* mTypeInfo = nullptr;
};
int main() {
Committer c;
int i;
float f;
c.mark_var_change(&i);
c.commit_change(42);
c.mark_var_change(&f);
c.commit_change(4.2f);
std::cout << i << " " << f << std::endl;
try
{
c.mark_var_change(&i);
c.commit_change(4.2f);
}
catch (const std::exception&e)
{
std::cout << e.what() << std::endl;
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RkZXhjZXB0PgogI2luY2x1ZGUgPHR5cGVpbmZvPgogCmNsYXNzIENvbW1pdHRlcgp7CnB1YmxpYzoJCiAKCXRlbXBsYXRlIDx0eXBlbmFtZSBUPgoJdm9pZCBtYXJrX3Zhcl9jaGFuZ2UoVCAqdmFyKQoJewoJICAgIG1Qb2ludGVyID0gdmFyOwoJICAgIG1UeXBlSW5mbyA9ICZ0eXBlaWQoVCopOwoJfQogCgl0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KCXZvaWQgY29tbWl0X2NoYW5nZShUIG5ld192YWx1ZSkKCXsKCQlpZiAoKm1UeXBlSW5mbyAhPSB0eXBlaWQoVCopKSB7CgkJICAgIHRocm93IHN0ZDo6cnVudGltZV9lcnJvcigiQmFkIHR5cGUiKTsKCQl9CgkJaWYgKG1Qb2ludGVyID09IG51bGxwdHIpIHsKCQkJdGhyb3cgc3RkOjpydW50aW1lX2Vycm9yKCJudWxscHRyIHdhcyBzdG9ja2VkIik7CgkJfQoJICAgICpyZWludGVycHJldF9jYXN0PFQqPihtUG9pbnRlcikgPSBuZXdfdmFsdWU7Cgl9CiAKcHJpdmF0ZToKICAgIHZvaWQqIG1Qb2ludGVyID0gbnVsbHB0cjsKICAgIGNvbnN0IHN0ZDo6dHlwZV9pbmZvKiBtVHlwZUluZm8gPSBudWxscHRyOwp9OwogCiAKaW50IG1haW4oKSB7CglDb21taXR0ZXIgYzsKCWludCBpOwoJZmxvYXQgZjsKIAoJYy5tYXJrX3Zhcl9jaGFuZ2UoJmkpOwoJYy5jb21taXRfY2hhbmdlKDQyKTsKIAoJYy5tYXJrX3Zhcl9jaGFuZ2UoJmYpOwoJYy5jb21taXRfY2hhbmdlKDQuMmYpOwogCglzdGQ6OmNvdXQgPDwgaSA8PCAiICIgPDwgZiA8PCBzdGQ6OmVuZGw7CgkKCXRyeQoJewoJCWMubWFya192YXJfY2hhbmdlKCZpKTsJCgkJYy5jb21taXRfY2hhbmdlKDQuMmYpOwkKCX0KCWNhdGNoIChjb25zdCBzdGQ6OmV4Y2VwdGlvbiZlKQoJewoJCXN0ZDo6Y291dCA8PCBlLndoYXQoKSA8PCBzdGQ6OmVuZGw7Cgl9Cn0KCg==