#include <iostream>
#include <type_traits>
#include <memory>
template<typename Derived>
struct PImplMagic
{
PImplMagic()
{
static_assert(std::is_base_of<PImplMagic, Derived>::value,
"Template parameter must be deriving class");
}
//protected: //has to be public, unfortunately
struct Impl;
};
struct Test : private PImplMagic<Test>, private std::unique_ptr<PImplMagic<Test>::Impl>
{
Test();
void f();
};
int main()
{
Test t;
t.f();
}
template<>
struct PImplMagic<Test>::Impl
{
Impl()
{
std::cout << "It works!" << std::endl;
}
int x = 7;
};
Test::Test()
: std::unique_ptr<Impl>(new Impl)
{
}
void Test::f()
{
std::cout << (*this)->x << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxtZW1vcnk+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBEZXJpdmVkPgpzdHJ1Y3QgUEltcGxNYWdpYwp7CglQSW1wbE1hZ2ljKCkKCXsKCQlzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfYmFzZV9vZjxQSW1wbE1hZ2ljLCBEZXJpdmVkPjo6dmFsdWUsCgkJICAgICAgICAgICAgICAiVGVtcGxhdGUgcGFyYW1ldGVyIG11c3QgYmUgZGVyaXZpbmcgY2xhc3MiKTsKCX0KLy9wcm90ZWN0ZWQ6IC8vaGFzIHRvIGJlIHB1YmxpYywgdW5mb3J0dW5hdGVseQoJc3RydWN0IEltcGw7Cn07CgpzdHJ1Y3QgVGVzdCA6IHByaXZhdGUgUEltcGxNYWdpYzxUZXN0PiwgcHJpdmF0ZSBzdGQ6OnVuaXF1ZV9wdHI8UEltcGxNYWdpYzxUZXN0Pjo6SW1wbD4KewoJVGVzdCgpOwoJdm9pZCBmKCk7Cn07CgppbnQgbWFpbigpCnsKCVRlc3QgdDsKCXQuZigpOwp9Cgp0ZW1wbGF0ZTw+CnN0cnVjdCBQSW1wbE1hZ2ljPFRlc3Q+OjpJbXBsCnsKCUltcGwoKQoJewoJCXN0ZDo6Y291dCA8PCAiSXQgd29ya3MhIiA8PCBzdGQ6OmVuZGw7Cgl9CglpbnQgeCA9IDc7Cn07CgpUZXN0OjpUZXN0KCkKOiBzdGQ6OnVuaXF1ZV9wdHI8SW1wbD4obmV3IEltcGwpCnsKfQoKdm9pZCBUZXN0OjpmKCkKewoJc3RkOjpjb3V0IDw8ICgqdGhpcyktPnggPDwgc3RkOjplbmRsOwp9Cg==