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

*/

#include <__config>

#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)

#  include <__assert>
#  include <__fwd/streambuf.h>
#  include <__locale>
#  include <__type_traits/is_same.h>
#  include <__utility/is_valid_range.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 _LIBCPP_TEMPLATE_VIS 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() {
    if (__ninp_ < __einp_)
      return static_cast<streamsize>(__einp_ - __ninp_);
    return showmanyc();
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type snextc() {
    if (sbumpc() == traits_type::eof())
      return traits_type::eof();
    return sgetc();
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sbumpc() {
    if (__ninp_ == __einp_)
      return uflow();
    return traits_type::to_int_type(*__ninp_++);
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sgetc() {
    if (__ninp_ == __einp_)
      return underflow();
    return traits_type::to_int_type(*__ninp_);
  }

  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) {
    if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1]))
      return pbackfail(traits_type::to_int_type(__c));
    return traits_type::to_int_type(*--__ninp_);
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sungetc() {
    if (__binp_ == __ninp_)
      return pbackfail();
    return traits_type::to_int_type(*--__ninp_);
  }

  // 27.6.2.2.5 Put area:
  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputc(char_type __c) {
    if (__nout_ == __eout_)
      return overflow(traits_type::to_int_type(__c));
    *__nout_++ = __c;
    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& __rhs);
  basic_streambuf& operator=(const basic_streambuf& __rhs);
  void swap(basic_streambuf& __rhs);

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

  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& __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());

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

template <class _CharT, class _Traits>
basic_streambuf<_CharT, _Traits>::~basic_streambuf() {}

template <class _CharT, class _Traits>
basic_streambuf<_CharT, _Traits>::basic_streambuf()
    : __binp_(nullptr), __ninp_(nullptr), __einp_(nullptr), __bout_(nullptr), __nout_(nullptr), __eout_(nullptr) {}

template <class _CharT, class _Traits>
basic_streambuf<_CharT, _Traits>::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_) {}

template <class _CharT, class _Traits>
basic_streambuf<_CharT, _Traits>& basic_streambuf<_CharT, _Traits>::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;
}

template <class _CharT, class _Traits>
void basic_streambuf<_CharT, _Traits>::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_);
}

template <class _CharT, class _Traits>
void basic_streambuf<_CharT, _Traits>::imbue(const locale&) {}

template <class _CharT, class _Traits>
basic_streambuf<_CharT, _Traits>* basic_streambuf<_CharT, _Traits>::setbuf(char_type*, streamsize) {
  return this;
}

template <class _CharT, class _Traits>
typename basic_streambuf<_CharT, _Traits>::pos_type
basic_streambuf<_CharT, _Traits>::seekoff(off_type, ios_base::seekdir, ios_base::openmode) {
  return pos_type(off_type(-1));
}

template <class _CharT, class _Traits>
typename basic_streambuf<_CharT, _Traits>::pos_type
basic_streambuf<_CharT, _Traits>::seekpos(pos_type, ios_base::openmode) {
  return pos_type(off_type(-1));
}

template <class _CharT, class _Traits>
int basic_streambuf<_CharT, _Traits>::sync() {
  return 0;
}

template <class _CharT, class _Traits>
streamsize basic_streambuf<_CharT, _Traits>::showmanyc() {
  return 0;
}

template <class _CharT, class _Traits>
streamsize basic_streambuf<_CharT, _Traits>::xsgetn(char_type* __s, streamsize __n) {
  const int_type __eof = traits_type::eof();
  int_type __c;
  streamsize __i = 0;
  while (__i < __n) {
    if (__ninp_ < __einp_) {
      const streamsize __len = std::min(static_cast<streamsize>(INT_MAX), std::min(__einp_ - __ninp_, __n - __i));
      traits_type::copy(__s, __ninp_, __len);
      __s += __len;
      __i += __len;
      this->gbump(__len);
    } else if ((__c = uflow()) != __eof) {
      *__s = traits_type::to_char_type(__c);
      ++__s;
      ++__i;
    } else
      break;
  }
  return __i;
}

template <class _CharT, class _Traits>
typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::underflow() {
  return traits_type::eof();
}

template <class _CharT, class _Traits>
typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::uflow() {
  if (underflow() == traits_type::eof())
    return traits_type::eof();
  return traits_type::to_int_type(*__ninp_++);
}

template <class _CharT, class _Traits>
typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::pbackfail(int_type) {
  return traits_type::eof();
}

template <class _CharT, class _Traits>
streamsize basic_streambuf<_CharT, _Traits>::xsputn(const char_type* __s, streamsize __n) {
  streamsize __i = 0;
  int_type __eof = traits_type::eof();
  while (__i < __n) {
    if (__nout_ >= __eout_) {
      if (overflow(traits_type::to_int_type(*__s)) == __eof)
        break;
      ++__s;
      ++__i;
    } else {
      streamsize __chunk_size = std::min(__eout_ - __nout_, __n - __i);
      traits_type::copy(__nout_, __s, __chunk_size);
      __nout_ += __chunk_size;
      __s += __chunk_size;
      __i += __chunk_size;
    }
  }
  return __i;
}

template <class _CharT, class _Traits>
typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>::overflow(int_type) {
  return traits_type::eof();
}

extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>;

#  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>;
#  endif

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif // !defined(_LIBCPP_HAS_NO_LOCALIZATION)

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#  include <cstdint>
#endif

#endif // _LIBCPP_STREAMBUF
