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