On Thu, Mar 20, 2025 at 10:31 AM Jonathan Wakely <[email protected]> wrote:
> libstdc++-v3/ChangeLog:
>
> * include/debug/map.h (map): Add from_range constructors and
> deduction guides.
> * include/debug/multimap.h (multimap): Likewise.
> * include/debug/multiset.h (multiset): Likewise.
> * include/debug/set.h (set): Likewise.
> ---
>
> When testing with -D_GLIBCXX_DEBUG I noticed we need the new ctors and
> deduction guides for the debug mode containers. This adds them for <map>
> and <set>, but we also need them for the unordered containers.
>
> Tested x86_64-linux.
>
LGTM
>
> libstdc++-v3/include/debug/map.h | 36 +++++++++++++++++++++++++++
> libstdc++-v3/include/debug/multimap.h | 36 +++++++++++++++++++++++++++
> libstdc++-v3/include/debug/multiset.h | 30 ++++++++++++++++++++++
> libstdc++-v3/include/debug/set.h | 32 +++++++++++++++++++++++-
> 4 files changed, 133 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/debug/map.h
> b/libstdc++-v3/include/debug/map.h
> index a9fac790b1c..aa1c1dbd47a 100644
> --- a/libstdc++-v3/include/debug/map.h
> +++ b/libstdc++-v3/include/debug/map.h
> @@ -133,6 +133,25 @@ namespace __debug
> __gnu_debug::__base(__last), __a)
> { }
>
> +#if __glibcxx_ranges_to_container // C++ >= 23
> + /**
> + * @brief Construct a map from a range.
> + * @since C++23
> + */
> + template<std::__detail::__container_compatible_range<value_type>
> _Rg>
> + map(std::from_range_t __t, _Rg&& __rg,
> + const _Compare& __c,
> + const allocator_type& __a = allocator_type())
> + : _Base(__t, std::forward<_Rg>(__rg), __c, __a)
> + { }
> +
> + template<std::__detail::__container_compatible_range<value_type>
> _Rg>
> + map(std::from_range_t __t, _Rg&& __rg,
> + const allocator_type& __a = allocator_type())
> + : _Base(__t, std::forward<_Rg>(__rg), __a)
> + { }
> +#endif
> +
> ~map() = default;
> #endif
>
> @@ -740,6 +759,23 @@ namespace __debug
> map(initializer_list<pair<_Key, _Tp>>, _Allocator)
> -> map<_Key, _Tp, less<_Key>, _Allocator>;
>
> +#if __glibcxx_ranges_to_container // C++ >= 23
> + template<ranges::input_range _Rg,
> + __not_allocator_like _Compare =
> less<__detail::__range_key_type<_Rg>>,
> + __allocator_like _Alloc =
> + std::allocator<__detail::__range_to_alloc_type<_Rg>>>
> + map(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc())
> + -> map<__detail::__range_key_type<_Rg>,
> + __detail::__range_mapped_type<_Rg>,
> + _Compare, _Alloc>;
> +
> + template<ranges::input_range _Rg, __allocator_like _Alloc>
> + map(from_range_t, _Rg&&, _Alloc)
> + -> map<__detail::__range_key_type<_Rg>,
> + __detail::__range_mapped_type<_Rg>,
> + less<__detail::__range_key_type<_Rg>>,
> + _Alloc>;
> +#endif
> #endif // deduction guides
>
> template<typename _Key, typename _Tp,
> diff --git a/libstdc++-v3/include/debug/multimap.h
> b/libstdc++-v3/include/debug/multimap.h
> index 8feca2c7eeb..bef1f174a8e 100644
> --- a/libstdc++-v3/include/debug/multimap.h
> +++ b/libstdc++-v3/include/debug/multimap.h
> @@ -133,6 +133,25 @@ namespace __debug
> __glibcxx_check_valid_constructor_range(__first,
> __last)),
> __gnu_debug::__base(__last), __a) { }
>
> +#if __glibcxx_ranges_to_container // C++ >= 23
> + /**
> + * @brief Construct a multimap from a range.
> + * @since C++23
> + */
> + template<std::__detail::__container_compatible_range<value_type>
> _Rg>
> + multimap(std::from_range_t __t, _Rg&& __rg,
> + const _Compare& __c,
> + const allocator_type& __a = allocator_type())
> + : _Base(__t, std::forward<_Rg>(__rg), __c, __a)
> + { }
> +
> + template<std::__detail::__container_compatible_range<value_type>
> _Rg>
> + multimap(std::from_range_t __t, _Rg&& __rg,
> + const allocator_type& __a = allocator_type())
> + : _Base(__t, std::forward<_Rg>(__rg), __a)
> + { }
> +#endif
> +
> ~multimap() = default;
> #endif
>
> @@ -622,6 +641,23 @@ namespace __debug
> multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)
> -> multimap<_Key, _Tp, less<_Key>, _Allocator>;
>
> +#if __glibcxx_ranges_to_container // C++ >= 23
> + template<ranges::input_range _Rg,
> + __not_allocator_like _Compare =
> less<__detail::__range_key_type<_Rg>>,
> + __allocator_like _Alloc =
> + std::allocator<__detail::__range_to_alloc_type<_Rg>>>
> + multimap(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc =
> _Alloc())
> + -> multimap<__detail::__range_key_type<_Rg>,
> + __detail::__range_mapped_type<_Rg>,
> + _Compare, _Alloc>;
> +
> + template<ranges::input_range _Rg, __allocator_like _Alloc>
> + multimap(from_range_t, _Rg&&, _Alloc)
> + -> multimap<__detail::__range_key_type<_Rg>,
> + __detail::__range_mapped_type<_Rg>,
> + less<__detail::__range_key_type<_Rg>>,
> + _Alloc>;
> +#endif
> #endif
>
> template<typename _Key, typename _Tp,
> diff --git a/libstdc++-v3/include/debug/multiset.h
> b/libstdc++-v3/include/debug/multiset.h
> index 09db81f8bae..bddcd282bfa 100644
> --- a/libstdc++-v3/include/debug/multiset.h
> +++ b/libstdc++-v3/include/debug/multiset.h
> @@ -133,6 +133,25 @@ namespace __debug
> __glibcxx_check_valid_constructor_range(__first,
> __last)),
> __gnu_debug::__base(__last), __a) { }
>
> +#if __glibcxx_ranges_to_container // C++ >= 23
> + /**
> + * @brief Construct a multiset from a range.
> + * @since C++23
> + */
> + template<std::__detail::__container_compatible_range<value_type>
> _Rg>
> + multiset(std::from_range_t __t, _Rg&& __rg,
> + const _Compare& __c,
> + const allocator_type& __a = allocator_type())
> + : _Base(__t, std::forward<_Rg>(__rg), __c, __a)
> + { }
> +
> + template<std::__detail::__container_compatible_range<value_type>
> _Rg>
> + multiset(std::from_range_t __t, _Rg&& __rg,
> + const allocator_type& __a = allocator_type())
> + : _Base(__t, std::forward<_Rg>(__rg), __a)
> + { }
> +#endif
> +
> ~multiset() = default;
> #endif
>
> @@ -594,6 +613,17 @@ namespace __debug
> multiset(initializer_list<_Key>, _Allocator)
> -> multiset<_Key, less<_Key>, _Allocator>;
>
> +#if __glibcxx_ranges_to_container // C++ >= 23
> + template<ranges::input_range _Rg,
> + __not_allocator_like _Compare =
> less<ranges::range_value_t<_Rg>>,
> + __allocator_like _Alloc =
> std::allocator<ranges::range_value_t<_Rg>>>
> + multiset(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc =
> _Alloc())
> + -> multiset<ranges::range_value_t<_Rg>, _Compare, _Alloc>;
> +
> + template<ranges::input_range _Rg, __allocator_like _Alloc>
> + multiset(from_range_t, _Rg&&, _Alloc)
> + -> multiset<ranges::range_value_t<_Rg>,
> less<ranges::range_value_t<_Rg>>, _Alloc>;
> +#endif
> #endif // deduction guides
>
> template<typename _Key, typename _Compare, typename _Allocator>
> diff --git a/libstdc++-v3/include/debug/set.h
> b/libstdc++-v3/include/debug/set.h
> index 5f6cf123898..9555555975f 100644
> --- a/libstdc++-v3/include/debug/set.h
> +++ b/libstdc++-v3/include/debug/set.h
> @@ -131,7 +131,26 @@ namespace __debug
> __glibcxx_check_valid_constructor_range(__first,
> __last)),
> __gnu_debug::__base(__last), __a) { }
>
> - ~set() = default;
> +#if __glibcxx_ranges_to_container // C++ >= 23
> + /**
> + * @brief Construct a set from a range.
> + * @since C++23
> + */
> + template<std::__detail::__container_compatible_range<_Key> _Rg>
> + set(std::from_range_t __t, _Rg&& __rg,
> + const _Compare& __c,
> + const allocator_type& __a = allocator_type())
> + : _Base(__t, std::forward<_Rg>(__rg), __c, __a)
> + { }
> +
> + template<std::__detail::__container_compatible_range<_Key> _Rg>
> + set(std::from_range_t __t, _Rg&& __rg,
> + const allocator_type& __a = allocator_type())
> + : _Base(__t, std::forward<_Rg>(__rg), __a)
> + { }
> +#endif
> +
> + ~set() = default;
> #endif
>
> explicit set(const _Compare& __comp,
> @@ -604,6 +623,17 @@ namespace __debug
> set(initializer_list<_Key>, _Allocator)
> -> set<_Key, less<_Key>, _Allocator>;
>
> +#if __glibcxx_ranges_to_container // C++ >= 23
> + template<ranges::input_range _Rg,
> + __not_allocator_like _Compare =
> less<ranges::range_value_t<_Rg>>,
> + __allocator_like _Alloc =
> std::allocator<ranges::range_value_t<_Rg>>>
> + set(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc())
> + -> set<ranges::range_value_t<_Rg>, _Compare, _Alloc>;
> +
> + template<ranges::input_range _Rg, __allocator_like _Alloc>
> + set(from_range_t, _Rg&&, _Alloc)
> + -> set<ranges::range_value_t<_Rg>,
> less<ranges::range_value_t<_Rg>>, _Alloc>;
> +#endif
> #endif // deduction guides
>
> template<typename _Key, typename _Compare, typename _Allocator>
> --
> 2.48.1
>
>