#include <memory>
#include <type_traits>
template<bool> struct copyable {};
template<> struct copyable<false>
{
copyable() = default; // default constructible
copyable(copyable const&) = delete; // but not copyable
};
template<typename T>
class Container : copyable<std::is_copy_constructible<T>::value> {
T t;
public:
Container() = default;
Container(const Container& other) : t(other.t) {}
Container(Container&& other) : t(std::move(other.t)) {}
};
static_assert(std::is_copy_constructible<Container<int>>::value, "Non-Copyable");
static_assert(!std::is_copy_constructible<Container<std::unique_ptr<int>>>::value, "Copyable");
Container<std::unique_ptr<int>> makeNonCopyableContainer() {
return Container<std::unique_ptr<int>>();
}
int main () {
Container<int> c1;
Container<int> c2(c1);
Container<std::unique_ptr<int>> c3;
// This would generate compile error:
// Container<std::unique_ptr<int>> c4(c3);
Container<std::unique_ptr<int>> c5(makeNonCopyableContainer());
return 0;
}
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGU8Ym9vbD4gc3RydWN0IGNvcHlhYmxlIHt9Owp0ZW1wbGF0ZTw+IHN0cnVjdCBjb3B5YWJsZTxmYWxzZT4KewogIGNvcHlhYmxlKCkgPSBkZWZhdWx0OyAgICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQgY29uc3RydWN0aWJsZQogIGNvcHlhYmxlKGNvcHlhYmxlIGNvbnN0JikgPSBkZWxldGU7ICAgIC8vIGJ1dCBub3QgY29weWFibGUKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmNsYXNzIENvbnRhaW5lciA6IGNvcHlhYmxlPHN0ZDo6aXNfY29weV9jb25zdHJ1Y3RpYmxlPFQ+Ojp2YWx1ZT4gewoJVCB0OwpwdWJsaWM6CiAgICBDb250YWluZXIoKSA9IGRlZmF1bHQ7CgogICAgQ29udGFpbmVyKGNvbnN0IENvbnRhaW5lciYgb3RoZXIpIDogdChvdGhlci50KSB7fQogICAgCiAgICBDb250YWluZXIoQ29udGFpbmVyJiYgb3RoZXIpIDogdChzdGQ6Om1vdmUob3RoZXIudCkpIHt9Cn07CgpzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfY29weV9jb25zdHJ1Y3RpYmxlPENvbnRhaW5lcjxpbnQ+Pjo6dmFsdWUsICJOb24tQ29weWFibGUiKTsKc3RhdGljX2Fzc2VydCghc3RkOjppc19jb3B5X2NvbnN0cnVjdGlibGU8Q29udGFpbmVyPHN0ZDo6dW5pcXVlX3B0cjxpbnQ+Pj46OnZhbHVlLCAiQ29weWFibGUiKTsKCkNvbnRhaW5lcjxzdGQ6OnVuaXF1ZV9wdHI8aW50Pj4gbWFrZU5vbkNvcHlhYmxlQ29udGFpbmVyKCkgewogICAgcmV0dXJuIENvbnRhaW5lcjxzdGQ6OnVuaXF1ZV9wdHI8aW50Pj4oKTsKfQoKaW50IG1haW4gKCkgeyAKICAgIENvbnRhaW5lcjxpbnQ+IGMxOwogICAgQ29udGFpbmVyPGludD4gYzIoYzEpOwogICAgQ29udGFpbmVyPHN0ZDo6dW5pcXVlX3B0cjxpbnQ+PiBjMzsKICAgIC8vIFRoaXMgd291bGQgZ2VuZXJhdGUgY29tcGlsZSBlcnJvcjoKICAgIC8vIENvbnRhaW5lcjxzdGQ6OnVuaXF1ZV9wdHI8aW50Pj4gYzQoYzMpOwogICAgQ29udGFpbmVyPHN0ZDo6dW5pcXVlX3B0cjxpbnQ+PiBjNShtYWtlTm9uQ29weWFibGVDb250YWluZXIoKSk7CiAgICByZXR1cm4gMDsKfQ==