From 76b37d5b08d3c374d3deb74eaa757e1a736a7d11 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Fri, 5 Sep 2025 15:19:33 +0200 Subject: [PATCH] [libc++][C++03] cherry-pick #112102 --- libcxx/include/__cxx03/__iterator/prev.h | 18 +++++++++++++++++- .../iterator.operations/prev.verify.cpp | 2 -- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__cxx03/__iterator/prev.h b/libcxx/include/__cxx03/__iterator/prev.h index dc1bdaf584022..32f6e66dac9a5 100644 --- a/libcxx/include/__cxx03/__iterator/prev.h +++ b/libcxx/include/__cxx03/__iterator/prev.h @@ -15,16 +15,20 @@ #include <__cxx03/__iterator/advance.h> #include <__cxx03/__iterator/iterator_traits.h> #include <__cxx03/__type_traits/enable_if.h> +#include <__cxx03/__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__cxx03/__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template ::value, int> = 0> inline _LIBCPP_HIDE_FROM_ABI _InputIter -prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { +prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n) { // Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation. // Note that this check duplicates the similar check in `std::advance`. _LIBCPP_ASSERT_PEDANTIC(__n <= 0 || __has_bidirectional_iterator_category<_InputIter>::value, @@ -33,6 +37,18 @@ prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = return __x; } +// LWG 3197 +// It is unclear what the implications of "BidirectionalIterator" in the standard are. +// However, calling std::prev(non-bidi-iterator) is obviously an error and we should catch it at compile time. +template ::value, int> = 0> +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _InputIter prev(_InputIter __it) { + static_assert(__has_bidirectional_iterator_category<_InputIter>::value, + "Attempt to prev(it) with a non-bidirectional iterator"); + return std::prev(std::move(__it), 1); +} + +_LIBCPP_POP_MACROS + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___CXX03___ITERATOR_PREV_H diff --git a/libcxx/test/libcxx-03/iterators/iterator.primitives/iterator.operations/prev.verify.cpp b/libcxx/test/libcxx-03/iterators/iterator.primitives/iterator.operations/prev.verify.cpp index ffef687723983..da0a336815a5c 100644 --- a/libcxx/test/libcxx-03/iterators/iterator.primitives/iterator.operations/prev.verify.cpp +++ b/libcxx/test/libcxx-03/iterators/iterator.primitives/iterator.operations/prev.verify.cpp @@ -8,8 +8,6 @@ // std::prev -// XFAIL: FROZEN-CXX03-HEADERS-FIXME - #include #include "test_iterators.h"