diff --git a/Logger.hpp b/Logger.hpp new file mode 100644 index 0000000..ff44ab2 --- /dev/null +++ b/Logger.hpp @@ -0,0 +1,21 @@ +#ifndef LOGGER_HPP +#define LOGGER_HPP + +#include +#include // move + +#include "Singleton_DCLP.hpp" + +class Logger : public Singleton_DCLP +{ +public: + void setStream(std::ostream* os) { m_os = os; } + std::ostream* getStream() { return m_os; } +private: + // ostreams are not copyable, hence storing a pointer only + std::ostream* m_os; +}; + +#define LOG *Logger::getInstance()->getStream() + +#endif // LOGGER_HPP diff --git a/Singleton_DCLP.hpp b/Singleton_DCLP.hpp new file mode 100644 index 0000000..755800b --- /dev/null +++ b/Singleton_DCLP.hpp @@ -0,0 +1,55 @@ +#ifndef SINGLETON_DCLP_HPP +#define SINGLETON_DCLP_HPP + +#include + +template +class Singleton_DCLP +{ +public: + + Singleton_DCLP() {}; + virtual ~Singleton_DCLP() + { + if (m_instance) + delete m_instance; + }; + + Singleton_DCLP( const Singleton_DCLP& ) = delete; + Singleton_DCLP& operator=( const Singleton_DCLP& ) = delete; + + + /** I knowthat c++-11 has the "atomic initializers" and this can be + * replaced with: + * + * static T getInstance() + * { + * static Singleton instance; + * return instance; + * } + * + * But that is not supported in Visual Studio 2012 SP4 + * https://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/ + */ + static T* getInstance() + { + if (!m_instance) { + std::lock_guard guard(m_lock); + if (!m_instance) { + volatile T *temp = new T(); + m_instance = (T*)temp; + } + } + return (T*)m_instance; + } + +private: + static std::mutex m_lock; + static volatile T* m_instance; +}; + +template std::mutex Singleton_DCLP::m_lock; +template volatile T* Singleton_DCLP::m_instance = 0; + + +#endif // SINGLETON_DCLP_HPP diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..a766323 --- /dev/null +++ b/main.cpp @@ -0,0 +1,15 @@ +#include +#include + +#include "Logger.hpp" + +int main(int /*argc*/, char* /*argv*/[]) +{ + Logger::getInstance()->setStream(&std::cout); + + + LOG << "hello" << std::endl; + + return EXIT_SUCCESS; +} +