// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_STREAMBUF
#define _LIBCPP_STREAMBUF

/*
    streambuf synopsis

namespace std
{

template <class charT, class traits = char_traits<charT> >
class basic_streambuf
{
public:
    // types:
    typedef charT char_type;
    typedef traits traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::off_type off_type;

    virtual ~basic_streambuf();

    // 27.6.2.2.1 locales:
    locale pubimbue(const locale& loc);
    locale getloc() const;

    // 27.6.2.2.2 buffer and positioning:
    basic_streambuf* pubsetbuf(char_type* s, streamsize n);
    pos_type pubseekoff(off_type off, ios_base::seekdir way,
                        ios_base::openmode which = ios_base::in | ios_base::out);
    pos_type pubseekpos(pos_type sp,
                        ios_base::openmode which = ios_base::in | ios_base::out);
    int pubsync();

    // Get and put areas:
    // 27.6.2.2.3 Get area:
    streamsize in_avail();
    int_type snextc();
    int_type sbumpc();
    int_type sgetc();
    streamsize sgetn(char_type* s, streamsize n);

    // 27.6.2.2.4 Putback:
    int_type sputbackc(char_type c);
    int_type sungetc();

    // 27.6.2.2.5 Put area:
    int_type sputc(char_type c);
    streamsize sputn(const char_type* s, streamsize n);

protected:
    basic_streambuf();
    basic_streambuf(const basic_streambuf& rhs);
    basic_streambuf& operator=(const basic_streambuf& rhs);
    void swap(basic_streambuf& rhs);

    // 27.6.2.3.2 Get area:
    char_type* eback() const;
    char_type* gptr() const;
    char_type* egptr() const;
    void gbump(int n);
    void setg(char_type* gbeg, char_type* gnext, char_type* gend);

    // 27.6.2.3.3 Put area:
    char_type* pbase() const;
    char_type* pptr() const;
    char_type* epptr() const;
    void pbump(int n);
    void setp(char_type* pbeg, char_type* pend);

    // 27.6.2.4 virtual functions:
    // 27.6.2.4.1 Locales:
    virtual void imbue(const locale& loc);

    // 27.6.2.4.2 Buffer management and positioning:
    virtual basic_streambuf* setbuf(char_type* s, streamsize n);
    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
                             ios_base::openmode which = ios_base::in | ios_base::out);
    virtual pos_type seekpos(pos_type sp,
                             ios_base::openmode which = ios_base::in | ios_base::out);
    virtual int sync();

    // 27.6.2.4.3 Get area:
    virtual streamsize showmanyc();
    virtual streamsize xsgetn(char_type* s, streamsize n);
    virtual int_type underflow();
    virtual int_type uflow();

    // 27.6.2.4.4 Putback:
    virtual int_type pbackfail(int_type c = traits_type::eof());

    // 27.6.2.4.5 Put area:
    virtual streamsize xsputn(const char_type* s, streamsize n);
    virtual int_type overflow (int_type c = traits_type::eof());
};

}  // std

*/

#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
#  include <__cxx03/streambuf>
#else
#  include <__config>

#  if _LIBCPP_HAS_LOCALIZATION

#    include <__assert>
#    include <__fwd/streambuf.h>
#    include <__locale>
#    include <__type_traits/is_same.h>
#    include <__utility/is_valid_range.h>
#    include <__utility/scope_guard.h>
#    include <climits>
#    include <ios>
#    include <iosfwd>
#    include <version>

#    if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#      pragma GCC system_header
#    endif

_LIBCPP_PUSH_MACROS
#    include <__undef_macros>

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _CharT, class _Traits>
class basic_streambuf {
public:
  // types:
  typedef _CharT char_type;
  typedef _Traits traits_type;
  typedef typename traits_type::int_type int_type;
  typedef typename traits_type::pos_type pos_type;
  typedef typename traits_type::off_type off_type;

  static_assert(is_same<_CharT, typename traits_type::char_type>::value,
                "traits_type::char_type must be the same type as CharT");

  virtual ~basic_streambuf() {}

  // 27.6.2.2.1 locales:
  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale pubimbue(const locale& __loc) {
    imbue(__loc);
    locale __r = __loc_;
    __loc_     = __loc;
    return __r;
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale getloc() const { return __loc_; }

  // 27.6.2.2.2 buffer and positioning:
  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) {
    return setbuf(__s, __n);
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type
  pubseekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which = ios_base::in | ios_base::out) {
    return seekoff(__off, __way, __which);
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type
  pubseekpos(pos_type __sp, ios_base::openmode __which = ios_base::in | ios_base::out) {
    return seekpos(__sp, __which);
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int pubsync() { return sync(); }

  // Get and put areas:
  // 27.6.2.2.3 Get area:
  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize in_avail() {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    if (gptr() < egptr())
      return static_cast<streamsize>(egptr() - gptr());
    return showmanyc();
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type snextc() {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    if (sbumpc() == traits_type::eof())
      return traits_type::eof();
    return sgetc();
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sbumpc() {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    if (gptr() == egptr())
      return uflow();
    int_type __c = traits_type::to_int_type(*gptr());
    this->gbump(1);
    return __c;
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sgetc() {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    if (gptr() == egptr())
      return underflow();
    return traits_type::to_int_type(*gptr());
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize sgetn(char_type* __s, streamsize __n) { return xsgetn(__s, __n); }

  // 27.6.2.2.4 Putback:
  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputbackc(char_type __c) {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    if (eback() == gptr() || !traits_type::eq(__c, *(gptr() - 1)))
      return pbackfail(traits_type::to_int_type(__c));
    this->gbump(-1);
    return traits_type::to_int_type(*gptr());
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sungetc() {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    if (eback() == gptr())
      return pbackfail();
    this->gbump(-1);
    return traits_type::to_int_type(*gptr());
  }

  // 27.6.2.2.5 Put area:
  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputc(char_type __c) {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    if (pptr() == epptr())
      return overflow(traits_type::to_int_type(__c));
    *pptr() = __c;
    this->pbump(1);
    return traits_type::to_int_type(__c);
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize sputn(const char_type* __s, streamsize __n) {
    return xsputn(__s, __n);
  }

protected:
  basic_streambuf() {}
  basic_streambuf(const basic_streambuf& __sb)
      : __loc_(__sb.__loc_),
        __binp_(__sb.__binp_),
        __ninp_(__sb.__ninp_),
        __einp_(__sb.__einp_),
        __bout_(__sb.__bout_),
        __nout_(__sb.__nout_),
        __eout_(__sb.__eout_) {}

  basic_streambuf& operator=(const basic_streambuf& __sb) {
    __loc_  = __sb.__loc_;
    __binp_ = __sb.__binp_;
    __ninp_ = __sb.__ninp_;
    __einp_ = __sb.__einp_;
    __bout_ = __sb.__bout_;
    __nout_ = __sb.__nout_;
    __eout_ = __sb.__eout_;
    return *this;
  }

  void swap(basic_streambuf& __sb) {
    std::swap(__loc_, __sb.__loc_);
    std::swap(__binp_, __sb.__binp_);
    std::swap(__ninp_, __sb.__ninp_);
    std::swap(__einp_, __sb.__einp_);
    std::swap(__bout_, __sb.__bout_);
    std::swap(__nout_, __sb.__nout_);
    std::swap(__eout_, __sb.__eout_);
  }

  // 27.6.2.3.2 Get area:
  _LIBCPP_HIDE_FROM_ABI char_type* eback() const { return __binp_; }
  _LIBCPP_HIDE_FROM_ABI char_type* gptr() const { return __ninp_; }
  _LIBCPP_HIDE_FROM_ABI char_type* egptr() const { return __einp_; }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void gbump(int __n) { __ninp_ += __n; }

  // gbump takes an int, so it might not be able to represent the offset we want to add.
  _LIBCPP_HIDE_FROM_ABI void __gbump_ptrdiff(ptrdiff_t __n) { __ninp_ += __n; }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) {
    _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__gbeg, __gnext), "[gbeg, gnext) must be a valid range");
    _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__gbeg, __gend), "[gbeg, gend) must be a valid range");
    _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__gnext, __gend), "[gnext, gend) must be a valid range");
    __binp_ = __gbeg;
    __ninp_ = __gnext;
    __einp_ = __gend;
  }

  // 27.6.2.3.3 Put area:
  _LIBCPP_HIDE_FROM_ABI char_type* pbase() const { return __bout_; }
  _LIBCPP_HIDE_FROM_ABI char_type* pptr() const { return __nout_; }
  _LIBCPP_HIDE_FROM_ABI char_type* epptr() const { return __eout_; }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void pbump(int __n) { __nout_ += __n; }

  _LIBCPP_HIDE_FROM_ABI void __pbump(streamsize __n) { __nout_ += __n; }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void setp(char_type* __pbeg, char_type* __pend) {
    _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__pbeg, __pend), "[pbeg, pend) must be a valid range");
    __bout_ = __nout_ = __pbeg;
    __eout_           = __pend;
  }

  // 27.6.2.4 virtual functions:
  // 27.6.2.4.1 Locales:
  virtual void imbue(const locale&) {}

  // 27.6.2.4.2 Buffer management and positioning:
  virtual basic_streambuf* setbuf(char_type*, streamsize) { return this; }
  virtual pos_type seekoff(off_type, ios_base::seekdir, ios_base::openmode = ios_base::in | ios_base::out) {
    return pos_type(off_type(-1));
  }
  virtual pos_type seekpos(pos_type, ios_base::openmode = ios_base::in | ios_base::out) {
    return pos_type(off_type(-1));
  }
  virtual int sync() { return 0; }

  // 27.6.2.4.3 Get area:
  virtual streamsize showmanyc() { return 0; }

  virtual streamsize xsgetn(char_type* __s, streamsize __n) {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    int_type __c;
    streamsize __i = 0;
    while (__i < __n) {
      if (gptr() < egptr()) {
        const streamsize __len = std::min(static_cast<streamsize>(INT_MAX), std::min(egptr() - gptr(), __n - __i));
        traits_type::copy(__s, gptr(), __len);
        __s += __len;
        __i += __len;
        this->gbump(__len);
      } else if ((__c = uflow()) != traits_type::eof()) {
        *__s = traits_type::to_char_type(__c);
        ++__s;
        ++__i;
      } else
        break;
    }
    return __i;
  }

  virtual int_type underflow() { return traits_type::eof(); }
  virtual int_type uflow() {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    if (underflow() == traits_type::eof())
      return traits_type::eof();
    int_type __c = traits_type::to_int_type(*gptr());
    this->gbump(1);
    return __c;
  }

  // 27.6.2.4.4 Putback:
  virtual int_type pbackfail(int_type = traits_type::eof()) { return traits_type::eof(); }

  // 27.6.2.4.5 Put area:
  virtual streamsize xsputn(const char_type* __s, streamsize __n) {
    __check_invariants();
    auto __guard = std::__make_scope_guard([this] { this->__check_invariants(); });

    streamsize __i = 0;
    while (__i < __n) {
      if (pptr() >= epptr()) {
        if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof())
          break;
        ++__s;
        ++__i;
      } else {
        streamsize __chunk_size = std::min(epptr() - pptr(), __n - __i);
        traits_type::copy(pptr(), __s, __chunk_size);
        __pbump(__chunk_size);
        __s += __chunk_size;
        __i += __chunk_size;
      }
    }
    return __i;
  }

  virtual int_type overflow(int_type = traits_type::eof()) { return traits_type::eof(); }

  // This function checks some invariants of the class (it isn't exhaustive).
  _LIBCPP_HIDE_FROM_ABI void __check_invariants() const {
    _LIBCPP_ASSERT_INTERNAL(pbase() <= pptr(), "this is an invariant of the class");
    _LIBCPP_ASSERT_INTERNAL(pptr() <= epptr(), "this is an invariant of the class");

    _LIBCPP_ASSERT_INTERNAL(eback() <= gptr(), "this is an invariant of the class");
    _LIBCPP_ASSERT_INTERNAL(gptr() <= egptr(), "this is an invariant of the class");
  }

private:
  locale __loc_;
  char_type* __binp_ = nullptr;
  char_type* __ninp_ = nullptr;
  char_type* __einp_ = nullptr;
  char_type* __bout_ = nullptr;
  char_type* __nout_ = nullptr;
  char_type* __eout_ = nullptr;

  template <class _CharT2, class _Traits2, class _Allocator>
  _LIBCPP_HIDE_FROM_ABI friend basic_istream<_CharT2, _Traits2>&
  getline(basic_istream<_CharT2, _Traits2>&, basic_string<_CharT2, _Traits2, _Allocator>&, _CharT2);
};

extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>;

#    if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>;
#    endif

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#  endif // _LIBCPP_HAS_LOCALIZATION

#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#    include <cstdint>
#    include <optional>
#  endif
#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif // _LIBCPP_STREAMBUF
