// -*- 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_dir/locale.h>
#    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
_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS

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;

  struct _GetArea {
    char_type* __begin_;
    char_type* __current_;
    char_type* __end_;
  };

  struct _PutArea {
    char_type* __begin_;
    char_type* __current_;
    char_type* __end_;
  };

  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_), __get_area_(__sb.__get_area_), __put_area_(__sb.__put_area_) {}

  basic_streambuf& operator=(const basic_streambuf& __sb) {
    __loc_      = __sb.__loc_;
    __get_area_ = __sb.__get_area_;
    __put_area_ = __sb.__put_area_;
    return *this;
  }

  void swap(basic_streambuf& __sb) {
    std::swap(__loc_, __sb.__loc_);
    std::swap(__get_area_, __sb.__get_area_);
    std::swap(__put_area_, __sb.__put_area_);
  }

  // 27.6.2.3.2 Get area:
  _LIBCPP_HIDE_FROM_ABI char_type* eback() const { return __get_area_.__begin_; }
  _LIBCPP_HIDE_FROM_ABI char_type* gptr() const { return __get_area_.__current_; }
  _LIBCPP_HIDE_FROM_ABI char_type* egptr() const { return __get_area_.__end_; }

  inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void gbump(int __n) { __get_area_.__current_ += __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) { __get_area_.__current_ += __n; }

  inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void setg(char_type* __begin, char_type* __current, char_type* __end) {
    _LIBCPP_ASSERT_VALID_INPUT_RANGE(
        std::__is_valid_range(__begin, __current), "[begin, current) must be a valid range");
    _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__begin, __end), "[begin, end) must be a valid range");
    _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__current, __end), "[current, end) must be a valid range");
    _GetArea __tmp = {__begin, __current, __end}; // This is a temporary for C++03 compatibility
    __get_area_    = __tmp;
  }

  // 27.6.2.3.3 Put area:
  _LIBCPP_HIDE_FROM_ABI char_type* pbase() const { return __put_area_.__begin_; }
  _LIBCPP_HIDE_FROM_ABI char_type* pptr() const { return __put_area_.__current_; }
  _LIBCPP_HIDE_FROM_ABI char_type* epptr() const { return __put_area_.__end_; }

  inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void pbump(int __n) { __put_area_.__current_ += __n; }

  _LIBCPP_HIDE_FROM_ABI void __pbump(streamsize __n) { __put_area_.__current_ += __n; }

  inline _LIBCPP_HIDE_FROM_ABI_SINCE_LLVM8 void setp(char_type* __begin, char_type* __end) {
    _LIBCPP_ASSERT_VALID_INPUT_RANGE(std::__is_valid_range(__begin, __end), "[begin, end) must be a valid range");
    _PutArea __tmp = {__begin, __begin, __end}; // This is a temporary for C++03 compatibility
    __put_area_    = __tmp;
  }

  // 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_;
  _GetArea __get_area_ = {};
  _PutArea __put_area_ = {};

  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_EXPLICIT_ABI_ANNOTATIONS
_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#  endif // _LIBCPP_HAS_LOCALIZATION

#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)

#endif // _LIBCPP_STREAMBUF
