Skip to content

Commit 222f11f

Browse files
committed
Tests: ospanstream and spanstream constructors + fixes
1 parent afcd8d3 commit 222f11f

File tree

5 files changed

+449
-5
lines changed

5 files changed

+449
-5
lines changed

libcxx/include/spanstream

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ public:
323323
basic_ospanstream(const basic_ospanstream&) = delete;
324324

325325
_LIBCPP_HIDE_FROM_ABI basic_ospanstream(basic_ospanstream&& __rhs)
326-
: basic_iostream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
326+
: basic_ostream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
327327
basic_ostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
328328
}
329329

@@ -344,9 +344,11 @@ public:
344344

345345
// [ospanstream.members], member functions
346346

347-
_LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
347+
_LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept {
348+
return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::addressof(__sb_));
349+
}
348350

349-
_LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept { return __sb_.rdbuf()->span(); }
351+
_LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept { return rdbuf()->span(); }
350352

351353
_LIBCPP_HIDE_FROM_ABI void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
352354

@@ -382,7 +384,7 @@ public:
382384
basic_spanstream(const basic_spanstream&) = delete;
383385

384386
_LIBCPP_HIDE_FROM_ABI basic_spanstream(basic_spanstream&& __rhs)
385-
: basic_iostream<_CharT, _Traits>(std::move(__rhs)), __sb_(__rhs.__sb_) {
387+
: basic_iostream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
386388
basic_iostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
387389
}
388390

@@ -403,7 +405,9 @@ public:
403405

404406
// [spanstream.members], members
405407

406-
_LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
408+
_LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept {
409+
return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::addressof(__sb_));
410+
}
407411

408412
_LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept { return rdbuf()->span(); }
409413

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <spanstream>
12+
13+
// template<class charT, class traits = char_traits<charT>>
14+
// class basic_ospanstream
15+
// : public basic_streambuf<charT, traits> {
16+
17+
// // [spanbuf.cons], constructors
18+
//
19+
// basic_ospanstream(basic_ospanstream&& rhs);
20+
21+
#include <cassert>
22+
#include <concepts>
23+
#include <span>
24+
#include <spanstream>
25+
26+
#include "constexpr_char_traits.h"
27+
#include "test_convertible.h"
28+
#include "test_macros.h"
29+
30+
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
31+
void test() {
32+
using SpStream = std::basic_ospanstream<CharT, TraitsT>;
33+
34+
CharT arr[4];
35+
std::span<CharT> sp{arr};
36+
37+
// Mode: default
38+
{
39+
SpStream rhsSpStream{sp};
40+
SpStream sps(std::move(rhsSpStream));
41+
assert(sps.span().data() == arr);
42+
assert(sps.span().empty());
43+
assert(sps.span().size() == 0);
44+
}
45+
// Mode: `ios_base::in`
46+
{
47+
SpStream rhsSpStream{sp, std::ios_base::in};
48+
SpStream sps(std::move(rhsSpStream));
49+
assert(sps.span().data() == arr);
50+
assert(sps.span().empty());
51+
assert(sps.span().size() == 0);
52+
}
53+
// Mode `ios_base::out`
54+
{
55+
SpStream rhsSpStream{sp, std::ios_base::out};
56+
SpStream sps(std::move(rhsSpStream));
57+
assert(sps.span().data() == arr);
58+
assert(sps.span().empty());
59+
assert(sps.span().size() == 0);
60+
}
61+
// Mode: multiple
62+
{
63+
SpStream rhsSpStream{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
64+
SpStream sps(std::move(rhsSpStream));
65+
assert(sps.span().data() == arr);
66+
assert(sps.span().empty());
67+
assert(sps.span().size() == 0);
68+
}
69+
}
70+
71+
int main(int, char**) {
72+
test<char>();
73+
test<char, constexpr_char_traits<char>>();
74+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
75+
test<wchar_t>();
76+
test<wchar_t, constexpr_char_traits<wchar_t>>();
77+
#endif
78+
79+
return 0;
80+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <spanstream>
12+
13+
// template<class charT, class traits = char_traits<charT>>
14+
// class basic_ospanstream
15+
// : public basic_streambuf<charT, traits> {
16+
17+
// // [spanbuf.cons], constructors
18+
//
19+
// explicit basic_ospanstream(std::span<charT> s,
20+
// ios_base::openmode which = ios_base::in);
21+
22+
#include <cassert>
23+
#include <concepts>
24+
#include <span>
25+
#include <spanstream>
26+
#include <utility>
27+
28+
#include "constexpr_char_traits.h"
29+
#include "nasty_string.h"
30+
#include "test_convertible.h"
31+
#include "test_macros.h"
32+
33+
#include "../../macros.h"
34+
#include "../../types.h"
35+
36+
#ifndef TEST_HAS_NO_NASTY_STRING
37+
void test_sfinae_with_nasty_char() {
38+
using SpStream = std::basic_ospanstream<nasty_char, nasty_char_traits>;
39+
40+
// Mode
41+
static_assert(std::constructible_from<SpStream, const std::span<nasty_char>, std::ios_base::openmode>);
42+
static_assert(!test_convertible<SpStream, std::ios_base::openmode>());
43+
44+
// Non-mode
45+
static_assert(!std::constructible_from<SpStream, const std::span<nasty_char>, const NonMode>);
46+
static_assert(!test_convertible<SpStream, const std::span<nasty_char>, const NonMode>());
47+
}
48+
#endif // TEST_HAS_NO_NASTY_STRING
49+
50+
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
51+
void test_sfinae() {
52+
using SpStream = std::basic_ospanstream<CharT, TraitsT>;
53+
54+
// Mode
55+
static_assert(std::constructible_from<SpStream, const std::span<CharT>, std::ios_base::openmode>);
56+
static_assert(!test_convertible<SpStream, const std::span<CharT>, std::ios_base::openmode>());
57+
58+
// Non-mode
59+
static_assert(!std::constructible_from<SpStream, const std::span<CharT>, const NonMode>);
60+
static_assert(!test_convertible<SpStream, const std::span<CharT>, const NonMode>());
61+
}
62+
63+
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
64+
void test() {
65+
using SpStream = std::basic_ospanstream<CharT, TraitsT>;
66+
67+
CharT arr[4];
68+
std::span<CharT> sp{arr};
69+
70+
// Mode: default
71+
{
72+
SpStream sps(sp);
73+
assert(sps.span().data() == arr);
74+
assert(sps.span().empty());
75+
assert(sps.span().size() == 0);
76+
}
77+
{
78+
SpStream sps(std::as_const(sp));
79+
assert(sps.span().data() == arr);
80+
assert(sps.span().empty());
81+
assert(sps.span().size() == 0);
82+
}
83+
// Mode: `ios_base::in`
84+
{
85+
SpStream sps(sp, std::ios_base::in);
86+
assert(sps.span().data() == arr);
87+
assert(sps.span().empty());
88+
assert(sps.span().size() == 0);
89+
}
90+
{
91+
SpStream sps(std::as_const(sp), std::ios_base::in);
92+
assert(sps.span().data() == arr);
93+
assert(sps.span().empty());
94+
assert(sps.span().size() == 0);
95+
}
96+
// Mode `ios_base::out`
97+
{
98+
SpStream sps(sp, std::ios_base::out);
99+
assert(sps.span().data() == arr);
100+
assert(sps.span().empty());
101+
assert(sps.span().size() == 0);
102+
}
103+
{
104+
SpStream sps(std::as_const(sp), std::ios_base::out);
105+
assert(sps.span().data() == arr);
106+
assert(sps.span().empty());
107+
assert(sps.span().size() == 0);
108+
}
109+
// Mode: multiple
110+
{
111+
SpStream sps(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
112+
assert(sps.span().data() == arr);
113+
assert(sps.span().empty());
114+
assert(sps.span().size() == 0);
115+
}
116+
{
117+
SpStream sps(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
118+
assert(sps.span().data() == arr);
119+
assert(sps.span().empty());
120+
assert(sps.span().size() == 0);
121+
}
122+
}
123+
124+
int main(int, char**) {
125+
#ifndef TEST_HAS_NO_NASTY_STRING
126+
test_sfinae_with_nasty_char();
127+
#endif
128+
test_sfinae<char>();
129+
test_sfinae<char, constexpr_char_traits<char>>();
130+
test<char>();
131+
test<char, constexpr_char_traits<char>>();
132+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
133+
test_sfinae<wchar_t>();
134+
test_sfinae<wchar_t, constexpr_char_traits<wchar_t>>();
135+
test<wchar_t>();
136+
test<wchar_t, constexpr_char_traits<wchar_t>>();
137+
#endif
138+
139+
return 0;
140+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10+
11+
// <spanstream>
12+
13+
// template<class charT, class traits = char_traits<charT>>
14+
// class basic_spanstream
15+
// : public basic_streambuf<charT, traits> {
16+
17+
// // [spanbuf.cons], constructors
18+
//
19+
// basic_spanstream(basic_spanstream&& rhs);
20+
21+
#include <cassert>
22+
#include <concepts>
23+
#include <span>
24+
#include <spanstream>
25+
26+
#include "constexpr_char_traits.h"
27+
#include "test_convertible.h"
28+
#include "test_macros.h"
29+
30+
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
31+
void test() {
32+
using SpStream = std::basic_spanstream<CharT, TraitsT>;
33+
34+
CharT arr[4];
35+
std::span<CharT> sp{arr};
36+
37+
// Mode: default
38+
{
39+
SpStream rhsSpStream{sp};
40+
SpStream sps(std::move(rhsSpStream));
41+
assert(sps.span().data() == arr);
42+
assert(sps.span().empty());
43+
assert(sps.span().size() == 0);
44+
}
45+
// Mode: `ios_base::in`
46+
{
47+
SpStream rhsSpStream{sp, std::ios_base::in};
48+
SpStream sps(std::move(rhsSpStream));
49+
assert(sps.span().data() == arr);
50+
assert(!sps.span().empty());
51+
assert(sps.span().size() == 4);
52+
}
53+
// Mode `ios_base::out`
54+
{
55+
SpStream rhsSpStream{sp, std::ios_base::out};
56+
SpStream sps(std::move(rhsSpStream));
57+
assert(sps.span().data() == arr);
58+
assert(sps.span().empty());
59+
assert(sps.span().size() == 0);
60+
}
61+
// Mode: multiple
62+
{
63+
SpStream rhsSpStream{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
64+
SpStream sps(std::move(rhsSpStream));
65+
assert(sps.span().data() == arr);
66+
assert(sps.span().empty());
67+
assert(sps.span().size() == 0);
68+
}
69+
}
70+
71+
int main(int, char**) {
72+
test<char>();
73+
test<char, constexpr_char_traits<char>>();
74+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
75+
test<wchar_t>();
76+
test<wchar_t, constexpr_char_traits<wchar_t>>();
77+
#endif
78+
79+
return 0;
80+
}

0 commit comments

Comments
 (0)