
PR libstdc++/103626 - _GLIBCXX_HOSTED should respect -ffreestanding Co-authored-by: Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ChangeLog: PR libstdc++/103626 * include/Makefile.am: Add new header. * include/Makefile.in: Regenerate. * include/bits/requires_hosted.h: New header. * include/experimental/algorithm: Include <bits/requires_hosted.h>. * include/experimental/any: Likewise. * include/experimental/array: Likewise. * include/experimental/buffer: Likewise. * include/experimental/chrono: Likewise. * include/experimental/deque: Likewise. * include/experimental/executor: Likewise. * include/experimental/filesystem: Likewise. * include/experimental/forward_list: Likewise. * include/experimental/functional: Likewise. * include/experimental/internet: Likewise. * include/experimental/io_context: Likewise. * include/experimental/iterator: Likewise. * include/experimental/list: Likewise. * include/experimental/map: Likewise. * include/experimental/memory: Likewise. * include/experimental/memory_resource: Likewise. * include/experimental/net: Likewise. * include/experimental/netfwd: Likewise. * include/experimental/numeric: Likewise. * include/experimental/optional: Likewise. * include/experimental/propagate_const: Likewise. * include/experimental/random: Likewise. * include/experimental/ratio: Likewise. * include/experimental/regex: Likewise. * include/experimental/scope: Likewise. * include/experimental/set: Likewise. * include/experimental/simd: Likewise. * include/experimental/socket: Likewise. * include/experimental/source_location: Likewise. * include/experimental/string: Likewise. * include/experimental/string_view: Likewise. * include/experimental/system_error: Likewise. * include/experimental/timer: Likewise. * include/experimental/tuple: Likewise. * include/experimental/unordered_map: Likewise. * include/experimental/unordered_set: Likewise. * include/experimental/utility: Likewise. * include/experimental/vector: Likewise. * include/std/barrier: Likewise. * include/std/chrono: Likewise. * include/std/condition_variable: Likewise. * include/std/deque: Likewise. * include/std/execution: Likewise. * include/std/filesystem: Likewise. * include/std/forward_list: Likewise. * include/std/fstream: Likewise. * include/std/future: Likewise. * include/std/iomanip: Likewise. * include/std/ios: Likewise. * include/std/iosfwd: Likewise. * include/std/iostream: Likewise. * include/std/istream: Likewise. * include/std/latch: Likewise. * include/std/list: Likewise. * include/std/locale: Likewise. * include/std/map: Likewise. * include/std/memory_resource: Likewise. * include/std/mutex: Likewise. * include/std/ostream: Likewise. * include/std/queue: Likewise. * include/std/random: Likewise. * include/std/regex: Likewise. * include/std/semaphore: Likewise. * include/std/set: Likewise. * include/std/shared_mutex: Likewise. * include/std/spanstream: Likewise. * include/std/sstream: Likewise. * include/std/stack: Likewise. * include/std/stacktrace: Likewise. * include/std/stop_token: Likewise. * include/std/streambuf: Likewise. * include/std/string: Likewise. * include/std/syncstream: Likewise. * include/std/system_error: Likewise. * include/std/thread: Likewise. * include/std/unordered_map: Likewise. * include/std/unordered_set: Likewise. * include/std/valarray: Likewise. * include/std/vector: Likewise. * include/tr1/array: Likewise. * include/tr1/ccomplex: Likewise. * include/tr1/cctype: Likewise. * include/tr1/cfenv: Likewise. * include/tr1/cfloat: Likewise. * include/tr1/cinttypes: Likewise. * include/tr1/climits: Likewise. * include/tr1/cmath: Likewise. * include/tr1/complex: Likewise. * include/tr1/complex.h: Likewise. * include/tr1/cstdarg: Likewise. * include/tr1/cstdbool: Likewise. * include/tr1/cstdint: Likewise. * include/tr1/cstdio: Likewise. * include/tr1/cstdlib: Likewise. * include/tr1/ctgmath: Likewise. * include/tr1/ctime: Likewise. * include/tr1/ctype.h: Likewise. * include/tr1/cwchar: Likewise. * include/tr1/cwctype: Likewise. * include/tr1/fenv.h: Likewise. * include/tr1/float.h: Likewise. * include/tr1/functional: Likewise. * include/tr1/inttypes.h: Likewise. * include/tr1/limits.h: Likewise. * include/tr1/math.h: Likewise. * include/tr1/memory: Likewise. * include/tr1/random: Likewise. * include/tr1/regex: Likewise. * include/tr1/stdarg.h: Likewise. * include/tr1/stdbool.h: Likewise. * include/tr1/stdint.h: Likewise. * include/tr1/stdio.h: Likewise. * include/tr1/stdlib.h: Likewise. * include/tr1/tgmath.h: Likewise. * include/tr1/tuple: Likewise. * include/tr1/type_traits: Likewise. * include/tr1/unordered_map: Likewise. * include/tr1/unordered_set: Likewise. * include/tr1/utility: Likewise. * include/tr1/wchar.h: Likewise. * include/tr1/wctype.h: Likewise. * include/c_global/cmath: Likewise. * include/ext/algorithm: Include <bits/requires_hosted.h>. * include/ext/bitmap_allocator.h: Likewise. * include/ext/cmath: Likewise. * include/ext/codecvt_specializations.h: Likewise. * include/ext/debug_allocator.h: Likewise. * include/ext/enc_filebuf.h: Likewise. * include/ext/extptr_allocator.h: Likewise. * include/ext/functional: Likewise. * include/ext/malloc_allocator.h: Likewise. * include/ext/memory: Likewise. * include/ext/mt_allocator.h: Likewise. * include/ext/new_allocator.h: Likewise. * include/ext/numeric: Likewise. * include/ext/pod_char_traits.h: Likewise. * include/ext/pool_allocator.h: Likewise. * include/ext/random: Likewise. * include/ext/random.tcc: Likewise. * include/ext/rb_tree: Likewise. * include/ext/rc_string_base.h: Likewise. * include/ext/rope: Likewise. * include/ext/ropeimpl.h: Likewise. * include/ext/slist: Likewise. * include/ext/sso_string_base.h: Likewise. * include/ext/stdio_filebuf.h: Likewise. * include/ext/stdio_sync_filebuf.h: Likewise. * include/ext/string_conversions.h: Likewise. * include/ext/throw_allocator.h: Likewise. * include/ext/vstring.h: Likewise. * include/ext/vstring.tcc: Likewise. * include/ext/vstring_fwd.h: Likewise. * include/ext/vstring_util.h: Likewise. * include/std/charconv: Likewise. (__cpp_lib_to_chars): Do not define for freestanding. * include/std/version: Adjust which macros get defined in freestanding. * include/ext/pointer.h [!_GLIBCXX_HOSTED]: Omit iostream functionality from freestanding. * include/std/algorithm [!_GLIBCXX_HOSTED]: Omit PSTL algos. * include/std/memory [!_GLIBCXX_HOSTED]: Omit <bits/stl_tempbuf.h> in freestanding * include/bits/algorithmfwd.h [!_GLIBCXX_HOSTED]: Omit leftover random_shuffle and stable_partition definition. * include/bits/stl_algo.h [!_GLIBCXX_HOSTED]: Omit random_shuffle and stable_partition from freestanding. * include/bits/ranges_algo.h [!_GLIBCXX_HOSTED]: Omit stable_partition from freestanding. * include/bits/concept_check.h: Remove needless HOSTED check. * include/std/iterator: Include <bits/ranges_base.h>. * include/std/numeric (__cpp_lib_parallel_algorithms): Do not define for freestanding. * include/std/functional (__cpp_lib_boyer_moore_searcher): Likewise. * testsuite/lib/prune.exp: Match error for hosted-only libstdc++ tests.
455 lines
12 KiB
C++
455 lines
12 KiB
C++
// Streams based on std::span -*- C++ -*-
|
|
|
|
// Copyright The GNU Toolchain Authors.
|
|
//
|
|
// This file is part of the GNU ISO C++ Library. This library is free
|
|
// software; you can redistribute it and/or modify it under the
|
|
// terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 3, or (at your option)
|
|
// any later version.
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// Under Section 7 of GPL version 3, you are granted additional
|
|
// permissions described in the GCC Runtime Library Exception, version
|
|
// 3.1, as published by the Free Software Foundation.
|
|
|
|
// You should have received a copy of the GNU General Public License and
|
|
// a copy of the GCC Runtime Library Exception along with this program;
|
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
/** @file spanstream
|
|
* This is a Standard C++ Library header.
|
|
*/
|
|
|
|
#ifndef _GLIBCXX_SPANSTREAM
|
|
#define _GLIBCXX_SPANSTREAM 1
|
|
|
|
#pragma GCC system_header
|
|
|
|
#include <bits/requires_hosted.h> // iostreams
|
|
|
|
#if __cplusplus > 202002L
|
|
#include <span>
|
|
#include <streambuf>
|
|
#include <istream>
|
|
#include <ostream>
|
|
#include <bits/ranges_base.h>
|
|
|
|
#if __cpp_lib_span
|
|
namespace std _GLIBCXX_VISIBILITY(default)
|
|
{
|
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|
|
|
#define __cpp_lib_spanstream 202106L
|
|
|
|
template<typename _CharT, typename _Traits>
|
|
class basic_spanbuf
|
|
: public basic_streambuf<_CharT, _Traits>
|
|
{
|
|
using __streambuf_type = 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.ctor], constructors
|
|
basic_spanbuf() : basic_spanbuf(ios_base::in | ios_base::out)
|
|
{ }
|
|
|
|
explicit
|
|
basic_spanbuf(ios_base::openmode __which)
|
|
: __streambuf_type(), _M_mode(__which)
|
|
{ }
|
|
|
|
explicit
|
|
basic_spanbuf(std::span<_CharT> __s,
|
|
ios_base::openmode __which = ios_base::in | ios_base::out)
|
|
: __streambuf_type(), _M_mode(__which)
|
|
{ span(__s); }
|
|
|
|
basic_spanbuf(const basic_spanbuf&) = delete;
|
|
|
|
/** Move constructor.
|
|
*
|
|
* Transfers the buffer and pointers into the get and put areas from
|
|
* `__rhs` to `*this`.
|
|
*
|
|
* In this implementation `rhs` is left unchanged,
|
|
* but that is not guaranteed by the standard.
|
|
*/
|
|
basic_spanbuf(basic_spanbuf&& __rhs)
|
|
: __streambuf_type(__rhs), _M_mode(__rhs._M_mode), _M_buf(__rhs._M_buf)
|
|
{ }
|
|
|
|
// [spanbuf.assign], assignment and swap
|
|
basic_spanbuf& operator=(const basic_spanbuf&) = delete;
|
|
|
|
basic_spanbuf&
|
|
operator=(basic_spanbuf&& __rhs)
|
|
{
|
|
basic_spanbuf(std::move(__rhs)).swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
void
|
|
swap(basic_spanbuf& __rhs)
|
|
{
|
|
__streambuf_type::swap(__rhs);
|
|
std::swap(_M_mode, __rhs._M_mode);
|
|
std::swap(_M_buf, __rhs._M_buf);
|
|
}
|
|
|
|
// [spanbuf.members], member functions
|
|
std::span<_CharT>
|
|
span() const noexcept
|
|
{
|
|
if (_M_mode & ios_base::out)
|
|
return {this->pbase(), this->pptr()};
|
|
else
|
|
return _M_buf;
|
|
}
|
|
|
|
void
|
|
span(std::span<_CharT> __s) noexcept
|
|
{
|
|
_M_buf = __s;
|
|
if (_M_mode & ios_base::out)
|
|
{
|
|
this->setp(__s.data(), __s.data() + __s.size());
|
|
if (_M_mode & ios_base::ate)
|
|
this->pbump(__s.size());
|
|
}
|
|
if (_M_mode & ios_base::in)
|
|
this->setg(__s.data(), __s.data(), __s.data() + __s.size());
|
|
}
|
|
|
|
protected:
|
|
// [spanbuf.virtuals], overridden virtual functions
|
|
basic_streambuf<_CharT, _Traits>*
|
|
setbuf(_CharT* __s, streamsize __n) override
|
|
{
|
|
span({__s, __n});
|
|
return this;
|
|
}
|
|
|
|
pos_type
|
|
seekoff(off_type __off, ios_base::seekdir __way,
|
|
ios_base::openmode __which = ios_base::in | ios_base::out) override
|
|
{
|
|
pos_type __ret = pos_type(off_type(-1));
|
|
|
|
if (__way == ios_base::beg)
|
|
{
|
|
if (0 <= __off && __off <= _M_buf.size())
|
|
{
|
|
if (__which & ios_base::in)
|
|
this->setg(this->eback(), this->eback() + __off, this->egptr());
|
|
|
|
if (__which & ios_base::out)
|
|
{
|
|
this->setp(this->pbase(), this->epptr());
|
|
this->pbump(__off);
|
|
}
|
|
|
|
__ret = pos_type(__off);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
off_type __base;
|
|
__which &= (ios_base::in|ios_base::out);
|
|
|
|
if (__which == ios_base::out)
|
|
__base = this->pptr() - this->pbase();
|
|
else if (__way == ios_base::cur)
|
|
{
|
|
if (__which == ios_base::in)
|
|
__base = this->gptr() - this->eback();
|
|
else
|
|
return __ret;
|
|
}
|
|
else if (__way == ios_base::end)
|
|
__base = _M_buf.size();
|
|
|
|
if (__builtin_add_overflow(__base, __off, &__off))
|
|
return __ret;
|
|
|
|
if (__off < 0 || __off > _M_buf.size())
|
|
return __ret;
|
|
|
|
if (__which & ios_base::in)
|
|
this->setg(this->eback(), this->eback() + __off, this->egptr());
|
|
|
|
if (__which & ios_base::out)
|
|
{
|
|
this->setp(this->pbase(), this->epptr());
|
|
this->pbump(__off);
|
|
}
|
|
|
|
__ret = pos_type(__off);
|
|
|
|
}
|
|
return __ret;
|
|
}
|
|
|
|
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 _M_mode;
|
|
std::span<_CharT> _M_buf;
|
|
};
|
|
|
|
template<typename _CharT, typename _Traits>
|
|
inline void
|
|
swap(basic_spanbuf<_CharT, _Traits>& __x,
|
|
basic_spanbuf<_CharT, _Traits>& __y)
|
|
{ __x.swap(__y); }
|
|
|
|
using spanbuf = basic_spanbuf<char>;
|
|
using wspanbuf = basic_spanbuf<wchar_t>;
|
|
|
|
template<typename _CharT, typename _Traits>
|
|
class basic_ispanstream
|
|
: public basic_istream<_CharT, _Traits>
|
|
{
|
|
using __istream_type = 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.ctor], constructors
|
|
explicit
|
|
basic_ispanstream(std::span<_CharT> __s,
|
|
ios_base::openmode __which = ios_base::in)
|
|
: __istream_type(std::__addressof(_M_sb)),
|
|
_M_sb(__s, __which | ios_base::in)
|
|
{ }
|
|
|
|
basic_ispanstream(const basic_ispanstream&) = delete;
|
|
|
|
basic_ispanstream(basic_ispanstream&& __rhs)
|
|
: __istream_type(std::move(__rhs)), _M_sb(std::move(__rhs._M_sb))
|
|
{
|
|
__istream_type::set_rdbuf(std::addressof(_M_sb));
|
|
}
|
|
|
|
template<typename _Ros>
|
|
requires ranges::borrowed_range<_Ros>
|
|
&& (!convertible_to<_Ros, std::span<_CharT>>)
|
|
&& convertible_to<_Ros, std::span<const _CharT>>
|
|
explicit
|
|
basic_ispanstream(_Ros&& __s)
|
|
: __istream_type(std::__addressof(_M_sb)),
|
|
_M_sb(ios_base::in)
|
|
{
|
|
std::span<const _CharT> __sp(std::forward<_Ros>(__s));
|
|
_M_sb.span({const_cast<_CharT*>(__sp.data()), __sp.size()});
|
|
}
|
|
|
|
// [ispanstream.assign], assignment and swap
|
|
basic_ispanstream& operator=(const basic_ispanstream&) = delete;
|
|
basic_ispanstream& operator=(basic_ispanstream&& __rhs) = default;
|
|
|
|
void
|
|
swap(basic_ispanstream& __rhs)
|
|
{
|
|
__istream_type::swap(__rhs);
|
|
_M_sb.swap(__rhs._M_sb);
|
|
}
|
|
|
|
// [ispanstream.members], member functions
|
|
basic_spanbuf<_CharT, _Traits>*
|
|
rdbuf() const noexcept
|
|
{
|
|
return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb));
|
|
}
|
|
|
|
std::span<const _CharT>
|
|
span() const noexcept
|
|
{ return _M_sb.span(); }
|
|
|
|
void
|
|
span(std::span<_CharT> __s) noexcept
|
|
{ return _M_sb.span(__s); }
|
|
|
|
template<typename _Ros>
|
|
requires ranges::borrowed_range<_Ros>
|
|
&& (!convertible_to<_Ros, std::span<_CharT>>)
|
|
&& convertible_to<_Ros, std::span<const _CharT>>
|
|
void
|
|
span(_Ros&& __s) noexcept
|
|
{
|
|
std::span<const _CharT> __sp(std::forward<_Ros>(__s));
|
|
_M_sb.span({const_cast<_CharT*>(__sp.data()), __sp.size()});
|
|
}
|
|
|
|
private:
|
|
basic_spanbuf<_CharT, _Traits> _M_sb;
|
|
};
|
|
|
|
template<typename _CharT, typename _Traits>
|
|
inline void
|
|
swap(basic_ispanstream<_CharT, _Traits>& __x,
|
|
basic_ispanstream<_CharT, _Traits>& __y)
|
|
{ __x.swap(__y); }
|
|
|
|
using ispanstream = basic_ispanstream<char>;
|
|
using wispanstream = basic_ispanstream<wchar_t>;
|
|
|
|
template<typename _CharT, typename _Traits>
|
|
class basic_ospanstream
|
|
: public basic_ostream<_CharT, _Traits>
|
|
{
|
|
using __ostream_type = 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.ctor], constructors
|
|
explicit
|
|
basic_ospanstream(std::span<_CharT> __s,
|
|
ios_base::openmode __which = ios_base::out)
|
|
: __ostream_type(std::__addressof(_M_sb)),
|
|
_M_sb(__s, __which | ios_base::in)
|
|
{ }
|
|
|
|
basic_ospanstream(const basic_ospanstream&) = delete;
|
|
|
|
basic_ospanstream(basic_ospanstream&& __rhs)
|
|
: __ostream_type(std::move(__rhs)), _M_sb(std::move(__rhs._M_sb))
|
|
{
|
|
__ostream_type::set_rdbuf(std::addressof(_M_sb));
|
|
}
|
|
|
|
// [ospanstream.assign], assignment and swap
|
|
basic_ospanstream& operator=(const basic_ospanstream&) = delete;
|
|
basic_ospanstream& operator=(basic_ospanstream&& __rhs) = default;
|
|
|
|
void
|
|
swap(basic_ospanstream& __rhs)
|
|
{
|
|
__ostream_type::swap(__rhs);
|
|
_M_sb.swap(__rhs._M_sb);
|
|
}
|
|
|
|
// [ospanstream.members], member functions
|
|
basic_spanbuf<_CharT, _Traits>*
|
|
rdbuf() const noexcept
|
|
{
|
|
return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb));
|
|
}
|
|
|
|
std::span<_CharT>
|
|
span() const noexcept
|
|
{ return _M_sb.span(); }
|
|
|
|
void
|
|
span(std::span<_CharT> __s) noexcept
|
|
{ return _M_sb.span(__s); }
|
|
|
|
private:
|
|
basic_spanbuf<_CharT, _Traits> _M_sb;
|
|
};
|
|
|
|
template<typename _CharT, typename _Traits>
|
|
inline void
|
|
swap(basic_ospanstream<_CharT, _Traits>& __x,
|
|
basic_ospanstream<_CharT, _Traits>& __y)
|
|
{ __x.swap(__y); }
|
|
|
|
using ospanstream = basic_ospanstream<char>;
|
|
using wospanstream = basic_ospanstream<wchar_t>;
|
|
|
|
template<typename _CharT, typename _Traits>
|
|
class basic_spanstream
|
|
: public basic_iostream<_CharT, _Traits>
|
|
{
|
|
using __iostream_type = 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.ctor], constructors
|
|
explicit
|
|
basic_spanstream(std::span<_CharT> __s,
|
|
ios_base::openmode __which = ios_base::out | ios_base::in)
|
|
: __iostream_type(std::__addressof(_M_sb)),
|
|
_M_sb(__s, __which)
|
|
{ }
|
|
|
|
basic_spanstream(const basic_spanstream&) = delete;
|
|
|
|
basic_spanstream(basic_spanstream&& __rhs)
|
|
: __iostream_type(std::move(__rhs)), _M_sb(std::move(__rhs._M_sb))
|
|
{
|
|
__iostream_type::set_rdbuf(std::addressof(_M_sb));
|
|
}
|
|
|
|
// [spanstream.assign], assignment and swap
|
|
basic_spanstream& operator=(const basic_spanstream&) = delete;
|
|
basic_spanstream& operator=(basic_spanstream&& __rhs) = default;
|
|
|
|
void
|
|
swap(basic_spanstream& __rhs)
|
|
{
|
|
__iostream_type::swap(__rhs);
|
|
_M_sb.swap(__rhs._M_sb);
|
|
}
|
|
|
|
// [spanstream.members], members
|
|
basic_spanbuf<_CharT, _Traits>*
|
|
rdbuf() const noexcept
|
|
{
|
|
return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb));
|
|
}
|
|
|
|
std::span<_CharT>
|
|
span() const noexcept
|
|
{ return _M_sb.span(); }
|
|
|
|
void
|
|
span(std::span<_CharT> __s) noexcept
|
|
{ return _M_sb.span(__s); }
|
|
|
|
private:
|
|
basic_spanbuf<_CharT, _Traits> _M_sb;
|
|
};
|
|
|
|
template<typename _CharT, typename _Traits>
|
|
inline void
|
|
swap(basic_spanstream<_CharT, _Traits>& __x,
|
|
basic_spanstream<_CharT, _Traits>& __y)
|
|
{ __x.swap(__y); }
|
|
|
|
using spanstream = basic_spanstream<char>;
|
|
using wspanstream = basic_spanstream<wchar_t>;
|
|
|
|
_GLIBCXX_END_NAMESPACE_VERSION
|
|
} // namespace std
|
|
#endif // __cpp_lib_span
|
|
#endif // C++23
|
|
#endif // _GLIBCXX_SPANSTREAM
|