On Thu, 20 Mar 2025 at 11:18, Tomasz Kamiński <[email protected]> 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
>