void advance(_InputIter& __i,
typename iterator_traits<_InputIter>::difference_type __n)
{
+ _LIBCPP_ASSERT(__n >= 0 || __is_bidirectional_iterator<_InputIter>::value,
+ "Attempt to advance(it, -n) on a non-bidi iterator");
__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
}
next(_InputIter __x,
typename iterator_traits<_InputIter>::difference_type __n = 1)
{
+ _LIBCPP_ASSERT(__n >= 0 || __is_bidirectional_iterator<_InputIter>::value,
+ "Attempt to next(it, -n) on a non-bidi iterator");
+
_VSTD::advance(__x, __n);
return __x;
}
-template <class _BidirectionalIter>
+template <class _InputIter>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
typename enable_if
<
- __is_bidirectional_iterator<_BidirectionalIter>::value,
- _BidirectionalIter
+ __is_input_iterator<_InputIter>::value,
+ _InputIter
>::type
-prev(_BidirectionalIter __x,
- typename iterator_traits<_BidirectionalIter>::difference_type __n = 1)
+prev(_InputIter __x,
+ typename iterator_traits<_InputIter>::difference_type __n = 1)
{
+ _LIBCPP_ASSERT(__n <= 0 || __is_bidirectional_iterator<_InputIter>::value,
+ "Attempt to prev(it, +n) on a non-bidi iterator");
_VSTD::advance(__x, -__n);
return __x;
}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Can't test the system lib because this test enables debug mode
+// MODULES_DEFINES: _LIBCPP_DEBUG=1
+// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: windows
+// UNSUPPORTED: with_system_cxx_lib
+
+// <list>
+
+// Call advance(non-bidi iterator, -1)
+
+#define _LIBCPP_DEBUG 0
+
+#include <iterator>
+#include "debug_mode_helper.h"
+
+#include "test_iterators.h"
+
+int main(int, char**)
+{
+ int a[] = {1, 2, 3};
+
+ bidirectional_iterator<int *> bidi(a+1);
+ std::advance(bidi, 1); // should work fine
+ std::advance(bidi, 0); // should work fine
+ std::advance(bidi, -1); // should work fine
+
+ forward_iterator<int *> it(a+1);
+ std::advance(it, 1); // should work fine
+ std::advance(it, 0); // should work fine
+ EXPECT_DEATH( std::advance(it, -1) ); // can't go backwards on a FwdIter
+
+ return 0;
+}
+
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Can't test the system lib because this test enables debug mode
+// MODULES_DEFINES: _LIBCPP_DEBUG=1
+// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: windows
+// UNSUPPORTED: with_system_cxx_lib
+
+// <list>
+
+// Call next(non-bidi iterator, -1)
+
+#define _LIBCPP_DEBUG 0
+
+#include <iterator>
+#include "debug_mode_helper.h"
+
+#include "test_iterators.h"
+
+int main(int, char**)
+{
+ int a[] = {1, 2, 3};
+
+
+ forward_iterator<int *> it(a+1);
+ std::next(it, 1); // should work fine
+ std::next(it, 0); // should work fine
+ EXPECT_DEATH( std::next(it, -1) ); // can't go backwards on a FwdIter
+
+ return 0;
+}
+
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Can't test the system lib because this test enables debug mode
+// MODULES_DEFINES: _LIBCPP_DEBUG=1
+// UNSUPPORTED: with_system_cxx_lib
+// UNSUPPORTED: c++98, c++03
+// UNSUPPORTED: windows
+// UNSUPPORTED: with_system_cxx_lib
+
+// <list>
+
+// Call prev(forward_iterator, -1)
+
+#define _LIBCPP_DEBUG 0
+
+#include <iterator>
+#include "debug_mode_helper.h"
+
+#include "test_iterators.h"
+
+int main(int, char**)
+{
+ int a[] = {1, 2, 3};
+
+ bidirectional_iterator<int *> bidi(a+1);
+ std::prev(bidi, -1); // should work fine
+ std::prev(bidi, 0); // should work fine
+ std::prev(bidi, 1); // should work fine
+
+ forward_iterator<int *> it(a+1);
+ std::prev(it, -1); // should work fine
+ std::prev(it, 0); // should work fine
+ EXPECT_DEATH( std::prev(it, 1) ); // can't go backwards on a FwdIter
+
+ return 0;
+}
{
{
const char* s = "1234567890";
- test(input_iterator<const char*>(s), 10, input_iterator<const char*>(s+10));
- test(forward_iterator<const char*>(s), 10, forward_iterator<const char*>(s+10));
- test(bidirectional_iterator<const char*>(s), 10, bidirectional_iterator<const char*>(s+10));
- test(random_access_iterator<const char*>(s), 10, random_access_iterator<const char*>(s+10));
+ test(input_iterator<const char*>(s), 10, input_iterator<const char*>(s+10));
+ test(forward_iterator<const char*>(s), 10, forward_iterator<const char*>(s+10));
+ test(bidirectional_iterator<const char*>(s), 10, bidirectional_iterator<const char*>(s+10));
+ test(bidirectional_iterator<const char*>(s+10), -10, bidirectional_iterator<const char*>(s));
+ test(random_access_iterator<const char*>(s), 10, random_access_iterator<const char*>(s+10));
+ test(random_access_iterator<const char*>(s+10), -10, random_access_iterator<const char*>(s));
test(s, 10, s+10);
test(input_iterator<const char*>(s), input_iterator<const char*>(s+1));
#if TEST_STD_VER > 14
{
constexpr const char* s = "1234567890";
- static_assert( constexpr_test(input_iterator<const char*>(s), 10, input_iterator<const char*>(s+10)), "" );
- static_assert( constexpr_test(forward_iterator<const char*>(s), 10, forward_iterator<const char*>(s+10)), "" );
- static_assert( constexpr_test(bidirectional_iterator<const char*>(s), 10, bidirectional_iterator<const char*>(s+10)), "" );
- static_assert( constexpr_test(random_access_iterator<const char*>(s), 10, random_access_iterator<const char*>(s+10)), "" );
+ static_assert( constexpr_test(input_iterator<const char*>(s), 10, input_iterator<const char*>(s+10)), "" );
+ static_assert( constexpr_test(forward_iterator<const char*>(s), 10, forward_iterator<const char*>(s+10)), "" );
+ static_assert( constexpr_test(bidirectional_iterator<const char*>(s), 10, bidirectional_iterator<const char*>(s+10)), "" );
+ static_assert( constexpr_test(bidirectional_iterator<const char*>(s+10), -10, bidirectional_iterator<const char*>(s)), "" );
+ static_assert( constexpr_test(random_access_iterator<const char*>(s), 10, random_access_iterator<const char*>(s+10)), "" );
+ static_assert( constexpr_test(random_access_iterator<const char*>(s+10), -10, random_access_iterator<const char*>(s)), "" );
static_assert( constexpr_test(s, 10, s+10), "" );
static_assert( constexpr_test(input_iterator<const char*>(s), input_iterator<const char*>(s+1)), "" );
// <iterator>
-// template <BidirectionalIterator Iter>
+// template <InputIterator Iter>
// Iter prev(Iter x, Iter::difference_type n = 1);
#include <iterator>
{
{
const char* s = "1234567890";
- test(bidirectional_iterator<const char*>(s+10), 10, bidirectional_iterator<const char*>(s));
- test(random_access_iterator<const char*>(s+10), 10, random_access_iterator<const char*>(s));
+ test(forward_iterator <const char*>(s), -10, forward_iterator <const char*>(s+10));
+ test(bidirectional_iterator<const char*>(s+10), 10, bidirectional_iterator<const char*>(s));
+ test(bidirectional_iterator<const char*>(s), -10, bidirectional_iterator<const char*>(s+10));
+ test(random_access_iterator<const char*>(s+10), 10, random_access_iterator<const char*>(s));
+ test(random_access_iterator<const char*>(s), -10, random_access_iterator<const char*>(s+10));
test(s+10, 10, s);
test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s));
#if TEST_STD_VER > 14
{
constexpr const char* s = "1234567890";
- static_assert( constexpr_test(bidirectional_iterator<const char*>(s+10), 10, bidirectional_iterator<const char*>(s)), "" );
- static_assert( constexpr_test(random_access_iterator<const char*>(s+10), 10, random_access_iterator<const char*>(s)), "" );
+ static_assert( constexpr_test(forward_iterator <const char*>(s), -10, forward_iterator <const char*>(s+10)), "" );
+ static_assert( constexpr_test(bidirectional_iterator<const char*>(s+10), 10, bidirectional_iterator<const char*>(s)), "" );
+ static_assert( constexpr_test(forward_iterator <const char*>(s), -10, forward_iterator <const char*>(s+10)), "" );
+ static_assert( constexpr_test(random_access_iterator<const char*>(s+10), 10, random_access_iterator<const char*>(s)), "" );
+ static_assert( constexpr_test(forward_iterator <const char*>(s), -10, forward_iterator <const char*>(s+10)), "" );
static_assert( constexpr_test(s+10, 10, s), "" );
static_assert( constexpr_test(bidirectional_iterator<const char*>(s+1), bidirectional_iterator<const char*>(s)), "" );