Thanks to visit codestin.com
Credit goes to github.com

Skip to content

<vector>: vectors with fancy pointers cause ranges::equal to fail STL-internal checks #4242

@StephanTLavavej

Description

@StephanTLavavej

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:

C:\Temp>type meow.cpp
#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/stl/inc/xutility

Lines 2571 to 2572 in 0403d19

_STL_INTERNAL_STATIC_ASSERT(
same_as<decltype(_STD declval<_Ty>()._Unchecked_begin()), _Unwrapped_iterator_t<_Ty>>);

_Vector_const_iterator unwraps to raw pointers:

STL/stl/inc/vector

Lines 216 to 222 in 0403d19

_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:

STL/stl/inc/vector

Lines 1858 to 1860 in 0403d19

_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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions