// -*- 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 <__memory/valid_range.h>
#    include <__type_traits/is_same.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_SINCE_LLVM8 locale pubimbue(const locale& __loc) {
    imbue(__loc);
    locale __r = __loc_;
    __loc_     = __loc;
    return __r;
  }

  [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 locale getloc() const { return __loc_; }

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

  inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 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_SINCE_LLVM8 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_SINCE_LLVM8 int pubsync() { return sync(); }

  // Get and put areas:
  // 27.6.2.2.3 Get area:
  [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 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();
  }

  [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 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_SINCE_LLVM8 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;
  }

  [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 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_SINCE_LLVM8 streamsize sgetn(char_type* __s, streamsize __n) { return xsgetn(__s, __n); }

  // 27.6.2.2.4 Putback:
  inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 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_SINCE_LLVM8 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_SINCE_LLVM8 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_SINCE_LLVM8 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_SINCE_LLVM8 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_SINCE_LLVM8 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_SINCE_LLVM8 void pbump(int __n) { __nout_ += __n; }

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

  inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 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
