DI: verify and improve static sanity checks
esp. for subclass instance creation from within a lambda
This commit is contained in:
parent
d9af3abb0f
commit
364dcd5291
6 changed files with 65 additions and 55 deletions
|
|
@ -70,7 +70,12 @@ typedef unsigned int uint;
|
|||
int
|
||||
main (int, char**)
|
||||
{
|
||||
std::srand(std::time(nullptr));
|
||||
|
||||
// DependInject<long>::useSingleton ([&] { return "long{rand() % 100}"; });
|
||||
// DependInject<long>::Local<std::string> dummy ([&]{ return new long{rand() % 100}; });
|
||||
|
||||
cout << "rrrrrr.."<< Depend<long>{}() <<endl;
|
||||
|
||||
cout << "\n.gulp.\n";
|
||||
|
||||
|
|
|
|||
|
|
@ -97,16 +97,8 @@ namespace lib {
|
|||
static void
|
||||
useSingleton(FUN&& ctor)
|
||||
{
|
||||
using lib::meta::_Fun;
|
||||
using lib::meta::Strip;
|
||||
|
||||
static_assert (_Fun<FUN>::value, "Need a Lambda or Function object to create a heap allocated instance");
|
||||
|
||||
using Ret = typename _Fun<FUN>::Ret;
|
||||
using Sub = typename Strip<Ret>::TypePlain;
|
||||
|
||||
using Sub = typename SubclassFactory<FUN>::Sub;
|
||||
__assert_compatible<Sub>();
|
||||
static_assert (std::is_pointer<Ret>::value, "Function must yield a pointer to a heap allocated instance");
|
||||
|
||||
static InstanceHolder<Sub> singleton;
|
||||
installFactory ([ctor]()
|
||||
|
|
@ -199,6 +191,8 @@ namespace lib {
|
|||
Local (FUN&& buildInstance)
|
||||
{
|
||||
__assert_compatible<MOC>();
|
||||
__assert_compatible<typename SubclassFactory<FUN>::Sub>();
|
||||
|
||||
temporarilyInstallAlternateFactory (origInstance_, origFactory_
|
||||
,[=]()
|
||||
{
|
||||
|
|
@ -249,10 +243,24 @@ namespace lib {
|
|||
static void
|
||||
__assert_compatible()
|
||||
{
|
||||
static_assert (std::is_base_of<SRV,SUB>::value,
|
||||
"Installed implementation class must be compatible to the interface.");
|
||||
static_assert (meta::is_Subclass<SUB,SRV>()
|
||||
,"Installed implementation class must be compatible to the interface.");
|
||||
}
|
||||
|
||||
template<typename FUN>
|
||||
struct SubclassFactory
|
||||
{
|
||||
static_assert (meta::_Fun<FUN>(),
|
||||
"Need a Lambda or Function object to create a heap allocated instance");
|
||||
|
||||
using Res = typename meta::_Fun<FUN>::Ret;
|
||||
using Sub = typename meta::Strip<Res>::TypePlain;
|
||||
|
||||
static_assert (std::is_pointer<Res>::value,
|
||||
"Function must yield a pointer to a heap allocated instance");
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
installFactory (Factory&& otherFac)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -94,12 +94,15 @@ namespace meta {
|
|||
using std::remove_cv;
|
||||
using std::remove_pointer;
|
||||
using std::remove_reference;
|
||||
using std::is_pointer;
|
||||
using std::is_base_of;
|
||||
using std::is_convertible;
|
||||
using std::is_constructible;
|
||||
using std::is_floating_point;
|
||||
using std::is_arithmetic;
|
||||
using std::is_unsigned;
|
||||
using std::is_signed;
|
||||
using std::is_class;
|
||||
using std::is_same;
|
||||
using std::__not_;
|
||||
using std::__and_;
|
||||
|
|
@ -270,6 +273,17 @@ namespace meta {
|
|||
,typename Strip<U>::TypeReferred>
|
||||
{ };
|
||||
|
||||
/** verify compliance to an interface by subtype check */
|
||||
template<typename S, typename I>
|
||||
struct is_Subclass
|
||||
: __or_< __and_< is_class<I>
|
||||
, is_class<S>
|
||||
, is_base_of<I,S>
|
||||
>
|
||||
, is_same<I,S>
|
||||
>
|
||||
{ };
|
||||
|
||||
/** detect various flavours of string / text data */
|
||||
template<typename X>
|
||||
struct is_StringLike
|
||||
|
|
@ -311,8 +325,8 @@ namespace meta {
|
|||
/** when to use custom string conversions for output streams */
|
||||
template<typename X>
|
||||
struct use_StringConversion4Stream
|
||||
: __and_<std::is_class<typename Strip<X>::TypePlain>
|
||||
,__not_<std::is_pointer<X>>
|
||||
: __and_<is_class<typename Strip<X>::TypePlain>
|
||||
,__not_<is_pointer<X>>
|
||||
,__not_<can_lexical2string<X>>
|
||||
>
|
||||
{ };
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/meta/trait.hpp"
|
||||
#include "lib/iter-adapter.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
|
@ -136,8 +137,7 @@ namespace lib {
|
|||
TY&
|
||||
create (ARGS&& ...args)
|
||||
{
|
||||
static_assert ( (std::is_same<I,TY>::value
|
||||
||std::is_base_of<I,TY>::value)
|
||||
static_assert ( meta::is_Subclass<TY,I>()
|
||||
&& sizeof(TY) <= siz,
|
||||
"ElementHolder buffer to small");
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ namespace test {
|
|||
TRACE(test, "Test-Suite( groupID=%s )\n", groupID.c_str () );
|
||||
|
||||
// Seed random number generator
|
||||
std::srand (std::time (NULL));
|
||||
std::srand (std::time (nullptr));
|
||||
|
||||
if (!testcases.getGroup(groupID))
|
||||
throw lumiera::error::Invalid ("empty testsuite");
|
||||
|
|
|
|||
|
|
@ -26601,8 +26601,7 @@
|
|||
Bei <i>diesem</i> Wunsch-Profil bleibt nur eine Variante von <b>Lösung-2</b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -26612,8 +26611,7 @@
|
|||
...denn nur eine dynamische Laufzeit-Factory ermöglicht, <i>jederzeit</i>  den Konstruktionsmodus zu wechseln
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1521159238935" ID="ID_1109622706" MODIFIED="1521159663752" TEXT="Ein Instanz-Pointer ist zwingend notwendig und auch besser">
|
||||
|
|
@ -26658,8 +26656,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521159870784" ID="ID_1588722588" MODIFIED="1521160019955" TEXT="der Zugang zur DependencyFactory ist stets ein virtueller Funktionsaufruf">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -26677,8 +26674,7 @@
|
|||
Freiheit der dynamischen Laufzeit-Konfiguration verlieren.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521160020971" ID="ID_1097297428" MODIFIED="1521160553255" TEXT="Deshalb sollte die Factory konventionell implementiert werden, nicht als Lambda">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -26693,8 +26689,7 @@
|
|||
und die konventionelle Lösung hat demgegenüber den Vorteil, daß sie Struktur und Kontrakt explizit macht.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521160107759" ID="ID_669924852" MODIFIED="1521239034598" TEXT="Das Konsistenz-Problem ist in Wirklichkeit ein Architekturproblem">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -26723,8 +26718,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#a9c1bb" DESTINATION="ID_669924852" ENDARROW="Default" ENDINCLINATION="795;125;" ID="Arrow_ID_949036001" SOURCE="ID_1505788760" STARTARROW="None" STARTINCLINATION="779;51;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
|
|
@ -26755,8 +26749,7 @@
|
|||
<i>scheidet</i> für unser Nutzungsmuster aus
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -26772,8 +26765,7 @@
|
|||
wieder auf NULL zurücksetzen zu können.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -26836,8 +26828,7 @@
|
|||
wenn die DependInject-Instanz stirbt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521208943105" ID="ID_295121984" MODIFIED="1521335440371" TEXT="Ownership an übergebener Service-Impl übernehmen">
|
||||
|
|
@ -26858,8 +26849,7 @@
|
|||
sie werden ja sofort ausgewertet, da die Service-Instanz unmittelbar gebaut wird
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521688321599" ID="ID_764253251" MODIFIED="1521688339230" TEXT="stattdessen: ctor-Argumente forwarden">
|
||||
|
|
@ -26908,7 +26898,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1521213011289" ID="ID_1360216253" MODIFIED="1521213015444" TEXT="Vereinheitlichung">
|
||||
<node CREATED="1521213011289" FOLDED="true" ID="ID_1360216253" MODIFIED="1521751375990" TEXT="Vereinheitlichung">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1521213017168" ID="ID_1734833663" MODIFIED="1521213021084" TEXT="alle Varianten">
|
||||
<node CREATED="1521213036670" ID="ID_1288760048" MODIFIED="1521416387077" TEXT="sind move-only">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -26928,8 +26919,7 @@
|
|||
<b>aber</b> Lebenszyklus ist an die Factory gebunden
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521236997978" ID="ID_937624268" MODIFIED="1521237012251" TEXT="...und im Fall Singleton lebt die Factory länger"/>
|
||||
</node>
|
||||
|
|
@ -27017,8 +27007,7 @@
|
|||
Har Har Har! Selber schuld wer sowas macht.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -27085,8 +27074,7 @@
|
|||
statische Storage ist <i>irgendwie cool</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node CREATED="1521324275919" ID="ID_1710451095" MODIFIED="1521418281285" TEXT="sehe aber auch keinen wirklichen Vorteil">
|
||||
|
|
@ -27111,8 +27099,7 @@
|
|||
selbst wenn die dynamische Konfiguration so angelegt ist, daß die Storage nie benötigt wird
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521324883035" ID="ID_1438637057" MODIFIED="1521418281285" TEXT="Heap-Allokation könnte insgesamt einfacher sein">
|
||||
<icon BUILTIN="yes"/>
|
||||
|
|
@ -27143,8 +27130,7 @@
|
|||
...aber dann eben nicht mehr <i>elegant.</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1521303905491" ID="ID_1749674332" MODIFIED="1521418281286" TEXT="Fazit: explizit ist besser">
|
||||
<icon BUILTIN="yes"/>
|
||||
|
|
@ -27196,8 +27182,7 @@
|
|||
In Zukunft könnten Compiler/Linker noch "schlauer" werden...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1521386182598" ID="ID_1671815821" MODIFIED="1521418281286" TEXT="ist undurchsichtig">
|
||||
|
|
@ -27244,8 +27229,8 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1521696315169" ID="ID_914761003" MODIFIED="1521696326988" TEXT="ob das wohl geht...."/>
|
||||
<node CREATED="1521696477035" ID="ID_1232450528" MODIFIED="1521696510682" TEXT="Verdammter Mist! Wird die Closure nun kopiert oder geMOVEd?"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1521696673440" ID="ID_1408713510" MODIFIED="1521696682160" TEXT="compile-time Checks mal verifizieren">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node COLOR="#338800" CREATED="1521696673440" ID="ID_1408713510" MODIFIED="1521751343055" TEXT="compile-time Checks mal verifizieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1521696334383" ID="ID_1627167666" MODIFIED="1521696684626" TEXT="gefällt mir nicht wirklich">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -27272,8 +27257,7 @@
|
|||
konstruieren wollen könnte, und es ist von der Implementierung her "quasi geschenkt".
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -27365,8 +27349,7 @@
|
|||
und heute würde ich den Code <i>so</i> nicht mehr schreiben
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="smiley-oh"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue