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