Library: reconsider join / stringify API

- it is not directly possible to provide a variadic join(args...),
  due to overload resolution ambiguities

- as a remedy, simplify the invocation of stringify() for the typical cases,
  and provide some frequently used shortcuts
This commit is contained in:
Fischlurch 2023-09-29 02:44:44 +02:00
parent 691d2b43fa
commit 201672a0ad
6 changed files with 105 additions and 15 deletions

View file

@ -117,13 +117,21 @@ namespace util {
*/
template<class CON, typename...ELMS>
inline CON
stringify(ELMS const& ...elms)
collectStr(ELMS const& ...elms)
{
SeqContainer<CON,ELMS...> storage;
do_stringify (storage, elms...);
return CON {move(storage)};
}
/** standard setup: convert to string into a vector */
template<typename...ELMS>
inline vector<string>
stringify (ELMS const& ...elms)
{
return collectStr<vector<string>> (elms...);
}
/** convert to string as transforming step in a pipeline
* @param src a "Lumiera Forward Iterator" with arbitrary result type
* @return a "Lumiera Forward Iterator" with string elements
@ -214,13 +222,30 @@ namespace util {
return join (ili, delim);
}
// Note: offering a variant of join with var-args would create lots of ambiguities
/** shortcut: List in parentheses, separated by comma, using temporary vector */
template<typename...ARGS>
inline string
joinArgList (ARGS const& ...args)
{
return "("+join (stringify<std::vector<string>> (args...))+")";
return "("+join (stringify (args...))+")";
}
/** shortcut: join directly with dashes */
template<typename...ARGS>
inline string
joinDash (ARGS const& ...args)
{
return join (stringify (args...), "-");
}
/** shortcut: join directly with dashes */
template<typename...ARGS>
inline string
joinDot (ARGS const& ...args)
{
return join (stringify (args...), ".");
}

View file

@ -102,7 +102,7 @@ namespace test{
using lib::Symbol;
using std::string;
using util::stringify;
using util::collectStr;
namespace {
using Entry = lib::diff::Record<string>;
@ -206,7 +206,7 @@ namespace test{
EventMatch&
arg (ARGS const& ...args)
{
refineSerach_matchArguments (stringify<ArgSeq> (args...));
refineSerach_matchArguments (collectStr<ArgSeq> (args...));
return *this;
}
@ -225,8 +225,8 @@ namespace test{
EventMatch&
argMatch (ARGS const& ...regExps)
{
refineSerach_matchArgsRegExp (stringify<RExSeq> (regExps...),
util::join(stringify<ArgSeq>(regExps...)));
refineSerach_matchArgsRegExp (collectStr<RExSeq> (regExps...),
util::join(collectStr<ArgSeq>(regExps...)));
return *this;
}
@ -380,7 +380,7 @@ namespace test{
EventLog&
call (string target, string function, ARGS const& ...args)
{
return call (target, function, stringify<ArgSeq>(args...));
return call (target, function, collectStr<ArgSeq>(args...));
}
/** Log a function call on given object ("`this`")... */
@ -402,7 +402,7 @@ namespace test{
EventLog&
note (ELMS const& ...initialiser)
{
log_->emplace_back (stringify<ArgSeq> (initialiser...));
log_->emplace_back (collectStr<ArgSeq> (initialiser...));
return *this;
}

View file

@ -305,7 +305,7 @@ namespace lib {
template<class SUB, typename...ARGS>
ThreadLifecycle (RES (SUB::*memFun) (ARGS...), ARGS&& ...args)
: ThreadLifecycle{util::joinArgList (lib::meta::typeStr<SUB>(), args...)
: ThreadLifecycle{util::joinDash (lib::meta::typeStr<SUB>(), args...)
,std::move (memFun)
,static_cast<SUB*> (this)
,std::forward<ARGS> (args)... }

View file

@ -156,8 +156,8 @@ namespace test {
using VecS = vector<string>;
// another variant: collect arbitrary number of arguments
VecS vals = stringify<VecS> (short(12), 345L, "67", '8');
// another variant: collect arbitrary heterogeneous arguments
VecS vals = stringify (short(12), 345L, "67", '8');
CHECK (vals == VecS({"12", "345", "67", "8"}));

View file

@ -102,8 +102,7 @@ namespace test{
static string
capture (ARGS ...args)
{
using VecS = std::vector<string>;
return "Memento⧏" + util::join (util::stringify<VecS> (args...),"") + "";
return "Memento⧏" + util::join (util::stringify (args...),"") + "";
}
static void

View file

@ -79395,11 +79395,77 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</body>
</html></richcontent>
<linktarget COLOR="#7898aa" DESTINATION="ID_1296792416" ENDARROW="Default" ENDINCLINATION="-613;39;" ID="Arrow_ID_1122896333" SOURCE="ID_1888383911" STARTARROW="None" STARTINCLINATION="88;-226;"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1695915569144" ID="ID_1968434740" MODIFIED="1695915583304" TEXT="auch die Thread-ID generieren">
<icon BUILTIN="pencil"/>
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1695915569144" FOLDED="true" ID="ID_1968434740" MODIFIED="1695947900416" TEXT="auch die Thread-ID generieren">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1695915584543" ID="ID_1434344091" MODIFIED="1695915603355" TEXT="erste Fassung: joinArgList">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#435e98" CREATED="1695946203234" ID="ID_499999802" MODIFIED="1695947847905" TEXT="Nebenthema: API-Design f&#xfc;r join()">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1695946248572" ID="ID_836851069" MODIFIED="1695946460622" TEXT="es fehlt eine Varargs-Variante">
<icon BUILTIN="broken-line"/>
<node CREATED="1695946473966" ID="ID_1960717352" MODIFIED="1695946522852" TEXT="join (Seq, delim) : Sequenz /Container ist inh&#xe4;rent homogen"/>
<node CREATED="1695946523910" ID="ID_1452548190" MODIFIED="1695946550905" TEXT="join (Initializer-list, delim) : ebenso, homogener Typ"/>
</node>
<node CREATED="1695946258298" ID="ID_1253418449" MODIFIED="1695946448060" TEXT="die kann man aber in dem gew&#xe4;hlten API-Schema nicht (mehr) realisieren">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
es ergeben sich zwei Schwierigkeiten...
</p>
<ul>
<li>
eine Varargs-Variante w&#252;rde die bestehenden Overloads kanibalisieren bzw. w&#252;rde f&#252;r 1-2 Argumente&#160;einen &quot;ambiguous overload&quot; provozieren
</li>
<li>
mit einer Varargs-Variante gibt es keine M&#246;glichkeit, den Delimiter anzugeben
</li>
</ul>
</body>
</html></richcontent>
<icon BUILTIN="stop-sign"/>
</node>
<node CREATED="1695946572960" ID="ID_810272356" MODIFIED="1695946595159" TEXT="man k&#xf6;nnte es leicht per stringify(args...) realisieren">
<node CREATED="1695946597085" ID="ID_25917917" MODIFIED="1695946612918" TEXT="aber stringify selber braucht einen Container-Parameter"/>
<node CREATED="1695946617794" ID="ID_1039128025" MODIFIED="1695946642579" TEXT="es gibt daf&#xfc;r bisher nur eine Verwendung in EventLog">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1695946643647" ID="ID_175299311" MODIFIED="1695946663576" TEXT="ansonsten k&#xf6;nnte man das n&#xe4;mlich auf vector&lt;string&gt; festlegen"/>
<node CREATED="1695946673835" ID="ID_1137129563" MODIFIED="1695946859221" TEXT="der Name &quot;stingify&quot; ist gut, aber nicht variierbar">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
Er ist aus mehreren Gr&#252;nden gut
</p>
<ul>
<li>
er ist bereits konventionell; im Besonderen in der C-Marko-Form (die Lumiera auch verwendet)
</li>
<li>
er teilt sich sprachlich gut mit
</li>
</ul>
<p>
Aber es ist ein sehr fester Name; er erm&#246;glicht kaum Verk&#252;rzungen oder Varianten
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1695946866425" ID="ID_702636837" MODIFIED="1695947005107" TEXT="&#x27f9; gib der flexiblen stringify-Variante einen neuen Namen: collectStr"/>
<node CREATED="1695947721359" ID="ID_1899069832" MODIFIED="1695947749039" TEXT="damit gen&#xfc;gt in den allermeisten F&#xe4;llen der kurze Nahme stringify"/>
</node>
</node>
<node CREATED="1695947879402" ID="ID_93040397" MODIFIED="1695947896944" TEXT="au&#xdf;erdem: verwende nur den Typnamen vom Tr&#xe4;ger der Member-Funktion"/>
<node COLOR="#5b280f" CREATED="1695947851257" ID="ID_1517502415" MODIFIED="1695947872327" TEXT="das Thema nicht &#xfc;bertreiben">
<icon BUILTIN="stop-sign"/>
</node>
</node>
<node COLOR="#338800" CREATED="1695915605227" ID="ID_414676042" MODIFIED="1695915614639" TEXT="downcast von *this machen">
<icon BUILTIN="button_ok"/>