#include <iostream>
#include <set>
template <typename Content>
struct SetWith {
std::set<Content> set;
};
template <typename... Contents>
struct SetsContainer {};
template <typename Content, typename... OtherContents>
struct SetsContainer<Content, OtherContents...> : public SetsContainer<OtherContents...>, public SetWith<Content> {};
template <typename... Contents>
struct Sets {
SetsContainer<Contents...> sets;
template <typename C>
std::set<C> & set_of(void) {
return static_cast<SetWith<C> *>(&sets)->set;
}
template <typename T>
void add(T t) {
set_of<typename std::decay<T>::type>().insert(std::forward<T>(t));
}
};
template <typename C, typename Container>
std::set<C> & set_of(Container & sets) {
return static_cast<SetWith<C> *>(&sets)->set;
}
struct Foo {};
int main() {
Sets<int, double, bool> s;
SetsContainer<int, char, bool> s2;
s.set_of<int>().insert(42);
s.set_of<double>().insert(3.14);
s.set_of<bool>().insert(true);
s.add(1.0);
s.add(3);
double const ddd = 6.28;
s.add(ddd);
double xyz = 0.001;
s.add(std::move(xyz));
for (auto const & d : s.set_of<double>()) {
std::cout << d << ", ";
}
std::cout << std::endl;
set_of<bool>(s2).insert(false);
// s.get<Foo>();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c2V0PgoKCnRlbXBsYXRlIDx0eXBlbmFtZSBDb250ZW50PgpzdHJ1Y3QgU2V0V2l0aCB7CglzdGQ6OnNldDxDb250ZW50PiBzZXQ7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQ29udGVudHM+CnN0cnVjdCBTZXRzQ29udGFpbmVyIHt9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIENvbnRlbnQsIHR5cGVuYW1lLi4uIE90aGVyQ29udGVudHM+CnN0cnVjdCBTZXRzQ29udGFpbmVyPENvbnRlbnQsIE90aGVyQ29udGVudHMuLi4+IDogcHVibGljIFNldHNDb250YWluZXI8T3RoZXJDb250ZW50cy4uLj4sIHB1YmxpYyBTZXRXaXRoPENvbnRlbnQ+IHt9OwoKdGVtcGxhdGUgPHR5cGVuYW1lLi4uIENvbnRlbnRzPgpzdHJ1Y3QgU2V0cyB7CglTZXRzQ29udGFpbmVyPENvbnRlbnRzLi4uPiBzZXRzOwoJdGVtcGxhdGUgPHR5cGVuYW1lIEM+CglzdGQ6OnNldDxDPiAmIHNldF9vZih2b2lkKSB7CgkJcmV0dXJuIHN0YXRpY19jYXN0PFNldFdpdGg8Qz4gKj4oJnNldHMpLT5zZXQ7Cgl9Cgl0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KCXZvaWQgYWRkKFQgdCkgewoJCXNldF9vZjx0eXBlbmFtZSBzdGQ6OmRlY2F5PFQ+Ojp0eXBlPigpLmluc2VydChzdGQ6OmZvcndhcmQ8VD4odCkpOwoJfQp9OwoKCXRlbXBsYXRlIDx0eXBlbmFtZSBDLCB0eXBlbmFtZSBDb250YWluZXI+CglzdGQ6OnNldDxDPiAmIHNldF9vZihDb250YWluZXIgJiBzZXRzKSB7CgkJcmV0dXJuIHN0YXRpY19jYXN0PFNldFdpdGg8Qz4gKj4oJnNldHMpLT5zZXQ7Cgl9CgpzdHJ1Y3QgRm9vIHt9OwoKaW50IG1haW4oKSB7CglTZXRzPGludCwgZG91YmxlLCBib29sPiBzOwoJU2V0c0NvbnRhaW5lcjxpbnQsIGNoYXIsIGJvb2w+IHMyOwoJcy5zZXRfb2Y8aW50PigpLmluc2VydCg0Mik7CglzLnNldF9vZjxkb3VibGU+KCkuaW5zZXJ0KDMuMTQpOwoJcy5zZXRfb2Y8Ym9vbD4oKS5pbnNlcnQodHJ1ZSk7CglzLmFkZCgxLjApOwoJcy5hZGQoMyk7Cglkb3VibGUgY29uc3QgZGRkID0gNi4yODsKCXMuYWRkKGRkZCk7Cglkb3VibGUgeHl6ID0gMC4wMDE7CglzLmFkZChzdGQ6Om1vdmUoeHl6KSk7Cglmb3IgKGF1dG8gY29uc3QgJiBkIDogcy5zZXRfb2Y8ZG91YmxlPigpKSB7CgkJc3RkOjpjb3V0IDw8IGQgPDwgIiwgIjsKCX0KCXN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7CglzZXRfb2Y8Ym9vbD4oczIpLmluc2VydChmYWxzZSk7Ci8vCXMuZ2V0PEZvbz4oKTsKCXJldHVybiAwOwp9