#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, __LINE__) = []() { \
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) {}
static std::map<std::string, std::unique_ptr<BaseEntry>> entries;
PAR(double, a, "какой то параметр");
PAR(int, b, "и еще один параметр");
};
std::map<std::string, std::unique_ptr<BaseEntry>> Model::entries;
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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8c3RyaW5nPgoKI2RlZmluZSBDT05DQVQoeCwgeSkgQ09OQ0FUXyh4LCB5KQojZGVmaW5lIENPTkNBVF8oeCwgeSkgeCAjIyB5CgojZGVmaW5lIFBBUih0eXBlLCBuYW1lLCBkZXNjcikgXAp0eXBlIG5hbWU7IFwKY29uc3QgYm9vbCBDT05DQVQoZG9SZWdpc3RyYXRpb24sIF9fTElORV9fKSA9IFtdKCkgeyBcCiAgICBlbnRyaWVzLmVtcGxhY2UoI25hbWUsIFwKICAgICAgICAgICAgICAgICAgICBzdGQ6OnVuaXF1ZV9wdHI8QmFzZUVudHJ5PiggXAogICAgICAgICAgICAgICAgICAgICAgICBuZXcgRW50cnk8TW9kZWwsIHR5cGU+eyB0eXBlIyNfdHlwZSwgJk1vZGVsOjpuYW1lIH0pKTsgXAogICAgcmV0dXJuIHRydWU7IFwKfSgpOwoKZW51bSBQYXJUeXBlIHsgZG91YmxlX3R5cGUsIGludF90eXBlIH07CgpjbGFzcyBNb2RlbDsKCnN0cnVjdCBCYXNlRW50cnkKewogICAgQmFzZUVudHJ5KFBhclR5cGUgdHlwZSkgOiB0eXBlKHR5cGUpIHt9CiAgICBQYXJUeXBlIHR5cGU7CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIEMsIHR5cGVuYW1lIFQ+CiAgICBUICYgZ2V0KEMgJmMpOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEMsIHR5cGVuYW1lIFQ+CnN0cnVjdCBFbnRyeSA6IEJhc2VFbnRyeQp7CiAgICBFbnRyeShQYXJUeXBlIHR5cGUsIFQgQzo6KiBwdHIpIDogQmFzZUVudHJ5KHR5cGUpLCBwdHIocHRyKSB7fQogICAgVCBDOjoqIHB0cjsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBDLCB0eXBlbmFtZSBUPgpUICYgQmFzZUVudHJ5OjpnZXQoQyAmYykKewogICAgcmV0dXJuIGMuKnN0YXRpY19jYXN0PEVudHJ5PEMsIFQ+Kj4odGhpcyktPnB0cjsKfQoKY2xhc3MgTW9kZWwKewpwdWJsaWM6CiAgICBNb2RlbCgpIDogYSgxLjApLCBiKDIpIHt9CgogICAgc3RhdGljIHN0ZDo6bWFwPHN0ZDo6c3RyaW5nLCBzdGQ6OnVuaXF1ZV9wdHI8QmFzZUVudHJ5Pj4gZW50cmllczsKCiAgICBQQVIoZG91YmxlLCBhLCAi0LrQsNC60L7QuSDRgtC+INC/0LDRgNCw0LzQtdGC0YAiKTsKICAgIFBBUihpbnQsIGIsICLQuCDQtdGJ0LUg0L7QtNC40L0g0L/QsNGA0LDQvNC10YLRgCIpOwp9OwoKc3RkOjptYXA8c3RkOjpzdHJpbmcsIHN0ZDo6dW5pcXVlX3B0cjxCYXNlRW50cnk+PiBNb2RlbDo6ZW50cmllczsKCmludAptYWluKHZvaWQpCnsKICAgIE1vZGVsIG07CiAgICBmb3IgKGNvbnN0IGF1dG8gJmUgOiBtLmVudHJpZXMpIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgZS5maXJzdCA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3dpdGNoIChlLnNlY29uZC0+dHlwZSkgewogICAgICAgICAgICBjYXNlIGRvdWJsZV90eXBlOgogICAgICAgICAgICAgICAgZS5zZWNvbmQtPmdldDxNb2RlbCwgZG91YmxlPihtKSA9IDEwLjE7CiAgICAgICAgICAgICAgICBzdGQ6OmNvdXQgPDwgZS5zZWNvbmQtPmdldDxNb2RlbCwgZG91YmxlPihtKSA8PCBzdGQ6OmVuZGw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBpbnRfdHlwZToKICAgICAgICAgICAgICAgIHN0ZDo6Y291dCA8PCBlLnNlY29uZC0+Z2V0PE1vZGVsLCBpbnQ+KG0pIDw8IHN0ZDo6ZW5kbDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwp9Cg==