On Mon, Mar 17, 2025 at 7:49 PM François Dumont <frs.dum...@gmail.com>
wrote:

>
> On 17/03/2025 09:21, Tomasz Kamiński wrote:
> > This is another piece of P1206R7, adding new members to std::set
> > and std::multiset.
> >
> >       PR libstdc++/111055
> >
> > libstdc++-v3/ChangeLog:
> >
> >       * include/bits/stl_multiset.h: (inser_range)
> >       (multiset(from_range_t, _Rg&&, const _Compare&, const _Alloc&))
> >       (multiset(from_range_t, _Rg&&, const _Alloc&)): Define.
> >       * include/bits/stl_set.h: (set(from_range_t, _Rg&&, const _Alloc&))
> >       (set(from_range_t, _Rg&&, const _Compare&, const _Alloc&),
> insert_range):
> >       Define.
> >       * testsuite/23_containers/multiset/cons/from_range.cc: New test.
> >       *
> testsuite/23_containers/multiset/modifiers/insert/insert_range.cc: New test.
> >       * testsuite/23_containers/set/cons/from_range.cc: New test.
> >       * testsuite/23_containers/set/modifiers/insert/insert_range.cc:
> New test.
> > ---
> >   Added missing includes, replaced spaces with tabs.
> >   Tested on x86_64-linux without PCH. OK for trunk?
> >
> >   libstdc++-v3/include/bits/stl_multiset.h      |  52 ++++++++
> >   libstdc++-v3/include/bits/stl_set.h           |  55 ++++++++
> >   .../23_containers/multiset/cons/from_range.cc | 118 ++++++++++++++++++
> >   .../multiset/modifiers/insert/insert_range.cc |  76 +++++++++++
> >   .../23_containers/set/cons/from_range.cc      | 117 +++++++++++++++++
> >   .../set/modifiers/insert/insert_range.cc      |  79 ++++++++++++
> >   6 files changed, 497 insertions(+)
> >   create mode 100644
> libstdc++-v3/testsuite/23_containers/multiset/cons/from_range.cc
> >   create mode 100644
> libstdc++-v3/testsuite/23_containers/multiset/modifiers/insert/insert_range.cc
> >   create mode 100644
> libstdc++-v3/testsuite/23_containers/set/cons/from_range.cc
> >   create mode 100644
> libstdc++-v3/testsuite/23_containers/set/modifiers/insert/insert_range.cc
> >
> > diff --git a/libstdc++-v3/include/bits/stl_multiset.h
> b/libstdc++-v3/include/bits/stl_multiset.h
> > index 57caf6e8cc4..1d40ae01de3 100644
> > --- a/libstdc++-v3/include/bits/stl_multiset.h
> > +++ b/libstdc++-v3/include/bits/stl_multiset.h
> > @@ -60,6 +60,9 @@
> >   #if __cplusplus >= 201103L
> >   #include <initializer_list>
> >   #endif
> > +#if __glibcxx_ranges_to_container // C++ >= 23
> > +# include <bits/ranges_base.h> // ranges::begin, ranges::distance etc.
> > +#endif
> >
> >   namespace std _GLIBCXX_VISIBILITY(default)
> >   {
> > @@ -271,6 +274,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >       : _M_t(_Key_alloc_type(__a))
> >       { _M_t._M_insert_range_equal(__first, __last); }
> >
> > +#if __glibcxx_ranges_to_container // C++ >= 23
> > +      /**
> > +       * @brief Builds a %set from a range.
> > +       * @since C++23
> > +       */
> > +      template<__detail::__container_compatible_range<_Key> _Rg>
> > +     multiset(from_range_t, _Rg&& __rg,
> > +              const _Compare& __comp,
> > +              const _Alloc& __a = _Alloc())
> > +     : _M_t(__comp, _Key_alloc_type(__a))
> > +     { insert_range(std::forward<_Rg>(__rg)); }
> > +
> > +      /// Allocator-extended range constructor.
> > +      template<__detail::__container_compatible_range<_Key> _Rg>
> > +     multiset(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc())
> > +     : _M_t(_Key_alloc_type(__a))
> > +     { insert_range(std::forward<_Rg>(__rg)); }
> > +#endif
> > +
> >         /**
> >          *  The dtor only erases the elements, and note that if the
> elements
> >          *  themselves are pointers, the pointed-to memory is not
> touched in any
> > @@ -566,6 +588,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >         { this->insert(__l.begin(), __l.end()); }
> >   #endif
> >
> > +#if __glibcxx_ranges_to_container // C++ >= 23
> > +      /**
> > +       *  @brief Inserts a range of elements.
> > +       *  @since C++23
> > +       *  @param  __rg An input range of elements that can be converted
> to
> > +       *               the list's value type.
> Looks like a copy/paste, this comment should adapted to the current
> context.
>
Indeed thank you.

> > +       */
> > +      template<__detail::__container_compatible_range<_Key> _Rg>
> > +     void
> > +     insert_range(_Rg&& __rg)
> > +     {
> > +       auto __first = ranges::begin(__rg);
> > +       const auto __last = ranges::end(__rg);
> > +       for (; __first != __last; ++__first)
> > +         _M_t._M_emplace_equal(*__first);
> > +     }
> > +#endif
> > +
> > +
> >   #ifdef __glibcxx_node_extract // >= C++17
> >         /// Extract a node.
> >         node_type
> > @@ -955,6 +996,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >       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
> >
> >     /**
> > diff --git a/libstdc++-v3/include/bits/stl_set.h
> b/libstdc++-v3/include/bits/stl_set.h
> > index f32323db368..2f9b2bbfb5f 100644
> > --- a/libstdc++-v3/include/bits/stl_set.h
> > +++ b/libstdc++-v3/include/bits/stl_set.h
> > @@ -60,6 +60,9 @@
> >   #if __cplusplus >= 201103L
> >   #include <initializer_list>
> >   #endif
> > +#if __glibcxx_ranges_to_container // C++ >= 23
> > +# include <bits/ranges_base.h> // ranges::begin, ranges::distance etc.
> > +#endif
> >
> >   namespace std _GLIBCXX_VISIBILITY(default)
> >   {
> > @@ -275,6 +278,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >       : _M_t(_Key_alloc_type(__a))
> >       { _M_t._M_insert_range_unique(__first, __last); }
> >
> > +#if __glibcxx_ranges_to_container // C++ >= 23
> > +      /**
> > +       * @brief Builds a %set from a range.
> > +       * @since C++23
> > +       */
> > +      template<__detail::__container_compatible_range<_Key> _Rg>
> > +     set(from_range_t, _Rg&& __rg,
> > +         const _Compare& __comp,
> > +         const _Alloc& __a = _Alloc())
> > +     : _M_t(__comp, _Key_alloc_type(__a))
> > +     { insert_range(std::forward<_Rg>(__rg)); }
> > +
> > +      /// Allocator-extended range constructor.
> > +      template<__detail::__container_compatible_range<_Key> _Rg>
> > +     set(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc())
> > +     : _M_t(_Key_alloc_type(__a))
> > +     { insert_range(std::forward<_Rg>(__rg)); }
> > +#endif
> > +
> >         /**
> >          *  The dtor only erases the elements, and note that if the
> elements
> >          *  themselves are pointers, the pointed-to memory is not
> touched in any
> > @@ -581,6 +603,28 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >         { this->insert(__l.begin(), __l.end()); }
> >   #endif
> >
> > +#if __glibcxx_ranges_to_container // C++ >= 23
> > +      /**
> > +       *  @brief Inserts a range of elements.
> > +       *  @since C++23
> > +       *  @param  __rg An input range of elements that can be converted
> to
> > +       *               the list's value type.
> > +       */
> > +      template<__detail::__container_compatible_range<_Key> _Rg>
> > +     void
> > +     insert_range(_Rg&& __rg)
> > +     {
> > +       auto __first = ranges::begin(__rg);
> > +       const auto __last = ranges::end(__rg);
> > +       using _Rv = __remove_cvref_t<ranges::range_value_t<_Rg>>;
>
This should use ranges::range_reference_t<_Rg>.

> > +       for (; __first != __last; ++__first)
> > +         if constexpr (is_same_v<_Rv, _Key>)
> > +           _M_t._M_insert_unique(*__first);
> > +         else
> > +           _M_t._M_emplace_unique(*__first);
>
> I hope it's not a too naive question but why not always call
> _M_emplace_unique ?
>
>
>

Reply via email to