/*============================================================================= Copyright (c) 2011-2019 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef TESTSPR_SINGLETON_HPP #define TESTSPR_SINGLETON_HPP #include #include #include namespace testspr { // // singleton_module // class singleton_module : public sprout::noncopyable { private: static inline SPROUT_NON_CONSTEXPR bool& get_lock() { static bool lock = false; return lock; } public: static inline SPROUT_NON_CONSTEXPR void lock() { get_lock() = true; } static inline SPROUT_NON_CONSTEXPR void unlock() { get_lock() = false; } static inline SPROUT_NON_CONSTEXPR bool is_locked() { return get_lock(); } }; namespace detail { template class singleton_wrapper : public T { public: static bool m_is_destroyed; public: ~singleton_wrapper() { m_is_destroyed = true; } }; template bool testspr::detail::singleton_wrapper::m_is_destroyed = false; } // namespace detail // // singleton // template class singleton : public testspr::singleton_module { public: typedef T instance_type; private: static instance_type& instance; private: static inline SPROUT_NON_CONSTEXPR void use(const instance_type&) {} static inline SPROUT_NON_CONSTEXPR instance_type& get_instance() { static detail::singleton_wrapper t; SPROUT_ASSERT(!testspr::detail::singleton_wrapper::m_is_destroyed); use(instance); return static_cast(t); } public: static inline SPROUT_NON_CONSTEXPR instance_type& get_mutable_instance() { SPROUT_ASSERT(!is_locked()); return get_instance(); } static inline SPROUT_NON_CONSTEXPR instance_type const& get_const_instance() { return get_instance(); } static inline SPROUT_NON_CONSTEXPR bool is_destroyed() { return testspr::detail::singleton_wrapper::m_is_destroyed; } }; template T& singleton::instance = testspr::singleton::get_instance(); } // namespace testspr #endif // #ifndef TESTSPR_SINGLETON_HPP