ZOn Mon, 24 Feb 2020, Patrick Palka wrote:

> This adds some missing pieces of the Ranges TS that make back_insert_iterator 
> and
> front_insert_iterator conform to the new output_iterator requirements.
> 
> It also fixes a bug in ranges::__copy_or_move and
> ranges::__copy_or_move_backward in which we were inspecting the iter_value_t 
> of
> the output iterator, but iterators such as back_insert_iterator and
> front_insert_iterator whose value_type is defined to be void do not have an
> iter_value_t according to [readable.traits] p4.  The entire __use_memmove
> condition can probably be refactored, but the simplest fix for now is to 
> inspect
> the iterator_traits of the output iterator instead.
> 
> libstdc++-v3/ChangeLog:
> 
>       PR libstdc++/93884
>       * include/bits/ranges_algobase.h (__copy_or_move,
>       __copy_or_move_backward): Don't inspect the iter_value_t of the output
>       iterator, instead inspect its iterator_traits directly.
>       * include/bits/stl_iterator.h (back_insert_iterator::container):
>       Conditionally initialize.
>       (back_insert_iterator::difference_type): Conditionally define.
>       (back_insert_iterator::back_insert_iterator): Conditionally define this
>       default constructor.
>       (front_insert_iterator::container): Conditionally initialize.
>       (front_insert_iterator::difference_type): Conditionally define.
>       (front_insert_iterator::front_insert_iterator): Conditionally define
>       this default constructor.
> ---
>  libstdc++-v3/include/bits/ranges_algobase.h   |  4 +-
>  libstdc++-v3/include/bits/stl_iterator.h      | 22 ++++++++++
>  .../back_insert_iterator/pr93884.C            | 44 +++++++++++++++++++
>  .../front_insert_iterator/pr93884.C           | 44 +++++++++++++++++++
>  4 files changed, 112 insertions(+), 2 deletions(-)
>  create mode 100644 
> libstdc++-v3/testsuite/24_iterators/back_insert_iterator/pr93884.C
>  create mode 100644 
> libstdc++-v3/testsuite/24_iterators/front_insert_iterator/pr93884.C
> 
> diff --git a/libstdc++-v3/include/bits/ranges_algobase.h 
> b/libstdc++-v3/include/bits/ranges_algobase.h
> index 807822e99c8..739424e1a2d 100644
> --- a/libstdc++-v3/include/bits/ranges_algobase.h
> +++ b/libstdc++-v3/include/bits/ranges_algobase.h
> @@ -249,7 +249,7 @@ namespace ranges
>        else if constexpr (sized_sentinel_for<_Sent, _Iter>)
>       {
>         using _ValueTypeI = iter_value_t<_Iter>;
> -       using _ValueTypeO = iter_value_t<_Out>;
> +       using _ValueTypeO = iterator_traits<_Out>::value_type;
>         constexpr bool __use_memmove
>           = (is_trivially_copyable_v<_ValueTypeI>
>              && is_same_v<_ValueTypeI, _ValueTypeO>
> @@ -386,7 +386,7 @@ namespace ranges
>        else if constexpr (sized_sentinel_for<_Sent, _Iter>)
>       {
>         using _ValueTypeI = iter_value_t<_Iter>;
> -       using _ValueTypeO = iter_value_t<_Out>;
> +       using _ValueTypeO = iterator_traits<_Out>::value_type;
>         constexpr bool __use_memmove
>           = (is_trivially_copyable_v<_ValueTypeI>
>              && is_same_v<_ValueTypeI, _ValueTypeO>
> diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
> b/libstdc++-v3/include/bits/stl_iterator.h
> index 372df223113..0f2742ae4cf 100644
> --- a/libstdc++-v3/include/bits/stl_iterator.h
> +++ b/libstdc++-v3/include/bits/stl_iterator.h
> @@ -496,11 +496,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      : public iterator<output_iterator_tag, void, void, void, void>
>      {
>      protected:
> +#if __cplusplus > 201703L
> +      _Container* container = nullptr;
> +#else
>        _Container* container;
> +#endif

Just noticed the order of this conditional is inconsistent with ...

>  
>      public:
>        /// A nested typedef for the type of whatever container you used.
>        typedef _Container          container_type;
> +#if __cplusplus > 201703L
> +      using difference_type = ptrdiff_t;
> +#endif
> +
> +#if __cplusplus > 201703L
> +      constexpr back_insert_iterator() noexcept = default;
> +#endif
>  
>        /// The only way to create this %iterator is with a container.
>        explicit
> @@ -588,11 +599,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      : public iterator<output_iterator_tag, void, void, void, void>
>      {
>      protected:
> +#if __cplusplus <= 201703L
>        _Container* container;
> +#else
> +      _Container* container = nullptr;
> +#endif

... this one.  Consider this fixed so that both conditionals are
__cplusplus <= 201703L, specifying the pre-C++20 version of the code
first.

Reply via email to