// Copyright 2018 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Generates random values for testing. Specialized only for the few types we // care about. #ifndef PHMAP_PRIV_HASH_GENERATOR_TESTING_H_ #define PHMAP_PRIV_HASH_GENERATOR_TESTING_H_ #include #include #include #include #include #include #include #include #include #include #if PHMAP_HAVE_STD_STRING_VIEW #include #endif #include "hash_policy_testing.h" namespace phmap { namespace priv { namespace hash_internal { namespace generator_internal { template struct IsMap : std::false_type {}; template struct IsMap> : std::true_type {}; } // namespace generator_internal namespace { class RandomDeviceSeedSeq { public: using result_type = typename std::random_device::result_type; template void generate(Iterator start, Iterator end) { while (start != end) { *start = gen_(); ++start; } } private: std::random_device gen_; }; } // namespace std::mt19937_64* GetSharedRng(); // declaration std::mt19937_64* GetSharedRng() { RandomDeviceSeedSeq seed_seq; static auto* rng = new std::mt19937_64(seed_seq); return rng; } enum Enum { kEnumEmpty, kEnumDeleted, }; enum class EnumClass : uint64_t { kEmpty, kDeleted, }; inline std::ostream& operator<<(std::ostream& o, const EnumClass& ec) { return o << static_cast(ec); } template struct Generator; template struct Generator::value>::type> { T operator()() const { std::uniform_int_distribution dist; return dist(*GetSharedRng()); } }; template <> struct Generator { Enum operator()() const { std::uniform_int_distribution::type> dist; while (true) { auto variate = dist(*GetSharedRng()); if (variate != kEnumEmpty && variate != kEnumDeleted) return static_cast(variate); } } }; template <> struct Generator { EnumClass operator()() const { std::uniform_int_distribution< typename std::underlying_type::type> dist; while (true) { EnumClass variate = static_cast(dist(*GetSharedRng())); if (variate != EnumClass::kEmpty && variate != EnumClass::kDeleted) return static_cast(variate); } } }; template <> struct Generator { std::string operator()() const { // NOLINTNEXTLINE(runtime/int) std::uniform_int_distribution chars(0x20, 0x7E); std::string res; res.resize(32); std::generate(res.begin(), res.end(), [&]() { return (char)chars(*GetSharedRng()); }); return res; } }; #if PHMAP_HAVE_STD_STRING_VIEW template <> struct Generator { std::string_view operator()() const { static auto* arena = new std::deque(); // NOLINTNEXTLINE(runtime/int) std::uniform_int_distribution chars(0x20, 0x7E); arena->emplace_back(); auto& res = arena->back(); res.resize(32); std::generate(res.begin(), res.end(), [&]() { return (char)chars(*GetSharedRng()); }); return res; } }; #endif template <> struct Generator { NonStandardLayout operator()() const { return NonStandardLayout(Generator()()); } }; template struct Generator> { std::pair operator()() const { return std::pair(Generator::type>()(), Generator::type>()()); } }; template struct Generator> { std::tuple operator()() const { return std::tuple(Generator::type>()()...); } }; template struct Generator().key()), decltype(std::declval().value())>> : Generator().key())>::type, typename std::decay().value())>::type>> {}; template using GeneratedType = decltype( std::declval::value, typename Container::value_type, typename Container::key_type>::type>&>()()); } // namespace hash_internal } // namespace priv } // namespace phmap namespace std { using phmap::priv::hash_internal::EnumClass; using phmap::priv::hash_internal::Enum; template<> struct hash { std::size_t operator()(EnumClass const &p) const { return (std::size_t)p; } }; template<> struct hash { std::size_t operator()(Enum const &p) const { return (std::size_t)p; } }; } #endif // PHMAP_PRIV_HASH_GENERATOR_TESTING_H_