Embedded Template Library  1.0
hash.h
Go to the documentation of this file.
1 
3 /******************************************************************************
4 The MIT License(MIT)
5 
6 Embedded Template Library.
7 https://github.com/ETLCPP/etl
8 https://www.etlcpp.com
9 
10 Copyright(c) 2014 jwellbelove
11 
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files(the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions :
18 
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21 
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29 ******************************************************************************/
30 
31 #ifndef ETL_HASH_INCLUDED
32 #define ETL_HASH_INCLUDED
33 
34 #include <stdint.h>
35 #include <stdlib.h>
36 
37 #include "platform.h"
38 
39 // The default hash calculation.
40 #include "fnv_1.h"
41 #include "type_traits.h"
42 #include "static_assert.h"
43 
46 
47 namespace etl
48 {
49  namespace private_hash
50  {
51  //*************************************************************************
54  //*************************************************************************
55  template <typename T>
56  typename enable_if<sizeof(T) == sizeof(uint16_t), size_t>::type
57  generic_hash(const uint8_t* begin, const uint8_t* end)
58  {
59  uint32_t h = fnv_1a_32(begin, end);
60 
61  return static_cast<size_t>(h ^ (h >> 16));
62  }
63 
64  //*************************************************************************
67  //*************************************************************************
68  template <typename T>
69  typename enable_if<sizeof(T) == sizeof(uint32_t), size_t>::type
70  generic_hash(const uint8_t* begin, const uint8_t* end)
71  {
72  return fnv_1a_32(begin, end);
73  }
74 
75 #if ETL_USING_64BIT_TYPES
76  //*************************************************************************
79  //*************************************************************************
80  template <typename T>
81  typename enable_if<sizeof(T) == sizeof(uint64_t), size_t>::type
82  generic_hash(const uint8_t* begin, const uint8_t* end)
83  {
84  return fnv_1a_64(begin, end);
85  }
86 #endif
87  }
88 
89  //***************************************************************************
92  //***************************************************************************
93  template <typename T> struct hash;
94 
95  //***************************************************************************
98  //***************************************************************************
99  template <>
100  struct hash <bool>
101  {
102  ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(bool), "size_t smaller than type");
103 
104  size_t operator ()(bool v) const
105  {
106  return static_cast<size_t>(v);
107  }
108  };
109 
110  //***************************************************************************
113  //***************************************************************************
114  template <>
115  struct hash<char>
116  {
117  ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(char), "size_t smaller than type");
118 
119  size_t operator ()(char v) const
120  {
121  return static_cast<size_t>(v);
122  }
123  };
124 
125  //***************************************************************************
128  //***************************************************************************
129  template<> struct
131  {
132  ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(signed char), "size_t smaller than type");
133 
134  size_t operator ()(signed char v) const
135  {
136  return static_cast<size_t>(v);
137  }
138  };
139 
140  //***************************************************************************
143  //***************************************************************************
144  template<>
145  struct hash<unsigned char>
146  {
147  ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned char), "size_t smaller than type");
148 
149  size_t operator ()(unsigned char v) const
150  {
151  return static_cast<size_t>(v);
152  }
153  };
154 
155  //***************************************************************************
158  //***************************************************************************
159  template<>
160  struct hash<wchar_t>
161  {
162  ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(wchar_t), "size_t smaller than type");
163 
164  size_t operator ()(wchar_t v) const
165  {
166  return static_cast<size_t>(v);
167  }
168  };
169 
170  //***************************************************************************
173  //***************************************************************************
174  template<>
175  struct hash<short>
176  {
177  ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(short), "size_t smaller than type");
178 
179  size_t operator ()(short v) const
180  {
181  return static_cast<size_t>(v);
182  }
183  };
184 
185  //***************************************************************************
188  //***************************************************************************
189  template<>
190  struct hash<unsigned short>
191  {
192  ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned short), "size_t smaller than type");
193 
194  size_t operator ()(unsigned short v) const
195  {
196  return static_cast<size_t>(v);
197  }
198  };
199 
200  //***************************************************************************
203  //***************************************************************************
204  template<>
205  struct hash<int>
206  {
207  ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(int), "size_t smaller than type");
208 
209  size_t operator ()(int v) const
210  {
211  return static_cast<size_t>(v);
212  }
213  };
214 
215  //***************************************************************************
218  //***************************************************************************
219  template<>
220  struct hash<unsigned int>
221  {
222  ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned int), "size_t smaller than type");
223 
224  size_t operator ()(unsigned int v) const
225  {
226  return static_cast<size_t>(v);
227  }
228  };
229 
230  //***************************************************************************
233  //***************************************************************************
234  template<>
235  struct hash<long>
236  {
237  size_t operator ()(long v) const
238  {
239  // If it's the same size as a size_t.
240  if (sizeof(size_t) >= sizeof(v))
241  {
242  return static_cast<size_t>(v);
243  }
244  else
245  {
246  uint8_t* p = reinterpret_cast<uint8_t*>(&v);
247  return private_hash::generic_hash<size_t>(p, p + sizeof(v));
248  }
249  }
250  };
251 
252  //***************************************************************************
255  //***************************************************************************
256  template<>
257  struct hash<long long>
258  {
259  size_t operator ()(long long v) const
260  {
261  // If it's the same size as a size_t.
262  if (sizeof(size_t) >= sizeof(v))
263  {
264  return static_cast<size_t>(v);
265  }
266  else
267  {
268  uint8_t* p = reinterpret_cast<uint8_t*>(&v);
269  return private_hash::generic_hash<size_t>(p, p + sizeof(v));
270  }
271  }
272  };
273 
274  //***************************************************************************
277  //***************************************************************************
278  template<>
279  struct hash<unsigned long>
280  {
281  size_t operator ()(unsigned long v) const
282  {
283  // If it's the same size as a size_t.
284  if (sizeof(size_t) >= sizeof(v))
285  {
286  return static_cast<size_t>(v);
287  }
288  else
289  {
290  uint8_t* p = reinterpret_cast<uint8_t*>(&v);
291  return private_hash::generic_hash<size_t>(p, p + sizeof(v));
292  }
293  }
294  };
295 
296  //***************************************************************************
299  //***************************************************************************
300  template<>
301  struct hash<unsigned long long>
302  {
303  size_t operator ()(unsigned long long v) const
304  {
305  // If it's the same size as a size_t.
306  if (sizeof(size_t) >= sizeof(v))
307  {
308  return static_cast<size_t>(v);
309  }
310  else
311  {
312  uint8_t* p = reinterpret_cast<uint8_t*>(&v);
313  return private_hash::generic_hash<size_t>(p, p + sizeof(v));
314  }
315  }
316  };
317 
318  //***************************************************************************
321  //***************************************************************************
322  template<>
323  struct hash<float>
324  {
325  size_t operator ()(float v) const
326  {
327  // If it's the same size as a size_t.
328  if (sizeof(size_t) == sizeof(v))
329  {
330  union
331  {
332  size_t s;
333  float v;
334  } u;
335 
336  u.v = v;
337 
338  return u.s;
339  }
340  else
341  {
342  uint8_t* p = reinterpret_cast<uint8_t*>(&v);
343  return private_hash::generic_hash<size_t>(p, p + sizeof(v));
344  }
345  }
346  };
347 
348  //***************************************************************************
351  //***************************************************************************
352  template<>
353  struct hash<double>
354  {
355  size_t operator ()(double v) const
356  {
357  // If it's the same size as a size_t.
358  if (sizeof(size_t) == sizeof(v))
359  {
360  union
361  {
362  size_t s;
363  double v;
364  } u;
365 
366  u.v = v;
367 
368  return u.s;
369  }
370  else
371  {
372  uint8_t* p = reinterpret_cast<uint8_t*>(&v);
373  return private_hash::generic_hash<size_t>(p, p + sizeof(v));
374  }
375  }
376  };
377 
378  //***************************************************************************
381  //***************************************************************************
382  template<>
383  struct hash<long double>
384  {
385  size_t operator ()(long double v) const
386  {
387  // If it's the same size as a size_t.
388  if (sizeof(size_t) == sizeof(v))
389  {
390  union
391  {
392  size_t s;
393  long double v;
394  } u;
395 
396  u.v = v;
397 
398  return u.s;
399  }
400  else
401  {
402  uint8_t* p = reinterpret_cast<uint8_t*>(&v);
403  return private_hash::generic_hash<size_t>(p, p + sizeof(v));
404  }
405  }
406  };
407 
408  //***************************************************************************
411  //***************************************************************************
412  template <typename T>
413  struct hash<T*>
414  {
415  size_t operator ()(const T* v) const
416  {
417  // If it's the same size as a size_t.
418  if (sizeof(size_t) == sizeof(T*))
419  {
420  union
421  {
422  size_t s;
423  const T* v;
424  } u;
425 
426  u.v = v;
427 
428  return u.s;
429  }
430  else
431  {
432  uint8_t* p = reinterpret_cast<uint8_t*>(&v);
433  return private_hash::generic_hash<size_t>(p, p + sizeof(v));
434  }
435  }
436  };
437 }
438 
439 #endif
Definition: fnv_1.h:262
Definition: fnv_1.h:145
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition: container.h:49
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition: container.h:99
Definition: hash.h:93
Definition: hash.h:131
enable_if
Definition: type_traits_generator.h:1228
enable_if< sizeof(T)==sizeof(uint16_t), size_t >::type generic_hash(const uint8_t *begin, const uint8_t *end)
Definition: hash.h:57
Definition: absolute.h:37