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)
108 lines
2.8 KiB
C++
108 lines
2.8 KiB
C++
/*
|
||
Symbol(impl) - helpers for working with literal string IDs
|
||
|
||
Copyright (C)
|
||
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
|
||
Free Software Foundation; either version 2 of the License, or (at your
|
||
option) any later version. See the file COPYING for further details.
|
||
|
||
* *****************************************************************/
|
||
|
||
/** @file symbol-impl.cpp
|
||
** 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_
|
||
*/
|
||
|
||
|
||
|
||
#include "lib/symbol.hpp"
|
||
#include "lib/symbol-table.hpp"
|
||
|
||
#include <boost/functional/hash.hpp>
|
||
#include <cstddef>
|
||
#include <cstring>
|
||
#include <string>
|
||
|
||
using std::size_t;
|
||
using std::string;
|
||
using std::forward;
|
||
using boost::hash_combine;
|
||
|
||
|
||
|
||
|
||
namespace lib {
|
||
|
||
const size_t STRING_MAX_RELEVANT = LUMIERA_IDSTRING_MAX_RELEVANT;
|
||
|
||
namespace { // global symbol table
|
||
|
||
SymbolTable&
|
||
symbolTable()
|
||
{
|
||
static SymbolTable theSymbolTable;
|
||
return theSymbolTable; // Meyer's Singleton
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* create Symbol by symbol table lookup.
|
||
* @note identical strings will be mapped to the same Symbol (embedded pointer)
|
||
* @warning potential lock contention, since each ctor call needs to do a lookup
|
||
* @remark since lumiera::LifecycleHook entries use a Symbol, the symbol table is
|
||
* implemented as Meyer's singleton and pulled up early, way before main()
|
||
*/
|
||
Symbol::Symbol (string&& definition)
|
||
: Literal{symbolTable().internedString (forward<string> (definition))}
|
||
{ }
|
||
|
||
|
||
/* == predefined marker Symbols == */
|
||
Symbol Symbol::ANY = "*";
|
||
Symbol Symbol::EMPTY = "";
|
||
Symbol Symbol::BOTTOM = "⟂";
|
||
Symbol Symbol::FAILURE = "↯";
|
||
|
||
// see also: lib/format-obj.cpp
|
||
// We can not share these definitions due to undefined static init order
|
||
|
||
|
||
|
||
|
||
|
||
/** generate hash value based on the Literal's contents.
|
||
* This function is intended to be picked up by ADL, and should be usable
|
||
* both with `std::hash` and `<boost/functional/hash.hpp>`. It is implemented
|
||
* similar as the boost::hash specialisation for std::string */
|
||
HashVal
|
||
hash_value (Literal literal)
|
||
{
|
||
size_t hash=0;
|
||
if (literal)
|
||
{
|
||
size_t cnt = 1;
|
||
CStr pos = literal;
|
||
for ( ; cnt <= STRING_MAX_RELEVANT and *pos ; ++cnt, ++pos )
|
||
hash_combine (hash, *pos);
|
||
}
|
||
|
||
return hash;
|
||
}
|
||
|
||
/** hash value for Symbols is directly based on the symbol table entry */
|
||
HashVal
|
||
hash_value (Symbol sym)
|
||
{
|
||
return sym? boost::hash_value (sym.c())
|
||
: 0;
|
||
}
|
||
|
||
|
||
|
||
} // namespace lib
|