On Thu, Mar 20, 2025 at 10:31 AM Jonathan Wakely <jwak...@redhat.com> 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 > >