diff --git a/include/internal/catch_registry_hub.cpp b/include/internal/catch_registry_hub.cpp index d98708c5..cfbd2e05 100644 --- a/include/internal/catch_registry_hub.cpp +++ b/include/internal/catch_registry_hub.cpp @@ -14,6 +14,7 @@ #include "catch_exception_translator_registry.h" #include "catch_tag_alias_registry.h" #include "catch_startup_exception_registry.h" +#include "catch_singletons.hpp" namespace Catch { @@ -84,6 +85,7 @@ namespace Catch { return *getTheRegistryHub(); } void cleanUp() { + cleanupSingletons(); delete getTheRegistryHub(); getTheRegistryHub() = nullptr; cleanUpContext(); diff --git a/include/internal/catch_singletons.cpp b/include/internal/catch_singletons.cpp new file mode 100644 index 00000000..e5367cad --- /dev/null +++ b/include/internal/catch_singletons.cpp @@ -0,0 +1,36 @@ +/* + * Created by Phil Nash on 15/6/2018. + * + * 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) + */ + +#include "catch_singletons.hpp" + +#include + +namespace Catch { + + namespace { + static auto getSingletons() -> std::vector*& { + static std::vector* g_singletons = nullptr; + if( !g_singletons ) + g_singletons = new std::vector(); + return g_singletons; + } + } + + ISingleton::~ISingleton() {} + + void addSingleton(ISingleton* singleton ) { + getSingletons()->push_back( singleton ); + } + void cleanupSingletons() { + auto& singletons = getSingletons(); + for( auto singleton : *singletons ) + delete singleton; + delete singletons; + singletons = nullptr; + } + +} // namespace Catch diff --git a/include/internal/catch_singletons.hpp b/include/internal/catch_singletons.hpp new file mode 100644 index 00000000..fbc4b32c --- /dev/null +++ b/include/internal/catch_singletons.hpp @@ -0,0 +1,44 @@ +/* + * Created by Phil Nash on 15/6/2018. + * + * 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 TWOBLUECUBES_CATCH_SINGLETONS_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_SINGLETONS_HPP_INCLUDED + +namespace Catch { + + struct ISingleton { + virtual ~ISingleton(); + }; + + + void addSingleton( ISingleton* singleton ); + void cleanupSingletons(); + + + template + class Singleton : SingletonImplT, public ISingleton { + + static auto getInternal() -> Singleton* { + static Singleton* s_instance = nullptr; + if( !s_instance ) { + s_instance = new Singleton; + addSingleton( s_instance ); + } + return s_instance; + } + + public: + static auto get() -> InterfaceT const& { + return *getInternal(); + } + static auto getMutable() -> MutableInterfaceT& { + return *getInternal(); + } + }; + +} // namespace Catch + +#endif // TWOBLUECUBES_CATCH_SINGLETONS_HPP_INCLUDED diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index 2084c745..70aca2f2 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -117,6 +117,7 @@ set(INTERNAL_HEADERS ${HEADER_DIR}/internal/catch_section.h ${HEADER_DIR}/internal/catch_section_info.h ${HEADER_DIR}/internal/catch_session.h + ${HEADER_DIR}/internal/catch_singletons.hpp ${HEADER_DIR}/internal/catch_startup_exception_registry.h ${HEADER_DIR}/internal/catch_stream.h ${HEADER_DIR}/internal/catch_stringref.h @@ -183,6 +184,7 @@ set(IMPL_SOURCES ${HEADER_DIR}/internal/catch_section.cpp ${HEADER_DIR}/internal/catch_section_info.cpp ${HEADER_DIR}/internal/catch_session.cpp + ${HEADER_DIR}/internal/catch_singletons.cpp ${HEADER_DIR}/internal/catch_startup_exception_registry.cpp ${HEADER_DIR}/internal/catch_stream.cpp ${HEADER_DIR}/internal/catch_stringref.cpp