#include <iostream>
using namespace std;

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

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;
};

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

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;
};

class Global {
  public:
    int GetA() { 
      cout << "GetA" << endl;
      return x-1; 
    }
    int GetB() { 
      cout << "GetB" << endl;    	
      return x+1; 
    }
    void Init() {};
    void Cleanup() {};
  private:
    int x = 1;
};

struct Test1Class {
  void Print() {
    cout << Singleton<Global>::Instance()->GetA() << endl;  	
  }	
};

struct Test2Class {
  void Print() {
    cout << Singleton<Global>::Instance()->GetB() << endl;  	
  }	
};


int main() {
  Test1Class T1;
  Test2Class T2;
  T1.Print();
  T2.Print();
  return 0;
}