+Updates a previously computed hash by adding bytes to it. N must be a native
+hash size.
+*/
+template<unsigned N>
+typename HashTraits<N>::ResultType hash_update(typename HashTraits<N>::HashType result, const void *data, std::size_t size)
+{
+ const uint8_t *ptr = static_cast<const uint8_t *>(data);
+ for(unsigned i=0; i<size; ++i)
+ result = hash_round<N>(result, *ptr++);
+ return result;
+}
+
+template<unsigned N>
+typename HashTraits<N>::ResultType hash_update(typename HashTraits<N>::HashType result, const std::string &str)
+{ return hash_update<N>(result, str.data(), str.size()); }
+
+// For some reason this causes an ambiguity error without the enable_if.
+template<unsigned N, typename T>
+typename std::enable_if<!std::is_same<T, std::string>::value, typename HashTraits<N>::ResultType>::type hash_update(typename HashTraits<N>::HashType result, const T &obj)
+{ return hash_update<N>(result, &obj, sizeof(obj)); }
+
+/**
+Manually folds a hash to a smaller size.
+*/
+template<unsigned N, typename T>
+typename std::enable_if<N!=std::numeric_limits<T>::digits, typename HashTraits<N>::ResultType>::type hash_fold(T hash)
+{ return (hash>>N ^ hash) & ((T(1)<<N)-1); }
+
+template<unsigned N, typename T>
+typename std::enable_if<N==std::numeric_limits<T>::digits, typename HashTraits<N>::ResultType>::type hash_fold(T hash)
+{ return hash; }
+
+/**
+Computes an N-bit Fowler-Noll-Vo (FNV-1a) hash. If N is not a native hash
+size, the next larger native hash is computed and XOR-folding is applied to
+the result.
+
+http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
+http://www.isthe.com/chongo/tech/comp/fnv/index.html