#include <memory>
#include <string>
#include <map>
template <typename> class manager;
template <typename T>
class managed_resource
{
typedef std::shared_ptr<manager<T>> manager_ptr;
public:
managed_resource(manager_ptr const & parent)
: parent_(parent)
{
}
/* ... */
private:
manager_ptr parent_;
};
template <typename Policy>
class manager
: Policy
, std::enable_shared_from_this<manager<Policy>>
{
typedef managed_resource<Policy> resource;
typedef std::shared_ptr<resource> resource_ptr;
public:
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;
}
};
class map_policy
{
typedef std::shared_ptr<managed_resource<map_policy>> resource_ptr;
typedef std::map<std::string, resource_ptr> resources;
public:
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;
}
private:
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;
}
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPG1hcD4KCnRlbXBsYXRlIDx0eXBlbmFtZT4gY2xhc3MgbWFuYWdlcjsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpjbGFzcyBtYW5hZ2VkX3Jlc291cmNlCnsKICAgICAgICB0eXBlZGVmIHN0ZDo6c2hhcmVkX3B0cjxtYW5hZ2VyPFQ+PiBtYW5hZ2VyX3B0cjsKICAgIHB1YmxpYzoKICAgICAgICBtYW5hZ2VkX3Jlc291cmNlKG1hbmFnZXJfcHRyIGNvbnN0ICYgcGFyZW50KQogICAgICAgICAgICA6IHBhcmVudF8ocGFyZW50KQogICAgICAgIHsKICAgICAgICB9CgogICAgICAgIC8qIC4uLiAqLwoKICAgIHByaXZhdGU6CiAgICAgICAgbWFuYWdlcl9wdHIgcGFyZW50XzsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBQb2xpY3k+CmNsYXNzIG1hbmFnZXIKICAgIDogUG9saWN5CiAgICAsIHN0ZDo6ZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXM8bWFuYWdlcjxQb2xpY3k+Pgp7CiAgICAgICAgdHlwZWRlZiBtYW5hZ2VkX3Jlc291cmNlPFBvbGljeT4gcmVzb3VyY2U7CiAgICAgICAgdHlwZWRlZiBzdGQ6OnNoYXJlZF9wdHI8cmVzb3VyY2U+IHJlc291cmNlX3B0cjsKICAgIHB1YmxpYzoKICAgICAgICByZXNvdXJjZV9wdHIgZ2V0X3Jlc291cmNlKHN0ZDo6c3RyaW5nIGNvbnN0ICYgbmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIFBvbGljeSAmIHAgPSAqdGhpczsKICAgICAgICAgICAgaWYocC5maW5kKG5hbWUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gcC5nZXQobmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzb3VyY2VfcHRyIHJlcyA9IHN0ZDo6bWFrZV9zaGFyZWQ8cmVzb3VyY2U+KHRoaXMtPnNoYXJlZF9mcm9tX3RoaXMoKSk7CiAgICAgICAgICAgIHAuc3RvcmUobmFtZSwgcmVzKTsKICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9Cn07CgpjbGFzcyBtYXBfcG9saWN5CnsKICAgICAgICB0eXBlZGVmIHN0ZDo6c2hhcmVkX3B0cjxtYW5hZ2VkX3Jlc291cmNlPG1hcF9wb2xpY3k+PiByZXNvdXJjZV9wdHI7CiAgICAgICAgdHlwZWRlZiBzdGQ6Om1hcDxzdGQ6OnN0cmluZywgcmVzb3VyY2VfcHRyPiByZXNvdXJjZXM7CgogICAgcHVibGljOgogICAgICAgIGJvb2wgZmluZChzdGQ6OnN0cmluZyBjb25zdCAmIG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXNvdXJjZXM6Oml0ZXJhdG9yIHJlc19pdCA9IHJlc291cmNlc18uZmluZChuYW1lKTsKICAgICAgICAgICAgcmV0dXJuIHJlc19pdCAhPSByZXNvdXJjZXNfLmVuZCgpOwogICAgICAgIH0KCiAgICAgICAgcmVzb3VyY2VfcHRyIGdldChzdGQ6OnN0cmluZyBjb25zdCAmIG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXNvdXJjZXM6Oml0ZXJhdG9yIHJlc19pdCA9IHJlc291cmNlc18uZmluZChuYW1lKTsKICAgICAgICAgICAgcmV0dXJuIHJlc19pdC0+c2Vjb25kOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBzdG9yZShzdGQ6OnN0cmluZyBjb25zdCAmIG5hbWUsIHJlc291cmNlX3B0ciBjb25zdCAmIHJlcykKICAgICAgICB7CiAgICAgICAgICAgIHJlc291cmNlc19bbmFtZV0gPSByZXM7CiAgICAgICAgfQoKICAgIHByaXZhdGU6CiAgICAgICAgcmVzb3VyY2VzIHJlc291cmNlc187Cn07Cgp0eXBlZGVmIG1hbmFnZXI8bWFwX3BvbGljeT4gbXlfbWFuYWdlcjsKCmludCBtYWluKCkKewogICAgYXV0byBtID0gc3RkOjptYWtlX3NoYXJlZDxteV9tYW5hZ2VyPigpOwogICAgYXV0byByZXMgPSBtLT5nZXRfcmVzb3VyY2UoInRlc3QiKTsKICAgIHJldHVybiAwOwp9
In file included from /usr/include/c++/4.7/bits/shared_ptr.h:52:0,
from /usr/include/c++/4.7/memory:87,
from prog.cpp:1:
/usr/include/c++/4.7/bits/shared_ptr_base.h: In instantiation of ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<manager<map_policy> >; _Args = {}; _Tp = manager<map_policy>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’:
/usr/include/c++/4.7/bits/shared_ptr.h:317:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<manager<map_policy> >; _Args = {}; _Tp = manager<map_policy>]’
/usr/include/c++/4.7/bits/shared_ptr.h:599:39: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = manager<map_policy>; _Alloc = std::allocator<manager<map_policy> >; _Args = {}]’
/usr/include/c++/4.7/bits/shared_ptr.h:615:42: required from ‘std::shared_ptr<_Tp1> std::make_shared(_Args&& ...) [with _Tp = manager<map_policy>; _Args = {}]’
prog.cpp:75:43: required from here
/usr/include/c++/4.7/bits/shared_ptr_base.h:1003:4: error: ‘std::enable_shared_from_this<manager<map_policy> >’ is an inaccessible base of ‘manager<map_policy>’