Skip to content

Commit 65f105b

Browse files
authored
[libc++] Implements LWG3600 Making istream_iterator copy constructor trivial is an ABI break (#127343)
Closes: #105003
1 parent 0751418 commit 65f105b

File tree

4 files changed

+36
-6
lines changed

4 files changed

+36
-6
lines changed

libcxx/docs/Status/Cxx23Issues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@
194194
"`LWG3569 <https://wg21.link/LWG3569>`__","``join_view`` fails to support ranges of ranges with non-default_initializable iterators","2022-11 (Kona)","","",""
195195
"`LWG3594 <https://wg21.link/LWG3594>`__","``inout_ptr`` — inconsistent ``release()`` in destructor","2022-11 (Kona)","|Complete|","19",""
196196
"`LWG3597 <https://wg21.link/LWG3597>`__","Unsigned integer types don't model advanceable","2022-11 (Kona)","","",""
197-
"`LWG3600 <https://wg21.link/LWG3600>`__","Making ``istream_iterator`` copy constructor trivial is an ABI break","2022-11 (Kona)","","",""
197+
"`LWG3600 <https://wg21.link/LWG3600>`__","Making ``istream_iterator`` copy constructor trivial is an ABI break","2022-11 (Kona)","|Nothing To Do|","",""
198198
"`LWG3629 <https://wg21.link/LWG3629>`__","``make_error_code`` and ``make_error_condition`` are customization points","2022-11 (Kona)","|Complete|","16",""
199199
"`LWG3636 <https://wg21.link/LWG3636>`__","``formatter<T>::format`` should be ``const``-qualified","2022-11 (Kona)","|Complete|","16",""
200200
"`LWG3646 <https://wg21.link/LWG3646>`__","``std::ranges::view_interface::size`` returns a signed type","2022-11 (Kona)","|Complete|","16",""

libcxx/include/__iterator/istream_iterator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class _LIBCPP_TEMPLATE_VIS istream_iterator
5858
__in_stream_ = nullptr;
5959
}
6060

61+
// LWG3600 Changed the wording of the copy constructor. In libc++ this constructor
62+
// can still be trivial after this change.
63+
6164
_LIBCPP_HIDE_FROM_ABI const _Tp& operator*() const { return __value_; }
6265
_LIBCPP_HIDE_FROM_ABI const _Tp* operator->() const { return std::addressof((operator*())); }
6366
_LIBCPP_HIDE_FROM_ABI istream_iterator& operator++() {

libcxx/include/iterator

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ public:
530530
istream_iterator(); // constexpr since C++11
531531
constexpr istream_iterator(default_sentinel_t); // since C++20
532532
istream_iterator(istream_type& s);
533-
istream_iterator(const istream_iterator& x);
533+
constexpr istream_iterator(const istream_iterator& x) noexcept(see below);
534534
~istream_iterator();
535535
536536
const T& operator*() const;

libcxx/test/std/iterators/stream.iterators/istream.iterator/istream.iterator.cons/copy.pass.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,45 @@
1010

1111
// class istream_iterator
1212

13-
// istream_iterator(const istream_iterator& x);
14-
// C++17 says: If is_trivially_copy_constructible_v<T> is true, then
15-
// this constructor is a trivial copy constructor.
13+
// istream_iterator(const istream_iterator& x) noexcept(see below);
1614

1715
#include <iterator>
1816
#include <sstream>
1917
#include <cassert>
2018

2119
#include "test_macros.h"
2220

21+
// The copy constructor is constexpr in C++11, but that is not easy to test.
22+
// The comparison of the class is not constexpr so this is only a compile test.
23+
TEST_CONSTEXPR_CXX14 bool test_constexpr() {
24+
std::istream_iterator<int> io;
25+
[[maybe_unused]] std::istream_iterator<int> i = io;
26+
27+
return true;
28+
}
29+
30+
struct thowing_copy_constructor {
31+
thowing_copy_constructor() {}
32+
thowing_copy_constructor(const thowing_copy_constructor&) TEST_NOEXCEPT_FALSE {}
33+
};
34+
2335
int main(int, char**)
2436
{
2537
{
2638
std::istream_iterator<int> io;
2739
std::istream_iterator<int> i = io;
2840
assert(i == std::istream_iterator<int>());
41+
#if TEST_STD_VER >= 11
42+
static_assert(std::is_nothrow_copy_constructible<std::istream_iterator<int>>::value, "");
43+
#endif
44+
}
45+
{
46+
std::istream_iterator<thowing_copy_constructor> io;
47+
std::istream_iterator<thowing_copy_constructor> i = io;
48+
assert(i == std::istream_iterator<thowing_copy_constructor>());
49+
#if TEST_STD_VER >= 11
50+
static_assert(!std::is_nothrow_copy_constructible<std::istream_iterator<thowing_copy_constructor>>::value, "");
51+
#endif
2952
}
3053
{
3154
std::istringstream inf(" 1 23");
@@ -37,5 +60,9 @@ int main(int, char**)
3760
assert(j == 1);
3861
}
3962

40-
return 0;
63+
#if TEST_STD_VER >= 14
64+
static_assert(test_constexpr(), "");
65+
#endif
66+
67+
return 0;
4168
}

0 commit comments

Comments
 (0)