#include <iostream>
#include <memory>
#include <functional>
using namespace std;
struct Trace
{
Trace() : src("()") { cout << "X()\n"; }
Trace(Trace const &) : src("(&)") { cout << "X(X&)\n"; }
Trace(Trace&&) : src("(&&)") { cout << "X(X&&)\n"; }
~Trace() { cout << "~X" << src << "\n"; }
void operator=(Trace const &) { cout << "X::op=(X&)\n"; }
void operator=(Trace &&) { cout << "X::op=(X&&)\n"; }
std::string src;
};
struct Game
{
static std::function<void()> later;
static void idle( std::function<void()> func, int x )
{ std::cout << "x = " << x << "\n"; later = func; }
static void cleanup() { if ( later ) later(); }
};
struct Player: Trace, std::enable_shared_from_this<Player>
{
void death() { std::cout << "player.death\n"; }
void kill() { Game::idle( std::bind(&Player::death, shared_from_this()), 48 ); }
Player() {}
};
int main()
{
{
auto p = std::make_shared<Player>();
p->kill();
}
std::cout << "beginning cleanup\n";
Game::cleanup();
}
std::function<void()> Game::later;
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpzdHJ1Y3QgVHJhY2UKewoJVHJhY2UoKSAJCQkJCQk6IHNyYygiKCkiKQkJeyBjb3V0IDw8ICJYKClcbiI7IH0KCVRyYWNlKFRyYWNlIGNvbnN0ICYpCQkJOiBzcmMoIigmKSIpCXsgY291dCA8PCAiWChYJilcbiI7IH0KCVRyYWNlKFRyYWNlJiYpCQkJCQk6IHNyYygiKCYmKSIpCXsgY291dCA8PCAiWChYJiYpXG4iOyB9Cgl+VHJhY2UoKSAJCQkJCQl7IGNvdXQgPDwgIn5YIiA8PCBzcmMgPDwgIlxuIjsgfQoJdm9pZCBvcGVyYXRvcj0oVHJhY2UgY29uc3QgJikgCXsgY291dCA8PCAiWDo6b3A9KFgmKVxuIjsgfQoJdm9pZCBvcGVyYXRvcj0oVHJhY2UgJiYpIAkJeyBjb3V0IDw8ICJYOjpvcD0oWCYmKVxuIjsgfQoKCXN0ZDo6c3RyaW5nIHNyYzsKfTsKCnN0cnVjdCBHYW1lIAp7IAoJc3RhdGljIHN0ZDo6ZnVuY3Rpb248dm9pZCgpPiBsYXRlcjsKCiAgICBzdGF0aWMgdm9pZCBpZGxlKCBzdGQ6OmZ1bmN0aW9uPHZvaWQoKT4gZnVuYywgaW50IHggKQogICAgICAgIHsgc3RkOjpjb3V0IDw8ICJ4ID0gIiA8PCB4IDw8ICJcbiI7IGxhdGVyID0gZnVuYzsgfQoKCXN0YXRpYyB2b2lkIGNsZWFudXAoKSB7IGlmICggbGF0ZXIgKSBsYXRlcigpOyB9Cn07CgpzdHJ1Y3QgUGxheWVyOiBUcmFjZSwgc3RkOjplbmFibGVfc2hhcmVkX2Zyb21fdGhpczxQbGF5ZXI+CnsKICAgICB2b2lkIGRlYXRoKCkgeyBzdGQ6OmNvdXQgPDwgInBsYXllci5kZWF0aFxuIjsgfQogICAgIHZvaWQga2lsbCgpIHsgR2FtZTo6aWRsZSggc3RkOjpiaW5kKCZQbGF5ZXI6OmRlYXRoLCBzaGFyZWRfZnJvbV90aGlzKCkpLCA0OCApOyB9CgkgUGxheWVyKCkge30KfTsKCmludCBtYWluKCkKewoJewoJCWF1dG8gcCA9IHN0ZDo6bWFrZV9zaGFyZWQ8UGxheWVyPigpOwogICAgCXAtPmtpbGwoKTsKCX0KCXN0ZDo6Y291dCA8PCAiYmVnaW5uaW5nIGNsZWFudXBcbiI7CglHYW1lOjpjbGVhbnVwKCk7Cn0KCnN0ZDo6ZnVuY3Rpb248dm9pZCgpPiBHYW1lOjpsYXRlcjsK