diff --git a/research/try.cpp b/research/try.cpp index f8190b934..afe11ee2f 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -48,12 +48,14 @@ typedef unsigned int uint; #include "lib/format-cout.hpp" #include "lib/depend.hpp" #include "lib/depend2.hpp" +#include "lib/meta/util.hpp" //#include "lib/meta/util.hpp" #include "lib/test/test-helper.hpp" #include "lib/util.hpp" #include #include +#include #define SHOW_TYPE(_TY_) \ @@ -62,9 +64,64 @@ typedef unsigned int uint; cout << "Probe " << STRINGIFY(_XX_) << " ? = " << _XX_ < + class InstanceHolder + : boost::noncopyable + { + /** storage for the service instance */ + char buff_[sizeof(TAR)]; + bool alive_ = false; + + + public: + ~InstanceHolder() + { + if (alive_) + try { + alive_ = false; + reinterpret_cast (buff_). ~TAR(); + } + catch(...) + { // no logging since we might be in static shutdown + lumiera_error(); // reset errorflag + } + } + + + TAR* + buildInstance() + { + if (alive_) + 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); + + // place new instance into embedded buffer + TAR* newInstance = new(&buff_) TAR (); + alive_ = true; + return newInstance; + } + }; + + 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."); + } + }; @@ -74,14 +131,16 @@ class DependInject; template class Depend { + public: using Factory = std::function; static SRV* instance; static Factory factory; + static InstanceHolder singleton; + friend class DependInject; - public: SRV& operator() () { @@ -101,8 +160,7 @@ class Depend { if (!factory) { - static SRV singleton{}; - instance = &singleton; + instance = singleton.buildInstance(); factory = disabledFactory; } else @@ -125,17 +183,29 @@ SRV* Depend::instance; template typename Depend::Factory Depend::factory; +template +InstanceHolder Depend::singleton; + + +struct Dum + : boost::noncopyable + { + virtual ~Dum() { } + virtual int probe() =0; + }; + + int checksum = 0; template struct Dummy - : boost::noncopyable + : Dum { Dummy() { checksum += N; } ~Dummy() { checksum -= N; } - int + virtual int probe() { return N * checksum; @@ -161,6 +231,10 @@ main (int, char**) SHOW_EXPR( dep12().probe() ); SHOW_EXPR( checksum ); + Depend dumm; + Depend::factory = [](){ return nullptr; }; + SHOW_EXPR( dumm().probe() ); + cout << "\n.gulp.\n"; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 7ae326b65..8f1b18fdf 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -26995,13 +26995,39 @@ + + + + + + + + + + + + + + + + +

+ ...aber dann eben nicht mehr elegant. +

+ + +
+
+ + +
- +