#ifndef SINGLETON_H_
#define SINGLETON_H_

#include <utility>

namespace f4ll {

template <typename T> class singleton
{
public:
    static T &instance()
    {
        return *m_instance;
    }
    template <typename... args_t> static T &init(args_t &&...args)
    {
        static T instance{std::forward<args_t>(args)...};
        m_instance = &instance;
        return instance;
    }

protected:
    singleton() = default;
    singleton(const singleton &) = delete;
    singleton &operator=(const singleton &) = delete;
    static T *m_instance;
};

template <typename T> T *singleton<T>::m_instance = nullptr;

} //  namespace f1ll {

#endif /* SINGLETON_H_ */
