#include <memory>
#include <string>
#include <map>
template <typename> struct manager;
template <typename T>
struct managed_resource
{
typedef std::shared_ptr<manager<T>> manager_ptr;
managed_resource(manager_ptr const & parent)
: parent_(parent)
{
}
/* ... */
manager_ptr parent_;
};
template <typename Policy>
struct manager
: Policy
, std::enable_shared_from_this<manager<Policy>>
{
typedef managed_resource<Policy> resource;
typedef std::shared_ptr<resource> resource_ptr;
resource_ptr get_resource(std::string const & name)
{
Policy & p = *this;
if(p.find(name))
{
return p.get(name);
}
resource_ptr res = std::make_shared<resource>(this->shared_from_this());
p.store(name, res);
return res;
}
};
struct map_policy
{
typedef std::shared_ptr<managed_resource<map_policy>> resource_ptr;
typedef std::map<std::string, resource_ptr> resources;
bool find(std::string const & name)
{
resources::iterator res_it = resources_.find(name);
return res_it != resources_.end();
}
resource_ptr get(std::string const & name)
{
resources::iterator res_it = resources_.find(name);
return res_it->second;
}
void store(std::string const & name, resource_ptr const & res)
{
resources_[name] = res;
}
resources resources_;
};
typedef manager<map_policy> my_manager;
int main()
{
auto m = std::make_shared<my_manager>();
auto res = m->get_resource("test");
return 0;
}
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPG1hcD4KCnRlbXBsYXRlIDx0eXBlbmFtZT4gc3RydWN0IG1hbmFnZXI7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IG1hbmFnZWRfcmVzb3VyY2UKewogICAgICAgIHR5cGVkZWYgc3RkOjpzaGFyZWRfcHRyPG1hbmFnZXI8VD4+IG1hbmFnZXJfcHRyOwoKICAgIG1hbmFnZWRfcmVzb3VyY2UobWFuYWdlcl9wdHIgY29uc3QgJiBwYXJlbnQpCiAgICAgICAgICAgIDogcGFyZW50XyhwYXJlbnQpCiAgICAgICAgewogICAgICAgIH0KCiAgICAgICAgLyogLi4uICovCgogICAgICAgIG1hbmFnZXJfcHRyIHBhcmVudF87Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgUG9saWN5PgpzdHJ1Y3QgbWFuYWdlcgogICAgOiBQb2xpY3kKICAgICwgc3RkOjplbmFibGVfc2hhcmVkX2Zyb21fdGhpczxtYW5hZ2VyPFBvbGljeT4+CnsKICAgICAgICB0eXBlZGVmIG1hbmFnZWRfcmVzb3VyY2U8UG9saWN5PiByZXNvdXJjZTsKICAgICAgICB0eXBlZGVmIHN0ZDo6c2hhcmVkX3B0cjxyZXNvdXJjZT4gcmVzb3VyY2VfcHRyOwoKICAgIHJlc291cmNlX3B0ciBnZXRfcmVzb3VyY2Uoc3RkOjpzdHJpbmcgY29uc3QgJiBuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgUG9saWN5ICYgcCA9ICp0aGlzOwogICAgICAgICAgICBpZihwLmZpbmQobmFtZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBwLmdldChuYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXNvdXJjZV9wdHIgcmVzID0gc3RkOjptYWtlX3NoYXJlZDxyZXNvdXJjZT4odGhpcy0+c2hhcmVkX2Zyb21fdGhpcygpKTsKICAgICAgICAgICAgcC5zdG9yZShuYW1lLCByZXMpOwogICAgICAgICAgICByZXR1cm4gcmVzOwogICAgICAgIH0KfTsKCnN0cnVjdCAgbWFwX3BvbGljeQp7CiAgICAgICAgdHlwZWRlZiBzdGQ6OnNoYXJlZF9wdHI8bWFuYWdlZF9yZXNvdXJjZTxtYXBfcG9saWN5Pj4gcmVzb3VyY2VfcHRyOwogICAgICAgIHR5cGVkZWYgc3RkOjptYXA8c3RkOjpzdHJpbmcsIHJlc291cmNlX3B0cj4gcmVzb3VyY2VzOwoKICAgICAgICBib29sIGZpbmQoc3RkOjpzdHJpbmcgY29uc3QgJiBuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmVzb3VyY2VzOjppdGVyYXRvciByZXNfaXQgPSByZXNvdXJjZXNfLmZpbmQobmFtZSk7CiAgICAgICAgICAgIHJldHVybiByZXNfaXQgIT0gcmVzb3VyY2VzXy5lbmQoKTsKICAgICAgICB9CgogICAgICAgIHJlc291cmNlX3B0ciBnZXQoc3RkOjpzdHJpbmcgY29uc3QgJiBuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmVzb3VyY2VzOjppdGVyYXRvciByZXNfaXQgPSByZXNvdXJjZXNfLmZpbmQobmFtZSk7CiAgICAgICAgICAgIHJldHVybiByZXNfaXQtPnNlY29uZDsKICAgICAgICB9CgogICAgICAgIHZvaWQgc3RvcmUoc3RkOjpzdHJpbmcgY29uc3QgJiBuYW1lLCByZXNvdXJjZV9wdHIgY29uc3QgJiByZXMpCiAgICAgICAgewogICAgICAgICAgICByZXNvdXJjZXNfW25hbWVdID0gcmVzOwogICAgICAgIH0KCiAgICAgICAgcmVzb3VyY2VzIHJlc291cmNlc187Cn07Cgp0eXBlZGVmIG1hbmFnZXI8bWFwX3BvbGljeT4gbXlfbWFuYWdlcjsKCmludCBtYWluKCkKewogICAgYXV0byBtID0gc3RkOjptYWtlX3NoYXJlZDxteV9tYW5hZ2VyPigpOwogICAgYXV0byByZXMgPSBtLT5nZXRfcmVzb3VyY2UoInRlc3QiKTsKICAgIHJldHVybiAwOwp9