xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/spanstream (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1b1e83836Smrg// Streams based on std::span -*- C++ -*-
2b1e83836Smrg
3b1e83836Smrg// Copyright The GNU Toolchain Authors.
4b1e83836Smrg//
5b1e83836Smrg// This file is part of the GNU ISO C++ Library.  This library is free
6b1e83836Smrg// software; you can redistribute it and/or modify it under the
7b1e83836Smrg// terms of the GNU General Public License as published by the
8b1e83836Smrg// Free Software Foundation; either version 3, or (at your option)
9b1e83836Smrg// any later version.
10b1e83836Smrg
11b1e83836Smrg// This library is distributed in the hope that it will be useful,
12b1e83836Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
13b1e83836Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14b1e83836Smrg// GNU General Public License for more details.
15b1e83836Smrg
16b1e83836Smrg// Under Section 7 of GPL version 3, you are granted additional
17b1e83836Smrg// permissions described in the GCC Runtime Library Exception, version
18b1e83836Smrg// 3.1, as published by the Free Software Foundation.
19b1e83836Smrg
20b1e83836Smrg// You should have received a copy of the GNU General Public License and
21b1e83836Smrg// a copy of the GCC Runtime Library Exception along with this program;
22b1e83836Smrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23b1e83836Smrg// <http://www.gnu.org/licenses/>.
24b1e83836Smrg
25b1e83836Smrg/** @file spanstream
26b1e83836Smrg *  This is a Standard C++ Library header.
27b1e83836Smrg */
28b1e83836Smrg
29b1e83836Smrg#ifndef _GLIBCXX_SPANSTREAM
30b1e83836Smrg#define _GLIBCXX_SPANSTREAM 1
31b1e83836Smrg
32b1e83836Smrg#pragma GCC system_header
33b1e83836Smrg
34b1e83836Smrg#if __cplusplus > 202002L
35b1e83836Smrg#include <span>
36b1e83836Smrg#include <streambuf>
37b1e83836Smrg#include <istream>
38b1e83836Smrg#include <ostream>
39b1e83836Smrg#include <bits/ranges_base.h>
40b1e83836Smrg
41b1e83836Smrg#if __cpp_lib_span
42b1e83836Smrgnamespace std _GLIBCXX_VISIBILITY(default)
43b1e83836Smrg{
44b1e83836Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
45b1e83836Smrg
46b1e83836Smrg#define __cpp_lib_spanstream 202106L
47b1e83836Smrg
48b1e83836Smrgtemplate<typename _CharT, typename _Traits>
49b1e83836Smrg  class basic_spanbuf
50b1e83836Smrg  : public basic_streambuf<_CharT, _Traits>
51b1e83836Smrg  {
52b1e83836Smrg    using __streambuf_type = basic_streambuf<_CharT, _Traits>;
53b1e83836Smrg
54b1e83836Smrg  public:
55b1e83836Smrg    using char_type   = _CharT;
56b1e83836Smrg    using int_type    = typename _Traits::int_type;
57b1e83836Smrg    using pos_type    = typename _Traits::pos_type;
58b1e83836Smrg    using off_type    = typename _Traits::off_type;
59b1e83836Smrg    using traits_type = _Traits;
60b1e83836Smrg
61b1e83836Smrg    // [spanbuf.ctor], constructors
62b1e83836Smrg    basic_spanbuf() : basic_spanbuf(ios_base::in | ios_base::out)
63b1e83836Smrg    { }
64b1e83836Smrg
65b1e83836Smrg    explicit
66b1e83836Smrg    basic_spanbuf(ios_base::openmode __which)
67b1e83836Smrg    : __streambuf_type(), _M_mode(__which)
68b1e83836Smrg    { }
69b1e83836Smrg
70b1e83836Smrg    explicit
71b1e83836Smrg    basic_spanbuf(std::span<_CharT> __s,
72b1e83836Smrg		  ios_base::openmode __which = ios_base::in | ios_base::out)
73b1e83836Smrg    : __streambuf_type(), _M_mode(__which)
74b1e83836Smrg    { span(__s); }
75b1e83836Smrg
76b1e83836Smrg    basic_spanbuf(const basic_spanbuf&) = delete;
77b1e83836Smrg
78b1e83836Smrg    /** Move constructor.
79b1e83836Smrg     *
80b1e83836Smrg     * Transfers the buffer and pointers into the get and put areas from
81b1e83836Smrg     * `__rhs` to `*this`.
82b1e83836Smrg     *
83b1e83836Smrg     * In this implementation `rhs` is left unchanged,
84b1e83836Smrg     * but that is not guaranteed by the standard.
85b1e83836Smrg     */
86b1e83836Smrg    basic_spanbuf(basic_spanbuf&& __rhs)
87b1e83836Smrg    : __streambuf_type(__rhs), _M_mode(__rhs._M_mode), _M_buf(__rhs._M_buf)
88b1e83836Smrg    { }
89b1e83836Smrg
90b1e83836Smrg    // [spanbuf.assign], assignment and swap
91b1e83836Smrg    basic_spanbuf& operator=(const basic_spanbuf&) = delete;
92b1e83836Smrg
93b1e83836Smrg    basic_spanbuf&
94b1e83836Smrg    operator=(basic_spanbuf&& __rhs)
95b1e83836Smrg    {
96b1e83836Smrg      basic_spanbuf(std::move(__rhs)).swap(*this);
97b1e83836Smrg      return *this;
98b1e83836Smrg    }
99b1e83836Smrg
100b1e83836Smrg    void
101b1e83836Smrg    swap(basic_spanbuf& __rhs)
102b1e83836Smrg    {
103b1e83836Smrg      __streambuf_type::swap(__rhs);
104b1e83836Smrg      std::swap(_M_mode, __rhs._M_mode);
105b1e83836Smrg      std::swap(_M_buf, __rhs._M_buf);
106b1e83836Smrg    }
107b1e83836Smrg
108b1e83836Smrg    // [spanbuf.members], member functions
109b1e83836Smrg    std::span<_CharT>
110b1e83836Smrg    span() const noexcept
111b1e83836Smrg    {
112b1e83836Smrg      if (_M_mode & ios_base::out)
113b1e83836Smrg	return {this->pbase(), this->pptr()};
114b1e83836Smrg      else
115b1e83836Smrg	return _M_buf;
116b1e83836Smrg    }
117b1e83836Smrg
118b1e83836Smrg    void
119b1e83836Smrg    span(std::span<_CharT> __s) noexcept
120b1e83836Smrg    {
121b1e83836Smrg      _M_buf = __s;
122b1e83836Smrg      if (_M_mode & ios_base::out)
123b1e83836Smrg	{
124b1e83836Smrg	  this->setp(__s.data(), __s.data() + __s.size());
125b1e83836Smrg	  if (_M_mode & ios_base::ate)
126b1e83836Smrg	    this->pbump(__s.size());
127b1e83836Smrg	}
128b1e83836Smrg      if (_M_mode & ios_base::in)
129b1e83836Smrg	this->setg(__s.data(), __s.data(), __s.data() + __s.size());
130b1e83836Smrg    }
131b1e83836Smrg
132b1e83836Smrg  protected:
133b1e83836Smrg    // [spanbuf.virtuals], overridden virtual functions
134b1e83836Smrg    basic_streambuf<_CharT, _Traits>*
135b1e83836Smrg    setbuf(_CharT* __s, streamsize __n) override
136b1e83836Smrg    {
137*0a307195Smrg      __glibcxx_assert(__n >= 0);
138*0a307195Smrg      this->span(std::span<_CharT>(__s, __n));
139b1e83836Smrg      return this;
140b1e83836Smrg    }
141b1e83836Smrg
142b1e83836Smrg    pos_type
143b1e83836Smrg    seekoff(off_type __off, ios_base::seekdir __way,
144b1e83836Smrg	    ios_base::openmode __which = ios_base::in | ios_base::out) override
145b1e83836Smrg    {
146b1e83836Smrg      pos_type __ret =  pos_type(off_type(-1));
147b1e83836Smrg
148b1e83836Smrg      if (__way == ios_base::beg)
149b1e83836Smrg	{
150b1e83836Smrg	  if (0 <= __off && __off <= _M_buf.size())
151b1e83836Smrg	    {
152b1e83836Smrg	      if (__which & ios_base::in)
153b1e83836Smrg		this->setg(this->eback(), this->eback() + __off, this->egptr());
154b1e83836Smrg
155b1e83836Smrg	      if (__which & ios_base::out)
156b1e83836Smrg		{
157b1e83836Smrg		  this->setp(this->pbase(), this->epptr());
158b1e83836Smrg		  this->pbump(__off);
159b1e83836Smrg		}
160b1e83836Smrg
161b1e83836Smrg	      __ret = pos_type(__off);
162b1e83836Smrg	    }
163b1e83836Smrg	}
164b1e83836Smrg      else
165b1e83836Smrg	{
166b1e83836Smrg	  off_type __base;
167b1e83836Smrg	  __which &= (ios_base::in|ios_base::out);
168b1e83836Smrg
169b1e83836Smrg	  if (__which == ios_base::out)
170b1e83836Smrg	    __base = this->pptr() - this->pbase();
171b1e83836Smrg	  else if (__way == ios_base::cur)
172b1e83836Smrg	    {
173b1e83836Smrg	      if (__which == ios_base::in)
174b1e83836Smrg		__base = this->gptr() - this->eback();
175b1e83836Smrg	      else
176b1e83836Smrg		return __ret;
177b1e83836Smrg	    }
178b1e83836Smrg	  else if (__way == ios_base::end)
179b1e83836Smrg	    __base = _M_buf.size();
180b1e83836Smrg
181b1e83836Smrg	  if (__builtin_add_overflow(__base, __off, &__off))
182b1e83836Smrg	    return __ret;
183b1e83836Smrg
184b1e83836Smrg	  if (__off < 0 || __off > _M_buf.size())
185b1e83836Smrg	    return __ret;
186b1e83836Smrg
187b1e83836Smrg	  if (__which & ios_base::in)
188b1e83836Smrg	    this->setg(this->eback(), this->eback() + __off, this->egptr());
189b1e83836Smrg
190b1e83836Smrg	  if (__which & ios_base::out)
191b1e83836Smrg	    {
192b1e83836Smrg	      this->setp(this->pbase(), this->epptr());
193b1e83836Smrg	      this->pbump(__off);
194b1e83836Smrg	    }
195b1e83836Smrg
196b1e83836Smrg	  __ret = pos_type(__off);
197b1e83836Smrg
198b1e83836Smrg	}
199b1e83836Smrg      return __ret;
200b1e83836Smrg    }
201b1e83836Smrg
202b1e83836Smrg    pos_type
203b1e83836Smrg    seekpos(pos_type __sp,
204b1e83836Smrg	    ios_base::openmode __which = ios_base::in | ios_base::out) override
205b1e83836Smrg    { return seekoff(off_type(__sp), ios_base::beg, __which); }
206b1e83836Smrg
207b1e83836Smrg  private:
208b1e83836Smrg
209b1e83836Smrg    ios_base::openmode _M_mode;
210b1e83836Smrg    std::span<_CharT> _M_buf;
211b1e83836Smrg  };
212b1e83836Smrg
213b1e83836Smrgtemplate<typename _CharT, typename _Traits>
214b1e83836Smrg  inline void
215b1e83836Smrg  swap(basic_spanbuf<_CharT, _Traits>& __x,
216b1e83836Smrg       basic_spanbuf<_CharT, _Traits>& __y)
217b1e83836Smrg  { __x.swap(__y); }
218b1e83836Smrg
219b1e83836Smrgusing spanbuf = basic_spanbuf<char>;
220b1e83836Smrgusing wspanbuf = basic_spanbuf<wchar_t>;
221b1e83836Smrg
222b1e83836Smrgtemplate<typename _CharT, typename _Traits>
223b1e83836Smrg  class basic_ispanstream
224b1e83836Smrg  : public basic_istream<_CharT, _Traits>
225b1e83836Smrg  {
226b1e83836Smrg    using __istream_type = basic_istream<_CharT, _Traits>;
227b1e83836Smrg
228b1e83836Smrg  public:
229b1e83836Smrg    using char_type   = _CharT;
230b1e83836Smrg    using int_type    = typename _Traits::int_type;
231b1e83836Smrg    using pos_type    = typename _Traits::pos_type;
232b1e83836Smrg    using off_type    = typename _Traits::off_type;
233b1e83836Smrg    using traits_type = _Traits;
234b1e83836Smrg
235b1e83836Smrg    // [ispanstream.ctor], constructors
236b1e83836Smrg    explicit
237b1e83836Smrg    basic_ispanstream(std::span<_CharT> __s,
238b1e83836Smrg		      ios_base::openmode __which = ios_base::in)
239b1e83836Smrg    : __istream_type(std::__addressof(_M_sb)),
240b1e83836Smrg      _M_sb(__s, __which | ios_base::in)
241b1e83836Smrg    { }
242b1e83836Smrg
243b1e83836Smrg    basic_ispanstream(const basic_ispanstream&) = delete;
244b1e83836Smrg
245b1e83836Smrg    basic_ispanstream(basic_ispanstream&& __rhs)
246b1e83836Smrg    : __istream_type(std::move(__rhs)), _M_sb(std::move(__rhs._M_sb))
247b1e83836Smrg    {
248b1e83836Smrg      __istream_type::set_rdbuf(std::addressof(_M_sb));
249b1e83836Smrg    }
250b1e83836Smrg
251b1e83836Smrg    template<typename _Ros>
252b1e83836Smrg      requires ranges::borrowed_range<_Ros>
253b1e83836Smrg	&& (!convertible_to<_Ros, std::span<_CharT>>)
254b1e83836Smrg	&& convertible_to<_Ros, std::span<const _CharT>>
255b1e83836Smrg      explicit
256b1e83836Smrg      basic_ispanstream(_Ros&& __s)
257b1e83836Smrg      : __istream_type(std::__addressof(_M_sb)),
258b1e83836Smrg	_M_sb(ios_base::in)
259b1e83836Smrg      {
260b1e83836Smrg	std::span<const _CharT> __sp(std::forward<_Ros>(__s));
261b1e83836Smrg	_M_sb.span({const_cast<_CharT*>(__sp.data()), __sp.size()});
262b1e83836Smrg      }
263b1e83836Smrg
264b1e83836Smrg    // [ispanstream.assign], assignment and swap
265b1e83836Smrg    basic_ispanstream& operator=(const basic_ispanstream&) = delete;
266b1e83836Smrg    basic_ispanstream& operator=(basic_ispanstream&& __rhs) = default;
267b1e83836Smrg
268b1e83836Smrg    void
269b1e83836Smrg    swap(basic_ispanstream& __rhs)
270b1e83836Smrg    {
271b1e83836Smrg      __istream_type::swap(__rhs);
272b1e83836Smrg      _M_sb.swap(__rhs._M_sb);
273b1e83836Smrg    }
274b1e83836Smrg
275b1e83836Smrg    // [ispanstream.members], member functions
276b1e83836Smrg    basic_spanbuf<_CharT, _Traits>*
277b1e83836Smrg    rdbuf() const noexcept
278b1e83836Smrg    {
279b1e83836Smrg      return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb));
280b1e83836Smrg    }
281b1e83836Smrg
282b1e83836Smrg    std::span<const _CharT>
283b1e83836Smrg    span() const noexcept
284b1e83836Smrg    { return _M_sb.span(); }
285b1e83836Smrg
286b1e83836Smrg    void
287b1e83836Smrg    span(std::span<_CharT> __s) noexcept
288b1e83836Smrg    { return _M_sb.span(__s); }
289b1e83836Smrg
290b1e83836Smrg    template<typename _Ros>
291b1e83836Smrg      requires ranges::borrowed_range<_Ros>
292b1e83836Smrg	&& (!convertible_to<_Ros, std::span<_CharT>>)
293b1e83836Smrg	&& convertible_to<_Ros, std::span<const _CharT>>
294b1e83836Smrg      void
295b1e83836Smrg      span(_Ros&& __s) noexcept
296b1e83836Smrg      {
297b1e83836Smrg	std::span<const _CharT> __sp(std::forward<_Ros>(__s));
298b1e83836Smrg	_M_sb.span({const_cast<_CharT*>(__sp.data()), __sp.size()});
299b1e83836Smrg      }
300b1e83836Smrg
301b1e83836Smrg  private:
302b1e83836Smrg    basic_spanbuf<_CharT, _Traits> _M_sb;
303b1e83836Smrg  };
304b1e83836Smrg
305b1e83836Smrgtemplate<typename _CharT, typename _Traits>
306b1e83836Smrg  inline void
307b1e83836Smrg  swap(basic_ispanstream<_CharT, _Traits>& __x,
308b1e83836Smrg       basic_ispanstream<_CharT, _Traits>& __y)
309b1e83836Smrg  { __x.swap(__y); }
310b1e83836Smrg
311b1e83836Smrgusing ispanstream = basic_ispanstream<char>;
312b1e83836Smrgusing wispanstream = basic_ispanstream<wchar_t>;
313b1e83836Smrg
314b1e83836Smrgtemplate<typename _CharT, typename _Traits>
315b1e83836Smrg  class basic_ospanstream
316b1e83836Smrg  : public basic_ostream<_CharT, _Traits>
317b1e83836Smrg  {
318b1e83836Smrg    using __ostream_type = basic_ostream<_CharT, _Traits>;
319b1e83836Smrg
320b1e83836Smrg  public:
321b1e83836Smrg    using char_type   = _CharT;
322b1e83836Smrg    using int_type    = typename _Traits::int_type;
323b1e83836Smrg    using pos_type    = typename _Traits::pos_type;
324b1e83836Smrg    using off_type    = typename _Traits::off_type;
325b1e83836Smrg    using traits_type = _Traits;
326b1e83836Smrg
327b1e83836Smrg    // [ospanstream.ctor], constructors
328b1e83836Smrg    explicit
329b1e83836Smrg    basic_ospanstream(std::span<_CharT> __s,
330b1e83836Smrg		      ios_base::openmode __which = ios_base::out)
331b1e83836Smrg    : __ostream_type(std::__addressof(_M_sb)),
332b1e83836Smrg      _M_sb(__s, __which | ios_base::in)
333b1e83836Smrg    { }
334b1e83836Smrg
335b1e83836Smrg    basic_ospanstream(const basic_ospanstream&) = delete;
336b1e83836Smrg
337b1e83836Smrg    basic_ospanstream(basic_ospanstream&& __rhs)
338b1e83836Smrg    : __ostream_type(std::move(__rhs)), _M_sb(std::move(__rhs._M_sb))
339b1e83836Smrg    {
340b1e83836Smrg      __ostream_type::set_rdbuf(std::addressof(_M_sb));
341b1e83836Smrg    }
342b1e83836Smrg
343b1e83836Smrg    // [ospanstream.assign], assignment and swap
344b1e83836Smrg    basic_ospanstream& operator=(const basic_ospanstream&) = delete;
345b1e83836Smrg    basic_ospanstream& operator=(basic_ospanstream&& __rhs) = default;
346b1e83836Smrg
347b1e83836Smrg    void
348b1e83836Smrg    swap(basic_ospanstream& __rhs)
349b1e83836Smrg    {
350b1e83836Smrg      __ostream_type::swap(__rhs);
351b1e83836Smrg      _M_sb.swap(__rhs._M_sb);
352b1e83836Smrg    }
353b1e83836Smrg
354b1e83836Smrg    // [ospanstream.members], member functions
355b1e83836Smrg    basic_spanbuf<_CharT, _Traits>*
356b1e83836Smrg    rdbuf() const noexcept
357b1e83836Smrg    {
358b1e83836Smrg      return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb));
359b1e83836Smrg    }
360b1e83836Smrg
361b1e83836Smrg    std::span<_CharT>
362b1e83836Smrg    span() const noexcept
363b1e83836Smrg    { return _M_sb.span(); }
364b1e83836Smrg
365b1e83836Smrg    void
366b1e83836Smrg    span(std::span<_CharT> __s) noexcept
367b1e83836Smrg    { return _M_sb.span(__s); }
368b1e83836Smrg
369b1e83836Smrg  private:
370b1e83836Smrg    basic_spanbuf<_CharT, _Traits> _M_sb;
371b1e83836Smrg  };
372b1e83836Smrg
373b1e83836Smrgtemplate<typename _CharT, typename _Traits>
374b1e83836Smrg  inline void
375b1e83836Smrg  swap(basic_ospanstream<_CharT, _Traits>& __x,
376b1e83836Smrg       basic_ospanstream<_CharT, _Traits>& __y)
377b1e83836Smrg  { __x.swap(__y); }
378b1e83836Smrg
379b1e83836Smrgusing ospanstream = basic_ospanstream<char>;
380b1e83836Smrgusing wospanstream = basic_ospanstream<wchar_t>;
381b1e83836Smrg
382b1e83836Smrgtemplate<typename _CharT, typename _Traits>
383b1e83836Smrg  class basic_spanstream
384b1e83836Smrg  : public basic_iostream<_CharT, _Traits>
385b1e83836Smrg  {
386b1e83836Smrg    using __iostream_type = basic_iostream<_CharT, _Traits>;
387b1e83836Smrg
388b1e83836Smrg  public:
389b1e83836Smrg    using char_type   = _CharT;
390b1e83836Smrg    using int_type    = typename _Traits::int_type;
391b1e83836Smrg    using pos_type    = typename _Traits::pos_type;
392b1e83836Smrg    using off_type    = typename _Traits::off_type;
393b1e83836Smrg    using traits_type = _Traits;
394b1e83836Smrg
395b1e83836Smrg    // [spanstream.ctor], constructors
396b1e83836Smrg    explicit
397b1e83836Smrg    basic_spanstream(std::span<_CharT> __s,
398b1e83836Smrg		     ios_base::openmode __which = ios_base::out | ios_base::in)
399b1e83836Smrg    : __iostream_type(std::__addressof(_M_sb)),
400b1e83836Smrg      _M_sb(__s, __which)
401b1e83836Smrg    { }
402b1e83836Smrg
403b1e83836Smrg    basic_spanstream(const basic_spanstream&) = delete;
404b1e83836Smrg
405b1e83836Smrg    basic_spanstream(basic_spanstream&& __rhs)
406b1e83836Smrg    : __iostream_type(std::move(__rhs)), _M_sb(std::move(__rhs._M_sb))
407b1e83836Smrg    {
408b1e83836Smrg      __iostream_type::set_rdbuf(std::addressof(_M_sb));
409b1e83836Smrg    }
410b1e83836Smrg
411b1e83836Smrg    // [spanstream.assign], assignment and swap
412b1e83836Smrg    basic_spanstream& operator=(const basic_spanstream&) = delete;
413b1e83836Smrg    basic_spanstream& operator=(basic_spanstream&& __rhs) = default;
414b1e83836Smrg
415b1e83836Smrg    void
416b1e83836Smrg    swap(basic_spanstream& __rhs)
417b1e83836Smrg    {
418b1e83836Smrg      __iostream_type::swap(__rhs);
419b1e83836Smrg      _M_sb.swap(__rhs._M_sb);
420b1e83836Smrg    }
421b1e83836Smrg
422b1e83836Smrg    // [spanstream.members], members
423b1e83836Smrg    basic_spanbuf<_CharT, _Traits>*
424b1e83836Smrg    rdbuf() const noexcept
425b1e83836Smrg    {
426b1e83836Smrg      return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb));
427b1e83836Smrg    }
428b1e83836Smrg
429b1e83836Smrg    std::span<_CharT>
430b1e83836Smrg    span() const noexcept
431b1e83836Smrg    { return _M_sb.span(); }
432b1e83836Smrg
433b1e83836Smrg    void
434b1e83836Smrg    span(std::span<_CharT> __s) noexcept
435b1e83836Smrg    { return _M_sb.span(__s); }
436b1e83836Smrg
437b1e83836Smrg  private:
438b1e83836Smrg    basic_spanbuf<_CharT, _Traits> _M_sb;
439b1e83836Smrg  };
440b1e83836Smrg
441b1e83836Smrgtemplate<typename _CharT, typename _Traits>
442b1e83836Smrg  inline void
443b1e83836Smrg  swap(basic_spanstream<_CharT, _Traits>& __x,
444b1e83836Smrg       basic_spanstream<_CharT, _Traits>& __y)
445b1e83836Smrg  { __x.swap(__y); }
446b1e83836Smrg
447b1e83836Smrgusing spanstream = basic_spanstream<char>;
448b1e83836Smrgusing wspanstream = basic_spanstream<wchar_t>;
449b1e83836Smrg
450b1e83836Smrg_GLIBCXX_END_NAMESPACE_VERSION
451b1e83836Smrg} // namespace std
452b1e83836Smrg#endif // __cpp_lib_span
453b1e83836Smrg#endif // C++23
454b1e83836Smrg#endif // _GLIBCXX_SPANSTREAM
455