/******************************************************************************
Online C++ Compiler.
Code, Compile, Run and Debug C++ program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <iostream>
#include <new>
#include <stdint.h>
using namespace std;
class RomObject
{
public:
constexpr RomObject() {}
};
template<typename T, class Enable = void>
class Singleton
{
public:
Singleton(const Singleton&) = delete;
Singleton& operator = (const Singleton&) = delete;
static constexpr T& GetInstance()
{
return instance;
}
static const std::string& where()
{
static std::string me = "RAM";
return me;
}
protected:
static T instance;
Singleton() = delete;
};
template<typename T, class Enable>
T Singleton<T,Enable>::instance ;
template<typename T>
class Singleton<T, typename std::enable_if_t<std::is_base_of<RomObject, T>::value>>
{
public:
Singleton(const Singleton&) = delete;
Singleton& operator = (const Singleton&) = delete;
static constexpr const T& GetInstance()
{
return instance;
}
static const std::string& where()
{
static std::string me = "ROM";
return me;
}
protected:
constexpr Singleton() = delete;
static constexpr T instance{T()} ;
};
template<typename T>
constexpr T Singleton<T, typename std::enable_if_t<std::is_base_of<RomObject, T>::value>>::instance ;
class IA
{
public:
virtual int Get() const = 0;
};
class B
{
friend class Singleton<B>;
public:
const B & operator=(const B &) = delete ;
int GetB() const
{
return b;
};
void setB(int v)
{
b = v;
}
private:
B() : b(23) {};
B(const B &) = default ;
int b;
};
class C : public RomObject
{
friend class Singleton<C> ;
public:
const C & operator=(const C &) = delete ;
int d;
private:
constexpr C() : d(6) {};
constexpr C(const C & obj) = default ;
};
class D
{
public:
int d;
};
class A : public RomObject, public IA
{
friend class Singleton<A>;
public:
const A & operator=(const A &) = delete ;
int Get() const override
{
return test.GetB();
}
void set(int v) const
{
test.setB(v);
}
private:
constexpr A(const A &) = default ;
B& test; //refence on object in RAM
const C& test2; //refence on object in ROM
constexpr A() :
test(Singleton<B>::GetInstance()),
test2(Singleton<C>::GetInstance())
{
}
};
int main()
{
//Singleton<A>::GetInstance().set(10) ;
cout<<"GetB - "<<Singleton<A>::GetInstance().Get()<<std::endl;
cout<<"Singleton<A> - "<<Singleton<A>::where().data()<<std::endl;
cout<<"Singleton<B> - "<<Singleton<B>::where().data()<<std::endl;
cout<<"Singleton<C> - "<<Singleton<C>::where().data()<<std::endl;
cout<<"Singleton<D> - "<<Singleton<D>::where().data()<<std::endl;
cout<<"Singleton<A> - "<<&Singleton<A>::GetInstance()<<std::endl;
cout<<"Singleton<B> - "<<&Singleton<B>::GetInstance()<<std::endl;
cout<<"Singleton<C> - "<<&Singleton<C>::GetInstance()<<std::endl;
cout<<"Singleton<D> - "<<&Singleton<D>::GetInstance()<<std::endl;
return 0;
}