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

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <bits/requires_hosted.h> // iostreams

#define __glibcxx_want_spanstream
#include <bits/version.h>

#ifdef __cpp_lib_spanstream // C++ >= 23 && hosted && lib_span
#include <span>
#include <streambuf>
#include <istream>
#include <ostream>
#include <bits/iosfwd_span.h>
#include <bits/ranges_base.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

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
    [[nodiscard]]
    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
    {
      __glibcxx_assert(__n >= 0);
      this->span(std::span<_CharT>(__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 && (size_t)__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();
	  else /* way is not ios::beg, ios::cur, or ios::end */ [[unlikely]]
	    return __ret;

	  if (__builtin_add_overflow(__base, __off, &__off)) [[unlikely]]
	    return __ret;

	  if (__off < 0 || (size_t)__off > _M_buf.size()) [[unlikely]]
	    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>;
#ifdef _GLIBCXX_USE_WCHAR_T
using wspanbuf = basic_spanbuf<wchar_t>;
#endif

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
    [[nodiscard]]
    basic_spanbuf<_CharT, _Traits>*
    rdbuf() const noexcept
    {
      return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb));
    }

    [[nodiscard]]
    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>;
#ifdef _GLIBCXX_USE_WCHAR_T
using wispanstream = basic_ispanstream<wchar_t>;
#endif

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
    [[nodiscard]]
    basic_spanbuf<_CharT, _Traits>*
    rdbuf() const noexcept
    {
      return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb));
    }

    [[nodiscard]]
    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>;
#ifdef _GLIBCXX_USE_WCHAR_T
using wospanstream = basic_ospanstream<wchar_t>;
#endif

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
    [[nodiscard]]
    basic_spanbuf<_CharT, _Traits>*
    rdbuf() const noexcept
    {
      return const_cast<basic_spanbuf<_CharT, _Traits>*>(std::__addressof(_M_sb));
    }

    [[nodiscard]]
    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>;
#ifdef _GLIBCXX_USE_WCHAR_T
using wspanstream = basic_spanstream<wchar_t>;
#endif

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __cpp_lib_spanstream
#endif // _GLIBCXX_SPANSTREAM
