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.