From 5fc85df38531849aa0d7e0772573dc1d65d8bdb8 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 29 Mar 2018 16:57:55 +0200 Subject: [PATCH] DI: inline into lib::Depend to obsolete InstanceHolder but now we've got two factory functors. So there is yet more potential for simplification & refactoring --- src/lib/depend2.hpp | 97 ++++++++++++----------- src/lib/format-obj.cpp | 2 +- tests/library/singleton-subclass-test.cpp | 3 +- tests/library/singleton-test.cpp | 2 +- wiki/thinkPad.ichthyo.mm | 16 ++++ 5 files changed, 69 insertions(+), 51 deletions(-) diff --git a/src/lib/depend2.hpp b/src/lib/depend2.hpp index 179ad53fb..f4eb79f83 100644 --- a/src/lib/depend2.hpp +++ b/src/lib/depend2.hpp @@ -105,49 +105,6 @@ namespace lib { namespace error = lumiera::error; - namespace { // Implementation helper... - - using lib::meta::enable_if; - - template - class InstanceHolder - : util::NonCopyable - { - std::unique_ptr instance_; - - public: - TAR* - buildInstance() - { - return buildInstance ([]{ return new TAR{}; }); - } - - template - TAR* - buildInstance(FUN&& ctor) - { - if (instance_) - throw error::Fatal("Attempt to double-create a singleton service. " - "Either the application logic, or the compiler " - "or runtime system is seriously broken" - ,error::LUMIERA_ERROR_LIFECYCLE); - instance_.reset (ctor()); - return instance_.get(); - } - }; - - template - class InstanceHolder>> - { - public: - ABS* - buildInstance(...) - { - throw error::Fatal("Attempt to create a singleton instance of an abstract class. " - "Application architecture or lifecycle is seriously broken."); - } - }; - }//(End)Implementation helper @@ -181,8 +138,6 @@ namespace lib { static std::atomic instance; static Factory factory; - static InstanceHolder singleton; - friend class DependInject; @@ -204,7 +159,13 @@ namespace lib { if (!object) { if (!factory) - object = singleton.buildInstance(); + { + object = buildInstance(); + deleter = []{ + destroy (instance); + instance = nullptr; + }; + } else object = factory(); factory = disabledFactory; @@ -224,6 +185,48 @@ namespace lib { throw error::Fatal("Service not available at this point of the Application Lifecycle" ,error::LUMIERA_ERROR_LIFECYCLE); } + + template + static meta::enable_if, + ABS* > + buildInstance() + { + throw error::Fatal("Attempt to create a singleton instance of an abstract class. " + "Application architecture or lifecycle is seriously broken."); + } + template + static meta::disable_if, + TAR* > + buildInstance() + { + return new TAR; + } + + static void + destroy (SRV* obj) + { + if (obj) + delete obj; + } + + class Deleter + { + std::function cleanUp_; + + public: + ~Deleter() + { + if (cleanUp_) + cleanUp_(); + } + template + void operator= (DEL&& fun) + { + cleanUp_ = std::forward (fun); + } + }; + + static Deleter deleter; }; @@ -237,7 +240,7 @@ namespace lib { typename Depend::Factory Depend::factory; template - InstanceHolder Depend::singleton; + typename Depend::Deleter Depend::deleter; diff --git a/src/lib/format-obj.cpp b/src/lib/format-obj.cpp index 2e6a57848..f2cdc0216 100644 --- a/src/lib/format-obj.cpp +++ b/src/lib/format-obj.cpp @@ -306,7 +306,7 @@ apologies for that." static regex identifierChars {"[A-Za-z]\\w*", regex::ECMAScript | regex::optimize}; return regex_replace (text, identifierChars, "$&", std::regex_constants::format_no_copy); - } + } // don't copy what does not match diff --git a/tests/library/singleton-subclass-test.cpp b/tests/library/singleton-subclass-test.cpp index 567308eea..90f9a76e9 100644 --- a/tests/library/singleton-subclass-test.cpp +++ b/tests/library/singleton-subclass-test.cpp @@ -66,8 +66,7 @@ namespace test{ Interface () : TestTargetObj(cnt) {} virtual ~Interface() {} - friend class lib::InstanceHolder; - friend class std::default_delete; + friend class lib::Depend; }; int Interface::cnt = 0; diff --git a/tests/library/singleton-test.cpp b/tests/library/singleton-test.cpp index 4a57c7060..6ae29744d 100644 --- a/tests/library/singleton-test.cpp +++ b/tests/library/singleton-test.cpp @@ -59,7 +59,7 @@ namespace test{ protected: TargetObj () : TestTargetObj(cnt) {} - friend class lib::InstanceHolder; + friend class lib::Depend; }; int TargetObj::cnt = 0; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 412f893c8..fc70113b5 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -27802,6 +27802,22 @@ + + + + + + + + + + + + + + + +