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
>

Reply via email to