On Mon, 19 Feb 2024, 07:08 Stephan Bergmann, wrote: > On 2/17/24 15:14, François Dumont wrote: > > Thanks for the link, tested and committed. > > I assume this is the cause for the below failure now, > Yes, the new >= C++11 overload of __niter_base recursively unwraps multiple layers of wrapping, so that a safe iterator wrapping a normal iterator wrapping a pointer is unwrapped to just a pointer. But then __niter_wrap doesn't restore both layers. I think the change might need to be reverted. > > $ cat test.cc > > #include > > #include > > void f(std::vector &v, void const * p) { > > std::erase(v, p); > > } > > > $ ~/gcc/inst/bin/g++ -std=c++20 -D_GLIBCXX_DEBUG -fsyntax-only test.cc > > In file included from ~/gcc/inst/include/c++/14.0.1/algorithm:60, > > from test.cc:1: > > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h: In instantiation of > ‘constexpr _From std::__niter_wrap(_From, _To) [with _From = > __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator __cxx1998::vector > >, > __debug::vector, random_access_iterator_tag>; _To = > __gnu_cxx::__normal_iterator allocator > >]’: > > ~/gcc/inst/include/c++/14.0.1/vector:144:29: required from ‘constexpr > typename std::__debug::vector<_Tp, _Allocator>::size_type > std::erase(__debug::vector<_Tp, _Alloc>&, const _Up&) [with _Tp = const > void*; _Alloc = allocator; _Up = const void*; typename > __debug::vector<_Tp, _Allocator>::size_type = long unsigned int]’ > > 144 | __cont.erase(__niter_wrap(__cont.begin(), __removed), > > | ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ > > test.cc:4:15: required from here > > 4 | std::erase(v, p); > > | ~~~~~~~~~~^~~~~~ > > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:30: error: no > match for ‘operator-’ (operand types are > ‘__gnu_cxx::__normal_iterator void*, std::allocator > >’ and ‘const void**’) > > 347 | { return __from + (__res - std::__niter_base(__from)); } > > | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > In file included from > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:67: > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1148:7: note: > candidate: ‘constexpr __gnu_cxx::__normal_iterator<_Iterator, _Container> > __gnu_cxx::__normal_iterator<_Iterator, > _Container>::operator-(difference_type) const [with _Iterator = const > void**; _Container = std::__cxx1998::vector std::allocator >; difference_type = long int]’ (near match) > > 1148 | operator-(difference_type __n) const _GLIBCXX_NOEXCEPT > > | ^~~~~~~~ > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1148:7: note: > conversion of argument 1 would be ill-formed: > > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:49: error: invalid > conversion from ‘const void**’ to ‘__gnu_cxx::__normal_iterator void**, std::__cxx1998::vector > > >::difference_type’ {aka ‘long int’} [-fpermissive] > > 347 | { return __from + (__res - std::__niter_base(__from)); } > > | ~~~~~~~~~~~~~~~~~^~~~~~~~ > > | | > > | const void** > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:618:5: note: > candidate: ‘template constexpr decltype > ((__y.base() - __x.base())) std::operator-(const > reverse_iterator<_IteratorL>&, const reverse_iterator<_IteratorR>&)’ > > 618 | operator-(const reverse_iterator<_IteratorL>& __x, > > | ^~~~~~~~ > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:618:5: note: > template argument deduction/substitution failed: > > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:30: note: > ‘__gnu_cxx::__normal_iterator void*, std::allocator > >’ is not derived from ‘const > std::reverse_iterator<_IteratorL>’ > > 347 | { return __from + (__res - std::__niter_base(__from)); } > > | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1789:5: note: > candidate: ‘template constexpr decltype > ((__x.base() - __y.base())) std::operator-(const > move_iterator<_IteratorL>&, const move_iterator<_IteratorR>&)’ > > 1789 | operator-(const move_iterator<_IteratorL>& __x, > > | ^~~~~~~~ > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1789:5: note: > template argument deduction/substitution failed: > > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:30: note: > ‘__gnu_cxx::__normal_iterator void*, std::allocator > >’ is not derived from ‘const > std::move_iterator<_IteratorL>’ > > 347 | { return __from + (__res - std::__niter_base(__from)); } > > | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1312:5: note: > candidate: ‘template > constexpr decltype ((__lhs.base() - __rhs.base())) > __gnu_cxx::operator-(const __normal_iterator<_IteratorL, _Container>&, > const __normal_iterator<_IteratorR, _Container>&)’ > > 1312 | operator-(const __normal_iterator<_IteratorL, _Container>& > __lhs, > > | ^~~~~~~~ > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1312:5: note: > template argument deduction/substitution failed: > > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:30: note: > mismatched types ‘const __gnu_cxx::__normal_iterator<_IteratorR, > _Container>’ and ‘const void**’ > > 347 | { return __from + (__res - std::__niter_base(__from)); } > > | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1325:5: note: > candidate: ‘template constexpr typename > __gnu_cxx::__normal_iterator<_Iterator, _Container>::difference_type > __gnu_cxx::operator-(const __normal_iterator<_Iterator, _Container>&, const > __normal_iterator<_Iterator, _Container>&)’ > > 1325 | operator-(const __normal_iterator<_Iterator, _Container>& > __lhs, > > | ^~~~~~~~ > > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1325:5: note: > template argument deduction/substitution failed: > > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:30: note: > mismatched types ‘const __gnu_cxx::__normal_iterator<_Iterator, > _Container>’ and ‘const void**’ > > 347 | { return __from + (__res - std::__niter_base(__from)); } > > | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ > >