Skip to content

Commit

Permalink
<deque>: Use unchecked iterators (#4071)
Browse files Browse the repository at this point in the history
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
  • Loading branch information
frederick-vs-ja and StephanTLavavej authored Oct 6, 2023
1 parent b448869 commit 78f5939
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 25 deletions.
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

0 comments on commit 78f5939

Please sign in to comment.