[libcxx-commits] [libcxx] 43bc1e5 - [libc++][ranges] Implement Ranges changes to `istream{, buf}_iterator`.
Konstantin Varlamov via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 15 16:59:52 PST 2022
Author: Konstantin Varlamov
Date: 2022-02-15T16:59:42-08:00
New Revision: 43bc1e5600344d54ad87eae9b1515e2fa5a9597e
URL: https://github.com/llvm/llvm-project/commit/43bc1e5600344d54ad87eae9b1515e2fa5a9597e
DIFF: https://github.com/llvm/llvm-project/commit/43bc1e5600344d54ad87eae9b1515e2fa5a9597e.diff
LOG: [libc++][ranges] Implement Ranges changes to `istream{,buf}_iterator`.
The changes from the One Ranges Proposal amount to adding:
- a constructor that takes a `default_sentinel_t` and is equivalent to
the default constructor;
- an `operator==` that compares the iterator to `default_sentinel_t`.
The original proposal defined two overloads for `operator==` (different
argument order) as well as `operator!=`. This has been removed by
[P1614](https://wg21.link/p1614).
Differential Revision: https://reviews.llvm.org/D119620
Added:
libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default_sentinel_t.pass.cpp
libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default_sentinel_t.pass.cpp
Modified:
libcxx/docs/Status/RangesPaper.csv
libcxx/include/__iterator/default_sentinel.h
libcxx/include/__iterator/istream_iterator.h
libcxx/include/__iterator/istreambuf_iterator.h
libcxx/include/iterator
libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.pass.cpp
libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.ops/equal.pass.cpp
libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default.pass.cpp
libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op!=/not_equal.pass.cpp
libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op==/equal.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/RangesPaper.csv b/libcxx/docs/Status/RangesPaper.csv
index 0aa3504ca083e..3e7be37614ad1 100644
--- a/libcxx/docs/Status/RangesPaper.csv
+++ b/libcxx/docs/Status/RangesPaper.csv
@@ -91,11 +91,11 @@ Section,Description,Dependencies,Assignee,Complete
| [iterator.cust.move]
| [default.sentinels]",Zoe Carver,✅
`[stream.iterators] <https://wg21.link/stream.iterators>`_,"
-| Updates to istream_iterator
+| `Updates to istream_iterator <https://llvm.org/D119620>`_
| `Updates to ostream_iterator <https://llvm.org/D103273>`_
-| Updates to istreambuf_iterator
+| `Updates to istreambuf_iterator <https://llvm.org/D119620>`_
| `Updates to ostreambuf_iterator <https://llvm.org/D103273>`_
-",[default.sentinels],Various,In progress
+",[default.sentinels],Various,✅
`[range.access] <https://wg21.link/range.access>`_,"| `ranges::begin <https://llvm.org/D100255>`_
| `ranges::end <https://llvm.org/D100255>`_
| `range::cbegin <https://llvm.org/D100255>`_
diff --git a/libcxx/include/__iterator/default_sentinel.h b/libcxx/include/__iterator/default_sentinel.h
index 0864d1c7443cb..669032aa97297 100644
--- a/libcxx/include/__iterator/default_sentinel.h
+++ b/libcxx/include/__iterator/default_sentinel.h
@@ -18,12 +18,12 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#if _LIBCPP_STD_VER > 17
struct default_sentinel_t { };
inline constexpr default_sentinel_t default_sentinel{};
-#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/istream_iterator.h b/libcxx/include/__iterator/istream_iterator.h
index f7014b8af1479..9ee0a989b8f6b 100644
--- a/libcxx/include/__iterator/istream_iterator.h
+++ b/libcxx/include/__iterator/istream_iterator.h
@@ -11,6 +11,7 @@
#define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H
#include <__config>
+#include <__iterator/default_sentinel.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <__memory/addressof.h>
@@ -45,6 +46,9 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
_Tp __value_;
public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {}
+#if _LIBCPP_STD_VER > 17
+ _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {}
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s))
{
if (!(*__in_stream_ >> __value_))
@@ -67,6 +71,12 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
bool
operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x,
const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y);
+
+#if _LIBCPP_STD_VER > 17
+ friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) {
+ return __i.__in_stream_ == nullptr;
+ }
+#endif // _LIBCPP_STD_VER > 17
};
template <class _Tp, class _CharT, class _Traits, class _Distance>
@@ -78,6 +88,7 @@ operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
return __x.__in_stream_ == __y.__in_stream_;
}
+#if _LIBCPP_STD_VER <= 17
template <class _Tp, class _CharT, class _Traits, class _Distance>
inline _LIBCPP_INLINE_VISIBILITY
bool
@@ -86,6 +97,7 @@ operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x,
{
return !(__x == __y);
}
+#endif // _LIBCPP_STD_VER <= 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__iterator/istreambuf_iterator.h b/libcxx/include/__iterator/istreambuf_iterator.h
index 16b2cb7b4a85b..3b16f79476783 100644
--- a/libcxx/include/__iterator/istreambuf_iterator.h
+++ b/libcxx/include/__iterator/istreambuf_iterator.h
@@ -11,6 +11,7 @@
#define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H
#include <__config>
+#include <__iterator/default_sentinel.h>
#include <__iterator/iterator.h>
#include <__iterator/iterator_traits.h>
#include <iosfwd> // for forward declaration of basic_streambuf
@@ -65,6 +66,10 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
}
public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {}
+#if _LIBCPP_STD_VER > 17
+ _LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept
+ : istreambuf_iterator() {}
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT
: __sbuf_(__s.rdbuf()) {}
_LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT
@@ -86,6 +91,12 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
_LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const
{return __test_for_eof() == __b.__test_for_eof();}
+
+#if _LIBCPP_STD_VER > 17
+ friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) {
+ return __i.__test_for_eof();
+ }
+#endif // _LIBCPP_STD_VER > 17
};
template <class _CharT, class _Traits>
@@ -94,11 +105,13 @@ bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a,
const istreambuf_iterator<_CharT,_Traits>& __b)
{return __a.equal(__b);}
+#if _LIBCPP_STD_VER <= 17
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a,
const istreambuf_iterator<_CharT,_Traits>& __b)
{return !__a.equal(__b);}
+#endif // _LIBCPP_STD_VER <= 17
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/iterator b/libcxx/include/iterator
index 202667809dcaf..fe91d15e6bc31 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -448,7 +448,8 @@ public:
typedef traits traits_type;
typedef basic_istream<charT, traits> istream_type;
- constexpr istream_iterator();
+ istream_iterator(); // constexpr since C++11
+ constexpr istream_iterator(default_sentinel_t); // since C++20
istream_iterator(istream_type& s);
istream_iterator(const istream_iterator& x);
~istream_iterator();
@@ -457,6 +458,7 @@ public:
const T* operator->() const;
istream_iterator& operator++();
istream_iterator operator++(int);
+ friend bool operator==(const istream_iterator& i, default_sentinel_t); // since C++20
};
template <class T, class charT, class traits, class Distance>
@@ -464,7 +466,7 @@ bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
const istream_iterator<T,charT,traits,Distance>& y);
template <class T, class charT, class traits, class Distance>
bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
- const istream_iterator<T,charT,traits,Distance>& y);
+ const istream_iterator<T,charT,traits,Distance>& y); // until C++20
template <class T, class charT = char, class traits = char_traits<charT> >
class ostream_iterator
@@ -510,7 +512,8 @@ public:
typedef basic_streambuf<charT, traits> streambuf_type;
typedef basic_istream<charT, traits> istream_type;
- istreambuf_iterator() noexcept;
+ istreambuf_iterator() noexcept; // constexpr since C++11
+ constexpr istreambuf_iterator(default_sentinel_t) noexcept; // since C++20
istreambuf_iterator(istream_type& s) noexcept;
istreambuf_iterator(streambuf_type* s) noexcept;
istreambuf_iterator(a-private-type) noexcept;
@@ -521,6 +524,7 @@ public:
a-private-type operator++(int);
bool equal(const istreambuf_iterator& b) const;
+ friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s); // since C++20
};
template <class charT, class traits>
@@ -528,7 +532,7 @@ bool operator==(const istreambuf_iterator<charT,traits>& a,
const istreambuf_iterator<charT,traits>& b);
template <class charT, class traits>
bool operator!=(const istreambuf_iterator<charT,traits>& a,
- const istreambuf_iterator<charT,traits>& b);
+ const istreambuf_iterator<charT,traits>& b); // until C++20
template <class charT, class traits = char_traits<charT> >
class ostreambuf_iterator
diff --git a/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.pass.cpp
index 39ace08c88d34..7273223a7dbc1 100644
--- a/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default.pass.cpp
@@ -10,7 +10,7 @@
// class istream_iterator
-// constexpr istream_iterator();
+// istream_iterator(); // constexpr since C++11
// C++17 says: If is_trivially_default_constructible_v<T> is true, then this
// constructor is a constexpr constructor.
@@ -38,8 +38,7 @@ void operator ()() const {}
#endif
-int main(int, char**)
-{
+int main(int, char**) {
{
typedef std::istream_iterator<int> T;
T it;
diff --git a/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default_sentinel_t.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default_sentinel_t.pass.cpp
new file mode 100644
index 0000000000000..e1fc85ddd4f12
--- /dev/null
+++ b/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/default_sentinel_t.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <iterator>
+//
+// constexpr istream_iterator(default_sentinel_t); // since C++20
+
+#include <iterator>
+#include <cassert>
+
+int main(int, char**) {
+ using T = std::istream_iterator<int>;
+
+ {
+ T it(std::default_sentinel);
+ assert(it == T());
+ }
+
+ {
+ T it = std::default_sentinel;
+ assert(it == T());
+ }
+
+ {
+ constexpr T it(std::default_sentinel);
+ (void)it;
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.ops/equal.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.ops/equal.pass.cpp
index 373d5ed0170c1..6ca6ce6b7215c 100644
--- a/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.ops/equal.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.ops/equal.pass.cpp
@@ -17,6 +17,8 @@
// template <class T, class charT, class traits, class Distance>
// bool operator!=(const istream_iterator<T,charT,traits,Distance> &x,
// const istream_iterator<T,charT,traits,Distance> &y);
+//
+// friend bool operator==(const istream_iterator& i, default_sentinel_t); // since C++20
#include <iterator>
#include <sstream>
@@ -24,8 +26,8 @@
#include "test_macros.h"
-int main(int, char**)
-{
+int main(int, char**) {
+ {
std::istringstream inf1(" 1 23");
std::istringstream inf2(" 1 23");
std::istream_iterator<int> i1(inf1);
@@ -52,7 +54,35 @@ int main(int, char**)
assert(i4 == i5);
assert(std::operator==(i1, i2));
+#if TEST_STD_VER <= 17
assert(std::operator!=(i1, i3));
+#endif
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::istream_iterator<int> i1;
+ std::istream_iterator<int> i2(std::default_sentinel);
+ assert(i1 == i2);
+
+ assert(i1 == std::default_sentinel);
+ assert(i2 == std::default_sentinel);
+ assert(std::default_sentinel == i1);
+ assert(std::default_sentinel == i2);
+ assert(!(i1 != std::default_sentinel));
+ assert(!(i2 != std::default_sentinel));
+ assert(!(std::default_sentinel != i1));
+ assert(!(std::default_sentinel != i2));
+
+ std::istringstream stream(" 1 23");
+ std::istream_iterator<int> i3(stream);
+
+ assert(!(i3 == std::default_sentinel));
+ assert(!(std::default_sentinel == i3));
+ assert(i3 != std::default_sentinel);
+ assert(std::default_sentinel != i3);
+ }
+#endif
return 0;
}
diff --git a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default.pass.cpp
index ccda358407a8f..1e8baeae105dd 100644
--- a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default.pass.cpp
@@ -10,7 +10,7 @@
// istreambuf_iterator
//
-// istreambuf_iterator() throw();
+// istreambuf_iterator() noexcept; // constexpr since C++11
//
// All specializations of istreambuf_iterator shall have a trivial copy constructor,
// a constexpr default constructor and a trivial destructor.
@@ -21,28 +21,31 @@
#include "test_macros.h"
-int main(int, char**)
-{
- {
- typedef std::istreambuf_iterator<char> T;
- T it;
- assert(it == T());
+int main(int, char**) {
+ {
+ typedef std::istreambuf_iterator<char> T;
+ T it;
+ assert(it == T());
#if TEST_STD_VER >= 11
- constexpr T it2;
- (void)it2;
+ constexpr T it2;
+ (void)it2;
#endif
- }
+
+ ASSERT_NOEXCEPT(T());
+ }
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- {
- typedef std::istreambuf_iterator<wchar_t> T;
- T it;
- assert(it == T());
+ {
+ typedef std::istreambuf_iterator<wchar_t> T;
+ T it;
+ assert(it == T());
#if TEST_STD_VER >= 11
- constexpr T it2;
- (void)it2;
+ constexpr T it2;
+ (void)it2;
#endif
- }
+
+ ASSERT_NOEXCEPT(T());
+ }
#endif // TEST_HAS_NO_WIDE_CHARACTERS
return 0;
diff --git a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default_sentinel_t.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default_sentinel_t.pass.cpp
new file mode 100644
index 0000000000000..b2e6dfe7a4e5b
--- /dev/null
+++ b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator.cons/default_sentinel_t.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <iterator>
+
+// constexpr istreambuf_iterator(default_sentinel_t) noexcept; // since C++20
+
+#include <iterator>
+#include <sstream>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+ using T = std::istreambuf_iterator<char>;
+
+ {
+ T it(std::default_sentinel);
+ assert(it == T());
+ }
+
+ {
+ T it = std::default_sentinel;
+ assert(it == T());
+ }
+
+ {
+ constexpr T it(std::default_sentinel);
+ (void)it;
+ }
+
+ ASSERT_NOEXCEPT(T(std::default_sentinel));
+
+ return 0;
+}
diff --git a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op!=/not_equal.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op!=/not_equal.pass.cpp
index 2771911bbae50..80520e579564f 100644
--- a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op!=/not_equal.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op!=/not_equal.pass.cpp
@@ -20,87 +20,106 @@
#include "test_macros.h"
-int main(int, char**)
-{
- {
- std::istringstream inf1("abc");
- std::istringstream inf2("def");
- std::istreambuf_iterator<char> i1(inf1);
- std::istreambuf_iterator<char> i2(inf2);
- std::istreambuf_iterator<char> i3;
- std::istreambuf_iterator<char> i4;
- std::istreambuf_iterator<char> i5(nullptr);
-
- assert(!(i1 != i1));
- assert(!(i1 != i2));
- assert( (i1 != i3));
- assert( (i1 != i4));
- assert( (i1 != i5));
-
- assert(!(i2 != i1));
- assert(!(i2 != i2));
- assert( (i2 != i3));
- assert( (i2 != i4));
- assert( (i2 != i5));
-
- assert( (i3 != i1));
- assert( (i3 != i2));
- assert(!(i3 != i3));
- assert(!(i3 != i4));
- assert(!(i3 != i5));
-
- assert( (i4 != i1));
- assert( (i4 != i2));
- assert(!(i4 != i3));
- assert(!(i4 != i4));
- assert(!(i4 != i5));
-
- assert( (i5 != i1));
- assert( (i5 != i2));
- assert(!(i5 != i3));
- assert(!(i5 != i4));
- assert(!(i5 != i5));
- }
+int main(int, char**) {
+ {
+ std::istringstream inf1("abc");
+ std::istringstream inf2("def");
+ std::istreambuf_iterator<char> i1(inf1);
+ std::istreambuf_iterator<char> i2(inf2);
+ std::istreambuf_iterator<char> i3;
+ std::istreambuf_iterator<char> i4;
+ std::istreambuf_iterator<char> i5(nullptr);
+
+ assert(!(i1 != i1));
+ assert(!(i1 != i2));
+ assert( (i1 != i3));
+ assert( (i1 != i4));
+ assert( (i1 != i5));
+
+ assert(!(i2 != i1));
+ assert(!(i2 != i2));
+ assert( (i2 != i3));
+ assert( (i2 != i4));
+ assert( (i2 != i5));
+
+ assert( (i3 != i1));
+ assert( (i3 != i2));
+ assert(!(i3 != i3));
+ assert(!(i3 != i4));
+ assert(!(i3 != i5));
+
+ assert( (i4 != i1));
+ assert( (i4 != i2));
+ assert(!(i4 != i3));
+ assert(!(i4 != i4));
+ assert(!(i4 != i5));
+
+ assert( (i5 != i1));
+ assert( (i5 != i2));
+ assert(!(i5 != i3));
+ assert(!(i5 != i4));
+ assert(!(i5 != i5));
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::istreambuf_iterator<char> i1;
+ std::istreambuf_iterator<char> i2(std::default_sentinel);
+ assert(i1 == i2);
+
+ assert(!(i1 != std::default_sentinel));
+ assert(!(i2 != std::default_sentinel));
+ assert(!(std::default_sentinel != i1));
+ assert(!(std::default_sentinel != i2));
+
+ std::istringstream stream(" 1 23");
+ std::istreambuf_iterator<char> i3(stream);
+
+ assert(i3 != std::default_sentinel);
+ assert(std::default_sentinel != i3);
+ }
+#endif
+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- {
- std::wistringstream inf1(L"abc");
- std::wistringstream inf2(L"def");
- std::istreambuf_iterator<wchar_t> i1(inf1);
- std::istreambuf_iterator<wchar_t> i2(inf2);
- std::istreambuf_iterator<wchar_t> i3;
- std::istreambuf_iterator<wchar_t> i4;
- std::istreambuf_iterator<wchar_t> i5(nullptr);
-
- assert(!(i1 != i1));
- assert(!(i1 != i2));
- assert( (i1 != i3));
- assert( (i1 != i4));
- assert( (i1 != i5));
-
- assert(!(i2 != i1));
- assert(!(i2 != i2));
- assert( (i2 != i3));
- assert( (i2 != i4));
- assert( (i2 != i5));
-
- assert( (i3 != i1));
- assert( (i3 != i2));
- assert(!(i3 != i3));
- assert(!(i3 != i4));
- assert(!(i3 != i5));
-
- assert( (i4 != i1));
- assert( (i4 != i2));
- assert(!(i4 != i3));
- assert(!(i4 != i4));
- assert(!(i4 != i5));
-
- assert( (i5 != i1));
- assert( (i5 != i2));
- assert(!(i5 != i3));
- assert(!(i5 != i4));
- assert(!(i5 != i5));
- }
+ {
+ std::wistringstream inf1(L"abc");
+ std::wistringstream inf2(L"def");
+ std::istreambuf_iterator<wchar_t> i1(inf1);
+ std::istreambuf_iterator<wchar_t> i2(inf2);
+ std::istreambuf_iterator<wchar_t> i3;
+ std::istreambuf_iterator<wchar_t> i4;
+ std::istreambuf_iterator<wchar_t> i5(nullptr);
+
+ assert(!(i1 != i1));
+ assert(!(i1 != i2));
+ assert( (i1 != i3));
+ assert( (i1 != i4));
+ assert( (i1 != i5));
+
+ assert(!(i2 != i1));
+ assert(!(i2 != i2));
+ assert( (i2 != i3));
+ assert( (i2 != i4));
+ assert( (i2 != i5));
+
+ assert( (i3 != i1));
+ assert( (i3 != i2));
+ assert(!(i3 != i3));
+ assert(!(i3 != i4));
+ assert(!(i3 != i5));
+
+ assert( (i4 != i1));
+ assert( (i4 != i2));
+ assert(!(i4 != i3));
+ assert(!(i4 != i4));
+ assert(!(i4 != i5));
+
+ assert( (i5 != i1));
+ assert( (i5 != i2));
+ assert(!(i5 != i3));
+ assert(!(i5 != i4));
+ assert(!(i5 != i5));
+ }
#endif // TEST_HAS_NO_WIDE_CHARACTERS
return 0;
diff --git a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op==/equal.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op==/equal.pass.cpp
index c0fbf687ef4fb..e0dda2e4c8ab7 100644
--- a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op==/equal.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/istreambuf.iterator_op==/equal.pass.cpp
@@ -13,6 +13,8 @@
// template <class charT, class traits>
// bool operator==(const istreambuf_iterator<charT,traits>& a,
// const istreambuf_iterator<charT,traits>& b);
+//
+// friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s); // since C++20
#include <iterator>
#include <sstream>
@@ -20,87 +22,106 @@
#include "test_macros.h"
-int main(int, char**)
-{
- {
- std::istringstream inf1("abc");
- std::istringstream inf2("def");
- std::istreambuf_iterator<char> i1(inf1);
- std::istreambuf_iterator<char> i2(inf2);
- std::istreambuf_iterator<char> i3;
- std::istreambuf_iterator<char> i4;
- std::istreambuf_iterator<char> i5(nullptr);
-
- assert( (i1 == i1));
- assert( (i1 == i2));
- assert(!(i1 == i3));
- assert(!(i1 == i4));
- assert(!(i1 == i5));
-
- assert( (i2 == i1));
- assert( (i2 == i2));
- assert(!(i2 == i3));
- assert(!(i2 == i4));
- assert(!(i2 == i5));
-
- assert(!(i3 == i1));
- assert(!(i3 == i2));
- assert( (i3 == i3));
- assert( (i3 == i4));
- assert( (i3 == i5));
-
- assert(!(i4 == i1));
- assert(!(i4 == i2));
- assert( (i4 == i3));
- assert( (i4 == i4));
- assert( (i4 == i5));
-
- assert(!(i5 == i1));
- assert(!(i5 == i2));
- assert( (i5 == i3));
- assert( (i5 == i4));
- assert( (i5 == i5));
- }
+int main(int, char**) {
+ {
+ std::istringstream inf1("abc");
+ std::istringstream inf2("def");
+ std::istreambuf_iterator<char> i1(inf1);
+ std::istreambuf_iterator<char> i2(inf2);
+ std::istreambuf_iterator<char> i3;
+ std::istreambuf_iterator<char> i4;
+ std::istreambuf_iterator<char> i5(nullptr);
+
+ assert( (i1 == i1));
+ assert( (i1 == i2));
+ assert(!(i1 == i3));
+ assert(!(i1 == i4));
+ assert(!(i1 == i5));
+
+ assert( (i2 == i1));
+ assert( (i2 == i2));
+ assert(!(i2 == i3));
+ assert(!(i2 == i4));
+ assert(!(i2 == i5));
+
+ assert(!(i3 == i1));
+ assert(!(i3 == i2));
+ assert( (i3 == i3));
+ assert( (i3 == i4));
+ assert( (i3 == i5));
+
+ assert(!(i4 == i1));
+ assert(!(i4 == i2));
+ assert( (i4 == i3));
+ assert( (i4 == i4));
+ assert( (i4 == i5));
+
+ assert(!(i5 == i1));
+ assert(!(i5 == i2));
+ assert( (i5 == i3));
+ assert( (i5 == i4));
+ assert( (i5 == i5));
+ }
+
+#if TEST_STD_VER > 17
+ {
+ std::istreambuf_iterator<char> i1;
+ std::istreambuf_iterator<char> i2(std::default_sentinel);
+ assert(i1 == i2);
+
+ assert(i1 == std::default_sentinel);
+ assert(i2 == std::default_sentinel);
+ assert(std::default_sentinel == i1);
+ assert(std::default_sentinel == i2);
+
+ std::istringstream stream(" 1 23");
+ std::istreambuf_iterator<char> i3(stream);
+
+ assert(!(i3 == std::default_sentinel));
+ assert(!(std::default_sentinel == i3));
+ }
+#endif
+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- {
- std::wistringstream inf1(L"abc");
- std::wistringstream inf2(L"def");
- std::istreambuf_iterator<wchar_t> i1(inf1);
- std::istreambuf_iterator<wchar_t> i2(inf2);
- std::istreambuf_iterator<wchar_t> i3;
- std::istreambuf_iterator<wchar_t> i4;
- std::istreambuf_iterator<wchar_t> i5(nullptr);
-
- assert( (i1 == i1));
- assert( (i1 == i2));
- assert(!(i1 == i3));
- assert(!(i1 == i4));
- assert(!(i1 == i5));
-
- assert( (i2 == i1));
- assert( (i2 == i2));
- assert(!(i2 == i3));
- assert(!(i2 == i4));
- assert(!(i2 == i5));
-
- assert(!(i3 == i1));
- assert(!(i3 == i2));
- assert( (i3 == i3));
- assert( (i3 == i4));
- assert( (i3 == i5));
-
- assert(!(i4 == i1));
- assert(!(i4 == i2));
- assert( (i4 == i3));
- assert( (i4 == i4));
- assert( (i4 == i5));
-
- assert(!(i5 == i1));
- assert(!(i5 == i2));
- assert( (i5 == i3));
- assert( (i5 == i4));
- assert( (i5 == i5));
- }
+ {
+ std::wistringstream inf1(L"abc");
+ std::wistringstream inf2(L"def");
+ std::istreambuf_iterator<wchar_t> i1(inf1);
+ std::istreambuf_iterator<wchar_t> i2(inf2);
+ std::istreambuf_iterator<wchar_t> i3;
+ std::istreambuf_iterator<wchar_t> i4;
+ std::istreambuf_iterator<wchar_t> i5(nullptr);
+
+ assert( (i1 == i1));
+ assert( (i1 == i2));
+ assert(!(i1 == i3));
+ assert(!(i1 == i4));
+ assert(!(i1 == i5));
+
+ assert( (i2 == i1));
+ assert( (i2 == i2));
+ assert(!(i2 == i3));
+ assert(!(i2 == i4));
+ assert(!(i2 == i5));
+
+ assert(!(i3 == i1));
+ assert(!(i3 == i2));
+ assert( (i3 == i3));
+ assert( (i3 == i4));
+ assert( (i3 == i5));
+
+ assert(!(i4 == i1));
+ assert(!(i4 == i2));
+ assert( (i4 == i3));
+ assert( (i4 == i4));
+ assert( (i4 == i5));
+
+ assert(!(i5 == i1));
+ assert(!(i5 == i2));
+ assert( (i5 == i3));
+ assert( (i5 == i4));
+ assert( (i5 == i5));
+ }
#endif // TEST_HAS_NO_WIDE_CHARACTERS
return 0;
More information about the libcxx-commits
mailing list