Lumiera  0.pre.03
»edit your freedom«
entry-id.hpp
Go to the documentation of this file.
1 /*
2  ENTRY-ID.hpp - plain symbolic and hash ID used for accounting
3 
4  Copyright (C)
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
40 #ifndef LIB_IDI_ENTRY_ID_H
41 #define LIB_IDI_ENTRY_ID_H
42 
43 
44 #include "lib/error.hpp"
45 #include "lib/hash-indexed.hpp"
46 #include "lib/idi/genfunc.hpp"
47 #include "lib/util.hpp"
48 
49 #include <boost/functional/hash.hpp>
50 #include <boost/operators.hpp>
51 #include <string>
52 
53 
54 namespace lib {
55 
63 namespace idi {
64 
65  namespace error = lumiera::error;
66 
67  using std::string;
68  using std::ostream;
69 
73  using lib::hash::LuidH;
74  using lib::HashVal;
75 
76  namespace {
83  const size_t KNUTH_MAGIC = 2654435761;
84 
85 
107  inline LuidH
108  buildHash (string const& sym, HashVal seed =0)
109  {
110  size_t l = sym.length();
111  if (l > 1) boost::hash_combine(seed, KNUTH_MAGIC * sym[l-1]);
112  if (l > 2) boost::hash_combine(seed, KNUTH_MAGIC * sym[l-2]);
113  if (l > 3) boost::hash_combine(seed, KNUTH_MAGIC * sym[l-3]);
114  if (l > 4) boost::hash_combine(seed, KNUTH_MAGIC * sym[l-4]);
115 
116  boost::hash_combine(seed, sym);
117  lumiera_uid tmpLUID;
118  lumiera_uid_set_ptr (&tmpLUID, reinterpret_cast<void*> (seed));
119  return reinterpret_cast<LuidH&> (tmpLUID);
120  }
121  }
122 
123 
124 
125  template<class TY>
126  struct EntryID;
127 
128 
134  : public boost::equality_comparable<BareEntryID>
135  {
136 
137  string symbol_;
138  LuidH hash_;
139 
140  protected:
147  BareEntryID (string const& symbolID, HashVal seed)
148  : symbol_(symbolID)
149  , hash_(buildHash (symbol_, seed))
150  { }
151 
153  explicit
154  BareEntryID (string const& symbolID)
155  : symbol_(symbolID)
156  , hash_{} // random
157  { }
158 
159  public:
160  /* default copyable and assignable */
161 
162 
163  bool
164  isValid() const
165  {
166  return bool(hash_);
167  }
168 
169  string const&
170  getSym() const
171  {
172  return symbol_;
173  }
174 
175  LuidH const&
176  getHash() const
177  {
178  return hash_;
179  }
180 
181  operator string() const;
182 
183 
186  : public std::unary_function<BareEntryID, size_t>
187  {
188  size_t operator() (BareEntryID const& obj) const { return obj.getHash(); }
189  };
190 
191 
192  template<typename TAR>
193  EntryID<TAR> const& recast() const;
194 
195  };
196 
197 
218  template<class TY>
219  struct EntryID
220  : BareEntryID
221  , boost::totally_ordered< EntryID<TY> >
222  {
223 
227  { }
228 
233  explicit
234  EntryID (string const& symbolID)
235  : BareEntryID (util::sanitise(symbolID), getTypeHash<TY>())
236  { }
237  explicit
238  EntryID (const char* symbolID)
239  : BareEntryID (util::sanitise(symbolID), getTypeHash<TY>())
240  { }
241 
246  explicit
247  EntryID (Symbol const& internalSymbol)
248  : BareEntryID (string(internalSymbol), getTypeHash<TY>())
249  { }
250 
251 
257  static bool
258  canRecast (BareEntryID const& bID)
259  {
260  return bID.getHash() == buildHash (bID.getSym(), getTypeHash<TY>());
261  }
262 
263  static EntryID const&
264  recast (BareEntryID const& bID)
265  {
266  if (!canRecast(bID))
267  throw error::Logic ("unable to recast EntryID: desired type "
268  "doesn't match original definition"
269  , error::LUMIERA_ERROR_WRONG_TYPE);
270  return static_cast<EntryID const&> (bID);
271  }
272 
273  explicit
274  operator string() const;
275 
276  friend bool operator< (EntryID const& i1, EntryID const& i2) { return i1.getSym() < i2.getSym(); }
277  };
278 
279 
280  inline bool
281  operator== (BareEntryID const& i1, BareEntryID const& i2)
282  {
283  return i1.getHash() == i2.getHash();
284  }
285 
286 
287 
288 
294  struct RandID
295  : BareEntryID
296  {
297  RandID (string const& symbolID)
298  : BareEntryID{util::sanitise (symbolID)}
299  { }
300  RandID (const char* symbolID)
301  : BareEntryID{util::sanitise (symbolID)}
302  { }
303  RandID (Symbol const& internalSymbol)
304  : BareEntryID{string{internalSymbol}}
305  { }
306  };
307 
308 
320  template<typename TAR>
321  EntryID<TAR> const&
323  {
324  return EntryID<TAR>::recast(*this);
325  }
326 
327 
328  inline
329  BareEntryID::operator string() const
330  {
331  return "bID-"+lib::idi::format::instance_hex_format(symbol_, hash_);
332  }
333 
334  template<class TY>
335  inline
336  EntryID<TY>::operator string() const
337  {
338  return "ID<"+typeSymbol<TY>()+">-"+EntryID::getSym();
339  }
340 
341 
342 
343 }} // namespace lib::idi
344 #endif /*LIB_IDI_ENTRY_ID_H*/
type erased baseclass for building a combined hash and symbolic ID.
Definition: entry-id.hpp:133
Entry-ID with a symbolic tag but just a plain random hash part.
Definition: entry-id.hpp:294
EntryID(string const &symbolID)
case-2: explicitly specify a symbolic ID to use.
Definition: entry-id.hpp:234
const size_t KNUTH_MAGIC
lousy old tinkerer&#39;s trick: hash values with poor distribution can be improved by spreading the input...
Definition: entry-id.hpp:83
typed symbolic and hash ID for asset-like position accounting.
Definition: entry-id.hpp:126
EntryID()
case-1: auto generated symbolic ID
Definition: entry-id.hpp:225
Implementation namespace for support and library code.
Generic functions to build identification schemes.
static bool canRecast(BareEntryID const &bID)
Definition: entry-id.hpp:258
BareEntryID(string const &symbolID, HashVal seed)
Not to be created stand-alone.
Definition: entry-id.hpp:147
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Token or Atom with distinct identity.
Definition: symbol.hpp:117
EntryID< TAR > const & recast() const
try to upcast this BareEntryID to a fully typed EntryID.
Definition: entry-id.hpp:322
BareEntryID(string const &symbolID)
store the symbol but use a random hash part
Definition: entry-id.hpp:154
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
HashVal getTypeHash()
Definition: genfunc.hpp:160
A template for generating hash based ID tags carrying compile-time type info.
Lumiera error handling (C++ interface).
string typeSymbol()
Short readable type identifier, not necessarily unique or complete.
Definition: genfunc.hpp:78
Hash implementation based on a lumiera unique object id (LUID) When invoking the default ctor...
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:52
EntryID(Symbol const &internalSymbol)
case-2b: rely on an internal, already sanitised symbol.
Definition: entry-id.hpp:247
string generateSymbolicID()
build a per-type identifier, with type prefix and running counter.
Definition: genfunc.hpp:136
unsigned char lumiera_uid[16]
storage for a Lumiera unique ID, based on a 128bit random number
Definition: hash-value.h:40
LuidH buildHash(string const &sym, HashVal seed=0)
build up a hash value, packaged as LUID.
Definition: entry-id.hpp:108
using BareEntryID derived objects as keys within std::unordered_map
Definition: entry-id.hpp:185
void lumiera_uid_set_ptr(lumiera_uid *luid, void *ptr)
Store a generic pointer in a luid.
Definition: luid.c:33