Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<deque>: Use unchecked iterators #4071

Merged
merged 3 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 36 additions & 25 deletions stl/inc/deque
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,8 @@ public:

if ((empty() && _Mapsize() > 0)
|| (!empty() && size() <= _Newcapacity && _Newcapacity < _Oldcapacity)) { // worth shrinking, do it
deque _Tmp(_STD make_move_iterator(begin()), _STD make_move_iterator(end()));
deque _Tmp(
_STD make_move_iterator(_Unchecked_begin()), _STD make_move_iterator(_Unchecked_end()), _Getal());
swap(_Tmp);
}
}
Expand All @@ -1005,63 +1006,63 @@ public:
_STL_VERIFY(_Pos < _Mysize(), "deque subscript out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0

return _Get_data()._Subscript(_Myoff() + _Pos);
return _Subscript(_Pos);
}

_NODISCARD reference operator[](size_type _Pos) noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(_Pos < _Mysize(), "deque subscript out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0

return _Get_data()._Subscript(_Myoff() + _Pos);
return _Subscript(_Pos);
}

_NODISCARD const_reference at(size_type _Pos) const {
if (_Mysize() <= _Pos) {
_Xran();
}

return _Get_data()._Subscript(_Myoff() + _Pos);
return _Subscript(_Pos);
}

_NODISCARD reference at(size_type _Pos) {
if (_Mysize() <= _Pos) {
_Xran();
}

return _Get_data()._Subscript(_Myoff() + _Pos);
return _Subscript(_Pos);
}

_NODISCARD reference front() noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(!empty(), "front() called on empty deque");
#endif // _CONTAINER_DEBUG_LEVEL > 0

return *_Unchecked_begin();
return _Subscript(0);
}

_NODISCARD const_reference front() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(!empty(), "front() called on empty deque");
#endif // _CONTAINER_DEBUG_LEVEL > 0

return *_Unchecked_begin();
return _Subscript(0);
}

_NODISCARD reference back() noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(!empty(), "back() called on empty deque");
#endif // _CONTAINER_DEBUG_LEVEL > 0

return *_Prev_iter(_Unchecked_end());
return _Subscript(_Mysize() - 1);
}

_NODISCARD const_reference back() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(!empty(), "back() called on empty deque");
#endif // _CONTAINER_DEBUG_LEVEL > 0

return *_Prev_iter(_Unchecked_end());
return _Subscript(_Mysize() - 1);
}

private:
Expand Down Expand Up @@ -1201,7 +1202,7 @@ public:
}

const auto _Num = static_cast<difference_type>(_Mysize() - _Oldsize);
_STD reverse(begin(), begin() + _Num);
_STD reverse(_Unchecked_begin(), _Unchecked_begin() + _Num);
}
_Guard._Container = nullptr;
}
Expand Down Expand Up @@ -1346,7 +1347,7 @@ private:
}

void _Insert_n(const_iterator _Where, size_type _Count, const _Ty& _Val) { // insert _Count * _Val at _Where
iterator _Mid;
_Unchecked_iterator _Mid;
size_type _Num;
size_type _Off = static_cast<size_type>(_Where - begin());
size_type _Oldsize = _Mysize();
Expand All @@ -1363,22 +1364,22 @@ private:
push_front(_Val); // push excess values
}
for (_Num = _Off; _Num > 0; --_Num) {
push_front(begin()[static_cast<difference_type>(_Count - 1)]); // push prefix
push_front(_Subscript(_Count - 1)); // push prefix
}

_Mid = begin() + static_cast<difference_type>(_Count);
_Mid = _Unchecked_begin() + static_cast<difference_type>(_Count);
_STD fill_n(_Mid, _Off, _Val); // fill in rest of values
} else { // insert not longer than prefix
for (_Num = _Count; _Num > 0; --_Num) {
push_front(begin()[static_cast<difference_type>(_Count - 1)]); // push part of prefix
push_front(_Subscript(_Count - 1)); // push part of prefix
}

_Mid = begin() + static_cast<difference_type>(_Count);
_Mid = _Unchecked_begin() + static_cast<difference_type>(_Count);
_Alloc_temporary2<_Alty> _Tmp(_Getal(), _Val); // in case _Val is in sequence
_STD move(_Mid + static_cast<difference_type>(_Count), _Mid + static_cast<difference_type>(_Off),
_Mid); // copy rest of prefix
_STD fill(begin() + static_cast<difference_type>(_Off), _Mid + static_cast<difference_type>(_Off),
_Tmp._Get_value()); // fill in values
_STD fill(_Unchecked_begin() + static_cast<difference_type>(_Off),
_Mid + static_cast<difference_type>(_Off), _Tmp._Get_value()); // fill in values
}
_Guard._Container = nullptr;
} else { // closer to back
Expand All @@ -1389,18 +1390,17 @@ private:
_Emplace_back_internal(_Val); // push excess values
}
for (_Num = 0; _Num < _Rem; ++_Num) {
_Emplace_back_internal(begin()[static_cast<difference_type>(_Off + _Num)]); // push suffix
_Emplace_back_internal(_Subscript(_Off + _Num)); // push suffix
}

_Mid = begin() + static_cast<difference_type>(_Off);
_Mid = _Unchecked_begin() + static_cast<difference_type>(_Off);
_STD fill_n(_Mid, _Rem, _Val); // fill in rest of values
} else { // insert not longer than prefix
for (_Num = 0; _Num < _Count; ++_Num) {
_Emplace_back_internal(
begin()[static_cast<difference_type>(_Off + _Rem - _Count + _Num)]); // push part of prefix
_Emplace_back_internal(_Subscript(_Off + _Rem - _Count + _Num)); // push part of prefix
}

_Mid = begin() + static_cast<difference_type>(_Off);
_Mid = _Unchecked_begin() + static_cast<difference_type>(_Off);
_Alloc_temporary2<_Alty> _Tmp(_Getal(), _Val); // in case _Val is in sequence
_STD move_backward(_Mid, _Mid + static_cast<difference_type>(_Rem - _Count),
_Mid + static_cast<difference_type>(_Rem)); // copy rest of prefix
Expand Down Expand Up @@ -1483,13 +1483,16 @@ public:
return _First;
}

if (_Off < static_cast<size_type>(end() - _Last)) { // closer to front
_STD move_backward(begin(), _First, _Last); // copy over hole
auto _Unchecked_first = _First._Unwrapped();
auto _Unchecked_last = _Last._Unwrapped();

if (_Off < static_cast<size_type>(_Unchecked_end() - _Unchecked_last)) { // closer to front
_STD move_backward(_Unchecked_begin(), _Unchecked_first, _Unchecked_last); // copy over hole
for (; _Count > 0; --_Count) {
pop_front(); // pop copied elements
}
} else { // closer to back
_STD move(_Last, end(), _First); // copy over hole
_STD move(_Unchecked_last, _Unchecked_end(), _Unchecked_first); // copy over hole
for (; _Count > 0; --_Count) {
pop_back(); // pop copied elements
}
Expand Down Expand Up @@ -1692,6 +1695,14 @@ private:
return static_cast<_Map_difference_type>(_Get_data()._Mapsize);
}

reference _Subscript(size_type _Pos) noexcept {
return _Get_data()._Subscript(_Myoff() + _Pos);
}

const_reference _Subscript(size_type _Pos) const noexcept {
return _Get_data()._Subscript(_Myoff() + _Pos);
}

_Compressed_pair<_Alty, _Scary_val> _Mypair;
};

Expand Down
28 changes: 28 additions & 0 deletions tests/std/tests/VSO_0000000_allocator_propagation/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,33 @@ _CONSTEXPR20 bool test_sequence() {
}


template <class Alloc>
void test_deque_shrink_to_fit_per_alloc() {
{
deque<int, Alloc> d(1729, 0, Alloc{42});
d.resize(0);
d.shrink_to_fit();
assert(d.get_allocator().id() == 42);
}
{
deque<int, Alloc> d(1729, 0, Alloc{42});
d.resize(128);
d.shrink_to_fit();
assert(d.get_allocator().id() == 42);
}
}

void test_deque_shrink_to_fit() { // MSVC STL's deque::shrink_to_fit relies on swap
test_deque_shrink_to_fit_per_alloc<StationaryAlloc<int>>();
test_deque_shrink_to_fit_per_alloc<CopyAlloc<int>>();
test_deque_shrink_to_fit_per_alloc<CopyEqualAlloc<int>>();
test_deque_shrink_to_fit_per_alloc<MoveAlloc<int>>();
test_deque_shrink_to_fit_per_alloc<MoveEqualAlloc<int>>();
test_deque_shrink_to_fit_per_alloc<SwapAlloc<int>>();
test_deque_shrink_to_fit_per_alloc<SwapEqualAlloc<int>>();
}


void test_flist_copy_ctor() {
forward_list<int, StationaryAlloc<int>> src({10, 20, 30}, StationaryAlloc<int>(11));
auto src_it = src.begin();
Expand Down Expand Up @@ -1849,6 +1876,7 @@ int main() {
static_assert(test_string());
#endif // _HAS_CXX20

test_deque_shrink_to_fit();
test_flist();
test_string();
test_vb();
Expand Down