Branch data Line data Source code
1 : : #pragma once 2 : : 3 : : #include <concepts> 4 : : #include <cstddef> 5 : : #include <functional> 6 : : 7 : : 8 : : namespace std { 9 : : 10 : : /** Conveniance specialization to provide hasing of `std::vector` by computing a rolling hash over the elements. */ 11 : : template<typename Container> 12 : : requires requires (Container C) { {C.cbegin() < C.cend() } -> std::same_as<bool>; } and 13 : : requires (Container C) { {C.cbegin() == C.cend() } -> std::same_as<bool>; } and 14 : : requires (Container C) { {C.cbegin() != C.cend() } -> std::same_as<bool>; } and 15 : : requires (Container C) { *C.cbegin(); } 16 : : struct hash<Container> 17 : : { 18 : 267 : std::size_t operator()(const Container &C) const { 19 : : using value_type = decltype(*C.cbegin()); 20 : : std::hash<std::decay_t<value_type>> h; 21 : 267 : std::size_t value = 0xcbf29ce484222325UL; 22 : : 23 [ + + ]: 534 : for (const auto &elem : C) { 24 : 267 : value ^= h(elem); 25 : 267 : value *= 0x100000001b3UL; 26 : : } 27 : : 28 : 267 : return value; 29 : : } 30 : : }; 31 : : 32 : : /** Convenience specialization to provide hashing of `std::reference_wrapper` by hashing the referenced object. */ 33 : : template<typename T> 34 : : struct hash<std::reference_wrapper<T>> 35 : : { 36 : 0 : std::size_t operator()(std::reference_wrapper<T> ref) const { 37 : : std::hash<std::decay_t<T>> h; 38 : 0 : return h(ref.get()); 39 : : } 40 : : }; 41 : : 42 : : template<typename T> 43 : 0 : bool operator==(std::reference_wrapper<T> left, std::reference_wrapper<T> right) { return left.get() == right.get(); } 44 : : 45 : : }