1515#include < __cxx03/__iterator/advance.h>
1616#include < __cxx03/__iterator/iterator_traits.h>
1717#include < __cxx03/__type_traits/enable_if.h>
18+ #include < __cxx03/__utility/move.h>
1819
1920#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2021# pragma GCC system_header
2122#endif
2223
24+ _LIBCPP_PUSH_MACROS
25+ #include < __cxx03/__undef_macros>
26+
2327_LIBCPP_BEGIN_NAMESPACE_STD
2428
2529template <class _InputIter , __enable_if_t <__has_input_iterator_category<_InputIter>::value, int > = 0 >
2630inline _LIBCPP_HIDE_FROM_ABI _InputIter
27- prev (_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1 ) {
31+ prev (_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n) {
2832 // Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation.
2933 // Note that this check duplicates the similar check in `std::advance`.
3034 _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 =
3337 return __x;
3438}
3539
40+ // LWG 3197
41+ // It is unclear what the implications of "BidirectionalIterator" in the standard are.
42+ // However, calling std::prev(non-bidi-iterator) is obviously an error and we should catch it at compile time.
43+ template <class _InputIter , __enable_if_t <__has_input_iterator_category<_InputIter>::value, int > = 0 >
44+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _InputIter prev (_InputIter __it) {
45+ static_assert (__has_bidirectional_iterator_category<_InputIter>::value,
46+ " Attempt to prev(it) with a non-bidirectional iterator" );
47+ return std::prev (std::move (__it), 1 );
48+ }
49+
50+ _LIBCPP_POP_MACROS
51+
3652_LIBCPP_END_NAMESPACE_STD
3753
3854#endif // _LIBCPP___CXX03___ITERATOR_PREV_H
0 commit comments