[libcxx-commits] [libcxx] WIP - [libc++][spanstream] P0448R4: A `strstream` replacement using `span<charT>` as buffer (PR #83541)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Mar 13 02:55:05 PDT 2024
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/83541
>From c8d64b067ceed6ee3e7e01313df16e5fa22419f4 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 27 Feb 2024 08:51:49 +0200
Subject: [PATCH 01/39] [libc++][spanstream] P0448R4: A `strstream` replacement
using `span<charT>` as buffer
Implements: P0448R https://wg21.link/P0448R4
- https://eel.is/c++draft/span.streams
- https://eel.is/c++draft/spanbuf
- https://eel.is/c++draft/ispanstream
- https://eel.is/c++draft/ospanstream
- https://eel.is/c++draft/spanstream
---
libcxx/docs/FeatureTestMacroTable.rst | 2 +-
libcxx/docs/ReleaseNotes/19.rst | 1 +
libcxx/docs/Status/Cxx23Papers.csv | 2 +-
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__std_clang_module | 3 +
libcxx/include/module.modulemap | 4 +
libcxx/include/spanstream | 428 ++++++++++++++++++
libcxx/include/version | 2 +-
libcxx/modules/std.compat.cppm.in | 3 -
libcxx/modules/std.cppm.in | 6 +-
.../ispanstream.general/lit.local.cfg | 3 +
.../nothing_to_do.pass.cpp | 15 +
.../ispanstream/types.compile.pass.cpp | 79 ++++
.../ospanstream.general/lit.local.cfg | 3 +
.../nothing_to_do.pass.cpp | 15 +
.../ospanstream/types.compile.pass.cpp | 79 ++++
.../spanbuf/spanbuf.cons/default.pass.cpp | 45 ++
.../spanbuf/spanbuf.general/lit.local.cfg | 3 +
.../spanbuf.general/nothing_to_do.pass.cpp | 15 +
.../spanbuf/types.compile.pass.cpp | 79 ++++
.../spanstream.general/lit.local.cfg | 3 +
.../spanstream.general/nothing_to_do.pass.cpp | 15 +
.../spanstream/types.compile.pass.cpp | 78 ++++
.../spanstream.version.compile.pass.cpp | 68 +++
.../version.version.compile.pass.cpp | 32 +-
.../generate_feature_test_macro_components.py | 1 -
libcxx/utils/libcxx/header_information.py | 3 +-
27 files changed, 955 insertions(+), 33 deletions(-)
create mode 100644 libcxx/include/spanstream
create mode 100644 libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.general/lit.local.cfg
create mode 100644 libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.general/nothing_to_do.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.general/lit.local.cfg
create mode 100644 libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.general/nothing_to_do.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.general/lit.local.cfg
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.general/nothing_to_do.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanstream/spanstream.general/lit.local.cfg
create mode 100644 libcxx/test/std/input.output/span.streams/spanstream/spanstream.general/nothing_to_do.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
create mode 100644 libcxx/test/std/language.support/support.limits/support.limits.general/spanstream.version.compile.pass.cpp
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index b213f430aa5922..c9ccdf7588498a 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -372,7 +372,7 @@ Status
--------------------------------------------------- -----------------
``__cpp_lib_reference_from_temporary`` *unimplemented*
--------------------------------------------------- -----------------
- ``__cpp_lib_spanstream`` *unimplemented*
+ ``__cpp_lib_spanstream`` ``202106L``
--------------------------------------------------- -----------------
``__cpp_lib_stacktrace`` *unimplemented*
--------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index 04f16610f8117e..373aeac26b280c 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -42,6 +42,7 @@ Implemented Papers
- P2652R2 - Disallow User Specialization of ``allocator_traits``
- P2819R2 - Add ``tuple`` protocol to ``complex``
- P2495R3 - Interfacing ``stringstream``\s with ``string_view``
+- P0448R4 - A ``strstream`` replacement using ``span<charT>`` as buffer
- P2302R4 - ``std::ranges::contains``
- P1659R3 - ``std::ranges::starts_with`` and ``std::ranges::ends_with``
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index 56e1468b4ca1a3..576269c15ae6f1 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -12,7 +12,7 @@
"`P2259R1 <https://wg21.link/P2259R1>`__","LWG","Repairing input range adaptors and counted_iterator","February 2021","","","|ranges|"
"","","","","","",""
"`P0401R6 <https://wg21.link/P0401R6>`__","LWG","Providing size feedback in the Allocator interface","June 2021","|Complete|","15.0"
-"`P0448R4 <https://wg21.link/P0448R4>`__","LWG","A strstream replacement using span<charT> as buffer","June 2021","",""
+"`P0448R4 <https://wg21.link/P0448R4>`__","LWG","A ``strstream`` replacement using ``span<charT>`` as buffer","June 2021","|Partial|","19.0"
"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","",""
"`P1328R1 <https://wg21.link/P1328R1>`__","LWG","Making std::type_info::operator== constexpr","June 2021","|Complete|","17.0"
"`P1425R4 <https://wg21.link/P1425R4>`__","LWG","Iterators pair constructors for stack and queue","June 2021","|Complete|","14.0","|ranges|"
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 63adc03fae2980..ddec03901e11d2 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -988,6 +988,7 @@ set(files
shared_mutex
source_location
span
+ spanstream
sstream
stack
stdatomic.h
diff --git a/libcxx/include/__std_clang_module b/libcxx/include/__std_clang_module
index 18d6ce6b46c1f6..f7cefc697c316f 100644
--- a/libcxx/include/__std_clang_module
+++ b/libcxx/include/__std_clang_module
@@ -163,6 +163,9 @@
#include <source_location>
#include <span>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <spanstream>
+#endif
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <sstream>
#endif
#include <stack>
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 0bd2831b7f159c..db584ac680a407 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -233,6 +233,10 @@ module std_span [system] {
export std_version
export std_private_span_span_fwd
}
+module std_spanstream [system] {
+ header "spanstream"
+ export *
+}
module std_sstream [system] {
header "sstream"
export *
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
new file mode 100644
index 00000000000000..f25a04c2cb5254
--- /dev/null
+++ b/libcxx/include/spanstream
@@ -0,0 +1,428 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SPANSTREAM
+#define _LIBCPP_SPANSTREAM
+
+// clang-format off
+
+/*
+ Span-based streams [span.streams]
+
+ template<class charT, class traits = char_traits<charT>>
+ class basic_spanbuf;
+
+ template<class charT, class traits>
+ void swap(basic_spanbuf<charT, traits>& x, basic_spanbuf<charT, traits>& y);
+
+ using spanbuf = basic_spanbuf<char>;
+ using wspanbuf = basic_spanbuf<wchar_t>;
+
+ template<class charT, class traits = char_traits<charT>>
+ class basic_ispanstream;
+
+ template<class charT, class traits>
+ void swap(basic_ispanstream<charT, traits>& x, basic_ispanstream<charT, traits>& y);
+
+ using ispanstream = basic_ispanstream<char>;
+ using wispanstream = basic_ispanstream<wchar_t>;
+
+ template<class charT, class traits = char_traits<charT>>
+ class basic_ospanstream;
+
+ template<class charT, class traits>
+ void swap(basic_ospanstream<charT, traits>& x, basic_ospanstream<charT, traits>& y);
+
+ using ospanstream = basic_ospanstream<char>;
+ using wospanstream = basic_ospanstream<wchar_t>;
+
+ template<class charT, class traits = char_traits<charT>>
+ class basic_spanstream;
+
+ template<class charT, class traits>
+ void swap(basic_spanstream<charT, traits>& x, basic_spanstream<charT, traits>& y);
+
+ using spanstream = basic_spanstream<char>;
+ using wspanstream = basic_spanstream<wchar_t>;
+*/
+
+// clang-format on
+
+#include <__assert> // all public C++ headers provide the assertion handler
+#include <__availability>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__ranges/concepts.h>
+#include <__utility/cmp.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <__utility/swap.h>
+#include <iostream>
+#include <span>
+#include <streambuf>
+#include <version>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+// Class template basic_spanbuf [spanbuf]
+
+template <class _CharT, class _Traits = char_traits<_CharT>>
+class _LIBCPP_TEMPLATE_VIS basic_spanbuf : public basic_streambuf<_CharT, _Traits> {
+public:
+ using char_type = _CharT;
+ using int_type = typename _Traits::int_type;
+ using pos_type = typename _Traits::pos_type;
+ using off_type = typename _Traits::off_type;
+ using traits_type = _Traits;
+
+ // [spanbuf.cons], constructors
+
+ _LIBCPP_HIDE_FROM_ABI basic_spanbuf() : basic_spanbuf(ios_base::in | ios_base::out) {}
+
+ _LIBCPP_HIDE_FROM_ABI explicit basic_spanbuf(ios_base::openmode __which)
+ : basic_spanbuf(std::span<_CharT>(), __which) {}
+
+ _LIBCPP_HIDE_FROM_ABI explicit basic_spanbuf(std::span<_CharT> __s,
+ ios_base::openmode __which = ios_base::in | ios_base::out)
+ : basic_streambuf<_CharT, _Traits>{}, __mode_{__which}, __buf_{__s} {
+ this->span(__s);
+ }
+
+ basic_spanbuf(const basic_spanbuf&) = delete;
+ _LIBCPP_HIDE_FROM_ABI basic_spanbuf(basic_spanbuf&& __rhs)
+ : basic_streambuf<_CharT, _Traits>{std::move(__rhs)},
+ __mode_{std::move(__rhs.__mode_)},
+ __buf_{std::move(__rhs.__buf_)} {}
+
+ // [spanbuf.assign], assignment and swap
+
+ basic_spanbuf& operator=(const basic_spanbuf&) = delete;
+ _LIBCPP_HIDE_FROM_ABI basic_spanbuf& operator=(basic_spanbuf&& __rhs) {
+ basic_spanbuf __tmp{std::move(__rhs)};
+ this->swap(__tmp);
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI void swap(basic_spanbuf& __rhs) {
+ basic_streambuf<_CharT, _Traits>::swap(__rhs);
+ std::swap(__mode_, __rhs.__mode_);
+ std::swap(__buf_, __rhs.__buf_);
+ }
+
+ // [spanbuf.members], member functions
+
+ _LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept {
+ if (__mode_ & ios_base::out) {
+ return std::span<_CharT>(this->pbase(), this->pptr());
+ }
+ return __buf_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI void span(std::span<_CharT> __s) noexcept {
+ __buf_ = __s;
+
+ if (__mode_ & ios_base::out) {
+ this->setp(__s.data(), __s.data() + __s.size());
+ if (__mode_ & ios_base::ate) {
+ this->pbump(__s.size());
+ }
+ }
+
+ if (__mode_ & ios_base::in) {
+ this->setg(__s.data(), __s.data(), __s.data() + __s.size());
+ }
+ }
+
+protected:
+ // [spanbuf.virtuals], overridden virtual functions
+
+ _LIBCPP_HIDE_FROM_ABI basic_streambuf<_CharT, _Traits>* setbuf(_CharT* __s, streamsize __n) override {
+ this->span(std::span<_CharT>(__s, __n));
+ return this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI pos_type
+ seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which = ios_base::in | ios_base::out) override {
+ const pos_type __error(off_type(-1));
+
+ if ((__which & ios_base::in) && (__which & ios_base::out) && (ios_base::cur == __way))
+ return __error;
+
+ off_type __baseoff = [this, __way, __which] {
+ switch (__way) {
+ case ios_base::beg:
+ return off_type(0);
+
+ case ios_base::cur:
+ if (__which & ios_base::out)
+ return off_type(this->pptr() - this->pbase());
+ return off_type(this->gptr() - this->eback());
+
+ case ios_base::end:
+ if ((__which & ios_base::out) && !(__which & ios_base::in))
+ return off_type(this->pptr() - this->pbase());
+ return off_type(__buf_.size());
+ }
+ }();
+
+ off_type __newoff;
+ if (__builtin_add_overflow(__baseoff, __off, &__newoff) || (__newoff < off_type(0)) ||
+ (std::cmp_greater(__newoff, __buf_.size())))
+ return __error;
+
+ if (__which & ios_base::in) {
+ if ((this->gptr() == nullptr) && (__newoff != off_type(0)))
+ return __error;
+ this->setg(this->eback(), this->eback() + __newoff, this->egptr());
+ }
+
+ if (__which & ios_base::out) {
+ if ((this->pptr() == nullptr) && (__newoff != off_type(0)))
+ return __error;
+ this->setp(this->pbase(), this->epptr());
+ this->pbump(__newoff);
+ }
+
+ return pos_type(__newoff);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI pos_type seekpos(pos_type __sp,
+ ios_base::openmode __which = ios_base::in | ios_base::out) override {
+ return seekoff(off_type(__sp), ios_base::beg, __which);
+ }
+
+private:
+ ios_base::openmode __mode_; // exposition only
+ std::span<_CharT> __buf_; // exposition only
+};
+
+template <class _CharT, class _Traits>
+void swap(basic_spanbuf<_CharT, _Traits>& __x, basic_spanbuf<_CharT, _Traits>& __y) {
+ __x.swap(__y);
+}
+
+using spanbuf = basic_spanbuf<char>;
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wspanbuf = basic_spanbuf<wchar_t>;
+# endif
+
+// Class template basic_ispanstream [ispanstream]
+
+template <class _CharT, class _Traits = char_traits<_CharT>>
+class basic_ispanstream : public basic_istream<_CharT, _Traits> {
+public:
+ using char_type = _CharT;
+ using int_type = typename _Traits::int_type;
+ using pos_type = typename _Traits::pos_type;
+ using off_type = typename _Traits::off_type;
+ using traits_type = _Traits;
+
+ // [ispanstream.cons], constructors
+
+ explicit basic_ispanstream(std::span<_CharT> __s, ios_base::openmode __which = ios_base::in)
+ : basic_istream<_CharT, _Traits>(std::addressof(__sb_)),
+ __sb_(basic_spanbuf<_CharT, _Traits>(__s, __which | ios_base::in)) {}
+
+ basic_ispanstream(const basic_ispanstream&) = delete;
+
+ basic_ispanstream(basic_ispanstream&& __rhs)
+ : basic_istream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
+ basic_istream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
+ }
+
+ template <ranges::borrowed_range _ROSeq>
+ requires(!convertible_to<_ROSeq, std::span<_CharT>>) && convertible_to<_ROSeq, std::span<const _CharT>>
+ explicit basic_ispanstream(_ROSeq&& __s) : basic_istream<_CharT, _Traits>(std::addressof(__sb_)) {
+ std::span<const _CharT> __sp(std::forward<_ROSeq>(__s));
+ this->span(std::span<_CharT>(std::span<_CharT>(const_cast<_CharT*>(__sp.data()), __sp.size())));
+ }
+
+ basic_ispanstream& operator=(const basic_ispanstream&) = delete;
+
+ basic_ispanstream& operator=(basic_ispanstream&& __rhs) {
+ basic_ispanstream __tmp{std::move(__rhs)};
+ this->swap(__tmp);
+ return *this;
+ }
+
+ // [ispanstream.swap], swap
+
+ void swap(basic_ispanstream& __rhs) {
+ basic_istream<_CharT, _Traits>::swap(__rhs);
+ __sb_.swap(__rhs.__sb_);
+ }
+
+ // [ispanstream.members], member functions
+
+ basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept {
+ return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::addressof(__sb_));
+ }
+
+ std::span<const _CharT> span() const noexcept { return rdbuf()->span(); }
+
+ void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
+
+ template <ranges::borrowed_range _ROSeq>
+ requires(!convertible_to<_ROSeq, std::span<_CharT>>) && convertible_to<_ROSeq, std::span<const _CharT>>
+ void span(_ROSeq&& __s) noexcept {
+ std::span<const _CharT> __sp(std::forward<_ROSeq>(__s));
+ this->span(std::span<_CharT>(const_cast<_CharT*>(__sp.data()), __sp.size()));
+ }
+
+private:
+ basic_spanbuf<_CharT, _Traits> __sb_; // exposition only
+};
+
+template <class _CharT, class _Traits>
+void swap(basic_ispanstream<_CharT, _Traits>& __x, basic_ispanstream<_CharT, _Traits>& __y) {
+ __x.swap(__y);
+}
+
+using ispanstream = basic_ispanstream<char>;
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wispanstream = basic_ispanstream<wchar_t>;
+# endif
+
+// Class template basic_ospanstream [ospanstream]
+
+template <class _CharT, class _Traits = char_traits<_CharT>>
+class basic_ospanstream : public basic_ostream<_CharT, _Traits> {
+public:
+ using char_type = _CharT;
+ using int_type = typename _Traits::int_type;
+ using pos_type = typename _Traits::pos_type;
+ using off_type = typename _Traits::off_type;
+ using traits_type = _Traits;
+
+ // [ospanstream.cons], constructors
+
+ explicit basic_ospanstream(std::span<_CharT> __s, ios_base::openmode __which = ios_base::out)
+ : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)),
+ __sb_(basic_spanbuf<_CharT, _Traits>(__s, __which | ios_base::out)) {}
+
+ basic_ospanstream(const basic_ospanstream&) = delete;
+
+ basic_ospanstream(basic_ospanstream&& __rhs) : basic_ospanstream(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
+ basic_ostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
+ }
+
+ basic_ospanstream& operator=(const basic_ospanstream&) = delete;
+
+ basic_ospanstream& operator=(basic_ospanstream&& __rhs) {
+ basic_ospanstream __tmp{std::move(__rhs)};
+ this->swap(__tmp);
+ return *this;
+ }
+
+ // [ospanstream.swap], swap
+
+ void swap(basic_ospanstream& __rhs) {
+ basic_ostream<_CharT, _Traits>::swap(__rhs);
+ __sb_.swap(__rhs.__sb_);
+ }
+
+ // [ospanstream.members], member functions
+
+ basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
+
+ std::span<_CharT> span() const noexcept { return __sb_.rdbuf()->span(); }
+
+ void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
+
+private:
+ basic_spanbuf<_CharT, _Traits> __sb_; // exposition only
+};
+
+template <class _CharT, class _Traits>
+void swap(basic_ospanstream<_CharT, _Traits>& __x, basic_ospanstream<_CharT, _Traits>& __y) {
+ __x.swap(__y);
+}
+
+using ospanstream = basic_ospanstream<char>;
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wospanstream = basic_ospanstream<wchar_t>;
+# endif
+
+template <class _CharT, class _Traits = char_traits<_CharT>>
+class basic_spanstream : public basic_iostream<_CharT, _Traits> {
+public:
+ using char_type = _CharT;
+ using int_type = typename _Traits::int_type;
+ using pos_type = typename _Traits::pos_type;
+ using off_type = typename _Traits::off_type;
+ using traits_type = _Traits;
+
+ // [spanstream.cons], constructors
+
+ explicit basic_spanstream(std::span<_CharT> __s, ios_base::openmode __which = ios_base::out | ios_base::in)
+ : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(basic_spanbuf<_CharT, _Traits>(__s, __which)) {}
+
+ basic_spanstream(const basic_spanstream&) = delete;
+
+ basic_spanstream(basic_spanstream&& __rhs) : basic_spanstream(std::move(__rhs)), __sb_(__rhs.__sb_) {
+ basic_iostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
+ }
+
+ basic_spanstream& operator=(const basic_spanstream&) = delete;
+
+ basic_spanstream& operator=(basic_spanstream&& __rhs) {
+ basic_spanstream __tmp{std::move(__rhs)};
+ this->swap(__tmp);
+ return *this;
+ }
+
+ // [spanstream.swap], swap
+
+ void swap(basic_spanstream& __rhs) {
+ basic_iostream<_CharT, _Traits>::swap(__rhs);
+ __sb_.swap(__rhs.__sb_);
+ }
+
+ // [spanstream.members], members
+
+ basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
+
+ std::span<_CharT> span() const noexcept { return rdbuf()->span(); }
+
+ void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
+
+private:
+ basic_spanbuf<_CharT, _Traits> __sb_; // exposition only
+};
+
+template <class _CharT, class _Traits>
+void swap(basic_spanstream<_CharT, _Traits>& __x, basic_spanstream<_CharT, _Traits>& __y) {
+ __x.swap(__y);
+}
+
+using spanstream = basic_spanstream<char>;
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wspanstream = basic_spanstream<wchar_t>;
+# endif
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#if _LIBCPP_STD_VER <= 20 && !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
+# include <type_traits>
+#endif
+
+#endif // _LIBCPP_SPANSTREAM
diff --git a/libcxx/include/version b/libcxx/include/version
index 3bd296e34aa4e3..d5bda9cca32501 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -473,7 +473,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
# define __cpp_lib_ranges_to_container 202202L
// # define __cpp_lib_ranges_zip 202110L
// # define __cpp_lib_reference_from_temporary 202202L
-// # define __cpp_lib_spanstream 202106L
+# define __cpp_lib_spanstream 202106L
// # define __cpp_lib_stacktrace 202011L
# define __cpp_lib_stdatomic_h 202011L
# define __cpp_lib_string_contains 202011L
diff --git a/libcxx/modules/std.compat.cppm.in b/libcxx/modules/std.compat.cppm.in
index b44dbab25c74b4..80e6b254905ec1 100644
--- a/libcxx/modules/std.compat.cppm.in
+++ b/libcxx/modules/std.compat.cppm.in
@@ -75,9 +75,6 @@ module;
# if __has_include(<rcu>)
# error "please update the header information for <rcu> in headers_not_available in utils/libcxx/header_information.py"
# endif // __has_include(<rcu>)
-# if __has_include(<spanstream>)
-# error "please update the header information for <spanstream> in headers_not_available in utils/libcxx/header_information.py"
-# endif // __has_include(<spanstream>)
# if __has_include(<stacktrace>)
# error "please update the header information for <stacktrace> in headers_not_available in utils/libcxx/header_information.py"
# endif // __has_include(<stacktrace>)
diff --git a/libcxx/modules/std.cppm.in b/libcxx/modules/std.cppm.in
index b8d89130aae989..d53d666c8de5c4 100644
--- a/libcxx/modules/std.cppm.in
+++ b/libcxx/modules/std.cppm.in
@@ -133,6 +133,9 @@ module;
#include <source_location>
#include <span>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <spanstream>
+#endif
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <sstream>
#endif
#include <stack>
@@ -197,9 +200,6 @@ module;
# if __has_include(<rcu>)
# error "please update the header information for <rcu> in headers_not_available in utils/libcxx/header_information.py"
# endif // __has_include(<rcu>)
-# if __has_include(<spanstream>)
-# error "please update the header information for <spanstream> in headers_not_available in utils/libcxx/header_information.py"
-# endif // __has_include(<spanstream>)
# if __has_include(<stacktrace>)
# error "please update the header information for <stacktrace> in headers_not_available in utils/libcxx/header_information.py"
# endif // __has_include(<stacktrace>)
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.general/lit.local.cfg b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.general/lit.local.cfg
new file mode 100644
index 00000000000000..2cb10010c45072
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.general/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if "no-localization" in config.available_features:
+ config.unsupported = True
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.general/nothing_to_do.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.general/nothing_to_do.pass.cpp
new file mode 100644
index 00000000000000..4a307014fa0f72
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.general/nothing_to_do.pass.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// [ispanstream.general]
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
new file mode 100644
index 00000000000000..773efffd61a39c
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_ispanstream
+// : public basic_istream<charT, traits> {
+// public:
+// using char_type = charT;
+// using int_type = typename traits::int_type;
+// using pos_type = typename traits::pos_type;
+// using off_type = typename traits::off_type;
+// using traits_type = traits;
+
+// using ispanstream = basic_ispanstream<char>;
+// using wispanstream = basic_ispanstream<wchar_t>;
+
+#include <spanstream>
+#include <string>
+#include <type_traits>
+
+#include "test_macros.h"
+
+// Types
+
+static_assert(std::is_base_of_v<std::basic_istream<char>, std::ispanstream>);
+static_assert(std::is_same_v<std::ispanstream::char_type, char>);
+static_assert(std::is_same_v<std::ispanstream::int_type, std::char_traits<char>::int_type>);
+static_assert(std::is_same_v<std::ispanstream::pos_type, std::char_traits<char>::pos_type>);
+static_assert(std::is_same_v<std::ispanstream::off_type, std::char_traits<char>::off_type>);
+static_assert(std::is_same_v<std::ispanstream::traits_type, std::char_traits<char>>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::is_base_of_v<std::basic_istream<wchar_t>, std::wispanstream>);
+static_assert(std::is_same_v<std::wispanstream::char_type, wchar_t>);
+static_assert(std::is_same_v<std::wispanstream::int_type, std::char_traits<wchar_t>::int_type>);
+static_assert(std::is_same_v<std::wispanstream::pos_type, std::char_traits<wchar_t>::pos_type>);
+static_assert(std::is_same_v<std::wispanstream::off_type, std::char_traits<wchar_t>::off_type>);
+static_assert(std::is_same_v<std::wispanstream::traits_type, std::char_traits<wchar_t>>);
+#endif
+
+// Copy properties
+
+static_assert(!std::is_copy_constructible_v<std::ispanstream>);
+static_assert(!std::is_copy_assignable_v<std::ispanstream>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::is_copy_constructible_v<std::wispanstream>);
+static_assert(!std::is_copy_assignable_v<std::wispanstream>);
+#endif
+
+// Move properties
+
+static_assert(!std::is_copy_constructible_v<std::ispanstream>);
+static_assert(!std::is_copy_assignable_v<std::ispanstream>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::is_copy_constructible_v<std::wispanstream>);
+static_assert(!std::is_copy_assignable_v<std::wispanstream>);
+#endif
+
+// Move properties
+
+static_assert(std::is_move_constructible_v<std::ispanstream>);
+static_assert(std::is_move_assignable_v<std::ispanstream>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::is_move_constructible_v<std::wispanstream>);
+static_assert(std::is_move_assignable_v<std::wispanstream>);
+#endif
+
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.general/lit.local.cfg b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.general/lit.local.cfg
new file mode 100644
index 00000000000000..2cb10010c45072
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.general/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if "no-localization" in config.available_features:
+ config.unsupported = True
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.general/nothing_to_do.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.general/nothing_to_do.pass.cpp
new file mode 100644
index 00000000000000..6f9497040a8977
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.general/nothing_to_do.pass.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// [ospanstream.general]
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
new file mode 100644
index 00000000000000..ab0cac07168407
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_ospanstream
+// : public basic_ostream<charT, traits> {
+// public:
+// using char_type = charT;
+// using int_type = typename traits::int_type;
+// using pos_type = typename traits::pos_type;
+// using off_type = typename traits::off_type;
+// using traits_type = traits;
+
+// using ospanstream = basic_ospanstream<char>;
+// using wospanstream = basic_ospanstream<wchar_t>;
+
+#include <spanstream>
+#include <string>
+#include <type_traits>
+
+#include "test_macros.h"
+
+// Types
+
+static_assert(std::is_base_of_v<std::basic_ostream<char>, std::ospanstream>);
+static_assert(std::is_same_v<std::ospanstream::char_type, char>);
+static_assert(std::is_same_v<std::ospanstream::int_type, std::char_traits<char>::int_type>);
+static_assert(std::is_same_v<std::ospanstream::pos_type, std::char_traits<char>::pos_type>);
+static_assert(std::is_same_v<std::ospanstream::off_type, std::char_traits<char>::off_type>);
+static_assert(std::is_same_v<std::ospanstream::traits_type, std::char_traits<char>>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::is_base_of_v<std::basic_ostream<wchar_t>, std::wospanstream>);
+static_assert(std::is_same_v<std::wospanstream::char_type, wchar_t>);
+static_assert(std::is_same_v<std::wospanstream::int_type, std::char_traits<wchar_t>::int_type>);
+static_assert(std::is_same_v<std::wospanstream::pos_type, std::char_traits<wchar_t>::pos_type>);
+static_assert(std::is_same_v<std::wospanstream::off_type, std::char_traits<wchar_t>::off_type>);
+static_assert(std::is_same_v<std::wospanstream::traits_type, std::char_traits<wchar_t>>);
+#endif
+
+// Copy properties
+
+static_assert(!std::is_copy_constructible_v<std::ospanstream>);
+static_assert(!std::is_copy_assignable_v<std::ospanstream>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::is_copy_constructible_v<std::wospanstream>);
+static_assert(!std::is_copy_assignable_v<std::wospanstream>);
+#endif
+
+// Move properties
+
+static_assert(!std::is_copy_constructible_v<std::ospanstream>);
+static_assert(!std::is_copy_assignable_v<std::ospanstream>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::is_copy_constructible_v<std::wospanstream>);
+static_assert(!std::is_copy_assignable_v<std::wospanstream>);
+#endif
+
+// Move properties
+
+static_assert(std::is_move_constructible_v<std::ospanstream>);
+static_assert(std::is_move_assignable_v<std::ospanstream>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::is_move_constructible_v<std::wospanstream>);
+static_assert(std::is_move_assignable_v<std::wospanstream>);
+#endif
+
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
new file mode 100644
index 00000000000000..4675c0e5fc2990
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+// basic_spanbuf();
+
+#include <cassert>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_macros.h"
+
+template <typename CharT, typename Traits = std::char_traits<CharT>>
+void test() {
+ using SpanBuf = std::basic_spanbuf<CharT, Traits>;
+
+ static_assert(std::default_initializable<SpanBuf>);
+
+ SpanBuf spBuf;
+ assert(spBuf.span().empty());
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.general/lit.local.cfg b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.general/lit.local.cfg
new file mode 100644
index 00000000000000..2cb10010c45072
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.general/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if "no-localization" in config.available_features:
+ config.unsupported = True
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.general/nothing_to_do.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.general/nothing_to_do.pass.cpp
new file mode 100644
index 00000000000000..fc746f4af7c762
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.general/nothing_to_do.pass.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// [spanbuf.general]
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
new file mode 100644
index 00000000000000..4585147ea8d2e7
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_streambuf<charT, traits> {
+// public:
+// using char_type = charT;
+// using int_type = typename traits::int_type;
+// using pos_type = typename traits::pos_type;
+// using off_type = typename traits::off_type;
+// using traits_type = traits;
+
+// using spanbuf = basic_spanbufchar>;
+// using wspanbuf = basic_spanbuf<wchar_t>;
+
+#include <spanstream>
+#include <string>
+#include <type_traits>
+
+#include "test_macros.h"
+
+// Types
+
+static_assert(std::is_base_of_v<std::basic_streambuf<char>, std::spanbuf>);
+static_assert(std::is_same_v<std::spanbuf::char_type, char>);
+static_assert(std::is_same_v<std::spanbuf::int_type, std::char_traits<char>::int_type>);
+static_assert(std::is_same_v<std::spanbuf::pos_type, std::char_traits<char>::pos_type>);
+static_assert(std::is_same_v<std::spanbuf::off_type, std::char_traits<char>::off_type>);
+static_assert(std::is_same_v<std::spanbuf::traits_type, std::char_traits<char>>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::is_base_of_v<std::basic_streambuf<wchar_t>, std::wspanbuf>);
+static_assert(std::is_same_v<std::wspanbuf::char_type, wchar_t>);
+static_assert(std::is_same_v<std::wspanbuf::int_type, std::char_traits<wchar_t>::int_type>);
+static_assert(std::is_same_v<std::wspanbuf::pos_type, std::char_traits<wchar_t>::pos_type>);
+static_assert(std::is_same_v<std::wspanbuf::off_type, std::char_traits<wchar_t>::off_type>);
+static_assert(std::is_same_v<std::wspanbuf::traits_type, std::char_traits<wchar_t>>);
+#endif
+
+// Copy properties
+
+static_assert(!std::is_copy_constructible_v<std::spanbuf>);
+static_assert(!std::is_copy_assignable_v<std::spanbuf>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::is_copy_constructible_v<std::wspanbuf>);
+static_assert(!std::is_copy_assignable_v<std::wspanbuf>);
+#endif
+
+// Move properties
+
+static_assert(!std::is_copy_constructible_v<std::spanbuf>);
+static_assert(!std::is_copy_assignable_v<std::spanbuf>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::is_copy_constructible_v<std::wspanbuf>);
+static_assert(!std::is_copy_assignable_v<std::wspanbuf>);
+#endif
+
+// Move properties
+
+static_assert(std::is_move_constructible_v<std::spanbuf>);
+static_assert(std::is_move_assignable_v<std::spanbuf>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::is_move_constructible_v<std::wspanbuf>);
+static_assert(std::is_move_assignable_v<std::wspanbuf>);
+#endif
+
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.general/lit.local.cfg b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.general/lit.local.cfg
new file mode 100644
index 00000000000000..2cb10010c45072
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.general/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if "no-localization" in config.available_features:
+ config.unsupported = True
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.general/nothing_to_do.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.general/nothing_to_do.pass.cpp
new file mode 100644
index 00000000000000..8677bb6d0906d3
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.general/nothing_to_do.pass.cpp
@@ -0,0 +1,15 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// [spanstream.general]
+
+int main(int, char**) { return 0; }
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
new file mode 100644
index 00000000000000..4e90f259ccf488
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanstream
+// : public basic_iostream<charT, traits> {
+// public:
+// using char_type = charT;
+// using int_type = typename traits::int_type;
+// using pos_type = typename traits::pos_type;
+// using off_type = typename traits::off_type;
+// using traits_type = traits;
+
+// using spanstream = basic_spanstream<char>;
+// using wspanstream = basic_spanstream<wchar_t>;
+
+#include <spanstream>
+#include <string>
+#include <type_traits>
+
+#include "test_macros.h"
+
+// Types
+
+static_assert(std::is_base_of_v<std::basic_iostream<char>, std::spanstream>);
+static_assert(std::is_same_v<std::spanstream::char_type, char>);
+static_assert(std::is_same_v<std::spanstream::int_type, std::char_traits<char>::int_type>);
+static_assert(std::is_same_v<std::spanstream::pos_type, std::char_traits<char>::pos_type>);
+static_assert(std::is_same_v<std::spanstream::off_type, std::char_traits<char>::off_type>);
+static_assert(std::is_same_v<std::spanstream::traits_type, std::char_traits<char>>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::is_base_of_v<std::basic_iostream<wchar_t>, std::wspanstream>);
+static_assert(std::is_same_v<std::wspanstream::char_type, wchar_t>);
+static_assert(std::is_same_v<std::wspanstream::int_type, std::char_traits<wchar_t>::int_type>);
+static_assert(std::is_same_v<std::wspanstream::pos_type, std::char_traits<wchar_t>::pos_type>);
+static_assert(std::is_same_v<std::wspanstream::off_type, std::char_traits<wchar_t>::off_type>);
+static_assert(std::is_same_v<std::wspanstream::traits_type, std::char_traits<wchar_t>>);
+#endif
+
+// Copy properties
+
+static_assert(!std::is_copy_constructible_v<std::spanstream>);
+static_assert(!std::is_copy_assignable_v<std::spanstream>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::is_copy_constructible_v<std::wspanstream>);
+static_assert(!std::is_copy_assignable_v<std::wspanstream>);
+#endif
+
+// Move properties
+
+static_assert(!std::is_copy_constructible_v<std::spanstream>);
+static_assert(!std::is_copy_assignable_v<std::spanstream>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(!std::is_copy_constructible_v<std::wspanstream>);
+static_assert(!std::is_copy_assignable_v<std::wspanstream>);
+#endif
+
+// Move properties
+
+static_assert(std::is_move_constructible_v<std::spanstream>);
+static_assert(std::is_move_assignable_v<std::spanstream>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::is_move_constructible_v<std::wspanstream>);
+static_assert(std::is_move_assignable_v<std::wspanstream>);
+#endif
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/spanstream.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/spanstream.version.compile.pass.cpp
new file mode 100644
index 00000000000000..8719352d4367e3
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/spanstream.version.compile.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <spanstream>
+
+// Test the feature test macros defined by <spanstream>
+
+/* Constant Value
+ __cpp_lib_spanstream 202106L [C++23]
+*/
+
+#include <spanstream>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_spanstream
+# error "__cpp_lib_spanstream should not be defined before c++23"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_spanstream
+# error "__cpp_lib_spanstream should not be defined before c++23"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_spanstream
+# error "__cpp_lib_spanstream should not be defined before c++23"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifdef __cpp_lib_spanstream
+# error "__cpp_lib_spanstream should not be defined before c++23"
+# endif
+
+#elif TEST_STD_VER == 23
+
+# ifndef __cpp_lib_spanstream
+# error "__cpp_lib_spanstream should be defined in c++23"
+# endif
+# if __cpp_lib_spanstream != 202106L
+# error "__cpp_lib_spanstream should have the value 202106L in c++23"
+# endif
+
+#elif TEST_STD_VER > 23
+
+# ifndef __cpp_lib_spanstream
+# error "__cpp_lib_spanstream should be defined in c++26"
+# endif
+# if __cpp_lib_spanstream != 202106L
+# error "__cpp_lib_spanstream should have the value 202106L in c++26"
+# endif
+
+#endif // TEST_STD_VER > 23
+
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 5501587915ffa0..a09396245d3ef4 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -5626,17 +5626,11 @@
# error "__cpp_lib_span_initializer_list should not be defined before c++26"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_spanstream
-# error "__cpp_lib_spanstream should be defined in c++23"
-# endif
-# if __cpp_lib_spanstream != 202106L
-# error "__cpp_lib_spanstream should have the value 202106L in c++23"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_spanstream
-# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_spanstream
+# error "__cpp_lib_spanstream should be defined in c++23"
+# endif
+# if __cpp_lib_spanstream != 202106L
+# error "__cpp_lib_spanstream should have the value 202106L in c++23"
# endif
# ifndef __cpp_lib_ssize
@@ -7374,17 +7368,11 @@
# error "__cpp_lib_span_initializer_list should have the value 202311L in c++26"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_spanstream
-# error "__cpp_lib_spanstream should be defined in c++26"
-# endif
-# if __cpp_lib_spanstream != 202106L
-# error "__cpp_lib_spanstream should have the value 202106L in c++26"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_spanstream
-# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_spanstream
+# error "__cpp_lib_spanstream should be defined in c++26"
+# endif
+# if __cpp_lib_spanstream != 202106L
+# error "__cpp_lib_spanstream should have the value 202106L in c++26"
# endif
# ifndef __cpp_lib_ssize
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index c55f5c7d19004a..69bca109fca195 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1105,7 +1105,6 @@ def add_version_header(tc):
"name": "__cpp_lib_spanstream",
"values": {"c++23": 202106},
"headers": ["spanstream"],
- "unimplemented": True,
},
{
"name": "__cpp_lib_ssize",
diff --git a/libcxx/utils/libcxx/header_information.py b/libcxx/utils/libcxx/header_information.py
index bccae353b0c6bd..62ae499be91421 100644
--- a/libcxx/utils/libcxx/header_information.py
+++ b/libcxx/utils/libcxx/header_information.py
@@ -26,6 +26,7 @@
"locale": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
"ostream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
"regex": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
+ "spanstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
"sstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
"streambuf": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
"strstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
@@ -76,6 +77,7 @@
"regex": "// UNSUPPORTED: no-localization",
"semaphore": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17",
"shared_mutex": "// UNSUPPORTED: no-threads, c++03, c++11",
+ "spanstream": "// UNSUPPORTED: no-localization",
"sstream": "// UNSUPPORTED: no-localization",
"stdatomic.h": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17, c++20",
"stop_token": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17",
@@ -145,7 +147,6 @@
"hazard_pointer",
"linalg",
"rcu",
- "spanstream",
"stacktrace",
"stdfloat",
"text_encoding",
>From 3a52474da6d09332181c18aeff2557d36a9d130e Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 28 Feb 2024 18:30:36 +0200
Subject: [PATCH 02/39] Added forward declarations to `<iosfwd>`
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__fwd/spanstream.h | 48 +++++++++++++++++++++++++++++++
libcxx/include/iosfwd | 20 +++++++++++++
libcxx/include/libcxx.imp | 1 +
libcxx/include/module.modulemap | 15 +++++-----
libcxx/include/spanstream | 15 +++++-----
6 files changed, 86 insertions(+), 14 deletions(-)
create mode 100644 libcxx/include/__fwd/spanstream.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index ddec03901e11d2..6a5995b9eae40c 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -439,6 +439,7 @@ set(files
__fwd/ostream.h
__fwd/pair.h
__fwd/span.h
+ __fwd/spanstream.h
__fwd/sstream.h
__fwd/streambuf.h
__fwd/string.h
diff --git a/libcxx/include/__fwd/spanstream.h b/libcxx/include/__fwd/spanstream.h
new file mode 100644
index 00000000000000..2afeaaecf7fb4d
--- /dev/null
+++ b/libcxx/include/__fwd/spanstream.h
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FWD_SPANSTREAM_H
+#define _LIBCPP___FWD_SPANSTREAM_H
+
+#include <__config>
+#include <__fwd/string.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+template <class _CharT, class traits = char_traits<_CharT>>
+class _LIBCPP_TEMPLATE_VIS basic_spanbuf;
+template <class _CharT, class traits = char_traits<_CharT>>
+class _LIBCPP_TEMPLATE_VIS basic_ispanstream;
+template <class _CharT, class traits = char_traits<_CharT>>
+class _LIBCPP_TEMPLATE_VIS basic_ospanstream;
+template <class _CharT, class traits = char_traits<_CharT>>
+class _LIBCPP_TEMPLATE_VIS basic_spanstream;
+
+using spanbuf = basic_spanbuf<char>;
+using ispanstream = basic_ispanstream<char>;
+using ospanstream = basic_ospanstream<char>;
+using spanstream = basic_spanstream<char>;
+
+# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
+using wspanbuf = basic_spanbuf<wchar_t>;
+using wispanstream = basic_ispanstream<wchar_t>;
+using wospanstream = basic_ospanstream<wchar_t>;
+using wspanstream = basic_spanstream<wchar_t>;
+# endif
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_SPANSTREAM_H
diff --git a/libcxx/include/iosfwd b/libcxx/include/iosfwd
index f1c2cbd9669679..c9d459592e2879 100644
--- a/libcxx/include/iosfwd
+++ b/libcxx/include/iosfwd
@@ -42,6 +42,15 @@ template <class charT, class traits = char_traits<charT>, class Allocator = allo
template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_stringstream;
+ template<class charT, class traits = char_traits<charT>>
+ class basic_spanbuf; // Since C++23
+ template<class charT, class traits = char_traits<charT>>
+ class basic_ispanstream; // Since C++23
+ template<class charT, class traits = char_traits<charT>>
+ class basic_ospanstream; // Since C++23
+ template<class charT, class traits = char_traits<charT>>
+ class basic_spanstream; // Since C++23
+
template <class charT, class traits = char_traits<charT> > class basic_filebuf;
template <class charT, class traits = char_traits<charT> > class basic_ifstream;
template <class charT, class traits = char_traits<charT> > class basic_ofstream;
@@ -63,6 +72,11 @@ typedef basic_istringstream<char> istringstream;
typedef basic_ostringstream<char> ostringstream;
typedef basic_stringstream<char> stringstream;
+using spanbuf = basic_spanbuf<char>; // Since C++23
+using ispanstream = basic_ispanstream<char>; // Since C++23
+using ospanstream = basic_ospanstream<char>; // Since C++23
+using spanstream = basic_spanstream<char>; // Since C++23
+
typedef basic_filebuf<char> filebuf;
typedef basic_ifstream<char> ifstream;
typedef basic_ofstream<char> ofstream;
@@ -78,6 +92,11 @@ typedef basic_istringstream<wchar_t> wistringstream;
typedef basic_ostringstream<wchar_t> wostringstream;
typedef basic_stringstream<wchar_t> wstringstream;
+using wspanbuf = basic_spanbuf<wchar_t>; // Since C++23
+using wispanstream = basic_ispanstream<wchar_t>; // Since C++23
+using wospanstream = basic_ospanstream<wchar_t>; // Since C++23
+using wspanstream = basic_spanstream<wchar_t>; // Since C++23
+
typedef basic_filebuf<wchar_t> wfilebuf;
typedef basic_ifstream<wchar_t> wifstream;
typedef basic_ofstream<wchar_t> wofstream;
@@ -111,6 +130,7 @@ using wosyncstream = basic_osyncstream<wchar_t>; // C++20
#include <__fwd/ios.h>
#include <__fwd/istream.h>
#include <__fwd/ostream.h>
+#include <__fwd/spanstream.h>
#include <__fwd/sstream.h>
#include <__fwd/streambuf.h>
#include <__fwd/string.h>
diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp
index b1e728cde868da..7e9d6e37800f89 100644
--- a/libcxx/include/libcxx.imp
+++ b/libcxx/include/libcxx.imp
@@ -434,6 +434,7 @@
{ include: [ "<__fwd/ostream.h>", "private", "<iosfwd>", "public" ] },
{ include: [ "<__fwd/pair.h>", "private", "<utility>", "public" ] },
{ include: [ "<__fwd/span.h>", "private", "<span>", "public" ] },
+ { include: [ "<__fwd/spanstream.h>", "private", "<spanstream>", "public" ] },
{ include: [ "<__fwd/sstream.h>", "private", "<iosfwd>", "public" ] },
{ include: [ "<__fwd/streambuf.h>", "private", "<iosfwd>", "public" ] },
{ include: [ "<__fwd/string.h>", "private", "<string>", "public" ] },
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index db584ac680a407..b88809c7fc205e 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1392,14 +1392,15 @@ module std_private_functional_unary_function [system] { header "__fu
module std_private_functional_unary_negate [system] { header "__functional/unary_negate.h" }
module std_private_functional_weak_result_type [system] { header "__functional/weak_result_type.h" }
-module std_private_ios_fpos [system] { header "__ios/fpos.h" }
+module std_private_ios_fpos [system] { header "__ios/fpos.h" }
-module std_private_iosfwd_fstream_fwd [system] { header "__fwd/fstream.h" }
-module std_private_iosfwd_ios_fwd [system] { header "__fwd/ios.h" }
-module std_private_iosfwd_istream_fwd [system] { header "__fwd/istream.h" }
-module std_private_iosfwd_ostream_fwd [system] { header "__fwd/ostream.h" }
-module std_private_iosfwd_sstream_fwd [system] { header "__fwd/sstream.h" }
-module std_private_iosfwd_streambuf_fwd [system] { header "__fwd/streambuf.h" }
+module std_private_iosfwd_fstream_fwd [system] { header "__fwd/fstream.h" }
+module std_private_iosfwd_ios_fwd [system] { header "__fwd/ios.h" }
+module std_private_iosfwd_istream_fwd [system] { header "__fwd/istream.h" }
+module std_private_iosfwd_ostream_fwd [system] { header "__fwd/ostream.h" }
+module std_private_iosfwd_spanstream_fwd [system] { header "__fwd/spanstream.h" }
+module std_private_iosfwd_sstream_fwd [system] { header "__fwd/sstream.h" }
+module std_private_iosfwd_streambuf_fwd [system] { header "__fwd/streambuf.h" }
module std_private_iterator_access [system] { header "__iterator/access.h" }
module std_private_iterator_advance [system] { header "__iterator/advance.h" }
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index f25a04c2cb5254..ffaba85ef252c0 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -57,6 +57,7 @@
#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
+#include <__fwd/spanstream.h>
#include <__memory/addressof.h>
#include <__ranges/concepts.h>
#include <__utility/cmp.h>
@@ -81,7 +82,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// Class template basic_spanbuf [spanbuf]
-template <class _CharT, class _Traits = char_traits<_CharT>>
+template <class _CharT, class _Traits>
class _LIBCPP_TEMPLATE_VIS basic_spanbuf : public basic_streambuf<_CharT, _Traits> {
public:
using char_type = _CharT;
@@ -223,8 +224,8 @@ using wspanbuf = basic_spanbuf<wchar_t>;
// Class template basic_ispanstream [ispanstream]
-template <class _CharT, class _Traits = char_traits<_CharT>>
-class basic_ispanstream : public basic_istream<_CharT, _Traits> {
+template <class _CharT, class _Traits>
+class _LIBCPP_TEMPLATE_VIS basic_ispanstream : public basic_istream<_CharT, _Traits> {
public:
using char_type = _CharT;
using int_type = typename _Traits::int_type;
@@ -300,8 +301,8 @@ using wispanstream = basic_ispanstream<wchar_t>;
// Class template basic_ospanstream [ospanstream]
-template <class _CharT, class _Traits = char_traits<_CharT>>
-class basic_ospanstream : public basic_ostream<_CharT, _Traits> {
+template <class _CharT, class _Traits>
+class _LIBCPP_TEMPLATE_VIS basic_ospanstream : public basic_ostream<_CharT, _Traits> {
public:
using char_type = _CharT;
using int_type = typename _Traits::int_type;
@@ -358,8 +359,8 @@ using ospanstream = basic_ospanstream<char>;
using wospanstream = basic_ospanstream<wchar_t>;
# endif
-template <class _CharT, class _Traits = char_traits<_CharT>>
-class basic_spanstream : public basic_iostream<_CharT, _Traits> {
+template <class _CharT, class _Traits>
+class _LIBCPP_TEMPLATE_VIS basic_spanstream : public basic_iostream<_CharT, _Traits> {
public:
using char_type = _CharT;
using int_type = typename _Traits::int_type;
>From 1a2816a700c630343224dda67eb2e7f374416715 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 28 Feb 2024 19:01:08 +0200
Subject: [PATCH 03/39] Tests: updated `types.compile.pass`
---
.../ispanstream/types.compile.pass.cpp | 67 +++++++++----------
.../ospanstream/types.compile.pass.cpp | 67 +++++++++----------
.../spanbuf/types.compile.pass.cpp | 67 +++++++++----------
.../spanstream/types.compile.pass.cpp | 66 +++++++++---------
4 files changed, 132 insertions(+), 135 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
index 773efffd61a39c..9615d270116ee4 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
@@ -27,53 +27,52 @@
#include <string>
#include <type_traits>
+#include "constexpr_char_traits.h"
#include "test_macros.h"
-// Types
+template <typename CharT, typename Traits = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ispanstream<CharT, Traits>;
-static_assert(std::is_base_of_v<std::basic_istream<char>, std::ispanstream>);
-static_assert(std::is_same_v<std::ispanstream::char_type, char>);
-static_assert(std::is_same_v<std::ispanstream::int_type, std::char_traits<char>::int_type>);
-static_assert(std::is_same_v<std::ispanstream::pos_type, std::char_traits<char>::pos_type>);
-static_assert(std::is_same_v<std::ispanstream::off_type, std::char_traits<char>::off_type>);
-static_assert(std::is_same_v<std::ispanstream::traits_type, std::char_traits<char>>);
+ // Types
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_base_of_v<std::basic_istream<wchar_t>, std::wispanstream>);
-static_assert(std::is_same_v<std::wispanstream::char_type, wchar_t>);
-static_assert(std::is_same_v<std::wispanstream::int_type, std::char_traits<wchar_t>::int_type>);
-static_assert(std::is_same_v<std::wispanstream::pos_type, std::char_traits<wchar_t>::pos_type>);
-static_assert(std::is_same_v<std::wispanstream::off_type, std::char_traits<wchar_t>::off_type>);
-static_assert(std::is_same_v<std::wispanstream::traits_type, std::char_traits<wchar_t>>);
-#endif
+ static_assert(std::is_base_of_v<std::basic_istream<CharT, Traits>, SpStream>);
+ static_assert(std::is_same_v<typename SpStream::char_type, CharT>);
+ static_assert(std::is_same_v<typename SpStream::int_type, typename Traits::int_type>);
+ static_assert(std::is_same_v<typename SpStream::pos_type, typename Traits::pos_type>);
+ static_assert(std::is_same_v<typename SpStream::off_type, typename Traits::off_type>);
+ static_assert(std::is_same_v<typename SpStream::traits_type, Traits>);
-// Copy properties
+ // Copy properties
-static_assert(!std::is_copy_constructible_v<std::ispanstream>);
-static_assert(!std::is_copy_assignable_v<std::ispanstream>);
+ static_assert(!std::is_copy_constructible_v<SpStream>);
+ static_assert(!std::is_copy_assignable_v<SpStream>);
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(!std::is_copy_constructible_v<std::wispanstream>);
-static_assert(!std::is_copy_assignable_v<std::wispanstream>);
-#endif
+ // Move properties
-// Move properties
+ static_assert(!std::is_copy_constructible_v<SpStream>);
+ static_assert(!std::is_copy_assignable_v<SpStream>);
-static_assert(!std::is_copy_constructible_v<std::ispanstream>);
-static_assert(!std::is_copy_assignable_v<std::ispanstream>);
+ // Move properties
+ static_assert(std::is_move_constructible_v<SpStream>);
+ static_assert(std::is_move_assignable_v<SpStream>);
+}
+
+void test() {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(!std::is_copy_constructible_v<std::wispanstream>);
-static_assert(!std::is_copy_assignable_v<std::wispanstream>);
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
#endif
+}
-// Move properties
-
-static_assert(std::is_move_constructible_v<std::ispanstream>);
-static_assert(std::is_move_assignable_v<std::ispanstream>);
+// Aliases
+static_assert(std::is_base_of_v<std::basic_istream<char>, std::ispanstream>);
+static_assert(std::is_same_v<std::basic_ispanstream<char>, std::ispanstream>);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_move_constructible_v<std::wispanstream>);
-static_assert(std::is_move_assignable_v<std::wispanstream>);
+static_assert(std::is_base_of_v<std::basic_istream<wchar_t>, std::wispanstream>);
+static_assert(std::is_same_v<std::basic_ispanstream<wchar_t>, std::wispanstream>);
#endif
-
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
index ab0cac07168407..e5a9e574eb39f7 100644
--- a/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
@@ -27,53 +27,52 @@
#include <string>
#include <type_traits>
+#include "constexpr_char_traits.h"
#include "test_macros.h"
-// Types
+template <typename CharT, typename Traits = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ospanstream<CharT, Traits>;
-static_assert(std::is_base_of_v<std::basic_ostream<char>, std::ospanstream>);
-static_assert(std::is_same_v<std::ospanstream::char_type, char>);
-static_assert(std::is_same_v<std::ospanstream::int_type, std::char_traits<char>::int_type>);
-static_assert(std::is_same_v<std::ospanstream::pos_type, std::char_traits<char>::pos_type>);
-static_assert(std::is_same_v<std::ospanstream::off_type, std::char_traits<char>::off_type>);
-static_assert(std::is_same_v<std::ospanstream::traits_type, std::char_traits<char>>);
+ // Types
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_base_of_v<std::basic_ostream<wchar_t>, std::wospanstream>);
-static_assert(std::is_same_v<std::wospanstream::char_type, wchar_t>);
-static_assert(std::is_same_v<std::wospanstream::int_type, std::char_traits<wchar_t>::int_type>);
-static_assert(std::is_same_v<std::wospanstream::pos_type, std::char_traits<wchar_t>::pos_type>);
-static_assert(std::is_same_v<std::wospanstream::off_type, std::char_traits<wchar_t>::off_type>);
-static_assert(std::is_same_v<std::wospanstream::traits_type, std::char_traits<wchar_t>>);
-#endif
+ static_assert(std::is_base_of_v<std::basic_ostream<CharT, Traits>, SpStream>);
+ static_assert(std::is_same_v<typename SpStream::char_type, CharT>);
+ static_assert(std::is_same_v<typename SpStream::int_type, typename Traits::int_type>);
+ static_assert(std::is_same_v<typename SpStream::pos_type, typename Traits::pos_type>);
+ static_assert(std::is_same_v<typename SpStream::off_type, typename Traits::off_type>);
+ static_assert(std::is_same_v<typename SpStream::traits_type, Traits>);
-// Copy properties
+ // Copy properties
-static_assert(!std::is_copy_constructible_v<std::ospanstream>);
-static_assert(!std::is_copy_assignable_v<std::ospanstream>);
+ static_assert(!std::is_copy_constructible_v<SpStream>);
+ static_assert(!std::is_copy_assignable_v<SpStream>);
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(!std::is_copy_constructible_v<std::wospanstream>);
-static_assert(!std::is_copy_assignable_v<std::wospanstream>);
-#endif
+ // Move properties
-// Move properties
+ static_assert(!std::is_copy_constructible_v<SpStream>);
+ static_assert(!std::is_copy_assignable_v<SpStream>);
-static_assert(!std::is_copy_constructible_v<std::ospanstream>);
-static_assert(!std::is_copy_assignable_v<std::ospanstream>);
+ // Move properties
+ static_assert(std::is_move_constructible_v<SpStream>);
+ static_assert(std::is_move_assignable_v<SpStream>);
+}
+
+void test() {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(!std::is_copy_constructible_v<std::wospanstream>);
-static_assert(!std::is_copy_assignable_v<std::wospanstream>);
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
#endif
+}
-// Move properties
-
-static_assert(std::is_move_constructible_v<std::ospanstream>);
-static_assert(std::is_move_assignable_v<std::ospanstream>);
+// Aliases
+static_assert(std::is_base_of_v<std::basic_ostream<char>, std::ospanstream>);
+static_assert(std::is_same_v<std::basic_ospanstream<char>, std::ospanstream>);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_move_constructible_v<std::wospanstream>);
-static_assert(std::is_move_assignable_v<std::wospanstream>);
+static_assert(std::is_base_of_v<std::basic_ostream<wchar_t>, std::wospanstream>);
+static_assert(std::is_same_v<std::basic_ospanstream<wchar_t>, std::wospanstream>);
#endif
-
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
index 4585147ea8d2e7..a8cc07ed524ea8 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
@@ -27,53 +27,52 @@
#include <string>
#include <type_traits>
+#include "constexpr_char_traits.h"
#include "test_macros.h"
-// Types
+template <typename CharT, typename Traits = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, Traits>;
-static_assert(std::is_base_of_v<std::basic_streambuf<char>, std::spanbuf>);
-static_assert(std::is_same_v<std::spanbuf::char_type, char>);
-static_assert(std::is_same_v<std::spanbuf::int_type, std::char_traits<char>::int_type>);
-static_assert(std::is_same_v<std::spanbuf::pos_type, std::char_traits<char>::pos_type>);
-static_assert(std::is_same_v<std::spanbuf::off_type, std::char_traits<char>::off_type>);
-static_assert(std::is_same_v<std::spanbuf::traits_type, std::char_traits<char>>);
+ // Types
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_base_of_v<std::basic_streambuf<wchar_t>, std::wspanbuf>);
-static_assert(std::is_same_v<std::wspanbuf::char_type, wchar_t>);
-static_assert(std::is_same_v<std::wspanbuf::int_type, std::char_traits<wchar_t>::int_type>);
-static_assert(std::is_same_v<std::wspanbuf::pos_type, std::char_traits<wchar_t>::pos_type>);
-static_assert(std::is_same_v<std::wspanbuf::off_type, std::char_traits<wchar_t>::off_type>);
-static_assert(std::is_same_v<std::wspanbuf::traits_type, std::char_traits<wchar_t>>);
-#endif
+ static_assert(std::is_base_of_v<std::basic_streambuf<CharT, Traits>, SpBuf>);
+ static_assert(std::is_same_v<typename SpBuf::char_type, CharT>);
+ static_assert(std::is_same_v<typename SpBuf::int_type, typename Traits::int_type>);
+ static_assert(std::is_same_v<typename SpBuf::pos_type, typename Traits::pos_type>);
+ static_assert(std::is_same_v<typename SpBuf::off_type, typename Traits::off_type>);
+ static_assert(std::is_same_v<typename SpBuf::traits_type, Traits>);
-// Copy properties
+ // Copy properties
-static_assert(!std::is_copy_constructible_v<std::spanbuf>);
-static_assert(!std::is_copy_assignable_v<std::spanbuf>);
+ static_assert(!std::is_copy_constructible_v<SpBuf>);
+ static_assert(!std::is_copy_assignable_v<SpBuf>);
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(!std::is_copy_constructible_v<std::wspanbuf>);
-static_assert(!std::is_copy_assignable_v<std::wspanbuf>);
-#endif
+ // Move properties
-// Move properties
+ static_assert(!std::is_copy_constructible_v<SpBuf>);
+ static_assert(!std::is_copy_assignable_v<SpBuf>);
-static_assert(!std::is_copy_constructible_v<std::spanbuf>);
-static_assert(!std::is_copy_assignable_v<std::spanbuf>);
+ // Move properties
+ static_assert(std::is_move_constructible_v<SpBuf>);
+ static_assert(std::is_move_assignable_v<SpBuf>);
+}
+
+void test() {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(!std::is_copy_constructible_v<std::wspanbuf>);
-static_assert(!std::is_copy_assignable_v<std::wspanbuf>);
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
#endif
+}
-// Move properties
-
-static_assert(std::is_move_constructible_v<std::spanbuf>);
-static_assert(std::is_move_assignable_v<std::spanbuf>);
+// Aliases
+static_assert(std::is_base_of_v<std::basic_streambuf<char>, std::spanbuf>);
+static_assert(std::is_same_v<std::basic_spanbuf<char>, std::spanbuf>);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_move_constructible_v<std::wspanbuf>);
-static_assert(std::is_move_assignable_v<std::wspanbuf>);
+static_assert(std::is_base_of_v<std::basic_streambuf<wchar_t>, std::wspanbuf>);
+static_assert(std::is_same_v<std::basic_spanbuf<wchar_t>, std::wspanbuf>);
#endif
-
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
index 4e90f259ccf488..5714834be2ce11 100644
--- a/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
@@ -27,52 +27,52 @@
#include <string>
#include <type_traits>
+#include "constexpr_char_traits.h"
#include "test_macros.h"
-// Types
+template <typename CharT, typename Traits = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_spanstream<CharT, Traits>;
-static_assert(std::is_base_of_v<std::basic_iostream<char>, std::spanstream>);
-static_assert(std::is_same_v<std::spanstream::char_type, char>);
-static_assert(std::is_same_v<std::spanstream::int_type, std::char_traits<char>::int_type>);
-static_assert(std::is_same_v<std::spanstream::pos_type, std::char_traits<char>::pos_type>);
-static_assert(std::is_same_v<std::spanstream::off_type, std::char_traits<char>::off_type>);
-static_assert(std::is_same_v<std::spanstream::traits_type, std::char_traits<char>>);
+ // Types
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_base_of_v<std::basic_iostream<wchar_t>, std::wspanstream>);
-static_assert(std::is_same_v<std::wspanstream::char_type, wchar_t>);
-static_assert(std::is_same_v<std::wspanstream::int_type, std::char_traits<wchar_t>::int_type>);
-static_assert(std::is_same_v<std::wspanstream::pos_type, std::char_traits<wchar_t>::pos_type>);
-static_assert(std::is_same_v<std::wspanstream::off_type, std::char_traits<wchar_t>::off_type>);
-static_assert(std::is_same_v<std::wspanstream::traits_type, std::char_traits<wchar_t>>);
-#endif
+ static_assert(std::is_base_of_v<std::basic_iostream<CharT, Traits>, SpStream>);
+ static_assert(std::is_same_v<typename SpStream::char_type, CharT>);
+ static_assert(std::is_same_v<typename SpStream::int_type, typename Traits::int_type>);
+ static_assert(std::is_same_v<typename SpStream::pos_type, typename Traits::pos_type>);
+ static_assert(std::is_same_v<typename SpStream::off_type, typename Traits::off_type>);
+ static_assert(std::is_same_v<typename SpStream::traits_type, Traits>);
-// Copy properties
+ // Copy properties
-static_assert(!std::is_copy_constructible_v<std::spanstream>);
-static_assert(!std::is_copy_assignable_v<std::spanstream>);
+ static_assert(!std::is_copy_constructible_v<SpStream>);
+ static_assert(!std::is_copy_assignable_v<SpStream>);
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(!std::is_copy_constructible_v<std::wspanstream>);
-static_assert(!std::is_copy_assignable_v<std::wspanstream>);
-#endif
+ // Move properties
+
+ static_assert(!std::is_copy_constructible_v<SpStream>);
+ static_assert(!std::is_copy_assignable_v<SpStream>);
-// Move properties
+ // Move properties
-static_assert(!std::is_copy_constructible_v<std::spanstream>);
-static_assert(!std::is_copy_assignable_v<std::spanstream>);
+ static_assert(std::is_move_constructible_v<SpStream>);
+ static_assert(std::is_move_assignable_v<SpStream>);
+}
+void test() {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(!std::is_copy_constructible_v<std::wspanstream>);
-static_assert(!std::is_copy_assignable_v<std::wspanstream>);
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
#endif
+}
-// Move properties
-
-static_assert(std::is_move_constructible_v<std::spanstream>);
-static_assert(std::is_move_assignable_v<std::spanstream>);
+// Aliases
+static_assert(std::is_base_of_v<std::basic_iostream<char>, std::spanstream>);
+static_assert(std::is_same_v<std::basic_spanstream<char>, std::spanstream>);
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_move_constructible_v<std::wspanstream>);
-static_assert(std::is_move_assignable_v<std::wspanstream>);
+static_assert(std::is_base_of_v<std::basic_iostream<wchar_t>, std::wspanstream>);
+static_assert(std::is_same_v<std::basic_spanstream<wchar_t>, std::wspanstream>);
#endif
>From 59a061715e3b454806217f5a4909729778821e85 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 28 Feb 2024 19:38:58 +0200
Subject: [PATCH 04/39] Implementation: added `_LIBCPP_HIDE_FROM_ABI`
---
libcxx/include/__fwd/spanstream.h | 8 ++--
libcxx/include/spanstream | 74 +++++++++++++++++--------------
2 files changed, 44 insertions(+), 38 deletions(-)
diff --git a/libcxx/include/__fwd/spanstream.h b/libcxx/include/__fwd/spanstream.h
index 2afeaaecf7fb4d..f5ff2ad2c9cfc6 100644
--- a/libcxx/include/__fwd/spanstream.h
+++ b/libcxx/include/__fwd/spanstream.h
@@ -20,13 +20,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 23
-template <class _CharT, class traits = char_traits<_CharT>>
+template <class _CharT, class _Traits = char_traits<_CharT>>
class _LIBCPP_TEMPLATE_VIS basic_spanbuf;
-template <class _CharT, class traits = char_traits<_CharT>>
+template <class _CharT, class _Traits = char_traits<_CharT>>
class _LIBCPP_TEMPLATE_VIS basic_ispanstream;
-template <class _CharT, class traits = char_traits<_CharT>>
+template <class _CharT, class _Traits = char_traits<_CharT>>
class _LIBCPP_TEMPLATE_VIS basic_ospanstream;
-template <class _CharT, class traits = char_traits<_CharT>>
+template <class _CharT, class _Traits = char_traits<_CharT>>
class _LIBCPP_TEMPLATE_VIS basic_spanstream;
using spanbuf = basic_spanbuf<char>;
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index ffaba85ef252c0..16bbf04d81c559 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -105,6 +105,7 @@ public:
}
basic_spanbuf(const basic_spanbuf&) = delete;
+
_LIBCPP_HIDE_FROM_ABI basic_spanbuf(basic_spanbuf&& __rhs)
: basic_streambuf<_CharT, _Traits>{std::move(__rhs)},
__mode_{std::move(__rhs.__mode_)},
@@ -113,6 +114,7 @@ public:
// [spanbuf.assign], assignment and swap
basic_spanbuf& operator=(const basic_spanbuf&) = delete;
+
_LIBCPP_HIDE_FROM_ABI basic_spanbuf& operator=(basic_spanbuf&& __rhs) {
basic_spanbuf __tmp{std::move(__rhs)};
this->swap(__tmp);
@@ -213,13 +215,13 @@ private:
};
template <class _CharT, class _Traits>
-void swap(basic_spanbuf<_CharT, _Traits>& __x, basic_spanbuf<_CharT, _Traits>& __y) {
+_LIBCPP_HIDE_FROM_ABI void swap(basic_spanbuf<_CharT, _Traits>& __x, basic_spanbuf<_CharT, _Traits>& __y) {
__x.swap(__y);
}
-using spanbuf = basic_spanbuf<char>;
+using std::spanbuf;
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-using wspanbuf = basic_spanbuf<wchar_t>;
+using std::wspanbuf;
# endif
// Class template basic_ispanstream [ispanstream]
@@ -235,27 +237,28 @@ public:
// [ispanstream.cons], constructors
- explicit basic_ispanstream(std::span<_CharT> __s, ios_base::openmode __which = ios_base::in)
+ _LIBCPP_HIDE_FROM_ABI explicit basic_ispanstream(std::span<_CharT> __s, ios_base::openmode __which = ios_base::in)
: basic_istream<_CharT, _Traits>(std::addressof(__sb_)),
__sb_(basic_spanbuf<_CharT, _Traits>(__s, __which | ios_base::in)) {}
basic_ispanstream(const basic_ispanstream&) = delete;
- basic_ispanstream(basic_ispanstream&& __rhs)
+ _LIBCPP_HIDE_FROM_ABI basic_ispanstream(basic_ispanstream&& __rhs)
: basic_istream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
basic_istream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
}
template <ranges::borrowed_range _ROSeq>
requires(!convertible_to<_ROSeq, std::span<_CharT>>) && convertible_to<_ROSeq, std::span<const _CharT>>
- explicit basic_ispanstream(_ROSeq&& __s) : basic_istream<_CharT, _Traits>(std::addressof(__sb_)) {
+ _LIBCPP_HIDE_FROM_ABI explicit basic_ispanstream(_ROSeq&& __s)
+ : basic_istream<_CharT, _Traits>(std::addressof(__sb_)) {
std::span<const _CharT> __sp(std::forward<_ROSeq>(__s));
this->span(std::span<_CharT>(std::span<_CharT>(const_cast<_CharT*>(__sp.data()), __sp.size())));
}
basic_ispanstream& operator=(const basic_ispanstream&) = delete;
- basic_ispanstream& operator=(basic_ispanstream&& __rhs) {
+ _LIBCPP_HIDE_FROM_ABI basic_ispanstream& operator=(basic_ispanstream&& __rhs) {
basic_ispanstream __tmp{std::move(__rhs)};
this->swap(__tmp);
return *this;
@@ -263,24 +266,24 @@ public:
// [ispanstream.swap], swap
- void swap(basic_ispanstream& __rhs) {
+ _LIBCPP_HIDE_FROM_ABI void swap(basic_ispanstream& __rhs) {
basic_istream<_CharT, _Traits>::swap(__rhs);
__sb_.swap(__rhs.__sb_);
}
// [ispanstream.members], member functions
- basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept {
+ _LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept {
return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::addressof(__sb_));
}
- std::span<const _CharT> span() const noexcept { return rdbuf()->span(); }
+ _LIBCPP_HIDE_FROM_ABI std::span<const _CharT> span() const noexcept { return rdbuf()->span(); }
- void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
+ _LIBCPP_HIDE_FROM_ABI void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
template <ranges::borrowed_range _ROSeq>
requires(!convertible_to<_ROSeq, std::span<_CharT>>) && convertible_to<_ROSeq, std::span<const _CharT>>
- void span(_ROSeq&& __s) noexcept {
+ _LIBCPP_HIDE_FROM_ABI void span(_ROSeq&& __s) noexcept {
std::span<const _CharT> __sp(std::forward<_ROSeq>(__s));
this->span(std::span<_CharT>(const_cast<_CharT*>(__sp.data()), __sp.size()));
}
@@ -290,13 +293,13 @@ private:
};
template <class _CharT, class _Traits>
-void swap(basic_ispanstream<_CharT, _Traits>& __x, basic_ispanstream<_CharT, _Traits>& __y) {
+_LIBCPP_HIDE_FROM_ABI void swap(basic_ispanstream<_CharT, _Traits>& __x, basic_ispanstream<_CharT, _Traits>& __y) {
__x.swap(__y);
}
-using ispanstream = basic_ispanstream<char>;
+using std::ispanstream;
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-using wispanstream = basic_ispanstream<wchar_t>;
+using std::wispanstream;
# endif
// Class template basic_ospanstream [ospanstream]
@@ -312,19 +315,20 @@ public:
// [ospanstream.cons], constructors
- explicit basic_ospanstream(std::span<_CharT> __s, ios_base::openmode __which = ios_base::out)
+ _LIBCPP_HIDE_FROM_ABI explicit basic_ospanstream(std::span<_CharT> __s, ios_base::openmode __which = ios_base::out)
: basic_ostream<_CharT, _Traits>(std::addressof(__sb_)),
__sb_(basic_spanbuf<_CharT, _Traits>(__s, __which | ios_base::out)) {}
basic_ospanstream(const basic_ospanstream&) = delete;
- basic_ospanstream(basic_ospanstream&& __rhs) : basic_ospanstream(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
+ _LIBCPP_HIDE_FROM_ABI basic_ospanstream(basic_ospanstream&& __rhs)
+ : basic_ospanstream(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
basic_ostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
}
basic_ospanstream& operator=(const basic_ospanstream&) = delete;
- basic_ospanstream& operator=(basic_ospanstream&& __rhs) {
+ _LIBCPP_HIDE_FROM_ABI basic_ospanstream& operator=(basic_ospanstream&& __rhs) {
basic_ospanstream __tmp{std::move(__rhs)};
this->swap(__tmp);
return *this;
@@ -332,31 +336,31 @@ public:
// [ospanstream.swap], swap
- void swap(basic_ospanstream& __rhs) {
+ _LIBCPP_HIDE_FROM_ABI void swap(basic_ospanstream& __rhs) {
basic_ostream<_CharT, _Traits>::swap(__rhs);
__sb_.swap(__rhs.__sb_);
}
// [ospanstream.members], member functions
- basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
+ _LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
- std::span<_CharT> span() const noexcept { return __sb_.rdbuf()->span(); }
+ _LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept { return __sb_.rdbuf()->span(); }
- void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
+ _LIBCPP_HIDE_FROM_ABI void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
private:
basic_spanbuf<_CharT, _Traits> __sb_; // exposition only
};
template <class _CharT, class _Traits>
-void swap(basic_ospanstream<_CharT, _Traits>& __x, basic_ospanstream<_CharT, _Traits>& __y) {
+_LIBCPP_HIDE_FROM_ABI void swap(basic_ospanstream<_CharT, _Traits>& __x, basic_ospanstream<_CharT, _Traits>& __y) {
__x.swap(__y);
}
-using ospanstream = basic_ospanstream<char>;
+using std::ospanstream;
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-using wospanstream = basic_ospanstream<wchar_t>;
+using std::wospanstream;
# endif
template <class _CharT, class _Traits>
@@ -370,18 +374,20 @@ public:
// [spanstream.cons], constructors
- explicit basic_spanstream(std::span<_CharT> __s, ios_base::openmode __which = ios_base::out | ios_base::in)
+ _LIBCPP_HIDE_FROM_ABI explicit basic_spanstream(std::span<_CharT> __s,
+ ios_base::openmode __which = ios_base::out | ios_base::in)
: basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(basic_spanbuf<_CharT, _Traits>(__s, __which)) {}
basic_spanstream(const basic_spanstream&) = delete;
- basic_spanstream(basic_spanstream&& __rhs) : basic_spanstream(std::move(__rhs)), __sb_(__rhs.__sb_) {
+ _LIBCPP_HIDE_FROM_ABI basic_spanstream(basic_spanstream&& __rhs)
+ : basic_spanstream(std::move(__rhs)), __sb_(__rhs.__sb_) {
basic_iostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
}
basic_spanstream& operator=(const basic_spanstream&) = delete;
- basic_spanstream& operator=(basic_spanstream&& __rhs) {
+ _LIBCPP_HIDE_FROM_ABI basic_spanstream& operator=(basic_spanstream&& __rhs) {
basic_spanstream __tmp{std::move(__rhs)};
this->swap(__tmp);
return *this;
@@ -396,24 +402,24 @@ public:
// [spanstream.members], members
- basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
+ _LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
- std::span<_CharT> span() const noexcept { return rdbuf()->span(); }
+ _LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept { return rdbuf()->span(); }
- void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
+ _LIBCPP_HIDE_FROM_ABI void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
private:
basic_spanbuf<_CharT, _Traits> __sb_; // exposition only
};
template <class _CharT, class _Traits>
-void swap(basic_spanstream<_CharT, _Traits>& __x, basic_spanstream<_CharT, _Traits>& __y) {
+_LIBCPP_HIDE_FROM_ABI void swap(basic_spanstream<_CharT, _Traits>& __x, basic_spanstream<_CharT, _Traits>& __y) {
__x.swap(__y);
}
-using spanstream = basic_spanstream<char>;
+using std::spanstream;
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-using wspanstream = basic_spanstream<wchar_t>;
+using std::wspanstream;
# endif
#endif // _LIBCPP_STD_VER >= 23
>From fd700e43cd1a56f9f3205a90a65457d040afb47e Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 29 Feb 2024 11:05:55 +0200
Subject: [PATCH 05/39] Tests: `spanbuf` constructor tests
---
.../ispanstream/types.compile.pass.cpp | 14 +-
.../std/input.output/span.streams/macros.h | 18 ++
.../ospanstream/types.compile.pass.cpp | 14 +-
.../spanbuf/spanbuf.cons/default.pass.cpp | 25 +-
.../spanbuf/spanbuf.cons/mode.pass.cpp | 96 ++++++++
.../spanbuf/spanbuf.cons/move.pass.cpp | 224 ++++++++++++++++++
.../spanbuf/spanbuf.cons/span.mode.pass.cpp | 155 ++++++++++++
.../spanbuf/types.compile.pass.cpp | 14 +-
.../spanstream/types.compile.pass.cpp | 14 +-
.../std/input.output/span.streams/types.h | 73 ++++++
10 files changed, 615 insertions(+), 32 deletions(-)
create mode 100644 libcxx/test/std/input.output/span.streams/macros.h
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/types.h
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
index 9615d270116ee4..c566a3fce647dc 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
@@ -30,18 +30,18 @@
#include "constexpr_char_traits.h"
#include "test_macros.h"
-template <typename CharT, typename Traits = std::char_traits<CharT>>
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
- using SpStream = std::basic_ispanstream<CharT, Traits>;
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
// Types
- static_assert(std::is_base_of_v<std::basic_istream<CharT, Traits>, SpStream>);
+ static_assert(std::is_base_of_v<std::basic_istream<CharT, TraitsT>, SpStream>);
static_assert(std::is_same_v<typename SpStream::char_type, CharT>);
- static_assert(std::is_same_v<typename SpStream::int_type, typename Traits::int_type>);
- static_assert(std::is_same_v<typename SpStream::pos_type, typename Traits::pos_type>);
- static_assert(std::is_same_v<typename SpStream::off_type, typename Traits::off_type>);
- static_assert(std::is_same_v<typename SpStream::traits_type, Traits>);
+ static_assert(std::is_same_v<typename SpStream::int_type, typename TraitsT::int_type>);
+ static_assert(std::is_same_v<typename SpStream::pos_type, typename TraitsT::pos_type>);
+ static_assert(std::is_same_v<typename SpStream::off_type, typename TraitsT::off_type>);
+ static_assert(std::is_same_v<typename SpStream::traits_type, TraitsT>);
// Copy properties
diff --git a/libcxx/test/std/input.output/span.streams/macros.h b/libcxx/test/std/input.output/span.streams/macros.h
new file mode 100644
index 00000000000000..679686eaa41a82
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/macros.h
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_STD_INPUTOUTPUT_SPANSTREAMS_MACROS_H
+#define TEST_STD_INPUTOUTPUT_SPANSTREAMS_MACROS_H
+
+#include "make_string.h"
+
+#define CS(S) MAKE_CSTRING(CharT, S)
+#define ST(S, a) std::basic_string<CharT, TraitsT, AllocT>(MAKE_CSTRING(CharT, S), MKSTR_LEN(CharT, S), a)
+#define SV(S) std::basic_string_view<CharT, TraitsT>(MAKE_CSTRING(CharT, S), MKSTR_LEN(CharT, S))
+
+#endif // TEST_STD_INPUTOUTPUT_SPANSTREAMS_MACROS_H
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
index e5a9e574eb39f7..595770aa5bd6b0 100644
--- a/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
@@ -30,18 +30,18 @@
#include "constexpr_char_traits.h"
#include "test_macros.h"
-template <typename CharT, typename Traits = std::char_traits<CharT>>
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
- using SpStream = std::basic_ospanstream<CharT, Traits>;
+ using SpStream = std::basic_ospanstream<CharT, TraitsT>;
// Types
- static_assert(std::is_base_of_v<std::basic_ostream<CharT, Traits>, SpStream>);
+ static_assert(std::is_base_of_v<std::basic_ostream<CharT, TraitsT>, SpStream>);
static_assert(std::is_same_v<typename SpStream::char_type, CharT>);
- static_assert(std::is_same_v<typename SpStream::int_type, typename Traits::int_type>);
- static_assert(std::is_same_v<typename SpStream::pos_type, typename Traits::pos_type>);
- static_assert(std::is_same_v<typename SpStream::off_type, typename Traits::off_type>);
- static_assert(std::is_same_v<typename SpStream::traits_type, Traits>);
+ static_assert(std::is_same_v<typename SpStream::int_type, typename TraitsT::int_type>);
+ static_assert(std::is_same_v<typename SpStream::pos_type, typename TraitsT::pos_type>);
+ static_assert(std::is_same_v<typename SpStream::off_type, typename TraitsT::off_type>);
+ static_assert(std::is_same_v<typename SpStream::traits_type, TraitsT>);
// Copy properties
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
index 4675c0e5fc2990..4c6b1ae3080d9e 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
@@ -21,19 +21,36 @@
#include <spanstream>
#include "constexpr_char_traits.h"
+#include "nasty_string.h"
#include "test_macros.h"
-template <typename CharT, typename Traits = std::char_traits<CharT>>
-void test() {
- using SpanBuf = std::basic_spanbuf<CharT, Traits>;
+void test_sfinae_with_nasty_char() {
+ using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
+
+ static_assert(std::default_initializable<SpBuf>);
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test_sfinae() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
- static_assert(std::default_initializable<SpanBuf>);
+ static_assert(std::default_initializable<SpBuf>);
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpanBuf = std::basic_spanbuf<CharT, TraitsT>;
SpanBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
}
int main(int, char**) {
+ test_sfinae_with_nasty_char();
+ test_sfinae<char>();
+ test_sfinae<char, constexpr_char_traits<char>>();
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
new file mode 100644
index 00000000000000..5a497e5b3238c0
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
@@ -0,0 +1,96 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// explicit basic_spanbuf(ios_base::openmode which);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "nasty_string.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+#include "../../types.h"
+
+void test_sfinae_with_nasty_char() {
+ using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
+
+ static_assert(std::constructible_from<SpBuf, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpBuf, std::ios_base::openmode>());
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test_sfinae() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ // `Mode`
+ static_assert(std::constructible_from<SpBuf, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpBuf, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpBuf, const NonMode>);
+ static_assert(!test_convertible<SpBuf, const NonMode>());
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ static_assert(std::default_initializable<SpBuf>);
+
+ // Mode: `in`
+ {
+ SpBuf spBuf(std::ios_base::in);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `out`
+ {
+ SpBuf spBuf(std::ios_base::out);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf spBuf(std::ios_base::out | std::ios_base::in | std::ios_base::binary);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test_sfinae_with_nasty_char();
+ test_sfinae<char>();
+ test_sfinae<char, constexpr_char_traits<char>>();
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_sfinae<wchar_t>();
+ test_sfinae<wchar_t, constexpr_char_traits<wchar_t>>();
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
new file mode 100644
index 00000000000000..cfc67b07ea3030
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
@@ -0,0 +1,224 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// basic_spanbuf(basic_spanbuf&& rhs);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "nasty_string.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT>
+struct TestSpanBuf : std::basic_spanbuf<CharT, TraitsT> {
+ using std::basic_spanbuf<CharT, TraitsT>::basic_spanbuf;
+
+ TestSpanBuf(std::basic_spanbuf<CharT, TraitsT>&& rhs) : std::basic_spanbuf<CharT, TraitsT>(std::move(rhs)) {}
+
+ void check_postconditions(TestSpanBuf<CharT, TraitsT> const& rhs_p) const {
+ assert(this->span().data() == rhs_p.span().data());
+ assert(this->span().size() == rhs_p.span().size());
+ assert(this->eback() == rhs_p.eback());
+ assert(this->gptr() == rhs_p.gptr());
+ assert(this->egptr() == rhs_p.egptr());
+ assert(this->pbase() == rhs_p.pbase());
+ assert(this->pptr() == rhs_p.pptr());
+ assert(this->epptr() == rhs_p.epptr());
+ assert(this->getloc() == rhs_p.getloc());
+ }
+};
+
+void test_sfinae_with_nasty_char() {
+ using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
+
+ static_assert(std::move_constructible<SpBuf>);
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test_sfinae() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ static_assert(std::move_constructible<SpBuf>);
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ {
+ // Empty `span`
+ {
+ // Mode: `ios_base::in`
+ {
+ SpBuf rhsSpBuf{std::ios_base::in};
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `ios_base::out`
+ {
+ SpBuf rhsSpBuf{std::ios_base::out};
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{std::ios_base::out | std::ios_base::in};
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ }
+
+ // Non-empty `span`
+ {
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: `ios_base::in`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in};
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out};
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out | std::ios_base::in | std::ios_base::binary};
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ }
+ }
+
+ // Check post-conditions
+ {
+ // Empty `span`
+ {
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().empty());
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `ios_base::in`
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().empty());
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `ios_base::out`
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().empty());
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: multiple
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::in | std::ios_base::binary);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().empty());
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ }
+
+ // Non-empty `span`
+ {
+ CharT arr[4];
+
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().empty());
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `ios_base::in`
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(!rhsSpBuf.span().empty());
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `ios_base::out`
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().empty());
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: multiple
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::in | std::ios_base::binary);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().empty());
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ }
+ }
+}
+
+int main(int, char**) {
+ test_sfinae_with_nasty_char();
+ test_sfinae<char>();
+ test_sfinae<char, constexpr_char_traits<char>>();
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
new file mode 100644
index 00000000000000..fb58235d8c1fe0
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// explicit basic_spanbuf(std::span<charT> s,
+// ios_base::openmode which = ios_base::in | ios_base::out);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+#include <utility>
+
+#include "constexpr_char_traits.h"
+#include "nasty_string.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+#include "../../macros.h"
+#include "../../types.h"
+
+void test_sfinae_with_nasty_char() {
+ using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
+
+ static_assert(std::constructible_from<SpBuf, const std::span<nasty_char>, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpBuf, std::ios_base::openmode>());
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test_sfinae() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ // `Mode`
+ static_assert(std::constructible_from<SpBuf, const std::span<CharT>, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpBuf, const std::span<CharT>, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpBuf, const std::span<CharT>, const NonMode>);
+ static_assert(!test_convertible<SpBuf, const std::span<CharT>, const NonMode>());
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ static_assert(std::default_initializable<SpBuf>);
+
+ // Empty `span`
+ {
+ std::span<CharT> sp{};
+
+ // Mode: `ios_base::in`
+ {
+ SpBuf spBuf(sp, std::ios_base::in);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ {
+ SpBuf spBuf(std::as_const(sp), std::ios_base::in);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `ios_base::out`
+ {
+ SpBuf spBuf(sp, std::ios_base::out);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ {
+ SpBuf spBuf(std::as_const(sp), std::ios_base::out);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ }
+
+ // Non-empty `span`
+ {
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: `ios_base::in`
+ {
+ SpBuf spBuf(sp, std::ios_base::in);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ {
+ SpBuf spBuf(std::as_const(sp), std::ios_base::in);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpBuf spBuf(sp, std::ios_base::out);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ {
+ SpBuf spBuf(std::as_const(sp), std::ios_base::out);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf spBuf(sp, std::ios_base::out | std::ios_base::in);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ {
+ SpBuf spBuf(std::as_const(sp), std::ios_base::out | std::ios_base::in | std::ios_base::binary);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ }
+}
+
+int main(int, char**) {
+ test_sfinae_with_nasty_char();
+ test_sfinae<char>();
+ test_sfinae<char, constexpr_char_traits<char>>();
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_sfinae<wchar_t>();
+ test_sfinae<wchar_t, constexpr_char_traits<wchar_t>>();
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
\ No newline at end of file
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
index a8cc07ed524ea8..4c18422ebff28c 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
@@ -30,18 +30,18 @@
#include "constexpr_char_traits.h"
#include "test_macros.h"
-template <typename CharT, typename Traits = std::char_traits<CharT>>
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
- using SpBuf = std::basic_spanbuf<CharT, Traits>;
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
// Types
- static_assert(std::is_base_of_v<std::basic_streambuf<CharT, Traits>, SpBuf>);
+ static_assert(std::is_base_of_v<std::basic_streambuf<CharT, TraitsT>, SpBuf>);
static_assert(std::is_same_v<typename SpBuf::char_type, CharT>);
- static_assert(std::is_same_v<typename SpBuf::int_type, typename Traits::int_type>);
- static_assert(std::is_same_v<typename SpBuf::pos_type, typename Traits::pos_type>);
- static_assert(std::is_same_v<typename SpBuf::off_type, typename Traits::off_type>);
- static_assert(std::is_same_v<typename SpBuf::traits_type, Traits>);
+ static_assert(std::is_same_v<typename SpBuf::int_type, typename TraitsT::int_type>);
+ static_assert(std::is_same_v<typename SpBuf::pos_type, typename TraitsT::pos_type>);
+ static_assert(std::is_same_v<typename SpBuf::off_type, typename TraitsT::off_type>);
+ static_assert(std::is_same_v<typename SpBuf::traits_type, TraitsT>);
// Copy properties
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
index 5714834be2ce11..67d29cf041d9cc 100644
--- a/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
@@ -30,18 +30,18 @@
#include "constexpr_char_traits.h"
#include "test_macros.h"
-template <typename CharT, typename Traits = std::char_traits<CharT>>
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
- using SpStream = std::basic_spanstream<CharT, Traits>;
+ using SpStream = std::basic_spanstream<CharT, TraitsT>;
// Types
- static_assert(std::is_base_of_v<std::basic_iostream<CharT, Traits>, SpStream>);
+ static_assert(std::is_base_of_v<std::basic_iostream<CharT, TraitsT>, SpStream>);
static_assert(std::is_same_v<typename SpStream::char_type, CharT>);
- static_assert(std::is_same_v<typename SpStream::int_type, typename Traits::int_type>);
- static_assert(std::is_same_v<typename SpStream::pos_type, typename Traits::pos_type>);
- static_assert(std::is_same_v<typename SpStream::off_type, typename Traits::off_type>);
- static_assert(std::is_same_v<typename SpStream::traits_type, Traits>);
+ static_assert(std::is_same_v<typename SpStream::int_type, typename TraitsT::int_type>);
+ static_assert(std::is_same_v<typename SpStream::pos_type, typename TraitsT::pos_type>);
+ static_assert(std::is_same_v<typename SpStream::off_type, typename TraitsT::off_type>);
+ static_assert(std::is_same_v<typename SpStream::traits_type, TraitsT>);
// Copy properties
diff --git a/libcxx/test/std/input.output/span.streams/types.h b/libcxx/test/std/input.output/span.streams/types.h
new file mode 100644
index 00000000000000..18788a56579dcb
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/types.h
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_STD_INPUTOUTPUT_SPANSTREAMS_TYPES_H
+#define TEST_STD_INPUTOUTPUT_SPANSTREAMS_TYPES_H
+
+#include <string_view>
+#include <concepts>
+
+#include "test_macros.h"
+
+// template <typename CharT, class Traits = std::char_traits<CharT>>
+// class ConstConvertibleStringView {
+// public:
+// explicit ConstConvertibleStringView(const CharT* cs) : cs_{cs} {}
+
+// operator std::basic_string_view<CharT, Traits>() = delete;
+// operator std::basic_string_view<CharT, Traits>() const { return std::basic_string_view<CharT, Traits>(cs_); }
+
+// private:
+// const CharT* cs_;
+// };
+
+// static_assert(!std::constructible_from<std::basic_string_view<char>, ConstConvertibleStringView<char>>);
+// static_assert(!std::convertible_to<ConstConvertibleStringView<char>, std::basic_string_view<char>>);
+
+// static_assert(std::constructible_from<std::basic_string_view<char>, const ConstConvertibleStringView<char>>);
+// static_assert(std::convertible_to<const ConstConvertibleStringView<char>, std::basic_string_view<char>>);
+
+// #ifndef TEST_HAS_NO_WIDE_CHARACTERS
+// static_assert(!std::constructible_from<std::basic_string_view<wchar_t>, ConstConvertibleStringView<wchar_t>>);
+// static_assert(!std::convertible_to<ConstConvertibleStringView<wchar_t>, std::basic_string_view<wchar_t>>);
+
+// static_assert(std::constructible_from<std::basic_string_view<wchar_t>, const ConstConvertibleStringView<wchar_t>>);
+// static_assert(std::convertible_to<const ConstConvertibleStringView<wchar_t>, std::basic_string_view<wchar_t>>);
+// #endif
+
+// template <typename CharT, class Traits = std::char_traits<CharT>>
+// class NonConstConvertibleStringView {
+// public:
+// explicit NonConstConvertibleStringView(const CharT* cs) : cs_{cs} {}
+
+// operator std::basic_string_view<CharT, Traits>() { return std::basic_string_view<CharT, Traits>(cs_); }
+// operator std::basic_string_view<CharT, Traits>() const = delete;
+
+// private:
+// const CharT* cs_;
+// };
+
+// static_assert(std::constructible_from<std::basic_string_view<char>, NonConstConvertibleStringView<char>>);
+// static_assert(std::convertible_to<NonConstConvertibleStringView<char>, std::basic_string_view<char>>);
+
+// static_assert(!std::constructible_from<std::basic_string_view<char>, const NonConstConvertibleStringView<char>>);
+// static_assert(!std::convertible_to<const NonConstConvertibleStringView<char>, std::basic_string_view<char>>);
+
+// #ifndef TEST_HAS_NO_WIDE_CHARACTERS
+// static_assert(std::constructible_from<std::basic_string_view<wchar_t>, NonConstConvertibleStringView<wchar_t>>);
+// static_assert(std::convertible_to<NonConstConvertibleStringView<wchar_t>, std::basic_string_view<wchar_t>>);
+
+// static_assert(!std::constructible_from<std::basic_string_view<wchar_t>, const NonConstConvertibleStringView<wchar_t>>);
+// static_assert(!std::convertible_to<const NonConstConvertibleStringView<wchar_t>, std::basic_string_view<wchar_t>>);
+// #endif
+
+struct SomeObject {};
+
+struct NonMode {};
+
+#endif // TEST_STD_INPUTOUTPUT_SPANSTREAMS_TYPES_H
>From 78e6188c877ae562344d4f37a37bfb67ecf37f2c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 09:49:14 +0200
Subject: [PATCH 06/39] Tests: tweaks
---
.../ospanstream/types.compile.pass.cpp | 11 +++---
.../spanbuf/spanbuf.cons/default.pass.cpp | 20 +---------
.../spanbuf/spanbuf.cons/mode.pass.cpp | 9 ++++-
.../spanbuf/spanbuf.cons/move.pass.cpp | 24 ++++++++++--
.../spanbuf/spanbuf.cons/span.mode.pass.cpp | 38 +++++++++++++++++--
.../spanbuf/types.compile.pass.cpp | 11 +++---
.../spanstream/types.compile.pass.cpp | 11 +++---
7 files changed, 83 insertions(+), 41 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
index 595770aa5bd6b0..5374011f61cc27 100644
--- a/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
@@ -28,12 +28,17 @@
#include <type_traits>
#include "constexpr_char_traits.h"
+#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpStream = std::basic_ospanstream<CharT, TraitsT>;
+ // Constructors
+
+ static_assert(!std::is_default_constructible_v<SpStream>);
+
// Types
static_assert(std::is_base_of_v<std::basic_ostream<CharT, TraitsT>, SpStream>);
@@ -50,11 +55,6 @@ void test() {
// Move properties
- static_assert(!std::is_copy_constructible_v<SpStream>);
- static_assert(!std::is_copy_assignable_v<SpStream>);
-
- // Move properties
-
static_assert(std::is_move_constructible_v<SpStream>);
static_assert(std::is_move_assignable_v<SpStream>);
}
@@ -62,6 +62,7 @@ void test() {
void test() {
test<char>();
test<char, constexpr_char_traits<char>>();
+ test<nasty_char, nasty_char_traits>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
test<wchar_t, constexpr_char_traits<wchar_t>>();
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
index 4c6b1ae3080d9e..a94551a96e0002 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
@@ -24,33 +24,17 @@
#include "nasty_string.h"
#include "test_macros.h"
-void test_sfinae_with_nasty_char() {
- using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
-
- static_assert(std::default_initializable<SpBuf>);
-}
-
-template <typename CharT, typename TraitsT = std::char_traits<CharT>>
-void test_sfinae() {
- using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
-
- static_assert(std::default_initializable<SpBuf>);
-}
-
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
- using SpanBuf = std::basic_spanbuf<CharT, TraitsT>;
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
- SpanBuf spBuf;
+ SpBuf spBuf;
assert(spBuf.span().data() == nullptr);
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
int main(int, char**) {
- test_sfinae_with_nasty_char();
- test_sfinae<char>();
- test_sfinae<char, constexpr_char_traits<char>>();
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
index 5a497e5b3238c0..b452b6e80248e1 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
@@ -33,15 +33,20 @@
void test_sfinae_with_nasty_char() {
using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
+ // Mode
static_assert(std::constructible_from<SpBuf, std::ios_base::openmode>);
static_assert(!test_convertible<SpBuf, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpBuf, const NonMode>);
+ static_assert(!test_convertible<SpBuf, const NonMode>());
}
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
- // `Mode`
+ // Mode
static_assert(std::constructible_from<SpBuf, std::ios_base::openmode>);
static_assert(!test_convertible<SpBuf, std::ios_base::openmode>());
@@ -72,7 +77,7 @@ void test() {
}
// Mode: multiple
{
- SpBuf spBuf(std::ios_base::out | std::ios_base::in | std::ios_base::binary);
+ SpBuf spBuf(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
assert(spBuf.span().data() == nullptr);
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
index cfc67b07ea3030..b32f6703981af6 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
@@ -32,7 +32,7 @@ template <typename CharT, typename TraitsT>
struct TestSpanBuf : std::basic_spanbuf<CharT, TraitsT> {
using std::basic_spanbuf<CharT, TraitsT>::basic_spanbuf;
- TestSpanBuf(std::basic_spanbuf<CharT, TraitsT>&& rhs) : std::basic_spanbuf<CharT, TraitsT>(std::move(rhs)) {}
+ TestSpanBuf(std::basic_spanbuf<CharT, TraitsT>&& rhs_p) : std::basic_spanbuf<CharT, TraitsT>(std::move(rhs_p)) {}
void check_postconditions(TestSpanBuf<CharT, TraitsT> const& rhs_p) const {
assert(this->span().data() == rhs_p.span().data());
@@ -67,6 +67,14 @@ void test() {
{
// Empty `span`
{
+ // Mode: default
+ {
+ SpBuf rhsSpBuf;
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
// Mode: `ios_base::in`
{
SpBuf rhsSpBuf{std::ios_base::in};
@@ -98,6 +106,14 @@ void test() {
CharT arr[4];
std::span<CharT> sp{arr};
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
// Mode: `ios_base::in`
{
SpBuf rhsSpBuf{sp, std::ios_base::in};
@@ -129,6 +145,7 @@ void test() {
{
// Empty `span`
{
+ // Mode: default
{
std::span<CharT> sp;
TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
@@ -158,7 +175,7 @@ void test() {
// Mode: multiple
{
std::span<CharT> sp;
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::in | std::ios_base::binary);
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
assert(rhsSpBuf.span().empty());
assert(spBuf.span().data() == nullptr);
@@ -170,6 +187,7 @@ void test() {
{
CharT arr[4];
+ // Mode: default
{
std::span<CharT> sp{arr};
TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
@@ -199,7 +217,7 @@ void test() {
// Mode: multiple
{
std::span<CharT> sp{arr};
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::in | std::ios_base::binary);
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
assert(rhsSpBuf.span().empty());
assert(spBuf.span().data() == arr);
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
index fb58235d8c1fe0..ff600b92e5c025 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
@@ -36,15 +36,20 @@
void test_sfinae_with_nasty_char() {
using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
+ // Mode
static_assert(std::constructible_from<SpBuf, const std::span<nasty_char>, std::ios_base::openmode>);
static_assert(!test_convertible<SpBuf, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpBuf, const std::span<nasty_char>, const NonMode>);
+ static_assert(!test_convertible<SpBuf, const NonMode>());
}
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
- // `Mode`
+ // Mode
static_assert(std::constructible_from<SpBuf, const std::span<CharT>, std::ios_base::openmode>);
static_assert(!test_convertible<SpBuf, const std::span<CharT>, std::ios_base::openmode>());
@@ -63,6 +68,13 @@ void test() {
{
std::span<CharT> sp{};
+ // Mode: default
+ {
+ SpBuf spBuf(sp);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
// Mode: `ios_base::in`
{
SpBuf spBuf(sp, std::ios_base::in);
@@ -89,6 +101,19 @@ void test() {
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
+ // Mode: multiple
+ {
+ SpBuf spBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ {
+ SpBuf spBuf(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
}
// Non-empty `span`
@@ -96,6 +121,13 @@ void test() {
CharT arr[4];
std::span<CharT> sp{arr};
+ // Mode: default
+ {
+ SpBuf spBuf(sp);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
// Mode: `ios_base::in`
{
SpBuf spBuf(sp, std::ios_base::in);
@@ -124,13 +156,13 @@ void test() {
}
// Mode: multiple
{
- SpBuf spBuf(sp, std::ios_base::out | std::ios_base::in);
+ SpBuf spBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
assert(spBuf.span().data() == arr);
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
{
- SpBuf spBuf(std::as_const(sp), std::ios_base::out | std::ios_base::in | std::ios_base::binary);
+ SpBuf spBuf(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
assert(spBuf.span().data() == arr);
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
index 4c18422ebff28c..dec47dbf7b8ebc 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
@@ -28,12 +28,17 @@
#include <type_traits>
#include "constexpr_char_traits.h"
+#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+ // Constructors
+
+ static_assert(std::is_default_constructible_v<SpBuf>);
+
// Types
static_assert(std::is_base_of_v<std::basic_streambuf<CharT, TraitsT>, SpBuf>);
@@ -50,11 +55,6 @@ void test() {
// Move properties
- static_assert(!std::is_copy_constructible_v<SpBuf>);
- static_assert(!std::is_copy_assignable_v<SpBuf>);
-
- // Move properties
-
static_assert(std::is_move_constructible_v<SpBuf>);
static_assert(std::is_move_assignable_v<SpBuf>);
}
@@ -62,6 +62,7 @@ void test() {
void test() {
test<char>();
test<char, constexpr_char_traits<char>>();
+ test<nasty_char, nasty_char_traits>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
test<wchar_t, constexpr_char_traits<wchar_t>>();
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
index 67d29cf041d9cc..7c33c604237a3b 100644
--- a/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
@@ -28,12 +28,17 @@
#include <type_traits>
#include "constexpr_char_traits.h"
+#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpStream = std::basic_spanstream<CharT, TraitsT>;
+ // Constructors
+
+ static_assert(!std::is_default_constructible_v<SpStream>);
+
// Types
static_assert(std::is_base_of_v<std::basic_iostream<CharT, TraitsT>, SpStream>);
@@ -50,11 +55,6 @@ void test() {
// Move properties
- static_assert(!std::is_copy_constructible_v<SpStream>);
- static_assert(!std::is_copy_assignable_v<SpStream>);
-
- // Move properties
-
static_assert(std::is_move_constructible_v<SpStream>);
static_assert(std::is_move_assignable_v<SpStream>);
}
@@ -62,6 +62,7 @@ void test() {
void test() {
test<char>();
test<char, constexpr_char_traits<char>>();
+ test<nasty_char, nasty_char_traits>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
test<wchar_t, constexpr_char_traits<wchar_t>>();
>From bf876525530562ab501e3cd6ef83b1527cd56147 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 09:49:44 +0200
Subject: [PATCH 07/39] Tests: `ispanstream` constructors - WIP
---
.../ispanstream.cons/move.pass.cpp | 81 +++++++++++
.../ispanstream/ispanstream.cons/ros.pass.cpp | 60 ++++++++
.../ispanstream.cons/span.mode.pass.cpp | 136 ++++++++++++++++++
.../ispanstream/types.compile.pass.cpp | 11 +-
4 files changed, 283 insertions(+), 5 deletions(-)
create mode 100644 libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp
new file mode 100644
index 00000000000000..ce711deedc140d
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_ispanstream
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// basic_ispanstream(basic_ispanstream&& rhs);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "nasty_string.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpStream rhsSpStream{sp};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(!sps.span().empty());
+ assert(sps.span().size() == 4);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpStream rhsSpStream{sp, std::ios_base::in};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(!sps.span().empty());
+ assert(sps.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpStream rhsSpStream{sp, std::ios_base::out};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpStream rhsSpStream{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
new file mode 100644
index 00000000000000..d4c9b2a765ac1b
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_ispanstream
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// template<class ROS> explicit basic_ispanstream(ROS&& s);
+
+#include <cassert>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "nasty_string.h"
+#include "test_macros.h"
+
+void test_sfinae_with_nasty_char() {
+ using SpStream = std::basic_ispanstream<nasty_char, nasty_char_traits>;
+
+ // TODO:
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test_sfinae() {
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+
+ // TODO:
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+
+ // TODO:
+}
+
+int main(int, char**) {
+ test_sfinae_with_nasty_char();
+ test_sfinae<char>();
+ test_sfinae<char, constexpr_char_traits<char>>();
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
new file mode 100644
index 00000000000000..0938e35d0fb60a
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
@@ -0,0 +1,136 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_ispanstream
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// explicit basic_ispanstream(std::span<charT> s,
+// ios_base::openmode which = ios_base::in);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+#include <utility>
+
+#include "constexpr_char_traits.h"
+#include "nasty_string.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+#include "../../macros.h"
+#include "../../types.h"
+
+void test_sfinae_with_nasty_char() {
+ using SpStream = std::basic_ispanstream<nasty_char, nasty_char_traits>;
+
+ // Mode
+ static_assert(std::constructible_from<SpStream, const std::span<nasty_char>, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpStream, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpStream, const std::span<nasty_char>, const NonMode>);
+ static_assert(!test_convertible<SpStream, const std::span<nasty_char>, const NonMode>());
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test_sfinae() {
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+
+ // Mode
+ static_assert(std::constructible_from<SpStream, const std::span<CharT>, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpStream, const std::span<CharT>, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpStream, const std::span<CharT>, const NonMode>);
+ static_assert(!test_convertible<SpStream, const std::span<CharT>, const NonMode>());
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpStream sps(sp);
+ assert(sps.span().data() == arr);
+ assert(!sps.span().empty());
+ assert(sps.span().size() == 4);
+ }
+ {
+ SpStream sps(std::as_const(sp));
+ assert(sps.span().data() == arr);
+ assert(!sps.span().empty());
+ assert(sps.span().size() == 4);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpStream sps(sp, std::ios_base::in);
+ assert(sps.span().data() == arr);
+ assert(!sps.span().empty());
+ assert(sps.span().size() == 4);
+ }
+ {
+ SpStream sps(std::as_const(sp), std::ios_base::in);
+ assert(sps.span().data() == arr);
+ assert(!sps.span().empty());
+ assert(sps.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpStream sps(sp, std::ios_base::out);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ {
+ SpStream sps(std::as_const(sp), std::ios_base::out);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpStream sps(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ {
+ SpStream sps(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test_sfinae_with_nasty_char();
+ test_sfinae<char>();
+ test_sfinae<char, constexpr_char_traits<char>>();
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_sfinae<wchar_t>();
+ test_sfinae<wchar_t, constexpr_char_traits<wchar_t>>();
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
\ No newline at end of file
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
index c566a3fce647dc..ddd15186b7c189 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
@@ -28,12 +28,17 @@
#include <type_traits>
#include "constexpr_char_traits.h"
+#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+ // Constructors
+
+ static_assert(!std::is_default_constructible_v<SpStream>);
+
// Types
static_assert(std::is_base_of_v<std::basic_istream<CharT, TraitsT>, SpStream>);
@@ -50,11 +55,6 @@ void test() {
// Move properties
- static_assert(!std::is_copy_constructible_v<SpStream>);
- static_assert(!std::is_copy_assignable_v<SpStream>);
-
- // Move properties
-
static_assert(std::is_move_constructible_v<SpStream>);
static_assert(std::is_move_assignable_v<SpStream>);
}
@@ -62,6 +62,7 @@ void test() {
void test() {
test<char>();
test<char, constexpr_char_traits<char>>();
+ test<nasty_char, nasty_char_traits>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
test<wchar_t, constexpr_char_traits<wchar_t>>();
>From 70a7fa16c29f929f6603a37084f99eeb5a64f644 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 10:52:23 +0200
Subject: [PATCH 08/39] Implementation: fixed module and forward declarations
---
libcxx/include/libcxx.imp | 2 +-
libcxx/modules/std/spanstream.inc | 4 ++--
libcxx/utils/generate_iwyu_mapping.py | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp
index 7e9d6e37800f89..790b2e7e4df461 100644
--- a/libcxx/include/libcxx.imp
+++ b/libcxx/include/libcxx.imp
@@ -434,7 +434,7 @@
{ include: [ "<__fwd/ostream.h>", "private", "<iosfwd>", "public" ] },
{ include: [ "<__fwd/pair.h>", "private", "<utility>", "public" ] },
{ include: [ "<__fwd/span.h>", "private", "<span>", "public" ] },
- { include: [ "<__fwd/spanstream.h>", "private", "<spanstream>", "public" ] },
+ { include: [ "<__fwd/spanstream.h>", "private", "<iosfwd>", "public" ] },
{ include: [ "<__fwd/sstream.h>", "private", "<iosfwd>", "public" ] },
{ include: [ "<__fwd/streambuf.h>", "private", "<iosfwd>", "public" ] },
{ include: [ "<__fwd/string.h>", "private", "<string>", "public" ] },
diff --git a/libcxx/modules/std/spanstream.inc b/libcxx/modules/std/spanstream.inc
index e6383a185e0798..c9a50f0c2b8410 100644
--- a/libcxx/modules/std/spanstream.inc
+++ b/libcxx/modules/std/spanstream.inc
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
export namespace std {
-#if 0
+#if _LIBCPP_STD_VER >= 23
using std::basic_spanbuf;
using std::swap;
@@ -38,5 +38,5 @@ export namespace std {
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
using std::wspanstream;
# endif
-#endif
+#endif // _LIBCPP_STD_VER >= 23
} // namespace std
diff --git a/libcxx/utils/generate_iwyu_mapping.py b/libcxx/utils/generate_iwyu_mapping.py
index 8ab7b86299edca..76e55b60a07df1 100644
--- a/libcxx/utils/generate_iwyu_mapping.py
+++ b/libcxx/utils/generate_iwyu_mapping.py
@@ -38,7 +38,7 @@ def IWYU_mapping(header: str) -> typing.Optional[typing.List[str]]:
return ["utility"]
elif header == "__fwd/subrange.h":
return ["ranges"]
- elif re.match("__fwd/(fstream|ios|istream|ostream|sstream|streambuf)[.]h", header):
+ elif re.match("__fwd/(fstream|ios|istream|ostream|spanstream|sstream|streambuf)[.]h", header):
return ["iosfwd"]
# Handle remaining forward declaration headers
elif re.match("__fwd/(.+)[.]h", header):
>From d1e19b9287ba3fffd168e5b583344239e728950f Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 10:56:25 +0200
Subject: [PATCH 09/39] Implementation: fixed python code formatting
---
libcxx/utils/generate_iwyu_mapping.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libcxx/utils/generate_iwyu_mapping.py b/libcxx/utils/generate_iwyu_mapping.py
index 76e55b60a07df1..b5098fafedbb48 100644
--- a/libcxx/utils/generate_iwyu_mapping.py
+++ b/libcxx/utils/generate_iwyu_mapping.py
@@ -38,7 +38,9 @@ def IWYU_mapping(header: str) -> typing.Optional[typing.List[str]]:
return ["utility"]
elif header == "__fwd/subrange.h":
return ["ranges"]
- elif re.match("__fwd/(fstream|ios|istream|ostream|spanstream|sstream|streambuf)[.]h", header):
+ elif re.match(
+ "__fwd/(fstream|ios|istream|ostream|spanstream|sstream|streambuf)[.]h", header
+ ):
return ["iosfwd"]
# Handle remaining forward declaration headers
elif re.match("__fwd/(.+)[.]h", header):
>From 439e10b09c5042b39d4808c77fe6533eb28ad61d Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 11:20:59 +0200
Subject: [PATCH 10/39] Implementation: updated transitive includes
---
libcxx/test/libcxx/transitive_includes/cxx03.csv | 8 ++++++++
libcxx/test/libcxx/transitive_includes/cxx11.csv | 8 ++++++++
libcxx/test/libcxx/transitive_includes/cxx14.csv | 8 ++++++++
libcxx/test/libcxx/transitive_includes/cxx17.csv | 8 ++++++++
libcxx/test/libcxx/transitive_includes/cxx20.csv | 8 ++++++++
libcxx/test/libcxx/transitive_includes/cxx23.csv | 7 +++++++
libcxx/test/libcxx/transitive_includes/cxx26.csv | 7 +++++++
7 files changed, 54 insertions(+)
diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv
index 678a986e522aa0..9ddfabc83c4b6c 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx03.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv
@@ -741,6 +741,14 @@ span limits
span stdexcept
span type_traits
span version
+spanstream cstddef
+spanstream initializer_list
+spanstream iostream
+spanstream limits
+spanstream span
+spanstream streambuf
+spanstream type_traits
+spanstream version
sstream cstddef
sstream istream
sstream ostream
diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv
index c3875fa2cfc06f..f6ab0e508e2dd6 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx11.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv
@@ -747,6 +747,14 @@ span limits
span stdexcept
span type_traits
span version
+spanstream cstddef
+spanstream initializer_list
+spanstream iostream
+spanstream limits
+spanstream span
+spanstream streambuf
+spanstream type_traits
+spanstream version
sstream cstddef
sstream istream
sstream ostream
diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv
index e28e0cd44fed95..b9adc215cf5e12 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx14.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv
@@ -749,6 +749,14 @@ span limits
span stdexcept
span type_traits
span version
+spanstream cstddef
+spanstream initializer_list
+spanstream iostream
+spanstream limits
+spanstream span
+spanstream streambuf
+spanstream type_traits
+spanstream version
sstream cstddef
sstream istream
sstream ostream
diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv
index e28e0cd44fed95..b9adc215cf5e12 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx17.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv
@@ -749,6 +749,14 @@ span limits
span stdexcept
span type_traits
span version
+spanstream cstddef
+spanstream initializer_list
+spanstream iostream
+spanstream limits
+spanstream span
+spanstream streambuf
+spanstream type_traits
+spanstream version
sstream cstddef
sstream istream
sstream ostream
diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv
index eec71f4fc6282e..ee9a1ceb112ecc 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx20.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv
@@ -754,6 +754,14 @@ span limits
span stdexcept
span type_traits
span version
+spanstream cstddef
+spanstream initializer_list
+spanstream iostream
+spanstream limits
+spanstream span
+spanstream streambuf
+spanstream type_traits
+spanstream version
sstream cstddef
sstream istream
sstream ostream
diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv
index daa3e17698bbed..1896a2d34215c0 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx23.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv
@@ -514,6 +514,13 @@ span initializer_list
span limits
span stdexcept
span version
+spanstream cstddef
+spanstream initializer_list
+spanstream iostream
+spanstream limits
+spanstream span
+spanstream streambuf
+spanstream version
sstream cstddef
sstream istream
sstream ostream
diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv
index daa3e17698bbed..1896a2d34215c0 100644
--- a/libcxx/test/libcxx/transitive_includes/cxx26.csv
+++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv
@@ -514,6 +514,13 @@ span initializer_list
span limits
span stdexcept
span version
+spanstream cstddef
+spanstream initializer_list
+spanstream iostream
+spanstream limits
+spanstream span
+spanstream streambuf
+spanstream version
sstream cstddef
sstream istream
sstream ostream
>From 746cfaf8b3713031950cecf5f5b451f0e882e00a Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 11:45:01 +0200
Subject: [PATCH 11/39] Implementation: fix CI
---
libcxx/include/spanstream | 1 +
1 file changed, 1 insertion(+)
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index 16bbf04d81c559..814fa9a6f00e26 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -56,6 +56,7 @@
#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
+#include <__concepts/convertible_to.h>
#include <__config>
#include <__fwd/spanstream.h>
#include <__memory/addressof.h>
>From f6d959c1c6766891c64ea9308fe169490727d9ae Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 13:33:23 +0200
Subject: [PATCH 12/39] Implementation: try to fix CI
---
.../ispanstream/ispanstream.cons/move.pass.cpp | 1 -
.../ispanstream/ispanstream.cons/ros.pass.cpp | 4 ++++
.../ispanstream.cons/span.mode.pass.cpp | 4 ++++
.../ispanstream/types.compile.pass.cpp | 4 +++-
.../ospanstream/types.compile.pass.cpp | 4 +++-
.../spanbuf/spanbuf.cons/default.pass.cpp | 1 -
.../spanbuf/spanbuf.cons/mode.pass.cpp | 4 ++++
.../spanbuf/spanbuf.cons/move.pass.cpp | 17 -----------------
.../spanbuf/spanbuf.cons/span.mode.pass.cpp | 4 ++++
.../span.streams/spanbuf/types.compile.pass.cpp | 4 +++-
.../spanstream/types.compile.pass.cpp | 4 +++-
11 files changed, 28 insertions(+), 23 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp
index ce711deedc140d..1b456a8a0ef38b 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp
@@ -24,7 +24,6 @@
#include <spanstream>
#include "constexpr_char_traits.h"
-#include "nasty_string.h"
#include "test_convertible.h"
#include "test_macros.h"
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
index d4c9b2a765ac1b..421ba8ff10e169 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
@@ -25,11 +25,13 @@
#include "nasty_string.h"
#include "test_macros.h"
+#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
using SpStream = std::basic_ispanstream<nasty_char, nasty_char_traits>;
// TODO:
}
+#endif // TEST_HAS_NO_NASTY_STRING
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
@@ -46,7 +48,9 @@ void test() {
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
test_sfinae_with_nasty_char();
+#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
test<char>();
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
index 0938e35d0fb60a..cd793210e2c063 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
@@ -33,6 +33,7 @@
#include "../../macros.h"
#include "../../types.h"
+#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
using SpStream = std::basic_ispanstream<nasty_char, nasty_char_traits>;
@@ -44,6 +45,7 @@ void test_sfinae_with_nasty_char() {
static_assert(!std::constructible_from<SpStream, const std::span<nasty_char>, const NonMode>);
static_assert(!test_convertible<SpStream, const std::span<nasty_char>, const NonMode>());
}
+#endif // TEST_HAS_NO_NASTY_STRING
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
@@ -120,7 +122,9 @@ void test() {
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
test_sfinae_with_nasty_char();
+#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
test<char>();
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
index ddd15186b7c189..9b492a9c59985e 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/types.compile.pass.cpp
@@ -60,9 +60,11 @@ void test() {
}
void test() {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
- test<nasty_char, nasty_char_traits>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
test<wchar_t, constexpr_char_traits<wchar_t>>();
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
index 5374011f61cc27..71f76790d66fdf 100644
--- a/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/types.compile.pass.cpp
@@ -60,9 +60,11 @@ void test() {
}
void test() {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
- test<nasty_char, nasty_char_traits>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
test<wchar_t, constexpr_char_traits<wchar_t>>();
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
index a94551a96e0002..b76af127f43144 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
@@ -21,7 +21,6 @@
#include <spanstream>
#include "constexpr_char_traits.h"
-#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
index b452b6e80248e1..eb8b29de9fbff0 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
@@ -30,6 +30,7 @@
#include "../../types.h"
+#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
@@ -41,6 +42,7 @@ void test_sfinae_with_nasty_char() {
static_assert(!std::constructible_from<SpBuf, const NonMode>);
static_assert(!test_convertible<SpBuf, const NonMode>());
}
+#endif // TEST_HAS_NO_NASTY_STRING
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
@@ -85,7 +87,9 @@ void test() {
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
test_sfinae_with_nasty_char();
+#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
test<char>();
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
index b32f6703981af6..1bab0f860d9f34 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
@@ -24,7 +24,6 @@
#include <spanstream>
#include "constexpr_char_traits.h"
-#include "nasty_string.h"
#include "test_convertible.h"
#include "test_macros.h"
@@ -47,19 +46,6 @@ struct TestSpanBuf : std::basic_spanbuf<CharT, TraitsT> {
}
};
-void test_sfinae_with_nasty_char() {
- using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
-
- static_assert(std::move_constructible<SpBuf>);
-}
-
-template <typename CharT, typename TraitsT = std::char_traits<CharT>>
-void test_sfinae() {
- using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
-
- static_assert(std::move_constructible<SpBuf>);
-}
-
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
@@ -228,9 +214,6 @@ void test() {
}
int main(int, char**) {
- test_sfinae_with_nasty_char();
- test_sfinae<char>();
- test_sfinae<char, constexpr_char_traits<char>>();
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
index ff600b92e5c025..fbcc8eeded2595 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
@@ -33,6 +33,7 @@
#include "../../macros.h"
#include "../../types.h"
+#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
@@ -44,6 +45,7 @@ void test_sfinae_with_nasty_char() {
static_assert(!std::constructible_from<SpBuf, const std::span<nasty_char>, const NonMode>);
static_assert(!test_convertible<SpBuf, const NonMode>());
}
+#endif // TEST_HAS_NO_NASTY_STRING
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
@@ -171,7 +173,9 @@ void test() {
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
test_sfinae_with_nasty_char();
+#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
test<char>();
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
index dec47dbf7b8ebc..7ffbb9d24eab90 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/types.compile.pass.cpp
@@ -60,9 +60,11 @@ void test() {
}
void test() {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
- test<nasty_char, nasty_char_traits>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
test<wchar_t, constexpr_char_traits<wchar_t>>();
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
index 7c33c604237a3b..83f6b235ae9135 100644
--- a/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanstream/types.compile.pass.cpp
@@ -60,9 +60,11 @@ void test() {
}
void test() {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
- test<nasty_char, nasty_char_traits>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<wchar_t>();
test<wchar_t, constexpr_char_traits<wchar_t>>();
>From 51f08ffd2ac4c6d8a6d62c6324af4071ced96cf3 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 14:47:23 +0200
Subject: [PATCH 13/39] Implementation: fixes
---
libcxx/include/spanstream | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index 814fa9a6f00e26..9f048a065c5c05 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -323,7 +323,7 @@ public:
basic_ospanstream(const basic_ospanstream&) = delete;
_LIBCPP_HIDE_FROM_ABI basic_ospanstream(basic_ospanstream&& __rhs)
- : basic_ospanstream(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
+ : basic_ostream(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
basic_ostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
}
@@ -382,7 +382,7 @@ public:
basic_spanstream(const basic_spanstream&) = delete;
_LIBCPP_HIDE_FROM_ABI basic_spanstream(basic_spanstream&& __rhs)
- : basic_spanstream(std::move(__rhs)), __sb_(__rhs.__sb_) {
+ : basic_iostream(std::move(__rhs)), __sb_(__rhs.__sb_) {
basic_iostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
}
>From 041051a943bf2b39eb001e6f0d86e894288414f5 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 15:53:25 +0200
Subject: [PATCH 14/39] Implementation: fixes
---
libcxx/include/spanstream | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index 9f048a065c5c05..1cad46a2cd1f5c 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -323,7 +323,7 @@ public:
basic_ospanstream(const basic_ospanstream&) = delete;
_LIBCPP_HIDE_FROM_ABI basic_ospanstream(basic_ospanstream&& __rhs)
- : basic_ostream(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
+ : basic_iostream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
basic_ostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
}
@@ -382,7 +382,7 @@ public:
basic_spanstream(const basic_spanstream&) = delete;
_LIBCPP_HIDE_FROM_ABI basic_spanstream(basic_spanstream&& __rhs)
- : basic_iostream(std::move(__rhs)), __sb_(__rhs.__sb_) {
+ : basic_iostream<_CharT, _Traits>(std::move(__rhs)), __sb_(__rhs.__sb_) {
basic_iostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
}
>From ecabe340dc33de6c7b16301046b5053bb45cbfac Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 1 Mar 2024 16:35:45 +0200
Subject: [PATCH 15/39] Tests: `ospanstream` and `spanstream` constructors +
fixes
---
libcxx/include/spanstream | 14 +-
.../ospanstream.cons/move.pass.cpp | 80 ++++++++++
.../ospanstream.cons/span.mode.pass.cpp | 140 ++++++++++++++++++
.../spanstream/spanstream.cons/move.pass.cpp | 80 ++++++++++
.../spanstream.cons/span.mode.pass.cpp | 140 ++++++++++++++++++
5 files changed, 449 insertions(+), 5 deletions(-)
create mode 100644 libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/move.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/move.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index 1cad46a2cd1f5c..6a3911a08a0476 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -323,7 +323,7 @@ public:
basic_ospanstream(const basic_ospanstream&) = delete;
_LIBCPP_HIDE_FROM_ABI basic_ospanstream(basic_ospanstream&& __rhs)
- : basic_iostream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
+ : basic_ostream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
basic_ostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
}
@@ -344,9 +344,11 @@ public:
// [ospanstream.members], member functions
- _LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
+ _LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept {
+ return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::addressof(__sb_));
+ }
- _LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept { return __sb_.rdbuf()->span(); }
+ _LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept { return rdbuf()->span(); }
_LIBCPP_HIDE_FROM_ABI void span(std::span<_CharT> __s) noexcept { rdbuf()->span(__s); }
@@ -382,7 +384,7 @@ public:
basic_spanstream(const basic_spanstream&) = delete;
_LIBCPP_HIDE_FROM_ABI basic_spanstream(basic_spanstream&& __rhs)
- : basic_iostream<_CharT, _Traits>(std::move(__rhs)), __sb_(__rhs.__sb_) {
+ : basic_iostream<_CharT, _Traits>(std::move(__rhs)), __sb_(std::move(__rhs.__sb_)) {
basic_iostream<_CharT, _Traits>::set_rdbuf(std::addressof(__sb_));
}
@@ -403,7 +405,9 @@ public:
// [spanstream.members], members
- _LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept { return __sb_; }
+ _LIBCPP_HIDE_FROM_ABI basic_spanbuf<_CharT, _Traits>* rdbuf() const noexcept {
+ return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::addressof(__sb_));
+ }
_LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept { return rdbuf()->span(); }
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/move.pass.cpp
new file mode 100644
index 00000000000000..895e07cdf7ecbd
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/move.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_ospanstream
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// basic_ospanstream(basic_ospanstream&& rhs);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ospanstream<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpStream rhsSpStream{sp};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpStream rhsSpStream{sp, std::ios_base::in};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode `ios_base::out`
+ {
+ SpStream rhsSpStream{sp, std::ios_base::out};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpStream rhsSpStream{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
new file mode 100644
index 00000000000000..086ea7c7653826
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
@@ -0,0 +1,140 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_ospanstream
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// explicit basic_ospanstream(std::span<charT> s,
+// ios_base::openmode which = ios_base::in);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+#include <utility>
+
+#include "constexpr_char_traits.h"
+#include "nasty_string.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+#include "../../macros.h"
+#include "../../types.h"
+
+#ifndef TEST_HAS_NO_NASTY_STRING
+void test_sfinae_with_nasty_char() {
+ using SpStream = std::basic_ospanstream<nasty_char, nasty_char_traits>;
+
+ // Mode
+ static_assert(std::constructible_from<SpStream, const std::span<nasty_char>, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpStream, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpStream, const std::span<nasty_char>, const NonMode>);
+ static_assert(!test_convertible<SpStream, const std::span<nasty_char>, const NonMode>());
+}
+#endif // TEST_HAS_NO_NASTY_STRING
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test_sfinae() {
+ using SpStream = std::basic_ospanstream<CharT, TraitsT>;
+
+ // Mode
+ static_assert(std::constructible_from<SpStream, const std::span<CharT>, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpStream, const std::span<CharT>, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpStream, const std::span<CharT>, const NonMode>);
+ static_assert(!test_convertible<SpStream, const std::span<CharT>, const NonMode>());
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ospanstream<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpStream sps(sp);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ {
+ SpStream sps(std::as_const(sp));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpStream sps(sp, std::ios_base::in);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ {
+ SpStream sps(std::as_const(sp), std::ios_base::in);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode `ios_base::out`
+ {
+ SpStream sps(sp, std::ios_base::out);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ {
+ SpStream sps(std::as_const(sp), std::ios_base::out);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpStream sps(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ {
+ SpStream sps(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test_sfinae_with_nasty_char();
+#endif
+ test_sfinae<char>();
+ test_sfinae<char, constexpr_char_traits<char>>();
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_sfinae<wchar_t>();
+ test_sfinae<wchar_t, constexpr_char_traits<wchar_t>>();
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
\ No newline at end of file
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/move.pass.cpp
new file mode 100644
index 00000000000000..1a02487d07198c
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/move.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanstream
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// basic_spanstream(basic_spanstream&& rhs);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_spanstream<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpStream rhsSpStream{sp};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpStream rhsSpStream{sp, std::ios_base::in};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(!sps.span().empty());
+ assert(sps.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpStream rhsSpStream{sp, std::ios_base::out};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpStream rhsSpStream{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpStream sps(std::move(rhsSpStream));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
new file mode 100644
index 00000000000000..8fcc216b2ef6b5
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
@@ -0,0 +1,140 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanstream
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// explicit basic_spanstream(std::span<charT> s,
+// ios_base::openmode which = ios_base::in);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+#include <utility>
+
+#include "constexpr_char_traits.h"
+#include "nasty_string.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+#include "../../macros.h"
+#include "../../types.h"
+
+#ifndef TEST_HAS_NO_NASTY_STRING
+void test_sfinae_with_nasty_char() {
+ using SpStream = std::basic_spanstream<nasty_char, nasty_char_traits>;
+
+ // Mode
+ static_assert(std::constructible_from<SpStream, const std::span<nasty_char>, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpStream, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpStream, const std::span<nasty_char>, const NonMode>);
+ static_assert(!test_convertible<SpStream, const std::span<nasty_char>, const NonMode>());
+}
+#endif // TEST_HAS_NO_NASTY_STRING
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test_sfinae() {
+ using SpStream = std::basic_spanstream<CharT, TraitsT>;
+
+ // Mode
+ static_assert(std::constructible_from<SpStream, const std::span<CharT>, std::ios_base::openmode>);
+ static_assert(!test_convertible<SpStream, const std::span<CharT>, std::ios_base::openmode>());
+
+ // Non-mode
+ static_assert(!std::constructible_from<SpStream, const std::span<CharT>, const NonMode>);
+ static_assert(!test_convertible<SpStream, const std::span<CharT>, const NonMode>());
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_spanstream<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpStream sps(sp);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ {
+ SpStream sps(std::as_const(sp));
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpStream sps(sp, std::ios_base::in);
+ assert(sps.span().data() == arr);
+ assert(!sps.span().empty());
+ assert(sps.span().size() == 4);
+ }
+ {
+ SpStream sps(std::as_const(sp), std::ios_base::in);
+ assert(sps.span().data() == arr);
+ assert(!sps.span().empty());
+ assert(sps.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpStream sps(sp, std::ios_base::out);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ {
+ SpStream sps(std::as_const(sp), std::ios_base::out);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpStream sps(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+ {
+ SpStream sps(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(sps.span().data() == arr);
+ assert(sps.span().empty());
+ assert(sps.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test_sfinae_with_nasty_char();
+#endif
+ test_sfinae<char>();
+ test_sfinae<char, constexpr_char_traits<char>>();
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_sfinae<wchar_t>();
+ test_sfinae<wchar_t, constexpr_char_traits<wchar_t>>();
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
\ No newline at end of file
>From 47a21e0045e5bb593d583ade080acff82b9f512c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 2 Mar 2024 08:26:39 +0200
Subject: [PATCH 16/39] Tests: `ispanstream` added assign and swap
---
libcxx/include/spanstream | 45 ++++++----
.../ispanstream.assign/move.pass.cpp | 80 ++++++++++++++++++
.../ispanstream.assign/swap.pass.cpp | 83 +++++++++++++++++++
.../swap_nonmember.pass.cpp | 79 ++++++++++++++++++
.../ispanstream.cons/move.pass.cpp | 40 ++++-----
.../ispanstream.cons/span.mode.pass.cpp | 64 +++++++-------
.../ospanstream.cons/move.pass.cpp | 40 ++++-----
.../ospanstream.cons/span.mode.pass.cpp | 64 +++++++-------
.../spanstream/spanstream.cons/move.pass.cpp | 40 ++++-----
.../spanstream.cons/span.mode.pass.cpp | 64 +++++++-------
10 files changed, 427 insertions(+), 172 deletions(-)
create mode 100644 libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/move.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap_nonmember.pass.cpp
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index 6a3911a08a0476..70e6faa4206fbe 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -167,24 +167,37 @@ protected:
if ((__which & ios_base::in) && (__which & ios_base::out) && (ios_base::cur == __way))
return __error;
- off_type __baseoff = [this, __way, __which] {
- switch (__way) {
- case ios_base::beg:
- return off_type(0);
-
- case ios_base::cur:
- if (__which & ios_base::out)
- return off_type(this->pptr() - this->pbase());
- return off_type(this->gptr() - this->eback());
-
- case ios_base::end:
- if ((__which & ios_base::out) && !(__which & ios_base::in))
- return off_type(this->pptr() - this->pbase());
- return off_type(__buf_.size());
- }
- }();
+ // Calculate __baseoff
+
+ off_type __baseoff;
+
+ switch (__way) {
+ case ios_base::beg:
+ __baseoff = off_type(0);
+ break;
+
+ case ios_base::cur:
+ if (__which & ios_base::out)
+ __baseoff = off_type(this->pptr() - this->pbase());
+ else
+ __baseoff = off_type(this->gptr() - this->eback());
+ break;
+
+ case ios_base::end:
+ if ((__which & ios_base::out) && !(__which & ios_base::in))
+ __baseoff = off_type(this->pptr() - this->pbase());
+ else
+ __baseoff = off_type(__buf_.size());
+ break;
+
+ default:
+ return __error;
+ };
+
+ // Calculate __newoff
off_type __newoff;
+
if (__builtin_add_overflow(__baseoff, __off, &__newoff) || (__newoff < off_type(0)) ||
(std::cmp_greater(__newoff, __buf_.size())))
return __error;
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/move.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/move.pass.cpp
new file mode 100644
index 00000000000000..117e2a6828e9da
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/move.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_ispanstream
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// basic_ispanstream& operator=(basic_ispanstream&& rhs);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpStream rhsSpSt{sp};
+ SpStream spSt = std::move(rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpStream rhsSpSt{sp, std::ios_base::in};
+ SpStream spSt = std::move(rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpStream rhsSpSt{sp, std::ios_base::out};
+ SpStream spSt = std::move(rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpStream rhsSpSt{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpStream spSt = std::move(rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap.pass.cpp
new file mode 100644
index 00000000000000..45fc6370a06d40
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_ispanstream
+// : public basic_streambuf<charT, traits> {
+
+// // [ispanstream.swap], swap
+// void swap(basic_ispanstream& rhs);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpStream rhsSpSt{sp};
+ SpStream spSt(std::span<CharT>{});
+ spSt.swap(rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpStream rhsSpSt{sp, std::ios_base::in};
+ SpStream spSt(std::span<CharT>{});
+ spSt.swap(rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpStream rhsSpSt{sp, std::ios_base::out};
+ SpStream spSt(std::span<CharT>{});
+ spSt.swap(rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpStream rhsSpSt{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpStream spSt(std::span<CharT>{});
+ spSt.swap(rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap_nonmember.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap_nonmember.pass.cpp
new file mode 100644
index 00000000000000..ae54e409297454
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap_nonmember.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits>
+// void swap(basic_ispanstream<charT, traits>& x, basic_ispanstream<charT, traits>& y);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpStream rhsSpSt{sp};
+ SpStream spSt(std::span<CharT>{});
+ std::swap(spSt, rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpStream rhsSpSt{sp, std::ios_base::in};
+ SpStream spSt(std::span<CharT>{});
+ std::swap(spSt, rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpStream rhsSpSt{sp, std::ios_base::out};
+ SpStream spSt(std::span<CharT>{});
+ std::swap(spSt, rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpStream rhsSpSt{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpStream spSt(std::span<CharT>{});
+ std::swap(spSt, rhsSpSt);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp
index 1b456a8a0ef38b..2207b773bd9cef 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/move.pass.cpp
@@ -36,35 +36,35 @@ void test() {
// Mode: default
{
- SpStream rhsSpStream{sp};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(!sps.span().empty());
- assert(sps.span().size() == 4);
+ SpStream rhsSpSt{sp};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
}
// Mode: `ios_base::in`
{
- SpStream rhsSpStream{sp, std::ios_base::in};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(!sps.span().empty());
- assert(sps.span().size() == 4);
+ SpStream rhsSpSt{sp, std::ios_base::in};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
}
// Mode `ios_base::out`
{
- SpStream rhsSpStream{sp, std::ios_base::out};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream rhsSpSt{sp, std::ios_base::out};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: multiple
{
- SpStream rhsSpStream{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream rhsSpSt{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
}
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
index cd793210e2c063..3502bbc1d676d7 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
@@ -69,55 +69,55 @@ void test() {
// Mode: default
{
- SpStream sps(sp);
- assert(sps.span().data() == arr);
- assert(!sps.span().empty());
- assert(sps.span().size() == 4);
+ SpStream spSt(sp);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
}
{
- SpStream sps(std::as_const(sp));
- assert(sps.span().data() == arr);
- assert(!sps.span().empty());
- assert(sps.span().size() == 4);
+ SpStream spSt(std::as_const(sp));
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
}
// Mode: `ios_base::in`
{
- SpStream sps(sp, std::ios_base::in);
- assert(sps.span().data() == arr);
- assert(!sps.span().empty());
- assert(sps.span().size() == 4);
+ SpStream spSt(sp, std::ios_base::in);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
}
{
- SpStream sps(std::as_const(sp), std::ios_base::in);
- assert(sps.span().data() == arr);
- assert(!sps.span().empty());
- assert(sps.span().size() == 4);
+ SpStream spSt(std::as_const(sp), std::ios_base::in);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
}
// Mode `ios_base::out`
{
- SpStream sps(sp, std::ios_base::out);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(sp, std::ios_base::out);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
{
- SpStream sps(std::as_const(sp), std::ios_base::out);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(std::as_const(sp), std::ios_base::out);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: multiple
{
- SpStream sps(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
{
- SpStream sps(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
}
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/move.pass.cpp
index 895e07cdf7ecbd..43354d6b8dfcba 100644
--- a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/move.pass.cpp
@@ -36,35 +36,35 @@ void test() {
// Mode: default
{
- SpStream rhsSpStream{sp};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream rhsSpSt{sp};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: `ios_base::in`
{
- SpStream rhsSpStream{sp, std::ios_base::in};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream rhsSpSt{sp, std::ios_base::in};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode `ios_base::out`
{
- SpStream rhsSpStream{sp, std::ios_base::out};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream rhsSpSt{sp, std::ios_base::out};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: multiple
{
- SpStream rhsSpStream{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream rhsSpSt{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
}
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
index 086ea7c7653826..f353719875bc96 100644
--- a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
@@ -69,55 +69,55 @@ void test() {
// Mode: default
{
- SpStream sps(sp);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(sp);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
{
- SpStream sps(std::as_const(sp));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(std::as_const(sp));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: `ios_base::in`
{
- SpStream sps(sp, std::ios_base::in);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(sp, std::ios_base::in);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
{
- SpStream sps(std::as_const(sp), std::ios_base::in);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(std::as_const(sp), std::ios_base::in);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode `ios_base::out`
{
- SpStream sps(sp, std::ios_base::out);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(sp, std::ios_base::out);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
{
- SpStream sps(std::as_const(sp), std::ios_base::out);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(std::as_const(sp), std::ios_base::out);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: multiple
{
- SpStream sps(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
{
- SpStream sps(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
}
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/move.pass.cpp
index 1a02487d07198c..73206597cd27d5 100644
--- a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/move.pass.cpp
@@ -36,35 +36,35 @@ void test() {
// Mode: default
{
- SpStream rhsSpStream{sp};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream rhsSpSt{sp};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: `ios_base::in`
{
- SpStream rhsSpStream{sp, std::ios_base::in};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(!sps.span().empty());
- assert(sps.span().size() == 4);
+ SpStream rhsSpSt{sp, std::ios_base::in};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
}
// Mode `ios_base::out`
{
- SpStream rhsSpStream{sp, std::ios_base::out};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream rhsSpSt{sp, std::ios_base::out};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: multiple
{
- SpStream rhsSpStream{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
- SpStream sps(std::move(rhsSpStream));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream rhsSpSt{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpStream spSt(std::move(rhsSpSt));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
}
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
index 8fcc216b2ef6b5..61a1a2530ad754 100644
--- a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
@@ -69,55 +69,55 @@ void test() {
// Mode: default
{
- SpStream sps(sp);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(sp);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
{
- SpStream sps(std::as_const(sp));
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(std::as_const(sp));
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: `ios_base::in`
{
- SpStream sps(sp, std::ios_base::in);
- assert(sps.span().data() == arr);
- assert(!sps.span().empty());
- assert(sps.span().size() == 4);
+ SpStream spSt(sp, std::ios_base::in);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
}
{
- SpStream sps(std::as_const(sp), std::ios_base::in);
- assert(sps.span().data() == arr);
- assert(!sps.span().empty());
- assert(sps.span().size() == 4);
+ SpStream spSt(std::as_const(sp), std::ios_base::in);
+ assert(spSt.span().data() == arr);
+ assert(!spSt.span().empty());
+ assert(spSt.span().size() == 4);
}
// Mode `ios_base::out`
{
- SpStream sps(sp, std::ios_base::out);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(sp, std::ios_base::out);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
{
- SpStream sps(std::as_const(sp), std::ios_base::out);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(std::as_const(sp), std::ios_base::out);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
// Mode: multiple
{
- SpStream sps(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
{
- SpStream sps(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- assert(sps.span().data() == arr);
- assert(sps.span().empty());
- assert(sps.span().size() == 0);
+ SpStream spSt(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
}
}
>From 1ca4160bf301b272ffd58944d750d4b9a9cfffbd Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 3 Mar 2024 18:08:43 +0200
Subject: [PATCH 17/39] Tests: added `ReadonlySpan` type
---
.../ispanstream/ispanstream.cons/ros.pass.cpp | 2 +
.../std/input.output/span.streams/types.h | 230 +++++++++++++++---
2 files changed, 193 insertions(+), 39 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
index 421ba8ff10e169..017cf24a89d7b4 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
@@ -25,6 +25,8 @@
#include "nasty_string.h"
#include "test_macros.h"
+#include "../../types.h"
+
#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
using SpStream = std::basic_ispanstream<nasty_char, nasty_char_traits>;
diff --git a/libcxx/test/std/input.output/span.streams/types.h b/libcxx/test/std/input.output/span.streams/types.h
index 18788a56579dcb..0d8eecd5f4db0c 100644
--- a/libcxx/test/std/input.output/span.streams/types.h
+++ b/libcxx/test/std/input.output/span.streams/types.h
@@ -9,62 +9,214 @@
#ifndef TEST_STD_INPUTOUTPUT_SPANSTREAMS_TYPES_H
#define TEST_STD_INPUTOUTPUT_SPANSTREAMS_TYPES_H
-#include <string_view>
#include <concepts>
+#include <cstddef>
+#include <span>
+#include <ranges>
#include "test_macros.h"
-// template <typename CharT, class Traits = std::char_traits<CharT>>
-// class ConstConvertibleStringView {
-// public:
-// explicit ConstConvertibleStringView(const CharT* cs) : cs_{cs} {}
+template <typename CharT, std::size_t N = 0>
+class ReadOnlySpan {
+ explicit ReadOnlySpan(CharT (&arr)[N]) : arr_{arr} {}
-// operator std::basic_string_view<CharT, Traits>() = delete;
-// operator std::basic_string_view<CharT, Traits>() const { return std::basic_string_view<CharT, Traits>(cs_); }
+public:
+ operator std::span<CharT>() = delete;
-// private:
-// const CharT* cs_;
-// };
+ operator std::span<const CharT>() { return std::span<const CharT, N>{arr_}; }
-// static_assert(!std::constructible_from<std::basic_string_view<char>, ConstConvertibleStringView<char>>);
-// static_assert(!std::convertible_to<ConstConvertibleStringView<char>, std::basic_string_view<char>>);
+ const CharT* begin() { return arr_; }
+ const CharT* end() { return arr_ + N; }
-// static_assert(std::constructible_from<std::basic_string_view<char>, const ConstConvertibleStringView<char>>);
-// static_assert(std::convertible_to<const ConstConvertibleStringView<char>, std::basic_string_view<char>>);
+private:
+ CharT* arr_;
+};
-// #ifndef TEST_HAS_NO_WIDE_CHARACTERS
-// static_assert(!std::constructible_from<std::basic_string_view<wchar_t>, ConstConvertibleStringView<wchar_t>>);
-// static_assert(!std::convertible_to<ConstConvertibleStringView<wchar_t>, std::basic_string_view<wchar_t>>);
+template <typename CharT, std::size_t N>
+inline constexpr bool std::ranges::enable_borrowed_range<ReadOnlySpan<CharT, N>> = true;
-// static_assert(std::constructible_from<std::basic_string_view<wchar_t>, const ConstConvertibleStringView<wchar_t>>);
-// static_assert(std::convertible_to<const ConstConvertibleStringView<wchar_t>, std::basic_string_view<wchar_t>>);
-// #endif
+static_assert(std::ranges::borrowed_range<ReadOnlySpan<char>>);
-// template <typename CharT, class Traits = std::char_traits<CharT>>
-// class NonConstConvertibleStringView {
-// public:
-// explicit NonConstConvertibleStringView(const CharT* cs) : cs_{cs} {}
+static_assert(!std::constructible_from<std::span<char>, ReadOnlySpan<char>>);
+static_assert(!std::convertible_to<ReadOnlySpan<char>, std::span<char>>);
-// operator std::basic_string_view<CharT, Traits>() { return std::basic_string_view<CharT, Traits>(cs_); }
-// operator std::basic_string_view<CharT, Traits>() const = delete;
+static_assert(!std::constructible_from<std::span<char>, const ReadOnlySpan<char>>);
+static_assert(!std::convertible_to<const ReadOnlySpan<char>, std::span<char>>);
-// private:
-// const CharT* cs_;
-// };
+static_assert(std::constructible_from<std::span<const char>, ReadOnlySpan<char>>);
+static_assert(std::convertible_to<ReadOnlySpan<char>, std::span<const char>>);
-// static_assert(std::constructible_from<std::basic_string_view<char>, NonConstConvertibleStringView<char>>);
-// static_assert(std::convertible_to<NonConstConvertibleStringView<char>, std::basic_string_view<char>>);
+static_assert(!std::constructible_from<std::span<const char>, const ReadOnlySpan<char>>);
+static_assert(!std::convertible_to<const ReadOnlySpan<char>, std::span<const char>>);
-// static_assert(!std::constructible_from<std::basic_string_view<char>, const NonConstConvertibleStringView<char>>);
-// static_assert(!std::convertible_to<const NonConstConvertibleStringView<char>, std::basic_string_view<char>>);
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-// #ifndef TEST_HAS_NO_WIDE_CHARACTERS
-// static_assert(std::constructible_from<std::basic_string_view<wchar_t>, NonConstConvertibleStringView<wchar_t>>);
-// static_assert(std::convertible_to<NonConstConvertibleStringView<wchar_t>, std::basic_string_view<wchar_t>>);
+static_assert(std::ranges::borrowed_range<ReadOnlySpan<wchar_t>>);
-// static_assert(!std::constructible_from<std::basic_string_view<wchar_t>, const NonConstConvertibleStringView<wchar_t>>);
-// static_assert(!std::convertible_to<const NonConstConvertibleStringView<wchar_t>, std::basic_string_view<wchar_t>>);
-// #endif
+static_assert(!std::constructible_from<std::span<wchar_t>, ReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<ReadOnlySpan<wchar_t>, std::span<wchar_t>>);
+
+static_assert(!std::constructible_from<std::span<wchar_t>, const ReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<const ReadOnlySpan<wchar_t>, std::span<wchar_t>>);
+
+static_assert(std::constructible_from<std::span<const wchar_t>, ReadOnlySpan<wchar_t>>);
+static_assert(std::convertible_to<ReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
+
+static_assert(!std::constructible_from<std::span<const wchar_t>, const ReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<const ReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
+#endif
+
+template <typename CharT, std::size_t N = 0>
+class NonReadOnlySpan {
+ explicit NonReadOnlySpan(CharT (&arr)[N]) : arr_{arr} {}
+
+public:
+ operator std::span<CharT>() { return std::span<CharT, N>{arr_}; }
+
+ operator std::span<const CharT>() = delete;
+
+ CharT* begin() { return arr_; }
+ CharT* end() { return arr_ + N; }
+
+private:
+ CharT* arr_;
+};
+
+template <typename CharT, std::size_t N>
+inline constexpr bool std::ranges::enable_borrowed_range<NonReadOnlySpan<CharT, N>> = true;
+
+static_assert(std::ranges::borrowed_range<NonReadOnlySpan<char>>);
+
+static_assert(std::constructible_from<std::span<char>, NonReadOnlySpan<char>>);
+static_assert(std::convertible_to<NonReadOnlySpan<char>, std::span<char>>);
+
+static_assert(!std::constructible_from<std::span<char>, const NonReadOnlySpan<char>>);
+static_assert(!std::convertible_to<const NonReadOnlySpan<char>, std::span<char>>);
+
+static_assert(std::constructible_from<std::span<const char>, NonReadOnlySpan<char>>);
+static_assert(!std::convertible_to<NonReadOnlySpan<char>, std::span<const char>>);
+
+static_assert(!std::constructible_from<std::span<const char>, const NonReadOnlySpan<char>>);
+static_assert(!std::convertible_to<const NonReadOnlySpan<char>, std::span<const char>>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::ranges::borrowed_range<NonReadOnlySpan<wchar_t>>);
+
+static_assert(std::constructible_from<std::span<wchar_t>, NonReadOnlySpan<wchar_t>>);
+static_assert(std::convertible_to<NonReadOnlySpan<wchar_t>, std::span<wchar_t>>);
+
+static_assert(!std::constructible_from<std::span<wchar_t>, const NonReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<const NonReadOnlySpan<wchar_t>, std::span<wchar_t>>);
+
+static_assert(std::constructible_from<std::span<const wchar_t>, NonReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<NonReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
+
+static_assert(!std::constructible_from<std::span<const wchar_t>, const NonReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<const NonReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
+#endif
+
+template <typename CharT, std::size_t N = 0>
+class ConstConvertibleReadOnlySpan {
+ explicit ConstConvertibleReadOnlySpan(CharT (&arr)[N]) : arr_{arr} {}
+
+public:
+ operator std::span<CharT>() = delete;
+ operator std::span<CharT>() const = delete;
+
+ operator std::span<const CharT>() = delete;
+ operator std::span<const CharT>() const { return std::span<const CharT, N>{arr_}; }
+
+ const CharT* begin() { return arr_; }
+ const CharT* end() { return arr_ + N; }
+
+private:
+ CharT* arr_;
+};
+
+template <typename CharT, std::size_t N>
+inline constexpr bool std::ranges::enable_borrowed_range<ConstConvertibleReadOnlySpan<CharT, N>> = true;
+
+static_assert(std::ranges::borrowed_range<ConstConvertibleReadOnlySpan<char>>);
+
+static_assert(!std::constructible_from<std::span<char>, ConstConvertibleReadOnlySpan<char>>);
+static_assert(!std::convertible_to<ConstConvertibleReadOnlySpan<char>, std::span<char>>);
+
+static_assert(!std::constructible_from<std::span<char>, const ConstConvertibleReadOnlySpan<char>>);
+static_assert(!std::convertible_to<const ConstConvertibleReadOnlySpan<char>, std::span<char>>);
+
+static_assert(std::constructible_from<std::span<const char>, ConstConvertibleReadOnlySpan<char>>);
+static_assert(!std::convertible_to<ConstConvertibleReadOnlySpan<char>, std::span<const char>>);
+
+static_assert(std::constructible_from<std::span<const char>, const ConstConvertibleReadOnlySpan<char>>);
+static_assert(std::convertible_to<const ConstConvertibleReadOnlySpan<char>, std::span<const char>>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+
+static_assert(std::ranges::borrowed_range<ConstConvertibleReadOnlySpan<wchar_t>>);
+
+static_assert(!std::constructible_from<std::span<wchar_t>, ConstConvertibleReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<ConstConvertibleReadOnlySpan<wchar_t>, std::span<wchar_t>>);
+
+static_assert(!std::constructible_from<std::span<wchar_t>, const ConstConvertibleReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<const ConstConvertibleReadOnlySpan<wchar_t>, std::span<wchar_t>>);
+
+static_assert(std::constructible_from<std::span<const wchar_t>, ConstConvertibleReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<ConstConvertibleReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
+
+static_assert(std::constructible_from<std::span<const wchar_t>, const ConstConvertibleReadOnlySpan<wchar_t>>);
+static_assert(std::convertible_to<const ConstConvertibleReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
+#endif
+
+template <typename CharT, std::size_t N = 0>
+class NonConstConvertibleReadOnlySpan {
+ explicit NonConstConvertibleReadOnlySpan(CharT (&arr)[N]) : arr_{arr} {}
+
+public:
+ operator std::span<CharT>() = delete;
+ operator std::span<CharT>() const = delete;
+
+ operator std::span<const CharT>() { return std::span<const CharT, N>{arr_}; }
+ operator std::span<const CharT>() const = delete;
+
+ const CharT* begin() { return arr_; }
+ const CharT* end() { return arr_ + N; }
+
+private:
+ CharT* arr_;
+};
+
+template <typename CharT, std::size_t N>
+inline constexpr bool std::ranges::enable_borrowed_range<NonConstConvertibleReadOnlySpan<CharT, N>> = true;
+
+static_assert(std::ranges::borrowed_range<NonConstConvertibleReadOnlySpan<char>>);
+
+static_assert(!std::constructible_from<std::span<char>, NonConstConvertibleReadOnlySpan<char>>);
+static_assert(!std::convertible_to<NonConstConvertibleReadOnlySpan<char>, std::span<char>>);
+
+static_assert(!std::constructible_from<std::span<char>, const NonConstConvertibleReadOnlySpan<char>>);
+static_assert(!std::convertible_to<const NonConstConvertibleReadOnlySpan<char>, std::span<char>>);
+
+static_assert(std::constructible_from<std::span<const char>, NonConstConvertibleReadOnlySpan<char>>);
+static_assert(std::convertible_to<NonConstConvertibleReadOnlySpan<char>, std::span<const char>>);
+
+static_assert(!std::constructible_from<std::span<const char>, const NonConstConvertibleReadOnlySpan<char>>);
+static_assert(!std::convertible_to<const NonConstConvertibleReadOnlySpan<char>, std::span<const char>>);
+
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+static_assert(std::ranges::borrowed_range<NonConstConvertibleReadOnlySpan<wchar_t>>);
+
+static_assert(!std::constructible_from<std::span<wchar_t>, NonConstConvertibleReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<NonConstConvertibleReadOnlySpan<wchar_t>, std::span<wchar_t>>);
+
+static_assert(!std::constructible_from<std::span<wchar_t>, const NonConstConvertibleReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<const NonConstConvertibleReadOnlySpan<wchar_t>, std::span<wchar_t>>);
+
+static_assert(std::constructible_from<std::span<const wchar_t>, NonConstConvertibleReadOnlySpan<wchar_t>>);
+static_assert(std::convertible_to<NonConstConvertibleReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
+
+static_assert(!std::constructible_from<std::span<const wchar_t>, const NonConstConvertibleReadOnlySpan<wchar_t>>);
+static_assert(!std::convertible_to<const NonConstConvertibleReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
+#endif
struct SomeObject {};
>From 974c08f37ef645e2ef1d8ef2d0f1f8374eabe3bd Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 4 Mar 2024 07:42:41 +0200
Subject: [PATCH 18/39] Tests: WIP `ROS` constructor
---
libcxx/include/spanstream | 7 +++
.../{macros.h => helper_macros.h} | 0
.../span.streams/{types.h => helper_types.h} | 21 +++++--
.../ispanstream/ispanstream.cons/ros.pass.cpp | 62 +++++++++++++++++--
.../ispanstream.cons/span.mode.pass.cpp | 4 +-
.../input.output/span.streams/lit.local.cfg | 3 +
.../ospanstream.cons/span.mode.pass.cpp | 4 +-
.../spanbuf/spanbuf.cons/mode.pass.cpp | 2 +-
.../spanbuf/spanbuf.cons/span.mode.pass.cpp | 4 +-
.../spanstream.cons/span.mode.pass.cpp | 4 +-
10 files changed, 93 insertions(+), 18 deletions(-)
rename libcxx/test/std/input.output/span.streams/{macros.h => helper_macros.h} (100%)
rename libcxx/test/std/input.output/span.streams/{types.h => helper_types.h} (96%)
create mode 100644 libcxx/test/std/input.output/span.streams/lit.local.cfg
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index 70e6faa4206fbe..14fd39d93e9915 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -66,6 +66,7 @@
#include <__utility/move.h>
#include <__utility/swap.h>
#include <iostream>
+#include <print>
#include <span>
#include <streambuf>
#include <version>
@@ -266,8 +267,14 @@ public:
requires(!convertible_to<_ROSeq, std::span<_CharT>>) && convertible_to<_ROSeq, std::span<const _CharT>>
_LIBCPP_HIDE_FROM_ABI explicit basic_ispanstream(_ROSeq&& __s)
: basic_istream<_CharT, _Traits>(std::addressof(__sb_)) {
+ std::println(stderr, "ispanstream");
std::span<const _CharT> __sp(std::forward<_ROSeq>(__s));
+ std::println(stderr, "span __sb_ {} {}", __sb_.span().empty(), __sb_.span().size());
+ std::println(stderr, "span data {} {}", __sp.empty(), __sp.size());
+ std::println(stderr, "ispanstream 2");
this->span(std::span<_CharT>(std::span<_CharT>(const_cast<_CharT*>(__sp.data()), __sp.size())));
+ std::println(stderr, "span __sb_ {} {}", __sb_.span().empty(), __sb_.span().size());
+ std::println(stderr, "ispanstream 3");
}
basic_ispanstream& operator=(const basic_ispanstream&) = delete;
diff --git a/libcxx/test/std/input.output/span.streams/macros.h b/libcxx/test/std/input.output/span.streams/helper_macros.h
similarity index 100%
rename from libcxx/test/std/input.output/span.streams/macros.h
rename to libcxx/test/std/input.output/span.streams/helper_macros.h
diff --git a/libcxx/test/std/input.output/span.streams/types.h b/libcxx/test/std/input.output/span.streams/helper_types.h
similarity index 96%
rename from libcxx/test/std/input.output/span.streams/types.h
rename to libcxx/test/std/input.output/span.streams/helper_types.h
index 0d8eecd5f4db0c..81fb2c7557714c 100644
--- a/libcxx/test/std/input.output/span.streams/types.h
+++ b/libcxx/test/std/input.output/span.streams/helper_types.h
@@ -16,17 +16,28 @@
#include "test_macros.h"
+#include <print>
+
template <typename CharT, std::size_t N = 0>
class ReadOnlySpan {
+public:
explicit ReadOnlySpan(CharT (&arr)[N]) : arr_{arr} {}
-public:
operator std::span<CharT>() = delete;
- operator std::span<const CharT>() { return std::span<const CharT, N>{arr_}; }
+ operator std::span<const CharT>() {
+ std::println(stderr, "----> ROspan");
+ return std::span<const CharT, N>{arr_};
+ }
- const CharT* begin() { return arr_; }
- const CharT* end() { return arr_ + N; }
+ const CharT* begin() {
+ std::println(stderr, "----> ROspan begin");
+ return arr_;
+ }
+ const CharT* end() {
+ std::println(stderr, "----> ROspan end");
+ return arr_ + N;
+ }
private:
CharT* arr_;
@@ -68,9 +79,9 @@ static_assert(!std::convertible_to<const ReadOnlySpan<wchar_t>, std::span<const
template <typename CharT, std::size_t N = 0>
class NonReadOnlySpan {
+public:
explicit NonReadOnlySpan(CharT (&arr)[N]) : arr_{arr} {}
-public:
operator std::span<CharT>() { return std::span<CharT, N>{arr_}; }
operator std::span<const CharT>() = delete;
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
index 017cf24a89d7b4..7a4f0f422404f4 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
@@ -19,27 +19,60 @@
// template<class ROS> explicit basic_ispanstream(ROS&& s);
#include <cassert>
+#include <concepts>
#include <spanstream>
#include "constexpr_char_traits.h"
#include "nasty_string.h"
+#include "test_convertible.h"
#include "test_macros.h"
-#include "../../types.h"
+#include "../../helper_types.h"
#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
using SpStream = std::basic_ispanstream<nasty_char, nasty_char_traits>;
- // TODO:
+ // Non-const convertible
+ static_assert(std::constructible_from<SpStream, ReadOnlySpan<nasty_char>>);
+ static_assert(!test_convertible<SpStream, ReadOnlySpan<nasty_char>>());
+
+ // Const convertible
+ static_assert(!std::constructible_from<SpStream, const ReadOnlySpan<nasty_char>>);
+ static_assert(!test_convertible<SpStream, const ReadOnlySpan<nasty_char>>());
+
+ // Non-const non-convertible
+ static_assert(std::constructible_from<SpStream, ReadOnlySpan<nasty_char>>);
+ static_assert(!test_convertible<SpStream, ReadOnlySpan<nasty_char>>());
+
+ // Const non-convertible
+ static_assert(!std::constructible_from<SpStream, const ReadOnlySpan<nasty_char>>);
+ static_assert(!test_convertible<SpStream, const ReadOnlySpan<nasty_char>>());
}
#endif // TEST_HAS_NO_NASTY_STRING
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
- using SpStream = std::basic_ispanstream<CharT, TraitsT>;
+ using SpStream =
+ std::conditional_t<std::same_as<CharT, nasty_char>,
+ std::basic_ispanstream<nasty_char, nasty_char_traits>,
+ std::basic_ispanstream<CharT, TraitsT>>;
- // TODO:
+ // Non-const convertible
+ static_assert(std::constructible_from<SpStream, ReadOnlySpan<CharT>>);
+ static_assert(!test_convertible<SpStream, ReadOnlySpan<CharT>>());
+
+ // Const convertible
+ static_assert(!std::constructible_from<SpStream, const ReadOnlySpan<CharT>>);
+ static_assert(!test_convertible<SpStream, const ReadOnlySpan<CharT>>());
+
+ // Non-const non-convertible
+ static_assert(std::constructible_from<SpStream, NonReadOnlySpan<CharT>>);
+ static_assert(!test_convertible<SpStream, NonReadOnlySpan<CharT>>());
+
+ // Const non-convertible
+ static_assert(!std::constructible_from<SpStream, const NonReadOnlySpan<CharT>>);
+ static_assert(!test_convertible<SpStream, const NonReadOnlySpan<CharT>>());
}
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
@@ -47,10 +80,31 @@ void test() {
using SpStream = std::basic_ispanstream<CharT, TraitsT>;
// TODO:
+ CharT arr[4];
+ ReadOnlySpan<CharT, 4> ros{arr};
+
+ {
+ SpStream spSt(ros);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
+ }
+
+ CharT arr1[6];
+ ReadOnlySpan<CharT, 6> ros2{arr1};
+
+ {
+ SpStream spSt(ros2);
+ assert(spSt.span().data() == arr);
+ assert(spSt.span().data() == arr1);
+ assert(spSt.span().empty());
+ assert(spSt.span().size() == 0);
+ }
}
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
+ // test_sfinae<nasty_char, nasty_char_traits>();
test_sfinae_with_nasty_char();
#endif
test_sfinae<char>();
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
index 3502bbc1d676d7..3527d197e7cdf9 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
@@ -30,8 +30,8 @@
#include "test_convertible.h"
#include "test_macros.h"
-#include "../../macros.h"
-#include "../../types.h"
+#include "../../helper_macros.h"
+#include "../../helper_types.h"
#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
diff --git a/libcxx/test/std/input.output/span.streams/lit.local.cfg b/libcxx/test/std/input.output/span.streams/lit.local.cfg
new file mode 100644
index 00000000000000..2cb10010c45072
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/lit.local.cfg
@@ -0,0 +1,3 @@
+# All non-trivial uses of iostreams require localization support
+if "no-localization" in config.available_features:
+ config.unsupported = True
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
index f353719875bc96..e036a0be4a48ba 100644
--- a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
@@ -30,8 +30,8 @@
#include "test_convertible.h"
#include "test_macros.h"
-#include "../../macros.h"
-#include "../../types.h"
+#include "../../helper_macros.h"
+#include "../../helper_types.h"
#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
index eb8b29de9fbff0..d040f0beb92a55 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
@@ -28,7 +28,7 @@
#include "test_convertible.h"
#include "test_macros.h"
-#include "../../types.h"
+#include "../../helper_types.h"
#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
index fbcc8eeded2595..45985aed49c618 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
@@ -30,8 +30,8 @@
#include "test_convertible.h"
#include "test_macros.h"
-#include "../../macros.h"
-#include "../../types.h"
+#include "../../helper_macros.h"
+#include "../../helper_types.h"
#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
index 61a1a2530ad754..2423c92fda9f8b 100644
--- a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
@@ -30,8 +30,8 @@
#include "test_convertible.h"
#include "test_macros.h"
-#include "../../macros.h"
-#include "../../types.h"
+#include "../../helper_macros.h"
+#include "../../helper_types.h"
#ifndef TEST_HAS_NO_NASTY_STRING
void test_sfinae_with_nasty_char() {
>From 1bfc6346e6e6612379b4bab475c381c6b834a2d7 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 4 Mar 2024 07:47:34 +0200
Subject: [PATCH 19/39] Tests: WIP retry CI
---
libcxx/include/spanstream | 14 +--
.../input.output/span.streams/helper_types.h | 111 +-----------------
.../ispanstream/ispanstream.cons/ros.pass.cpp | 27 +----
3 files changed, 13 insertions(+), 139 deletions(-)
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index 14fd39d93e9915..c735baaae93d90 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -66,7 +66,7 @@
#include <__utility/move.h>
#include <__utility/swap.h>
#include <iostream>
-#include <print>
+// #include <print>
#include <span>
#include <streambuf>
#include <version>
@@ -267,14 +267,14 @@ public:
requires(!convertible_to<_ROSeq, std::span<_CharT>>) && convertible_to<_ROSeq, std::span<const _CharT>>
_LIBCPP_HIDE_FROM_ABI explicit basic_ispanstream(_ROSeq&& __s)
: basic_istream<_CharT, _Traits>(std::addressof(__sb_)) {
- std::println(stderr, "ispanstream");
+ // std::println(stderr, "ispanstream");
std::span<const _CharT> __sp(std::forward<_ROSeq>(__s));
- std::println(stderr, "span __sb_ {} {}", __sb_.span().empty(), __sb_.span().size());
- std::println(stderr, "span data {} {}", __sp.empty(), __sp.size());
- std::println(stderr, "ispanstream 2");
+ // std::println(stderr, "span __sb_ {} {}", __sb_.span().empty(), __sb_.span().size());
+ // std::println(stderr, "span data {} {}", __sp.empty(), __sp.size());
+ // std::println(stderr, "ispanstream 2");
this->span(std::span<_CharT>(std::span<_CharT>(const_cast<_CharT*>(__sp.data()), __sp.size())));
- std::println(stderr, "span __sb_ {} {}", __sb_.span().empty(), __sb_.span().size());
- std::println(stderr, "ispanstream 3");
+ // std::println(stderr, "span __sb_ {} {}", __sb_.span().empty(), __sb_.span().size());
+ // std::println(stderr, "ispanstream 3");
}
basic_ispanstream& operator=(const basic_ispanstream&) = delete;
diff --git a/libcxx/test/std/input.output/span.streams/helper_types.h b/libcxx/test/std/input.output/span.streams/helper_types.h
index 81fb2c7557714c..7f67432f9f8806 100644
--- a/libcxx/test/std/input.output/span.streams/helper_types.h
+++ b/libcxx/test/std/input.output/span.streams/helper_types.h
@@ -16,7 +16,7 @@
#include "test_macros.h"
-#include <print>
+// #include <print>
template <typename CharT, std::size_t N = 0>
class ReadOnlySpan {
@@ -26,16 +26,16 @@ class ReadOnlySpan {
operator std::span<CharT>() = delete;
operator std::span<const CharT>() {
- std::println(stderr, "----> ROspan");
+ // std::println(stderr, "----> ROspan");
return std::span<const CharT, N>{arr_};
}
const CharT* begin() {
- std::println(stderr, "----> ROspan begin");
+ // std::println(stderr, "----> ROspan begin");
return arr_;
}
const CharT* end() {
- std::println(stderr, "----> ROspan end");
+ // std::println(stderr, "----> ROspan end");
return arr_ + N;
}
@@ -126,109 +126,6 @@ static_assert(!std::constructible_from<std::span<const wchar_t>, const NonReadOn
static_assert(!std::convertible_to<const NonReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
#endif
-template <typename CharT, std::size_t N = 0>
-class ConstConvertibleReadOnlySpan {
- explicit ConstConvertibleReadOnlySpan(CharT (&arr)[N]) : arr_{arr} {}
-
-public:
- operator std::span<CharT>() = delete;
- operator std::span<CharT>() const = delete;
-
- operator std::span<const CharT>() = delete;
- operator std::span<const CharT>() const { return std::span<const CharT, N>{arr_}; }
-
- const CharT* begin() { return arr_; }
- const CharT* end() { return arr_ + N; }
-
-private:
- CharT* arr_;
-};
-
-template <typename CharT, std::size_t N>
-inline constexpr bool std::ranges::enable_borrowed_range<ConstConvertibleReadOnlySpan<CharT, N>> = true;
-
-static_assert(std::ranges::borrowed_range<ConstConvertibleReadOnlySpan<char>>);
-
-static_assert(!std::constructible_from<std::span<char>, ConstConvertibleReadOnlySpan<char>>);
-static_assert(!std::convertible_to<ConstConvertibleReadOnlySpan<char>, std::span<char>>);
-
-static_assert(!std::constructible_from<std::span<char>, const ConstConvertibleReadOnlySpan<char>>);
-static_assert(!std::convertible_to<const ConstConvertibleReadOnlySpan<char>, std::span<char>>);
-
-static_assert(std::constructible_from<std::span<const char>, ConstConvertibleReadOnlySpan<char>>);
-static_assert(!std::convertible_to<ConstConvertibleReadOnlySpan<char>, std::span<const char>>);
-
-static_assert(std::constructible_from<std::span<const char>, const ConstConvertibleReadOnlySpan<char>>);
-static_assert(std::convertible_to<const ConstConvertibleReadOnlySpan<char>, std::span<const char>>);
-
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-
-static_assert(std::ranges::borrowed_range<ConstConvertibleReadOnlySpan<wchar_t>>);
-
-static_assert(!std::constructible_from<std::span<wchar_t>, ConstConvertibleReadOnlySpan<wchar_t>>);
-static_assert(!std::convertible_to<ConstConvertibleReadOnlySpan<wchar_t>, std::span<wchar_t>>);
-
-static_assert(!std::constructible_from<std::span<wchar_t>, const ConstConvertibleReadOnlySpan<wchar_t>>);
-static_assert(!std::convertible_to<const ConstConvertibleReadOnlySpan<wchar_t>, std::span<wchar_t>>);
-
-static_assert(std::constructible_from<std::span<const wchar_t>, ConstConvertibleReadOnlySpan<wchar_t>>);
-static_assert(!std::convertible_to<ConstConvertibleReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
-
-static_assert(std::constructible_from<std::span<const wchar_t>, const ConstConvertibleReadOnlySpan<wchar_t>>);
-static_assert(std::convertible_to<const ConstConvertibleReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
-#endif
-
-template <typename CharT, std::size_t N = 0>
-class NonConstConvertibleReadOnlySpan {
- explicit NonConstConvertibleReadOnlySpan(CharT (&arr)[N]) : arr_{arr} {}
-
-public:
- operator std::span<CharT>() = delete;
- operator std::span<CharT>() const = delete;
-
- operator std::span<const CharT>() { return std::span<const CharT, N>{arr_}; }
- operator std::span<const CharT>() const = delete;
-
- const CharT* begin() { return arr_; }
- const CharT* end() { return arr_ + N; }
-
-private:
- CharT* arr_;
-};
-
-template <typename CharT, std::size_t N>
-inline constexpr bool std::ranges::enable_borrowed_range<NonConstConvertibleReadOnlySpan<CharT, N>> = true;
-
-static_assert(std::ranges::borrowed_range<NonConstConvertibleReadOnlySpan<char>>);
-
-static_assert(!std::constructible_from<std::span<char>, NonConstConvertibleReadOnlySpan<char>>);
-static_assert(!std::convertible_to<NonConstConvertibleReadOnlySpan<char>, std::span<char>>);
-
-static_assert(!std::constructible_from<std::span<char>, const NonConstConvertibleReadOnlySpan<char>>);
-static_assert(!std::convertible_to<const NonConstConvertibleReadOnlySpan<char>, std::span<char>>);
-
-static_assert(std::constructible_from<std::span<const char>, NonConstConvertibleReadOnlySpan<char>>);
-static_assert(std::convertible_to<NonConstConvertibleReadOnlySpan<char>, std::span<const char>>);
-
-static_assert(!std::constructible_from<std::span<const char>, const NonConstConvertibleReadOnlySpan<char>>);
-static_assert(!std::convertible_to<const NonConstConvertibleReadOnlySpan<char>, std::span<const char>>);
-
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::ranges::borrowed_range<NonConstConvertibleReadOnlySpan<wchar_t>>);
-
-static_assert(!std::constructible_from<std::span<wchar_t>, NonConstConvertibleReadOnlySpan<wchar_t>>);
-static_assert(!std::convertible_to<NonConstConvertibleReadOnlySpan<wchar_t>, std::span<wchar_t>>);
-
-static_assert(!std::constructible_from<std::span<wchar_t>, const NonConstConvertibleReadOnlySpan<wchar_t>>);
-static_assert(!std::convertible_to<const NonConstConvertibleReadOnlySpan<wchar_t>, std::span<wchar_t>>);
-
-static_assert(std::constructible_from<std::span<const wchar_t>, NonConstConvertibleReadOnlySpan<wchar_t>>);
-static_assert(std::convertible_to<NonConstConvertibleReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
-
-static_assert(!std::constructible_from<std::span<const wchar_t>, const NonConstConvertibleReadOnlySpan<wchar_t>>);
-static_assert(!std::convertible_to<const NonConstConvertibleReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
-#endif
-
struct SomeObject {};
struct NonMode {};
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
index 7a4f0f422404f4..6425b6ed94e493 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
@@ -29,28 +29,6 @@
#include "../../helper_types.h"
-#ifndef TEST_HAS_NO_NASTY_STRING
-void test_sfinae_with_nasty_char() {
- using SpStream = std::basic_ispanstream<nasty_char, nasty_char_traits>;
-
- // Non-const convertible
- static_assert(std::constructible_from<SpStream, ReadOnlySpan<nasty_char>>);
- static_assert(!test_convertible<SpStream, ReadOnlySpan<nasty_char>>());
-
- // Const convertible
- static_assert(!std::constructible_from<SpStream, const ReadOnlySpan<nasty_char>>);
- static_assert(!test_convertible<SpStream, const ReadOnlySpan<nasty_char>>());
-
- // Non-const non-convertible
- static_assert(std::constructible_from<SpStream, ReadOnlySpan<nasty_char>>);
- static_assert(!test_convertible<SpStream, ReadOnlySpan<nasty_char>>());
-
- // Const non-convertible
- static_assert(!std::constructible_from<SpStream, const ReadOnlySpan<nasty_char>>);
- static_assert(!test_convertible<SpStream, const ReadOnlySpan<nasty_char>>());
-}
-#endif // TEST_HAS_NO_NASTY_STRING
-
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
using SpStream =
@@ -95,7 +73,7 @@ void test() {
{
SpStream spSt(ros2);
- assert(spSt.span().data() == arr);
+ assert(spSt.span().data() != arr);
assert(spSt.span().data() == arr1);
assert(spSt.span().empty());
assert(spSt.span().size() == 0);
@@ -104,8 +82,7 @@ void test() {
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
- // test_sfinae<nasty_char, nasty_char_traits>();
- test_sfinae_with_nasty_char();
+ test_sfinae<nasty_char, nasty_char_traits>();
#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
>From b2d531ab314bea6043482d76fa569a8feb646125 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 5 Mar 2024 09:50:42 +0200
Subject: [PATCH 20/39] Tests: Try to fix CI
---
.../span.streams/ispanstream/ispanstream.cons/ros.pass.cpp | 4 ++++
libcxx/utils/generate_feature_test_macro_components.py | 1 +
2 files changed, 5 insertions(+)
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
index 6425b6ed94e493..b2cae9b9f54ced 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
@@ -32,9 +32,13 @@
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
using SpStream =
+#ifndef TEST_HAS_NO_NASTY_STRING
std::conditional_t<std::same_as<CharT, nasty_char>,
std::basic_ispanstream<nasty_char, nasty_char_traits>,
std::basic_ispanstream<CharT, TraitsT>>;
+#else
+ std::basic_ispanstream<CharT, TraitsT>;
+#endif
// Non-const convertible
static_assert(std::constructible_from<SpStream, ReadOnlySpan<CharT>>);
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 69bca109fca195..2837b9a92a7d82 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1338,6 +1338,7 @@ def add_version_header(tc):
"regex": ["UNSUPPORTED: no-localization"],
"semaphore": ["UNSUPPORTED: no-threads"],
"shared_mutex": ["UNSUPPORTED: no-threads"],
+ "spanstream": ["UNSUPPORTED: no-localization"],
"sstream": ["UNSUPPORTED: no-localization"],
"syncstream": ["UNSUPPORTED: no-localization"],
"stdatomic.h": ["UNSUPPORTED: no-threads"],
>From 25c54012f1b4d1496088c696ab6f9e06da16dadd Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 5 Mar 2024 10:29:11 +0200
Subject: [PATCH 21/39] Tests: updated generated tests
---
.../support.limits.general/spanstream.version.compile.pass.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/spanstream.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/spanstream.version.compile.pass.cpp
index 8719352d4367e3..53c528e320a874 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/spanstream.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/spanstream.version.compile.pass.cpp
@@ -11,6 +11,8 @@
//
// clang-format off
+// UNSUPPORTED: no-localization
+
// <spanstream>
// Test the feature test macros defined by <spanstream>
>From c0c72bcb40c7eab63a9ad5b1fea9f46be88592c6 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 5 Mar 2024 17:13:47 +0200
Subject: [PATCH 22/39] Tests: WIP
---
.../ispanstream.cons/span.mode.pass.cpp | 2 +-
.../ospanstream.cons/span.mode.pass.cpp | 27 +++++++------------
.../spanbuf/spanbuf.cons/mode.pass.cpp | 25 +++++++----------
.../spanbuf/spanbuf.cons/span.mode.pass.cpp | 2 +-
.../spanstream.cons/span.mode.pass.cpp | 13 ++++++---
5 files changed, 31 insertions(+), 38 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
index 3527d197e7cdf9..a04cc578153b22 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
@@ -137,4 +137,4 @@ int main(int, char**) {
#endif
return 0;
-}
\ No newline at end of file
+}
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
index e036a0be4a48ba..bf619e8f18f7e7 100644
--- a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
@@ -33,23 +33,16 @@
#include "../../helper_macros.h"
#include "../../helper_types.h"
-#ifndef TEST_HAS_NO_NASTY_STRING
-void test_sfinae_with_nasty_char() {
- using SpStream = std::basic_ospanstream<nasty_char, nasty_char_traits>;
-
- // Mode
- static_assert(std::constructible_from<SpStream, const std::span<nasty_char>, std::ios_base::openmode>);
- static_assert(!test_convertible<SpStream, std::ios_base::openmode>());
-
- // Non-mode
- static_assert(!std::constructible_from<SpStream, const std::span<nasty_char>, const NonMode>);
- static_assert(!test_convertible<SpStream, const std::span<nasty_char>, const NonMode>());
-}
-#endif // TEST_HAS_NO_NASTY_STRING
-
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
- using SpStream = std::basic_ospanstream<CharT, TraitsT>;
+ using SpStream =
+#ifndef TEST_HAS_NO_NASTY_STRING
+ std::conditional_t<std::same_as<CharT, nasty_char>,
+ std::basic_ispanstream<nasty_char, nasty_char_traits>,
+ std::basic_ispanstream<CharT, TraitsT>>;
+#else
+ std::basic_ispanstream<CharT, TraitsT>;
+#endif
// Mode
static_assert(std::constructible_from<SpStream, const std::span<CharT>, std::ios_base::openmode>);
@@ -123,7 +116,7 @@ void test() {
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
- test_sfinae_with_nasty_char();
+ test_sfinae<nasty_char, nasty_char_traits>();
#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
@@ -137,4 +130,4 @@ int main(int, char**) {
#endif
return 0;
-}
\ No newline at end of file
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
index d040f0beb92a55..f4d7667ca8327f 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
@@ -30,23 +30,16 @@
#include "../../helper_types.h"
-#ifndef TEST_HAS_NO_NASTY_STRING
-void test_sfinae_with_nasty_char() {
- using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
-
- // Mode
- static_assert(std::constructible_from<SpBuf, std::ios_base::openmode>);
- static_assert(!test_convertible<SpBuf, std::ios_base::openmode>());
-
- // Non-mode
- static_assert(!std::constructible_from<SpBuf, const NonMode>);
- static_assert(!test_convertible<SpBuf, const NonMode>());
-}
-#endif // TEST_HAS_NO_NASTY_STRING
-
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
- using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+ using SpStream =
+#ifndef TEST_HAS_NO_NASTY_STRING
+ std::conditional_t<std::same_as<CharT, nasty_char>,
+ std::basic_ispanstream<nasty_char, nasty_char_traits>,
+ std::basic_ispanstream<CharT, TraitsT>>;
+#else
+ std::basic_ispanstream<CharT, TraitsT>;
+#endif
// Mode
static_assert(std::constructible_from<SpBuf, std::ios_base::openmode>);
@@ -88,7 +81,7 @@ void test() {
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
- test_sfinae_with_nasty_char();
+ test_sfinae<nasty_char, nasty_char_traits>();
#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
index 45985aed49c618..b0326f82451edd 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
@@ -188,4 +188,4 @@ int main(int, char**) {
#endif
return 0;
-}
\ No newline at end of file
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
index 2423c92fda9f8b..322ac32e1126cf 100644
--- a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
@@ -49,7 +49,14 @@ void test_sfinae_with_nasty_char() {
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
- using SpStream = std::basic_spanstream<CharT, TraitsT>;
+ using SpStream =
+#ifndef TEST_HAS_NO_NASTY_STRING
+ std::conditional_t<std::same_as<CharT, nasty_char>,
+ std::basic_ispanstream<nasty_char, nasty_char_traits>,
+ std::basic_ispanstream<CharT, TraitsT>>;
+#else
+ std::basic_ispanstream<CharT, TraitsT>;
+#endif
// Mode
static_assert(std::constructible_from<SpStream, const std::span<CharT>, std::ios_base::openmode>);
@@ -123,7 +130,7 @@ void test() {
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
- test_sfinae_with_nasty_char();
+ test_sfinae<nasty_char>();
#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
@@ -137,4 +144,4 @@ int main(int, char**) {
#endif
return 0;
-}
\ No newline at end of file
+}
>From 50dab65d5afce9fbcc813a40dd945c4fd12e25a2 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 5 Mar 2024 17:24:55 +0200
Subject: [PATCH 23/39] Tests: WIP cleanup
---
.../ispanstream/ispanstream.cons/ros.pass.cpp | 9 +------
.../ispanstream.cons/span.mode.pass.cpp | 16 +-----------
.../ospanstream.cons/span.mode.pass.cpp | 9 +------
.../spanbuf/spanbuf.cons/mode.pass.cpp | 9 +------
.../spanbuf/spanbuf.cons/span.mode.pass.cpp | 16 +-----------
.../spanstream.cons/span.mode.pass.cpp | 25 ++-----------------
6 files changed, 7 insertions(+), 77 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
index b2cae9b9f54ced..ac64e66725f154 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/ros.pass.cpp
@@ -31,14 +31,7 @@
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
- using SpStream =
-#ifndef TEST_HAS_NO_NASTY_STRING
- std::conditional_t<std::same_as<CharT, nasty_char>,
- std::basic_ispanstream<nasty_char, nasty_char_traits>,
- std::basic_ispanstream<CharT, TraitsT>>;
-#else
- std::basic_ispanstream<CharT, TraitsT>;
-#endif
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
// Non-const convertible
static_assert(std::constructible_from<SpStream, ReadOnlySpan<CharT>>);
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
index a04cc578153b22..55b2aaf5c3b2be 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.cons/span.mode.pass.cpp
@@ -33,20 +33,6 @@
#include "../../helper_macros.h"
#include "../../helper_types.h"
-#ifndef TEST_HAS_NO_NASTY_STRING
-void test_sfinae_with_nasty_char() {
- using SpStream = std::basic_ispanstream<nasty_char, nasty_char_traits>;
-
- // Mode
- static_assert(std::constructible_from<SpStream, const std::span<nasty_char>, std::ios_base::openmode>);
- static_assert(!test_convertible<SpStream, std::ios_base::openmode>());
-
- // Non-mode
- static_assert(!std::constructible_from<SpStream, const std::span<nasty_char>, const NonMode>);
- static_assert(!test_convertible<SpStream, const std::span<nasty_char>, const NonMode>());
-}
-#endif // TEST_HAS_NO_NASTY_STRING
-
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
using SpStream = std::basic_ispanstream<CharT, TraitsT>;
@@ -123,7 +109,7 @@ void test() {
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
- test_sfinae_with_nasty_char();
+ test_sfinae<nasty_char, nasty_char_traits>();
#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
diff --git a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
index bf619e8f18f7e7..fe274e9208c622 100644
--- a/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ospanstream/ospanstream.cons/span.mode.pass.cpp
@@ -35,14 +35,7 @@
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
- using SpStream =
-#ifndef TEST_HAS_NO_NASTY_STRING
- std::conditional_t<std::same_as<CharT, nasty_char>,
- std::basic_ispanstream<nasty_char, nasty_char_traits>,
- std::basic_ispanstream<CharT, TraitsT>>;
-#else
- std::basic_ispanstream<CharT, TraitsT>;
-#endif
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
// Mode
static_assert(std::constructible_from<SpStream, const std::span<CharT>, std::ios_base::openmode>);
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
index f4d7667ca8327f..d2bd64f35cb59a 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
@@ -32,14 +32,7 @@
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
- using SpStream =
-#ifndef TEST_HAS_NO_NASTY_STRING
- std::conditional_t<std::same_as<CharT, nasty_char>,
- std::basic_ispanstream<nasty_char, nasty_char_traits>,
- std::basic_ispanstream<CharT, TraitsT>>;
-#else
- std::basic_ispanstream<CharT, TraitsT>;
-#endif
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
// Mode
static_assert(std::constructible_from<SpBuf, std::ios_base::openmode>);
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
index b0326f82451edd..fbfc2f144ab6d3 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
@@ -33,20 +33,6 @@
#include "../../helper_macros.h"
#include "../../helper_types.h"
-#ifndef TEST_HAS_NO_NASTY_STRING
-void test_sfinae_with_nasty_char() {
- using SpBuf = std::basic_spanbuf<nasty_char, nasty_char_traits>;
-
- // Mode
- static_assert(std::constructible_from<SpBuf, const std::span<nasty_char>, std::ios_base::openmode>);
- static_assert(!test_convertible<SpBuf, std::ios_base::openmode>());
-
- // Non-mode
- static_assert(!std::constructible_from<SpBuf, const std::span<nasty_char>, const NonMode>);
- static_assert(!test_convertible<SpBuf, const NonMode>());
-}
-#endif // TEST_HAS_NO_NASTY_STRING
-
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
@@ -174,7 +160,7 @@ void test() {
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
- test_sfinae_with_nasty_char();
+ test_sfinae<nasty_char, nasty_char_traits>();
#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
diff --git a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
index 322ac32e1126cf..122d210430d9f1 100644
--- a/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanstream/spanstream.cons/span.mode.pass.cpp
@@ -33,30 +33,9 @@
#include "../../helper_macros.h"
#include "../../helper_types.h"
-#ifndef TEST_HAS_NO_NASTY_STRING
-void test_sfinae_with_nasty_char() {
- using SpStream = std::basic_spanstream<nasty_char, nasty_char_traits>;
-
- // Mode
- static_assert(std::constructible_from<SpStream, const std::span<nasty_char>, std::ios_base::openmode>);
- static_assert(!test_convertible<SpStream, std::ios_base::openmode>());
-
- // Non-mode
- static_assert(!std::constructible_from<SpStream, const std::span<nasty_char>, const NonMode>);
- static_assert(!test_convertible<SpStream, const std::span<nasty_char>, const NonMode>());
-}
-#endif // TEST_HAS_NO_NASTY_STRING
-
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test_sfinae() {
- using SpStream =
-#ifndef TEST_HAS_NO_NASTY_STRING
- std::conditional_t<std::same_as<CharT, nasty_char>,
- std::basic_ispanstream<nasty_char, nasty_char_traits>,
- std::basic_ispanstream<CharT, TraitsT>>;
-#else
- std::basic_ispanstream<CharT, TraitsT>;
-#endif
+ using SpStream = std::basic_ispanstream<CharT, TraitsT>;
// Mode
static_assert(std::constructible_from<SpStream, const std::span<CharT>, std::ios_base::openmode>);
@@ -130,7 +109,7 @@ void test() {
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
- test_sfinae<nasty_char>();
+ test_sfinae<nasty_char, nasty_char_traits>();
#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
>From cab2087ea20e073df120cb2a280ec6b5b988751c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 5 Mar 2024 17:55:59 +0200
Subject: [PATCH 24/39] Tests: added test skelettons
---
.../ispanstream.assign/move.pass.cpp | 2 +
.../ispanstream.assign/swap.pass.cpp | 2 +
.../swap_nonmember.pass.cpp | 2 +
.../spanbuf/spanbuf.assign/move.pass.cpp | 82 ++++++++++++++++++
.../spanbuf/spanbuf.assign/swap.pass.cpp | 85 +++++++++++++++++++
.../spanbuf.assign/swap_nonmember.pass.cpp | 81 ++++++++++++++++++
.../spanbuf/spanbuf.members/span.pass.cpp | 58 +++++++++++++
.../spanbuf.members/span.span.pass.cpp | 59 +++++++++++++
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 62 ++++++++++++++
.../seekoff.pos_type.open_mode.pass.cpp | 58 +++++++++++++
.../spanbuf/spanbuf.virtuals/setbuf.pass.cpp | 58 +++++++++++++
11 files changed, 549 insertions(+)
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/move.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/move.pass.cpp
index 117e2a6828e9da..75ae944d01c820 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/move.pass.cpp
@@ -34,6 +34,8 @@ void test() {
CharT arr[4];
std::span<CharT> sp{arr};
+ // TODO:
+
// Mode: default
{
SpStream rhsSpSt{sp};
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap.pass.cpp
index 45fc6370a06d40..1aef6a3f476295 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap.pass.cpp
@@ -33,6 +33,8 @@ void test() {
CharT arr[4];
std::span<CharT> sp{arr};
+ // TODO:
+
// Mode: default
{
SpStream rhsSpSt{sp};
diff --git a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap_nonmember.pass.cpp b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap_nonmember.pass.cpp
index ae54e409297454..165dc72673e9ff 100644
--- a/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap_nonmember.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/ispanstream/ispanstream.assign/swap_nonmember.pass.cpp
@@ -29,6 +29,8 @@ void test() {
CharT arr[4];
std::span<CharT> sp{arr};
+ // TODO:
+
// Mode: default
{
SpStream rhsSpSt{sp};
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
new file mode 100644
index 00000000000000..798a4de1ae4d4a
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_streambuf<charT, traits> {
+
+// // [spanbuf.cons], constructors
+//
+// basic_spanbuf& operator=(basic_spanbuf&& rhs);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // TODO:
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in};
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out};
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
new file mode 100644
index 00000000000000..26aed41479890b
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_spanbuf<charT, traits> {
+
+// // [ispanstream.swap], swap
+// void swap(basic_spanbuf& rhs);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // TODO:
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
new file mode 100644
index 00000000000000..f92b77bfc1511a
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits>
+// void swap(basic_spanbuf<charT, traits>& x, basic_spanbuf<charT, traits>& y);
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf= std::basic_spanbuf<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // TODO:
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ std::swap(spBuf, rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in};
+ SpBuf spBuf(std::span<CharT>{});
+ std::swap(spBuf, rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode `ios_base::out`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out};
+ SpBuf spBuf(std::span<CharT>{});
+ std::swap(spBuf, rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpBuf spBuf(std::span<CharT>{});
+ std::swap(spBuf, rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
new file mode 100644
index 00000000000000..25cee726941636
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_spanbuf<charT, traits> {
+
+// // [spanbuf.members], member functions
+// std::span<charT> span() const noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // TODO:
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
new file mode 100644
index 00000000000000..9b696391b746f0
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_spanbuf<charT, traits> {
+
+// // [spanbuf.members], member functions
+//
+// void span(std::span<charT> s) noexcept;
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // TODO:
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
new file mode 100644
index 00000000000000..039fa1f61c09a8
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_spanbuf<charT, traits> {
+
+// // [spanbuf.virtuals], overridden virtual functions
+//
+// pos_type seekoff(off_type off, ios_base::seekdir way,
+// ios_base::openmode which = ios_base::in | ios_base::out) override;
+// pos_type seekpos(pos_type sp,
+// ios_base::openmode which = ios_base::in | ios_base::out) override;
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // TODO:
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
new file mode 100644
index 00000000000000..006d282cacc78b
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_spanbuf<charT, traits> {
+
+// // [spanbuf.virtuals], overridden virtual functions
+//
+// pos_type seekpos(pos_type sp,
+// ios_base::openmode which = ios_base::in | ios_base::out) override;
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
new file mode 100644
index 00000000000000..fe9f5c3bf9cd89
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+
+// <spanstream>
+
+// template<class charT, class traits = char_traits<charT>>
+// class basic_spanbuf
+// : public basic_spanbuf<charT, traits> {
+
+// // [spanbuf.virtuals], overridden virtual functions
+// basic_streambuf<charT, traits>* setbuf(charT*, streamsize) override;
+
+#include <cassert>
+#include <concepts>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "test_convertible.h"
+#include "test_macros.h"
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // TODO:
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+}
+
+int main(int, char**) {
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
>From 5e5fb2f8f9da24b2be2bcd7172f59b1ad641082f Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 5 Mar 2024 18:27:22 +0200
Subject: [PATCH 25/39] Tests: updated `iosfwd.pass.cpp`
---
.../iostream.forward/iosfwd.pass.cpp | 37 +++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/libcxx/test/std/input.output/iostream.forward/iosfwd.pass.cpp b/libcxx/test/std/input.output/iostream.forward/iosfwd.pass.cpp
index 1a28a5985a0112..bd9a6ae00de352 100644
--- a/libcxx/test/std/input.output/iostream.forward/iosfwd.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.forward/iosfwd.pass.cpp
@@ -83,6 +83,29 @@ int main(int, char**)
#endif
test<std::basic_stringstream<unsigned short>*>();
+#if TEST_STD_VER >= 23
+ test<std::basic_spanbuf<unsigned short>*>();
+ test<std::basic_spanbuf<char>*>();
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<std::basic_spanbuf<wchar_t>*>();
+# endif
+ test<std::basic_ispanstream<unsigned short>*>();
+ test<std::basic_ispanstream<char>*>();
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<std::basic_ispanstream<wchar_t>*>();
+# endif
+ test<std::basic_ospanstream<unsigned short>*>();
+ test<std::basic_ospanstream<char>*>();
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<std::basic_ospanstream<wchar_t>*>();
+# endif
+ test<std::basic_spanstream<char>*>();
+ test<std::basic_spanstream<unsigned short>*>();
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<std::basic_spanstream<wchar_t>*>();
+# endif
+#endif // TEST_STD_VER >= 23
+
test<std::basic_filebuf<char>* >();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test<std::basic_filebuf<wchar_t>* >();
@@ -134,6 +157,13 @@ int main(int, char**)
test<std::ostringstream*>();
test<std::stringstream* >();
+#if TEST_STD_VER >= 23
+ test<std::spanbuf*>();
+ test<std::ispanstream*>();
+ test<std::ospanstream*>();
+ test<std::spanstream*>();
+#endif // TEST_STD_VER >= 23
+
test<std::filebuf* >();
test<std::ifstream*>();
test<std::ofstream*>();
@@ -150,6 +180,13 @@ int main(int, char**)
test<std::wostringstream*>();
test<std::wstringstream* >();
+# if TEST_STD_VER >= 23
+ test<std::wspanbuf*>();
+ test<std::wispanstream*>();
+ test<std::wospanstream*>();
+ test<std::wspanstream*>();
+# endif // TEST_STD_VER >= 23
+
test<std::wfilebuf* >();
test<std::wifstream*>();
test<std::wofstream*>();
>From 43e83898b003cfcfe9244c9a4d4ed6f2eeb00a26 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 5 Mar 2024 18:33:06 +0200
Subject: [PATCH 26/39] Tests: WIP fix test skelettons
---
.../spanbuf/spanbuf.assign/move.pass.cpp | 66 ++++++++--------
.../spanbuf/spanbuf.assign/swap.pass.cpp | 74 +++++++++---------
.../spanbuf.assign/swap_nonmember.pass.cpp | 76 +++++++++----------
.../spanbuf/spanbuf.members/span.pass.cpp | 20 ++---
.../spanbuf.members/span.span.pass.cpp | 18 ++---
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 20 ++---
.../seekoff.pos_type.open_mode.pass.cpp | 20 ++---
.../spanbuf/spanbuf.virtuals/setbuf.pass.cpp | 18 ++---
8 files changed, 156 insertions(+), 156 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
index 798a4de1ae4d4a..7702c2c51dbc82 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
@@ -35,39 +35,39 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
-
- // Mode: default
- {
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf = std::move(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
- // Mode: `ios_base::in`
- {
- SpBuf rhsSpBuf{sp, std::ios_base::in};
- SpBuf spBuf = std::move(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
- // Mode `ios_base::out`
- {
- SpBuf rhsSpBuf{sp, std::ios_base::out};
- SpBuf spBuf = std::move(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
- // Mode: multiple
- {
- SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
- SpBuf spBuf = std::move(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
+ (void)sp;
+ // // Mode: default
+ // {
+ // SpBuf rhsSpBuf{sp};
+ // SpBuf spBuf = std::move(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
+ // // Mode: `ios_base::in`
+ // {
+ // SpBuf rhsSpBuf{sp, std::ios_base::in};
+ // SpBuf spBuf = std::move(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
+ // // Mode `ios_base::out`
+ // {
+ // SpBuf rhsSpBuf{sp, std::ios_base::out};
+ // SpBuf spBuf = std::move(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(spBuf.span().empty());
+ // assert(spBuf.span().size() == 0);
+ // }
+ // // Mode: multiple
+ // {
+ // SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ // SpBuf spBuf = std::move(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(spBuf.span().empty());
+ // assert(spBuf.span().size() == 0);
+ // }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
index 26aed41479890b..e5a2fff2ba8ba7 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
@@ -34,43 +34,43 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
-
- // Mode: default
- {
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
- // Mode: `ios_base::in`
- {
- SpBuf rhsSpBuf{sp, std::ios_base::in};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
- // Mode `ios_base::out`
- {
- SpBuf rhsSpBuf{sp, std::ios_base::out};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
- // Mode: multiple
- {
- SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
+ (void)sp;
+ // // Mode: default
+ // {
+ // SpBuf rhsSpBuf{sp};
+ // SpBuf spBuf(std::span<CharT>{});
+ // spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
+ // // Mode: `ios_base::in`
+ // {
+ // SpBuf rhsSpBuf{sp, std::ios_base::in};
+ // SpBuf spBuf(std::span<CharT>{});
+ // spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
+ // // Mode `ios_base::out`
+ // {
+ // SpBuf rhsSpBuf{sp, std::ios_base::out};
+ // SpBuf spBuf(std::span<CharT>{});
+ // spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(spBuf.span().empty());
+ // assert(spBuf.span().size() == 0);
+ // }
+ // // Mode: multiple
+ // {
+ // SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ // SpBuf spBuf(std::span<CharT>{});
+ // spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(spBuf.span().empty());
+ // assert(spBuf.span().size() == 0);
+ // }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
index f92b77bfc1511a..e3342253bc741e 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
@@ -24,49 +24,49 @@
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
- using SpBuf= std::basic_spanbuf<CharT, TraitsT>;
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
CharT arr[4];
std::span<CharT> sp{arr};
// TODO:
-
- // Mode: default
- {
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- std::swap(spBuf, rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
- // Mode: `ios_base::in`
- {
- SpBuf rhsSpBuf{sp, std::ios_base::in};
- SpBuf spBuf(std::span<CharT>{});
- std::swap(spBuf, rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
- // Mode `ios_base::out`
- {
- SpBuf rhsSpBuf{sp, std::ios_base::out};
- SpBuf spBuf(std::span<CharT>{});
- std::swap(spBuf, rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
- // Mode: multiple
- {
- SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
- SpBuf spBuf(std::span<CharT>{});
- std::swap(spBuf, rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
+ (void)sp;
+ // // Mode: default
+ // {
+ // SpBuf rhsSpBuf{sp};
+ // SpBuf spBuf(std::span<CharT>{});
+ // std::swap(spBuf, rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
+ // // Mode: `ios_base::in`
+ // {
+ // SpBuf rhsSpBuf{sp, std::ios_base::in};
+ // SpBuf spBuf(std::span<CharT>{});
+ // std::swap(spBuf, rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
+ // // Mode `ios_base::out`
+ // {
+ // SpBuf rhsSpBuf{sp, std::ios_base::out};
+ // SpBuf spBuf(std::span<CharT>{});
+ // std::swap(spBuf, rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(spBuf.span().empty());
+ // assert(spBuf.span().size() == 0);
+ // }
+ // // Mode: multiple
+ // {
+ // SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ // SpBuf spBuf(std::span<CharT>{});
+ // std::swap(spBuf, rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(spBuf.span().empty());
+ // assert(spBuf.span().size() == 0);
+ // }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
index 25cee726941636..10316fe19f9ff7 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
@@ -34,16 +34,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
-
- // Mode: default
- {
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
+ (void)sp;
+ // // Mode: default
+ // {
+ // SpBuf rhsSpBuf{sp};
+ // SpBuf spBuf(std::span<CharT>{});
+ // spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
index 9b696391b746f0..8a0e3adc9df0e6 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
@@ -35,16 +35,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
-
+ (void)sp;
// Mode: default
- {
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
+ // {
+ // SpBuf rhsSpBuf{sp};
+ // SpBuf spBuf(std::span<CharT>{});
+ // spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
index 039fa1f61c09a8..341e9f3f61d242 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -38,16 +38,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
-
- // Mode: default
- {
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
+ (void)sp;
+ // // Mode: default
+ // {
+ // SpBuf rhsSpBuf{sp};
+ // SpBuf spBuf(std::span<CharT>{});
+ // spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
index 006d282cacc78b..08b6cade94fb3d 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
@@ -34,16 +34,16 @@ void test() {
CharT arr[4];
std::span<CharT> sp{arr};
-
- // Mode: default
- {
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
+ (void)sp;
+ // // Mode: default
+ // {
+ // SpBuf rhsSpBuf{sp};
+ // SpBuf spBuf(std::span<CharT>{});
+ // spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
index fe9f5c3bf9cd89..50e5b02a01c25b 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
@@ -34,16 +34,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
-
+ (void)sp;
// Mode: default
- {
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
+ // {
+ // SpBuf rhsSpBuf{sp};
+ // SpBuf spBuf(std::span<CharT>{});
+ // spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ // }
}
int main(int, char**) {
>From 87e976cc8cccaf129cb57203e850e6c9f05a64c9 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 5 Mar 2024 19:26:52 +0200
Subject: [PATCH 27/39] Tests: try to fix CI
---
.../spanbuf/spanbuf.assign/move.pass.cpp | 19 +++++++++---------
.../spanbuf/spanbuf.assign/swap.pass.cpp | 20 +++++++++----------
.../spanbuf.assign/swap_nonmember.pass.cpp | 20 +++++++++----------
.../spanbuf/spanbuf.members/span.pass.cpp | 20 +++++++++----------
.../spanbuf.members/span.span.pass.cpp | 18 ++++++++---------
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 20 +++++++++----------
.../seekoff.pos_type.open_mode.pass.cpp | 20 +++++++++----------
.../spanbuf/spanbuf.virtuals/setbuf.pass.cpp | 18 ++++++++---------
8 files changed, 78 insertions(+), 77 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
index 7702c2c51dbc82..c2cc8104707be4 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
@@ -35,15 +35,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
- (void)sp;
- // // Mode: default
- // {
- // SpBuf rhsSpBuf{sp};
- // SpBuf spBuf = std::move(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf = std::move(rhsSpBuf);
+ (void)spBuf;
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ }
// // Mode: `ios_base::in`
// {
// SpBuf rhsSpBuf{sp, std::ios_base::in};
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
index e5a2fff2ba8ba7..cf036856f0b000 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
@@ -34,16 +34,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
- (void)sp;
- // // Mode: default
- // {
- // SpBuf rhsSpBuf{sp};
- // SpBuf spBuf(std::span<CharT>{});
- // spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ }
// // Mode: `ios_base::in`
// {
// SpBuf rhsSpBuf{sp, std::ios_base::in};
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
index e3342253bc741e..d834332bdca156 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
@@ -30,16 +30,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
- (void)sp;
- // // Mode: default
- // {
- // SpBuf rhsSpBuf{sp};
- // SpBuf spBuf(std::span<CharT>{});
- // std::swap(spBuf, rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ std::swap(spBuf, rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ }
// // Mode: `ios_base::in`
// {
// SpBuf rhsSpBuf{sp, std::ios_base::in};
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
index 10316fe19f9ff7..98e8aef0330e9d 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
@@ -34,16 +34,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
- (void)sp;
- // // Mode: default
- // {
- // SpBuf rhsSpBuf{sp};
- // SpBuf spBuf(std::span<CharT>{});
- // spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
index 8a0e3adc9df0e6..3b3ef6704bade4 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
@@ -35,16 +35,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
- (void)sp;
+
// Mode: default
- // {
- // SpBuf rhsSpBuf{sp};
- // SpBuf spBuf(std::span<CharT>{});
- // spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
index 341e9f3f61d242..6b4580bedb89c2 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -38,16 +38,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
- (void)sp;
- // // Mode: default
- // {
- // SpBuf rhsSpBuf{sp};
- // SpBuf spBuf(std::span<CharT>{});
- // spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
index 08b6cade94fb3d..0980143e674075 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
@@ -34,16 +34,16 @@ void test() {
CharT arr[4];
std::span<CharT> sp{arr};
- (void)sp;
- // // Mode: default
- // {
- // SpBuf rhsSpBuf{sp};
- // SpBuf spBuf(std::span<CharT>{});
- // spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
+
+ // Mode: default
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
index 50e5b02a01c25b..193185da8d9ca3 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
@@ -34,16 +34,16 @@ void test() {
std::span<CharT> sp{arr};
// TODO:
- (void)sp;
+
// Mode: default
- // {
- // SpBuf rhsSpBuf{sp};
- // SpBuf spBuf(std::span<CharT>{});
- // spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
+ {
+ SpBuf rhsSpBuf{sp};
+ SpBuf spBuf(std::span<CharT>{});
+ spBuf.swap(rhsSpBuf);
+ // assert(spBuf.span().data() == arr);
+ // assert(!spBuf.span().empty());
+ // assert(spBuf.span().size() == 4);
+ }
}
int main(int, char**) {
>From fe640ca08d242679a56b1c22addd0ef76e069657 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 6 Mar 2024 14:53:21 +0200
Subject: [PATCH 28/39] Tests: WIP `span.pass` and `span.span.pass`
---
libcxx/include/spanstream | 13 +--
.../input.output/span.streams/helper_types.h | 23 ++---
.../spanbuf/spanbuf.members/span.pass.cpp | 20 ++--
.../spanbuf.members/span.span.pass.cpp | 94 +++++++++++++++++--
4 files changed, 107 insertions(+), 43 deletions(-)
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index c735baaae93d90..f1ffd4f201368b 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -66,11 +66,12 @@
#include <__utility/move.h>
#include <__utility/swap.h>
#include <iostream>
-// #include <print>
#include <span>
#include <streambuf>
#include <version>
+// #include <print>
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -98,11 +99,11 @@ public:
_LIBCPP_HIDE_FROM_ABI basic_spanbuf() : basic_spanbuf(ios_base::in | ios_base::out) {}
_LIBCPP_HIDE_FROM_ABI explicit basic_spanbuf(ios_base::openmode __which)
- : basic_spanbuf(std::span<_CharT>(), __which) {}
+ : basic_streambuf<_CharT, _Traits>{}, __mode_{__which} {}
_LIBCPP_HIDE_FROM_ABI explicit basic_spanbuf(std::span<_CharT> __s,
ios_base::openmode __which = ios_base::in | ios_base::out)
- : basic_streambuf<_CharT, _Traits>{}, __mode_{__which}, __buf_{__s} {
+ : basic_streambuf<_CharT, _Traits>{}, __mode_{__which} {
this->span(__s);
}
@@ -267,14 +268,8 @@ public:
requires(!convertible_to<_ROSeq, std::span<_CharT>>) && convertible_to<_ROSeq, std::span<const _CharT>>
_LIBCPP_HIDE_FROM_ABI explicit basic_ispanstream(_ROSeq&& __s)
: basic_istream<_CharT, _Traits>(std::addressof(__sb_)) {
- // std::println(stderr, "ispanstream");
std::span<const _CharT> __sp(std::forward<_ROSeq>(__s));
- // std::println(stderr, "span __sb_ {} {}", __sb_.span().empty(), __sb_.span().size());
- // std::println(stderr, "span data {} {}", __sp.empty(), __sp.size());
- // std::println(stderr, "ispanstream 2");
this->span(std::span<_CharT>(std::span<_CharT>(const_cast<_CharT*>(__sp.data()), __sp.size())));
- // std::println(stderr, "span __sb_ {} {}", __sb_.span().empty(), __sb_.span().size());
- // std::println(stderr, "ispanstream 3");
}
basic_ispanstream& operator=(const basic_ispanstream&) = delete;
diff --git a/libcxx/test/std/input.output/span.streams/helper_types.h b/libcxx/test/std/input.output/span.streams/helper_types.h
index 7f67432f9f8806..79760f97e223b6 100644
--- a/libcxx/test/std/input.output/span.streams/helper_types.h
+++ b/libcxx/test/std/input.output/span.streams/helper_types.h
@@ -16,7 +16,7 @@
#include "test_macros.h"
-// #include <print>
+// ROS types
template <typename CharT, std::size_t N = 0>
class ReadOnlySpan {
@@ -25,19 +25,10 @@ class ReadOnlySpan {
operator std::span<CharT>() = delete;
- operator std::span<const CharT>() {
- // std::println(stderr, "----> ROspan");
- return std::span<const CharT, N>{arr_};
- }
+ operator std::span<const CharT>() { return std::span<const CharT, N>{arr_}; }
- const CharT* begin() {
- // std::println(stderr, "----> ROspan begin");
- return arr_;
- }
- const CharT* end() {
- // std::println(stderr, "----> ROspan end");
- return arr_ + N;
- }
+ const CharT* begin() { return arr_; }
+ const CharT* end() { return arr_ + N; }
private:
CharT* arr_;
@@ -46,6 +37,8 @@ class ReadOnlySpan {
template <typename CharT, std::size_t N>
inline constexpr bool std::ranges::enable_borrowed_range<ReadOnlySpan<CharT, N>> = true;
+// Constraints: Constructors [ispanstream.cons]
+
static_assert(std::ranges::borrowed_range<ReadOnlySpan<char>>);
static_assert(!std::constructible_from<std::span<char>, ReadOnlySpan<char>>);
@@ -96,6 +89,8 @@ class NonReadOnlySpan {
template <typename CharT, std::size_t N>
inline constexpr bool std::ranges::enable_borrowed_range<NonReadOnlySpan<CharT, N>> = true;
+// Constraints: Constructors [ispanstream.cons]
+
static_assert(std::ranges::borrowed_range<NonReadOnlySpan<char>>);
static_assert(std::constructible_from<std::span<char>, NonReadOnlySpan<char>>);
@@ -126,7 +121,7 @@ static_assert(!std::constructible_from<std::span<const wchar_t>, const NonReadOn
static_assert(!std::convertible_to<const NonReadOnlySpan<wchar_t>, std::span<const wchar_t>>);
#endif
-struct SomeObject {};
+// Mode types
struct NonMode {};
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
index 98e8aef0330e9d..7d5ebea2903ea6 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
@@ -31,19 +31,17 @@ void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
CharT arr[4];
- std::span<CharT> sp{arr};
-
- // TODO:
- // Mode: default
+ std::span<CharT> sp{arr};
+ assert(sp.data() == arr);
+ assert(!sp.empty());
+ assert(sp.size() == 4);
+
{
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- }
+ SpBuf spBuf(sp);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
index 3b3ef6704bade4..e1dfe517fe0d62 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
@@ -32,18 +32,94 @@ void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
CharT arr[4];
- std::span<CharT> sp{arr};
- // TODO:
+ // Mode: default (`in` | `out`)
+ {
+ SpBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.span(arr);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ {
+ SpBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ std::span<CharT> sp{arr};
+ assert(sp.data() == arr);
+ assert(!sp.empty());
+ assert(sp.size() == 4);
+
+ spBuf.span(sp);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `in`
+ {
+ SpBuf spBuf{std::ios_base::in};
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.span(arr);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ {
+ SpBuf spBuf{std::ios_base::in};
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ std::span<CharT> sp{arr};
+ assert(sp.data() == arr);
+ assert(!sp.empty());
+ assert(sp.size() == 4);
- // Mode: default
+ spBuf.span(sp);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode: `out`
{
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
+ SpBuf spBuf{std::ios_base::out};
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.span(arr);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ {
+ SpBuf spBuf{std::ios_base::out};
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ std::span<CharT> sp{arr};
+ assert(sp.data() == arr);
+ assert(!sp.empty());
+ assert(sp.size() == 4);
+
+ spBuf.span(sp);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
}
}
>From c2279fdc8a54db9a617d5cbc40e6ec4333f2594e Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 6 Mar 2024 21:59:17 +0200
Subject: [PATCH 29/39] Tests: updated `span.pass` and `span.span.pass`
---
.../spanbuf/spanbuf.members/span.pass.cpp | 36 ++++++++--
.../spanbuf.members/span.span.pass.cpp | 66 +++++++++++++++----
2 files changed, 83 insertions(+), 19 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
index 7d5ebea2903ea6..635b8d2a030733 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
@@ -36,12 +36,38 @@ void test() {
assert(sp.data() == arr);
assert(!sp.empty());
assert(sp.size() == 4);
-
+
+ // Mode: default (`in` | `out`)
+ {
+ SpBuf spBuf(sp);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `in`
+ {
+ SpBuf spBuf(sp, std::ios_base::in);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode: `out`
+ {
+ SpBuf spBuf(sp, std::ios_base::out);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
{
- SpBuf spBuf(sp);
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
+ SpBuf spBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
index e1dfe517fe0d62..5495cdefbe7c68 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
@@ -33,6 +33,11 @@ void test() {
CharT arr[4];
+ std::span<CharT> sp{arr};
+ assert(sp.data() == arr);
+ assert(!sp.empty());
+ assert(sp.size() == 4);
+
// Mode: default (`in` | `out`)
{
SpBuf spBuf;
@@ -52,11 +57,6 @@ void test() {
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
- std::span<CharT> sp{arr};
- assert(sp.data() == arr);
- assert(!sp.empty());
- assert(sp.size() == 4);
-
spBuf.span(sp);
assert(spBuf.span().data() == arr);
// Mode `out` counts read characters
@@ -81,11 +81,6 @@ void test() {
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
- std::span<CharT> sp{arr};
- assert(sp.data() == arr);
- assert(!sp.empty());
- assert(sp.size() == 4);
-
spBuf.span(sp);
assert(spBuf.span().data() == arr);
assert(!spBuf.span().empty());
@@ -110,10 +105,30 @@ void test() {
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
- std::span<CharT> sp{arr};
- assert(sp.data() == arr);
- assert(!sp.empty());
- assert(sp.size() == 4);
+ spBuf.span(sp);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf spBuf(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.span(arr);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ {
+ SpBuf spBuf(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
spBuf.span(sp);
assert(spBuf.span().data() == arr);
@@ -121,6 +136,29 @@ void test() {
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
+ // Mode: `ate`
+ {
+ SpBuf spBuf(std::ios_base::out | std::ios_base::ate);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.span(arr);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ {
+ SpBuf spBuf(std::ios_base::out | std::ios_base::ate);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.span(sp);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
}
int main(int, char**) {
>From dfc0515bdb4ccce7c388467fca655c160b635c01 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 9 Mar 2024 07:52:45 +0200
Subject: [PATCH 30/39] Implementations: `basic_spanbuf` improved constructors
and member functions
---
libcxx/include/spanstream | 39 ++++++++++++++++++++-------------------
1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index f1ffd4f201368b..63b61d1dee26d0 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -99,12 +99,12 @@ public:
_LIBCPP_HIDE_FROM_ABI basic_spanbuf() : basic_spanbuf(ios_base::in | ios_base::out) {}
_LIBCPP_HIDE_FROM_ABI explicit basic_spanbuf(ios_base::openmode __which)
- : basic_streambuf<_CharT, _Traits>{}, __mode_{__which} {}
+ : basic_spanbuf(std::span<_CharT>(), __which) {}
_LIBCPP_HIDE_FROM_ABI explicit basic_spanbuf(std::span<_CharT> __s,
ios_base::openmode __which = ios_base::in | ios_base::out)
- : basic_streambuf<_CharT, _Traits>{}, __mode_{__which} {
- this->span(__s);
+ : basic_streambuf<_CharT, _Traits>{}, __mode_(__which) {
+ span(__s);
}
basic_spanbuf(const basic_spanbuf&) = delete;
@@ -113,6 +113,7 @@ public:
: basic_streambuf<_CharT, _Traits>{std::move(__rhs)},
__mode_{std::move(__rhs.__mode_)},
__buf_{std::move(__rhs.__buf_)} {}
+ // __buf_{std::exchange(__rhs.__buf_, {})} {}
// [spanbuf.assign], assignment and swap
@@ -120,7 +121,7 @@ public:
_LIBCPP_HIDE_FROM_ABI basic_spanbuf& operator=(basic_spanbuf&& __rhs) {
basic_spanbuf __tmp{std::move(__rhs)};
- this->swap(__tmp);
+ swap(__tmp);
return *this;
}
@@ -134,7 +135,7 @@ public:
_LIBCPP_HIDE_FROM_ABI std::span<_CharT> span() const noexcept {
if (__mode_ & ios_base::out) {
- return std::span<_CharT>(this->pbase(), this->pptr());
+ return std::span<_CharT>{this->pbase(), this->pptr()};
}
return __buf_;
}
@@ -158,38 +159,38 @@ protected:
// [spanbuf.virtuals], overridden virtual functions
_LIBCPP_HIDE_FROM_ABI basic_streambuf<_CharT, _Traits>* setbuf(_CharT* __s, streamsize __n) override {
- this->span(std::span<_CharT>(__s, __n));
+ span(std::span<_CharT>(__s, __n));
return this;
}
_LIBCPP_HIDE_FROM_ABI pos_type
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which = ios_base::in | ios_base::out) override {
- const pos_type __error(off_type(-1));
+ const auto __error = static_cast<pos_type>(off_type{-1});
if ((__which & ios_base::in) && (__which & ios_base::out) && (ios_base::cur == __way))
return __error;
// Calculate __baseoff
- off_type __baseoff;
+ std::size_t __baseoff;
switch (__way) {
case ios_base::beg:
- __baseoff = off_type(0);
+ __baseoff = 0Z;
break;
case ios_base::cur:
if (__which & ios_base::out)
- __baseoff = off_type(this->pptr() - this->pbase());
+ __baseoff = this->pptr() - this->pbase();
else
- __baseoff = off_type(this->gptr() - this->eback());
+ __baseoff = this->gptr() - this->eback();
break;
case ios_base::end:
if ((__which & ios_base::out) && !(__which & ios_base::in))
- __baseoff = off_type(this->pptr() - this->pbase());
+ __baseoff = this->pptr() - this->pbase();
else
- __baseoff = off_type(__buf_.size());
+ __baseoff = __buf_.size();
break;
default:
@@ -200,29 +201,29 @@ protected:
off_type __newoff;
- if (__builtin_add_overflow(__baseoff, __off, &__newoff) || (__newoff < off_type(0)) ||
- (std::cmp_greater(__newoff, __buf_.size())))
+ if (__builtin_add_overflow(__baseoff, __off, &__newoff) || (__newoff < off_type{0}) ||
+ std::cmp_greater(__newoff, __buf_.size()))
return __error;
if (__which & ios_base::in) {
- if ((this->gptr() == nullptr) && (__newoff != off_type(0)))
+ if ((this->gptr() == nullptr) && (__newoff != off_type{0}))
return __error;
this->setg(this->eback(), this->eback() + __newoff, this->egptr());
}
if (__which & ios_base::out) {
- if ((this->pptr() == nullptr) && (__newoff != off_type(0)))
+ if ((this->pptr() == nullptr) && (__newoff != off_type{0}))
return __error;
this->setp(this->pbase(), this->epptr());
this->pbump(__newoff);
}
- return pos_type(__newoff);
+ return static_cast<pos_type>(__newoff);
}
_LIBCPP_HIDE_FROM_ABI pos_type seekpos(pos_type __sp,
ios_base::openmode __which = ios_base::in | ios_base::out) override {
- return seekoff(off_type(__sp), ios_base::beg, __which);
+ return seekoff(static_cast<off_type>(__sp), ios_base::beg, __which);
}
private:
>From 3984f4e57e3a98adb2f061f6866da7b52d9b6a91 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sat, 9 Mar 2024 07:53:28 +0200
Subject: [PATCH 31/39] Tests: `basic_spanbuf` improved tests for constructors
and member functions
---
.../spanbuf/spanbuf.assign/move.pass.cpp | 353 ++++++++++++--
.../spanbuf/spanbuf.assign/swap.pass.cpp | 138 ++++--
.../spanbuf.assign/swap_nonmember.pass.cpp | 138 ++++--
.../spanbuf/spanbuf.cons/default.pass.cpp | 14 +-
.../spanbuf/spanbuf.cons/mode.pass.cpp | 15 +-
.../spanbuf/spanbuf.cons/move.pass.cpp | 449 ++++++++++++------
.../spanbuf/spanbuf.cons/span.mode.pass.cpp | 67 ++-
.../spanbuf/spanbuf.members/span.pass.cpp | 7 +
8 files changed, 912 insertions(+), 269 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
index c2cc8104707be4..c1749a1068ea90 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
@@ -24,54 +24,337 @@
#include <spanstream>
#include "constexpr_char_traits.h"
-#include "test_convertible.h"
+#include "nasty_string.h"
#include "test_macros.h"
+template <typename CharT, typename TraitsT>
+struct TestSpanBuf : std::basic_spanbuf<CharT, TraitsT> {
+ using std::basic_spanbuf<CharT, TraitsT>::basic_spanbuf;
+
+ TestSpanBuf(std::basic_spanbuf<CharT, TraitsT>&& rhs_p) : std::basic_spanbuf<CharT, TraitsT>(std::move(rhs_p)) {}
+
+ void check_postconditions(TestSpanBuf<CharT, TraitsT> const& rhs_p) const {
+ assert(this->span().data() == rhs_p.span().data());
+ assert(this->span().size() == rhs_p.span().size());
+ assert(this->eback() == rhs_p.eback());
+ assert(this->gptr() == rhs_p.gptr());
+ assert(this->egptr() == rhs_p.egptr());
+ assert(this->pbase() == rhs_p.pbase());
+ assert(this->pptr() == rhs_p.pptr());
+ assert(this->epptr() == rhs_p.epptr());
+ assert(this->getloc() == rhs_p.getloc());
+ }
+};
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test_postconditions() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ // Empty `span`
+ {
+ // Mode: default
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `in`
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `out`
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: multiple
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `ate`
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::ate);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ }
+
+ // Non-empty `span`
+ {
+ CharT arr[4];
+
+ // Mode: default
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `in`
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `out`
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: multiple
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `ate`
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::ate);
+ TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ }
+}
+
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
- CharT arr[4];
- std::span<CharT> sp{arr};
+ // Empty `span`
+ {
+ // Mode: default (`in` | `out`)
+ {
+ SpBuf rhsSpBuf;
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `in`
+ {
+ SpBuf rhsSpBuf{std::ios_base::in};
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `out`
+ {
+ SpBuf rhsSpBuf{std::ios_base::out};
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
- // TODO:
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
- // Mode: default
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{std::ios_base::out | std::ios_base::in | std::ios_base::binary};
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `ate`
+ {
+ SpBuf rhsSpBuf{std::ios_base::ate};
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ }
+
+ // Non-empty `span`
{
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf = std::move(rhsSpBuf);
- (void)spBuf;
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default (`in` | `out`)
+ {
+ SpBuf rhsSpBuf{sp};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == arr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `in`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in};
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
+
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode `out`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == arr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out | std::ios_base::in | std::ios_base::binary};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == arr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `ate`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::ate};
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
+
+ SpBuf spBuf = std::move(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+
+ // After move
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
+ }
}
- // // Mode: `ios_base::in`
- // {
- // SpBuf rhsSpBuf{sp, std::ios_base::in};
- // SpBuf spBuf = std::move(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
- // // Mode `ios_base::out`
- // {
- // SpBuf rhsSpBuf{sp, std::ios_base::out};
- // SpBuf spBuf = std::move(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(spBuf.span().empty());
- // assert(spBuf.span().size() == 0);
- // }
- // // Mode: multiple
- // {
- // SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
- // SpBuf spBuf = std::move(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(spBuf.span().empty());
- // assert(spBuf.span().size() == 0);
- // }
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test_postconditions<nasty_char, nasty_char_traits>();
+#endif
+ test_postconditions<char>();
+ test_postconditions<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_postconditions<wchar_t>();
+ test_postconditions<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
index cf036856f0b000..6db44e92be58d3 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
@@ -31,46 +31,118 @@ void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
CharT arr[4];
- std::span<CharT> sp{arr};
- // TODO:
+ std::span<CharT> sp{arr};
+ assert(sp.data() == arr);
+ assert(!sp.empty());
+ assert(sp.size() == 4);
- // Mode: default
+ // Mode: default (`in` | `out`)
{
SpBuf rhsSpBuf{sp};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in};
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
+
SpBuf spBuf(std::span<CharT>{});
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode `ios_base::out`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.swap(rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `ios_base::ate`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out | std::ios_base::ate};
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
+
+ SpBuf spBuf(std::span<CharT>{});
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
}
- // // Mode: `ios_base::in`
- // {
- // SpBuf rhsSpBuf{sp, std::ios_base::in};
- // SpBuf spBuf(std::span<CharT>{});
- // spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
- // // Mode `ios_base::out`
- // {
- // SpBuf rhsSpBuf{sp, std::ios_base::out};
- // SpBuf spBuf(std::span<CharT>{});
- // spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(spBuf.span().empty());
- // assert(spBuf.span().size() == 0);
- // }
- // // Mode: multiple
- // {
- // SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
- // SpBuf spBuf(std::span<CharT>{});
- // spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(spBuf.span().empty());
- // assert(spBuf.span().size() == 0);
- // }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
index d834332bdca156..78c50156740199 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
@@ -27,46 +27,118 @@ void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
CharT arr[4];
- std::span<CharT> sp{arr};
- // TODO:
+ std::span<CharT> sp{arr};
+ assert(sp.data() == arr);
+ assert(!sp.empty());
+ assert(sp.size() == 4);
- // Mode: default
+ // Mode: default (`in` | `out`)
{
SpBuf rhsSpBuf{sp};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ std::swap(spBuf, rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `ios_base::in`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in};
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
+
SpBuf spBuf(std::span<CharT>{});
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ std::swap(spBuf, rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode `ios_base::out`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ std::swap(spBuf, rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ std::swap(spBuf, rhsSpBuf);
+ assert(spBuf.span().data() == arr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `ios_base::ate`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out | std::ios_base::ate};
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
+
+ SpBuf spBuf(std::span<CharT>{});
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
std::swap(spBuf, rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
}
- // // Mode: `ios_base::in`
- // {
- // SpBuf rhsSpBuf{sp, std::ios_base::in};
- // SpBuf spBuf(std::span<CharT>{});
- // std::swap(spBuf, rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
- // }
- // // Mode `ios_base::out`
- // {
- // SpBuf rhsSpBuf{sp, std::ios_base::out};
- // SpBuf spBuf(std::span<CharT>{});
- // std::swap(spBuf, rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(spBuf.span().empty());
- // assert(spBuf.span().size() == 0);
- // }
- // // Mode: multiple
- // {
- // SpBuf rhsSpBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
- // SpBuf spBuf(std::span<CharT>{});
- // std::swap(spBuf, rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(spBuf.span().empty());
- // assert(spBuf.span().size() == 0);
- // }
}
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
index b76af127f43144..e1c6604b1bceb5 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/default.pass.cpp
@@ -21,19 +21,25 @@
#include <spanstream>
#include "constexpr_char_traits.h"
+#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
- SpBuf spBuf;
- assert(spBuf.span().data() == nullptr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
+ {
+ SpBuf spBuf;
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
index d2bd64f35cb59a..91fc5385484f71 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/mode.pass.cpp
@@ -47,8 +47,6 @@ template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
- static_assert(std::default_initializable<SpBuf>);
-
// Mode: `in`
{
SpBuf spBuf(std::ios_base::in);
@@ -60,6 +58,7 @@ void test() {
{
SpBuf spBuf(std::ios_base::out);
assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
@@ -67,6 +66,15 @@ void test() {
{
SpBuf spBuf(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read character
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `ate`
+ {
+ SpBuf spBuf(std::ios_base::out | std::ios_base::ate);
+ assert(spBuf.span().data() == nullptr);
+
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
@@ -78,6 +86,9 @@ int main(int, char**) {
#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
index 1bab0f860d9f34..9252f64908de46 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
@@ -24,7 +24,7 @@
#include <spanstream>
#include "constexpr_char_traits.h"
-#include "test_convertible.h"
+#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT>
@@ -47,173 +47,314 @@ struct TestSpanBuf : std::basic_spanbuf<CharT, TraitsT> {
};
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
-void test() {
+void test_postconditions() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+ // Empty `span`
+ {
+ // Mode: default
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `in`
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `out`
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: multiple
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `ate`
+ {
+ std::span<CharT> sp;
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::ate);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(spBuf.span().data() == nullptr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ }
+
+ // Non-empty `span`
{
- // Empty `span`
- {
- // Mode: default
- {
- SpBuf rhsSpBuf;
- SpBuf spBuf(std::move(rhsSpBuf));
- assert(spBuf.span().data() == nullptr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
- // Mode: `ios_base::in`
- {
- SpBuf rhsSpBuf{std::ios_base::in};
- SpBuf spBuf(std::move(rhsSpBuf));
- assert(spBuf.span().data() == nullptr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
- // Mode: `ios_base::out`
- {
- SpBuf rhsSpBuf{std::ios_base::out};
- SpBuf spBuf(std::move(rhsSpBuf));
- assert(spBuf.span().data() == nullptr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
- // Mode: multiple
- {
- SpBuf rhsSpBuf{std::ios_base::out | std::ios_base::in};
- SpBuf spBuf(std::move(rhsSpBuf));
- assert(spBuf.span().data() == nullptr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
- }
-
- // Non-empty `span`
- {
- CharT arr[4];
+ CharT arr[4];
+
+ // Mode: default
+ {
std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `in`
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `out`
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: multiple
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `ate`
+ {
+ std::span<CharT> sp{arr};
+ TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::ate);
+ TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
+ assert(rhsSpBuf.span().data() == arr);
+ assert(spBuf.span().data() == arr);
+ spBuf.check_postconditions(rhsSpBuf);
+ }
+ }
+}
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+
+ // Empty `span`
+ {
+ // Mode: default (`in` | `out`)
+ {
+ SpBuf rhsSpBuf;
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
- // Mode: default
- {
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::move(rhsSpBuf));
- assert(spBuf.span().data() == arr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
- // Mode: `ios_base::in`
- {
- SpBuf rhsSpBuf{sp, std::ios_base::in};
- SpBuf spBuf(std::move(rhsSpBuf));
- assert(spBuf.span().data() == arr);
- assert(!spBuf.span().empty());
- assert(spBuf.span().size() == 4);
- }
- // Mode `ios_base::out`
- {
- SpBuf rhsSpBuf{sp, std::ios_base::out};
- SpBuf spBuf(std::move(rhsSpBuf));
- assert(spBuf.span().data() == arr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
- // Mode: multiple
- {
- SpBuf rhsSpBuf{sp, std::ios_base::out | std::ios_base::in | std::ios_base::binary};
- SpBuf spBuf(std::move(rhsSpBuf));
- assert(spBuf.span().data() == arr);
- assert(spBuf.span().empty());
- assert(spBuf.span().size() == 0);
- }
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `in`
+ {
+ SpBuf rhsSpBuf{std::ios_base::in};
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `out`
+ {
+ SpBuf rhsSpBuf{std::ios_base::out};
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{std::ios_base::out | std::ios_base::in | std::ios_base::binary};
+ assert(rhsSpBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `ate`
+ {
+ SpBuf rhsSpBuf{std::ios_base::ate};
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == nullptr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
}
}
- // Check post-conditions
+ // Non-empty `span`
{
- // Empty `span`
- {
- // Mode: default
- {
- std::span<CharT> sp;
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
- TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
- assert(rhsSpBuf.span().empty());
- assert(spBuf.span().data() == nullptr);
- spBuf.check_postconditions(rhsSpBuf);
- }
- // Mode: `ios_base::in`
- {
- std::span<CharT> sp;
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in);
- TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
- assert(rhsSpBuf.span().empty());
- assert(spBuf.span().data() == nullptr);
- spBuf.check_postconditions(rhsSpBuf);
- }
- // Mode: `ios_base::out`
- {
- std::span<CharT> sp;
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out);
- TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
- assert(rhsSpBuf.span().empty());
- assert(spBuf.span().data() == nullptr);
- spBuf.check_postconditions(rhsSpBuf);
- }
- // Mode: multiple
- {
- std::span<CharT> sp;
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
- assert(rhsSpBuf.span().empty());
- assert(spBuf.span().data() == nullptr);
- spBuf.check_postconditions(rhsSpBuf);
- }
- }
-
- // Non-empty `span`
- {
- CharT arr[4];
-
- // Mode: default
- {
- std::span<CharT> sp{arr};
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
- TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
- assert(rhsSpBuf.span().empty());
- assert(spBuf.span().data() == arr);
- spBuf.check_postconditions(rhsSpBuf);
- }
- // Mode: `ios_base::in`
- {
- std::span<CharT> sp{arr};
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in);
- TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
- assert(!rhsSpBuf.span().empty());
- assert(spBuf.span().data() == arr);
- spBuf.check_postconditions(rhsSpBuf);
- }
- // Mode: `ios_base::out`
- {
- std::span<CharT> sp{arr};
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out);
- TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
- assert(rhsSpBuf.span().empty());
- assert(spBuf.span().data() == arr);
- spBuf.check_postconditions(rhsSpBuf);
- }
- // Mode: multiple
- {
- std::span<CharT> sp{arr};
- TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
- TestSpanBuf<CharT, TraitsT> spBuf(std::move(static_cast<SpBuf&>(rhsSpBuf)));
- assert(rhsSpBuf.span().empty());
- assert(spBuf.span().data() == arr);
- spBuf.check_postconditions(rhsSpBuf);
- }
+ CharT arr[4];
+ std::span<CharT> sp{arr};
+
+ // Mode: default (`in` | `out`)
+ {
+ SpBuf rhsSpBuf{sp};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == arr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `in`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::in};
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
+
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ // Mode `out`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == arr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::out | std::ios_base::in | std::ios_base::binary};
+ assert(rhsSpBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ // After move
+ assert(rhsSpBuf.span().data() == arr);
+ assert(rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 0);
+ }
+ // Mode: `ate`
+ {
+ SpBuf rhsSpBuf{sp, std::ios_base::ate};
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
+
+ SpBuf spBuf(std::move(rhsSpBuf));
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+
+ // After move
+ assert(rhsSpBuf.span().data() == arr);
+ assert(!rhsSpBuf.span().empty());
+ assert(rhsSpBuf.span().size() == 4);
}
}
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test_postconditions<nasty_char, nasty_char_traits>();
+#endif
+ test_postconditions<char>();
+ test_postconditions<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test_postconditions<wchar_t>();
+ test_postconditions<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
index fbfc2f144ab6d3..dc6b6e9e5a83b6 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
@@ -50,20 +50,26 @@ template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
- static_assert(std::default_initializable<SpBuf>);
-
// Empty `span`
{
std::span<CharT> sp{};
- // Mode: default
+ // Mode: default (`in` | `out`)
{
SpBuf spBuf(sp);
assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
- // Mode: `ios_base::in`
+ {
+ SpBuf spBuf(std::as_const(sp));
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `in`
{
SpBuf spBuf(sp, std::ios_base::in);
assert(spBuf.span().data() == nullptr);
@@ -76,16 +82,18 @@ void test() {
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
- // Mode: `ios_base::out`
+ // Mode: `out`
{
SpBuf spBuf(sp, std::ios_base::out);
assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
{
SpBuf spBuf(std::as_const(sp), std::ios_base::out);
assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
@@ -93,12 +101,27 @@ void test() {
{
SpBuf spBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
{
SpBuf spBuf(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `ate`
+ {
+ SpBuf spBuf(sp, std::ios_base::out | std::ios_base::ate);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ {
+ SpBuf spBuf(std::as_const(sp), std::ios_base::out | std::ios_base::ate);
+ assert(spBuf.span().data() == nullptr);
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
@@ -109,14 +132,22 @@ void test() {
CharT arr[4];
std::span<CharT> sp{arr};
- // Mode: default
+ // Mode: default (`in` | `out`)
{
SpBuf spBuf(sp);
assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
- // Mode: `ios_base::in`
+ {
+ SpBuf spBuf(std::as_const(sp));
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `in`
{
SpBuf spBuf(sp, std::ios_base::in);
assert(spBuf.span().data() == arr);
@@ -129,16 +160,18 @@ void test() {
assert(!spBuf.span().empty());
assert(spBuf.span().size() == 4);
}
- // Mode `ios_base::out`
+ // Mode `out`
{
SpBuf spBuf(sp, std::ios_base::out);
assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
{
SpBuf spBuf(std::as_const(sp), std::ios_base::out);
assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
@@ -146,15 +179,30 @@ void test() {
{
SpBuf spBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
{
SpBuf spBuf(std::as_const(sp), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
+ // Mode: `ate`
+ {
+ SpBuf spBuf(sp, std::ios_base::out | std::ios_base::ate);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
+ {
+ SpBuf spBuf(std::as_const(sp), std::ios_base::out | std::ios_base::ate);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
}
}
@@ -164,6 +212,9 @@ int main(int, char**) {
#endif
test_sfinae<char>();
test_sfinae<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
index 635b8d2a030733..a13fbd10d051c9 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
@@ -68,6 +68,13 @@ void test() {
assert(spBuf.span().empty());
assert(spBuf.span().size() == 0);
}
+ // Mode: `ate`
+ {
+ SpBuf spBuf(sp, std::ios_base::out | std::ios_base::ate);
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+ }
}
int main(int, char**) {
>From 67ac93164e3a441648b40e1cf3fd217704be0cfc Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 11 Mar 2024 08:47:58 +0200
Subject: [PATCH 32/39] Tests: Added `setbuf.pass`
---
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 5 +-
.../seekoff.pos_type.open_mode.pass.cpp | 5 +-
.../spanbuf/spanbuf.virtuals/setbuf.pass.cpp | 76 ++++++++++++++++---
3 files changed, 75 insertions(+), 11 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
index 6b4580bedb89c2..2378a23dc8aefe 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -27,7 +27,7 @@
#include <spanstream>
#include "constexpr_char_traits.h"
-#include "test_convertible.h"
+#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
@@ -51,6 +51,9 @@ void test() {
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
index 0980143e674075..2558e2999dc09d 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
@@ -25,7 +25,7 @@
#include <spanstream>
#include "constexpr_char_traits.h"
-#include "test_convertible.h"
+#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
@@ -47,6 +47,9 @@ void test() {
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
index 193185da8d9ca3..2fd0e791e13e65 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
@@ -23,7 +23,7 @@
#include <spanstream>
#include "constexpr_char_traits.h"
-#include "test_convertible.h"
+#include "nasty_string.h"
#include "test_macros.h"
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
@@ -33,20 +33,78 @@ void test() {
CharT arr[4];
std::span<CharT> sp{arr};
- // TODO:
+ // Mode: default (`in` | `out`)
+ {
+ SpBuf spBuf{sp};
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
- // Mode: default
+ spBuf.pubsetbuf(nullptr, 0);
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `ios_base::in`
{
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
+ SpBuf spBuf{sp, std::ios_base::in};
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+
+ spBuf.pubsetbuf(nullptr, 0);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode `ios_base::out`
+ {
+ SpBuf spBuf{sp, std::ios_base::out};
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.pubsetbuf(nullptr, 0);
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: multiple
+ {
+ SpBuf spBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ assert(spBuf.span().data() == arr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+
+ spBuf.pubsetbuf(nullptr, 0);
+ assert(spBuf.span().data() == nullptr);
+ // Mode `out` counts read characters
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
+ }
+ // Mode: `ios_base::ate`
+ {
+ SpBuf spBuf{sp, std::ios_base::out | std::ios_base::ate};
+ assert(spBuf.span().data() == arr);
+ assert(!spBuf.span().empty());
+ assert(spBuf.span().size() == 4);
+
+ spBuf.pubsetbuf(nullptr, 0);
+ assert(spBuf.span().data() == nullptr);
+ assert(spBuf.span().empty());
+ assert(spBuf.span().size() == 0);
}
}
int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ test<nasty_char, nasty_char_traits>();
+#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
>From de5cc7c6badb5708f545459dc87b9e34c48bb598 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 11 Mar 2024 12:15:48 +0200
Subject: [PATCH 33/39] Tests: WIP `seekoff`
---
.../spanbuf/spanbuf.assign/move.pass.cpp | 4 +-
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 200 ++++++++++++++++--
2 files changed, 186 insertions(+), 18 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
index c1749a1068ea90..07306326b99e41 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
@@ -52,7 +52,7 @@ void test_postconditions() {
// Empty `span`
{
- // Mode: default
+ // Mode: default (`in` | `out`)
{
std::span<CharT> sp;
TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
@@ -103,7 +103,7 @@ void test_postconditions() {
{
CharT arr[4];
- // Mode: default
+ // Mode: default (`in` | `out`)
{
std::span<CharT> sp{arr};
TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
index 2378a23dc8aefe..b7e44293a5d69a 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -18,47 +18,215 @@
//
// pos_type seekoff(off_type off, ios_base::seekdir way,
// ios_base::openmode which = ios_base::in | ios_base::out) override;
-// pos_type seekpos(pos_type sp,
-// ios_base::openmode which = ios_base::in | ios_base::out) override;
+#include <algorithm>
#include <cassert>
#include <concepts>
#include <span>
#include <spanstream>
+// #include <string>
#include "constexpr_char_traits.h"
#include "nasty_string.h"
#include "test_macros.h"
+// #include "../../helper_macros.h"
+#include <print>
+
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
- using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+ using SpBuffError = typename SpBuf::pos_type;
- CharT arr[4];
- std::span<CharT> sp{arr};
+ const SpBuffError error{-1};
- // TODO:
+ // Empty `span`
+ {
+ std::span<CharT> sp;
+
+ // Mode: default (`in` | `out`)
+ {
+ SpBuf spBuf{sp};
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
+ }
+ // Mode: `in`
+ {
+ SpBuf spBuf{sp, std::ios_base::in};
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
+ }
+ // Mode: `out`
+ {
+ SpBuf spBuf{sp, std::ios_base::out};
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
+ }
+ // Mode: `multiple`
+ {
+ SpBuf spBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
+ }
+ // Mode: `ate`
+ {
+ SpBuf spBuf{sp, std::ios_base::out | std::ios_base::ate};
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
+ }
+ }
- // Mode: default
+ // Non-empty `span`
{
- SpBuf rhsSpBuf{sp};
- SpBuf spBuf(std::span<CharT>{});
- spBuf.swap(rhsSpBuf);
- // assert(spBuf.span().data() == arr);
- // assert(!spBuf.span().empty());
- // assert(spBuf.span().size() == 4);
+ // const CharT* cStr = CS("0123456789");
+ // const std::basic_string_view<CharT, TraitsT> sv{SV("0123456789")};
+ // std::span sp{sv.begin(), sv.end()};
+
+ // std::print(stderr, "-=----- {}", sp);
+
+ // Initialize with ASCII codes: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+ CharT arr[]{
+ CharT{48}, CharT{49}, CharT{50}, CharT{51}, CharT{52}, CharT{53}, CharT{54}, CharT{55}, CharT{56}, CharT{57}};
+ std::span sp{arr};
+ // std::print(stderr, "-=----- {}", sp);
+ // assert(false);
+
+ // Mode: default (`in` | `out`)
+ {
+ // TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
+ // TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ // assert(rhsSpBuf.span().data() == arr);
+ // assert(spBuf.span().data() == arr);
+ // spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `in`
+ {
+ SpBuf spBuf(sp, std::ios_base::in);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == 3);
+ // assert(spBuf.sgetc() == '3');
+ assert(spBuf.sgetc() == 51);
+ // std::print(stderr, CS("-=-=======> {}"), spBuf.sgetc());
+ std::println(stderr, "-------- {}", spBuf.sgetc());
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == 6);
+ assert(spBuf.sgetc() == 54);
+ // std::print(stderr, CS("-=-=======> {}"), spBuf.sgetc());
+ std::println(stderr, "-------- {}", spBuf.sgetc());
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == 7);
+ assert(spBuf.sgetc() == 55);
+ // std::print(stderr, CS("-=-=======> {}"), spBuf.sgetc());
+ std::println(stderr, "-------- {}", spBuf.sgetc());
+ // assert(false);
+ }
+ // Mode: `out`
+ {
+ CharT resultArr[]{
+ CharT{48}, CharT{49}, CharT{50}, CharT{51}, CharT{52}, CharT{53}, CharT{54}, CharT{55}, CharT{56}, CharT{57}};
+
+ SpBuf spBuf(sp, std::ios_base::out);
+ std::println(stderr, "fasdfasdfasdfasdfasd 0 {}", spBuf.span());
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out | std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out | std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out | std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == 3);
+ assert(spBuf.sputc(CharT{90}) == 90);
+ // assert(spBuf.str() == "012a456789");
+ resultArr[3] = CharT{90};
+ // assert(spBuf.span() == std::span<CharT>{resultArr});
+ std::println(stderr, "fasdfasdfasdfasdfasd 1 {}", spBuf.span());
+ std::println(stderr, "fasdfasdfasdfasdfasd {}", spBuf.span().data());
+ std::println(stderr, "fasdfasdfasdfasdfasd {}", spBuf.span().size());
+ std::println(stderr, "fasdfasdfasdfasdfasd 2 {}", std::span<CharT>{resultArr});
+ // assert(std::ranges::equal(spBuf.span(), std::span<CharT>{resultArr}));
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == 7);
+ assert(spBuf.sputc(CharT{77}) == 77);
+ std::println(stderr, "fasdfasdfasdfasdfasd 5 {}", spBuf.span());
+ // assert(spBuf.str() == "012a456b89");
+ resultArr[7] = CharT{77};
+ // assert(spBuf.span() == std::span<CharT>{resultArr});
+ // assert(std::ranges::equal(spBuf.span(), std::span<CharT>{resultArr}));
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 7);
+ std::println(stderr, "fasdfasdfasdfasdfasd 6 {}", spBuf.span());
+#if 0
+ assert(spBuf.sputc(CharT{84}) == 84);
+ // assert(spBuf.str() == "012a456c89");
+ resultArr[6] = CharT{84};
+ assert(spBuf.span() == std::span<CharT>{resultArr});
+#endif
+ }
+ // Mode: multiple
+ {
+ // std::span<CharT> sp{arr};
+ // TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ // TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ // assert(rhsSpBuf.span().data() == arr);
+ // assert(spBuf.span().data() == arr);
+ // spBuf.check_postconditions(rhsSpBuf);
+ }
+ // Mode: `ate`
+ {
+ // std::span<CharT> sp{arr};
+ // TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::ate);
+ // TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
+ // assert(rhsSpBuf.span().data() == arr);
+ // assert(spBuf.span().data() == arr);
+ // spBuf.check_postconditions(rhsSpBuf);
+ }
}
}
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
- test<nasty_char, nasty_char_traits>();
+ // test<nasty_char, nasty_char_traits>();
#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test<wchar_t>();
- test<wchar_t, constexpr_char_traits<wchar_t>>();
+ // test<wchar_t>();
+ // test<wchar_t, constexpr_char_traits<wchar_t>>();
#endif
return 0;
>From b3b531ff1a68f8d4951b7c348c1dd9348c0004b9 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 11 Mar 2024 15:13:37 +0200
Subject: [PATCH 34/39] Tests: WIP cleanup
---
.../spanbuf/spanbuf.assign/move.pass.cpp | 1 -
.../spanbuf/spanbuf.assign/swap.pass.cpp | 1 -
.../spanbuf.assign/swap_nonmember.pass.cpp | 1 -
.../spanbuf/spanbuf.cons/move.pass.cpp | 1 -
.../spanbuf/spanbuf.cons/span.mode.pass.cpp | 1 -
.../spanbuf/spanbuf.members/span.pass.cpp | 1 -
.../spanbuf.members/span.span.pass.cpp | 1 -
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 32 ++++++-------------
.../seekoff.pos_type.open_mode.pass.cpp | 1 -
.../spanbuf/spanbuf.virtuals/setbuf.pass.cpp | 1 -
10 files changed, 9 insertions(+), 32 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
index 07306326b99e41..88179fece5908c 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/move.pass.cpp
@@ -19,7 +19,6 @@
// basic_spanbuf& operator=(basic_spanbuf&& rhs);
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
index 6db44e92be58d3..26b305333e42ec 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap.pass.cpp
@@ -18,7 +18,6 @@
// void swap(basic_spanbuf& rhs);
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
index 78c50156740199..681f157553326b 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.assign/swap_nonmember.pass.cpp
@@ -14,7 +14,6 @@
// void swap(basic_spanbuf<charT, traits>& x, basic_spanbuf<charT, traits>& y);
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
index 9252f64908de46..e9e483d290c55d 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/move.pass.cpp
@@ -19,7 +19,6 @@
// basic_spanbuf(basic_spanbuf&& rhs);
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
index dc6b6e9e5a83b6..9557b096f8f913 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.cons/span.mode.pass.cpp
@@ -20,7 +20,6 @@
// ios_base::openmode which = ios_base::in | ios_base::out);
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
#include <utility>
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
index a13fbd10d051c9..d868676c188868 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.pass.cpp
@@ -18,7 +18,6 @@
// std::span<charT> span() const noexcept;
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
index 5495cdefbe7c68..e3c836d27e3494 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.members/span.span.pass.cpp
@@ -19,7 +19,6 @@
// void span(std::span<charT> s) noexcept;
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
index b7e44293a5d69a..2d378127e5fa44 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -21,16 +21,13 @@
#include <algorithm>
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
-// #include <string>
#include "constexpr_char_traits.h"
#include "nasty_string.h"
#include "test_macros.h"
-// #include "../../helper_macros.h"
#include <print>
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
@@ -113,12 +110,6 @@ void test() {
// Non-empty `span`
{
- // const CharT* cStr = CS("0123456789");
- // const std::basic_string_view<CharT, TraitsT> sv{SV("0123456789")};
- // std::span sp{sv.begin(), sv.end()};
-
- // std::print(stderr, "-=----- {}", sp);
-
// Initialize with ASCII codes: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
CharT arr[]{
CharT{48}, CharT{49}, CharT{50}, CharT{51}, CharT{52}, CharT{53}, CharT{54}, CharT{55}, CharT{56}, CharT{57}};
@@ -144,19 +135,11 @@ void test() {
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == 3);
- // assert(spBuf.sgetc() == '3');
assert(spBuf.sgetc() == 51);
- // std::print(stderr, CS("-=-=======> {}"), spBuf.sgetc());
- std::println(stderr, "-------- {}", spBuf.sgetc());
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == 6);
assert(spBuf.sgetc() == 54);
- // std::print(stderr, CS("-=-=======> {}"), spBuf.sgetc());
- std::println(stderr, "-------- {}", spBuf.sgetc());
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == 7);
assert(spBuf.sgetc() == 55);
- // std::print(stderr, CS("-=-=======> {}"), spBuf.sgetc());
- std::println(stderr, "-------- {}", spBuf.sgetc());
- // assert(false);
}
// Mode: `out`
{
@@ -164,7 +147,7 @@ void test() {
CharT{48}, CharT{49}, CharT{50}, CharT{51}, CharT{52}, CharT{53}, CharT{54}, CharT{55}, CharT{56}, CharT{57}};
SpBuf spBuf(sp, std::ios_base::out);
- std::println(stderr, "fasdfasdfasdfasdfasd 0 {}", spBuf.span());
+ // std::println(stderr, "fasdfasdfasdfasdfasd 0 {}", spBuf.span());
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
@@ -172,6 +155,7 @@ void test() {
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out | std::ios_base::in) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out | std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == 3);
+ // #if 0
assert(spBuf.sputc(CharT{90}) == 90);
// assert(spBuf.str() == "012a456789");
resultArr[3] = CharT{90};
@@ -181,21 +165,23 @@ void test() {
std::println(stderr, "fasdfasdfasdfasdfasd {}", spBuf.span().size());
std::println(stderr, "fasdfasdfasdfasdfasd 2 {}", std::span<CharT>{resultArr});
// assert(std::ranges::equal(spBuf.span(), std::span<CharT>{resultArr}));
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == 7);
+ // assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == 7);
assert(spBuf.sputc(CharT{77}) == 77);
- std::println(stderr, "fasdfasdfasdfasdfasd 5 {}", spBuf.span());
+ std::println(stderr,"fasdfasdfasdfasdfasd 5 {}", spBuf.span());
// assert(spBuf.str() == "012a456b89");
resultArr[7] = CharT{77};
// assert(spBuf.span() == std::span<CharT>{resultArr});
// assert(std::ranges::equal(spBuf.span(), std::span<CharT>{resultArr}));
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 7);
- std::println(stderr, "fasdfasdfasdfasdfasd 6 {}", spBuf.span());
-#if 0
+ // std::println(stderr, "ljjklj {}", static_cast<int>(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out)));
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 2);
+ std::println(stderr, "fasdfasdfasdfasdfasd 6 {}", spBuf.span());
assert(spBuf.sputc(CharT{84}) == 84);
+#if 0
// assert(spBuf.str() == "012a456c89");
resultArr[6] = CharT{84};
assert(spBuf.span() == std::span<CharT>{resultArr});
#endif
+ assert(false);
}
// Mode: multiple
{
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
index 2558e2999dc09d..78fda499086010 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.pos_type.open_mode.pass.cpp
@@ -20,7 +20,6 @@
// ios_base::openmode which = ios_base::in | ios_base::out) override;
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
index 2fd0e791e13e65..b0d64710979989 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/setbuf.pass.cpp
@@ -18,7 +18,6 @@
// basic_streambuf<charT, traits>* setbuf(charT*, streamsize) override;
#include <cassert>
-#include <concepts>
#include <span>
#include <spanstream>
>From bb8b6f40c5974bcc88d29f51bac824ce43e5f358 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 12 Mar 2024 14:34:48 +0200
Subject: [PATCH 35/39] Tests: WIP `seekoff`
---
libcxx/include/spanstream | 3 +-
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 231 ++++---
.../temp_test/temp_test.pass.cpp | 575 ++++++++++++++++++
3 files changed, 723 insertions(+), 86 deletions(-)
create mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index 63b61d1dee26d0..68d65db9d0afe3 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -113,7 +113,6 @@ public:
: basic_streambuf<_CharT, _Traits>{std::move(__rhs)},
__mode_{std::move(__rhs.__mode_)},
__buf_{std::move(__rhs.__buf_)} {}
- // __buf_{std::exchange(__rhs.__buf_, {})} {}
// [spanbuf.assign], assignment and swap
@@ -187,7 +186,7 @@ protected:
break;
case ios_base::end:
- if ((__which & ios_base::out) && !(__which & ios_base::in))
+ if ((__mode_ & ios_base::out) && !(__mode_ & ios_base::in))
__baseoff = this->pptr() - this->pbase();
else
__baseoff = __buf_.size();
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
index 2d378127e5fa44..3dac603ca1fbe9 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -28,14 +28,11 @@
#include "nasty_string.h"
#include "test_macros.h"
-#include <print>
+#include <iostream>
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
- using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
- using SpBuffError = typename SpBuf::pos_type;
-
- const SpBuffError error{-1};
+ using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
// Empty `span`
{
@@ -44,149 +41,215 @@ void test() {
// Mode: default (`in` | `out`)
{
SpBuf spBuf{sp};
+
+ // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
+
+ // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
}
// Mode: `in`
{
SpBuf spBuf{sp, std::ios_base::in};
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+
+ // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
+
+ // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
}
// Mode: `out`
{
SpBuf spBuf{sp, std::ios_base::out};
+
+ // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
+
+ // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
}
// Mode: `multiple`
{
SpBuf spBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+
+ // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
+
+ // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
}
// Mode: `ate`
{
SpBuf spBuf{sp, std::ios_base::out | std::ios_base::ate};
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+
+ // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
+
+ // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
}
}
// Non-empty `span`
{
- // Initialize with ASCII codes: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
- CharT arr[]{
- CharT{48}, CharT{49}, CharT{50}, CharT{51}, CharT{52}, CharT{53}, CharT{54}, CharT{55}, CharT{56}, CharT{57}};
+ CharT arr[10];
std::span sp{arr};
- // std::print(stderr, "-=----- {}", sp);
- // assert(false);
// Mode: default (`in` | `out`)
{
- // TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp);
- // TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
- // assert(rhsSpBuf.span().data() == arr);
- // assert(spBuf.span().data() == arr);
- // spBuf.check_postconditions(rhsSpBuf);
+ SpBuf spBuf{sp};
+
+ // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+
+ std::cerr << spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) << std::endl;
+ // assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == 3);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == 6);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 3);
+
+ // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
}
// Mode: `in`
{
- SpBuf spBuf(sp, std::ios_base::in);
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in | std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in | std::ios_base::out) == -1);
+ SpBuf spBuf{sp, std::ios_base::in};
+
+ // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == 3);
- assert(spBuf.sgetc() == 51);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == 6);
- assert(spBuf.sgetc() == 54);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == 7);
- assert(spBuf.sgetc() == 55);
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
+
+ // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
}
// Mode: `out`
{
- CharT resultArr[]{
- CharT{48}, CharT{49}, CharT{50}, CharT{51}, CharT{52}, CharT{53}, CharT{54}, CharT{55}, CharT{56}, CharT{57}};
+ SpBuf spBuf{sp, std::ios_base::out};
+
+ // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
- SpBuf spBuf(sp, std::ios_base::out);
- // std::println(stderr, "fasdfasdfasdfasdfasd 0 {}", spBuf.span());
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out | std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out | std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out | std::ios_base::in) == -1);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == 3);
- // #if 0
- assert(spBuf.sputc(CharT{90}) == 90);
- // assert(spBuf.str() == "012a456789");
- resultArr[3] = CharT{90};
- // assert(spBuf.span() == std::span<CharT>{resultArr});
- std::println(stderr, "fasdfasdfasdfasdfasd 1 {}", spBuf.span());
- std::println(stderr, "fasdfasdfasdfasdfasd {}", spBuf.span().data());
- std::println(stderr, "fasdfasdfasdfasdfasd {}", spBuf.span().size());
- std::println(stderr, "fasdfasdfasdfasdfasd 2 {}", std::span<CharT>{resultArr});
- // assert(std::ranges::equal(spBuf.span(), std::span<CharT>{resultArr}));
- // assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == 7);
- assert(spBuf.sputc(CharT{77}) == 77);
- std::println(stderr,"fasdfasdfasdfasdfasd 5 {}", spBuf.span());
- // assert(spBuf.str() == "012a456b89");
- resultArr[7] = CharT{77};
- // assert(spBuf.span() == std::span<CharT>{resultArr});
- // assert(std::ranges::equal(spBuf.span(), std::span<CharT>{resultArr}));
- // std::println(stderr, "ljjklj {}", static_cast<int>(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out)));
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 2);
- std::println(stderr, "fasdfasdfasdfasdfasd 6 {}", spBuf.span());
- assert(spBuf.sputc(CharT{84}) == 84);
-#if 0
- // assert(spBuf.str() == "012a456c89");
- resultArr[6] = CharT{84};
- assert(spBuf.span() == std::span<CharT>{resultArr});
-#endif
- assert(false);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == 6);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 3);
+
+ // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
}
// Mode: multiple
{
// std::span<CharT> sp{arr};
- // TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary);
+ // TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp | std::ios_base::binary);
// TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
// assert(rhsSpBuf.span().data() == arr);
// assert(spBuf.span().data() == arr);
@@ -206,13 +269,13 @@ void test() {
int main(int, char**) {
#ifndef TEST_HAS_NO_NASTY_STRING
- // test<nasty_char, nasty_char_traits>();
+ test<nasty_char, nasty_char_traits>();
#endif
test<char>();
test<char, constexpr_char_traits<char>>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- // test<wchar_t>();
- // test<wchar_t, constexpr_char_traits<wchar_t>>();
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
#endif
return 0;
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp
new file mode 100644
index 00000000000000..33c75ba9b1fa8d
--- /dev/null
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp
@@ -0,0 +1,575 @@
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <ios>
+#include <limits>
+#include <span>
+#include <spanstream>
+#include <string_view>
+#include <type_traits>
+#include <utility>
+
+#include <algorithm>
+#include <cassert>
+#include <span>
+#include <spanstream>
+
+#include "constexpr_char_traits.h"
+#include "nasty_string.h"
+#include "test_macros.h"
+
+#include <iostream>
+
+using namespace std;
+
+template <class Spanbuf>
+class basic_test_buf : public Spanbuf {
+public:
+ using Spanbuf::Spanbuf;
+
+ using Spanbuf::eback;
+ using Spanbuf::egptr;
+ using Spanbuf::epptr;
+ using Spanbuf::gptr;
+ using Spanbuf::pbase;
+ using Spanbuf::pptr;
+
+ using Spanbuf::setp;
+
+ using Spanbuf::seekoff;
+ using Spanbuf::seekpos;
+ using Spanbuf::setbuf;
+};
+
+template <typename CharT, typename TraitsT = std::char_traits<CharT>>
+void test() {
+ using test_buf = basic_test_buf<basic_spanbuf<CharT>>;
+ { // construction
+ CharT buffer[10];
+ const test_buf default_constructed{};
+ assert(default_constructed.span().data() == nullptr);
+ assert(default_constructed.eback() == nullptr);
+ assert(default_constructed.gptr() == nullptr);
+ assert(default_constructed.egptr() == nullptr);
+ assert(default_constructed.pbase() == nullptr);
+ assert(default_constructed.pptr() == nullptr);
+ assert(default_constructed.epptr() == nullptr);
+
+ const test_buf mode_constructed{ios_base::in};
+ assert(mode_constructed.span().data() == nullptr);
+ assert(mode_constructed.eback() == nullptr);
+ assert(mode_constructed.gptr() == nullptr);
+ assert(mode_constructed.egptr() == nullptr);
+ assert(mode_constructed.pbase() == nullptr);
+ assert(mode_constructed.pptr() == nullptr);
+ assert(mode_constructed.epptr() == nullptr);
+
+ test_buf span_constructed{span<CharT>{buffer}};
+ assert(span_constructed.span().data() == buffer);
+ assert(span_constructed.eback() == buffer);
+ assert(span_constructed.gptr() == buffer);
+ // assert(span_constructed.egptr() == std::end(buffer));
+ assert(span_constructed.pbase() == buffer);
+ assert(span_constructed.pptr() == buffer);
+ // assert(span_constructed.epptr() == std::end(buffer));
+
+ const test_buf span_mode_in_constructed{span<CharT>{buffer}, ios_base::in};
+ assert(span_mode_in_constructed.span().data() == buffer);
+ assert(span_mode_in_constructed.eback() == buffer);
+ assert(span_mode_in_constructed.gptr() == buffer);
+ // assert(span_mode_in_constructed.egptr() == std::end(buffer));
+ assert(span_mode_in_constructed.pbase() == nullptr);
+ assert(span_mode_in_constructed.pptr() == nullptr);
+ assert(span_mode_in_constructed.epptr() == nullptr);
+
+ const test_buf span_mode_in_ate_constructed{span<CharT>{buffer}, ios_base::in | ios_base::ate};
+ assert(span_mode_in_ate_constructed.span().data() == buffer);
+ assert(span_mode_in_ate_constructed.eback() == buffer);
+ assert(span_mode_in_ate_constructed.gptr() == buffer);
+ // assert(span_mode_in_ate_constructed.egptr() == std::end(buffer));
+ assert(span_mode_in_ate_constructed.pbase() == nullptr);
+ assert(span_mode_in_ate_constructed.pptr() == nullptr);
+ assert(span_mode_in_ate_constructed.epptr() == nullptr);
+
+ const test_buf span_mode_out_constructed{span<CharT>{buffer}, ios_base::out};
+ assert(span_mode_out_constructed.span().data() == buffer);
+ assert(span_mode_out_constructed.eback() == nullptr);
+ assert(span_mode_out_constructed.gptr() == nullptr);
+ assert(span_mode_out_constructed.egptr() == nullptr);
+ assert(span_mode_out_constructed.pbase() == buffer);
+ assert(span_mode_out_constructed.pptr() == buffer);
+ assert(span_mode_out_constructed.epptr() == std::end(buffer));
+
+ const test_buf span_mode_out_ate_constructed{span<CharT>{buffer}, ios_base::out | ios_base::ate};
+ assert(span_mode_out_ate_constructed.span().data() == buffer);
+ assert(span_mode_out_ate_constructed.eback() == nullptr);
+ assert(span_mode_out_ate_constructed.gptr() == nullptr);
+ assert(span_mode_out_ate_constructed.egptr() == nullptr);
+ assert(span_mode_out_ate_constructed.pbase() == buffer);
+ // assert(span_mode_out_ate_constructed.pptr() == std::end(buffer));
+ // assert(span_mode_out_ate_constructed.epptr() == std::end(buffer));
+
+ const test_buf span_mode_unknown_constructed{span<CharT>{buffer}, 0};
+ assert(span_mode_unknown_constructed.span().data() == buffer);
+ assert(span_mode_unknown_constructed.eback() == nullptr);
+ assert(span_mode_unknown_constructed.gptr() == nullptr);
+ assert(span_mode_unknown_constructed.egptr() == nullptr);
+ assert(span_mode_unknown_constructed.pbase() == nullptr);
+ assert(span_mode_unknown_constructed.pptr() == nullptr);
+ assert(span_mode_unknown_constructed.epptr() == nullptr);
+#if 0
+ test_buf move_constructed{std::move(span_constructed)};
+ assert(move_constructed.span().data() == buffer);
+ assert(move_constructed.eback() == buffer);
+ assert(move_constructed.gptr() == buffer);
+ // assert(move_constructed.egptr() == std::end(buffer));
+ assert(move_constructed.pbase() == buffer);
+ assert(move_constructed.pptr() == buffer);
+ // assert(move_constructed.epptr() == std::end(buffer));
+ assert(span_constructed.span().data() == nullptr);
+ assert(span_constructed.eback() == nullptr);
+ assert(span_constructed.gptr() == nullptr);
+ assert(span_constructed.egptr() == nullptr);
+ assert(span_constructed.pbase() == nullptr);
+ assert(span_constructed.pptr() == nullptr);
+ assert(span_constructed.epptr() == nullptr);
+
+ test_buf move_assigned;
+ move_assigned = std::move(move_constructed);
+ assert(move_assigned.span().data() == buffer);
+ assert(move_assigned.eback() == buffer);
+ assert(move_assigned.gptr() == buffer);
+ // assert(move_assigned.egptr() == std::end(buffer));
+ assert(move_assigned.pbase() == buffer);
+ assert(move_assigned.pptr() == buffer);
+ // assert(move_assigned.epptr() == std::end(buffer));
+ assert(move_constructed.span().data() == nullptr);
+ assert(move_constructed.eback() == nullptr);
+ assert(move_constructed.gptr() == nullptr);
+ assert(move_constructed.egptr() == nullptr);
+ assert(move_constructed.pbase() == nullptr);
+ assert(move_constructed.pptr() == nullptr);
+ assert(move_constructed.epptr() == nullptr);
+#endif
+ }
+
+ // { // swap
+ // CharT buffer1[10];
+ // CharT buffer2[20];
+ // test_buf first{span<CharT>{buffer1}};
+ // test_buf second{span<CharT>{buffer2}};
+ // assert(first.span().data() == buffer1);
+ // assert(second.span().data() == buffer2);
+
+ // first.swap(second);
+ // assert(first.span().data() == buffer2);
+ // assert(second.span().data() == buffer1);
+
+ // swap(first, second);
+ // assert(first.span().data() == buffer1);
+ // assert(second.span().data() == buffer2);
+ // }
+
+ // { // span, span, span, span
+ // CharT buffer1[10];
+ // test_buf input_buffer{span<CharT>{buffer1}, ios_base::in};
+ // assert(input_buffer.span().data() == buffer1);
+ // assert(input_buffer.span().size() == std::size(buffer1));
+
+ // test_buf output_buffer{span<CharT>{buffer1}, ios_base::out};
+ // assert(output_buffer.span().data() == buffer1);
+ // assert(output_buffer.span().size() == 0); // counts the written characters
+
+ // // Manually move the written pointer
+ // output_buffer.setp(buffer1, buffer1 + 5, std::end(buffer1));
+ // assert(output_buffer.span().data() == buffer1);
+ // assert(output_buffer.span().size() == 5);
+
+ // CharT buffer2[10];
+ // input_buffer.span(span<CharT>{buffer2});
+ // assert(input_buffer.span().data() == buffer2);
+ // assert(input_buffer.span().size() == std::size(buffer2));
+
+ // output_buffer.span(span<CharT>{buffer2});
+ // assert(output_buffer.span().data() == buffer2);
+ // assert(output_buffer.span().size() == 0);
+
+ // test_buf hungry_buffer{span<CharT>{buffer1}, ios_base::out | ios_base::ate};
+ // assert(hungry_buffer.span().data() == buffer1);
+ // assert(hungry_buffer.span().size() == std::size(buffer1));
+
+ // hungry_buffer.span(span<CharT>{buffer2});
+ // assert(hungry_buffer.span().data() == buffer2);
+ // assert(hungry_buffer.span().size() == std::size(buffer2));
+ // }
+
+ { // seekoff ios_base::beg
+ CharT buffer[10];
+ test_buf input_buffer{span<CharT>{buffer}, ios_base::in};
+ test_buf output_buffer{span<CharT>{buffer}, ios_base::out};
+
+ auto result = input_buffer.seekoff(0, ios_base::beg, ios_base::in);
+ assert(result == 0);
+
+ // pptr not set but off is 0
+ result = input_buffer.seekoff(0, ios_base::beg, ios_base::out);
+ assert(result == 0);
+
+ // pptr not set and off != 0 -> fail
+ result = input_buffer.seekoff(1, ios_base::beg, ios_base::out);
+ assert(result == -1);
+
+ // gptr not set but off is 0
+ result = output_buffer.seekoff(0, ios_base::beg, ios_base::in);
+ assert(result == 0);
+
+ // gptr not set and off != 0 -> fail
+ result = output_buffer.seekoff(1, ios_base::beg, ios_base::in);
+ assert(result == -1);
+
+ // negative off -> fail
+ result = input_buffer.seekoff(-1, ios_base::beg, ios_base::in);
+ assert(result == -1);
+
+ // negative off -> fail
+ result = output_buffer.seekoff(-1, ios_base::beg, ios_base::out);
+ assert(result == -1);
+
+ // off larger than buf -> fail
+ result = input_buffer.seekoff(20, ios_base::beg, ios_base::in);
+ assert(result == -1);
+
+ // off larger than buf -> fail
+ result = output_buffer.seekoff(20, ios_base::beg, ios_base::out);
+ assert(result == -1);
+
+ // passes
+ result = input_buffer.seekoff(5, ios_base::beg, ios_base::in);
+ assert(result == 5);
+
+ result = output_buffer.seekoff(5, ios_base::beg, ios_base::out);
+ assert(result == 5);
+
+ // always from front
+ result = input_buffer.seekoff(7, ios_base::beg, ios_base::in);
+ assert(result == 7);
+
+ result = output_buffer.seekoff(7, ios_base::beg, ios_base::out);
+ assert(result == 7);
+ }
+
+ { // seekoff ios_base::end
+ CharT buffer[10];
+ test_buf input_buffer{span<CharT>{buffer}, ios_base::in};
+ // all fine we move to end of stream
+ auto result = input_buffer.seekoff(0, ios_base::end, ios_base::in);
+ assert(result == 10);
+
+ // pptr not set but off is == 0
+ result = input_buffer.seekoff(-10, ios_base::end, ios_base::out);
+ std::cerr << result << std::endl;
+ assert(result == 0);
+
+ // pptr not set and off != 0 -> fail
+ result = input_buffer.seekoff(0, ios_base::end, ios_base::out);
+ std::cerr << result << std::endl;
+ assert(result == -1);
+
+ // negative off -> fail
+ result = input_buffer.seekoff(-20, ios_base::end, ios_base::in);
+ assert(result == -1);
+
+ // off beyond end of buffer -> fail
+ result = input_buffer.seekoff(1, ios_base::end, ios_base::in);
+ assert(result == -1);
+
+ // passes and moves to buffer size - off
+ result = input_buffer.seekoff(-5, ios_base::end, ios_base::in);
+ assert(result == 5);
+
+ // always from front
+ result = input_buffer.seekoff(-7, ios_base::end, ios_base::in);
+ assert(result == 3);
+
+ // integer overflow due to large off
+ result = input_buffer.seekoff(numeric_limits<long long>::max(), ios_base::end, ios_base::in);
+ assert(result == -1);
+
+ test_buf output_buffer{span<CharT>{buffer}, ios_base::out};
+ // gptr not set but off is 0
+ result = output_buffer.seekoff(0, ios_base::end, ios_base::in);
+ assert(result == 0);
+
+ // newoff is negative -> fail
+ result = output_buffer.seekoff(-10, ios_base::end, ios_base::out);
+ assert(result == -1);
+
+ // pptr not set but off == 0
+ result = output_buffer.seekoff(0, ios_base::end, ios_base::out);
+ assert(result == 0);
+
+ // all fine we stay at end of stream
+ result = output_buffer.seekoff(0, ios_base::end, ios_base::in);
+ assert(result == 0);
+
+ // gptr not set and off != 0 -> fail
+ result = output_buffer.seekoff(1, ios_base::end, ios_base::in);
+ assert(result == -1);
+
+ // off + buffer size is negative -> fail
+ result = output_buffer.seekoff(-20, ios_base::end, ios_base::out);
+ assert(result == -1);
+
+ // off larger than buffer -> fail
+ result = output_buffer.seekoff(11, ios_base::end, ios_base::out);
+ assert(result == -1);
+
+ // passes and moves to buffer size - off
+ result = output_buffer.seekoff(5, ios_base::end, ios_base::out);
+ assert(result == 5);
+
+ // passes we are still below buffer size
+ result = output_buffer.seekoff(3, ios_base::end, ios_base::out);
+ assert(result == 8);
+
+ // moves beyond buffer size -> fails
+ result = output_buffer.seekoff(3, ios_base::end, ios_base::out);
+ assert(result == -1);
+
+ // integer overflow due to large off
+ result = output_buffer.seekoff(numeric_limits<long long>::max(), ios_base::end, ios_base::in);
+ assert(result == -1);
+
+ test_buf inout_buffer{span<CharT>{buffer}, ios_base::in | ios_base::out};
+ // all fine we move to end of stream
+ result = inout_buffer.seekoff(0, ios_base::end, ios_base::in);
+ assert(result == 10);
+
+ // we move to front of the buffer
+ result = inout_buffer.seekoff(-10, ios_base::end, ios_base::out);
+ assert(result == 0);
+
+ // we move to end of buffer
+ result = inout_buffer.seekoff(0, ios_base::end, ios_base::out);
+ assert(result == 10);
+
+ // negative off -> fail
+ result = inout_buffer.seekoff(-20, ios_base::end, ios_base::in);
+ assert(result == -1);
+
+ // off beyond end of buffer -> fail
+ result = inout_buffer.seekoff(1, ios_base::end, ios_base::in);
+ assert(result == -1);
+
+ // passes and moves to buffer size - off
+ result = inout_buffer.seekoff(-5, ios_base::end, ios_base::in);
+ assert(result == 5);
+
+ // always from front
+ result = inout_buffer.seekoff(-7, ios_base::end, ios_base::in);
+ assert(result == 3);
+
+ // integer overflow due to large off
+ result = inout_buffer.seekoff(numeric_limits<long long>::max(), ios_base::end, ios_base::in);
+ assert(result == -1);
+ }
+
+ { // seekoff ios_base::cur
+ CharT buffer[10];
+ test_buf input_buffer{span<CharT>{buffer}, ios_base::in};
+
+ // no mode set -> fail
+ auto result = input_buffer.seekoff(0, ios_base::cur, 0);
+ std::cerr << result << std::endl;
+ assert(result == -1);
+
+ // both in and out modes set -> fail
+ result = input_buffer.seekoff(0, ios_base::cur, ios_base::in | ios_base::out);
+ assert(result == -1);
+
+ // pptr not set and off is != 0 -> fail
+ result = input_buffer.seekoff(1, ios_base::cur, ios_base::out);
+ assert(result == -1);
+
+ // off larger than buffer size -> fail
+ result = input_buffer.seekoff(20, ios_base::cur, ios_base::out);
+ assert(result == -1);
+
+ // off negative -> fail
+ result = input_buffer.seekoff(-1, ios_base::cur, ios_base::out);
+ assert(result == -1);
+
+ // pptr not set but off is == 0
+ result = input_buffer.seekoff(0, ios_base::cur, ios_base::out);
+ assert(result == 0);
+
+ // passes and sets position
+ result = input_buffer.seekoff(3, ios_base::cur, ios_base::in);
+ assert(result == 3);
+
+ // negative off moves back
+ result = input_buffer.seekoff(-2, ios_base::cur, ios_base::in);
+ assert(result == 1);
+
+ // off + current position is beyond buffer size -> fail
+ result = input_buffer.seekoff(10, ios_base::cur, ios_base::in);
+ assert(result == -1);
+
+ test_buf output_buffer{span<CharT>{buffer}, ios_base::out};
+ // no mode set -> fail
+ result = output_buffer.seekoff(0, ios_base::cur, 0);
+ std::cerr << result << std::endl;
+ // assert(result == -1);
+
+ // both in and out modes set -> fail
+ result = output_buffer.seekoff(0, ios_base::cur, ios_base::in | ios_base::out);
+ assert(result == -1);
+
+ // gptr not set and off is != 0 -> fail
+ result = output_buffer.seekoff(1, ios_base::cur, ios_base::in);
+ assert(result == -1);
+
+ // off larger than buffer size -> fail
+ result = output_buffer.seekoff(20, ios_base::cur, ios_base::out);
+ assert(result == -1);
+
+ // off negative -> fail
+ result = output_buffer.seekoff(-1, ios_base::cur, ios_base::out);
+ assert(result == -1);
+
+ // gptr not set but off is == 0
+ result = output_buffer.seekoff(0, ios_base::cur, ios_base::in);
+ assert(result == 0);
+
+ // passes and sets position
+ result = output_buffer.seekoff(3, ios_base::cur, ios_base::out);
+ assert(result == 3);
+
+ // negative off moves back
+ result = output_buffer.seekoff(-2, ios_base::cur, ios_base::out);
+ assert(result == 1);
+
+ // off + current position is beyond buffer size -> fail
+ result = output_buffer.seekoff(10, ios_base::cur, ios_base::out);
+ assert(result == -1);
+
+ test_buf inout_buffer{span<CharT>{buffer}, ios_base::in | ios_base::out};
+ // no mode set -> fail
+ result = inout_buffer.seekoff(0, ios_base::cur, 0);
+ std::cerr << result << std::endl;
+ // assert(result == -1);
+
+ // both in and out modes set -> fail
+ result = inout_buffer.seekoff(0, ios_base::cur, ios_base::in | ios_base::out);
+ assert(result == -1);
+
+ // off larger than buffer size -> fail
+ result = inout_buffer.seekoff(20, ios_base::cur, ios_base::out);
+ assert(result == -1);
+
+ // off negative -> fail
+ result = inout_buffer.seekoff(-1, ios_base::cur, ios_base::out);
+ assert(result == -1);
+
+ // Moves input sequence to position 3
+ result = inout_buffer.seekoff(3, ios_base::cur, ios_base::in);
+ assert(result == 3);
+
+ // Moves output sequence to position 3
+ result = inout_buffer.seekoff(3, ios_base::cur, ios_base::out);
+ assert(result == 3);
+
+ // negative off moves back
+ result = inout_buffer.seekoff(-2, ios_base::cur, ios_base::in);
+ assert(result == 1);
+
+ // negative off moves back
+ result = inout_buffer.seekoff(-2, ios_base::cur, ios_base::out);
+ assert(result == 1);
+
+ // off + current position is beyond buffer size -> fail
+ result = inout_buffer.seekoff(10, ios_base::cur, ios_base::in);
+ assert(result == -1);
+
+ // off + current position is beyond buffer size -> fail
+ result = inout_buffer.seekoff(10, ios_base::cur, ios_base::out);
+ assert(result == -1);
+
+ // off + current position is before buffer size -> fail
+ result = inout_buffer.seekoff(-2, ios_base::cur, ios_base::in);
+ assert(result == -1);
+
+ // off + current position is before buffer size -> fail
+ result = inout_buffer.seekoff(-2, ios_base::cur, ios_base::out);
+ assert(result == -1);
+ }
+
+ { // seekpos (same as seekoff with ios_base::beg)
+ CharT buffer[10];
+ test_buf input_buffer{span<CharT>{buffer}, ios_base::in};
+ test_buf output_buffer{span<CharT>{buffer}, ios_base::out};
+
+ auto result = input_buffer.seekpos(0, ios_base::in);
+ assert(result == 0);
+
+ // pptr not set but off is 0
+ result = input_buffer.seekpos(0, ios_base::out);
+ assert(result == 0);
+
+ // pptr not set and off != 0 -> fail
+ result = input_buffer.seekpos(1, ios_base::out);
+ assert(result == -1);
+
+ // gptr not set but off is 0
+ result = output_buffer.seekpos(0, ios_base::in);
+ assert(result == 0);
+
+ // gptr not set and off != 0 -> fail
+ result = output_buffer.seekpos(1, ios_base::in);
+ assert(result == -1);
+
+ // negative off -> fail
+ result = input_buffer.seekpos(-1, ios_base::in);
+ assert(result == -1);
+
+ // negative off -> fail
+ result = output_buffer.seekpos(-1, ios_base::out);
+ assert(result == -1);
+
+ // off larger than buf -> fail
+ result = input_buffer.seekpos(20, ios_base::in);
+ assert(result == -1);
+
+ // off larger than buf -> fail
+ result = output_buffer.seekpos(20, ios_base::out);
+ assert(result == -1);
+
+ // passes
+ result = input_buffer.seekpos(5, ios_base::in);
+ assert(result == 5);
+
+ result = output_buffer.seekpos(5, ios_base::out);
+ assert(result == 5);
+
+ // always from front
+ result = input_buffer.seekpos(7, ios_base::in);
+ assert(result == 7);
+
+ result = output_buffer.seekpos(7, ios_base::out);
+ assert(result == 7);
+ }
+}
+
+int main(int, char**) {
+#ifndef TEST_HAS_NO_NASTY_STRING
+ // test<nasty_char, nasty_char_traits>();
+#endif
+ test<char>();
+ test<char, constexpr_char_traits<char>>();
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ test<wchar_t>();
+ test<wchar_t, constexpr_char_traits<wchar_t>>();
+#endif
+
+ return 0;
+}
>From db4e80c02a9a1f669435b510971b7660ca11d3b7 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 12 Mar 2024 17:39:41 +0200
Subject: [PATCH 36/39] Implementation: `seekoff` no mode is set
---
libcxx/include/spanstream | 9 +++++++++
.../spanbuf.virtuals/temp_test/temp_test.pass.cpp | 8 ++++----
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index 68d65db9d0afe3..ed998566f15412 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -166,8 +166,12 @@ protected:
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which = ios_base::in | ios_base::out) override {
const auto __error = static_cast<pos_type>(off_type{-1});
+ // Both `in` and `out` modes are set
if ((__which & ios_base::in) && (__which & ios_base::out) && (ios_base::cur == __way))
return __error;
+ // No mode is set
+ if (!((__which & ios_base::in) || (__which & ios_base::out)) && (ios_base::cur == __way))
+ return __error;
// Calculate __baseoff
@@ -204,6 +208,11 @@ protected:
std::cmp_greater(__newoff, __buf_.size()))
return __error;
+ // if (((__which & ios_base::in && (this->gptr() == nullptr)) ||
+ // (__which & ios_base::out && (this->pptr() == nullptr))) &&
+ // (__newoff != off_type{0}))
+ // return __error;
+
if (__which & ios_base::in) {
if ((this->gptr() == nullptr) && (__newoff != off_type{0}))
return __error;
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp
index 33c75ba9b1fa8d..8c613e2a26bfda 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp
@@ -267,12 +267,12 @@ void test() {
// pptr not set but off is == 0
result = input_buffer.seekoff(-10, ios_base::end, ios_base::out);
- std::cerr << result << std::endl;
+ // std::cerr << result << std::endl;
assert(result == 0);
// pptr not set and off != 0 -> fail
result = input_buffer.seekoff(0, ios_base::end, ios_base::out);
- std::cerr << result << std::endl;
+ // std::cerr << result << std::endl;
assert(result == -1);
// negative off -> fail
@@ -419,7 +419,7 @@ void test() {
// no mode set -> fail
result = output_buffer.seekoff(0, ios_base::cur, 0);
std::cerr << result << std::endl;
- // assert(result == -1);
+ assert(result == -1);
// both in and out modes set -> fail
result = output_buffer.seekoff(0, ios_base::cur, ios_base::in | ios_base::out);
@@ -457,7 +457,7 @@ void test() {
// no mode set -> fail
result = inout_buffer.seekoff(0, ios_base::cur, 0);
std::cerr << result << std::endl;
- // assert(result == -1);
+ assert(result == -1);
// both in and out modes set -> fail
result = inout_buffer.seekoff(0, ios_base::cur, ios_base::in | ios_base::out);
>From 6f4b0210d06a25eaf2b4ab950576d2720aa91208 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 12 Mar 2024 21:12:10 +0200
Subject: [PATCH 37/39] Tests: WIP `seekoff.pass`
---
libcxx/include/spanstream | 16 +-
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 15 +-
.../temp_test/temp_test.pass.cpp | 575 ------------------
3 files changed, 13 insertions(+), 593 deletions(-)
delete mode 100644 libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp
diff --git a/libcxx/include/spanstream b/libcxx/include/spanstream
index ed998566f15412..2b4b6b79d86fde 100644
--- a/libcxx/include/spanstream
+++ b/libcxx/include/spanstream
@@ -70,8 +70,6 @@
#include <streambuf>
#include <version>
-// #include <print>
-
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -166,14 +164,15 @@ protected:
seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which = ios_base::in | ios_base::out) override {
const auto __error = static_cast<pos_type>(off_type{-1});
- // Both `in` and `out` modes are set
+ // Mode: `in` and `out`
if ((__which & ios_base::in) && (__which & ios_base::out) && (ios_base::cur == __way))
return __error;
- // No mode is set
+
+ // Mode: none
if (!((__which & ios_base::in) || (__which & ios_base::out)) && (ios_base::cur == __way))
return __error;
- // Calculate __baseoff
+ // Calculate `__baseoff`
std::size_t __baseoff;
@@ -200,7 +199,7 @@ protected:
return __error;
};
- // Calculate __newoff
+ // Calculate `__newoff`
off_type __newoff;
@@ -208,10 +207,7 @@ protected:
std::cmp_greater(__newoff, __buf_.size()))
return __error;
- // if (((__which & ios_base::in && (this->gptr() == nullptr)) ||
- // (__which & ios_base::out && (this->pptr() == nullptr))) &&
- // (__newoff != off_type{0}))
- // return __error;
+ // Set pointers
if (__which & ios_base::in) {
if ((this->gptr() == nullptr) && (__newoff != off_type{0}))
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
index 3dac603ca1fbe9..e5814eaeabe77f 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -182,19 +182,18 @@ void test() {
assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
- std::cerr << spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) << std::endl;
- // assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == 3);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == 6);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == 7);
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == 3);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == 6);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 3);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 7);
// Default `in` && `out`
- assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::beg) == 3);
assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == 7);
}
// Mode: `in`
{
@@ -244,7 +243,7 @@ void test() {
// Default `in` && `out`
assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == 0);
}
// Mode: multiple
{
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp
deleted file mode 100644
index 8c613e2a26bfda..00000000000000
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/temp_test/temp_test.pass.cpp
+++ /dev/null
@@ -1,575 +0,0 @@
-#include <algorithm>
-#include <array>
-#include <cassert>
-#include <ios>
-#include <limits>
-#include <span>
-#include <spanstream>
-#include <string_view>
-#include <type_traits>
-#include <utility>
-
-#include <algorithm>
-#include <cassert>
-#include <span>
-#include <spanstream>
-
-#include "constexpr_char_traits.h"
-#include "nasty_string.h"
-#include "test_macros.h"
-
-#include <iostream>
-
-using namespace std;
-
-template <class Spanbuf>
-class basic_test_buf : public Spanbuf {
-public:
- using Spanbuf::Spanbuf;
-
- using Spanbuf::eback;
- using Spanbuf::egptr;
- using Spanbuf::epptr;
- using Spanbuf::gptr;
- using Spanbuf::pbase;
- using Spanbuf::pptr;
-
- using Spanbuf::setp;
-
- using Spanbuf::seekoff;
- using Spanbuf::seekpos;
- using Spanbuf::setbuf;
-};
-
-template <typename CharT, typename TraitsT = std::char_traits<CharT>>
-void test() {
- using test_buf = basic_test_buf<basic_spanbuf<CharT>>;
- { // construction
- CharT buffer[10];
- const test_buf default_constructed{};
- assert(default_constructed.span().data() == nullptr);
- assert(default_constructed.eback() == nullptr);
- assert(default_constructed.gptr() == nullptr);
- assert(default_constructed.egptr() == nullptr);
- assert(default_constructed.pbase() == nullptr);
- assert(default_constructed.pptr() == nullptr);
- assert(default_constructed.epptr() == nullptr);
-
- const test_buf mode_constructed{ios_base::in};
- assert(mode_constructed.span().data() == nullptr);
- assert(mode_constructed.eback() == nullptr);
- assert(mode_constructed.gptr() == nullptr);
- assert(mode_constructed.egptr() == nullptr);
- assert(mode_constructed.pbase() == nullptr);
- assert(mode_constructed.pptr() == nullptr);
- assert(mode_constructed.epptr() == nullptr);
-
- test_buf span_constructed{span<CharT>{buffer}};
- assert(span_constructed.span().data() == buffer);
- assert(span_constructed.eback() == buffer);
- assert(span_constructed.gptr() == buffer);
- // assert(span_constructed.egptr() == std::end(buffer));
- assert(span_constructed.pbase() == buffer);
- assert(span_constructed.pptr() == buffer);
- // assert(span_constructed.epptr() == std::end(buffer));
-
- const test_buf span_mode_in_constructed{span<CharT>{buffer}, ios_base::in};
- assert(span_mode_in_constructed.span().data() == buffer);
- assert(span_mode_in_constructed.eback() == buffer);
- assert(span_mode_in_constructed.gptr() == buffer);
- // assert(span_mode_in_constructed.egptr() == std::end(buffer));
- assert(span_mode_in_constructed.pbase() == nullptr);
- assert(span_mode_in_constructed.pptr() == nullptr);
- assert(span_mode_in_constructed.epptr() == nullptr);
-
- const test_buf span_mode_in_ate_constructed{span<CharT>{buffer}, ios_base::in | ios_base::ate};
- assert(span_mode_in_ate_constructed.span().data() == buffer);
- assert(span_mode_in_ate_constructed.eback() == buffer);
- assert(span_mode_in_ate_constructed.gptr() == buffer);
- // assert(span_mode_in_ate_constructed.egptr() == std::end(buffer));
- assert(span_mode_in_ate_constructed.pbase() == nullptr);
- assert(span_mode_in_ate_constructed.pptr() == nullptr);
- assert(span_mode_in_ate_constructed.epptr() == nullptr);
-
- const test_buf span_mode_out_constructed{span<CharT>{buffer}, ios_base::out};
- assert(span_mode_out_constructed.span().data() == buffer);
- assert(span_mode_out_constructed.eback() == nullptr);
- assert(span_mode_out_constructed.gptr() == nullptr);
- assert(span_mode_out_constructed.egptr() == nullptr);
- assert(span_mode_out_constructed.pbase() == buffer);
- assert(span_mode_out_constructed.pptr() == buffer);
- assert(span_mode_out_constructed.epptr() == std::end(buffer));
-
- const test_buf span_mode_out_ate_constructed{span<CharT>{buffer}, ios_base::out | ios_base::ate};
- assert(span_mode_out_ate_constructed.span().data() == buffer);
- assert(span_mode_out_ate_constructed.eback() == nullptr);
- assert(span_mode_out_ate_constructed.gptr() == nullptr);
- assert(span_mode_out_ate_constructed.egptr() == nullptr);
- assert(span_mode_out_ate_constructed.pbase() == buffer);
- // assert(span_mode_out_ate_constructed.pptr() == std::end(buffer));
- // assert(span_mode_out_ate_constructed.epptr() == std::end(buffer));
-
- const test_buf span_mode_unknown_constructed{span<CharT>{buffer}, 0};
- assert(span_mode_unknown_constructed.span().data() == buffer);
- assert(span_mode_unknown_constructed.eback() == nullptr);
- assert(span_mode_unknown_constructed.gptr() == nullptr);
- assert(span_mode_unknown_constructed.egptr() == nullptr);
- assert(span_mode_unknown_constructed.pbase() == nullptr);
- assert(span_mode_unknown_constructed.pptr() == nullptr);
- assert(span_mode_unknown_constructed.epptr() == nullptr);
-#if 0
- test_buf move_constructed{std::move(span_constructed)};
- assert(move_constructed.span().data() == buffer);
- assert(move_constructed.eback() == buffer);
- assert(move_constructed.gptr() == buffer);
- // assert(move_constructed.egptr() == std::end(buffer));
- assert(move_constructed.pbase() == buffer);
- assert(move_constructed.pptr() == buffer);
- // assert(move_constructed.epptr() == std::end(buffer));
- assert(span_constructed.span().data() == nullptr);
- assert(span_constructed.eback() == nullptr);
- assert(span_constructed.gptr() == nullptr);
- assert(span_constructed.egptr() == nullptr);
- assert(span_constructed.pbase() == nullptr);
- assert(span_constructed.pptr() == nullptr);
- assert(span_constructed.epptr() == nullptr);
-
- test_buf move_assigned;
- move_assigned = std::move(move_constructed);
- assert(move_assigned.span().data() == buffer);
- assert(move_assigned.eback() == buffer);
- assert(move_assigned.gptr() == buffer);
- // assert(move_assigned.egptr() == std::end(buffer));
- assert(move_assigned.pbase() == buffer);
- assert(move_assigned.pptr() == buffer);
- // assert(move_assigned.epptr() == std::end(buffer));
- assert(move_constructed.span().data() == nullptr);
- assert(move_constructed.eback() == nullptr);
- assert(move_constructed.gptr() == nullptr);
- assert(move_constructed.egptr() == nullptr);
- assert(move_constructed.pbase() == nullptr);
- assert(move_constructed.pptr() == nullptr);
- assert(move_constructed.epptr() == nullptr);
-#endif
- }
-
- // { // swap
- // CharT buffer1[10];
- // CharT buffer2[20];
- // test_buf first{span<CharT>{buffer1}};
- // test_buf second{span<CharT>{buffer2}};
- // assert(first.span().data() == buffer1);
- // assert(second.span().data() == buffer2);
-
- // first.swap(second);
- // assert(first.span().data() == buffer2);
- // assert(second.span().data() == buffer1);
-
- // swap(first, second);
- // assert(first.span().data() == buffer1);
- // assert(second.span().data() == buffer2);
- // }
-
- // { // span, span, span, span
- // CharT buffer1[10];
- // test_buf input_buffer{span<CharT>{buffer1}, ios_base::in};
- // assert(input_buffer.span().data() == buffer1);
- // assert(input_buffer.span().size() == std::size(buffer1));
-
- // test_buf output_buffer{span<CharT>{buffer1}, ios_base::out};
- // assert(output_buffer.span().data() == buffer1);
- // assert(output_buffer.span().size() == 0); // counts the written characters
-
- // // Manually move the written pointer
- // output_buffer.setp(buffer1, buffer1 + 5, std::end(buffer1));
- // assert(output_buffer.span().data() == buffer1);
- // assert(output_buffer.span().size() == 5);
-
- // CharT buffer2[10];
- // input_buffer.span(span<CharT>{buffer2});
- // assert(input_buffer.span().data() == buffer2);
- // assert(input_buffer.span().size() == std::size(buffer2));
-
- // output_buffer.span(span<CharT>{buffer2});
- // assert(output_buffer.span().data() == buffer2);
- // assert(output_buffer.span().size() == 0);
-
- // test_buf hungry_buffer{span<CharT>{buffer1}, ios_base::out | ios_base::ate};
- // assert(hungry_buffer.span().data() == buffer1);
- // assert(hungry_buffer.span().size() == std::size(buffer1));
-
- // hungry_buffer.span(span<CharT>{buffer2});
- // assert(hungry_buffer.span().data() == buffer2);
- // assert(hungry_buffer.span().size() == std::size(buffer2));
- // }
-
- { // seekoff ios_base::beg
- CharT buffer[10];
- test_buf input_buffer{span<CharT>{buffer}, ios_base::in};
- test_buf output_buffer{span<CharT>{buffer}, ios_base::out};
-
- auto result = input_buffer.seekoff(0, ios_base::beg, ios_base::in);
- assert(result == 0);
-
- // pptr not set but off is 0
- result = input_buffer.seekoff(0, ios_base::beg, ios_base::out);
- assert(result == 0);
-
- // pptr not set and off != 0 -> fail
- result = input_buffer.seekoff(1, ios_base::beg, ios_base::out);
- assert(result == -1);
-
- // gptr not set but off is 0
- result = output_buffer.seekoff(0, ios_base::beg, ios_base::in);
- assert(result == 0);
-
- // gptr not set and off != 0 -> fail
- result = output_buffer.seekoff(1, ios_base::beg, ios_base::in);
- assert(result == -1);
-
- // negative off -> fail
- result = input_buffer.seekoff(-1, ios_base::beg, ios_base::in);
- assert(result == -1);
-
- // negative off -> fail
- result = output_buffer.seekoff(-1, ios_base::beg, ios_base::out);
- assert(result == -1);
-
- // off larger than buf -> fail
- result = input_buffer.seekoff(20, ios_base::beg, ios_base::in);
- assert(result == -1);
-
- // off larger than buf -> fail
- result = output_buffer.seekoff(20, ios_base::beg, ios_base::out);
- assert(result == -1);
-
- // passes
- result = input_buffer.seekoff(5, ios_base::beg, ios_base::in);
- assert(result == 5);
-
- result = output_buffer.seekoff(5, ios_base::beg, ios_base::out);
- assert(result == 5);
-
- // always from front
- result = input_buffer.seekoff(7, ios_base::beg, ios_base::in);
- assert(result == 7);
-
- result = output_buffer.seekoff(7, ios_base::beg, ios_base::out);
- assert(result == 7);
- }
-
- { // seekoff ios_base::end
- CharT buffer[10];
- test_buf input_buffer{span<CharT>{buffer}, ios_base::in};
- // all fine we move to end of stream
- auto result = input_buffer.seekoff(0, ios_base::end, ios_base::in);
- assert(result == 10);
-
- // pptr not set but off is == 0
- result = input_buffer.seekoff(-10, ios_base::end, ios_base::out);
- // std::cerr << result << std::endl;
- assert(result == 0);
-
- // pptr not set and off != 0 -> fail
- result = input_buffer.seekoff(0, ios_base::end, ios_base::out);
- // std::cerr << result << std::endl;
- assert(result == -1);
-
- // negative off -> fail
- result = input_buffer.seekoff(-20, ios_base::end, ios_base::in);
- assert(result == -1);
-
- // off beyond end of buffer -> fail
- result = input_buffer.seekoff(1, ios_base::end, ios_base::in);
- assert(result == -1);
-
- // passes and moves to buffer size - off
- result = input_buffer.seekoff(-5, ios_base::end, ios_base::in);
- assert(result == 5);
-
- // always from front
- result = input_buffer.seekoff(-7, ios_base::end, ios_base::in);
- assert(result == 3);
-
- // integer overflow due to large off
- result = input_buffer.seekoff(numeric_limits<long long>::max(), ios_base::end, ios_base::in);
- assert(result == -1);
-
- test_buf output_buffer{span<CharT>{buffer}, ios_base::out};
- // gptr not set but off is 0
- result = output_buffer.seekoff(0, ios_base::end, ios_base::in);
- assert(result == 0);
-
- // newoff is negative -> fail
- result = output_buffer.seekoff(-10, ios_base::end, ios_base::out);
- assert(result == -1);
-
- // pptr not set but off == 0
- result = output_buffer.seekoff(0, ios_base::end, ios_base::out);
- assert(result == 0);
-
- // all fine we stay at end of stream
- result = output_buffer.seekoff(0, ios_base::end, ios_base::in);
- assert(result == 0);
-
- // gptr not set and off != 0 -> fail
- result = output_buffer.seekoff(1, ios_base::end, ios_base::in);
- assert(result == -1);
-
- // off + buffer size is negative -> fail
- result = output_buffer.seekoff(-20, ios_base::end, ios_base::out);
- assert(result == -1);
-
- // off larger than buffer -> fail
- result = output_buffer.seekoff(11, ios_base::end, ios_base::out);
- assert(result == -1);
-
- // passes and moves to buffer size - off
- result = output_buffer.seekoff(5, ios_base::end, ios_base::out);
- assert(result == 5);
-
- // passes we are still below buffer size
- result = output_buffer.seekoff(3, ios_base::end, ios_base::out);
- assert(result == 8);
-
- // moves beyond buffer size -> fails
- result = output_buffer.seekoff(3, ios_base::end, ios_base::out);
- assert(result == -1);
-
- // integer overflow due to large off
- result = output_buffer.seekoff(numeric_limits<long long>::max(), ios_base::end, ios_base::in);
- assert(result == -1);
-
- test_buf inout_buffer{span<CharT>{buffer}, ios_base::in | ios_base::out};
- // all fine we move to end of stream
- result = inout_buffer.seekoff(0, ios_base::end, ios_base::in);
- assert(result == 10);
-
- // we move to front of the buffer
- result = inout_buffer.seekoff(-10, ios_base::end, ios_base::out);
- assert(result == 0);
-
- // we move to end of buffer
- result = inout_buffer.seekoff(0, ios_base::end, ios_base::out);
- assert(result == 10);
-
- // negative off -> fail
- result = inout_buffer.seekoff(-20, ios_base::end, ios_base::in);
- assert(result == -1);
-
- // off beyond end of buffer -> fail
- result = inout_buffer.seekoff(1, ios_base::end, ios_base::in);
- assert(result == -1);
-
- // passes and moves to buffer size - off
- result = inout_buffer.seekoff(-5, ios_base::end, ios_base::in);
- assert(result == 5);
-
- // always from front
- result = inout_buffer.seekoff(-7, ios_base::end, ios_base::in);
- assert(result == 3);
-
- // integer overflow due to large off
- result = inout_buffer.seekoff(numeric_limits<long long>::max(), ios_base::end, ios_base::in);
- assert(result == -1);
- }
-
- { // seekoff ios_base::cur
- CharT buffer[10];
- test_buf input_buffer{span<CharT>{buffer}, ios_base::in};
-
- // no mode set -> fail
- auto result = input_buffer.seekoff(0, ios_base::cur, 0);
- std::cerr << result << std::endl;
- assert(result == -1);
-
- // both in and out modes set -> fail
- result = input_buffer.seekoff(0, ios_base::cur, ios_base::in | ios_base::out);
- assert(result == -1);
-
- // pptr not set and off is != 0 -> fail
- result = input_buffer.seekoff(1, ios_base::cur, ios_base::out);
- assert(result == -1);
-
- // off larger than buffer size -> fail
- result = input_buffer.seekoff(20, ios_base::cur, ios_base::out);
- assert(result == -1);
-
- // off negative -> fail
- result = input_buffer.seekoff(-1, ios_base::cur, ios_base::out);
- assert(result == -1);
-
- // pptr not set but off is == 0
- result = input_buffer.seekoff(0, ios_base::cur, ios_base::out);
- assert(result == 0);
-
- // passes and sets position
- result = input_buffer.seekoff(3, ios_base::cur, ios_base::in);
- assert(result == 3);
-
- // negative off moves back
- result = input_buffer.seekoff(-2, ios_base::cur, ios_base::in);
- assert(result == 1);
-
- // off + current position is beyond buffer size -> fail
- result = input_buffer.seekoff(10, ios_base::cur, ios_base::in);
- assert(result == -1);
-
- test_buf output_buffer{span<CharT>{buffer}, ios_base::out};
- // no mode set -> fail
- result = output_buffer.seekoff(0, ios_base::cur, 0);
- std::cerr << result << std::endl;
- assert(result == -1);
-
- // both in and out modes set -> fail
- result = output_buffer.seekoff(0, ios_base::cur, ios_base::in | ios_base::out);
- assert(result == -1);
-
- // gptr not set and off is != 0 -> fail
- result = output_buffer.seekoff(1, ios_base::cur, ios_base::in);
- assert(result == -1);
-
- // off larger than buffer size -> fail
- result = output_buffer.seekoff(20, ios_base::cur, ios_base::out);
- assert(result == -1);
-
- // off negative -> fail
- result = output_buffer.seekoff(-1, ios_base::cur, ios_base::out);
- assert(result == -1);
-
- // gptr not set but off is == 0
- result = output_buffer.seekoff(0, ios_base::cur, ios_base::in);
- assert(result == 0);
-
- // passes and sets position
- result = output_buffer.seekoff(3, ios_base::cur, ios_base::out);
- assert(result == 3);
-
- // negative off moves back
- result = output_buffer.seekoff(-2, ios_base::cur, ios_base::out);
- assert(result == 1);
-
- // off + current position is beyond buffer size -> fail
- result = output_buffer.seekoff(10, ios_base::cur, ios_base::out);
- assert(result == -1);
-
- test_buf inout_buffer{span<CharT>{buffer}, ios_base::in | ios_base::out};
- // no mode set -> fail
- result = inout_buffer.seekoff(0, ios_base::cur, 0);
- std::cerr << result << std::endl;
- assert(result == -1);
-
- // both in and out modes set -> fail
- result = inout_buffer.seekoff(0, ios_base::cur, ios_base::in | ios_base::out);
- assert(result == -1);
-
- // off larger than buffer size -> fail
- result = inout_buffer.seekoff(20, ios_base::cur, ios_base::out);
- assert(result == -1);
-
- // off negative -> fail
- result = inout_buffer.seekoff(-1, ios_base::cur, ios_base::out);
- assert(result == -1);
-
- // Moves input sequence to position 3
- result = inout_buffer.seekoff(3, ios_base::cur, ios_base::in);
- assert(result == 3);
-
- // Moves output sequence to position 3
- result = inout_buffer.seekoff(3, ios_base::cur, ios_base::out);
- assert(result == 3);
-
- // negative off moves back
- result = inout_buffer.seekoff(-2, ios_base::cur, ios_base::in);
- assert(result == 1);
-
- // negative off moves back
- result = inout_buffer.seekoff(-2, ios_base::cur, ios_base::out);
- assert(result == 1);
-
- // off + current position is beyond buffer size -> fail
- result = inout_buffer.seekoff(10, ios_base::cur, ios_base::in);
- assert(result == -1);
-
- // off + current position is beyond buffer size -> fail
- result = inout_buffer.seekoff(10, ios_base::cur, ios_base::out);
- assert(result == -1);
-
- // off + current position is before buffer size -> fail
- result = inout_buffer.seekoff(-2, ios_base::cur, ios_base::in);
- assert(result == -1);
-
- // off + current position is before buffer size -> fail
- result = inout_buffer.seekoff(-2, ios_base::cur, ios_base::out);
- assert(result == -1);
- }
-
- { // seekpos (same as seekoff with ios_base::beg)
- CharT buffer[10];
- test_buf input_buffer{span<CharT>{buffer}, ios_base::in};
- test_buf output_buffer{span<CharT>{buffer}, ios_base::out};
-
- auto result = input_buffer.seekpos(0, ios_base::in);
- assert(result == 0);
-
- // pptr not set but off is 0
- result = input_buffer.seekpos(0, ios_base::out);
- assert(result == 0);
-
- // pptr not set and off != 0 -> fail
- result = input_buffer.seekpos(1, ios_base::out);
- assert(result == -1);
-
- // gptr not set but off is 0
- result = output_buffer.seekpos(0, ios_base::in);
- assert(result == 0);
-
- // gptr not set and off != 0 -> fail
- result = output_buffer.seekpos(1, ios_base::in);
- assert(result == -1);
-
- // negative off -> fail
- result = input_buffer.seekpos(-1, ios_base::in);
- assert(result == -1);
-
- // negative off -> fail
- result = output_buffer.seekpos(-1, ios_base::out);
- assert(result == -1);
-
- // off larger than buf -> fail
- result = input_buffer.seekpos(20, ios_base::in);
- assert(result == -1);
-
- // off larger than buf -> fail
- result = output_buffer.seekpos(20, ios_base::out);
- assert(result == -1);
-
- // passes
- result = input_buffer.seekpos(5, ios_base::in);
- assert(result == 5);
-
- result = output_buffer.seekpos(5, ios_base::out);
- assert(result == 5);
-
- // always from front
- result = input_buffer.seekpos(7, ios_base::in);
- assert(result == 7);
-
- result = output_buffer.seekpos(7, ios_base::out);
- assert(result == 7);
- }
-}
-
-int main(int, char**) {
-#ifndef TEST_HAS_NO_NASTY_STRING
- // test<nasty_char, nasty_char_traits>();
-#endif
- test<char>();
- test<char, constexpr_char_traits<char>>();
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
- test<wchar_t>();
- test<wchar_t, constexpr_char_traits<wchar_t>>();
-#endif
-
- return 0;
-}
>From 2dcacc095c4b8f89ef142b1be294a1f02cd83c1c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 13 Mar 2024 11:41:35 +0200
Subject: [PATCH 38/39] Tests: `seekoff.off_type.seek_dir.open_mode.pass`
---
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 236 +++++++++++-------
1 file changed, 144 insertions(+), 92 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
index e5814eaeabe77f..ce9fd90f6e7c3d 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -28,27 +28,30 @@
#include "nasty_string.h"
#include "test_macros.h"
-#include <iostream>
+// #include <iostream>
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
+ constexpr auto no_mode = 0;
+
// Empty `span`
{
std::span<CharT> sp;
+ // For an empty span:
+ // -3 is an out-of-range offset value
+ // 0 is an in-range offset value for an empty span
+ // 3 is an out-of-range offset value
+
// Mode: default (`in` | `out`)
{
SpBuf spBuf{sp};
- // Out-of-range
- assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::in) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
@@ -58,48 +61,36 @@ void test() {
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
- // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
+
+ // Default parameter value `openmode`
+ assert(spBuf.pubseekoff(0, std::ios_base::beg) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::end) == 0);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
+
+ // No mode
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, no_mode) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, no_mode) == 0);
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, no_mode) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(-1, std::ios_base::end, no_mode) == -1);
}
// Mode: `in`
{
SpBuf spBuf{sp, std::ios_base::in};
- // Out-of-range
- assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
-
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
- assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
-
- // Default `in` && `out`
- assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
- }
- // Mode: `out`
- {
- SpBuf spBuf{sp, std::ios_base::out};
-
- // Out-of-range
- assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
-
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
@@ -108,22 +99,35 @@ void test() {
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
- // Default `in` && `out`
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
+
+ // Default parameter value `openmode`
+ assert(spBuf.pubseekoff(0, std::ios_base::beg) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur) == -1); // ???
+ assert(spBuf.pubseekoff(0, std::ios_base::end) == 0);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
+
+ // No mode
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, no_mode) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, no_mode) == 0);
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, no_mode) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, no_mode) == -1);
}
- // Mode: `multiple`
+ // Mode: `out`
{
- SpBuf spBuf{sp, std::ios_base::in | std::ios_base::out | std::ios_base::binary};
+ SpBuf spBuf{sp, std::ios_base::out};
- // Out-of-range
- assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
@@ -133,35 +137,27 @@ void test() {
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
- // Default `in` && `out`
- assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
- assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
- }
- // Mode: `ate`
- {
- SpBuf spBuf{sp, std::ios_base::out | std::ios_base::ate};
-
- // Out-of-range
- assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
- assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
-
- assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
- assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
- assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
-
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
- // Default `in` && `out`
+ // Default parameter value `openmode`
+ assert(spBuf.pubseekoff(0, std::ios_base::beg) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur) == -1); // ???
+ assert(spBuf.pubseekoff(0, std::ios_base::end) == 0);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
+
+ // No mode
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, no_mode) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, no_mode) == 0);
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, no_mode) == -1);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, no_mode) == -1);
}
}
@@ -170,6 +166,10 @@ void test() {
CharT arr[10];
std::span sp{arr};
+ // For an empty span:
+ // -999 is an out-of-range offset value
+ // 999 is an out-of-range offset value
+
// Mode: default (`in` | `out`)
{
SpBuf spBuf{sp};
@@ -182,18 +182,43 @@ void test() {
assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+ // In-range
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
+ // std::cerr << spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) << std::endl;
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 10); // ???
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == 3);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == 6);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == 7);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
+ // std::cerr << spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) << std::endl;
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 10); // ???
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == 3);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == 6);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 7);
- // Default `in` && `out`
+ // Default parameter value `openmode`
+ assert(spBuf.pubseekoff(0, std::ios_base::beg) == 0);
+ // std::cerr << spBuf.pubseekoff(0, std::ios_base::cur) << std::endl;
+ assert(spBuf.pubseekoff(0, std::ios_base::cur) == -1); // ???
+ assert(spBuf.pubseekoff(0, std::ios_base::end) == 10);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg) == 3);
assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end) == 7);
+
+ // No mode
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, no_mode) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, no_mode) == 10); // ???
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, no_mode) == 3);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, no_mode) == 7);
}
// Mode: `in`
{
@@ -207,18 +232,41 @@ void test() {
assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+ // In-range
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 10); // ???
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == 3);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == 6);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == 7);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
+ // std::cerr << spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) << std::endl;
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == -1); // ???
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
- // Default `in` && `out`
+ // Default parameter value `openmode`
+ assert(spBuf.pubseekoff(0, std::ios_base::beg) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur) == -1); // ???
+ assert(spBuf.pubseekoff(0, std::ios_base::end) == -1); // ???
+
assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
+
+ // No mode
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, no_mode) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, no_mode) == 10); // ???
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, no_mode) == 3);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, no_mode) == 7);
}
// Mode: `out`
{
@@ -232,36 +280,40 @@ void test() {
assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
+ // In-range
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::in) == -1);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 0);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == 3);
assert(spBuf.pubseekoff(3, std::ios_base::cur, std::ios_base::out) == 6);
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 3);
- // Default `in` && `out`
+ // Default parameter value `openmode`
+ assert(spBuf.pubseekoff(0, std::ios_base::beg) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur) == -1); // ???
+ assert(spBuf.pubseekoff(0, std::ios_base::end) == 0);
+
assert(spBuf.pubseekoff(3, std::ios_base::beg) == -1);
assert(spBuf.pubseekoff(3, std::ios_base::cur) == -1);
- assert(spBuf.pubseekoff(-3, std::ios_base::end) == 0);
- }
- // Mode: multiple
- {
- // std::span<CharT> sp{arr};
- // TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp | std::ios_base::binary);
- // TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
- // assert(rhsSpBuf.span().data() == arr);
- // assert(spBuf.span().data() == arr);
- // spBuf.check_postconditions(rhsSpBuf);
- }
- // Mode: `ate`
- {
- // std::span<CharT> sp{arr};
- // TestSpanBuf<CharT, TraitsT> rhsSpBuf(sp, std::ios_base::out | std::ios_base::ate);
- // TestSpanBuf<CharT, TraitsT> spBuf = std::move(static_cast<SpBuf&>(rhsSpBuf));
- // assert(rhsSpBuf.span().data() == arr);
- // assert(spBuf.span().data() == arr);
- // spBuf.check_postconditions(rhsSpBuf);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
+
+ // No mode
+ assert(spBuf.pubseekoff(0, std::ios_base::beg, no_mode) == 0);
+ assert(spBuf.pubseekoff(0, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(0, std::ios_base::end, no_mode) == 0); // ???
+
+ assert(spBuf.pubseekoff(3, std::ios_base::beg, no_mode) == 3);
+ assert(spBuf.pubseekoff(3, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(-3, std::ios_base::end, no_mode) == -1); // ???
}
}
}
>From 0add325a1d39ede8049189a67e50fe32a2a3ec0c Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Wed, 13 Mar 2024 11:50:47 +0200
Subject: [PATCH 39/39] Tests: clean-up
`seekoff.off_type.seek_dir.open_mode.pass`
---
...ekoff.off_type.seek_dir.open_mode.pass.cpp | 87 ++++++++++++++++---
1 file changed, 75 insertions(+), 12 deletions(-)
diff --git a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
index ce9fd90f6e7c3d..1a3d43f99b0ff5 100644
--- a/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
+++ b/libcxx/test/std/input.output/span.streams/spanbuf/spanbuf.virtuals/seekoff.off_type.seek_dir.open_mode.pass.cpp
@@ -28,8 +28,6 @@
#include "nasty_string.h"
#include "test_macros.h"
-// #include <iostream>
-
template <typename CharT, typename TraitsT = std::char_traits<CharT>>
void test() {
using SpBuf = std::basic_spanbuf<CharT, TraitsT>;
@@ -174,18 +172,24 @@ void test() {
{
SpBuf spBuf{sp};
- // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::in) == -1);
+
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::in) == -1);
+
assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
- // In-range
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
- // std::cerr << spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) << std::endl;
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 10); // ???
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::in) == 3);
@@ -194,7 +198,6 @@ void test() {
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
- // std::cerr << spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) << std::endl;
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == 10); // ???
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == 3);
@@ -202,8 +205,15 @@ void test() {
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 7);
// Default parameter value `openmode`
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end) == -1);
+
+ assert(spBuf.pubseekoff(999, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg) == 0);
- // std::cerr << spBuf.pubseekoff(0, std::ios_base::cur) << std::endl;
assert(spBuf.pubseekoff(0, std::ios_base::cur) == -1); // ???
assert(spBuf.pubseekoff(0, std::ios_base::end) == 10);
@@ -212,6 +222,14 @@ void test() {
assert(spBuf.pubseekoff(-3, std::ios_base::end) == 7);
// No mode
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, no_mode) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, no_mode) == -1);
+
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, no_mode) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, no_mode) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg, no_mode) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, no_mode) == -1);
assert(spBuf.pubseekoff(0, std::ios_base::end, no_mode) == 10); // ???
@@ -224,15 +242,22 @@ void test() {
{
SpBuf spBuf{sp, std::ios_base::in};
- // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::in) == -1);
+
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::in) == -1);
+
assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
- // In-range
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 10); // ???
@@ -243,7 +268,6 @@ void test() {
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::out) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::out) == 0);
- // std::cerr << spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) << std::endl;
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::out) == -1); // ???
assert(spBuf.pubseekoff(3, std::ios_base::beg, std::ios_base::out) == -1);
@@ -251,6 +275,14 @@ void test() {
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == -1);
// Default parameter value `openmode`
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end) == -1);
+
+ assert(spBuf.pubseekoff(999, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur) == -1); // ???
assert(spBuf.pubseekoff(0, std::ios_base::end) == -1); // ???
@@ -260,6 +292,14 @@ void test() {
assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
// No mode
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, no_mode) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, no_mode) == -1);
+
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, no_mode) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, no_mode) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg, no_mode) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, no_mode) == -1);
assert(spBuf.pubseekoff(0, std::ios_base::end, no_mode) == 10); // ???
@@ -272,15 +312,22 @@ void test() {
{
SpBuf spBuf{sp, std::ios_base::out};
- // Out-of-range
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::in) == -1);
+
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::in) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::in) == -1);
+
assert(spBuf.pubseekoff(-999, std::ios_base::beg, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(-999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(-999, std::ios_base::end, std::ios_base::out) == -1);
+
assert(spBuf.pubseekoff(999, std::ios_base::beg, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::cur, std::ios_base::out) == -1);
assert(spBuf.pubseekoff(999, std::ios_base::end, std::ios_base::out) == -1);
- // In-range
assert(spBuf.pubseekoff(0, std::ios_base::beg, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, std::ios_base::in) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::end, std::ios_base::in) == 0);
@@ -298,6 +345,14 @@ void test() {
assert(spBuf.pubseekoff(-3, std::ios_base::end, std::ios_base::out) == 3);
// Default parameter value `openmode`
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end) == -1);
+
+ assert(spBuf.pubseekoff(999, std::ios_base::beg) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur) == -1); // ???
assert(spBuf.pubseekoff(0, std::ios_base::end) == 0);
@@ -307,6 +362,14 @@ void test() {
assert(spBuf.pubseekoff(-3, std::ios_base::end) == -1);
// No mode
+ assert(spBuf.pubseekoff(-999, std::ios_base::beg, no_mode) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(-999, std::ios_base::end, no_mode) == -1);
+
+ assert(spBuf.pubseekoff(999, std::ios_base::beg, no_mode) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::cur, no_mode) == -1);
+ assert(spBuf.pubseekoff(999, std::ios_base::end, no_mode) == -1);
+
assert(spBuf.pubseekoff(0, std::ios_base::beg, no_mode) == 0);
assert(spBuf.pubseekoff(0, std::ios_base::cur, no_mode) == -1);
assert(spBuf.pubseekoff(0, std::ios_base::end, no_mode) == 0); // ???
More information about the libcxx-commits
mailing list