Found while updating the libcxx test suite. I'm looking into a fix.
ranges::equal doesn't tolerate vectors with fancy pointers when STL-internal checks are enabled:
#include "min_allocator.h"
#include <algorithm>
#include <cassert>
#include <vector>
int main() {
const std::vector<int, min_allocator<int>> v{11, 22, 33};
const int arr[]{11, 22, 33};
assert(std::ranges::equal(v, arr));
}
C:\Temp>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od /D_ENABLE_STL_INTERNAL_CHECK /I D:\GitHub\stl\llvm-project\libcxx\test\support meow.cpp
meow.cpp
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.39.33218\include\xutility(2576): error C2338: static_assert failed: 'same_as<decltype(_STD declval<_Ty>()._Unchecked_begin()), _Unwrapped_iterator_t<_Ty>>'
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.39.33218\include\xutility(2576): note: the template instantiation context (the oldest one first) is
meow.cpp(9): note: see reference to function template instantiation 'bool std::ranges::_Equal_fn::operator ()<const std::vector<int,min_allocator<int>>&,const int(&)[3],std::ranges::equal_to,std::identity,std::identity>(_Rng1,_Rng2,_Pr,_Pj1,_Pj2) const' being compiled
with
[
_Rng1=const std::vector<int,min_allocator<int>> &,
_Rng2=const int (&)[3],
_Pr=std::ranges::equal_to,
_Pj1=std::identity,
_Pj2=std::identity
]
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.39.33218\include\xutility(2592): note: see reference to variable template 'const std::_Choice_t<std::ranges::_Unchecked_begin::_Cpo::_St> std::ranges::_Unchecked_begin::_Cpo::_Choice<std::vector<int,min_allocator<int> > const &>' being compiled
C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.39.33218\include\xutility(2588): note: see reference to function template instantiation 'std::_Choice_t<std::ranges::_Unchecked_begin::_Cpo::_St> std::ranges::_Unchecked_begin::_Cpo::_Choose<const std::vector<int,min_allocator<int>>&>(void) noexcept' being compiled
This is a good check:
|
_STL_INTERNAL_STATIC_ASSERT(
|
|
same_as<decltype(_STD declval<_Ty>()._Unchecked_begin()), _Unwrapped_iterator_t<_Ty>>);
|
_Vector_const_iterator unwraps to raw pointers:
|
_NODISCARD _CONSTEXPR20 const value_type* _Unwrapped() const noexcept {
|
|
return _Unfancy(_Ptr);
|
|
}
|
|
|
|
_CONSTEXPR20 void _Seek_to(const value_type* _It) noexcept {
|
|
_Ptr = _Refancy<_Tptr>(const_cast<value_type*>(_It));
|
|
}
|
But vector::_Unchecked_begin() returns fancy pointers:
|
_NODISCARD _CONSTEXPR20 pointer _Unchecked_begin() noexcept {
|
|
return _Mypair._Myval2._Myfirst;
|
|
}
|
I think we should resolve this by making vector::_Unchecked_begin() and _Unchecked_end() return raw pointers, but I haven't verified this yet.
Found while updating the libcxx test suite. I'm looking into a fix.
ranges::equaldoesn't toleratevectors with fancy pointers when STL-internal checks are enabled:This is a good check:
STL/stl/inc/xutility
Lines 2571 to 2572 in 0403d19
_Vector_const_iteratorunwraps to raw pointers:STL/stl/inc/vector
Lines 216 to 222 in 0403d19
But
vector::_Unchecked_begin()returns fancy pointers:STL/stl/inc/vector
Lines 1858 to 1860 in 0403d19
I think we should resolve this by making
vector::_Unchecked_begin()and_Unchecked_end()return raw pointers, but I haven't verified this yet.