Adobe Source Libraries 2.0.0
A collection of C++ libraries.
Loading...
Searching...
No Matches
fnv.hpp
Go to the documentation of this file.
1/*
2 Copyright 2005-2013 Adobe Systems Incorporated
3 Distributed under the Boost Software License - Version 1.0 (see the accompanying file LICENSE
4 or a copy at https://stlab.github.io/adobe_source_libraries/licenses.html)
5*/
6
7/**************************************************************************************************/
8
9#ifndef ADOBE_FNV_HPP
10#define ADOBE_FNV_HPP
11
12/**************************************************************************************************/
13
14#include <cstddef>
15#include <cstdint>
16
17#ifndef ADOBE_FNV_NO_BIGINTS
18#include <boost/multiprecision/cpp_int.hpp>
19#endif
20
22
23/**************************************************************************************************/
79/**************************************************************************************************/
80
81namespace adobe {
82
83/**************************************************************************************************/
84
85namespace detail {
86
87/**************************************************************************************************/
88
89constexpr std::size_t rollup(std::size_t n) {
90 return n == 0 ? 0
91 : n <= 32 ? 32
92 : n <= 64 ? 64
93 : n <= 128 ? 128
94 : n <= 256 ? 256
95 : n <= 512 ? 512
96 : n <= 1024 ? 1024
97 : 0;
98}
99
100/**************************************************************************************************/
101
102template <std::size_t Bits>
103struct fnv_base_traits {};
104
105/**************************************************************************************************/
106
107template <>
108struct fnv_base_traits<32> {
109 typedef std::uint32_t value_type;
110
111 static constexpr std::size_t size() { return 32; }
112
113 static constexpr value_type offset_basis() { return 0x811c9dc5; }
114
115 static constexpr value_type prime() { return 0x1000193; }
116};
117
118/**************************************************************************************************/
119
120template <>
121struct fnv_base_traits<64> {
122 typedef std::uint64_t value_type;
123
124 static constexpr std::size_t size() { return 64; }
125
126 static constexpr value_type offset_basis() { return 0xcbf29ce484222325; }
127
128 static constexpr value_type prime() { return 0x100000001b3; }
129};
130
131/**************************************************************************************************/
132#ifndef ADOBE_FNV_NO_BIGINTS
133using namespace boost::multiprecision::literals;
134
135/**************************************************************************************************/
136
137template <>
138struct fnv_base_traits<128> {
139 typedef boost::multiprecision::uint128_t value_type;
140
141 static constexpr std::size_t size() { return 128; }
142
143 static constexpr value_type offset_basis() {
144 return 0x6C62272E07BB014262B821756295C58D_cppui128;
145 }
146
147 static constexpr value_type prime() { return 0x1000000000000000000013B_cppui128; }
148};
149
150/**************************************************************************************************/
151
152template <>
153struct fnv_base_traits<256> {
154 typedef boost::multiprecision::uint256_t value_type;
155
156 static constexpr std::size_t size() { return 256; }
157
158 static constexpr value_type offset_basis() {
159 return 0xDD268DBCAAC550362D98C384C4E576CCC8B1536847B6BBB31023B4C8CAEE0535_cppui256;
160 }
161
162 static constexpr value_type prime() {
163 return 0x1000000000000000000000000000000000000000163_cppui256;
164 }
165};
166
167/**************************************************************************************************/
168
169template <>
170struct fnv_base_traits<512> {
171 typedef boost::multiprecision::uint512_t value_type;
172
173 static constexpr std::size_t size() { return 512; }
174
175 static constexpr value_type offset_basis() {
176 return 0xB86DB0B1171F4416DCA1E50F309990ACAC87D059C90000000000000000000D21E948F68A34C192F62EA79BC942DBE7CE182036415F56E34BAC982AAC4AFE9FD9_cppui512;
177 }
178
179 static constexpr value_type prime() {
180 return 0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000157_cppui512;
181 }
182};
183
184/**************************************************************************************************/
185
186template <>
187struct fnv_base_traits<1024> {
188 typedef boost::multiprecision::uint1024_t value_type;
189
190 static constexpr std::size_t size() { return 1024; }
191
192 static constexpr value_type offset_basis() {
193 return 0x5F7A76758ECC4D32E56D5A591028B74B29FC4223FDADA16C3BF34EDA3674DA9A21D9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C6D7EB6E73802734510A555F256CC005AE556BDE8CC9C6A93B21AFF4B16C71EE90B3_cppui1024;
194 }
195
196 static constexpr value_type prime() {
197 return 0x10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018D_cppui1024;
198 }
199};
200#endif
201/**************************************************************************************************/
202
203template <std::size_t FromBits, std::size_t ToBits>
204struct bitmask {
205 template <typename T>
206 inline static T mask(T value) {
207 return value & ((T(1) << ToBits) - 1);
208 }
209};
210
211template <std::size_t SameBits>
212struct bitmask<SameBits, SameBits> {
213 template <typename T>
214 inline static T mask(T value) {
215 return value;
216 }
217};
218
219/**************************************************************************************************/
220
221} // namespace detail
222
223/**************************************************************************************************/
234template <std::size_t Bits>
235using fnv_traits = typename detail::fnv_base_traits<detail::rollup(Bits)>;
236
244template <std::size_t Bits>
246
247/**************************************************************************************************/
257template <std::size_t Bits, typename Iterator, typename Predicate>
258fnvtype<Bits> fnv1a(Iterator first, Predicate p) {
259 static_assert(sizeof(typename std::iterator_traits<Iterator>::value_type) == 1,
260 "Iterator value_type must be 1 byte.");
261
262 typedef fnvtype<Bits> result_type;
263
264 result_type result(fnv_traits<Bits>::offset_basis());
265
266 while (!p(*first))
267 result = (result ^ static_cast<result_type>(*first++)) * fnv_traits<Bits>::prime();
268
269 return detail::bitmask<fnv_traits<Bits>::size(), Bits>::mask(result);
270}
271
272/**************************************************************************************************/
281template <std::size_t Bits, typename Iterator>
282inline fnvtype<Bits> fnv1a(Iterator first, Iterator last) {
283 static_assert(sizeof(typename std::iterator_traits<Iterator>::value_type) == 1,
284 "Iterator value_type must be 1 byte.");
285
286 typedef fnvtype<Bits> result_type;
287
288 result_type result(fnv_traits<Bits>::offset_basis());
289
290 while (first != last)
291 result = (result ^ static_cast<result_type>(*first++)) * fnv_traits<Bits>::prime();
292
293 return detail::bitmask<fnv_traits<Bits>::size(), Bits>::mask(result);
294}
295
296/**************************************************************************************************/
302template <std::size_t Bits, typename Container>
303inline fnvtype<Bits> fnv1a(Container c) {
304 return fnv1a<Bits>(begin(c), end(c));
305}
306
307/**************************************************************************************************/
308
309} // namespace adobe
310
311/**************************************************************************************************/
312
313#endif
314
315/**************************************************************************************************/
fnvtype< Bits > fnv1a(Iterator first, Predicate p)
Definition fnv.hpp:258
typename fnv_traits< Bits >::value_type fnvtype
Definition fnv.hpp:245
typename detail::fnv_base_traits< detail::rollup(Bits)> fnv_traits
Definition fnv.hpp:235
boost::range_size< Selection >::type size(const Selection &x)