From 439fbb1433c31504bee2b79072062bbb66ae4e7a Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Tue, 26 Oct 2021 05:10:40 -0400 Subject: [PATCH] StaticValue helper. Incorporated into `Testing`, for now. Semi-threadsafe statics, initialize them before going multithreaded. --- Testing/test.h | 12 +++++------ Utility/StaticValue.h | 47 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 Utility/StaticValue.h diff --git a/Testing/test.h b/Testing/test.h index e0654e9..e7fe23a 100644 --- a/Testing/test.h +++ b/Testing/test.h @@ -15,6 +15,8 @@ static_assert( __cplusplus > 201700, "C++17 Required" ); #include #include +#include +#include namespace Alepha::Hydrogen::Testing { @@ -34,6 +36,8 @@ namespace Alepha::Hydrogen::Testing } using namespace std::literals::string_literals; + using namespace Utility::exports::evaluation; + using namespace Utility::exports::static_value; struct TestName { @@ -65,12 +69,8 @@ namespace Alepha::Hydrogen::Testing } } - inline auto & - registry() - { - static std::vector< std::tuple< std::string, bool, std::function< void() > > > registry; - return registry; - } + StaticValue< std::vector< std::tuple< std::string, bool, std::function< void() > > > > registry; + auto initRegistry= enroll <=registry; // It is okay to discard this, if making tests in an enroll block. inline auto diff --git a/Utility/StaticValue.h b/Utility/StaticValue.h new file mode 100644 index 0000000..d80bb99 --- /dev/null +++ b/Utility/StaticValue.h @@ -0,0 +1,47 @@ +static_assert( __cplusplus > 201700, "C++17 Required" ); + +#pragma once + +namespace Alepha::Hydrogen::Utility +{ + inline namespace exports { inline namespace static_value {} } + + namespace detail::static_value + { + inline namespace exports {} + + template< typename T > + struct default_init + { + T *operator()() const { return new T{}; } + }; + + namespace exports + { + template< typename T, typename Init= default_init< T > > + struct StaticValue; + } + + template< typename T, typename Init > + struct exports::StaticValue + { + private: + T *storage= nullptr; + + public: + decltype( auto ) + get() + { + if( not storage ) storage= Init{}(); + return *storage; + } + + decltype( auto ) operator ()() { return get(); } + }; + } + + namespace exports::static_value + { + using namespace detail::static_value::exports; + } +}