/* OctaSTD extensions for std::unordered_map. * * This file is part of OctaSTD. See COPYING.md for futher information. */ #ifndef OSTD_UNORDERED_MAP_HH #define OSTD_UNORDERED_MAP_HH #include #include #include "ostd/range.hh" namespace ostd { template struct ranged_traits> { using Range = IteratorRange< typename std::unordered_map::iterator >; static Range iter(std::unordered_map &v) { return Range{v.begin(), v.end()}; } }; template struct ranged_traits const> { using Range = IteratorRange< typename std::unordered_map::const_iterator >; static Range iter(std::unordered_map const &v) { return Range{v.cbegin(), v.cend()}; } }; template< typename K, typename T, typename H = std::hash, typename E = std::equal_to, typename A = std::allocator>, typename R > inline std::unordered_map make_unordered_map( R range, size_t bcount = 1, H const &hash = H{}, E const &kequal = E{}, A const &alloc = A{} ) { std::unordered_map ret{bcount, hash, kequal, alloc}; using C = RangeCategory; if constexpr(std::is_convertible_v) { /* at least try to preallocate here... */ ret.reserve(range.size()); } for (; !range.empty(); range.pop_front()) { ret.emplace(range.front()); } return ret; } template< typename R, typename H = std::hash::first_type>, typename E = std::equal_to::first_type>, typename A = std::allocator::first_type, typename RangeValue::second_type >> > inline std::unordered_map< typename RangeValue::first_type, typename RangeValue::second_type, H, E, A > make_unordered_map( R &&range, size_t bcount = 1, H const &hash = H{}, E const &kequal = E{}, A const &alloc = A{} ) { return make_unordered_map< typename RangeValue::first_type, typename RangeValue::second_type, H, E, A >(std::forward(range), bcount, hash, kequal, alloc); } } /* namespace ostd */ #endif