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.
This commit is contained in:
Fischlurch 2015-06-29 02:31:22 +02:00
parent 7ea4f739bd
commit fc488f3b56
5 changed files with 151 additions and 7 deletions

76
src/lib/idi/genfunc.cpp Normal file
View file

@ -0,0 +1,76 @@
/*
GenFunc - generic identification functions (raw)
Copyright (C) Lumiera.org
2015, Hermann Vosseler <Ichthyostega@web.de>
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 <string>
#include <boost/functional/hash.hpp>
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

View file

@ -43,27 +43,93 @@
#define LIB_IDI_GENFUNC_H #define LIB_IDI_GENFUNC_H
#include "lib/hash-value.h" #include "lib/hash-value.h"
#include "lib/symbol.hpp"
#include "lib/typed-counter.hpp"
//#include "lib/hash-standard.hpp" //#include "lib/hash-standard.hpp"
#include <typeinfo>
#include <string> #include <string>
namespace lib { namespace lib {
namespace idi { namespace idi {
using lib::HashVal;
using std::string;
namespace { // integration helpers... 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... } //(End)integration helpers...
/********************************************************//** /** Short readable type identifier, not necessarily unique or complete.
* A Mixin to add a private ID type to the target class, * @return the innermost component of the demangled C++ type name.
* together with storage to hold an instance of this ID, * Usually, this is the bare name without any namespaces.
* getter and setter, and a templated version of the ID type
* which can be used to pass specific subclass type info.
*/ */
template<typename TY>
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<typename TY>
inline string
typeFullID()
{
return demangled_sanitised_name (typeid(TY).name());
}
template<typename TY>
inline string
categoryFolder()
{
return typeSymbol<TY>();
}
template<typename TY>
inline string
namePrefix()
{
return typeSymbol<TY>();
}
/** 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<class TY>
inline string
generateSymbolicID()
{
static TypedCounter instanceCounter;
return instance_formatter (namePrefix<TY>(), instanceCounter.inc<TY>());
}
/**
* @return a boost hash value, based on the full (mangled) C++ type name
*/
template<typename TY>
inline HashVal
getTypeHash()
{
Literal rawTypeName (typeid(TY).name());
return hash_value (rawTypeName);
}

View file

@ -68,7 +68,8 @@ namespace lib {
and should be usable both with \c std::tr1 and and should be usable both with \c std::tr1 and
\c <boost/functional/hash.hpp> . It is implemented \c <boost/functional/hash.hpp> . It is implemented
similar as the boost::hash specialisation for std::string */ 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; size_t hash=0;
if (sym) if (sym)

View file

@ -30,7 +30,7 @@
** setup allows to bridge between metaprogramming and (runtime) dispatcher tables. ** setup allows to bridge between metaprogramming and (runtime) dispatcher tables.
** **
** Each such series of type-id-slots is associated to a distinct usage context. ** 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 ** 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). ** new type encountered at runtime gets the next higher ID number (slot).
** @warning the actual ID numbers depend on the sequence of first encountering ** @warning the actual ID numbers depend on the sequence of first encountering

View file

@ -46,6 +46,7 @@
#include "proc/asset.hpp" #include "proc/asset.hpp"
#include "proc/asset/struct-scheme.hpp" #include "proc/asset/struct-scheme.hpp"
#include "lib/hash-indexed.hpp" #include "lib/hash-indexed.hpp"
#include "lib/idi/genfunc.hpp"
#include "lib/util.hpp" #include "lib/util.hpp"
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>