Upgrade: Literal can be constexpr

Only minor rearrangements necessary to make that possible with C++20
And while at this change (which requires a full rebuild of Lumiera)

- simplify the defined comparison operators, as C++20 can infer most variations
- also mark various usages of `const char*` either as Literal or CStr

Remark: regarding copyright, up to now this is entirely my work,
        with two major creation steps in 2008 (conception) and
        in 2017 (introduction of a symbol table)
This commit is contained in:
Fischlurch 2025-07-02 22:18:39 +02:00
parent 170b68ac5c
commit bad4827b34
44 changed files with 209 additions and 234 deletions

View file

@ -41,11 +41,11 @@ namespace lumiera {
using lib::Symbol;
//defined in liblumiera.so
extern const char * ON_BASIC_INIT; ///< automatic static init. treated specially to run as soon as possible
extern const char * ON_GLOBAL_INIT; ///< to be triggered in main() @note no magic!
extern const char * ON_GLOBAL_SHUTDOWN; ///< to be triggered at the end of main() @note no magic!
extern CStr ON_BASIC_INIT; ///< automatic static init. treated specially to run as soon as possible
extern CStr ON_GLOBAL_INIT; ///< to be triggered in main() @note no magic!
extern CStr ON_GLOBAL_SHUTDOWN; ///< to be triggered at the end of main() @note no magic!
extern const char * ON_EMERGENCY; ///< activated on shutdown after premature failure of a subsystem
extern CStr ON_EMERGENCY; ///< activated on shutdown after premature failure of a subsystem
// client code is free to register and use additional lifecycle events

View file

@ -334,7 +334,7 @@ namespace lib {
{
storage_.erase (pos); // EX_FREE
const char* errID = lumiera_error();
CStr errID = lumiera_error();
ERROR (memory, "Allocation failed with unknown exception. "
"Lumiera errorID=%s", errID?errID:"??");
throw;

View file

@ -269,11 +269,11 @@ namespace diff{
, data(std::forward<X>(val))
{ }
GenNode(string const& symbolicID, const char* text)
GenNode(string const& symbolicID, CStr text)
: GenNode(symbolicID, string(text))
{ }
GenNode(const char* text)
GenNode(CStr text)
: GenNode(string(text))
{ }

View file

@ -39,19 +39,20 @@
#include <exception>
#include <string>
using CStr = const char*;
#define LERR_(_NAME_) lumiera::error::LUMIERA_ERROR_##_NAME_
namespace lumiera {
using std::string;
using CStr = const char*;
namespace error {
/** error-ID for unspecified exceptions */
LUMIERA_ERROR_DECLARE(EXCEPTION);
}
using std::string;
/**
* Interface and Base definition for all Lumiera Exceptions.
@ -266,13 +267,13 @@ namespace lumiera {
#define ERROR_LOG_AND_IGNORE(_FLAG_,_OP_DESCR_) \
catch (std::exception& problem) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
WARN (_FLAG_, "%s failed: %s", _OP_DESCR_, problem.what()); \
TRACE (debugging, "Error flag was: %s", errID);\
} \
catch (...) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
ERROR (_FLAG_, "%s failed with unknown exception; " \
"error flag is: %s" \
, _OP_DESCR_, errID?errID:"??"); \
@ -281,14 +282,14 @@ namespace lumiera {
#define ERROR_LOG_AND_RETHROW(_FLAG_,_OP_DESCR_) \
catch (std::exception& problem) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
WARN (_FLAG_, "%s failed: %s", _OP_DESCR_, problem.what()); \
TRACE (debugging, "Error flag was: %s", errID); \
throw; \
} \
catch (...) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
ERROR (_FLAG_, "%s failed with unknown exception; " \
"error flag is: %s" \
, _OP_DESCR_, errID?errID:"??"); \
@ -304,7 +305,7 @@ namespace lumiera {
#define ON_EXCEPTION_RETURN(_VAL_,_OP_DESCR_) \
catch (std::exception& problem) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
WARN (stage, "%s (Handler) failed: %s", \
_OP_DESCR_, problem.what()); \
TRACE (debugging, "Error flag was: %s", errID); \
@ -312,7 +313,7 @@ namespace lumiera {
} \
catch (...) \
{ \
const char* errID = lumiera_error(); \
CStr errID = lumiera_error(); \
ERROR (stage, "(Handler) %s failed with " \
"unknown exception; error flag is: %s" \
, _OP_DESCR_, errID?errID:"??"); \

View file

@ -76,7 +76,7 @@ namespace util {
/** in case the formatting of a (primitive) value fails,
* we try to supply an error indicator instead */
void
pushFailsafeReplacement (std::byte* formatter, const char* errorMsg =NULL)
pushFailsafeReplacement (std::byte* formatter, CStr errorMsg =nullptr)
try {
string placeholder("<Error");
if (errorMsg){

View file

@ -182,11 +182,11 @@ namespace util {
friend std::ostream&
operator<< (std::ostream& os, _Fmt const&);
friend bool operator== (_Fmt const&, _Fmt const&);
friend bool operator== (_Fmt const&, string const&);
friend bool operator== (_Fmt const&, const char * const);
friend bool operator== (string const& , _Fmt const&);
friend bool operator== (const char * const, _Fmt const&);
friend bool operator== (_Fmt const&, _Fmt const&);
friend bool operator== (_Fmt const&, string const&);
friend bool operator== (_Fmt const&, CStr const );
friend bool operator== (string const&, _Fmt const&);
friend bool operator== (CStr const, _Fmt const&);
template<typename X>
friend bool operator != (_Fmt const& fmt, X const& x) { return not (fmt == x); }
@ -299,7 +299,7 @@ namespace util {
inline void
_clear_errorflag()
{
const char* errID = lumiera_error();
CStr errID = lumiera_error();
TRACE_IF (errID, progress, "Lumiera errorstate '%s' cleared.", errID);
}
@ -318,7 +318,7 @@ namespace util {
inline string
_log_unknown_exception()
{
const char* errID = lumiera_error();
CStr errID = lumiera_error();
if (errID)
ERROR (progress, "Unknown error while invoking custom string conversion. Lumiera error flag = %s", errID);
else
@ -368,10 +368,10 @@ namespace util {
};
template<>
struct _Fmt::Converter<const char *>
struct _Fmt::Converter<CStr>
{
static void
dump (const char* cString, Implementation& impl)
dump (CStr cString, Implementation& impl)
{
format (cString? cString : BOTTOM_INDICATOR, impl);
}
@ -473,7 +473,7 @@ namespace util {
}
inline bool
operator== (_Fmt const& fmt, const char * const cString)
operator== (_Fmt const& fmt, CStr const cString)
{
return string(fmt) == string(cString);
}
@ -485,7 +485,7 @@ namespace util {
}
inline bool
operator== (const char * const cString, _Fmt const& fmt)
operator== (CStr const cString, _Fmt const& fmt)
{
return fmt == cString;
}

View file

@ -234,7 +234,7 @@ namespace idi {
: BareEntryID (util::sanitise(symbolID), getTypeHash<TY>())
{ }
explicit
EntryID (const char* symbolID)
EntryID (CStr symbolID)
: BareEntryID (util::sanitise(symbolID), getTypeHash<TY>())
{ }
@ -296,7 +296,7 @@ namespace idi {
RandID (string const& symbolID)
: BareEntryID{util::sanitise (symbolID)}
{ }
RandID (const char* symbolID)
RandID (CStr symbolID)
: BareEntryID{util::sanitise (symbolID)}
{ }
RandID (Symbol const& internalSymbol)

View file

@ -76,11 +76,11 @@ namespace lumiera {
const char * ON_BASIC_INIT ("ON_BASIC_INIT");
const char * ON_GLOBAL_INIT ("ON_GLOBAL_INIT");
const char * ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN");
CStr ON_BASIC_INIT ("ON_BASIC_INIT");
CStr ON_GLOBAL_INIT ("ON_GLOBAL_INIT");
CStr ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN");
const char * ON_EMERGENCY ("ON_EMERGENCY");
CStr ON_EMERGENCY ("ON_EMERGENCY");
} // namespace lumiera

View file

@ -226,7 +226,6 @@ namespace lib {
{
static_assert (0 < chunk_size, "PathArray chunk_size must be nonempty");
using CcP = const char*;
using LiteralArray = std::array<Literal, chunk_size>;
LiteralArray elms_;
@ -245,8 +244,8 @@ namespace lib {
PathArray (IndexSeq<prefix...>
,IndexSeq<rest...>
,ARGS&& ...args)
: elms_{pickInit<prefix,CcP> (forward<ARGS>(args)...) ...}
, tail_{pickArg<rest> (forward<ARGS>(args)...) ...}
: elms_{pickInit<prefix, CStr> (forward<ARGS>(args)...) ...}
, tail_{pickArg<rest> (forward<ARGS>(args)...) ...}
{
this->normalise();
}
@ -492,7 +491,7 @@ namespace lib {
normalise()
{
if (size() == 0) return;
const char* fill = Symbol::EMPTY;
CStr fill = Symbol::EMPTY;
Literal* end = elms_.end();
Literal* pos = elms_.begin();

View file

@ -2,7 +2,7 @@
Symbol(impl) - helpers for working with literal string IDs
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
2009,2017 Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
@ -12,15 +12,10 @@
* *****************************************************************/
/** @file symbol-impl.cpp
** Collection of helpers for working with the lib::Symbol.
**
** @todo currently as of 9/09 this is more of a placeholder.
** And maybe a location for collecting small bits of implementation,
** which could be usable later for real Symbol and Literal datatypes.
**
** lib::Symbol
** control::CommandRegistry for usage example of the hash function.
**
** Implementation functionality to support definition of lib::Symbol.
** @see lib::Symbol
** @see control::CommandRegistry for usage example of the hash function.
** @see symbol-table.hpp for the implementation of _interned strings_
*/
@ -45,7 +40,6 @@ namespace lib {
const size_t STRING_MAX_RELEVANT = LUMIERA_IDSTRING_MAX_RELEVANT;
namespace { // global symbol table
SymbolTable&
@ -54,12 +48,6 @@ namespace lib {
static SymbolTable theSymbolTable;
return theSymbolTable; // Meyer's Singleton
}
inline int
strNcmp (CStr a, CStr b, size_t len)
{
return a == b ? 0 : std::strncmp (a?a:"", b?b:"", len);
}
}
@ -87,14 +75,6 @@ namespace lib {
/** equality on Literal and Symbol values is defined
* based on the content, not the address. */
bool
Literal::operator== (CStr charPtr) const
{
return 0 == strNcmp (this->str_, charPtr, STRING_MAX_RELEVANT);
}
/** generate hash value based on the Literal's contents.
* This function is intended to be picked up by ADL, and should be usable
@ -107,7 +87,7 @@ namespace lib {
if (literal)
{
size_t cnt = 1;
const char *pos = literal;
CStr pos = literal;
for ( ; cnt <= STRING_MAX_RELEVANT and *pos ; ++cnt, ++pos )
hash_combine (hash, *pos);
}

View file

@ -2,7 +2,7 @@
SYMBOL.hpp - symbolic constant datatype
Copyright (C)
2008, Hermann Vosseler <Ichthyostega@web.de>
2008,2017 Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
@ -16,21 +16,22 @@
** Instead of working just with pointers, which could represent pretty much anything,
** it is prudent to express the meaning at interfaces and for variables and members explicitly.
**
** On concept level, while a string is just some sequence of characters and nothing can be said
** about mutability or lifetime, a Literal on the contrary is meant to be _static._ It is fixed
** and assumed to exist literally as is during the whole lifetime of the execution. The concept
** of a Symbol is related, yet slightly different: it is meant to be a distinguishable fixed,
** unique token. _Identical sequence_ of characters means we have exactly the _same Symbol._
** On conceptual level, while a **string** is just some sequence of characters and nothing can be
** said about its mutability or lifetime, a **Literal** is explicitly meant to be _static._ It is
** a fixed sequence of characters placed in a stable memory location and assumed to exist during
** the whole lifetime of the execution. The concept of a **Symbol** is slightly different: it is
** meant to be a distinguishable, fixed, unique token. An _Identical sequence_ of characters means
** we have _exactly the same Symbol_.
**
** These concepts can be fused by treating Symbol as a specialisation of Literal, additionally
** maintaining an automatically populated, static [symbol table](\ref symbol-table.hpp), and
** we close the circle by allowing Symbol instances to be created from strings at runtime.
**
** @remark this started on occasion 11/2008, just with a typedef to mark assumption on interfaces
** for rules based configuration in the Steam-Layer. Over time, conversions, comparison and
** hashcode implementation were added. It turned out that the most smooth integration in
** coding practice is achieved when allowing transparent conversion for Literal, but not
** for Symbol or std::string.
** @remark this abstraction was first used occasionally 11/2008, at that time just as a typedef
** to mark assumption on the new interfaces for rules based configuration in the Steam-Layer.
** Over time, conversions, comparison and hashcode implementation were added. It turned out
** that the most smooth integration in coding practice is achieved when allowing transparent
** conversion between Literal CStr, but not for Symbol or std::string.
** @todo 9/2017 consider this mostly as settled, but might require some finishing touches
** - maybe improve interoperation of Symbol and std::string
** - investigate performance of the automatic symbol table
@ -64,7 +65,7 @@ cStr (std::string const& rendered)
namespace lib {
/** inline string literal
/** Inline string literal.
* This is a _marker type_ to indicate that
* - the string was given literally
* - storage is _somewhere_, not managed by Literal,
@ -75,37 +76,38 @@ namespace lib {
*/
class Literal
{
CStr str_;
CStr str_;
public:
/** empty string by default */
Literal() noexcept;
/** empty string by default */
constexpr Literal() noexcept;
Literal (const char* literal) noexcept
: str_(literal)
{ }
constexpr Literal (CStr literal) noexcept
: str_(literal)
{ }
Literal (Literal const&) noexcept = default;
Literal& operator= (Literal const&) noexcept = default;
constexpr Literal (Literal const&) noexcept = default;
constexpr Literal& operator= (Literal const&) noexcept = default;
operator CStr() const { return str_; }
const char* c() const { return str_; }
constexpr operator CStr() const { return str_; }
constexpr const char* c() const { return str_; }
bool
empty() const
{
return not str_ or 0 == std::strlen(str_);
}
constexpr bool
empty() const
{
return not str_ or 0 == std::strlen(str_);
}
bool operator== (CStr cString) const;
constexpr bool operator== (CStr cString) const;
constexpr size_t length() const;
protected:
/** Assignment generally prohibited */
Literal& operator= (CStr newStr) noexcept
{
str_ = newStr;
return *this;
}
/** Assignment generally prohibited */
Literal& operator= (CStr newStr) noexcept
{
str_ = newStr;
return *this;
}
};
@ -141,30 +143,49 @@ namespace lib {
: Symbol{base, std::string(ext)}
{ }
Symbol (Symbol const&) = default;
Symbol (Symbol &&) = default;
Symbol (Symbol const&) = default;
Symbol (Symbol &&) = default;
Symbol& operator= (Symbol const&) = default;
Symbol& operator= (Symbol &&) = default;
Symbol& operator= (Symbol const&) = default;
Symbol& operator= (Symbol &&) = default;
explicit operator bool() const { return not empty(); }
bool empty() const { return *this == BOTTOM.c() or *this == EMPTY.c(); }
size_t
length() const
{
return std::strlen(c());
}
explicit operator bool() const { return not empty(); }
bool empty() const { return *this == BOTTOM.c() or *this == EMPTY.c(); }
};
/** @note storage guaranteed to exist */
constexpr inline Literal::Literal() noexcept : str_(Symbol::EMPTY) { }
namespace{
constexpr inline int
strNcmp (CStr a, CStr b, size_t len)
{
return a == b ? 0 : std::strncmp (a?a:"", b?b:"", len);
}
}
/** safety guard: maximum number of chars to process.
* For comparisons, hash calculations etc., when dealing
* with raw char ptrs (typically literal values) */
extern const size_t STRING_MAX_RELEVANT;
/** @note storage guaranteed to exist */
inline Literal::Literal() noexcept : str_(Symbol::EMPTY) { }
/** equality on Literal and Symbol values is defined
* based on the content, not the address. */
constexpr inline bool
Literal::operator== (CStr charPtr) const
{
return 0 == strNcmp (this->str_, charPtr, STRING_MAX_RELEVANT);
}
constexpr inline size_t
Literal::length() const
{
return std::strlen(c());
}
/* ===== to be picked up by ADL ===== */
@ -175,35 +196,16 @@ namespace lib {
/* === equality comparisons === */
inline bool operator== (Literal const& s1, Literal const& s2) { return s1.operator== (s2.c()); }
inline bool operator== (Symbol const& s1, Symbol const& s2) { return s1.c() == s2.c(); } ///< @note comparison of symbol table entries
constexpr inline bool operator== (Literal const& s1, Literal const& s2) { return s1.operator== (s2.c()); }
constexpr inline bool operator== (Symbol const& s1, Symbol const& s2) { return s1.c() == s2.c(); } ///< @note comparison of symbol table entries
/* === mixed comparisons === */
inline bool operator== (CStr s1, Literal s2) { return s2.operator== (s1); }
inline bool operator== (Symbol s1, CStr s2) { return s1.operator== (s2); }
inline bool operator== (CStr s1, Symbol s2) { return s2.operator== (s1); }
inline bool operator== (Literal s1, Symbol s2) { return s1.operator== (s2.c()); }
inline bool operator== (Symbol s1, Literal s2) { return s2.operator== (s1.c()); }
inline bool operator== (Literal s1, std::string s2) { return s1.operator== (s2.c_str()); }
inline bool operator== (std::string s1, Literal s2) { return s2.operator== (s1.c_str()); }
inline bool operator== (Symbol s1, std::string s2) { return s1.operator== (s2.c_str()); }
inline bool operator== (std::string s1, Symbol s2) { return s2.operator== (s1.c_str()); }
/* === negations === */
inline bool operator!= (Literal const& s1, Literal const& s2) { return not s1.operator== (s2.c()); }
inline bool operator!= (Symbol const& s1, Symbol const& s2) { return not (s1.c() == s2.c()); }
inline bool operator!= (Literal s1, CStr s2) { return not s1.operator== (s2); }
inline bool operator!= (CStr s1, Literal s2) { return not s2.operator== (s1); }
inline bool operator!= (Symbol s1, CStr s2) { return not s1.operator== (s2); }
inline bool operator!= (CStr s1, Symbol s2) { return not s2.operator== (s1); }
inline bool operator!= (Literal s1, Symbol s2) { return not s1.operator== (s2.c()); }
inline bool operator!= (Symbol s1, Literal s2) { return not s2.operator== (s1.c()); }
inline bool operator!= (Literal s1, std::string s2) { return not s1.operator== (s2.c_str()); }
inline bool operator!= (std::string s1, Literal s2) { return not s2.operator== (s1.c_str()); }
inline bool operator!= (Symbol s1, std::string s2) { return not s1.operator== (s2.c_str()); }
inline bool operator!= (std::string s1, Symbol s2) { return not s2.operator== (s1.c_str()); }
constexpr inline bool operator== (CStr s1, Literal s2) { return s2.operator== (s1); }
constexpr inline bool operator== (Symbol s1, CStr s2) { return s1.operator== (s2); }
constexpr inline bool operator== (Literal s1, Symbol s2) { return s1.operator== (s2.c()); }
constexpr inline bool operator== (Literal s1, std::string const& s2) { return s1.operator== (s2.c_str()); }
constexpr inline bool operator== (Symbol s1, std::string const& s2) { return s1.operator== (s2.c_str()); }

View file

@ -588,7 +588,7 @@ namespace test{
}
EventMatch&
EventMatch::on (const char* targetID)
EventMatch::on (CStr targetID)
{
refineSerach (solution_, matchAttribute("this",targetID));
evaluateQuery ("match-this(\""+string(targetID)+"\")");
@ -663,7 +663,7 @@ namespace test{
}
EventLog&
EventLog::clear (const char* alteredLogID)
EventLog::clear (CStr alteredLogID)
{
return clear (string{alteredLogID});
}
@ -700,7 +700,7 @@ namespace test{
}
EventLog&
EventLog::call (const char* target, const char* function, ArgSeq&& args)
EventLog::call (CStr target, CStr function, ArgSeq&& args)
{
return call (string(target), string(function), std::forward<ArgSeq>(args));
}

View file

@ -238,7 +238,7 @@ namespace test{
EventMatch& attrib (string key, string valueMatch);
EventMatch& id (string classifier);
EventMatch& on (string targetID);
EventMatch& on (const char* targetID);
EventMatch& on (CStr targetID);
template<typename X>
EventMatch& on (const X *const targetObj)
@ -298,7 +298,7 @@ namespace test{
EventLog (string logID);
explicit
EventLog (const char* logID)
EventLog (CStr logID)
: EventLog(string(logID))
{ }
@ -331,7 +331,7 @@ namespace test{
/** purge log contents while retaining just the original Header-ID */
EventLog& clear();
EventLog& clear (string alteredLogID);
EventLog& clear (const char* alteredLogID);
EventLog& clear (CStr alteredLogID);
template<class X>
EventLog&
@ -372,7 +372,7 @@ namespace test{
/** Log a function call with a sequence of stringified arguments */
EventLog& call (string target, string function, ArgSeq&& args);
EventLog& call (const char* target, const char* function, ArgSeq&& args);
EventLog& call (CStr target, CStr function, ArgSeq&& args);
/** Log a function call with arbitrary arguments */
template<typename...ARGS>
@ -392,7 +392,7 @@ namespace test{
template<typename...ARGS>
EventLog&
call (const char* target, string function, ARGS const& ...args)
call (CStr target, string function, ARGS const& ...args)
{
return call (string(target), function, args...);
}

View file

@ -105,7 +105,7 @@ namespace test{
*/
template<typename T>
inline string
showSizeof (T const* obj =0, const char* name =0)
showSizeof (T const* obj =0, CStr name =0)
{
return showSizeof (obj? sizeof(*obj) : sizeof(T),
name? name : util::typeStr(obj));
@ -114,14 +114,14 @@ namespace test{
template<typename T>
inline meta::disable_if<std::is_pointer<T>,
string > // note:: force invocations with pointer to the first overload
showSizeof (T const& obj, const char* name=0)
showSizeof (T const& obj, CStr name =nullptr)
{
return showSizeof (&obj, name);
}
template<typename T>
inline string
showSizeof (const char* name)
showSizeof (CStr name)
{
return showSizeof<T> (nullptr, name);
}
@ -375,7 +375,7 @@ namespace test{
* \endcode
*/
inline lib::test::ExpectString
operator""_expect (const char* lit, size_t siz)
operator""_expect (CStr lit, size_t siz)
{
return lib::test::ExpectString{lit, siz};
}

View file

@ -236,7 +236,7 @@ namespace lib {
}
friend string
operator+ (const char* prefix, FamilyMember id)
operator+ (CStr prefix, FamilyMember id)
{
return string(prefix)+id;
}

View file

@ -46,14 +46,14 @@ namespace std {// forward declarations to avoid pervasive includes
}
const char* cStr (std::string const&);
using CStr = const char*;
CStr cStr (std::string const&);
namespace util {
using std::string;
using CStr = const char*;
template <class NUM>

View file

@ -361,7 +361,7 @@ namespace ctrl {
// Temporary Junk
void
unimplemented (const char* todo)
unimplemented (Literal todo)
{
WARN (stage, "%s is not yet implemented. So sorry.", todo);
}

View file

@ -83,7 +83,7 @@ namespace ctrl {
namespace {
/** @note reads and clears the lumiera error flag */
inline string
generateErrorResponse (const char* problem = "unexpected problem")
generateErrorResponse (lib::Literal problem = "unexpected problem")
{
static _Fmt messageTemplate{"asynchronous UI response failed: %s (error flag was: %s)"};
string response{messageTemplate % problem % lumiera_error()};

View file

@ -145,7 +145,7 @@ namespace stage {
}
catch(...)
{
const char* errID = lumiera_error(); // clear C-style error flag
CStr errID = lumiera_error(); // clear C-style error flag
WARN (stage, "Unexpected error while starting the GUI thread.");
if (errID)
TRACE (stage, "Error flag was: %s", errID);

View file

@ -117,7 +117,7 @@ namespace interact {
namespace { // Temporary Junk
inline void
unimplemented (const char* todo)
unimplemented (Literal todo)
{
WARN (stage, "%s is not yet implemented. So sorry.", todo);
}

View file

@ -279,10 +279,10 @@ namespace interact {
struct Resolution
{
const char* anchor = nullptr;
size_t depth = 0;
CStr anchor = nullptr;
size_t depth = 0;
unique_ptr<UICoord> covfefe{};
bool isResolved = false;
bool isResolved = false;
};
LocationQuery& query_;

View file

@ -113,11 +113,11 @@ namespace widget{
void
MenuButton::append (const char *slug, const char* title,
MenuButton::append (CStr slug, CStr title,
sigc::slot<void>& callback, bool toggle)
{
uString uSlug (slug);
uString uTitle (_(title));
uString uSlug{slug};
uString uTitle{_(title)};
append (uSlug, uTitle, callback, toggle);
}

View file

@ -95,7 +95,7 @@ namespace widget {
* @param callback The signal handler when clicked
* @param toggle
*/
void append (const char* slug, const char* title, sigc::slot<void>& callback, bool toggle=false);
void append (CStr slug, CStr title, sigc::slot<void>& callback, bool toggle=false);
/** Append a Gtk::SeparatorMenuItem to the Menu */

View file

@ -261,7 +261,7 @@ namespace workspace {
int
DockArea::findPanelDescription (const char* class_name)
DockArea::findPanelDescription (CStr class_name)
{
REQUIRE(class_name);
@ -313,7 +313,7 @@ namespace workspace {
panel::Panel*
DockArea::createPanel_by_name (const char* class_name)
DockArea::createPanel_by_name (CStr class_name)
{
REQUIRE(class_name);
const int index = findPanelDescription(class_name);

View file

@ -173,7 +173,7 @@ namespace workspace {
* @return Returns the index of the panel description found, or -1
* if no description was found for this type.
*/
static int findPanelDescription (const char* class_name);
static int findPanelDescription (CStr class_name);
/**
* Creates a panel by description index.
@ -195,7 +195,7 @@ namespace workspace {
* @param class_name The name of the object class to create.
* @return Returns a pointer to the new instantiated panel object.
*/
panel::Panel* createPanel_by_name (const char* class_name);
panel::Panel* createPanel_by_name (CStr class_name);
/**
* Gets the type of a given panel.

View file

@ -166,7 +166,7 @@ namespace workspace {
* @return Returns the index of the panel description found, or -1
* if no description was found for this type.
*/
static int findPanelDescription (const char* class_name);
static int findPanelDescription (CStr class_name);
/**
* Creates a panel by description index.
@ -188,7 +188,7 @@ namespace workspace {
* @param class_name The name of the object class to create.
* @return Returns a pointer to the new instantiated panel object.
*/
panel::Panel* createPanel_by_name (const char* class_name);
panel::Panel* createPanel_by_name (CStr class_name);
/**
* Gets the type of a given panel.

View file

@ -194,28 +194,6 @@ namespace asset {
}
MediaFactory::PType
MediaFactory::operator() (const char* file, const Category& cat)
{
if (!file) file = "";
return operator() (string(file),cat);
}
MediaFactory::PType
MediaFactory::operator() (const char* file, asset::Kind kind)
{
if (!file) file = "";
return operator() (string(file),kind);
}
MediaFactory::PType
MediaFactory::operator() (Asset::Ident& key, const char* file)
{
if (!file) file = "";
return operator() (key, string(file));
}
/** Factory method for creating a Clip asset based
* on the given Media asset. This asset::Clip can be used
* to create a clip in the session covering the whole length

View file

@ -141,10 +141,6 @@ namespace asset {
PType operator() (const string& file, const Category& cat);
PType operator() (const string& file, asset::Kind);
PType operator() (Asset::Ident& key, const char* file); ///< convenience overload using C-String
PType operator() (const char* file, const Category& cat);
PType operator() (const char* file, asset::Kind);
lib::P<Clip>
operator() (Media& mediaref);

View file

@ -137,7 +137,7 @@ namespace control {
inline
com::RuntimeCheckedCommandInvoker
invoke (const char* cmdID)
invoke (CStr cmdID)
{
return invoke(Symbol(cmdID));
}

View file

@ -45,7 +45,7 @@ namespace control {
ExecResult
HandlingPattern::invoke (CommandImpl& command, string id, Action action) const
{
const char* cmdName = cStr(id);
CStr cmdName = cStr(id);
TRACE (proc_dbg, "invoking %s...", cmdName);
static _Fmt err_pre ("Error state detected, %s *NOT* invoked.");
static _Fmt err_post ("Error state after %s invocation.");

View file

@ -59,7 +59,7 @@ namespace control {
* their basic setup functions using this hook, which can be done via
* the C interface functions
*/
const char* ON_STREAMTYPES_RESET ("ON_STREAMTYPES_RESET");
CStr ON_STREAMTYPES_RESET ("ON_STREAMTYPES_RESET");

View file

@ -90,7 +90,7 @@ namespace control {
ImplFacade const& fetchImpl (StreamType::ImplFacade::TypeTag);
};
extern const char* ON_STREAMTYPES_RESET; ///< triggered to load the generic pristine default
extern CStr ON_STREAMTYPES_RESET; ///< triggered to load the generic pristine default
template<class TY>

View file

@ -84,7 +84,7 @@ namespace mobject {
* session should register their basic setup functions using this hook, which can be
* done via the C interface functions defined in lifecycle.h
*/
const char* ON_SESSION_START = "ON_SESSION_START";
CStr ON_SESSION_START = "ON_SESSION_START";
/**
* LifecycleHook, to perform any initialisation, wiring and registrations necessary
@ -92,7 +92,7 @@ namespace mobject {
* and configuration has already be loaded. Any subsystems requiring to build some indices
* or wiring to keep track of the session's content should register here.
*/
const char* ON_SESSION_INIT = "ON_SESSION_INIT";
CStr ON_SESSION_INIT = "ON_SESSION_INIT";
/**
* LifecycleHook, to perform post loading tasks, requiring an already completely usable
@ -103,7 +103,7 @@ namespace mobject {
* fully functional client side APIs. Examples would be statistics gathering, validation
* or auto-correction of the session's contents.
*/
const char* ON_SESSION_READY = "ON_SESSION_READY";
CStr ON_SESSION_READY = "ON_SESSION_READY";
/**
* LifecycleHook, to commence any activity relying on an opened and fully operative session.
@ -112,7 +112,7 @@ namespace mobject {
* sequence will be initiated, by detaching the engine interfaces and signalling the
* scheduler to cease running render jobs.
*/
const char* ON_SESSION_CLOSE ="ON_SESSION_CLOSE";
CStr ON_SESSION_CLOSE ="ON_SESSION_CLOSE";
/**
* LifecycleHook, to perform any state saving, deregistration or de-activation necessary
@ -122,7 +122,7 @@ namespace mobject {
* specific/internal information into the persisted state, besides actually attaching
* data to objects within the session?
*/
const char* ON_SESSION_END ="ON_SESSION_END";
CStr ON_SESSION_END ="ON_SESSION_END";

View file

@ -113,7 +113,7 @@ namespace vault {
* for the media asset corresponding to this channel.
* May be NULL or empty and need not be unique.
*/
const char* chanID;
CStr chanID;
/** identifier characterising the access method (or codec)
* needed to get at the media data. This should be rather
@ -121,15 +121,16 @@ namespace vault {
* e.g. "H264" -- anyhow, it will be used to find a
* codec asset for this channel.
*/
const char* codecID;
CStr codecID;
/** opaque handle, which will be used later to open this
* channel and retrieve some frames from it
*/
MediaAccessFacade::ChanHandle handle;
ChanDesc (const char* chanName=0, const char* codec=0,
MediaAccessFacade::ChanHandle h=0)
ChanDesc (CStr chanName =nullptr
,CStr codec =nullptr
,MediaAccessFacade::ChanHandle h =nullptr)
: chanID(chanName),
codecID(codec),
handle(h)

View file

@ -249,7 +249,7 @@ namespace test {
Symbol i11 = iManager.newInstance (COMMAND_PROTOTYPE, "i1");
CHECK (i11 == i1);
CHECK ((const char*)i11 == (const char*) i1);
CHECK (CStr(i11) == CStr(i1));
// but the instances themselves are disjoint
Command c13 = iManager.getInstance (i1);

View file

@ -119,7 +119,7 @@ namespace test {
CHECK (sizeof(def_empty) == sizeof(Literal));
CHECK (sizeof(def_empty) == sizeof(char*));
const char* actualContent = reinterpret_cast<char*&>(def_empty);
CStr actualContent = reinterpret_cast<char*&>(def_empty);
CHECK (actualContent == empty_text);
// for convenience a string conversion is provided...

View file

@ -66,7 +66,7 @@ namespace test{
string*
next ()
{
static const char* lumi ="Lumiera";
static Literal lumi{"Lumiera"};
currentText_ = string (lumi + *DummySolutions<int>::next());
return &currentText_;
}

View file

@ -108,7 +108,7 @@ namespace test{
ulong l2 (rani (1000));
string s1 (randStr(50));
string s2 (randStr(50));
const char* cp (s1.c_str());
CStr cp (s1.c_str());
verifyWrapper<ulong> (l1, l2);
verifyWrapper<ulong&> (l1, l2);
@ -121,7 +121,7 @@ namespace test{
verifyWrapper<string&> (s1, s2);
verifyWrapper<string*> (&s1, &s2);
verifyWrapper<const char*> (cp, "Lumiera");
verifyWrapper<CStr> (cp, "Lumiera");
verifySaneInstanceHandling();

View file

@ -152,7 +152,7 @@ namespace test{
verify_inlineStorage()
{
// char payload[24];// ◁─────────────────────────────── use this to make the test fail....
const char* payload = "please look elsewhere";
const char* payload = "I am innocent as a lamb";
auto lambda = [payload]{ return RawAddr(&payload); };
RawAddr location = lambda();

View file

@ -34,7 +34,7 @@ namespace test {
void basicInitHook () { ++basicInit; }
void myCallback() { ++customCallback; }
const char* MY_DEADLY_EVENT = "dial M for murder";
CStr MY_DEADLY_EVENT = "dial M for murder";
namespace // register them to be invoked by lifecycle event id

View file

@ -69,7 +69,7 @@ class ExamplePlugin_de
}
static void
servus (const char* m)
servus (CStr m)
{
cout << "Tschüss " << m << endl;
}
@ -87,7 +87,7 @@ class ExamplePlugin_en
}
static void
bye (const char* m)
bye (CStr m)
{
cout << "Bye " << m << endl;
}

View file

@ -171,7 +171,7 @@ namespace interact {
{
if (depth<maxDepth and path.isPresent(depth))
{
const char* pathElm = resolveElm (path, depth);
CStr pathElm = resolveElm (path, depth);
if (hasNode (tree, pathElm, depth))
{
++depth;
@ -189,7 +189,7 @@ namespace interact {
* when navigating the widgets of a real-world UI toolkit set
*/
static bool
hasNode (Rec const& tree, const char* pathElm, size_t depth)
hasNode (Rec const& tree, CStr pathElm, size_t depth)
{
return depth==UIC_PERSP? pathElm == tree.getType()
: tree.hasAttribute(pathElm);
@ -197,7 +197,7 @@ namespace interact {
/** within `tree` _at level_ `depth` descend into the child element designated by `pathElm` */
static Rec const&
descendInto (Rec const& tree, size_t depth, const char* pathElm)
descendInto (Rec const& tree, size_t depth, CStr pathElm)
{
return depth==UIC_PERSP? tree // perspective info is attached as type at the parent node
: tree.get(pathElm).data.get<Rec>();

View file

@ -315,7 +315,7 @@ namespace test{
}
catch(...)
{
const char* errID = lumiera_error();
CStr errID = lumiera_error();
if (errID)
cerr << "Error while logging shutdown of Mock-UI-Element: " << errID <<endl;
else

View file

@ -167002,9 +167002,10 @@ Since then others have made contributions, see the log for the history.</font></
</node>
</node>
</node>
<node CREATED="1749399035206" ID="ID_1949114637" MODIFIED="1749399038099" TEXT="clean-up">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1749399035206" ID="ID_1949114637" MODIFIED="1751487101003" TEXT="clean-up">
<icon BUILTIN="pencil"/>
<node CREATED="1749399040718" ID="ID_1669273438" MODIFIED="1749399043457" TEXT="Variant-o"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1749428622377" ID="ID_1502394581" MODIFIED="1749428716314" TEXT="soll Literal / Symbol weiterhin implizit aus CStr erstellbar sein">
<node COLOR="#435e98" CREATED="1749428622377" ID="ID_1502394581" MODIFIED="1751479815831" TEXT="soll Literal / Symbol weiterhin implizit aus CStr erstellbar sein">
<linktarget COLOR="#9e335b" DESTINATION="ID_1502394581" ENDARROW="Default" ENDINCLINATION="553;-29;" ID="Arrow_ID_227291299" SOURCE="ID_1640565416" STARTARROW="None" STARTINCLINATION="-98;111;"/>
<icon BUILTIN="help"/>
<node CREATED="1749428768562" HGAP="34" ID="ID_1963341770" MODIFIED="1749429203699" TEXT="eigentlich schon ...." VSHIFT="6">
@ -167028,6 +167029,23 @@ Since then others have made contributions, see the log for the history.</font></
</html></richcontent>
<icon BUILTIN="ksmiletris"/>
</node>
<node COLOR="#338800" CREATED="1751487056673" ID="ID_1177999705" MODIFIED="1751487077626">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
aber Literal kann komplett <b>constexpr</b>&#160;sein
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1751487078974" ID="ID_145911599" MODIFIED="1751487096003" TEXT="und die meisten Vergleichsoperatoren sind &#xfc;berfl&#xfc;ssig">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1749437085707" ID="ID_586550649" MODIFIED="1749437096722" TEXT="Boost-Operators k&#xf6;nnte man komplett loswerden">
<icon BUILTIN="flag-yellow"/>