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) Lumiera.org
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
49 #ifndef LIB_IDI_ENTRY_ID_H
50 #define LIB_IDI_ENTRY_ID_H
51 
52 
53 #include "lib/error.hpp"
54 #include "lib/hash-indexed.hpp"
55 #include "lib/idi/genfunc.hpp"
56 #include "lib/util.hpp"
57 
58 #include <boost/functional/hash.hpp>
59 #include <boost/operators.hpp>
60 #include <string>
61 
62 
63 namespace lib {
64 
72 namespace idi {
73 
74  namespace error = lumiera::error;
75 
76  using std::string;
77  using std::ostream;
78 
82  using lib::hash::LuidH;
83  using lib::HashVal;
84 
85  namespace {
92  const size_t KNUTH_MAGIC = 2654435761;
93 
94 
116  inline LuidH
117  buildHash (string const& sym, HashVal seed =0)
118  {
119  size_t l = sym.length();
120  if (l > 1) boost::hash_combine(seed, KNUTH_MAGIC * sym[l-1]);
121  if (l > 2) boost::hash_combine(seed, KNUTH_MAGIC * sym[l-2]);
122  if (l > 3) boost::hash_combine(seed, KNUTH_MAGIC * sym[l-3]);
123  if (l > 4) boost::hash_combine(seed, KNUTH_MAGIC * sym[l-4]);
124 
125  boost::hash_combine(seed, sym);
126  lumiera_uid tmpLUID;
127  lumiera_uid_set_ptr (&tmpLUID, reinterpret_cast<void*> (seed));
128  return reinterpret_cast<LuidH&> (tmpLUID);
129  }
130  }
131 
132 
133 
134  template<class TY>
135  struct EntryID;
136 
137 
143  : public boost::equality_comparable<BareEntryID>
144  {
145 
146  string symbol_;
147  LuidH hash_;
148 
149  protected:
156  BareEntryID (string const& symbolID, HashVal seed)
157  : symbol_(symbolID)
158  , hash_(buildHash (symbol_, seed))
159  { }
160 
162  explicit
163  BareEntryID (string const& symbolID)
164  : symbol_(symbolID)
165  , hash_{} // random
166  { }
167 
168  public:
169  /* default copyable and assignable */
170 
171 
172  bool
173  isValid() const
174  {
175  return bool(hash_);
176  }
177 
178  string const&
179  getSym() const
180  {
181  return symbol_;
182  }
183 
184  LuidH const&
185  getHash() const
186  {
187  return hash_;
188  }
189 
190  operator string() const;
191 
192 
195  : public std::unary_function<BareEntryID, size_t>
196  {
197  size_t operator() (BareEntryID const& obj) const { return obj.getHash(); }
198  };
199 
200 
201  template<typename TAR>
202  EntryID<TAR> const& recast() const;
203 
204  };
205 
206 
227  template<class TY>
228  struct EntryID
229  : BareEntryID
230  , boost::totally_ordered< EntryID<TY> >
231  {
232 
236  { }
237 
242  explicit
243  EntryID (string const& symbolID)
244  : BareEntryID (util::sanitise(symbolID), getTypeHash<TY>())
245  { }
246  explicit
247  EntryID (const char* symbolID)
248  : BareEntryID (util::sanitise(symbolID), getTypeHash<TY>())
249  { }
250 
255  explicit
256  EntryID (Symbol const& internalSymbol)
257  : BareEntryID (string(internalSymbol), getTypeHash<TY>())
258  { }
259 
260 
266  static bool
267  canRecast (BareEntryID const& bID)
268  {
269  return bID.getHash() == buildHash (bID.getSym(), getTypeHash<TY>());
270  }
271 
272  static EntryID const&
273  recast (BareEntryID const& bID)
274  {
275  if (!canRecast(bID))
276  throw error::Logic ("unable to recast EntryID: desired type "
277  "doesn't match original definition"
278  , error::LUMIERA_ERROR_WRONG_TYPE);
279  return static_cast<EntryID const&> (bID);
280  }
281 
282  explicit
283  operator string() const;
284 
285  friend bool operator< (EntryID const& i1, EntryID const& i2) { return i1.getSym() < i2.getSym(); }
286  };
287 
288 
289  inline bool
290  operator== (BareEntryID const& i1, BareEntryID const& i2)
291  {
292  return i1.getHash() == i2.getHash();
293  }
294 
295 
296 
297 
303  struct RandID
304  : BareEntryID
305  {
306  RandID (string const& symbolID)
307  : BareEntryID{util::sanitise (symbolID)}
308  { }
309  RandID (const char* symbolID)
310  : BareEntryID{util::sanitise (symbolID)}
311  { }
312  RandID (Symbol const& internalSymbol)
313  : BareEntryID{string{internalSymbol}}
314  { }
315  };
316 
317 
329  template<typename TAR>
330  EntryID<TAR> const&
332  {
333  return EntryID<TAR>::recast(*this);
334  }
335 
336 
337  inline
338  BareEntryID::operator string() const
339  {
340  return "bID-"+lib::idi::format::instance_hex_format(symbol_, hash_);
341  }
342 
343  template<class TY>
344  inline
345  EntryID<TY>::operator string() const
346  {
347  return "ID<"+typeSymbol<TY>()+">-"+EntryID::getSym();
348  }
349 
350 
351 
352 }} // namespace lib::idi
353 #endif /*LIB_IDI_ENTRY_ID_H*/
type erased baseclass for building a combined hash and symbolic ID.
Definition: entry-id.hpp:142
Entry-ID with a symbolic tag but just a plain random hash part.
Definition: entry-id.hpp:303
EntryID(string const &symbolID)
case-2: explicitly specify a symbolic ID to use.
Definition: entry-id.hpp:243
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:92
typed symbolic and hash ID for asset-like position accounting.
Definition: entry-id.hpp:135
EntryID()
case-1: auto generated symbolic ID
Definition: entry-id.hpp:234
Implementation namespace for support and library code.
Generic functions to build identification schemes.
static bool canRecast(BareEntryID const &bID)
Definition: entry-id.hpp:267
BareEntryID(string const &symbolID, HashVal seed)
Not to be created stand-alone.
Definition: entry-id.hpp:156
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:199
Token or Atom with distinct identity.
Definition: symbol.hpp:126
EntryID< TAR > const & recast() const
try to upcast this BareEntryID to a fully typed EntryID.
Definition: entry-id.hpp:331
BareEntryID(string const &symbolID)
store the symbol but use a random hash part
Definition: entry-id.hpp:163
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
HashVal getTypeHash()
Definition: genfunc.hpp:169
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:87
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:56
EntryID(Symbol const &internalSymbol)
case-2b: rely on an internal, already sanitised symbol.
Definition: entry-id.hpp:256
string generateSymbolicID()
build a per-type identifier, with type prefix and running counter.
Definition: genfunc.hpp:145
unsigned char lumiera_uid[16]
storage for a Lumiera unique ID, based on a 128bit random number
Definition: hash-value.h:45
LuidH buildHash(string const &sym, HashVal seed=0)
build up a hash value, packaged as LUID.
Definition: entry-id.hpp:117
using BareEntryID derived objects as keys within std::unordered_map
Definition: entry-id.hpp:194
void lumiera_uid_set_ptr(lumiera_uid *luid, void *ptr)
Store a generic pointer in a luid.
Definition: luid.c:42