#include <map>
#include <string>
#include <iostream>
template<typename T>
struct disable_default
{
T& get_default()
{
throw 1;
}
const T& get_default() const
{
throw 1;
}
};
template<typename T>
struct enable_default
{
template<typename Value>
enable_default(Value&& def_value) : default_value(std::forward<Value>(def_value))
{
}
const T& get_default() const
{
return default_value;
}
T& get_default()
{
return default_value;
}
private:
T default_value;
};
template<typename K, typename T, template <typename> class default_policy = enable_default, typename key_comp = std::less<K>>
struct selector : public default_policy<T>
{
template<typename Value>
selector(Value&& def_value) : default_policy<T>(std::forward<Value>(def_value))
{
}
selector()
{
}
struct selector_proxy
{
selector_proxy(std::map<K,T, key_comp>& sel_map, const K& pKey) : selector_map(sel_map), key(pKey)
{
}
template<typename Val>
selector_proxy& operator=(Val&& pValue)
{
auto it = selector_map.find(key);
if ( it != end(selector_map) )
{
it->second = std::forward<Val>(pValue);
}
else
{
selector_map.insert(std::make_pair(key, std::forward<Val>(pValue)));
}
}
private:
std::map<K,T,key_comp>& selector_map;
const K& key;
};
selector_proxy at(const K& key)
{
return selector_proxy(selector_map, key);
}
T& get(const K& key)
{
return const_cast<T&>(static_cast<const selector*>(this)->get(key));
}
const T& get(const K& key) const
{
auto it = selector_map.find(key);
if ( it != end(selector_map) )
{
return it->second;
}
else
{
return default_policy<T>::get_default();
}
}
private:
std::map<K,T,key_comp> selector_map;
};
using namespace std;
int main()
{
selector<string, int> d_sel_1(0);
d_sel_1.at("one") = 1;
d_sel_1.at("two") = 2;
cout << d_sel_1.get("one") << endl;
cout << d_sel_1.get("three") << endl;
selector<string, int, disable_default> nd_sel {};
try
{
cout << nd_sel.get("one") << endl;
}
catch(...)
{
cout << "not found" << endl;
}
}
I2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IGRpc2FibGVfZGVmYXVsdAp7ICAgIAoJVCYgZ2V0X2RlZmF1bHQoKQoJewoJCXRocm93IDE7Cgl9CiAgICAKICAgIGNvbnN0IFQmIGdldF9kZWZhdWx0KCkgY29uc3QKICAgIHsKICAgICAgICB0aHJvdyAxOwogICAgfQp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IGVuYWJsZV9kZWZhdWx0CnsKCXRlbXBsYXRlPHR5cGVuYW1lIFZhbHVlPgoJZW5hYmxlX2RlZmF1bHQoVmFsdWUmJiBkZWZfdmFsdWUpIDogZGVmYXVsdF92YWx1ZShzdGQ6OmZvcndhcmQ8VmFsdWU+KGRlZl92YWx1ZSkpCgl7Cgl9CgkKCWNvbnN0IFQmIGdldF9kZWZhdWx0KCkgY29uc3QKCXsKCQlyZXR1cm4gZGVmYXVsdF92YWx1ZTsKCX0KCQoJVCYgZ2V0X2RlZmF1bHQoKQoJewoJCXJldHVybiBkZWZhdWx0X3ZhbHVlOwoJfQoJCnByaXZhdGU6CglUIGRlZmF1bHRfdmFsdWU7CQkKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEssIHR5cGVuYW1lIFQsIHRlbXBsYXRlIDx0eXBlbmFtZT4gY2xhc3MgZGVmYXVsdF9wb2xpY3kgPSBlbmFibGVfZGVmYXVsdCwgdHlwZW5hbWUga2V5X2NvbXAgPSBzdGQ6Omxlc3M8Sz4+CnN0cnVjdCBzZWxlY3RvciA6IHB1YmxpYyBkZWZhdWx0X3BvbGljeTxUPgp7CQkKCXRlbXBsYXRlPHR5cGVuYW1lIFZhbHVlPgoJc2VsZWN0b3IoVmFsdWUmJiBkZWZfdmFsdWUpIDogZGVmYXVsdF9wb2xpY3k8VD4oc3RkOjpmb3J3YXJkPFZhbHVlPihkZWZfdmFsdWUpKQoJewoJfQoJCglzZWxlY3RvcigpCgl7CQoJfQoJCQkJCglzdHJ1Y3Qgc2VsZWN0b3JfcHJveHkKCXsKCQlzZWxlY3Rvcl9wcm94eShzdGQ6Om1hcDxLLFQsIGtleV9jb21wPiYgc2VsX21hcCwgY29uc3QgSyYgcEtleSkgOiBzZWxlY3Rvcl9tYXAoc2VsX21hcCksIGtleShwS2V5KQoJCXsKCQl9CgkJCgkJdGVtcGxhdGU8dHlwZW5hbWUgVmFsPgoJCXNlbGVjdG9yX3Byb3h5JiBvcGVyYXRvcj0oVmFsJiYgcFZhbHVlKQoJCXsKCQkJYXV0byBpdCA9IHNlbGVjdG9yX21hcC5maW5kKGtleSk7CgkJCWlmICggaXQgIT0gZW5kKHNlbGVjdG9yX21hcCkgKQoJCQl7CgkJCQlpdC0+c2Vjb25kID0gc3RkOjpmb3J3YXJkPFZhbD4ocFZhbHVlKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCXNlbGVjdG9yX21hcC5pbnNlcnQoc3RkOjptYWtlX3BhaXIoa2V5LCBzdGQ6OmZvcndhcmQ8VmFsPihwVmFsdWUpKSk7CgkJCX0KCQl9CgkJCQkKCXByaXZhdGU6CgkJc3RkOjptYXA8SyxULGtleV9jb21wPiYgc2VsZWN0b3JfbWFwOwkKCQljb25zdCBLJiBrZXk7Cgl9OwoJCglzZWxlY3Rvcl9wcm94eSBhdChjb25zdCBLJiBrZXkpCgl7CgkJcmV0dXJuIHNlbGVjdG9yX3Byb3h5KHNlbGVjdG9yX21hcCwga2V5KTsKCX0KCQkKCVQmIGdldChjb25zdCBLJiBrZXkpCgl7CgkJcmV0dXJuIGNvbnN0X2Nhc3Q8VCY+KHN0YXRpY19jYXN0PGNvbnN0IHNlbGVjdG9yKj4odGhpcyktPmdldChrZXkpKTsKCX0KCQoJY29uc3QgVCYgZ2V0KGNvbnN0IEsmIGtleSkgY29uc3QKCXsKCQlhdXRvIGl0ID0gc2VsZWN0b3JfbWFwLmZpbmQoa2V5KTsKCQlpZiAoIGl0ICE9IGVuZChzZWxlY3Rvcl9tYXApICkKCQl7CgkJCXJldHVybiBpdC0+c2Vjb25kOwoJCX0KCQllbHNlCgkJewoJCQlyZXR1cm4gZGVmYXVsdF9wb2xpY3k8VD46OmdldF9kZWZhdWx0KCk7CgkJfQoJfQoJCnByaXZhdGU6CglzdGQ6Om1hcDxLLFQsa2V5X2NvbXA+IHNlbGVjdG9yX21hcDsKfTsKCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgppbnQgbWFpbigpCnsKICAgIHNlbGVjdG9yPHN0cmluZywgaW50PiBkX3NlbF8xKDApOwogICAgZF9zZWxfMS5hdCgib25lIikgPSAxOwogICAgZF9zZWxfMS5hdCgidHdvIikgPSAyOwogICAgY291dCA8PCBkX3NlbF8xLmdldCgib25lIikgPDwgZW5kbDsKICAgIGNvdXQgPDwgZF9zZWxfMS5nZXQoInRocmVlIikgPDwgZW5kbDsKICAgIAogICAgc2VsZWN0b3I8c3RyaW5nLCBpbnQsIGRpc2FibGVfZGVmYXVsdD4gbmRfc2VsIHt9OwogICAgdHJ5IAogICAgewogICAgICAgIGNvdXQgPDwgbmRfc2VsLmdldCgib25lIikgPDwgZW5kbDsKICAgIH0KICAgIGNhdGNoKC4uLikKICAgIHsKICAgICAgICBjb3V0IDw8ICJub3QgZm91bmQiIDw8IGVuZGw7CiAgICB9Cn0=