#include <iostream>
#include <memory>
template<typename T>
struct Key
{
friend T;
};
class Service;
class Session
{
private:
Session(Service const&) {}
public:
void run() { std::cout << "Running!\n"; }
// has access to private members of enclosing Session (C++11)
class Guard;
};
class Session::Guard
{
public:
Guard(Service const& s, Key<Service>): enclosing(s) {}
Session* operator->() { return &enclosing; }
private:
Session enclosing;
};
class Service
{
public:
std::shared_ptr<Session::Guard> CreateSession()
{
return std::make_shared<Session::Guard>(*this, Key<Service>{});
}
};
int main()
{
Service s;
auto ss = s.CreateSession();
(*ss)->run();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgogCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBLZXkKewogICAgZnJpZW5kIFQ7Cn07CiAKY2xhc3MgU2VydmljZTsKIApjbGFzcyBTZXNzaW9uCnsKcHJpdmF0ZToKICAgIFNlc3Npb24oU2VydmljZSBjb25zdCYpIHt9CiAgICAKcHVibGljOgogICAgdm9pZCBydW4oKSB7IHN0ZDo6Y291dCA8PCAiUnVubmluZyFcbiI7IH0KIAogICAgLy8gaGFzIGFjY2VzcyB0byBwcml2YXRlIG1lbWJlcnMgb2YgZW5jbG9zaW5nIFNlc3Npb24gKEMrKzExKQogICAgY2xhc3MgR3VhcmQ7ICAgIAp9OwogCmNsYXNzIFNlc3Npb246Okd1YXJkCnsKcHVibGljOgogICAgR3VhcmQoU2VydmljZSBjb25zdCYgcywgS2V5PFNlcnZpY2U+KTogZW5jbG9zaW5nKHMpIHt9CiAgICBTZXNzaW9uKiBvcGVyYXRvci0+KCkgeyByZXR1cm4gJmVuY2xvc2luZzsgfQogICAgCnByaXZhdGU6CiAgICBTZXNzaW9uIGVuY2xvc2luZzsKfTsKIApjbGFzcyBTZXJ2aWNlCnsKcHVibGljOgogICAgc3RkOjpzaGFyZWRfcHRyPFNlc3Npb246Okd1YXJkPiBDcmVhdGVTZXNzaW9uKCkgCiAgICB7IAogICAgICAgIHJldHVybiBzdGQ6Om1ha2Vfc2hhcmVkPFNlc3Npb246Okd1YXJkPigqdGhpcywgS2V5PFNlcnZpY2U+e30pOyAgICAgICAgIAogICAgfQp9OwogCmludCBtYWluKCkKewogICAgU2VydmljZSBzOwogICAgYXV0byBzcyA9IHMuQ3JlYXRlU2Vzc2lvbigpOwogICAgKCpzcyktPnJ1bigpOwp9