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