#include <iostream>
#include <memory>


template<typename T>
struct Holder {
   Holder() {
      std::cout << "Holder()::Holder()" << std::endl;
      if (!Self)  Self = new T();
      Self->Init();
   }
   ~Holder() {
      if (Self) {
         Self->Cleanup();
         delete Self;
         std::cout << "~Holder()::Holder()" << std::endl;
      }
   }
   T* Self = nullptr;
};

class SomeClass
{
public:
   void Init(){}
   void Cleanup() {}
   int member;
};

////////////////////////////////////////////////////////////////////////////////////////

template <typename T>
class Singleton {
public:
   static T* Instance() {
      std::cout << "Singlton::Instance()" << std::endl;
      static Holder<T> Dummy;
      return Dummy.Self;
   }
private:
   Singleton() = delete;
   Singleton(Singleton const&) = delete;
   Singleton& operator= (Singleton const&) = delete;
   Singleton(Singleton const&&) = delete;
   Singleton& operator= (Singleton const&&) = delete;
};

int main()
{
   {
      auto pInst = Singleton<SomeClass>::Instance();
      pInst->member = 10;
      std::cout << pInst->member << std::endl;
      std::unique_ptr<SomeClass> pObj(pInst);
   }
   auto pInst = Singleton<SomeClass>::Instance();
   pInst->member = 20;

   return 0;
}
