#include <list>
#include <memory>
#include <functional>
#include <iostream>
template<typename TObject, typename... CtorArgs>
class GenericPool {
public:
typedef std::shared_ptr<TObject> TObjectPtr;
explicit GenericPool(CtorArgs... args)
{
m_creator = [=]() { return std::make_shared<TObject>(args...); };
}
~GenericPool()
{
}
TObjectPtr getObject()
{
if (!m_availables.empty()) {
auto pooled = m_availables.front();
m_availables.pop_front();
return pooled;
}
m_availables.push_back(m_creator());
return m_availables.back();
}
void release(TObjectPtr &objPtr)
{
m_availables.push_back(objPtr);
m_inUse.remove(objPtr);
objPtr.reset();
}
private:
std::function<TObjectPtr()> m_creator;
std::list<TObjectPtr> m_availables;
std::list<TObjectPtr> m_inUse;
};
struct YobaBase {
YobaBase(int num, char sym) : m_num(num), m_sym(sym) {}
virtual ~YobaBase() {}
int m_num;
char m_sym;
};
struct YobaDerived : YobaBase {
YobaDerived(int num, char sym, float fnum) : YobaBase(num, sym), m_fnum(fnum) {}
float m_fnum;
};
int main()
{
typedef GenericPool<YobaBase, int, char> YobaBasePool;
typedef GenericPool<YobaDerived, int, char, float> YobaDerivedPool;
YobaBasePool ybPool(0, 'a');
YobaDerivedPool ydPool(5, 'b', 0.0f);
auto yb = ybPool.getObject();
auto yd = ydPool.getObject();
std::cout << "Yoba base (num = " << yb->m_num << ", sym = " << yb->m_sym << ")" << std::endl;
std::cout << "Yoba derived (num = " << yd->m_num << ", sym = "
<< yd->m_sym << ", fnum = " << yd->m_fnum << ")" << std::endl;
ybPool.release(yb);
ydPool.release(yd);
return 0;
}
I2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8aW9zdHJlYW0+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUT2JqZWN0LCB0eXBlbmFtZS4uLiBDdG9yQXJncz4KY2xhc3MgR2VuZXJpY1Bvb2wgewpwdWJsaWM6Cgl0eXBlZGVmIHN0ZDo6c2hhcmVkX3B0cjxUT2JqZWN0PiBUT2JqZWN0UHRyOwoKCWV4cGxpY2l0IEdlbmVyaWNQb29sKEN0b3JBcmdzLi4uIGFyZ3MpCgl7CgkJbV9jcmVhdG9yID0gWz1dKCkgeyByZXR1cm4gc3RkOjptYWtlX3NoYXJlZDxUT2JqZWN0PihhcmdzLi4uKTsgfTsKCX0KCgl+R2VuZXJpY1Bvb2woKQoJewoJfQoKCVRPYmplY3RQdHIgZ2V0T2JqZWN0KCkKCXsKCQlpZiAoIW1fYXZhaWxhYmxlcy5lbXB0eSgpKSB7CgkJCWF1dG8gcG9vbGVkID0gbV9hdmFpbGFibGVzLmZyb250KCk7CgkJCW1fYXZhaWxhYmxlcy5wb3BfZnJvbnQoKTsKCQkJcmV0dXJuIHBvb2xlZDsKCQl9CgoJCW1fYXZhaWxhYmxlcy5wdXNoX2JhY2sobV9jcmVhdG9yKCkpOwoJCXJldHVybiBtX2F2YWlsYWJsZXMuYmFjaygpOwoJfQoKCXZvaWQgcmVsZWFzZShUT2JqZWN0UHRyICZvYmpQdHIpCgl7CgkJbV9hdmFpbGFibGVzLnB1c2hfYmFjayhvYmpQdHIpOwoJCW1faW5Vc2UucmVtb3ZlKG9ialB0cik7CgkJb2JqUHRyLnJlc2V0KCk7Cgl9Cgpwcml2YXRlOgoJc3RkOjpmdW5jdGlvbjxUT2JqZWN0UHRyKCk+IG1fY3JlYXRvcjsKCglzdGQ6Omxpc3Q8VE9iamVjdFB0cj4gbV9hdmFpbGFibGVzOwoJc3RkOjpsaXN0PFRPYmplY3RQdHI+IG1faW5Vc2U7Cn07CgpzdHJ1Y3QgWW9iYUJhc2UgewoJWW9iYUJhc2UoaW50IG51bSwgY2hhciBzeW0pIDogbV9udW0obnVtKSwgbV9zeW0oc3ltKSB7fQoJdmlydHVhbCB+WW9iYUJhc2UoKSB7fQoKCWludCBtX251bTsKCWNoYXIgbV9zeW07Cn07CgpzdHJ1Y3QgWW9iYURlcml2ZWQgOiBZb2JhQmFzZSB7CglZb2JhRGVyaXZlZChpbnQgbnVtLCBjaGFyIHN5bSwgZmxvYXQgZm51bSkgOiBZb2JhQmFzZShudW0sIHN5bSksIG1fZm51bShmbnVtKSB7fQoKCWZsb2F0IG1fZm51bTsKfTsKCmludCBtYWluKCkKewoJdHlwZWRlZiBHZW5lcmljUG9vbDxZb2JhQmFzZSwgaW50LCBjaGFyPiBZb2JhQmFzZVBvb2w7Cgl0eXBlZGVmIEdlbmVyaWNQb29sPFlvYmFEZXJpdmVkLCBpbnQsIGNoYXIsIGZsb2F0PiBZb2JhRGVyaXZlZFBvb2w7CgoJWW9iYUJhc2VQb29sIHliUG9vbCgwLCAnYScpOwoJWW9iYURlcml2ZWRQb29sIHlkUG9vbCg1LCAnYicsIDAuMGYpOwoKCWF1dG8geWIgPSB5YlBvb2wuZ2V0T2JqZWN0KCk7CglhdXRvIHlkID0geWRQb29sLmdldE9iamVjdCgpOwoKCXN0ZDo6Y291dCA8PCAiWW9iYSBiYXNlIChudW0gPSAiIDw8IHliLT5tX251bSA8PCAiLCBzeW0gPSAiIDw8IHliLT5tX3N5bSA8PCAiKSIgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJZb2JhIGRlcml2ZWQgKG51bSA9ICIgPDwgeWQtPm1fbnVtIDw8ICIsIHN5bSA9ICIgCgkJCSAgPDwgeWQtPm1fc3ltIDw8ICIsIGZudW0gPSAiIDw8IHlkLT5tX2ZudW0gPDwgIikiIDw8IHN0ZDo6ZW5kbDsKCgl5YlBvb2wucmVsZWFzZSh5Yik7Cgl5ZFBvb2wucmVsZWFzZSh5ZCk7CgoJcmV0dXJuIDA7Cn0=