// 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/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>;
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
    [[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>;
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
    [[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>;
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
    [[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>;
using wspanstream = basic_spanstream<wchar_t>;

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