// Standard stream manipulators -*- C++ -*-

// Copyright (C) 1997-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/iomanip
 *  This is a Standard C++ Library header.
 */

//
// ISO C++ 14882: 27.6.3  Standard manipulators
//

#ifndef _GLIBCXX_IOMANIP
#define _GLIBCXX_IOMANIP 1

#pragma GCC system_header

#include <bits/c++config.h>
#include <iosfwd>
#include <bits/ios_base.h>

#if __cplusplus >= 201103L
#include <locale>
#if __cplusplus > 201103L
#include <sstream> // used in quoted.
#endif
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // [27.6.3] standard manipulators
  // Also see DR 183.

  struct _Resetiosflags { ios_base::fmtflags _M_mask; };

  /**
   *  @brief  Manipulator for @c setf.
   *  @param  __mask  A format flags mask.
   *
   *  Sent to a stream object, this manipulator resets the specified flags,
   *  via @e stream.setf(0,__mask).
  */
  inline _Resetiosflags 
  resetiosflags(ios_base::fmtflags __mask)
  { return { __mask }; }

  template<typename _CharT, typename _Traits>
    inline basic_istream<_CharT, _Traits>& 
    operator>>(basic_istream<_CharT, _Traits>& __is, _Resetiosflags __f)
    { 
      __is.setf(ios_base::fmtflags(0), __f._M_mask); 
      return __is; 
    }

  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __os, _Resetiosflags __f)
    { 
      __os.setf(ios_base::fmtflags(0), __f._M_mask); 
      return __os; 
    }


  struct _Setiosflags { ios_base::fmtflags _M_mask; };

  /**
   *  @brief  Manipulator for @c setf.
   *  @param  __mask  A format flags mask.
   *
   *  Sent to a stream object, this manipulator sets the format flags
   *  to @a __mask.
  */
  inline _Setiosflags 
  setiosflags(ios_base::fmtflags __mask)
  { return { __mask }; }

  template<typename _CharT, typename _Traits>
    inline basic_istream<_CharT, _Traits>& 
    operator>>(basic_istream<_CharT, _Traits>& __is, _Setiosflags __f)
    { 
      __is.setf(__f._M_mask); 
      return __is; 
    }

  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setiosflags __f)
    { 
      __os.setf(__f._M_mask); 
      return __os; 
    }


  struct _Setbase { int _M_base; };

  /**
   *  @brief  Manipulator for @c setf.
   *  @param  __base  A numeric base.
   *
   *  Sent to a stream object, this manipulator changes the
   *  @c ios_base::basefield flags to @c oct, @c dec, or @c hex when @a base
   *  is 8, 10, or 16, accordingly, and to 0 if @a __base is any other value.
  */
  inline _Setbase 
  setbase(int __base)
  { return { __base }; }

  template<typename _CharT, typename _Traits>
    inline basic_istream<_CharT, _Traits>& 
    operator>>(basic_istream<_CharT, _Traits>& __is, _Setbase __f)
    {
      __is.setf(__f._M_base ==  8 ? ios_base::oct : 
		__f._M_base == 10 ? ios_base::dec : 
		__f._M_base == 16 ? ios_base::hex : 
		ios_base::fmtflags(0), ios_base::basefield);
      return __is; 
    }
  
  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setbase __f)
    {
      __os.setf(__f._M_base ==  8 ? ios_base::oct : 
		__f._M_base == 10 ? ios_base::dec : 
		__f._M_base == 16 ? ios_base::hex : 
		ios_base::fmtflags(0), ios_base::basefield);
      return __os; 
    }
  

  template<typename _CharT>
    struct _Setfill { _CharT _M_c; };

  /**
   *  @brief  Manipulator for @c fill.
   *  @param  __c  The new fill character.
   *
   *  Sent to a stream object, this manipulator calls @c fill(__c) for that
   *  object.
  */
  template<typename _CharT>
    inline _Setfill<_CharT>
    setfill(_CharT __c)
    { return { __c }; }

  template<typename _CharT, typename _Traits>
    inline basic_istream<_CharT, _Traits>& 
    operator>>(basic_istream<_CharT, _Traits>& __is, _Setfill<_CharT> __f)
    { 
      __is.fill(__f._M_c); 
      return __is; 
    }

  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setfill<_CharT> __f)
    { 
      __os.fill(__f._M_c); 
      return __os; 
    }


  struct _Setprecision { int _M_n; };

  /**
   *  @brief  Manipulator for @c precision.
   *  @param  __n  The new precision.
   *
   *  Sent to a stream object, this manipulator calls @c precision(__n) for
   *  that object.
  */
  inline _Setprecision 
  setprecision(int __n)
  { return { __n }; }

  template<typename _CharT, typename _Traits>
    inline basic_istream<_CharT, _Traits>& 
    operator>>(basic_istream<_CharT, _Traits>& __is, _Setprecision __f)
    { 
      __is.precision(__f._M_n); 
      return __is; 
    }

  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setprecision __f)
    { 
      __os.precision(__f._M_n); 
      return __os; 
    }


  struct _Setw { int _M_n; };

  /**
   *  @brief  Manipulator for @c width.
   *  @param  __n  The new width.
   *
   *  Sent to a stream object, this manipulator calls @c width(__n) for
   *  that object.
  */
  inline _Setw 
  setw(int __n)
  { return { __n }; }

  template<typename _CharT, typename _Traits>
    inline basic_istream<_CharT, _Traits>& 
    operator>>(basic_istream<_CharT, _Traits>& __is, _Setw __f)
    {
      __is.width(__f._M_n);
      return __is; 
    }

  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setw __f)
    {
      __os.width(__f._M_n);
      return __os; 
    }

#if __cplusplus >= 201103L
  
  template<typename _MoneyT>
    struct _Get_money { _MoneyT& _M_mon; bool _M_intl; };

  /**
   *  @brief  Extended manipulator for extracting money.
   *  @param  __mon  Either long double or a specialization of @c basic_string.
   *  @param  __intl A bool indicating whether international format 
   *                 is to be used.
   *
   *  Sent to a stream object, this manipulator extracts @a __mon.
  */
  template<typename _MoneyT>
    inline _Get_money<_MoneyT>
    get_money(_MoneyT& __mon, bool __intl = false)
    { return { __mon, __intl }; }

  template<typename _CharT, typename _Traits, typename _MoneyT>
    basic_istream<_CharT, _Traits>&
    operator>>(basic_istream<_CharT, _Traits>& __is, _Get_money<_MoneyT> __f)
    {
      typename basic_istream<_CharT, _Traits>::sentry __cerb(__is, false);
      if (__cerb)
	{
	  ios_base::iostate __err = ios_base::goodbit;
	  __try
	    {
	      typedef istreambuf_iterator<_CharT, _Traits>   _Iter;
	      typedef money_get<_CharT, _Iter>               _MoneyGet;

	      const _MoneyGet& __mg = use_facet<_MoneyGet>(__is.getloc());
	      __mg.get(_Iter(__is.rdbuf()), _Iter(), __f._M_intl,
		       __is, __err, __f._M_mon);
	    }
	  __catch(__cxxabiv1::__forced_unwind&)
	    {
	      __is._M_setstate(ios_base::badbit);
	      __throw_exception_again;
	    }
	  __catch(...)
	    { __is._M_setstate(ios_base::badbit); }
	  if (__err)
	    __is.setstate(__err);
	}
      return __is; 
    }


  template<typename _MoneyT>
    struct _Put_money { const _MoneyT& _M_mon; bool _M_intl; };

  /**
   *  @brief  Extended manipulator for inserting money.
   *  @param  __mon  Either long double or a specialization of @c basic_string.
   *  @param  __intl A bool indicating whether international format 
   *                 is to be used.
   *
   *  Sent to a stream object, this manipulator inserts @a __mon.
  */
  template<typename _MoneyT>
    inline _Put_money<_MoneyT>
    put_money(const _MoneyT& __mon, bool __intl = false)
    { return { __mon, __intl }; }

  template<typename _CharT, typename _Traits, typename _MoneyT>
    basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __os, _Put_money<_MoneyT> __f)
    {
      typename basic_ostream<_CharT, _Traits>::sentry __cerb(__os);
      if (__cerb)
	{
	  ios_base::iostate __err = ios_base::goodbit;
	  __try
	    {
	      typedef ostreambuf_iterator<_CharT, _Traits>   _Iter;
	      typedef money_put<_CharT, _Iter>               _MoneyPut;

	      const _MoneyPut& __mp = use_facet<_MoneyPut>(__os.getloc());
	      if (__mp.put(_Iter(__os.rdbuf()), __f._M_intl, __os,
			   __os.fill(), __f._M_mon).failed())
		__err |= ios_base::badbit;
	    }
	  __catch(__cxxabiv1::__forced_unwind&)
	    {
	      __os._M_setstate(ios_base::badbit);
	      __throw_exception_again;
	    }
	  __catch(...)
	    { __os._M_setstate(ios_base::badbit); }
	  if (__err)
	    __os.setstate(__err);
	}
      return __os; 
    }

#if __cplusplus > 201103L

#define __cpp_lib_quoted_string_io 201304

_GLIBCXX_END_NAMESPACE_VERSION
  namespace __detail {
  _GLIBCXX_BEGIN_NAMESPACE_VERSION

    /**
     * @brief Struct for delimited strings.
     */
    template<typename _String, typename _CharT>
      struct _Quoted_string
      {
	static_assert(is_reference<_String>::value
		   || is_pointer<_String>::value,
		      "String type must be pointer or reference");

	_Quoted_string(_String __str, _CharT __del, _CharT __esc)
	: _M_string(__str), _M_delim{__del}, _M_escape{__esc}
	{ }

	_Quoted_string&
	operator=(_Quoted_string&) = delete;

	_String _M_string;
	_CharT _M_delim;
	_CharT _M_escape;
      };

    /**
     * @brief Inserter for quoted strings.
     *
     *  _GLIBCXX_RESOLVE_LIB_DEFECTS
     *  DR 2344 quoted()'s interaction with padding is unclear
     */
    template<typename _CharT, typename _Traits>
      auto&
      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		 const _Quoted_string<const _CharT*, _CharT>& __str)
      {
	std::basic_ostringstream<_CharT, _Traits> __ostr;
	__ostr << __str._M_delim;
	for (const _CharT* __c = __str._M_string; *__c; ++__c)
	  {
	    if (*__c == __str._M_delim || *__c == __str._M_escape)
	      __ostr << __str._M_escape;
	    __ostr << *__c;
	  }
	__ostr << __str._M_delim;

	return __os << __ostr.str();
      }

    /**
     * @brief Inserter for quoted strings.
     *
     *  _GLIBCXX_RESOLVE_LIB_DEFECTS
     *  DR 2344 quoted()'s interaction with padding is unclear
     */
    template<typename _CharT, typename _Traits, typename _String>
      auto&
      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
		 const _Quoted_string<_String, _CharT>& __str)
      {
	std::basic_ostringstream<_CharT, _Traits> __ostr;
	__ostr << __str._M_delim;
	for (auto& __c : __str._M_string)
	  {
	    if (__c == __str._M_delim || __c == __str._M_escape)
	      __ostr << __str._M_escape;
	    __ostr << __c;
	  }
	__ostr << __str._M_delim;

	return __os << __ostr.str();
      }

    /**
     * @brief Extractor for delimited strings.
     *        The left and right delimiters can be different.
     */
    template<typename _CharT, typename _Traits, typename _Alloc>
      auto&
      operator>>(std::basic_istream<_CharT, _Traits>& __is,
		 const _Quoted_string<basic_string<_CharT, _Traits, _Alloc>&,
				      _CharT>& __str)
      {
	_CharT __c;
	__is >> __c;
	if (!__is.good())
	  return __is;
	if (__c != __str._M_delim)
	  {
	    __is.unget();
	    __is >> __str._M_string;
	    return __is;
	  }
	__str._M_string.clear();
	std::ios_base::fmtflags __flags
	  = __is.flags(__is.flags() & ~std::ios_base::skipws);
	do
	  {
	    __is >> __c;
	    if (!__is.good())
	      break;
	    if (__c == __str._M_escape)
	      {
		__is >> __c;
		if (!__is.good())
		  break;
	      }
	    else if (__c == __str._M_delim)
	      break;
	    __str._M_string += __c;
	  }
	while (true);
	__is.setf(__flags);

	return __is;
      }
  _GLIBCXX_END_NAMESPACE_VERSION
  } // namespace __detail
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @brief Manipulator for quoted strings.
   * @param __str    String to quote.
   * @param __delim  Character to quote string with.
   * @param __escape Escape character to escape itself or quote character.
   */
  template<typename _CharT>
    inline auto
    quoted(const _CharT* __string,
	   _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
    {
      return __detail::_Quoted_string<const _CharT*, _CharT>(__string, __delim,
							     __escape);
    }

  template<typename _CharT, typename _Traits, typename _Alloc>
    inline auto
    quoted(const basic_string<_CharT, _Traits, _Alloc>& __string,
	   _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
    {
      return __detail::_Quoted_string<
			const basic_string<_CharT, _Traits, _Alloc>&, _CharT>(
				__string, __delim, __escape);
    }

  template<typename _CharT, typename _Traits, typename _Alloc>
    inline auto
    quoted(basic_string<_CharT, _Traits, _Alloc>& __string,
	   _CharT __delim = _CharT('"'), _CharT __escape = _CharT('\\'))
    {
      return __detail::_Quoted_string<
			basic_string<_CharT, _Traits, _Alloc>&, _CharT>(
				__string, __delim, __escape);
    }

#endif // __cplusplus > 201103L

#endif // __cplusplus >= 201103L

  // Inhibit implicit instantiations for required instantiations,
  // which are defined via explicit instantiations elsewhere.  
  // NB:  This syntax is a GNU extension.
#if _GLIBCXX_EXTERN_TEMPLATE
  extern template ostream& operator<<(ostream&, _Setfill<char>);
  extern template ostream& operator<<(ostream&, _Setiosflags);
  extern template ostream& operator<<(ostream&, _Resetiosflags);
  extern template ostream& operator<<(ostream&, _Setbase);
  extern template ostream& operator<<(ostream&, _Setprecision);
  extern template ostream& operator<<(ostream&, _Setw);
  extern template istream& operator>>(istream&, _Setfill<char>);
  extern template istream& operator>>(istream&, _Setiosflags);
  extern template istream& operator>>(istream&, _Resetiosflags);
  extern template istream& operator>>(istream&, _Setbase);
  extern template istream& operator>>(istream&, _Setprecision);
  extern template istream& operator>>(istream&, _Setw);

#ifdef _GLIBCXX_USE_WCHAR_T
  extern template wostream& operator<<(wostream&, _Setfill<wchar_t>);
  extern template wostream& operator<<(wostream&, _Setiosflags);
  extern template wostream& operator<<(wostream&, _Resetiosflags);
  extern template wostream& operator<<(wostream&, _Setbase);
  extern template wostream& operator<<(wostream&, _Setprecision);
  extern template wostream& operator<<(wostream&, _Setw);
  extern template wistream& operator>>(wistream&, _Setfill<wchar_t>);
  extern template wistream& operator>>(wistream&, _Setiosflags);
  extern template wistream& operator>>(wistream&, _Resetiosflags);
  extern template wistream& operator>>(wistream&, _Setbase);
  extern template wistream& operator>>(wistream&, _Setprecision);
  extern template wistream& operator>>(wistream&, _Setw);
#endif
#endif

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif /* _GLIBCXX_IOMANIP */
