123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- // 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
- #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
|