On Thu, 20 Mar 2025 at 11:18, Tomasz Kamiński <tkami...@redhat.com> wrote: > > libstdc++-v3/ChangeLog: > > * include/debug/unordered_map (unordered_map): Add from_range > constructors and deduction guides. > (unordered_multimap): Likewise. > * include/debug/unordered_set (unordered_set): Add from_range > constructors and deduction guides. > (unordered_multiset): Likewise. > --- > As noticed by Jonathan, new ctors and deduction guides where not > added to debug versions > > Testing on x86_64-linux, unordered_* test passed with -D_GLIBCXX_DEBUG. > OK for trunk?
OK, thanks for the quick fix. > libstdc++-v3/include/debug/unordered_map | 141 +++++++++++++++++++++++ > libstdc++-v3/include/debug/unordered_set | 131 +++++++++++++++++++++ > 2 files changed, 272 insertions(+) > > diff --git a/libstdc++-v3/include/debug/unordered_map > b/libstdc++-v3/include/debug/unordered_map > index eb9590ac8e7..16d4a4a98e0 100644 > --- a/libstdc++-v3/include/debug/unordered_map > +++ b/libstdc++-v3/include/debug/unordered_map > @@ -201,6 +201,34 @@ namespace __debug > : unordered_map(__l, __n, __hf, key_equal(), __a) > { } > > +#if __glibcxx_ranges_to_container // C++ >= 23 > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_map(from_range_t, _Rg&& __rg, > + size_type __n = 0, > + const hasher& __hf = hasher(), > + const key_equal& __eql = key_equal(), > + const allocator_type& __a = allocator_type()) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __eql, __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_map(from_range_t, _Rg&& __rg, const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_map(from_range_t, _Rg&& __rg, size_type __n, > + const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_map(from_range_t, _Rg&& __rg, size_type __n, > + const hasher& __hf, const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __a) > + { } > +#endif > + > ~unordered_map() = default; > > unordered_map& > @@ -841,6 +869,47 @@ namespace __debug > _Hash, _Allocator) > -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; > > +#if __glibcxx_ranges_to_container // C++ >= 23 > + template<ranges::input_range _Rg, > + __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>, > + __not_allocator_like _Pred = > equal_to<__detail::__range_key_type<_Rg>>, > + __allocator_like _Allocator = > + allocator<__detail::__range_to_alloc_type<_Rg>>> > + unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type = > {}, > + _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) > + -> unordered_map<__detail::__range_key_type<_Rg>, > + __detail::__range_mapped_type<_Rg>, > + _Hash, _Pred, _Allocator>; > + > + template<ranges::input_range _Rg, > + __allocator_like _Allocator> > + unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type, > + _Allocator) > + -> unordered_map<__detail::__range_key_type<_Rg>, > + __detail::__range_mapped_type<_Rg>, > + hash<__detail::__range_key_type<_Rg>>, > + equal_to<__detail::__range_key_type<_Rg>>, > + _Allocator>; > + > + template<ranges::input_range _Rg, > + __allocator_like _Allocator> > + unordered_map(from_range_t, _Rg&&, _Allocator) > + -> unordered_map<__detail::__range_key_type<_Rg>, > + __detail::__range_mapped_type<_Rg>, > + hash<__detail::__range_key_type<_Rg>>, > + equal_to<__detail::__range_key_type<_Rg>>, > + _Allocator>; > + > + template<ranges::input_range _Rg, > + __not_allocator_like _Hash, > + __allocator_like _Allocator> > + unordered_map(from_range_t, _Rg&&, unordered_map<int, int>::size_type, > + _Hash, _Allocator) > + -> unordered_map<__detail::__range_key_type<_Rg>, > + __detail::__range_mapped_type<_Rg>, > + _Hash, equal_to<__detail::__range_key_type<_Rg>>, > + _Allocator>; > +#endif > #endif > > template<typename _Key, typename _Tp, typename _Hash, > @@ -1008,6 +1077,34 @@ namespace __debug > : unordered_multimap(__l, __n, __hf, key_equal(), __a) > { } > > +#if __glibcxx_ranges_to_container // C++ >= 23 > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_multimap(from_range_t, _Rg&& __rg, > + size_type __n = 0, > + const hasher& __hf = hasher(), > + const key_equal& __eql = key_equal(), > + const allocator_type& __a = allocator_type()) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __eql, __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_multimap(from_range_t, _Rg&& __rg, const allocator_type& > __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_multimap(from_range_t, _Rg&& __rg, size_type __n, > + const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_multimap(from_range_t, _Rg&& __rg, size_type __n, > + const hasher& __hf, const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __a) > + { } > +#endif > + > ~unordered_multimap() = default; > > unordered_multimap& > @@ -1558,6 +1655,50 @@ namespace __debug > _Hash, _Allocator) > -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; > > +#if __glibcxx_ranges_to_container // C++ >= 23 > + template<ranges::input_range _Rg, > + __not_allocator_like _Hash = hash<__detail::__range_key_type<_Rg>>, > + __not_allocator_like _Pred = > equal_to<__detail::__range_key_type<_Rg>>, > + __allocator_like _Allocator = > + allocator<__detail::__range_to_alloc_type<_Rg>>> > + unordered_multimap(from_range_t, _Rg&&, > + unordered_multimap<int, int>::size_type = {}, > + _Hash = _Hash(), _Pred = _Pred(), > + _Allocator = _Allocator()) > + -> unordered_multimap<__detail::__range_key_type<_Rg>, > + __detail::__range_mapped_type<_Rg>, > + _Hash, _Pred, _Allocator>; > + > + template<ranges::input_range _Rg, > + __allocator_like _Allocator> > + unordered_multimap(from_range_t, _Rg&&, unordered_multimap<int, > int>::size_type, > + _Allocator) > + -> unordered_multimap<__detail::__range_key_type<_Rg>, > + __detail::__range_mapped_type<_Rg>, > + hash<__detail::__range_key_type<_Rg>>, > + equal_to<__detail::__range_key_type<_Rg>>, > + _Allocator>; > + > + template<ranges::input_range _Rg, > + __allocator_like _Allocator> > + unordered_multimap(from_range_t, _Rg&&, _Allocator) > + -> unordered_multimap<__detail::__range_key_type<_Rg>, > + __detail::__range_mapped_type<_Rg>, > + hash<__detail::__range_key_type<_Rg>>, > + equal_to<__detail::__range_key_type<_Rg>>, > + _Allocator>; > + > + template<ranges::input_range _Rg, > + __not_allocator_like _Hash, > + __allocator_like _Allocator> > + unordered_multimap(from_range_t, _Rg&&, > + unordered_multimap<int, int>::size_type, > + _Hash, _Allocator) > + -> unordered_multimap<__detail::__range_key_type<_Rg>, > + __detail::__range_mapped_type<_Rg>, > + _Hash, equal_to<__detail::__range_key_type<_Rg>>, > + _Allocator>; > +#endif > #endif > > template<typename _Key, typename _Tp, typename _Hash, > diff --git a/libstdc++-v3/include/debug/unordered_set > b/libstdc++-v3/include/debug/unordered_set > index 0f82e72ca64..2e342ccbd97 100644 > --- a/libstdc++-v3/include/debug/unordered_set > +++ b/libstdc++-v3/include/debug/unordered_set > @@ -194,6 +194,34 @@ namespace __debug > : unordered_set(__l, __n, __hf, key_equal(), __a) > { } > > +#if __glibcxx_ranges_to_container // C++ >= 23 > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_set(from_range_t, _Rg&& __rg, > + size_type __n = 0, > + const hasher& __hf = hasher(), > + const key_equal& __eql = key_equal(), > + const allocator_type& __a = allocator_type()) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __eql, __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_set(from_range_t, _Rg&& __rg, const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_set(from_range_t, _Rg&& __rg, size_type __n, > + const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_set(from_range_t, _Rg&& __rg, size_type __n, > + const hasher& __hf, const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __a) > + { } > +#endif > + > ~unordered_set() = default; > > unordered_set& > @@ -874,6 +902,34 @@ namespace __debug > : unordered_multiset(__l, __n, __hf, key_equal(), __a) > { } > > +#if __glibcxx_ranges_to_container // C++ >= 23 > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_multiset(from_range_t, _Rg&& __rg, > + size_type __n = 0, > + const hasher& __hf = hasher(), > + const key_equal& __eql = key_equal(), > + const allocator_type& __a = allocator_type()) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __eql, __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_multiset(from_range_t, _Rg&& __rg, const allocator_type& > __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_multiset(from_range_t, _Rg&& __rg, size_type __n, > + const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __a) > + { } > + > + template<__detail::__container_compatible_range<value_type> _Rg> > + unordered_multiset(from_range_t, _Rg&& __rg, size_type __n, > + const hasher& __hf, const allocator_type& __a) > + : _Base(from_range, std::forward<_Rg>(__rg), __n, __hf, __a) > + { } > +#endif > + > ~unordered_multiset() = default; > > unordered_multiset& > @@ -1388,6 +1444,81 @@ namespace __debug > unordered_multiset<int>::size_type, _Hash, _Allocator) > -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>; > > +#if __glibcxx_ranges_to_container // C++ >= 23 > + template<ranges::input_range _Rg, > + __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>, > + __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>, > + __allocator_like _Allocator = > allocator<ranges::range_value_t<_Rg>>> > + unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type = {}, > + _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) > + -> unordered_set<ranges::range_value_t<_Rg>, _Hash, _Pred, _Allocator>; > + > + template<ranges::input_range _Rg, > + __allocator_like _Allocator> > + unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type, > + _Allocator) > + -> unordered_set<ranges::range_value_t<_Rg>, > + hash<ranges::range_value_t<_Rg>>, > + equal_to<ranges::range_value_t<_Rg>>, > + _Allocator>; > + > + template<ranges::input_range _Rg, > + __allocator_like _Allocator> > + unordered_set(from_range_t, _Rg&&, _Allocator) > + -> unordered_set<ranges::range_value_t<_Rg>, > + hash<ranges::range_value_t<_Rg>>, > + equal_to<ranges::range_value_t<_Rg>>, > + _Allocator>; > + > + template<ranges::input_range _Rg, > + __not_allocator_like _Hash, > + __allocator_like _Allocator> > + unordered_set(from_range_t, _Rg&&, unordered_set<int>::size_type, > + _Hash, _Allocator) > + -> unordered_set<ranges::range_value_t<_Rg>, _Hash, > + equal_to<ranges::range_value_t<_Rg>>, > + _Allocator>; > + > +#if __glibcxx_ranges_to_container // C++ >= 23 > + template<ranges::input_range _Rg, > + __not_allocator_like _Hash = hash<ranges::range_value_t<_Rg>>, > + __not_allocator_like _Pred = equal_to<ranges::range_value_t<_Rg>>, > + __allocator_like _Allocator = > allocator<ranges::range_value_t<_Rg>>> > + unordered_multiset(from_range_t, _Rg&&, > + unordered_multiset<int>::size_type = {}, > + _Hash = _Hash(), _Pred = _Pred(), > + _Allocator = _Allocator()) > + -> unordered_multiset<ranges::range_value_t<_Rg>, _Hash, _Pred, > _Allocator>; > + > + template<ranges::input_range _Rg, > + __allocator_like _Allocator> > + unordered_multiset(from_range_t, _Rg&&, _Allocator) > + -> unordered_multiset<ranges::range_value_t<_Rg>, > + hash<ranges::range_value_t<_Rg>>, > + equal_to<ranges::range_value_t<_Rg>>, > + _Allocator>; > + > + template<ranges::input_range _Rg, > + __allocator_like _Allocator> > + unordered_multiset(from_range_t, _Rg&&, > unordered_multiset<int>::size_type, > + _Allocator) > + -> unordered_multiset<ranges::range_value_t<_Rg>, > + hash<ranges::range_value_t<_Rg>>, > + equal_to<ranges::range_value_t<_Rg>>, > + _Allocator>; > + > + template<ranges::input_range _Rg, > + __not_allocator_like _Hash, > + __allocator_like _Allocator> > + unordered_multiset(from_range_t, _Rg&&, > + unordered_multiset<int>::size_type, > + _Hash, _Allocator) > + -> unordered_multiset<ranges::range_value_t<_Rg>, _Hash, > + equal_to<ranges::range_value_t<_Rg>>, > + _Allocator>; > +#endif > +#endif > + > #endif > > template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> > -- > 2.48.1 >