// -*- 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_ISTREAM
#define _LIBCPP_ISTREAM

/*
    istream synopsis

template <class charT, class traits = char_traits<charT> >
class basic_istream
    : virtual public basic_ios<charT,traits>
{
public:
    // types (inherited from basic_ios (27.5.4)):
    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;

    // 27.7.1.1.1 Constructor/destructor:
    explicit basic_istream(basic_streambuf<char_type, traits_type>* sb);
    basic_istream(basic_istream&& rhs);
    virtual ~basic_istream();

    // 27.7.1.1.2 Assign/swap:
    basic_istream& operator=(basic_istream&& rhs);
    void swap(basic_istream& rhs);

    // 27.7.1.1.3 Prefix/suffix:
    class sentry;

    // 27.7.1.2 Formatted input:
    basic_istream& operator>>(basic_istream& (*pf)(basic_istream&));
    basic_istream& operator>>(basic_ios<char_type, traits_type>&
                              (*pf)(basic_ios<char_type, traits_type>&));
    basic_istream& operator>>(ios_base& (*pf)(ios_base&));
    basic_istream& operator>>(basic_streambuf<char_type, traits_type>* sb);
    basic_istream& operator>>(bool& n);
    basic_istream& operator>>(short& n);
    basic_istream& operator>>(unsigned short& n);
    basic_istream& operator>>(int& n);
    basic_istream& operator>>(unsigned int& n);
    basic_istream& operator>>(long& n);
    basic_istream& operator>>(unsigned long& n);
    basic_istream& operator>>(long long& n);
    basic_istream& operator>>(unsigned long long& n);
    basic_istream& operator>>(float& f);
    basic_istream& operator>>(double& f);
    basic_istream& operator>>(long double& f);
    basic_istream& operator>>(void*& p);

    // 27.7.1.3 Unformatted input:
    streamsize gcount() const;
    int_type get();
    basic_istream& get(char_type& c);
    basic_istream& get(char_type* s, streamsize n);
    basic_istream& get(char_type* s, streamsize n, char_type delim);
    basic_istream& get(basic_streambuf<char_type,traits_type>& sb);
    basic_istream& get(basic_streambuf<char_type,traits_type>& sb, char_type delim);

    basic_istream& getline(char_type* s, streamsize n);
    basic_istream& getline(char_type* s, streamsize n, char_type delim);

    basic_istream& ignore(streamsize n = 1, int_type delim = traits_type::eof());
    int_type peek();
    basic_istream& read (char_type* s, streamsize n);
    streamsize readsome(char_type* s, streamsize n);

    basic_istream& putback(char_type c);
    basic_istream& unget();
    int sync();

    pos_type tellg();
    basic_istream& seekg(pos_type);
    basic_istream& seekg(off_type, ios_base::seekdir);
protected:
    basic_istream(const basic_istream& rhs) = delete;
    basic_istream(basic_istream&& rhs);
    // 27.7.2.1.2 Assign/swap:
    basic_istream& operator=(const basic_istream& rhs) = delete;
    basic_istream& operator=(basic_istream&& rhs);
    void swap(basic_istream& rhs);
};

// 27.7.1.2.3 character extraction templates:
template<class charT, class traits>
  basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&, charT&);

template<class traits>
  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, unsigned char&);

template<class traits>
  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, signed char&);

template<class charT, class traits>
  basic_istream<charT,traits>& operator>>(basic_istream<charT,traits>&, charT*);

template<class traits>
  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, unsigned char*);

template<class traits>
  basic_istream<char,traits>& operator>>(basic_istream<char,traits>&, signed char*);

template <class charT, class traits>
  void
  swap(basic_istream<charT, traits>& x, basic_istream<charT, traits>& y);

typedef basic_istream<char> istream;
typedef basic_istream<wchar_t> wistream;

template <class charT, class traits = char_traits<charT> >
class basic_iostream :
    public basic_istream<charT,traits>,
    public basic_ostream<charT,traits>
{
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;

    // constructor/destructor
    explicit basic_iostream(basic_streambuf<char_type, traits_type>* sb);
    basic_iostream(basic_iostream&& rhs);
    virtual ~basic_iostream();

    // assign/swap
    basic_iostream& operator=(basic_iostream&& rhs);
    void swap(basic_iostream& rhs);
};

template <class charT, class traits>
  void
  swap(basic_iostream<charT, traits>& x, basic_iostream<charT, traits>& y);

typedef basic_iostream<char> iostream;
typedef basic_iostream<wchar_t> wiostream;

template <class charT, class traits>
  basic_istream<charT,traits>&
  ws(basic_istream<charT,traits>& is);

// rvalue stream extraction
template <class Stream, class T>
  Stream&& operator>>(Stream&& is, T&& x);

}  // std

*/

#include <__config>

#if _LIBCPP_HAS_LOCALIZATION

#  include <__fwd/istream.h>
#  include <__iterator/istreambuf_iterator.h>
#  include <__ostream/basic_ostream.h>
#  include <__type_traits/conjunction.h>
#  include <__type_traits/enable_if.h>
#  include <__type_traits/is_base_of.h>
#  include <__type_traits/make_unsigned.h>
#  include <__utility/declval.h>
#  include <__utility/forward.h>
#  include <bitset>
#  include <ios>
#  include <locale>
#  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_istream : virtual public basic_ios<_CharT, _Traits> {
  streamsize __gc_;

  _LIBCPP_HIDE_FROM_ABI void __inc_gcount() {
    if (__gc_ < numeric_limits<streamsize>::max())
      ++__gc_;
  }

public:
  // types (inherited from basic_ios (27.5.4)):
  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;

  // 27.7.1.1.1 Constructor/destructor:
  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb)
      : __gc_(0) {
    this->init(__sb);
  }
  ~basic_istream() override;

protected:
  inline _LIBCPP_HIDE_FROM_ABI basic_istream(basic_istream&& __rhs);

  // 27.7.1.1.2 Assign/swap:
  inline _LIBCPP_HIDE_FROM_ABI basic_istream& operator=(basic_istream&& __rhs);

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_istream& __rhs) {
    std::swap(__gc_, __rhs.__gc_);
    basic_ios<char_type, traits_type>::swap(__rhs);
  }

public:
  basic_istream(const basic_istream& __rhs)            = delete;
  basic_istream& operator=(const basic_istream& __rhs) = delete;

  // 27.7.1.1.3 Prefix/suffix:
  class _LIBCPP_TEMPLATE_VIS sentry;

  // 27.7.1.2 Formatted input:
  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&)) {
    return __pf(*this);
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream&
  operator>>(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type, traits_type>&)) {
    __pf(*this);
    return *this;
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& operator>>(ios_base& (*__pf)(ios_base&)) {
    __pf(*this);
    return *this;
  }

  basic_istream& operator>>(basic_streambuf<char_type, traits_type>* __sb);
  basic_istream& operator>>(bool& __n);
  basic_istream& operator>>(short& __n);
  basic_istream& operator>>(unsigned short& __n);
  basic_istream& operator>>(int& __n);
  basic_istream& operator>>(unsigned int& __n);
  basic_istream& operator>>(long& __n);
  basic_istream& operator>>(unsigned long& __n);
  basic_istream& operator>>(long long& __n);
  basic_istream& operator>>(unsigned long long& __n);
  basic_istream& operator>>(float& __f);
  basic_istream& operator>>(double& __f);
  basic_istream& operator>>(long double& __f);
  basic_istream& operator>>(void*& __p);

  // 27.7.1.3 Unformatted input:
  _LIBCPP_HIDE_FROM_ABI streamsize gcount() const { return __gc_; }
  int_type get();

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type& __c) {
    int_type __ch = get();
    if (__ch != traits_type::eof())
      __c = traits_type::to_char_type(__ch);
    return *this;
  }

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type* __s, streamsize __n) {
    return get(__s, __n, this->widen('\n'));
  }

  basic_istream& get(char_type* __s, streamsize __n, char_type __dlm);

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(basic_streambuf<char_type, traits_type>& __sb) {
    return get(__sb, this->widen('\n'));
  }

  basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm);

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& getline(char_type* __s, streamsize __n) {
    return getline(__s, __n, this->widen('\n'));
  }

  basic_istream& getline(char_type* __s, streamsize __n, char_type __dlm);

  basic_istream& ignore(streamsize __n = 1, int_type __dlm = traits_type::eof());
  int_type peek();
  basic_istream& read(char_type* __s, streamsize __n);
  streamsize readsome(char_type* __s, streamsize __n);

  basic_istream& putback(char_type __c);
  basic_istream& unget();
  int sync();

  pos_type tellg();
  basic_istream& seekg(pos_type __pos);
  basic_istream& seekg(off_type __off, ios_base::seekdir __dir);
};

template <class _CharT, class _Traits>
class _LIBCPP_TEMPLATE_VIS basic_istream<_CharT, _Traits>::sentry {
  bool __ok_;

public:
  explicit sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws = false);
  //    ~sentry() = default;

  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const { return __ok_; }

  sentry(const sentry&)            = delete;
  sentry& operator=(const sentry&) = delete;
};

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>::sentry::sentry(basic_istream<_CharT, _Traits>& __is, bool __noskipws) : __ok_(false) {
  if (__is.good()) {
    if (__is.tie())
      __is.tie()->flush();
    if (!__noskipws && (__is.flags() & ios_base::skipws)) {
      typedef istreambuf_iterator<_CharT, _Traits> _Ip;
      const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
      _Ip __i(__is);
      _Ip __eof;
      for (; __i != __eof; ++__i)
        if (!__ct.is(__ct.space, *__i))
          break;
      if (__i == __eof)
        __is.setstate(ios_base::failbit | ios_base::eofbit);
    }
    __ok_ = __is.good();
  } else
    __is.setstate(ios_base::failbit);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>::basic_istream(basic_istream&& __rhs) : __gc_(__rhs.__gc_) {
  __rhs.__gc_ = 0;
  this->move(__rhs);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator=(basic_istream&& __rhs) {
  swap(__rhs);
  return *this;
}

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

template <class _Tp, class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
__input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
  ios_base::iostate __state = ios_base::goodbit;
  typename basic_istream<_CharT, _Traits>::sentry __s(__is);
  if (__s) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      typedef istreambuf_iterator<_CharT, _Traits> _Ip;
      typedef num_get<_CharT, _Ip> _Fp;
      std::use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __n);
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      __is.__setstate_nothrow(__state);
      if (__is.exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif
    __is.setstate(__state);
  }
  return __is;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n) {
  return std::__input_arithmetic<unsigned short>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(unsigned int& __n) {
  return std::__input_arithmetic<unsigned int>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(long& __n) {
  return std::__input_arithmetic<long>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(unsigned long& __n) {
  return std::__input_arithmetic<unsigned long>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(long long& __n) {
  return std::__input_arithmetic<long long>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(unsigned long long& __n) {
  return std::__input_arithmetic<unsigned long long>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(float& __n) {
  return std::__input_arithmetic<float>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(double& __n) {
  return std::__input_arithmetic<double>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(long double& __n) {
  return std::__input_arithmetic<long double>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(bool& __n) {
  return std::__input_arithmetic<bool>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(void*& __n) {
  return std::__input_arithmetic<void*>(*this, __n);
}

template <class _Tp, class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
__input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp& __n) {
  ios_base::iostate __state = ios_base::goodbit;
  typename basic_istream<_CharT, _Traits>::sentry __s(__is);
  if (__s) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      typedef istreambuf_iterator<_CharT, _Traits> _Ip;
      typedef num_get<_CharT, _Ip> _Fp;
      long __temp;
      std::use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __temp);
      if (__temp < numeric_limits<_Tp>::min()) {
        __state |= ios_base::failbit;
        __n = numeric_limits<_Tp>::min();
      } else if (__temp > numeric_limits<_Tp>::max()) {
        __state |= ios_base::failbit;
        __n = numeric_limits<_Tp>::max();
      } else {
        __n = static_cast<_Tp>(__temp);
      }
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      __is.__setstate_nothrow(__state);
      if (__is.exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    __is.setstate(__state);
  }
  return __is;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(short& __n) {
  return std::__input_arithmetic_with_numeric_limits<short>(*this, __n);
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(int& __n) {
  return std::__input_arithmetic_with_numeric_limits<int>(*this, __n);
}

template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
__input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n) {
  ios_base::iostate __state = ios_base::goodbit;
  typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif
      _CharT* __s               = __p;
      const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
      while (__s != __p + (__n - 1)) {
        typename _Traits::int_type __i = __is.rdbuf()->sgetc();
        if (_Traits::eq_int_type(__i, _Traits::eof())) {
          __state |= ios_base::eofbit;
          break;
        }
        _CharT __ch = _Traits::to_char_type(__i);
        if (__ct.is(__ct.space, __ch))
          break;
        *__s++ = __ch;
        __is.rdbuf()->sbumpc();
      }
      *__s = _CharT();
      __is.width(0);
      if (__s == __p)
        __state |= ios_base::failbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      __is.__setstate_nothrow(__state);
      if (__is.exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif
    __is.setstate(__state);
  }
  return __is;
}

#  if _LIBCPP_STD_VER >= 20

template <class _CharT, class _Traits, size_t _Np>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT (&__buf)[_Np]) {
  size_t __n = _Np;
  if (__is.width() > 0)
    __n = std::min(size_t(__is.width()), _Np);
  return std::__input_c_string(__is, __buf, __n);
}

template <class _Traits, size_t _Np>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __is, unsigned char (&__buf)[_Np]) {
  return __is >> (char(&)[_Np])__buf;
}

template <class _Traits, size_t _Np>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __is, signed char (&__buf)[_Np]) {
  return __is >> (char(&)[_Np])__buf;
}

#  else

template <class _CharT, class _Traits>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) {
  streamsize __n = __is.width();
  if (__n <= 0)
    __n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1;
  return std::__input_c_string(__is, __s, size_t(__n));
}

template <class _Traits>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __is, unsigned char* __s) {
  return __is >> (char*)__s;
}

template <class _Traits>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __is, signed char* __s) {
  return __is >> (char*)__s;
}

#  endif // _LIBCPP_STD_VER >= 20

template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c) {
  ios_base::iostate __state = ios_base::goodbit;
  typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif
      typename _Traits::int_type __i = __is.rdbuf()->sbumpc();
      if (_Traits::eq_int_type(__i, _Traits::eof()))
        __state |= ios_base::eofbit | ios_base::failbit;
      else
        __c = _Traits::to_char_type(__i);
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      __is.__setstate_nothrow(__state);
      if (__is.exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif
    __is.setstate(__state);
  }
  return __is;
}

template <class _Traits>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __is, unsigned char& __c) {
  return __is >> (char&)__c;
}

template <class _Traits>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __is, signed char& __c) {
  return __is >> (char&)__c;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_type>* __sb) {
  ios_base::iostate __state = ios_base::goodbit;
  __gc_                     = 0;
  sentry __s(*this, true);
  if (__s) {
    if (__sb) {
#  if _LIBCPP_HAS_EXCEPTIONS
      try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
        while (true) {
          typename traits_type::int_type __i = this->rdbuf()->sgetc();
          if (traits_type::eq_int_type(__i, _Traits::eof())) {
            __state |= ios_base::eofbit;
            break;
          }
          if (traits_type::eq_int_type(__sb->sputc(traits_type::to_char_type(__i)), traits_type::eof()))
            break;
          __inc_gcount();
          this->rdbuf()->sbumpc();
        }
        if (__gc_ == 0)
          __state |= ios_base::failbit;
#  if _LIBCPP_HAS_EXCEPTIONS
      } catch (...) {
        __state |= ios_base::badbit;
        if (__gc_ == 0)
          __state |= ios_base::failbit;

        this->__setstate_nothrow(__state);
        if (this->exceptions() & ios_base::failbit || this->exceptions() & ios_base::badbit) {
          throw;
        }
      }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    } else {
      __state |= ios_base::failbit;
    }
    this->setstate(__state);
  }
  return *this;
}

template <class _CharT, class _Traits>
typename basic_istream<_CharT, _Traits>::int_type basic_istream<_CharT, _Traits>::get() {
  ios_base::iostate __state = ios_base::goodbit;
  __gc_                     = 0;
  int_type __r              = traits_type::eof();
  sentry __s(*this, true);
  if (__s) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif
      __r = this->rdbuf()->sbumpc();
      if (traits_type::eq_int_type(__r, traits_type::eof()))
        __state |= ios_base::failbit | ios_base::eofbit;
      else
        __gc_ = 1;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      this->__setstate_nothrow(this->rdstate() | ios_base::badbit);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif
    this->setstate(__state);
  }
  return __r;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __dlm) {
  ios_base::iostate __state = ios_base::goodbit;
  __gc_                     = 0;
  sentry __sen(*this, true);
  if (__sen) {
    if (__n > 0) {
#  if _LIBCPP_HAS_EXCEPTIONS
      try {
#  endif
        while (__gc_ < __n - 1) {
          int_type __i = this->rdbuf()->sgetc();
          if (traits_type::eq_int_type(__i, traits_type::eof())) {
            __state |= ios_base::eofbit;
            break;
          }
          char_type __ch = traits_type::to_char_type(__i);
          if (traits_type::eq(__ch, __dlm))
            break;
          *__s++ = __ch;
          __inc_gcount();
          this->rdbuf()->sbumpc();
        }
        if (__gc_ == 0)
          __state |= ios_base::failbit;
#  if _LIBCPP_HAS_EXCEPTIONS
      } catch (...) {
        __state |= ios_base::badbit;
        this->__setstate_nothrow(__state);
        if (this->exceptions() & ios_base::badbit) {
          if (__n > 0)
            *__s = char_type();
          throw;
        }
      }
#  endif
    } else {
      __state |= ios_base::failbit;
    }

    if (__n > 0)
      *__s = char_type();
    this->setstate(__state);
  }
  if (__n > 0)
    *__s = char_type();
  return *this;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm) {
  ios_base::iostate __state = ios_base::goodbit;
  __gc_                     = 0;
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      while (true) {
        typename traits_type::int_type __i = this->rdbuf()->sgetc();
        if (traits_type::eq_int_type(__i, traits_type::eof())) {
          __state |= ios_base::eofbit;
          break;
        }
        char_type __ch = traits_type::to_char_type(__i);
        if (traits_type::eq(__ch, __dlm))
          break;
        if (traits_type::eq_int_type(__sb.sputc(__ch), traits_type::eof()))
          break;
        __inc_gcount();
        this->rdbuf()->sbumpc();
      }
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      // according to the spec, exceptions here are caught but not rethrown
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    if (__gc_ == 0)
      __state |= ios_base::failbit;
    this->setstate(__state);
  }
  return *this;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_type __dlm) {
  ios_base::iostate __state = ios_base::goodbit;
  __gc_                     = 0;
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      while (true) {
        typename traits_type::int_type __i = this->rdbuf()->sgetc();
        if (traits_type::eq_int_type(__i, traits_type::eof())) {
          __state |= ios_base::eofbit;
          break;
        }
        char_type __ch = traits_type::to_char_type(__i);
        if (traits_type::eq(__ch, __dlm)) {
          this->rdbuf()->sbumpc();
          __inc_gcount();
          break;
        }
        if (__gc_ >= __n - 1) {
          __state |= ios_base::failbit;
          break;
        }
        *__s++ = __ch;
        this->rdbuf()->sbumpc();
        __inc_gcount();
      }
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        if (__n > 0)
          *__s = char_type();
        if (__gc_ == 0)
          __state |= ios_base::failbit;
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
  }
  if (__n > 0)
    *__s = char_type();
  if (__gc_ == 0)
    __state |= ios_base::failbit;
  this->setstate(__state);
  return *this;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm) {
  ios_base::iostate __state = ios_base::goodbit;
  __gc_                     = 0;
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      if (__n == numeric_limits<streamsize>::max()) {
        while (true) {
          typename traits_type::int_type __i = this->rdbuf()->sbumpc();
          if (traits_type::eq_int_type(__i, traits_type::eof())) {
            __state |= ios_base::eofbit;
            break;
          }
          __inc_gcount();
          if (traits_type::eq_int_type(__i, __dlm))
            break;
        }
      } else {
        while (__gc_ < __n) {
          typename traits_type::int_type __i = this->rdbuf()->sbumpc();
          if (traits_type::eq_int_type(__i, traits_type::eof())) {
            __state |= ios_base::eofbit;
            break;
          }
          __inc_gcount();
          if (traits_type::eq_int_type(__i, __dlm))
            break;
        }
      }
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    this->setstate(__state);
  }
  return *this;
}

template <class _CharT, class _Traits>
typename basic_istream<_CharT, _Traits>::int_type basic_istream<_CharT, _Traits>::peek() {
  ios_base::iostate __state = ios_base::goodbit;
  __gc_                     = 0;
  int_type __r              = traits_type::eof();
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      __r = this->rdbuf()->sgetc();
      if (traits_type::eq_int_type(__r, traits_type::eof()))
        __state |= ios_base::eofbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    this->setstate(__state);
  }
  return __r;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) {
  ios_base::iostate __state = ios_base::goodbit;
  __gc_                     = 0;
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      __gc_ = this->rdbuf()->sgetn(__s, __n);
      if (__gc_ != __n)
        __state |= ios_base::failbit | ios_base::eofbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
  } else {
    __state |= ios_base::failbit;
  }
  this->setstate(__state);
  return *this;
}

template <class _CharT, class _Traits>
streamsize basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n) {
  ios_base::iostate __state = ios_base::goodbit;
  __gc_                     = 0;
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      streamsize __c = this->rdbuf()->in_avail();
      switch (__c) {
      case -1:
        __state |= ios_base::eofbit;
        break;
      case 0:
        break;
      default:
        __n   = std::min(__c, __n);
        __gc_ = this->rdbuf()->sgetn(__s, __n);
        if (__gc_ != __n)
          __state |= ios_base::failbit | ios_base::eofbit;
        break;
      }
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
  } else {
    __state |= ios_base::failbit;
  }
  this->setstate(__state);
  return __gc_;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::putback(char_type __c) {
  ios_base::iostate __state = this->rdstate() & ~ios_base::eofbit;
  __gc_                     = 0;
  this->clear(__state);
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      if (this->rdbuf() == nullptr || this->rdbuf()->sputbackc(__c) == traits_type::eof())
        __state |= ios_base::badbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
  } else {
    __state |= ios_base::failbit;
  }
  this->setstate(__state);
  return *this;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::unget() {
  ios_base::iostate __state = this->rdstate() & ~ios_base::eofbit;
  __gc_                     = 0;
  this->clear(__state);
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      if (this->rdbuf() == nullptr || this->rdbuf()->sungetc() == traits_type::eof())
        __state |= ios_base::badbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
  } else {
    __state |= ios_base::failbit;
  }
  this->setstate(__state);
  return *this;
}

template <class _CharT, class _Traits>
int basic_istream<_CharT, _Traits>::sync() {
  ios_base::iostate __state = ios_base::goodbit;
  sentry __sen(*this, true);
  if (this->rdbuf() == nullptr)
    return -1;

  int __r = 0;
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      if (this->rdbuf()->pubsync() == -1) {
        __state |= ios_base::badbit;
        __r = -1;
      }
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    this->setstate(__state);
  }
  return __r;
}

template <class _CharT, class _Traits>
typename basic_istream<_CharT, _Traits>::pos_type basic_istream<_CharT, _Traits>::tellg() {
  ios_base::iostate __state = ios_base::goodbit;
  pos_type __r(-1);
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    this->setstate(__state);
  }
  return __r;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::seekg(pos_type __pos) {
  ios_base::iostate __state = this->rdstate() & ~ios_base::eofbit;
  this->clear(__state);
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1))
        __state |= ios_base::failbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    this->setstate(__state);
  }
  return *this;
}

template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir) {
  ios_base::iostate __state = this->rdstate() & ~ios_base::eofbit;
  this->clear(__state);
  sentry __sen(*this, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1))
        __state |= ios_base::failbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      this->__setstate_nothrow(__state);
      if (this->exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    this->setstate(__state);
  }
  return *this;
}

template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& ws(basic_istream<_CharT, _Traits>& __is) {
  ios_base::iostate __state = ios_base::goodbit;
  typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif // _LIBCPP_HAS_EXCEPTIONS
      const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
      while (true) {
        typename _Traits::int_type __i = __is.rdbuf()->sgetc();
        if (_Traits::eq_int_type(__i, _Traits::eof())) {
          __state |= ios_base::eofbit;
          break;
        }
        if (!__ct.is(__ct.space, _Traits::to_char_type(__i)))
          break;
        __is.rdbuf()->sbumpc();
      }
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      __is.__setstate_nothrow(__state);
      if (__is.exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif // _LIBCPP_HAS_EXCEPTIONS
    __is.setstate(__state);
  }
  return __is;
}

template <class _Stream, class _Tp, class = void>
struct __is_istreamable : false_type {};

template <class _Stream, class _Tp>
struct __is_istreamable<_Stream, _Tp, decltype(std::declval<_Stream>() >> std::declval<_Tp>(), void())> : true_type {};

template <class _Stream,
          class _Tp,
          __enable_if_t< _And<is_base_of<ios_base, _Stream>, __is_istreamable<_Stream&, _Tp&&> >::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _Stream&& operator>>(_Stream&& __is, _Tp&& __x) {
  __is >> std::forward<_Tp>(__x);
  return std::move(__is);
}

template <class _CharT, class _Traits>
class _LIBCPP_TEMPLATE_VIS basic_iostream
    : public basic_istream<_CharT, _Traits>,
      public basic_ostream<_CharT, _Traits> {
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;

  // constructor/destructor
  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb)
      : basic_istream<_CharT, _Traits>(__sb) {}

  ~basic_iostream() override;

protected:
  inline _LIBCPP_HIDE_FROM_ABI basic_iostream(basic_iostream&& __rhs);

  // assign/swap
  inline _LIBCPP_HIDE_FROM_ABI basic_iostream& operator=(basic_iostream&& __rhs);

  inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_iostream& __rhs) {
    basic_istream<char_type, traits_type>::swap(__rhs);
  }
};

template <class _CharT, class _Traits>
basic_iostream<_CharT, _Traits>::basic_iostream(basic_iostream&& __rhs)
    : basic_istream<_CharT, _Traits>(std::move(__rhs)) {}

template <class _CharT, class _Traits>
basic_iostream<_CharT, _Traits>& basic_iostream<_CharT, _Traits>::operator=(basic_iostream&& __rhs) {
  swap(__rhs);
  return *this;
}

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

template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str) {
  ios_base::iostate __state = ios_base::goodbit;
  typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif
      __str.clear();
      using _Size              = typename basic_string<_CharT, _Traits, _Allocator>::size_type;
      streamsize const __width = __is.width();
      _Size const __max_size   = __str.max_size();
      _Size __n;
      if (__width <= 0) {
        __n = __max_size;
      } else {
        __n = std::__to_unsigned_like(__width) < __max_size ? static_cast<_Size>(__width) : __max_size;
      }

      _Size __c                 = 0;
      const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
      while (__c < __n) {
        typename _Traits::int_type __i = __is.rdbuf()->sgetc();
        if (_Traits::eq_int_type(__i, _Traits::eof())) {
          __state |= ios_base::eofbit;
          break;
        }
        _CharT __ch = _Traits::to_char_type(__i);
        if (__ct.is(__ct.space, __ch))
          break;
        __str.push_back(__ch);
        ++__c;
        __is.rdbuf()->sbumpc();
      }
      __is.width(0);
      if (__c == 0)
        __state |= ios_base::failbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      __is.__setstate_nothrow(__state);
      if (__is.exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif
    __is.setstate(__state);
  }
  return __is;
}

template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm) {
  ios_base::iostate __state = ios_base::goodbit;
  typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif
      __str.clear();
      streamsize __extr = 0;
      while (true) {
        typename _Traits::int_type __i = __is.rdbuf()->sbumpc();
        if (_Traits::eq_int_type(__i, _Traits::eof())) {
          __state |= ios_base::eofbit;
          break;
        }
        ++__extr;
        _CharT __ch = _Traits::to_char_type(__i);
        if (_Traits::eq(__ch, __dlm))
          break;
        __str.push_back(__ch);
        if (__str.size() == __str.max_size()) {
          __state |= ios_base::failbit;
          break;
        }
      }
      if (__extr == 0)
        __state |= ios_base::failbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      __is.__setstate_nothrow(__state);
      if (__is.exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif
    __is.setstate(__state);
  }
  return __is;
}

template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Allocator>& __str) {
  return std::getline(__is, __str, __is.widen('\n'));
}

template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm) {
  return std::getline(__is, __str, __dlm);
}

template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Allocator>& __str) {
  return std::getline(__is, __str, __is.widen('\n'));
}

template <class _CharT, class _Traits, size_t _Size>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) {
  ios_base::iostate __state = ios_base::goodbit;
  typename basic_istream<_CharT, _Traits>::sentry __sen(__is);
  if (__sen) {
#  if _LIBCPP_HAS_EXCEPTIONS
    try {
#  endif
      basic_string<_CharT, _Traits> __str;
      const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc());
      size_t __c                = 0;
      _CharT __zero             = __ct.widen('0');
      _CharT __one              = __ct.widen('1');
      while (__c != _Size) {
        typename _Traits::int_type __i = __is.rdbuf()->sgetc();
        if (_Traits::eq_int_type(__i, _Traits::eof())) {
          __state |= ios_base::eofbit;
          break;
        }
        _CharT __ch = _Traits::to_char_type(__i);
        if (!_Traits::eq(__ch, __zero) && !_Traits::eq(__ch, __one))
          break;
        __str.push_back(__ch);
        ++__c;
        __is.rdbuf()->sbumpc();
      }
      __x = bitset<_Size>(__str);
      if (_Size > 0 && __c == 0)
        __state |= ios_base::failbit;
#  if _LIBCPP_HAS_EXCEPTIONS
    } catch (...) {
      __state |= ios_base::badbit;
      __is.__setstate_nothrow(__state);
      if (__is.exceptions() & ios_base::badbit) {
        throw;
      }
    }
#  endif
    __is.setstate(__state);
  }
  return __is;
}

extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<char>;
#  if _LIBCPP_HAS_WIDE_CHARACTERS
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<wchar_t>;
#  endif
extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<char>;

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_HAS_LOCALIZATION

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#  include <concepts>
#  include <iosfwd>
#  include <ostream>
#  include <type_traits>
#endif

_LIBCPP_POP_MACROS

#endif // _LIBCPP_ISTREAM
