[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
Tue Mar 12 05:30:27 PDT 2024
================
@@ -0,0 +1,456 @@
+// -*- 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 <__concepts/convertible_to.h>
+#include <__config>
+#include <__fwd/spanstream.h>
+#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>
+
+// #include <print>
+
+#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>
+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) {
+ 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_)} {}
+ // __buf_{std::exchange(__rhs.__buf_, {})} {}
+
----------------
H-G-Hristov wrote:
Alternative implementation with `std::exchange`, which sets an empty `span` (`data() == nullptr`):
```suggestion
_LIBCPP_HIDE_FROM_ABI basic_spanbuf(basic_spanbuf&& __rhs)
: basic_streambuf<_CharT, _Traits>{std::move(__rhs)},
__mode_{std::move(__rhs.__mode_)},
__buf_{std::exchange(__rhs.__buf_, {})} {}
```
https://github.com/llvm/llvm-project/pull/83541
More information about the libcxx-commits
mailing list