From fc488f3b562125d5318f44886821f8dbdbb1a9da Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 29 Jun 2015 02:31:22 +0200 Subject: [PATCH] extract a basic set of generic ID functions for #984 using the struct-scheme.hpp and the requirements for EntryID as a guideline. The goal is to move EntryID over into the support lib, which means we need to get rid of all direct proc::asset dependencies. Thus, these generic ID functions shall form a baseline implementation, while asset::Struct may provide the previously used implementation through specialisation -- so the behaviour of EntryID will not change for the structural assets, but we'll get a more sane and readable default implementation for all other types. --- src/lib/idi/genfunc.cpp | 76 +++++++++++++++++++++++++++++++++++++ src/lib/idi/genfunc.hpp | 76 ++++++++++++++++++++++++++++++++++--- src/lib/symbol-impl.cpp | 3 +- src/lib/typed-counter.hpp | 2 +- src/proc/asset/entry-id.hpp | 1 + 5 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 src/lib/idi/genfunc.cpp diff --git a/src/lib/idi/genfunc.cpp b/src/lib/idi/genfunc.cpp new file mode 100644 index 000000000..76ca64e7b --- /dev/null +++ b/src/lib/idi/genfunc.cpp @@ -0,0 +1,76 @@ +/* + GenFunc - generic identification functions (raw) + + Copyright (C) Lumiera.org + 2015, Hermann Vosseler + + 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. + +* *****************************************************/ + + +#include "lib/idi/genfunc.hpp" +#include "lib/format-string.hpp" +#include "lib/util.hpp" + +#include +#include + + +using util::_Fmt; +using std::string; + + +namespace lib { +namespace test{ // see test-helper.cpp + std::string demangleCxx (lib::Literal rawName); +} +namespace idi { + + + namespace { // generic entry points / integration helpers... + + using lib::test::demangleCxx; + + string + demangled_innermost_component (const char* rawName) + { + string typeStr = demangleCxx (rawName); + size_t pos = typeStr.rfind("::"); + if (pos != string::npos) + typeStr = typeStr.substr(pos+2); + return typeStr; + } + + string + demangled_sanitised_name (const char* rawName) + { + return util::sanitise (test::demangleCxx (rawName)); + } + + + string + instance_formatter (string const& prefix, long instanceNr) + { + return _Fmt("%s.%03d") + % prefix % instanceNr; + } + + } //(End)integration helpers... + + + + +}} // namespace lib::test diff --git a/src/lib/idi/genfunc.hpp b/src/lib/idi/genfunc.hpp index d88c4b306..53f760674 100644 --- a/src/lib/idi/genfunc.hpp +++ b/src/lib/idi/genfunc.hpp @@ -43,27 +43,93 @@ #define LIB_IDI_GENFUNC_H #include "lib/hash-value.h" +#include "lib/symbol.hpp" +#include "lib/typed-counter.hpp" //#include "lib/hash-standard.hpp" +#include #include namespace lib { namespace idi { + using lib::HashVal; + using std::string; + namespace { // integration helpers... + string demangled_innermost_component (const char* rawName); + string demangled_sanitised_name (const char* rawName); + + string instance_formatter (string const& prefix, long instanceNr); + } //(End)integration helpers... - /********************************************************//** - * A Mixin to add a private ID type to the target class, - * together with storage to hold an instance of this ID, - * getter and setter, and a templated version of the ID type - * which can be used to pass specific subclass type info. + /** Short readable type identifier, not necessarily unique or complete. + * @return the innermost component of the demangled C++ type name. + * Usually, this is the bare name without any namespaces. */ + template + inline string + typeSymbol() + { + return demangled_innermost_component (typeid(TY).name()); + } + + /** Complete unique type identifier + * @return complete demangled C++ type name, additionally + * passed through our ID sanitiser function, i.e. + * one word, no whitespace, only minimal punctuation + */ + template + inline string + typeFullID() + { + return demangled_sanitised_name (typeid(TY).name()); + } + + template + inline string + categoryFolder() + { + return typeSymbol(); + } + + template + inline string + namePrefix() + { + return typeSymbol(); + } + /** build a per-type unique identifier. + * @return a type based prefix, followed by an instance number + * @note we use the short prefix without namespace, not necessarily unique + * @warning this operation is not exactly cheap; it acquires a lock + * for the counter and, after increasing and dropping the lock, + * it builds and uses a boost::format instance. + */ + template + inline string + generateSymbolicID() + { + static TypedCounter instanceCounter; + return instance_formatter (namePrefix(), instanceCounter.inc()); + } + + /** + * @return a boost hash value, based on the full (mangled) C++ type name + */ + template + inline HashVal + getTypeHash() + { + Literal rawTypeName (typeid(TY).name()); + return hash_value (rawTypeName); + } diff --git a/src/lib/symbol-impl.cpp b/src/lib/symbol-impl.cpp index b9aade749..3762179c4 100644 --- a/src/lib/symbol-impl.cpp +++ b/src/lib/symbol-impl.cpp @@ -68,7 +68,8 @@ namespace lib { and should be usable both with \c std::tr1 and \c . It is implemented similar as the boost::hash specialisation for std::string */ - size_t hash_value (Literal sym) + size_t + hash_value (Literal sym) { size_t hash=0; if (sym) diff --git a/src/lib/typed-counter.hpp b/src/lib/typed-counter.hpp index ce62ab6d2..88e14fc07 100644 --- a/src/lib/typed-counter.hpp +++ b/src/lib/typed-counter.hpp @@ -30,7 +30,7 @@ ** setup allows to bridge between metaprogramming and (runtime) dispatcher tables. ** ** Each such series of type-id-slots is associated to a distinct usage context. - ** Those usage contexts are discerned by the template parameter \c XY. Each of + ** Those usage contexts are discerned by the template parameter \c CX. Each of ** these usage contexts uses a separate numbering scheme on his own, i.e. every ** new type encountered at runtime gets the next higher ID number (slot). ** @warning the actual ID numbers depend on the sequence of first encountering diff --git a/src/proc/asset/entry-id.hpp b/src/proc/asset/entry-id.hpp index a352a8d4e..d4bc7b6db 100644 --- a/src/proc/asset/entry-id.hpp +++ b/src/proc/asset/entry-id.hpp @@ -46,6 +46,7 @@ #include "proc/asset.hpp" #include "proc/asset/struct-scheme.hpp" #include "lib/hash-indexed.hpp" +#include "lib/idi/genfunc.hpp" #include "lib/util.hpp" #include