hash/table: add a trivial table lookup 'hash'

This commit is contained in:
Danny Robson 2019-04-22 09:51:04 +10:00
parent 0683f80903
commit 81715c1602
4 changed files with 378 additions and 0 deletions

View File

@ -349,6 +349,8 @@ list (
hash/murmur/murmur3.hpp hash/murmur/murmur3.hpp
hash/siphash.cpp hash/siphash.cpp
hash/siphash.hpp hash/siphash.hpp
hash/table.cpp
hash/table.hpp
hash/wang.hpp hash/wang.hpp
hash/xxhash.cpp hash/xxhash.cpp
hash/xxhash.hpp hash/xxhash.hpp
@ -599,6 +601,7 @@ if (TESTS)
hash/fnv1a hash/fnv1a
hash/murmur hash/murmur
hash/siphash hash/siphash
hash/table
hash/xxhash hash/xxhash
hton hton
io io

262
hash/table.cpp Normal file
View File

@ -0,0 +1,262 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
*/
#include "table.hpp"
#include "../std.hpp"
#include <array>
using cruft::hash::table;
///////////////////////////////////////////////////////////////////////////////
namespace {
// Declare a trivial mapping up front which we can specialise for each type
// in the following sections.
template <typename SrcT, typename DstT>
struct mapping {
static constexpr std::size_t size = 1u << (sizeof (SrcT) * 8);
static const std::array<DstT,size> value;
};
}
//-----------------------------------------------------------------------------
template <>
const std::array<u08,256>
mapping<u08,u08>::value {
0x6c, 0xe5, 0x77, 0x5f, 0x58, 0xbc, 0x3f, 0x3d,
0xdc, 0x54, 0xc5, 0x52, 0x1f, 0xce, 0x60, 0x04,
0x03, 0x33, 0xd1, 0xc6, 0xfb, 0x1a, 0x95, 0xee,
0xa4, 0x57, 0x27, 0x0a, 0x2a, 0x5e, 0xa1, 0x69,
0x38, 0x84, 0x2b, 0x95, 0x31, 0x69, 0x86, 0x55,
0xf7, 0x93, 0x64, 0xd3, 0x4c, 0xac, 0xb0, 0xec,
0x4b, 0x99, 0x3e, 0xb3, 0x44, 0x47, 0x22, 0x24,
0xb9, 0x32, 0xa9, 0x7a, 0xd5, 0x94, 0x66, 0xa4,
0x68, 0xd9, 0x84, 0x04, 0xec, 0x40, 0x2e, 0x0b,
0xf7, 0xe6, 0x90, 0x15, 0x31, 0xf9, 0xab, 0x63,
0x58, 0xb0, 0x97, 0x1f, 0xd9, 0x42, 0x06, 0x45,
0x91, 0xd9, 0x39, 0xda, 0x43, 0xe3, 0x5c, 0x9b,
0x9e, 0xa9, 0x68, 0x61, 0xfb, 0xa7, 0x3d, 0xaa,
0xff, 0xef, 0x33, 0x59, 0xeb, 0x9e, 0xbe, 0xd5,
0x28, 0xc5, 0xe1, 0x01, 0x62, 0x80, 0xfd, 0xc0,
0xf5, 0x1d, 0x4a, 0xdc, 0x8a, 0x45, 0xf5, 0xab,
0x33, 0x4e, 0x49, 0x66, 0xb7, 0x28, 0x22, 0xb8,
0x52, 0x5b, 0x54, 0x84, 0x37, 0x93, 0x44, 0xcc,
0xef, 0xb2, 0xb2, 0x1c, 0x53, 0x5e, 0xf3, 0xc1,
0x5c, 0xa2, 0x52, 0x9b, 0xc6, 0xb4, 0x2b, 0x47,
0x25, 0x06, 0x5e, 0x62, 0x27, 0x6c, 0xc3, 0x3f,
0xb0, 0x4d, 0x1e, 0x3b, 0x3b, 0x22, 0xfc, 0x0c,
0x6c, 0xc6, 0xab, 0x93, 0x19, 0xe6, 0xc4, 0xb2,
0xba, 0x9e, 0xdb, 0x8a, 0x02, 0xf5, 0x4c, 0xc0,
0x9f, 0xab, 0x3f, 0x72, 0x00, 0x8d, 0xd7, 0xee,
0x7a, 0x09, 0x1f, 0xf4, 0x05, 0xc1, 0x0c, 0x7d,
0x4d, 0xa5, 0x6f, 0x84, 0xfd, 0x98, 0x1d, 0x86,
0x56, 0x76, 0xaf, 0xb6, 0xa2, 0x52, 0x31, 0xba,
0xef, 0x2d, 0x8c, 0xd5, 0xe9, 0x4e, 0xd9, 0xf8,
0xa3, 0x7a, 0x22, 0xab, 0x03, 0x58, 0xbf, 0xf1,
0x6c, 0x20, 0xf1, 0x7d, 0x30, 0x48, 0xc1, 0xdf,
0x45, 0x89, 0x9b, 0x92, 0x38, 0x8a, 0x74, 0xc8,
};
//-----------------------------------------------------------------------------
template <>
const std::array<u16,256>
mapping<u08,u16>::value {
0xa69d, 0x7df3, 0x0ec5, 0xe648, 0x0102, 0x9d13, 0x7439, 0x7b70,
0x74a3, 0x3939, 0xb6f7, 0x3493, 0xc26b, 0x8115, 0xc894, 0xc986,
0xa929, 0xcbb9, 0x43b6, 0x6e56, 0x9097, 0x09cb, 0xd785, 0x1307,
0x3131, 0x9d65, 0x21ca, 0xbde8, 0x2260, 0x377f, 0xe20c, 0xea40,
0xd223, 0x36df, 0xc7b2, 0xe5dc, 0x22d8, 0xe315, 0x09f4, 0x0f37,
0x1e4f, 0xbb99, 0x1b8f, 0x5b0f, 0x54a2, 0xebff, 0xa745, 0xae6f,
0x6031, 0x44a6, 0x1a62, 0xe33f, 0x3508, 0xc0ac, 0x0248, 0x8712,
0xb490, 0x8ab6, 0x7095, 0xdcdd, 0x68e7, 0x9e66, 0x188c, 0xd4ca,
0x08e2, 0xd017, 0x3f06, 0x6f1c, 0x3166, 0x162c, 0x776e, 0x196b,
0xa6e1, 0xdbef, 0x1bef, 0xc3fd, 0x6d3b, 0x4852, 0xf7a4, 0x2691,
0x3f50, 0x2383, 0x2746, 0xa03f, 0x8e92, 0x79ee, 0xeab9, 0x65c9,
0xca3a, 0xe0ea, 0x9459, 0xc909, 0x9d82, 0xb469, 0xbe2d, 0xe5a1,
0xda59, 0x19ec, 0x4126, 0x1bdc, 0x1676, 0x2a3a, 0xfa2a, 0xbb57,
0xead1, 0x4bea, 0x4b54, 0x415a, 0xa69a, 0x8077, 0x81dd, 0xd4a0,
0xf572, 0x71bb, 0xb4a8, 0x35a1, 0x975e, 0x9adc, 0xf2ad, 0xfedd,
0xf0e1, 0xe023, 0x142a, 0x6c58, 0x519d, 0xf8d4, 0x9f21, 0x45d7,
0xfc7e, 0x8966, 0x0f09, 0x79c0, 0x6939, 0x8f41, 0x8703, 0x2ba4,
0xc4dd, 0xa4ee, 0x21cf, 0x4079, 0x8bac, 0xdc55, 0x3e71, 0x8e2b,
0x117e, 0x3c1b, 0x3c76, 0xb7fb, 0x7cf0, 0xe720, 0x5b86, 0x6a02,
0xbc8c, 0x095c, 0x3412, 0xb049, 0xb64e, 0x11a0, 0x2fe6, 0x1866,
0x700f, 0xdd06, 0xef71, 0x42c8, 0xb75a, 0x01df, 0x9997, 0x9e9a,
0x7a89, 0xa92a, 0x3cbc, 0xa06b, 0x1314, 0xa069, 0xce75, 0x71e4,
0xc285, 0x5ae8, 0xe550, 0x9c30, 0xef47, 0x8b99, 0xfc1e, 0x81ef,
0xc59d, 0xcab6, 0x4859, 0xd645, 0x169f, 0xf1b1, 0x0195, 0xbd71,
0xd631, 0xbece, 0x635f, 0x0fc2, 0x4f5f, 0x7cf0, 0x7a79, 0x7b2e,
0x2ff2, 0x5830, 0x2f89, 0x301c, 0xd215, 0xbe67, 0x862a, 0x455d,
0x27d3, 0xae8d, 0xc697, 0xa01a, 0x905d, 0x3458, 0x4c55, 0x5402,
0x6c18, 0xd9e5, 0x07a3, 0xef84, 0x10c4, 0x1320, 0xa820, 0x55bf,
0x1aaa, 0xb8b7, 0x5fbf, 0xd183, 0xcdd7, 0xdc99, 0xe003, 0x8fff,
0x66cc, 0xcbf8, 0xb5e4, 0x5de2, 0x6988, 0xbee4, 0xf315, 0xf3c6,
0x533e, 0xc54e, 0x28ae, 0x0a08, 0x5ff7, 0x6f9b, 0x4f60, 0x14a1,
0x6798, 0xd066, 0x872b, 0xdc9c, 0x63e3, 0x6d60, 0x66fa, 0x4876,
};
//-----------------------------------------------------------------------------
template <>
const std::array<u32,256>
mapping<u08,u32>::value {
0x19a6d112, 0xbe09745f, 0x546645ba, 0x8bf79105,
0xa73d9e4f, 0xf713dc9a, 0x0c102027, 0x1647eb7c,
0x77cbec63, 0x052d4897, 0xab0c7abd, 0x4f834c9e,
0xb8bfb259, 0x93862d41, 0x9297a028, 0xc543a8be,
0x6e7ed566, 0x76d83ea4, 0xbfd059ea, 0x628c6fe8,
0x5962e774, 0xca240819, 0x06b959c6, 0x1a84da34,
0x3016e212, 0x08e2710b, 0x086eef4d, 0x381207c4,
0xd0f1fbde, 0x18969bc7, 0xb7869b96, 0x6f420064,
0xfbb62317, 0x34cb71ae, 0x562854c9, 0x86157987,
0x11696968, 0x322997cc, 0x07d54ca4, 0x18017062,
0x07dc8022, 0xfdb94a1e, 0x6fd4bb6d, 0xa74e93cd,
0xdbd0e7af, 0x9d5e3f2d, 0x7acc14a6, 0x212ef652,
0x6036ec83, 0x2fb2e951, 0x7c983b42, 0xef1d0b30,
0x7a5d9ebe, 0x3f8b23d7, 0x709f0f02, 0xbad5d162,
0x7c5c0b0a, 0x6e208bcd, 0xa3dfb5ad, 0xe4b42cb1,
0xfb1a3b5d, 0x4f683197, 0x0d3918ef, 0x1d4ada76,
0x3e2d4f7a, 0x4eb0e7a8, 0x4b2df385, 0xc10eb437,
0xba9dd5a1, 0x74e75c10, 0x5c64fd2a, 0x6e4ca755,
0xcea9e7d5, 0xcde0d0cd, 0x2e733ee4, 0x1e6826e9,
0xd3dbf5a8, 0x8ffc0336, 0xfc998b32, 0x888819a3,
0x43e8335e, 0xe872386a, 0xe8f48a1c, 0xe9b17b5d,
0x42f3fe7d, 0x2170b556, 0x33a36e33, 0x6906dea4,
0xa8fd2048, 0xb2f1bf4e, 0x92121f21, 0x59b6d93e,
0x54e2f4a8, 0x05d5e576, 0xf2cb20c0, 0xc738cc9a,
0x50754392, 0x3a88a0cc, 0x1cd98db5, 0x6fe291cf,
0xa7beaadb, 0xc986c767, 0xe8c2ad0f, 0x81781ae9,
0xac1301e9, 0x41450e81, 0x3a53dee3, 0x553ccbf6,
0x252bb696, 0x603508bf, 0x23b845d1, 0x9395069d,
0xc46754a9, 0x37f417d0, 0xadcb5a89, 0xe2bfb29f,
0xb9149ca5, 0xb191955b, 0xa498067c, 0xdacb1668,
0x8dbf0066, 0x1262f4fe, 0x49e54020, 0x833fec83,
0x043838d1, 0xc2440f26, 0x6a78e25d, 0x904db85f,
0xbb657557, 0x82bfffb6, 0xc45c4829, 0x522986d9,
0x9f9b9c32, 0x46318331, 0x4821edfb, 0x0415ccb6,
0x40b6eea0, 0x519ca6f8, 0xcc2aaad8, 0x05ed01e9,
0x8901fe5d, 0x9cb37e6b, 0x87c4d537, 0x988e3583,
0xdf6aa13b, 0x9d5d0c98, 0xb1eaa968, 0xb127caa4,
0x82e1573b, 0x115d4898, 0x4c94b901, 0x4e82a878,
0x3da34f30, 0xf662b20b, 0x2d4e3502, 0x89b39e1a,
0xa51bd71d, 0x5697670a, 0x8780fcf8, 0xc9cb263f,
0xd99eadfe, 0xbfbd6e5a, 0x9efc16f0, 0xfcd7d20d,
0x85d67f5d, 0x77656995, 0xd76658a1, 0xe1d7d47e,
0x68137b3f, 0x78ceb394, 0x7a4981c1, 0x937a7697,
0x75033abc, 0x1f07c27f, 0x53435805, 0xa0cedf5f,
0x5a1809d4, 0xe5730168, 0x6fc76ce8, 0xe7e9c462,
0xfe4518d0, 0x5f25ab7c, 0x89638f84, 0xb93e273e,
0x72d6f60a, 0x79eee1e7, 0xf04425e1, 0x2bdd4f4a,
0x3b6c4311, 0x852a4df7, 0x1d223753, 0x91306d4b,
0x246b51f8, 0x946c9571, 0x0bf52999, 0xd1e3a894,
0x9e8355c5, 0xeeecc63f, 0x730ee978, 0x2359e488,
0xbfb31640, 0x7a8a42e2, 0xc30a61de, 0x70b6d56d,
0x1482a13c, 0x5b55d382, 0x9f69b2d5, 0x85e71dd7,
0xc242a669, 0xb0b72506, 0xfd17fea5, 0xfa57d68b,
0x608ad2b2, 0xb5bf59c4, 0x32d333b1, 0xe361d090,
0x8da1e82a, 0x2faa2829, 0xc8be66b4, 0xd48712f0,
0x360e08ac, 0x803dc62a, 0x21110547, 0xeb58a1ab,
0x36ace913, 0x0795beca, 0x69f9e64e, 0xdc54c84e,
0xa5f856dd, 0x4432b0ef, 0xfe6ac60d, 0x764013d0,
0xcccf5b91, 0xa0b52069, 0x65293eee, 0xd42c0da5,
0x38b95641, 0x21acfb4b, 0xef0b72bf, 0xfef160f4,
0x27690333, 0x425eec16, 0x04e41f07, 0xda2c4d13,
0x9802fa71, 0x819d1992, 0xf47bf356, 0xec5bc2c3,
0x6556210f, 0x0bc9aee1, 0x626e1068, 0xef718d43,
0xfe925d8c, 0xd64e3685, 0x10d818f7, 0x5b49bb72,
};
//-----------------------------------------------------------------------------
template <>
const std::array<u64,256>
mapping<u08,u64>::value {
0x48fa7695f8bffc1f, 0x7e15f803ca2e9ee5, 0xa385755546846c49, 0xe04df75fd1fde754,
0xf85a7e610f19a019, 0x9fa9d6ac099a6332, 0x6204ca1e06d75edf, 0x4fc4d3066312a04d,
0x209ad56140d6dcfc, 0x8cd0d058ce0a2c97, 0x897d3ce28ddea6a7, 0xc7811f3207259dd7,
0x086d127cd0e60d2e, 0x4c1e378f67871dd8, 0xdc8050fc6662350e, 0x376e0819bc2ac82a,
0x0168434875dc2684, 0xf3ba8e0970ed8ee3, 0x9a18995b9f88a954, 0x2f4fe572072262ca,
0xfca13a2f849bd6ad, 0xbf9169b9a6d3cc7a, 0x10c584a81a9bf9a1, 0x2eed879acae98f39,
0x6fe2b2bcec271026, 0x949800dcf417dfc5, 0xf04f75f8c129ec8c, 0x22d63de93b49c19d,
0x5a4b8f465780f89c, 0x2ac81c66981bb6a3, 0xdba147ffd84b317e, 0x958267c4cbc5459e,
0x2134d6f74a75f1ea, 0x5c2d0936006ed5db, 0x639c6c5e531563d3, 0x32560bddb5edffa1,
0x67d35c751580087e, 0xa4283ced0e4267a6, 0x0267ac8005740014, 0x6b9bf3d7f887786b,
0xab889df9c67c5020, 0x6a7e97cf14222e12, 0xd0b36f4219419336, 0x92f174320b72c3b0,
0x8334f88a1097919f, 0x5b38eb76191edc39, 0xf6a6692f0effdde2, 0x0c45aab785f006dc,
0x56850cfce9895ce2, 0x7473ed186851afdb, 0x8c3e222c99ab6091, 0x64362b7b1ea429e1,
0xbbc2d9c88fa67cda, 0x8faf127175e14028, 0xf5aa8c645f29f65c, 0xe79c2736405d171a,
0x0428ebf4bbb70a7d, 0xfc91f75e36f51477, 0x250d2932c06eae5d, 0x249628a87a682ca7,
0xda034ca8935c0531, 0x1efc3420e2407f16, 0x183938b4ee4e3935, 0x4a7a3a4c67106f8d,
0x14f4b95607f7bd53, 0xd41fb8dab49e7186, 0xbdfc07597b842f51, 0x6ac12831d5b17a98,
0xb396ea299af9a877, 0x6ee0fa3ca47092b6, 0x83563047b9308d43, 0xd6954718afd5821c,
0x7f39e22184856e54, 0x8cd58e2bbb95571c, 0x853a8e64501133f9, 0xd9e004a2236f9536,
0x3015f7240679c0b2, 0xed2c47906243bdf7, 0x6f66c8da6aa4f0d8, 0x7203217b5e3b0418,
0xf0d7221f29dacc98, 0xa758db877c787ad3, 0x5e00c7bceeba0297, 0x21e67d73c17fd3b6,
0x634f391ca12e0af2, 0x56a8b12e34eeaa8d, 0x41d987f545501e59, 0x180d37631a15665c,
0x35910699ede3eae0, 0x5ecc3e63630481ea, 0x17c4b84fc92a8b48, 0x5d5e58c8008dcf00,
0xde45e0982c1c707d, 0x8eefdbf3155d6def, 0xea53eab2d97e7ff8, 0x4d2cb2c7eb40bee7,
0xf86770f8ff01652e, 0xe3bba2eb7143c327, 0x32bbd721e0d65820, 0x36e177cecae8e53a,
0xe4ea59087ac44e61, 0xc464805600bb7aa6, 0xce1e882bacae9690, 0xb668d4a40dbd3d16,
0x2b51c2af28b64b8f, 0x332bd68111c32663, 0x35ca694e328aa12c, 0x52c57dffd572072d,
0x450ee4be31125e67, 0xa1ce9b99066e279d, 0xe7a9cadc1c7cf7c0, 0xd59ed8491b982202,
0xb2c1a6d6ec246b7c, 0xe3e2929560a25c7f, 0x83792c9d28edf47d, 0xdfd406f8dbe3880b,
0xf7dfeec860912d45, 0xe6b9d5220d925fbb, 0x5a0ad5674fba8fc0, 0x6e19bf5f99acf45a,
0x7564758871b991ef, 0x2d3b3eb373ecc318, 0x0751b4f9bf3c0779, 0xb9ce83213669cefb,
0x4d7530df405b91a5, 0x26eb04560c6459ce, 0xedb611a12b7e76aa, 0xebcd1e83e89eae7f,
0xbcf9092b123929f5, 0x6b6bc2bd8e79b803, 0x65494e6e8e247728, 0x9e4d1bef8696d11c,
0xf9af0a18c65960ee, 0x2ab76d25d7509a8c, 0x6cc6a4bfe6f750f6, 0x2728853fdd27b17c,
0x80e8d5ee1649e2b6, 0x8e90dc21b076a840, 0x8e7557630baf0eec, 0xfbd6271796357b23,
0xcf1788a82a5d4be8, 0x2934f2733b8f6a76, 0x8da6c6d3dbb693a5, 0xf95228c70b428fc5,
0x808f892ff9ded557, 0x3a9048d371e9cbb7, 0xb1e74e046e83227c, 0xda7b34be72639547,
0x0674a89371f5cfbe, 0x09bf4d0abe9921dd, 0x2853c78d673fda9c, 0x358b8d7591d3a44c,
0xb978d274f183fdc3, 0xdc1fe91508607d1d, 0x878961e2802d75cb, 0x758ed969dbc92e83,
0xb097b06c06aca941, 0x54bdda38450793c6, 0xf312554b2f42397c, 0xa5e3e30f7683a08e,
0x11b0c4e5c4458a03, 0x85f9c0c5fc74b00d, 0x4d728b901516b426, 0x55f6ee84d3fa9d23,
0x8d45bedde7c5efb6, 0x5767130b2a1a10a8, 0x9823934b79942f02, 0x4763be7da390182f,
0x6d37058cda97d694, 0x9900f88d22b1cad3, 0x517948dedc6d238a, 0xc9510628cc2c713e,
0x017ad5c17a19cfe8, 0x43c671d0395bb38c, 0x5c34fde2e7e32781, 0x70fc7635505183a0,
0x8f3c064bf3ef5793, 0xfe486dde380e9960, 0x420617c2d7c4eaa9, 0x8a0778a5da46e739,
0x77c17335a01c3bef, 0x5823b3def4bd9a7a, 0x5b8c8894fec93862, 0x59447bb35f131a97,
0xe57b028027acf794, 0xf12169deac287129, 0x04ba5452277285db, 0xd85227b664e60271,
0x8d343169577a6e15, 0x1dbd0c09c681c123, 0x12a3135379d5f3dc, 0xaeff36ce55259067,
0xf5b285e250a07d0c, 0x8ff0ef90b71fa5c4, 0x1cbf1fb651b35209, 0x1893c724846900f2,
0x75e34f3f73ebe24f, 0x3a712608aa1eaf09, 0x7314ae1b21d7ae1d, 0x7ff05f52f15c80d1,
0x1890914b9b8958a1, 0x358452e5fcf6f00a, 0x8535bf35952d56ec, 0xc881f437cf623296,
0xa8721442499c10fa, 0x134e05243dd8897a, 0xbf1c9d965063f63e, 0xeb8c3357c99f7335,
0xfaf46d2f06056a60, 0xe49a6ba88fa59ffb, 0xa6effb9388ab81b7, 0x27e4d9604bf4dc5f,
0x2f544d91ef41bd1a, 0xb26b78180ebe4b89, 0xdc003a4578e29411, 0x18cf7aecb08e4820,
0xe43694d0b8e0a1d5, 0x52d9b382b96d036f, 0xa18a779fadea3bb5, 0xc19d65c469c72520,
0xc70982bdd36757c6, 0x0a63b14adc78b344, 0x00a2ad3fec425073, 0xe85c9053be5b0f91,
0x4bc842cab9b5c468, 0x167b97eabd0eefdc, 0x78d6996fbe0a5eda, 0x1b6b6981453c8268,
0xf84b95d5b2f7f9bd, 0x322e64d8dd1cb289, 0x66a6f74ea2f25c21, 0xcefd830f87ab4b2c,
0xb4421bf1d5df3845, 0xa98e2b8a6fb915a7, 0x9d0b06a0a48c4d56, 0x1da26385347a5483,
0xd230e0baa011d3c3, 0x992f20d2b879d0f2, 0x629de3f4b2208ad5, 0x834bf844e300dc6a,
0xbadbfe2057de2913, 0x0d376924fe13d0e3, 0xc173c9b1e7de1447, 0xd3784f179bd3ee1c,
0xb87585f73aafde61, 0x778dc8c75140e57a, 0xf06f3e698e0a2f4b, 0xc88fa1507f3f6993,
0xe3134a26ccd165c5, 0x00b9fd6b2d0e2448, 0xb52ede16b5c81901, 0x9a444cf20fc247e8,
0x8006098737207aca, 0x136bbb29b2193413, 0x4f34f009ecc412e9, 0x3a9a8a910772dde2,
};
///////////////////////////////////////////////////////////////////////////////
template <typename ResultT, typename WordT>
ResultT table<ResultT,WordT>::operator() (WordT const idx) const noexcept
{
return mapping<WordT,ResultT>::value[idx];
}
///////////////////////////////////////////////////////////////////////////////
template class cruft::hash::table<u08, u08>;
template class cruft::hash::table<u16, u08>;
template class cruft::hash::table<u32, u08>;
template class cruft::hash::table<u64, u08>;

32
hash/table.hpp Normal file
View File

@ -0,0 +1,32 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
*/
#pragma once
#include "../std.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace cruft::hash {
/// Provide a trivial static mapping from a ValueT to a ResultT.
///
/// We guarantee that all outputs are:
/// * unique
/// * are unbiased at every bit offset
///
/// Specialisations are provided for u08, u16, u32, and u64 outputs with
/// u08 inputs. If further flexibility is required we can move the
/// implementation into the header.
///
/// \tparam ResultT The output of the 'hash' function.
/// \tparam WordT The input to the 'hash' function.
template <typename ResultT, typename WordT = u08>
class table {
public:
ResultT operator() (WordT const) const noexcept;
};
}

81
test/hash/table.cpp Normal file
View File

@ -0,0 +1,81 @@
#include "hash/table.hpp"
#include "tap.hpp"
#include "introspection.hpp"
///////////////////////////////////////////////////////////////////////////////
/// Exhaustively test the table hash output for:
/// * uniqueness
/// * equal counts of bit values at each bit offset
template <typename ValueT>
void test_type (cruft::TAP::logger &tap)
{
// Exhaustively list the hash outputs for u08. The result is sorted
// because it simplifies upcoming tests and we don't care about mapping it
// back to the original values.
std::vector<ValueT> results;
std::iota (
std::begin (results),
std::end (results),
0
);
std::transform (
std::begin (results),
std::end (results),
std::begin (results),
cruft::hash::table<ValueT> {}
);
std::sort (std::begin (results), std::end (results));
// Ensure all values are unique.
{
auto const pos = std::adjacent_find (std::begin (results), std::end (results));
tap.expect (
pos == std::end (results),
"no equal elements, %!",
cruft::type_name<ValueT> ()
);
}
// Ensure that at each bit offset we have equal numbers of high and low
// values across the table results.
{
bool success = true;
std::vector<int> bits;
for (std::size_t i = 0; i < sizeof (ValueT) * 8; ++i) {
bits.clear ();
for (auto const v: results)
bits.push_back ((v >> i) & 0x1);
auto const zeros = std::count (std::begin (bits), std::end (bits), 0);
auto const ones = std::count (std::begin (bits), std::end (bits), 1);
if (zeros != ones) {
success = false;
break;
}
}
tap.expect (
success,
"equal counts at bit positions, %!",
cruft::type_name<ValueT> ()
);
}
}
///////////////////////////////////////////////////////////////////////////////
int main ()
{
cruft::TAP::logger tap;
test_type<u08> (tap);
test_type<u16> (tap);
test_type<u32> (tap);
test_type<u64> (tap);
return tap.status ();
}