Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
hash.h
00001 ///\file 00002 00003 /****************************************************************************** 00004 The MIT License(MIT) 00005 00006 Embedded Template Library. 00007 https://github.com/ETLCPP/etl 00008 http://www.etlcpp.com 00009 00010 Copyright(c) 2014 jwellbelove 00011 00012 Permission is hereby granted, free of charge, to any person obtaining a copy 00013 of this software and associated documentation files(the "Software"), to deal 00014 in the Software without restriction, including without limitation the rights 00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 00016 copies of the Software, and to permit persons to whom the Software is 00017 furnished to do so, subject to the following conditions : 00018 00019 The above copyright notice and this permission notice shall be included in all 00020 copies or substantial portions of the Software. 00021 00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00028 SOFTWARE. 00029 ******************************************************************************/ 00030 00031 #ifndef __ETL_HASH__ 00032 #define __ETL_HASH__ 00033 00034 #include <stdint.h> 00035 #include <stdlib.h> 00036 00037 #include "platform.h " 00038 00039 // The default hash calculation. 00040 #include "fnv_1.h " 00041 #include "type_traits.h " 00042 #include "static_assert.h" 00043 00044 ///\defgroup hash Standard hash calculations 00045 ///\ingroup maths 00046 00047 namespace etl 00048 { 00049 namespace __private_hash__ 00050 { 00051 //************************************************************************* 00052 /// Hash to use when size_t is 16 bits. 00053 /// T is always expected to be size_t. 00054 //************************************************************************* 00055 template <typename T> 00056 typename enable_if<sizeof(T) == sizeof(uint16_t), size_t>::type 00057 generic_hash(const uint8_t* begin, const uint8_t* end) 00058 { 00059 uint32_t h = fnv_1a_32(begin, end); 00060 00061 return static_cast<size_t>(h ^ (h >> 16)); 00062 } 00063 00064 //************************************************************************* 00065 /// Hash to use when size_t is 32 bits. 00066 /// T is always expected to be size_t. 00067 //************************************************************************* 00068 template <typename T> 00069 typename enable_if<sizeof(T) == sizeof(uint32_t), size_t>::type 00070 generic_hash(const uint8_t* begin, const uint8_t* end) 00071 { 00072 return fnv_1a_32(begin, end); 00073 } 00074 00075 //************************************************************************* 00076 /// Hash to use when size_t is 64 bits. 00077 /// T is always expected to be size_t. 00078 //************************************************************************* 00079 template <typename T> 00080 typename enable_if<sizeof(T) == sizeof(uint64_t), size_t>::type 00081 generic_hash(const uint8_t* begin, const uint8_t* end) 00082 { 00083 return fnv_1a_64(begin, end); 00084 } 00085 } 00086 00087 //*************************************************************************** 00088 /// Generic declaration for etl::hash 00089 ///\ingroup hash 00090 //*************************************************************************** 00091 template <typename T> struct hash; 00092 00093 //*************************************************************************** 00094 /// Specialisation for bool. 00095 ///\ingroup hash 00096 //*************************************************************************** 00097 template <> 00098 struct hash <bool> 00099 { 00100 STATIC_ASSERT(sizeof(size_t) >= sizeof(bool), "size_t smaller than type"); 00101 00102 size_t operator ()(bool v) const 00103 { 00104 return static_cast<size_t>(v); 00105 } 00106 }; 00107 00108 //*************************************************************************** 00109 /// Specialisation for char. 00110 ///\ingroup hash 00111 //*************************************************************************** 00112 template <> 00113 struct hash<char> 00114 { 00115 STATIC_ASSERT(sizeof(size_t) >= sizeof(char), "size_t smaller than type"); 00116 00117 size_t operator ()(char v) const 00118 { 00119 return static_cast<size_t>(v); 00120 } 00121 }; 00122 00123 //*************************************************************************** 00124 /// Specialisation for signed char. 00125 ///\ingroup hash 00126 //*************************************************************************** 00127 template<> struct 00128 hash<signed char> 00129 { 00130 STATIC_ASSERT(sizeof(size_t) >= sizeof(signed char), "size_t smaller than type"); 00131 00132 size_t operator ()(signed char v) const 00133 { 00134 return static_cast<size_t>(v); 00135 } 00136 }; 00137 00138 //*************************************************************************** 00139 /// Specialisation for unsigned char. 00140 ///\ingroup hash 00141 //*************************************************************************** 00142 template<> 00143 struct hash<unsigned char> 00144 { 00145 STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned char), "size_t smaller than type"); 00146 00147 size_t operator ()(unsigned char v) const 00148 { 00149 return static_cast<size_t>(v); 00150 } 00151 }; 00152 00153 //*************************************************************************** 00154 /// Specialisation for wchar_t. 00155 ///\ingroup hash 00156 //*************************************************************************** 00157 template<> 00158 struct hash<wchar_t> 00159 { 00160 STATIC_ASSERT(sizeof(size_t) >= sizeof(wchar_t), "size_t smaller than type"); 00161 00162 size_t operator ()(wchar_t v) const 00163 { 00164 return static_cast<size_t>(v); 00165 } 00166 }; 00167 00168 //*************************************************************************** 00169 /// Specialisation for short. 00170 ///\ingroup hash 00171 //*************************************************************************** 00172 template<> 00173 struct hash<short> 00174 { 00175 STATIC_ASSERT(sizeof(size_t) >= sizeof(short), "size_t smaller than type"); 00176 00177 size_t operator ()(short v) const 00178 { 00179 return static_cast<size_t>(v); 00180 } 00181 }; 00182 00183 //*************************************************************************** 00184 /// Specialisation for unsigned short. 00185 ///\ingroup hash 00186 //*************************************************************************** 00187 template<> 00188 struct hash<unsigned short> 00189 { 00190 STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned short), "size_t smaller than type"); 00191 00192 size_t operator ()(unsigned short v) const 00193 { 00194 return static_cast<size_t>(v); 00195 } 00196 }; 00197 00198 //*************************************************************************** 00199 /// Specialisation for int. 00200 ///\ingroup hash 00201 //*************************************************************************** 00202 template<> 00203 struct hash<int> 00204 { 00205 STATIC_ASSERT(sizeof(size_t) >= sizeof(int), "size_t smaller than type"); 00206 00207 size_t operator ()(int v) const 00208 { 00209 return static_cast<size_t>(v); 00210 } 00211 }; 00212 00213 //*************************************************************************** 00214 /// Specialisation for unsigned int. 00215 ///\ingroup hash 00216 //*************************************************************************** 00217 template<> 00218 struct hash<unsigned int> 00219 { 00220 STATIC_ASSERT(sizeof(size_t) >= sizeof(unsigned int), "size_t smaller than type"); 00221 00222 size_t operator ()(unsigned int v) const 00223 { 00224 return static_cast<size_t>(v); 00225 } 00226 }; 00227 00228 //*************************************************************************** 00229 /// Specialisation for long. 00230 ///\ingroup hash 00231 //*************************************************************************** 00232 template<> 00233 struct hash<long> 00234 { 00235 size_t operator ()(long v) const 00236 { 00237 // If it's the same size as a size_t. 00238 if (sizeof(size_t) >= sizeof(v)) 00239 { 00240 return static_cast<size_t>(v); 00241 } 00242 else 00243 { 00244 uint8_t* p = reinterpret_cast<uint8_t*>(&v); 00245 return __private_hash__::generic_hash<size_t>(p, p + sizeof(v)); 00246 } 00247 } 00248 }; 00249 00250 //*************************************************************************** 00251 /// Specialisation for long long. 00252 ///\ingroup hash 00253 //*************************************************************************** 00254 template<> 00255 struct hash<long long> 00256 { 00257 size_t operator ()(long long v) const 00258 { 00259 // If it's the same size as a size_t. 00260 if (sizeof(size_t) >= sizeof(v)) 00261 { 00262 return static_cast<size_t>(v); 00263 } 00264 else 00265 { 00266 uint8_t* p = reinterpret_cast<uint8_t*>(&v); 00267 return __private_hash__::generic_hash<size_t>(p, p + sizeof(v)); 00268 } 00269 } 00270 }; 00271 00272 //*************************************************************************** 00273 /// Specialisation for unsigned long. 00274 ///\ingroup hash 00275 //*************************************************************************** 00276 template<> 00277 struct hash<unsigned long> 00278 { 00279 size_t operator ()(unsigned long v) const 00280 { 00281 // If it's the same size as a size_t. 00282 if (sizeof(size_t) >= sizeof(v)) 00283 { 00284 return static_cast<size_t>(v); 00285 } 00286 else 00287 { 00288 uint8_t* p = reinterpret_cast<uint8_t*>(&v); 00289 return __private_hash__::generic_hash<size_t>(p, p + sizeof(v)); 00290 } 00291 } 00292 }; 00293 00294 //*************************************************************************** 00295 /// Specialisation for unsigned long long. 00296 ///\ingroup hash 00297 //*************************************************************************** 00298 template<> 00299 struct hash<unsigned long long> 00300 { 00301 size_t operator ()(unsigned long long v) const 00302 { 00303 // If it's the same size as a size_t. 00304 if (sizeof(size_t) >= sizeof(v)) 00305 { 00306 return static_cast<size_t>(v); 00307 } 00308 else 00309 { 00310 uint8_t* p = reinterpret_cast<uint8_t*>(&v); 00311 return __private_hash__::generic_hash<size_t>(p, p + sizeof(v)); 00312 } 00313 } 00314 }; 00315 00316 //*************************************************************************** 00317 /// Specialisation for float. 00318 ///\ingroup hash 00319 //*************************************************************************** 00320 template<> 00321 struct hash<float> 00322 { 00323 size_t operator ()(float v) const 00324 { 00325 // If it's the same size as a size_t. 00326 if (sizeof(size_t) == sizeof(v)) 00327 { 00328 union 00329 { 00330 size_t s; 00331 float v; 00332 } u; 00333 00334 u.v = v; 00335 00336 return u.s; 00337 } 00338 else 00339 { 00340 uint8_t* p = reinterpret_cast<uint8_t*>(&v); 00341 return __private_hash__::generic_hash<size_t>(p, p + sizeof(v)); 00342 } 00343 } 00344 }; 00345 00346 //*************************************************************************** 00347 /// Specialisation for double. 00348 ///\ingroup hash 00349 //*************************************************************************** 00350 template<> 00351 struct hash<double> 00352 { 00353 size_t operator ()(double v) const 00354 { 00355 // If it's the same size as a size_t. 00356 if (sizeof(size_t) == sizeof(v)) 00357 { 00358 union 00359 { 00360 size_t s; 00361 double v; 00362 } u; 00363 00364 u.v = v; 00365 00366 return u.s; 00367 } 00368 else 00369 { 00370 uint8_t* p = reinterpret_cast<uint8_t*>(&v); 00371 return __private_hash__::generic_hash<size_t>(p, p + sizeof(v)); 00372 } 00373 } 00374 }; 00375 00376 //*************************************************************************** 00377 /// Specialisation for long double. 00378 ///\ingroup hash 00379 //*************************************************************************** 00380 template<> 00381 struct hash<long double> 00382 { 00383 size_t operator ()(long double v) const 00384 { 00385 // If it's the same size as a size_t. 00386 if (sizeof(size_t) == sizeof(v)) 00387 { 00388 union 00389 { 00390 size_t s; 00391 long double v; 00392 } u; 00393 00394 u.v = v; 00395 00396 return u.s; 00397 } 00398 else 00399 { 00400 uint8_t* p = reinterpret_cast<uint8_t*>(&v); 00401 return __private_hash__::generic_hash<size_t>(p, p + sizeof(v)); 00402 } 00403 } 00404 }; 00405 00406 //*************************************************************************** 00407 /// Specialisation for pointers. 00408 ///\ingroup hash 00409 //*************************************************************************** 00410 template <typename T> 00411 struct hash<T*> 00412 { 00413 size_t operator ()(const T* v) const 00414 { 00415 // If it's the same size as a size_t. 00416 if (sizeof(size_t) == sizeof(T*)) 00417 { 00418 union 00419 { 00420 size_t s; 00421 const T* v; 00422 } u; 00423 00424 u.v = v; 00425 00426 return u.s; 00427 } 00428 else 00429 { 00430 uint8_t* p = reinterpret_cast<uint8_t*>(&v); 00431 return __private_hash__::generic_hash<size_t>(p, p + sizeof(v)); 00432 } 00433 } 00434 }; 00435 } 00436 00437 #endif 00438
Generated on Tue Jul 12 2022 14:05:41 by
