<deque>: Use _Next_iter and _Prev_iter (#1161)

This commit is contained in:
Casey Carter 2020-08-12 12:51:26 -07:00 коммит произвёл GitHub
Родитель 7f29487be5
Коммит ae1068e07b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 24 добавлений и 7 удалений

Просмотреть файл

@ -836,10 +836,10 @@ public:
if (_Off <= _Mysize() / 2) { // closer to front, push to front then rotate if (_Off <= _Mysize() / 2) { // closer to front, push to front then rotate
emplace_front(_STD forward<_Valty>(_Val)...); emplace_front(_STD forward<_Valty>(_Val)...);
_STD rotate(begin(), begin() + 1, begin() + static_cast<difference_type>(1 + _Off)); _STD rotate(begin(), _Next_iter(begin()), begin() + static_cast<difference_type>(1 + _Off));
} else { // closer to back, push to back then rotate } else { // closer to back, push to back then rotate
emplace_back(_STD forward<_Valty>(_Val)...); emplace_back(_STD forward<_Valty>(_Val)...);
_STD rotate(begin() + static_cast<difference_type>(_Off), end() - 1, end()); _STD rotate(begin() + static_cast<difference_type>(_Off), _Prev_iter(end()), end());
} }
return begin() + static_cast<difference_type>(_Off); return begin() + static_cast<difference_type>(_Off);
} }
@ -1064,7 +1064,7 @@ public:
_STL_VERIFY(!empty(), "back() called on empty deque"); _STL_VERIFY(!empty(), "back() called on empty deque");
#endif // _CONTAINER_DEBUG_LEVEL > 0 #endif // _CONTAINER_DEBUG_LEVEL > 0
return *(_Unchecked_end() - 1); return *_Prev_iter(_Unchecked_end());
} }
_NODISCARD const_reference back() const noexcept /* strengthened */ { _NODISCARD const_reference back() const noexcept /* strengthened */ {
@ -1072,7 +1072,7 @@ public:
_STL_VERIFY(!empty(), "back() called on empty deque"); _STL_VERIFY(!empty(), "back() called on empty deque");
#endif // _CONTAINER_DEBUG_LEVEL > 0 #endif // _CONTAINER_DEBUG_LEVEL > 0
return *(_Unchecked_end() - 1); return *_Prev_iter(_Unchecked_end());
} }
void push_front(const _Ty& _Val) { void push_front(const _Ty& _Val) {
@ -1197,10 +1197,10 @@ public:
if (_Off <= _Mysize() / 2) { // closer to front, push to front then copy if (_Off <= _Mysize() / 2) { // closer to front, push to front then copy
push_front(_Val); push_front(_Val);
_STD rotate(begin(), begin() + 1, begin() + static_cast<difference_type>(1 + _Off)); _STD rotate(begin(), _Next_iter(begin()), begin() + static_cast<difference_type>(1 + _Off));
} else { // closer to back, push to back then copy } else { // closer to back, push to back then copy
push_back(_Val); push_back(_Val);
_STD rotate(begin() + static_cast<difference_type>(_Off), end() - 1, end()); _STD rotate(begin() + static_cast<difference_type>(_Off), _Prev_iter(end()), end());
} }
return begin() + static_cast<difference_type>(_Off); return begin() + static_cast<difference_type>(_Off);

Просмотреть файл

@ -282,7 +282,7 @@ constexpr bool can_addressof = false;
template <typename T> template <typename T>
constexpr bool can_addressof<T, void_t<decltype(addressof(declval<T>()))>> = true; constexpr bool can_addressof<T, void_t<decltype(addressof(declval<T>()))>> = true;
void test_LWG_2598() { void test_LWG_2598() { // COMPILE-ONLY
STATIC_ASSERT(can_addressof<int&>); STATIC_ASSERT(can_addressof<int&>);
STATIC_ASSERT(can_addressof<const int&>); STATIC_ASSERT(can_addressof<const int&>);
STATIC_ASSERT(can_addressof<volatile int&>); STATIC_ASSERT(can_addressof<volatile int&>);
@ -292,3 +292,20 @@ void test_LWG_2598() {
STATIC_ASSERT(!can_addressof<volatile int>); STATIC_ASSERT(!can_addressof<volatile int>);
STATIC_ASSERT(!can_addressof<const volatile int>); STATIC_ASSERT(!can_addressof<const volatile int>);
} }
// Also test DevCom-1134328, in which `deque<S*>::_Unchecked_iterator{} - 1` finds
// operator-(const S&, int) by argument-dependent lookup causing overload resolution
// to fail due to ambiguity when compiling 64-bit.
struct S {
S() = default;
template <typename T>
S(T&&);
};
S operator-(const S&, int);
void test_DevCom_1134328() { // COMPILE-ONLY
deque<S*> d{nullptr};
(void) d.back();
}