#include <type_traits>
#include <utility>
#include <iostream>
#include <vector>
template <typename Type>
class ptr_scope_manager
{
private:
std::vector<Type> ptrs;
public:
template <typename T = Type, typename... Args>
auto create(Args&&... args) -> typename std::enable_if<!std::is_constructible<T, Args...>::value, T*>::type
{
std::cout << "push_back" << std::endl;
ptrs.push_back(T{ std::forward<Args>(args)... });
return &ptrs.back();
}
template <typename T = Type, typename... Args>
auto create(Args&&... args) -> typename std::enable_if<std::is_constructible<T, Args...>::value, T*>::type
{
std::cout << "emplace_back" << std::endl;
ptrs.emplace_back(std::forward<Args>(args)...);
return &ptrs.back();
}
};
class public_ctor
{
int i;
public:
public_ctor(int i): i(i) {} // public
};
class private_ctor
{
friend class ptr_scope_manager<private_ctor>;
int i;
private:
private_ctor(int i): i(i) {} // private
};
class non_friendly_private_ctor
{ int i;
private:
non_friendly_private_ctor(int i): i(i) {} // private
};
int main()
{
ptr_scope_manager<public_ctor> public_manager;
ptr_scope_manager<private_ctor> private_manager;
ptr_scope_manager<non_friendly_private_ctor> non_friendly_private_manager;
public_manager.create(3);
private_manager.create(3);
// non_friendly_private_manager.create(3); raises error
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGU+CmNsYXNzIHB0cl9zY29wZV9tYW5hZ2VyCnsKcHJpdmF0ZToKICAgIHN0ZDo6dmVjdG9yPFR5cGU+IHB0cnM7CgpwdWJsaWM6CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCA9IFR5cGUsIHR5cGVuYW1lLi4uIEFyZ3M+CiAgICBhdXRvIGNyZWF0ZShBcmdzJiYuLi4gYXJncykgLT4gdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8IXN0ZDo6aXNfY29uc3RydWN0aWJsZTxULCBBcmdzLi4uPjo6dmFsdWUsIFQqPjo6dHlwZQogICAgewogICAgCXN0ZDo6Y291dCA8PCAicHVzaF9iYWNrIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgcHRycy5wdXNoX2JhY2soVHsgc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uIH0pOwogICAgICAgIHJldHVybiAmcHRycy5iYWNrKCk7CiAgICB9CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQgPSBUeXBlLCB0eXBlbmFtZS4uLiBBcmdzPgogICAgYXV0byBjcmVhdGUoQXJncyYmLi4uIGFyZ3MpIC0+IHR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPHN0ZDo6aXNfY29uc3RydWN0aWJsZTxULCBBcmdzLi4uPjo6dmFsdWUsIFQqPjo6dHlwZQogICAgewogICAgCXN0ZDo6Y291dCA8PCAiZW1wbGFjZV9iYWNrIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgcHRycy5lbXBsYWNlX2JhY2soc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKTsKICAgICAgICByZXR1cm4gJnB0cnMuYmFjaygpOwogICAgfQp9OwoKY2xhc3MgcHVibGljX2N0b3IKewogICAgaW50IGk7CgpwdWJsaWM6CiAgICBwdWJsaWNfY3RvcihpbnQgaSk6IGkoaSkge30gLy8gcHVibGljCn07CgpjbGFzcyBwcml2YXRlX2N0b3IKewogICAgZnJpZW5kIGNsYXNzIHB0cl9zY29wZV9tYW5hZ2VyPHByaXZhdGVfY3Rvcj47CiAgICBpbnQgaTsKCnByaXZhdGU6CiAgICBwcml2YXRlX2N0b3IoaW50IGkpOiBpKGkpIHt9IC8vIHByaXZhdGUKfTsKCmNsYXNzIG5vbl9mcmllbmRseV9wcml2YXRlX2N0b3IKeyAgICBpbnQgaTsKCnByaXZhdGU6CiAgICBub25fZnJpZW5kbHlfcHJpdmF0ZV9jdG9yKGludCBpKTogaShpKSB7fSAvLyBwcml2YXRlCn07CgoKaW50IG1haW4oKQp7CiAgICBwdHJfc2NvcGVfbWFuYWdlcjxwdWJsaWNfY3Rvcj4gcHVibGljX21hbmFnZXI7CiAgICBwdHJfc2NvcGVfbWFuYWdlcjxwcml2YXRlX2N0b3I+IHByaXZhdGVfbWFuYWdlcjsKICAgIHB0cl9zY29wZV9tYW5hZ2VyPG5vbl9mcmllbmRseV9wcml2YXRlX2N0b3I+IG5vbl9mcmllbmRseV9wcml2YXRlX21hbmFnZXI7CgogICAgcHVibGljX21hbmFnZXIuY3JlYXRlKDMpOwoKICAgIHByaXZhdGVfbWFuYWdlci5jcmVhdGUoMyk7CgogICAgLy8gbm9uX2ZyaWVuZGx5X3ByaXZhdGVfbWFuYWdlci5jcmVhdGUoMyk7IHJhaXNlcyBlcnJvcgp9Cg==