15
15
#include < __cxx03/__iterator/advance.h>
16
16
#include < __cxx03/__iterator/iterator_traits.h>
17
17
#include < __cxx03/__type_traits/enable_if.h>
18
+ #include < __cxx03/__utility/move.h>
18
19
19
20
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20
21
# pragma GCC system_header
21
22
#endif
22
23
24
+ _LIBCPP_PUSH_MACROS
25
+ #include < __cxx03/__undef_macros>
26
+
23
27
_LIBCPP_BEGIN_NAMESPACE_STD
24
28
25
29
template <class _InputIter , __enable_if_t <__has_input_iterator_category<_InputIter>::value, int > = 0 >
26
30
inline _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) {
28
32
// Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation.
29
33
// Note that this check duplicates the similar check in `std::advance`.
30
34
_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 =
33
37
return __x;
34
38
}
35
39
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
+
36
52
_LIBCPP_END_NAMESPACE_STD
37
53
38
54
#endif // _LIBCPP___CXX03___ITERATOR_PREV_H
0 commit comments