// -*- 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___CXX03_IOMANIP
#define _LIBCPP___CXX03_IOMANIP

/*
    iomanip synopsis

namespace std {

// types T1, T2, ... are unspecified implementation types
T1 resetiosflags(ios_base::fmtflags mask);
T2 setiosflags (ios_base::fmtflags mask);
T3 setbase(int base);
template<charT> T4 setfill(charT c);
T5 setprecision(int n);
T6 setw(int n);
template <class moneyT> T7 get_money(moneyT& mon, bool intl = false);
template <class charT, class moneyT> T8 put_money(const moneyT& mon, bool intl = false);
template <class charT> T9 get_time(struct tm* tmb, const charT* fmt);
template <class charT> T10 put_time(const struct tm* tmb, const charT* fmt);

template <class charT>
  T11 quoted(const charT* s, charT delim=charT('"'), charT escape=charT('\\')); // C++14

template <class charT, class traits, class Allocator>
  T12 quoted(const basic_string<charT, traits, Allocator>& s,
             charT delim=charT('"'), charT escape=charT('\\')); // C++14

template <class charT, class traits, class Allocator>
  T13 quoted(basic_string<charT, traits, Allocator>& s,
             charT delim=charT('"'), charT escape=charT('\\')); // C++14

}  // std

*/

#include <__cxx03/__config>
#include <__cxx03/istream>
#include <__cxx03/version>

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

_LIBCPP_BEGIN_NAMESPACE_STD

// resetiosflags

class __iom_t1 {
  ios_base::fmtflags __mask_;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __iom_t1(ios_base::fmtflags __m) : __mask_(__m) {}

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t1& __x) {
    __is.unsetf(__x.__mask_);
    return __is;
  }

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t1& __x) {
    __os.unsetf(__x.__mask_);
    return __os;
  }
};

inline _LIBCPP_HIDE_FROM_ABI __iom_t1 resetiosflags(ios_base::fmtflags __mask) { return __iom_t1(__mask); }

// setiosflags

class __iom_t2 {
  ios_base::fmtflags __mask_;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __iom_t2(ios_base::fmtflags __m) : __mask_(__m) {}

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t2& __x) {
    __is.setf(__x.__mask_);
    return __is;
  }

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t2& __x) {
    __os.setf(__x.__mask_);
    return __os;
  }
};

inline _LIBCPP_HIDE_FROM_ABI __iom_t2 setiosflags(ios_base::fmtflags __mask) { return __iom_t2(__mask); }

// setbase

class __iom_t3 {
  int __base_;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __iom_t3(int __b) : __base_(__b) {}

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t3& __x) {
    __is.setf(__x.__base_ == 8    ? ios_base::oct
              : __x.__base_ == 10 ? ios_base::dec
              : __x.__base_ == 16 ? ios_base::hex
                                  : ios_base::fmtflags(0),
              ios_base::basefield);
    return __is;
  }

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t3& __x) {
    __os.setf(__x.__base_ == 8    ? ios_base::oct
              : __x.__base_ == 10 ? ios_base::dec
              : __x.__base_ == 16 ? ios_base::hex
                                  : ios_base::fmtflags(0),
              ios_base::basefield);
    return __os;
  }
};

inline _LIBCPP_HIDE_FROM_ABI __iom_t3 setbase(int __base) { return __iom_t3(__base); }

// setfill

template <class _CharT>
class __iom_t4 {
  _CharT __fill_;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __iom_t4(_CharT __c) : __fill_(__c) {}

  template <class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t4& __x) {
    __os.fill(__x.__fill_);
    return __os;
  }
};

template <class _CharT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t4<_CharT> setfill(_CharT __c) {
  return __iom_t4<_CharT>(__c);
}

// setprecision

class __iom_t5 {
  int __n_;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __iom_t5(int __n) : __n_(__n) {}

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t5& __x) {
    __is.precision(__x.__n_);
    return __is;
  }

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t5& __x) {
    __os.precision(__x.__n_);
    return __os;
  }
};

inline _LIBCPP_HIDE_FROM_ABI __iom_t5 setprecision(int __n) { return __iom_t5(__n); }

// setw

class __iom_t6 {
  int __n_;

public:
  _LIBCPP_HIDE_FROM_ABI explicit __iom_t6(int __n) : __n_(__n) {}

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t6& __x) {
    __is.width(__x.__n_);
    return __is;
  }

  template <class _CharT, class _Traits>
  friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t6& __x) {
    __os.width(__x.__n_);
    return __os;
  }
};

inline _LIBCPP_HIDE_FROM_ABI __iom_t6 setw(int __n) { return __iom_t6(__n); }

// get_money

template <class _MoneyT>
class __iom_t7;

template <class _CharT, class _Traits, class _MoneyT>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x);

template <class _MoneyT>
class __iom_t7 {
  _MoneyT& __mon_;
  bool __intl_;

public:
  _LIBCPP_HIDE_FROM_ABI __iom_t7(_MoneyT& __mon, bool __intl) : __mon_(__mon), __intl_(__intl) {}

  template <class _CharT, class _Traits, class _Mp>
  friend basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_Mp>& __x);
};

template <class _CharT, class _Traits, class _MoneyT>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x) {
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  try {
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
    typename basic_istream<_CharT, _Traits>::sentry __s(__is);
    if (__s) {
      typedef istreambuf_iterator<_CharT, _Traits> _Ip;
      typedef money_get<_CharT, _Ip> _Fp;
      ios_base::iostate __err = ios_base::goodbit;
      const _Fp& __mf         = std::use_facet<_Fp>(__is.getloc());
      __mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_);
      __is.setstate(__err);
    }
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  } catch (...) {
    __is.__set_badbit_and_consider_rethrow();
  }
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
  return __is;
}

template <class _MoneyT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t7<_MoneyT> get_money(_MoneyT& __mon, bool __intl = false) {
  return __iom_t7<_MoneyT>(__mon, __intl);
}

// put_money

template <class _MoneyT>
class __iom_t8;

template <class _CharT, class _Traits, class _MoneyT>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x);

template <class _MoneyT>
class __iom_t8 {
  const _MoneyT& __mon_;
  bool __intl_;

public:
  _LIBCPP_HIDE_FROM_ABI __iom_t8(const _MoneyT& __mon, bool __intl) : __mon_(__mon), __intl_(__intl) {}

  template <class _CharT, class _Traits, class _Mp>
  friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_Mp>& __x);
};

template <class _CharT, class _Traits, class _MoneyT>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x) {
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  try {
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
    typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
    if (__s) {
      typedef ostreambuf_iterator<_CharT, _Traits> _Op;
      typedef money_put<_CharT, _Op> _Fp;
      const _Fp& __mf = std::use_facet<_Fp>(__os.getloc());
      if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed())
        __os.setstate(ios_base::badbit);
    }
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  } catch (...) {
    __os.__set_badbit_and_consider_rethrow();
  }
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
  return __os;
}

template <class _MoneyT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t8<_MoneyT> put_money(const _MoneyT& __mon, bool __intl = false) {
  return __iom_t8<_MoneyT>(__mon, __intl);
}

// get_time

template <class _CharT>
class __iom_t9;

template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x);

template <class _CharT>
class __iom_t9 {
  tm* __tm_;
  const _CharT* __fmt_;

public:
  _LIBCPP_HIDE_FROM_ABI __iom_t9(tm* __tm, const _CharT* __fmt) : __tm_(__tm), __fmt_(__fmt) {}

  template <class _Cp, class _Traits>
  friend basic_istream<_Cp, _Traits>& operator>>(basic_istream<_Cp, _Traits>& __is, const __iom_t9<_Cp>& __x);
};

template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x) {
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  try {
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
    typename basic_istream<_CharT, _Traits>::sentry __s(__is);
    if (__s) {
      typedef istreambuf_iterator<_CharT, _Traits> _Ip;
      typedef time_get<_CharT, _Ip> _Fp;
      ios_base::iostate __err = ios_base::goodbit;
      const _Fp& __tf         = std::use_facet<_Fp>(__is.getloc());
      __tf.get(_Ip(__is), _Ip(), __is, __err, __x.__tm_, __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_));
      __is.setstate(__err);
    }
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  } catch (...) {
    __is.__set_badbit_and_consider_rethrow();
  }
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
  return __is;
}

template <class _CharT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t9<_CharT> get_time(tm* __tm, const _CharT* __fmt) {
  return __iom_t9<_CharT>(__tm, __fmt);
}

// put_time

template <class _CharT>
class __iom_t10;

template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x);

template <class _CharT>
class __iom_t10 {
  const tm* __tm_;
  const _CharT* __fmt_;

public:
  _LIBCPP_HIDE_FROM_ABI __iom_t10(const tm* __tm, const _CharT* __fmt) : __tm_(__tm), __fmt_(__fmt) {}

  template <class _Cp, class _Traits>
  friend basic_ostream<_Cp, _Traits>& operator<<(basic_ostream<_Cp, _Traits>& __os, const __iom_t10<_Cp>& __x);
};

template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x) {
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  try {
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
    typename basic_ostream<_CharT, _Traits>::sentry __s(__os);
    if (__s) {
      typedef ostreambuf_iterator<_CharT, _Traits> _Op;
      typedef time_put<_CharT, _Op> _Fp;
      const _Fp& __tf = std::use_facet<_Fp>(__os.getloc());
      if (__tf.put(_Op(__os), __os, __os.fill(), __x.__tm_, __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_))
              .failed())
        __os.setstate(ios_base::badbit);
    }
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
  } catch (...) {
    __os.__set_badbit_and_consider_rethrow();
  }
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
  return __os;
}

template <class _CharT>
inline _LIBCPP_HIDE_FROM_ABI __iom_t10<_CharT> put_time(const tm* __tm, const _CharT* __fmt) {
  return __iom_t10<_CharT>(__tm, __fmt);
}

template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& __quoted_output(
    basic_ostream<_CharT, _Traits>& __os,
    const _CharT* __first,
    const _CharT* __last,
    _CharT __delim,
    _CharT __escape) {
  basic_string<_CharT, _Traits> __str;
  __str.push_back(__delim);
  for (; __first != __last; ++__first) {
    if (_Traits::eq(*__first, __escape) || _Traits::eq(*__first, __delim))
      __str.push_back(__escape);
    __str.push_back(*__first);
  }
  __str.push_back(__delim);
  return std::__put_character_sequence(__os, __str.data(), __str.size());
}

template <class _CharT, class _Traits, class _String>
_LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
__quoted_input(basic_istream<_CharT, _Traits>& __is, _String& __string, _CharT __delim, _CharT __escape) {
  __string.clear();
  _CharT __c;
  __is >> __c;
  if (__is.fail())
    return __is;

  if (!_Traits::eq(__c, __delim)) {
    // no delimiter, read the whole string
    __is.unget();
    __is >> __string;
    return __is;
  }

  __save_flags<_CharT, _Traits> __sf(__is);
  std::noskipws(__is);
  while (true) {
    __is >> __c;
    if (__is.fail())
      break;
    if (_Traits::eq(__c, __escape)) {
      __is >> __c;
      if (__is.fail())
        break;
    } else if (_Traits::eq(__c, __delim))
      break;
    __string.push_back(__c);
  }
  return __is;
}

template <class _CharT, class _Traits>
struct _LIBCPP_HIDDEN __quoted_output_proxy {
  const _CharT* __first_;
  const _CharT* __last_;
  _CharT __delim_;
  _CharT __escape_;

  _LIBCPP_HIDE_FROM_ABI explicit __quoted_output_proxy(const _CharT* __f, const _CharT* __l, _CharT __d, _CharT __e)
      : __first_(__f), __last_(__l), __delim_(__d), __escape_(__e) {}

  template <class _T2, __enable_if_t<_IsSame<_Traits, void>::value || _IsSame<_Traits, _T2>::value, int> = 0>
  friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _T2>&
  operator<<(basic_ostream<_CharT, _T2>& __os, const __quoted_output_proxy& __p) {
    return std::__quoted_output(__os, __p.__first_, __p.__last_, __p.__delim_, __p.__escape_);
  }
};

template <class _CharT, class _Traits, class _Allocator>
struct _LIBCPP_HIDDEN __quoted_proxy {
  basic_string<_CharT, _Traits, _Allocator>& __string_;
  _CharT __delim_;
  _CharT __escape_;

  _LIBCPP_HIDE_FROM_ABI explicit __quoted_proxy(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __d, _CharT __e)
      : __string_(__s), __delim_(__d), __escape_(__e) {}

  friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  operator<<(basic_ostream<_CharT, _Traits>& __os, const __quoted_proxy& __p) {
    return std::__quoted_output(
        __os, __p.__string_.data(), __p.__string_.data() + __p.__string_.size(), __p.__delim_, __p.__escape_);
  }

  friend _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  operator>>(basic_istream<_CharT, _Traits>& __is, const __quoted_proxy& __p) {
    return std::__quoted_input(__is, __p.__string_, __p.__delim_, __p.__escape_);
  }
};

template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI __quoted_output_proxy<_CharT, _Traits>
__quoted(const basic_string<_CharT, _Traits, _Allocator>& __s,
         _CharT __delim  = _CharT('"'),
         _CharT __escape = _CharT('\\')) {
  return __quoted_output_proxy<_CharT, _Traits>(__s.data(), __s.data() + __s.size(), __delim, __escape);
}

template <class _CharT, class _Traits, class _Allocator>
_LIBCPP_HIDE_FROM_ABI __quoted_proxy<_CharT, _Traits, _Allocator>
__quoted(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\')) {
  return __quoted_proxy<_CharT, _Traits, _Allocator>(__s, __delim, __escape);
}

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___CXX03_IOMANIP
