/* Symbol(impl) - helpers for working with literal string IDs Copyright (C) 2009,2017 Hermann Vosseler   **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 #include #include #include 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 (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 ``. 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