Library: change of plan - retain the »Either« wrapper
on second thought, the ability to transport an exception still seems worthwhile, and can be achieved by some rearrangements in the design. As preparation, reorganise the design of the Either-wrapper (lib::Result)
This commit is contained in:
parent
59bb99f653
commit
4348e110cb
4 changed files with 416 additions and 93 deletions
|
|
@ -52,74 +52,23 @@ namespace lib {
|
|||
using util::isnil;
|
||||
using std::string;
|
||||
namespace error = lumiera::error;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Optional Result value or status of some operation.
|
||||
* It can be created for passing a result produced by the operation, or the
|
||||
* failure to do so. The value can be retrieved by implicit or explicit conversion.
|
||||
* Representation of the result of some operation, _EITHER_ a value or a failure.
|
||||
* It can be created for passing a result produced by the operation, or the failure
|
||||
* to do so. The value can be retrieved by implicit or explicit conversion.
|
||||
* @throw error::State on any attempt to access the value in case of failure
|
||||
* @warning this class has a lot of implicit conversions;
|
||||
* care should be taken when defining functions
|
||||
* to take Result instances as parameter....
|
||||
*/
|
||||
template<typename RES>
|
||||
class Result
|
||||
{
|
||||
string failureLog_;
|
||||
wrapper::ItemWrapper<RES> value_;
|
||||
|
||||
public:
|
||||
/** mark an invalid/failed result */
|
||||
Result (string const& failureReason ="no result")
|
||||
: failureLog_{failureReason}
|
||||
{ }
|
||||
|
||||
/** failed result, with reason given.*/
|
||||
Result (lumiera::Error const& reason)
|
||||
: failureLog_{reason.what()}
|
||||
{ }
|
||||
|
||||
/** standard case: valid result */
|
||||
Result (RES&& value)
|
||||
: failureLog_{}
|
||||
, value_{std::forward<RES> (value)}
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
bool
|
||||
isValid() const
|
||||
{
|
||||
return value_.isValid();
|
||||
}
|
||||
|
||||
void
|
||||
maybeThrow() const
|
||||
{
|
||||
if (not isValid())
|
||||
throw error::State (failureLog_, lumiera_error_peek());
|
||||
}
|
||||
|
||||
operator RES() const
|
||||
{
|
||||
maybeThrow();
|
||||
return *value_;
|
||||
}
|
||||
|
||||
template<typename TY>
|
||||
TY
|
||||
get() const
|
||||
{
|
||||
maybeThrow();
|
||||
return static_cast<TY> (*value_);
|
||||
}
|
||||
};
|
||||
class Result;
|
||||
|
||||
|
||||
/**
|
||||
* Specialisation for signalling success or failure,
|
||||
* The base case is just to capture success or failure,
|
||||
* without returning any value result.
|
||||
*/
|
||||
template<>
|
||||
|
|
@ -138,23 +87,81 @@ namespace lib {
|
|||
: failureLog_{reason.what()}
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
bool
|
||||
isValid() const
|
||||
{
|
||||
return isnil (failureLog_);
|
||||
}
|
||||
operator bool() const { return isValid(); }
|
||||
bool isValid() const { return isnil (failureLog_); }
|
||||
|
||||
void
|
||||
maybeThrow() const
|
||||
{
|
||||
if (not isValid())
|
||||
throw error::State (failureLog_, lumiera_error_peek());
|
||||
throw error::State (failureLog_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Optional Result value or status of some operation.
|
||||
* It can be created for passing a result produced by the operation, or the
|
||||
* failure to do so. The value can be retrieved by implicit or explicit conversion.
|
||||
* @throw error::State on any attempt to access the value in case of failure
|
||||
* @warning this class has a lot of implicit conversions;
|
||||
* care should be taken when defining functions
|
||||
* to take Result instances as parameter....
|
||||
*/
|
||||
template<typename RES>
|
||||
class Result
|
||||
: public Result<void>
|
||||
{
|
||||
wrapper::ItemWrapper<RES> value_;
|
||||
|
||||
public:
|
||||
/** mark an invalid/failed result */
|
||||
Result (string const& failureReason ="no result")
|
||||
: Result<void>{failureReason}
|
||||
{ }
|
||||
|
||||
/** failed result, with reason given.*/
|
||||
Result (lumiera::Error const& reason)
|
||||
: Result<void>{reason}
|
||||
{ }
|
||||
|
||||
/** standard case: valid result */
|
||||
Result (RES&& value)
|
||||
: Result<void>{true}
|
||||
, value_{std::forward<RES> (value)}
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
operator RES() const
|
||||
{
|
||||
maybeThrow();
|
||||
return *value_;
|
||||
}
|
||||
|
||||
template<typename TY>
|
||||
TY
|
||||
get() const
|
||||
{
|
||||
maybeThrow();
|
||||
return static_cast<TY> (*value_);
|
||||
}
|
||||
|
||||
template<typename MAKE, typename...ARGS>
|
||||
RES
|
||||
getOrElse (MAKE&& producer, ARGS ...args)
|
||||
{
|
||||
if (isValid())
|
||||
return *value_;
|
||||
else
|
||||
return std::invoke(std::forward<MAKE> (producer), std::forward<ARGS> (args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename VAL>
|
||||
Result (VAL&& x) -> Result<VAL>;
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace lib
|
||||
|
|
|
|||
|
|
@ -533,6 +533,11 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
TEST "Either-result-or-failure" Result_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
||||
TEST "ScopedHolder_test" ScopedHolder_test <<END
|
||||
out: checking ScopedHolder<Dummy>...
|
||||
out: checking ScopedPtrHolder<Dummy>...
|
||||
|
|
|
|||
108
tests/library/result-test.cpp
Normal file
108
tests/library/result-test.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Result(Test) - verify the either-result-or-failure intermediary wrapper
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2023, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
/** @file result-test.cpp
|
||||
** unit test \ref Result_test
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/result.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace test{
|
||||
|
||||
using util::isSameObject;
|
||||
using std::rand;
|
||||
|
||||
namespace error = lumiera::error;
|
||||
using error::LUMIERA_ERROR_FATAL;
|
||||
using error::LUMIERA_ERROR_STATE; ///////////////////TODO
|
||||
|
||||
|
||||
namespace {
|
||||
const Literal THE_END = "all dead and hero got the girl";
|
||||
|
||||
|
||||
#define Type(_EXPR_) lib::test::showType<decltype(_EXPR_)>()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************//**
|
||||
* @test Verify an intermediary »Either« type, to embody either a successful result,
|
||||
* or document a failure with encountered exception.
|
||||
* @see result.hpp
|
||||
* @see lib::ThreadJoinable usage example
|
||||
*/
|
||||
class Result_test
|
||||
: public Test
|
||||
{
|
||||
|
||||
void
|
||||
run (Arg)
|
||||
{
|
||||
auto happy = Result{THE_END};
|
||||
CHECK (happy == THE_END);
|
||||
CHECK (happy.isValid());
|
||||
CHECK (true == happy);
|
||||
|
||||
happy.maybeThrow(); // still alive...
|
||||
|
||||
CHECK (Type(happy) == "Result<Literal const&>"_expect);
|
||||
|
||||
// Note type deduction: RValue moved into the Result...
|
||||
auto sequel = Result{Literal{THE_END}};
|
||||
CHECK (sequel.isValid());
|
||||
CHECK (Type(sequel) == "Result<Literal>"_expect);
|
||||
|
||||
CHECK ( isSameObject (happy.get<Literal const&>(), THE_END));
|
||||
CHECK (not isSameObject (sequel.get<Literal const&>(), THE_END));
|
||||
|
||||
// »Either Right« case : mark as failure
|
||||
Result<double> facepalm{error::Fatal()};
|
||||
CHECK (not facepalm.isValid());
|
||||
|
||||
VERIFY_ERROR (STATE, (double)facepalm );
|
||||
VERIFY_ERROR (STATE, facepalm.get<double&>());
|
||||
VERIFY_ERROR (STATE, facepalm.maybeThrow() );
|
||||
|
||||
CHECK (42.0 == facepalm.getOrElse([]{ return 42; }));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (Result_test, "unit common");
|
||||
|
||||
|
||||
}} // namespace lib::test
|
||||
|
|
@ -78947,6 +78947,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#fed5c5" DESTINATION="ID_1859841213" ENDARROW="Default" ENDINCLINATION="1276;51;" ID="Arrow_ID_1453893581" SOURCE="ID_1803056303" STARTARROW="None" STARTINCLINATION="1738;-79;"/>
|
||||
<node COLOR="#ee6e3b" CREATED="1695748033606" HGAP="157" ID="ID_1181956652" MODIFIED="1695748384597" TEXT="(das geht an mich selber)" VSHIFT="13">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Um das klar zu sagen: zwar hat Christian ein Verbot von »join« angedacht, aber <i>grade in dieser Frage war und bin ich absolut einer Meinung mit ihm. </i>Tatsächlich war Christian sogar zurückhaltender („man sollte es deprecaten“) — und das hat <i>mich</i>  dann auf die Idee gebracht, einen separaten »Joinable«-Wrapper zu schreiben. Und jetzt, viele Jahre später stehe <i>ich an dem Punkt, </i>daß es kein absehbares Usage-Pattern gibt, und mein Design von damals ungerchtfertigt erscheint.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<edge COLOR="#de7676"/>
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1693788648105" ID="ID_426109467" MODIFIED="1695312840978">
|
||||
|
|
@ -79410,17 +79425,6 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1695657061352" ID="ID_1954347934" MODIFIED="1695657066365" TEXT="Code-Anordnung">
|
||||
<node CREATED="1695657067583" ID="ID_1218314116" MODIFIED="1695657096921" TEXT="Problem: weitgehend redundant">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1695657076966" ID="ID_535675901" MODIFIED="1695657084689" TEXT="aber dennoch variabel"/>
|
||||
<node CREATED="1695657085260" ID="ID_1430248620" MODIFIED="1695657093224" TEXT="keine VTable erwünsch"/>
|
||||
</node>
|
||||
<node CREATED="1695657098101" ID="ID_273999408" MODIFIED="1695657107014" TEXT="Lösung: parametrisierbare Basisklasse"/>
|
||||
<node CREATED="1695657111918" ID="ID_463997820" MODIFIED="1695657217094" TEXT="in Sub-Namespace lib::thread">
|
||||
<arrowlink COLOR="#6e85a1" DESTINATION="ID_750029588" ENDARROW="Default" ENDINCLINATION="-741;56;" ID="Arrow_ID_1885189676" STARTARROW="None" STARTINCLINATION="-489;0;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1695677839257" ID="ID_1013931122" MODIFIED="1695677867799" TEXT="Problem: Rückgabewert von join()">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1695677870757" ID="ID_1158604113" MODIFIED="1695678100114" TEXT="war für die alte Implementierung kein Problem">
|
||||
|
|
@ -79433,8 +79437,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
...da die Implementierung mit einem aktiven Threadpool verbunden war, gab es dort auch eine Managment-Datenstruktur; die Threadpool-Logik hat eine eventuell im Thread noch erkannte Fehlerflag dorthin gespeichert — und join() konnte diese Fehlerflag dann einfach abholen.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1695678101764" ID="ID_411970965" MODIFIED="1695678328883" TEXT="hat bisher aber nur Fehlerflags abgedeckt, keine Exceptions">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -79446,8 +79449,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
...C kennt ja keine Exceptions — und der Author des Threadpool-Frameworks hielt Exceptions für ein bestenfalls überflüssiges Feature, das es ganz bestimmt nicht rechtfertigt, zusätzlichen Aufwand zu treiben
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1695678330517" ID="ID_1924651405" MODIFIED="1695678362369" TEXT="der Rückgabewert wurde bisher über einen »Either-Typ« dargestellt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -79459,8 +79461,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
gemeint ist lib::Result
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1695679266329" ID="ID_1299395095" MODIFIED="1695679291989" TEXT="das Feature erscheint mir „halbgar“">
|
||||
<node CREATED="1695679293241" ID="ID_782789148" MODIFIED="1695679338571" TEXT="Exceptions könnten strukturierte Diagnose-Info transportieren"/>
|
||||
|
|
@ -79476,8 +79477,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
...und zwar im Besonderen, wenn man in einer »reaping-loop« alle Kind-Threads ernten möchte; dann würde nur ein Fehler ausgeworfen, und die weiteren Kinder bleiben ungeerntet (und terminieren jetzt, mit der C++14-Lösung sogar das Programm)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1695679527561" ID="ID_1584831418" MODIFIED="1695679550241" TEXT="und das Naheliegendste, nämlich das Abholen von Ergebnissen ist nicht implementiert"/>
|
||||
<node CREATED="1695679555637" ID="ID_1907767140" MODIFIED="1695679621871" TEXT="zu allem Überfluss...">
|
||||
|
|
@ -79504,9 +79504,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1695680809244" ID="ID_530073405" MODIFIED="1695680823462" TEXT="YAGNI ⟹ das Feature wird aufgegeben">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1695680809244" ID="ID_530073405" MODIFIED="1695749285205" TEXT="YAGNI ⟹ aufgeben?">
|
||||
<font NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="help"/>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node CREATED="1695680837800" ID="ID_556594754" MODIFIED="1695680932789" TEXT="das ganze Thread-Join-Gedöns hat sich generell als nicht so glücklich herausgestellt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -79517,8 +79518,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Das ist ein klassischer Fall für ein Feature, das zu Beginn so offensichtlich und irre nützlich aussieht — dann aber in der Realität nicht wirklich „fliegt“
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1695680933859" ID="ID_9664587" MODIFIED="1695680967629">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -79530,8 +79530,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
heute bevorzugt man für ähnliche Anforderungen das <b>Future / Promise</b> - Konstrukt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1695680969567" ID="ID_854612368" MODIFIED="1695681002718" TEXT="oder man sammelt gleich Ergebnis-Nachrichten in einer Lock-free-Queue"/>
|
||||
<node CREATED="1695681067025" ID="ID_1829988819" MODIFIED="1695681202200" TEXT="Fehler in Threads können im Einzelfall sehr relevant sein — das ist aber nix Generisches">
|
||||
|
|
@ -79544,13 +79543,217 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Denn tatsächlich sind aufgetretene Fehler dann ehr schon eine Form von Zustand, den man mit einem speziellen Protokoll im Thread-Objekt erfassen und nach dem join() abfragen sollte; so kann man auch die Ergebnisse mehrerer Threads korrekt kombinieren
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1695681207655" ID="ID_1998022902" MODIFIED="1695681463386" TEXT="brauche dann aber einen Ersatz für die zwei Tests">
|
||||
<arrowlink COLOR="#b65b7a" DESTINATION="ID_478666570" ENDARROW="Default" ENDINCLINATION="41;-72;" ID="Arrow_ID_1595086726" STARTARROW="None" STARTINCLINATION="-427;24;"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1695747229306" ID="ID_1952535260" MODIFIED="1695747238936" TEXT="am nächsten Tag dann wieder Zweifel">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
<node BACKGROUND_COLOR="#d7cfb0" COLOR="#3fa41b" CREATED="1695747248047" ID="ID_1584465729" MODIFIED="1695747828936" TEXT="»es ist so schöne Physik«"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1695748401477" ID="ID_1245905649" MODIFIED="1695748490377" TEXT="ohne einen Rückgabewert wirkt die »Joinable«-Variante insgesamt fragwürdig">
|
||||
<linktarget COLOR="#8c5869" DESTINATION="ID_1245905649" ENDARROW="Default" ENDINCLINATION="10;123;" ID="Arrow_ID_155554446" SOURCE="ID_1803056303" STARTARROW="None" STARTINCLINATION="129;7;"/>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node COLOR="#641f4f" CREATED="1695748527108" ID="ID_964369484" MODIFIED="1695748573531" TEXT="Policy-Design ungerechtfertigt">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node COLOR="#9b0f8e" CREATED="1695748885164" ID="ID_1477111545" MODIFIED="1695749387232" TEXT="verdammt noch einmal!!">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<b>Knoten durchhauen</b>!
|
||||
</p>
|
||||
<p>
|
||||
Warum quäle ich mich damit herum, was ich künftig dürfen darf, und was unangemessen wäre? Meine Einstellung ist doch, daß eine Library strukturieren sollte, aber nicht vorgreifen und bestimmen. Wenn die letzten 10 Jahre eines gezeigt haben, dann den Umstand, daß der Thread-Wrapper vor <b>allem für Tests</b> verwendet wird. Und genau da gelten die ganzen Performance- und Architektur-Überlegungen überhaupt nicht; sondern es kommt auf die den Umständen entsprechende, gradlinige Formulierung im Testcode an. Und da könnte <i>unter Umständen </i>Fork-Join genau die KISS-Lösung sein. Insofern wäre das Design bereits nahezu gelungen: es trennt einen intendierten Standardfall ab, läßt aber sonst alle Türen offen....
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<edge COLOR="#9a3d6d"/>
|
||||
<arrowlink COLOR="#dd26d2" DESTINATION="ID_1308996711" ENDARROW="Default" ENDINCLINATION="194;-5;" ID="Arrow_ID_1982134212" STARTARROW="None" STARTINCLINATION="172;16;"/>
|
||||
<font NAME="SansSerif" SIZE="15"/>
|
||||
<icon BUILTIN="smiley-angry"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1695749294374" HGAP="18" ID="ID_1090986395" MODIFIED="1695749396815" TEXT="besser machen!!!!" VSHIFT="3">
|
||||
<font NAME="SansSerif" SIZE="9"/>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1695749704247" ID="ID_827179831" MODIFIED="1695749714510" TEXT="Rückgabewert per lib::Result">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1695749715525" ID="ID_914625209" MODIFIED="1695749847745" TEXT="das ist ein Either-Typ">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1695749719789" ID="ID_1636786367" MODIFIED="1695749844541" TEXT="diesen modernisieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1695749730882" ID="ID_720335444" MODIFIED="1695749749631" TEXT="sollte einen std::exception_ptr nehmen">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1695749758416" ID="ID_1018098640" MODIFIED="1695749764076" TEXT="dieser dient als Varianten-Flag"/>
|
||||
<node CREATED="1695749764647" ID="ID_160637410" MODIFIED="1695749781209">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
und kann zugleich <b>jedwede</b> Exception halten
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1695749796803" ID="ID_1154699124" MODIFIED="1695749823763" TEXT="API sollte künftig eine Exception als »right value« nehmen"/>
|
||||
<node CREATED="1695749825847" ID="ID_1357368217" MODIFIED="1695749841931">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
und ansonsten aber <i>left-biassed</i> sein
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1695657061352" ID="ID_1954347934" MODIFIED="1695747338448" TEXT="Code-Anordnung">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1695657067583" ID="ID_1218314116" MODIFIED="1695657096921" TEXT="Problem: weitgehend redundant">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1695657076966" ID="ID_535675901" MODIFIED="1695657084689" TEXT="aber dennoch variabel"/>
|
||||
<node CREATED="1695657085260" ID="ID_1430248620" MODIFIED="1695657093224" TEXT="keine VTable erwünscht"/>
|
||||
</node>
|
||||
<node CREATED="1695657098101" ID="ID_273999408" MODIFIED="1695657107014" TEXT="Lösung: parametrisierbare Basisklasse"/>
|
||||
<node CREATED="1695657111918" ID="ID_463997820" MODIFIED="1695657217094" TEXT="in Sub-Namespace lib::thread">
|
||||
<arrowlink COLOR="#6e85a1" DESTINATION="ID_750029588" ENDARROW="Default" ENDINCLINATION="-741;56;" ID="Arrow_ID_1885189676" STARTARROW="None" STARTINCLINATION="-489;0;"/>
|
||||
</node>
|
||||
<node CREATED="1695747369039" ID="ID_1807166092" MODIFIED="1695747532236" TEXT="immer noch unklar und problematisch">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Es wäre zwar so irgendwie hinzubekommen — aber <i>weit entfernt von einem guten Design.</i>
|
||||
</p>
|
||||
<p>
|
||||
Ich baue hier eine auf Dauer angelegte Lösung, die auch sichtbar ist und in Frage gestellt werden wird!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<node CREATED="1695747533905" ID="ID_990711241" MODIFIED="1695747552434" TEXT="der bool-Template-Parameter wirkt unbeholfen"/>
|
||||
<node CREATED="1695747554262" ID="ID_1830373313" MODIFIED="1695747660353" TEXT="dadurch ist es erschwert, Grundbausteine in eine CPP-Unit wegzupacken">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
hab das gestern versucht — so kann das nicht stehen bleiben, das ist ja lächerlich (brauche explizite Template-Instantiierung) — zumindest solange wir keine C++-Module verwenden (C++20)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1695747673046" ID="ID_1466067755" MODIFIED="1695747692667">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
die Code-Anordnung <i>hat keinen Flow</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
</node>
|
||||
<node CREATED="1695747880669" ID="ID_1803056303" MODIFIED="1695748482205" TEXT="die erzwungene »Joinable«-Variante wirkt mutwillig">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Ich habe doch selber oben diese Prinzipien formuliert: eine Library-Lösung sollte nicht mutwillig beschränken, sondern eine sinnvolle Gliederung anbieten...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<arrowlink COLOR="#fed5c5" DESTINATION="ID_1859841213" ENDARROW="Default" ENDINCLINATION="1276;51;" ID="Arrow_ID_1453893581" STARTARROW="None" STARTINCLINATION="1738;-79;"/>
|
||||
<arrowlink COLOR="#8c5869" DESTINATION="ID_1245905649" ENDARROW="Default" ENDINCLINATION="10;123;" ID="Arrow_ID_155554446" STARTARROW="None" STARTINCLINATION="129;7;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1695748592388" ID="ID_836153579" MODIFIED="1695748632222">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
also vielleicht doch <b>Policy-based-Design</b>?
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1695748635886" ID="ID_859201330" MODIFIED="1695748676734" TEXT="aaber ... dann wird ja alles noch umständlicher">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
<node CREATED="1695748653462" ID="ID_763671935" MODIFIED="1695748671048" TEXT="dann kann ich nicht mehr die Konstruktor-Varianten erben">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1695748787634" ID="ID_1593689414" MODIFIED="1695748855312">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
⟹ wenn überhaupt, müßte die Policy einen <i>mittleren Binding-Layer </i>bilden
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1695749319298" ID="ID_1308996711" MODIFIED="1695749370296" TEXT="eine Policy für Fehlerbehandlung + Rückgabewert + Join wäre gerechtfertigt">
|
||||
<linktarget COLOR="#dd26d2" DESTINATION="ID_1308996711" ENDARROW="Default" ENDINCLINATION="194;-5;" ID="Arrow_ID_1982134212" SOURCE="ID_1477111545" STARTARROW="None" STARTINCLINATION="172;16;"/>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1695749427868" ID="ID_1042254250" MODIFIED="1695749686462" TEXT="Lösung">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1695749436922" ID="ID_1431671531" MODIFIED="1695749455500" TEXT="Unterlage: »ThreadWrapper«"/>
|
||||
<node CREATED="1695749456164" ID="ID_1054598766" MODIFIED="1695749478601" TEXT="Mittelschicht: »ThreadLifecycle«">
|
||||
<node CREATED="1695749538333" ID="ID_1896384393" MODIFIED="1695749549565" TEXT="definiert alle Konstruktoren"/>
|
||||
<node CREATED="1695749531182" ID="ID_1148976245" MODIFIED="1695749537508" TEXT="definiert den Destruktor"/>
|
||||
<node CREATED="1695749523263" ID="ID_1222427695" MODIFIED="1695749551050" TEXT="führt eine Policy ein"/>
|
||||
<node CREATED="1695749552627" ID="ID_573772960" MODIFIED="1695749648141">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Policy <font size="5"><b>⤵</b></font> <font color="#07097c" face="Monospaced">main<POL,FUN,ARGS...></font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1695749669204" ID="ID_1950929730" MODIFIED="1695749680246" TEXT="Front-End: wie bisher"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue