#include <iostream>
#include <map>
#include <memory>
#include <string>
#define CONCAT(x, y) CONCAT_(x, y)
#define CONCAT_(x, y) x ## y
#define PAR(type, name, descr) \
type name; \
const bool CONCAT(doRegistration, name) = [this]() { \
entries.emplace(#name, \
std::unique_ptr<BaseEntry>( \
new Entry<Model, type>{ type##_type, &Model::name })); \
return true; \
}();
enum ParType { double_type, int_type };
class Model;
struct BaseEntry
{
BaseEntry(ParType type) : type(type) {}
ParType type;
template <typename C, typename T>
T & get(C &c);
};
template <typename C, typename T>
struct Entry : BaseEntry
{
Entry(ParType type, T C::* ptr) : BaseEntry(type), ptr(ptr) {}
T C::* ptr;
};
template <typename C, typename T>
T & BaseEntry::get(C &c)
{
return c.*static_cast<Entry<C, T>*>(this)->ptr;
}
class Model
{
public:
Model() : a(1.0), b(2) {}
std::map<std::string, std::unique_ptr<BaseEntry>> entries;
PAR(double, a, "какой то параметр");
PAR(int, b, "и еще один параметр");
};
int
main(void)
{
Model m;
for (const auto &e : m.entries) {
std::cout << e.first << std::endl;
switch (e.second->type) {
case double_type:
e.second->get<Model, double>(m) = 10.1;
std::cout << e.second->get<Model, double>(m) << std::endl;
break;
case int_type:
std::cout << e.second->get<Model, int>(m) << std::endl;
break;
}
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8c3RyaW5nPgoKI2RlZmluZSBDT05DQVQoeCwgeSkgQ09OQ0FUXyh4LCB5KQojZGVmaW5lIENPTkNBVF8oeCwgeSkgeCAjIyB5CgojZGVmaW5lIFBBUih0eXBlLCBuYW1lLCBkZXNjcikgXAp0eXBlIG5hbWU7IFwKY29uc3QgYm9vbCBDT05DQVQoZG9SZWdpc3RyYXRpb24sIG5hbWUpID0gW3RoaXNdKCkgeyBcCiAgICBlbnRyaWVzLmVtcGxhY2UoI25hbWUsIFwKICAgICAgICAgICAgICAgICAgICBzdGQ6OnVuaXF1ZV9wdHI8QmFzZUVudHJ5PiggXAogICAgICAgICAgICAgICAgICAgICAgICBuZXcgRW50cnk8TW9kZWwsIHR5cGU+eyB0eXBlIyNfdHlwZSwgJk1vZGVsOjpuYW1lIH0pKTsgXAogICAgcmV0dXJuIHRydWU7IFwKfSgpOwoKZW51bSBQYXJUeXBlIHsgZG91YmxlX3R5cGUsIGludF90eXBlIH07CgpjbGFzcyBNb2RlbDsKCnN0cnVjdCBCYXNlRW50cnkKewogICAgQmFzZUVudHJ5KFBhclR5cGUgdHlwZSkgOiB0eXBlKHR5cGUpIHt9CiAgICBQYXJUeXBlIHR5cGU7CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIEMsIHR5cGVuYW1lIFQ+CiAgICBUICYgZ2V0KEMgJmMpOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEMsIHR5cGVuYW1lIFQ+CnN0cnVjdCBFbnRyeSA6IEJhc2VFbnRyeQp7CiAgICBFbnRyeShQYXJUeXBlIHR5cGUsIFQgQzo6KiBwdHIpIDogQmFzZUVudHJ5KHR5cGUpLCBwdHIocHRyKSB7fQogICAgVCBDOjoqIHB0cjsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBDLCB0eXBlbmFtZSBUPgpUICYgQmFzZUVudHJ5OjpnZXQoQyAmYykKewogICAgcmV0dXJuIGMuKnN0YXRpY19jYXN0PEVudHJ5PEMsIFQ+Kj4odGhpcyktPnB0cjsKfQoKY2xhc3MgTW9kZWwKewpwdWJsaWM6CiAgICBNb2RlbCgpIDogYSgxLjApLCBiKDIpIHt9CgogICAgc3RkOjptYXA8c3RkOjpzdHJpbmcsIHN0ZDo6dW5pcXVlX3B0cjxCYXNlRW50cnk+PiBlbnRyaWVzOwoKICAgIFBBUihkb3VibGUsIGEsICLQutCw0LrQvtC5INGC0L4g0L/QsNGA0LDQvNC10YLRgCIpOwogICAgUEFSKGludCwgYiwgItC4INC10YnQtSDQvtC00LjQvSDQv9Cw0YDQsNC80LXRgtGAIik7Cn07CgppbnQKbWFpbih2b2lkKQp7CiAgICBNb2RlbCBtOwogICAgZm9yIChjb25zdCBhdXRvICZlIDogbS5lbnRyaWVzKSB7CiAgICAgICAgc3RkOjpjb3V0IDw8IGUuZmlyc3QgPDwgc3RkOjplbmRsOwogICAgICAgIHN3aXRjaCAoZS5zZWNvbmQtPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSBkb3VibGVfdHlwZToKICAgICAgICAgICAgICAgIGUuc2Vjb25kLT5nZXQ8TW9kZWwsIGRvdWJsZT4obSkgPSAxMC4xOwogICAgICAgICAgICAgICAgc3RkOjpjb3V0IDw8IGUuc2Vjb25kLT5nZXQ8TW9kZWwsIGRvdWJsZT4obSkgPDwgc3RkOjplbmRsOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgaW50X3R5cGU6CiAgICAgICAgICAgICAgICBzdGQ6OmNvdXQgPDwgZS5zZWNvbmQtPmdldDxNb2RlbCwgaW50PihtKSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMDsKfQ==