/*
 * Copyright (c) 1999
 * Silicon Graphics Computer Systems, Inc.
 *
 * Copyright (c) 1999
 * Boris Fomitchev
 *
 * This material is provided "as is", with absolutely no warranty expressed
 * or implied. Any use is at your own risk.
 *
 * Permission to use or copy this software for any purpose is hereby granted
 * without fee, provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 *
 */
#ifndef _STLP_NUM_PUT_C
#define _STLP_NUM_PUT_C

#ifndef _STLP_INTERNAL_NUM_PUT_H
#  include <stl/_num_put.h>
#endif

#ifndef _STLP_INTERNAL_LIMITS
#  include <stl/_limits.h>
#endif

_STLP_BEGIN_NAMESPACE

_STLP_MOVE_TO_PRIV_NAMESPACE

// __do_put_float and its helper functions.  Strategy: write the output
// to a buffer of char, transform the buffer to _CharT, and then copy
// it to the output.

//----------------------------------------------------------------------
// num_put facet

template <class _CharT, class _OutputIter>
_OutputIter  _STLP_CALL
__copy_float_and_fill(const _CharT* __first, const _CharT* __last,
                      _OutputIter __oi,
                      ios_base::fmtflags __flags,
                      streamsize __width, _CharT __fill,
                      _CharT __xplus, _CharT __xminus) {
  if (__width <= __last - __first)
    return copy(__first, __last, __oi);
  else {
    streamsize __pad = __width - (__last - __first);
    ios_base::fmtflags __dir = __flags & ios_base::adjustfield;

    if (__dir == ios_base::left) {
      __oi = copy(__first, __last, __oi);
      return __fill_n(__oi, __pad, __fill);
    }
    else if (__dir == ios_base::internal && __first != __last &&
             (*__first == __xplus || *__first == __xminus)) {
      *__oi++ = *__first++;
      __oi = __fill_n(__oi, __pad, __fill);
      return copy(__first, __last, __oi);
    }
    else {
      __oi = __fill_n(__oi, __pad, __fill);
      return copy(__first, __last, __oi);
    }
  }
}

#if !defined (_STLP_NO_WCHAR_T)
// Helper routine for wchar_t
template <class _OutputIter>
_OutputIter  _STLP_CALL
__put_float(__iostring &__str, _OutputIter __oi,
            ios_base& __f, wchar_t __fill,
            wchar_t __decimal_point, wchar_t __sep,
            size_t __group_pos, const string& __grouping) {
  const ctype<wchar_t>& __ct = *__STATIC_CAST(const ctype<wchar_t>*, __f._M_ctype_facet());

  __iowstring __wbuf;
  __convert_float_buffer(__str, __wbuf, __ct, __decimal_point);

  if (!__grouping.empty()) {
    __insert_grouping(__wbuf, __group_pos, __grouping,
                      __sep, __ct.widen('+'), __ct.widen('-'), 0);
  }

  return __copy_float_and_fill(__CONST_CAST(wchar_t*, __wbuf.data()),
                               __CONST_CAST(wchar_t*, __wbuf.data()) + __wbuf.size(), __oi,
                               __f.flags(), __f.width(0), __fill, __ct.widen('+'), __ct.widen('-'));
}
#endif /* WCHAR_T */

// Helper routine for char
template <class _OutputIter>
_OutputIter  _STLP_CALL
__put_float(__iostring &__str, _OutputIter __oi,
            ios_base& __f, char __fill,
            char __decimal_point, char __sep,
            size_t __group_pos, const string& __grouping) {
  if ((__group_pos < __str.size()) && (__str[__group_pos] == '.')) {
    __str[__group_pos] = __decimal_point;
  }

  if (!__grouping.empty()) {
    __insert_grouping(__str, __group_pos,
                      __grouping, __sep, '+', '-', 0);
  }

  return __copy_float_and_fill(__CONST_CAST(char*, __str.data()),
                               __CONST_CAST(char*, __str.data()) + __str.size(), __oi,
                               __f.flags(), __f.width(0), __fill, '+', '-');
}

template <class _CharT, class _OutputIter, class _Float>
_OutputIter _STLP_CALL
__do_put_float(_OutputIter __s, ios_base& __f,
                _CharT __fill, _Float __x) {
  __iostring __buf;

  size_t __group_pos = __write_float(__buf, __f.flags(), (int)__f.precision(), __x);

  const numpunct<_CharT>& __np = *__STATIC_CAST(const numpunct<_CharT>*, __f._M_numpunct_facet());

  return __put_float(__buf, __s, __f, __fill,
                     __np.decimal_point(), __np.thousands_sep(),
                     __group_pos, __f._M_grouping());
}

inline void __get_money_digits_aux (__iostring &__buf, ios_base &, _STLP_LONGEST_FLOAT_TYPE __x)
{ __get_floor_digits(__buf, __x); }

#if !defined (_STLP_NO_WCHAR_T)
inline void __get_money_digits_aux (__iowstring &__wbuf, ios_base &__f, _STLP_LONGEST_FLOAT_TYPE __x) {
  __iostring __buf;
  __get_floor_digits(__buf, __x);

  const ctype<wchar_t>& __ct = *__STATIC_CAST(const ctype<wchar_t>*, __f._M_ctype_facet());
  __convert_float_buffer(__buf, __wbuf, __ct, wchar_t(0), false);
}
#endif

template <class _CharT>
void _STLP_CALL __get_money_digits(_STLP_BASIC_IOSTRING(_CharT) &__buf, ios_base& __f, _STLP_LONGEST_FLOAT_TYPE __x)
{ __get_money_digits_aux(__buf, __f, __x); }

// _M_do_put_integer and its helper functions.

template <class _CharT, class _OutputIter>
_OutputIter _STLP_CALL
__copy_integer_and_fill(const _CharT* __buf, ptrdiff_t __len,
                        _OutputIter __oi,
                        ios_base::fmtflags __flg, streamsize __wid, _CharT __fill,
                        _CharT __xplus, _CharT __xminus) {
  if (__len >= __wid)
    return copy(__buf, __buf + __len, __oi);
  else {
    //casting numeric_limits<ptrdiff_t>::max to streamsize only works is ptrdiff_t is signed or streamsize representation
    //is larger than ptrdiff_t one.
    _STLP_STATIC_ASSERT(((sizeof(streamsize) > sizeof(ptrdiff_t)) ||
                         (sizeof(streamsize) == sizeof(ptrdiff_t))) && numeric_limits<ptrdiff_t>::is_signed)
    ptrdiff_t __pad = __STATIC_CAST(ptrdiff_t, (min) (__STATIC_CAST(streamsize, (numeric_limits<ptrdiff_t>::max)()),
                                                      __STATIC_CAST(streamsize, __wid - __len)));
    ios_base::fmtflags __dir = __flg & ios_base::adjustfield;

    if (__dir == ios_base::left) {
      __oi = copy(__buf, __buf + __len, __oi);
      return __fill_n(__oi, __pad, __fill);
    }
    else if (__dir == ios_base::internal && __len != 0 &&
             (__buf[0] == __xplus || __buf[0] == __xminus)) {
      *__oi++ = __buf[0];
      __oi = __fill_n(__oi, __pad, __fill);
      return copy(__buf + 1, __buf + __len, __oi);
    }
    else if (__dir == ios_base::internal && __len >= 2  &&
             (__flg & ios_base::showbase) &&
             (__flg & ios_base::basefield) == ios_base::hex) {
      *__oi++ = __buf[0];
      *__oi++ = __buf[1];
      __oi = __fill_n(__oi, __pad, __fill);
      return copy(__buf + 2, __buf + __len, __oi);
    }
    else {
      __oi = __fill_n(__oi, __pad, __fill);
      return copy(__buf, __buf + __len, __oi);
    }
  }
}

#if !defined (_STLP_NO_WCHAR_T)
// Helper function for wchar_t
template <class _OutputIter>
_OutputIter _STLP_CALL
__put_integer(char* __buf, char* __iend, _OutputIter __s,
              ios_base& __f,
              ios_base::fmtflags __flags, wchar_t __fill) {
  locale __loc = __f.getloc();
  //  const ctype<wchar_t>& __ct = use_facet<ctype<wchar_t> >(__loc);
  const ctype<wchar_t>& __ct = *__STATIC_CAST(const ctype<wchar_t>*, __f._M_ctype_facet());

  wchar_t __xplus  = __ct.widen('+');
  wchar_t __xminus = __ct.widen('-');

  wchar_t __wbuf[64];
  __ct.widen(__buf, __iend, __wbuf);
  ptrdiff_t __len = __iend - __buf;
  wchar_t* __eend = __wbuf + __len;

  //  const numpunct<wchar_t>& __np = use_facet<numpunct<wchar_t> >(__loc);
  //  const string& __grouping = __np.grouping();

  const numpunct<wchar_t>& __np = *__STATIC_CAST(const numpunct<wchar_t>*, __f._M_numpunct_facet());
  const string& __grouping = __f._M_grouping();

  if (!__grouping.empty()) {
    int __basechars;
    if (__flags & ios_base::showbase)
      switch (__flags & ios_base::basefield) {
        case ios_base::hex: __basechars = 2; break;
        case ios_base::oct: __basechars = 1; break;
        default: __basechars = 0;
      }
    else
      __basechars = 0;

    __len = __insert_grouping(__wbuf, __eend, __grouping, __np.thousands_sep(),
                              __xplus, __xminus, __basechars);
  }

  return __copy_integer_and_fill((wchar_t*)__wbuf, __len, __s,
                                 __flags, __f.width(0), __fill, __xplus, __xminus);
}
#endif

// Helper function for char
template <class _OutputIter>
_OutputIter _STLP_CALL
__put_integer(char* __buf, char* __iend, _OutputIter __s,
              ios_base& __f, ios_base::fmtflags __flags, char __fill) {
  char __grpbuf[64];
  ptrdiff_t __len = __iend - __buf;

  //  const numpunct<char>& __np = use_facet<numpunct<char> >(__f.getloc());
  //  const string& __grouping = __np.grouping();

  const numpunct<char>& __np = *__STATIC_CAST(const numpunct<char>*, __f._M_numpunct_facet());
  const string& __grouping = __f._M_grouping();

  if (!__grouping.empty()) {
    int __basechars;
    if (__flags & ios_base::showbase)
      switch (__flags & ios_base::basefield) {
        case ios_base::hex: __basechars = 2; break;
        case ios_base::oct: __basechars = 1; break;
        default: __basechars = 0;
      }
    else
      __basechars = 0;

     // make sure there is room at the end of the buffer
     // we pass to __insert_grouping
    copy(__buf, __iend, (char *) __grpbuf);
    __buf = __grpbuf;
    __iend = __grpbuf + __len;
    __len = __insert_grouping(__buf, __iend, __grouping, __np.thousands_sep(),
                              '+', '-', __basechars);
  }

  return __copy_integer_and_fill(__buf, __len, __s, __flags, __f.width(0), __fill, '+', '-');
}

#if defined (_STLP_LONG_LONG)
typedef _STLP_LONG_LONG __max_int_t;
typedef unsigned _STLP_LONG_LONG __umax_int_t;
#else
typedef long __max_int_t;
typedef unsigned long __umax_int_t;
#endif

_STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_lo();
_STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_hi();

template <class _Integer>
inline char* _STLP_CALL
__write_decimal_backward(char* __ptr, _Integer __x, ios_base::fmtflags __flags, const __true_type& /* is_signed */) {
  const bool __negative = __x < 0 ;
  __max_int_t __temp = __x;
  __umax_int_t __utemp = __negative?-__temp:__temp;

  for (; __utemp != 0; __utemp /= 10)
    *--__ptr = (char)((int)(__utemp % 10) + '0');
  // put sign if needed or requested
  if (__negative)
    *--__ptr = '-';
  else if (__flags & ios_base::showpos)
    *--__ptr = '+';
  return __ptr;
}

template <class _Integer>
inline char* _STLP_CALL
__write_decimal_backward(char* __ptr, _Integer __x, ios_base::fmtflags __flags, const __false_type& /* is_signed */) {
  for (; __x != 0; __x /= 10)
    *--__ptr = (char)((int)(__x % 10) + '0');
  // put sign if requested
  if (__flags & ios_base::showpos)
    *--__ptr = '+';
  return __ptr;
}

template <class _Integer>
char* _STLP_CALL
__write_integer_backward(char* __buf, ios_base::fmtflags __flags, _Integer __x) {
  char* __ptr = __buf;

  if (__x == 0) {
    *--__ptr = '0';
    if ((__flags & ios_base::showpos) && ((__flags & (ios_base::oct | ios_base::hex)) == 0))
      *--__ptr = '+';
    // oct or hex base shall not be added to the 0 value (see '#' flag in C formating strings)
  }
  else {
    switch (__flags & ios_base::basefield) {
      case ios_base::oct:
        {
          __umax_int_t __temp = __x;
          // if the size of integer is less than 8, clear upper part
          if ( sizeof(__x) < 8  && sizeof(__umax_int_t) >= 8 )
            __temp &= 0xFFFFFFFF;

          for (; __temp != 0; __temp >>=3)
            *--__ptr = (char)((((unsigned)__temp)& 0x7) + '0');

          // put leading '0' if showbase is set
          if (__flags & ios_base::showbase)
            *--__ptr = '0';
        }
        break;
      case ios_base::hex:
        {
          const char* __table_ptr = (__flags & ios_base::uppercase) ?
            __hex_char_table_hi() : __hex_char_table_lo();
          __umax_int_t __temp = __x;
          // if the size of integer is less than 8, clear upper part
          if ( sizeof(__x) < 8  && sizeof(__umax_int_t) >= 8 )
            __temp &= 0xFFFFFFFF;

          for (; __temp != 0; __temp >>=4)
            *--__ptr = __table_ptr[((unsigned)__temp & 0xF)];

          if (__flags & ios_base::showbase) {
            *--__ptr = __table_ptr[16];
            *--__ptr = '0';
          }
        }
        break;
      //case ios_base::dec:
      default:
        {
#if defined(__HP_aCC) && (__HP_aCC == 1)
          bool _IsSigned = !((_Integer)-1 > 0);
          if (_IsSigned)
            __ptr = __write_decimal_backward(__ptr, __x, __flags, __true_type() );
          else
            __ptr = __write_decimal_backward(__ptr, __x, __flags, __false_type() );
#else
          typedef typename __bool2type<numeric_limits<_Integer>::is_signed>::_Ret _IsSigned;
          __ptr = __write_decimal_backward(__ptr, __x, __flags, _IsSigned());
#endif
        }
        break;
    }
  }

  // return pointer to beginning of the string
  return __ptr;
}

template <class _CharT, class _OutputIter, class _Integer>
_OutputIter _STLP_CALL
__do_put_integer(_OutputIter __s, ios_base& __f, _CharT __fill, _Integer __x) {
  // buffer size = number of bytes * number of digit necessary in the smallest Standard base (base 8, 3 digits/byte)
  //               plus the longest base representation '0x'
  // Do not use __buf_size to define __buf static buffer, some compilers (HP aCC) do not accept const variable as
  // the specification of a static buffer size.
  char __buf[sizeof(_Integer) * 3 + 2];
  const ptrdiff_t __buf_size = sizeof(__buf) / sizeof(char);
  ios_base::fmtflags __flags = __f.flags();
  char* __ibeg = __write_integer_backward((char*)__buf+__buf_size, __flags, __x);
  return __put_integer(__ibeg, (char*)__buf+__buf_size, __s, __f, __flags, __fill);
}

_STLP_MOVE_TO_STD_NAMESPACE

//
// num_put<>
//

#if (_STLP_STATIC_TEMPLATE_DATA > 0)

#  if !defined (__BORLANDC__)
template <class _CharT, class _OutputIterator>
locale::id num_put<_CharT, _OutputIterator>::id;
#  endif

#  if (defined (__CYGWIN__) || defined (__MINGW32__)) && \
       defined (_STLP_USE_DYNAMIC_LIB) && !defined (__BUILDING_STLPORT)
/*
 * Under cygwin, when STLport is used as a shared library, the id needs
 * to be specified as imported otherwise they will be duplicated in the
 * calling executable.
 */
template <>
_STLP_DECLSPEC locale::id num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id;
/*
template <>
_STLP_DECLSPEC locale::id num_put<char, char*>::id;
*/

#    if !defined (_STLP_NO_WCHAR_T)
template <>
_STLP_DECLSPEC locale::id num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id;
/*
template <>
_STLP_DECLSPEC locale::id num_put<wchar_t, wchar_t*>::id;
*/
#    endif

#  endif /* __CYGWIN__ && _STLP_USE_DYNAMIC_LIB */

#else /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */

//typedef num_put<char, char*> num_put_char;
typedef num_put<char, ostreambuf_iterator<char, char_traits<char> > > num_put_char_2;

//__DECLARE_INSTANCE(locale::id, num_put_char::id, );
__DECLARE_INSTANCE(locale::id, num_put_char_2::id, );

#  if !defined (_STLP_NO_WCHAR_T)

//typedef num_put<wchar_t, wchar_t*> num_put_wchar_t;
typedef num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > num_put_wchar_t_2;

//__DECLARE_INSTANCE(locale::id, num_put_wchar_t::id, );
__DECLARE_INSTANCE(locale::id, num_put_wchar_t_2::id, );

#  endif

#endif /* ( _STLP_STATIC_TEMPLATE_DATA > 0 ) */

// issue 118

#if !defined (_STLP_NO_BOOL)
template <class _CharT, class _OutputIter>
_OutputIter
num_put<_CharT, _OutputIter>::do_put(_OutputIter __s, ios_base& __f,
                                     char_type __fill,  bool __val) const {
  if (!(__f.flags() & ios_base::boolalpha))
    return this->do_put(__s, __f, __fill, __STATIC_CAST(long,__val));

  locale __loc = __f.getloc();
  //  typedef numpunct<_CharT> _Punct;
  //  const _Punct& __np = use_facet<_Punct>(__loc);

  const numpunct<_CharT>& __np = *__STATIC_CAST(const numpunct<_CharT>*, __f._M_numpunct_facet());

  basic_string<_CharT> __str = __val ? __np.truename() : __np.falsename();

  // Reuse __copy_integer_and_fill.  Since internal padding makes no
  // sense for bool, though, make sure we use something else instead.
  // The last two argument to __copy_integer_and_fill are dummies.
  ios_base::fmtflags __flags = __f.flags();
  if ((__flags & ios_base::adjustfield) == ios_base::internal)
    __flags = (__flags & ~ios_base::adjustfield) | ios_base::right;

  return _STLP_PRIV __copy_integer_and_fill(__str.c_str(), __str.size(), __s,
                                            __flags, __f.width(0), __fill,
                                            (_CharT) 0, (_CharT) 0);
}

#endif

template <class _CharT, class _OutputIter>
_OutputIter
num_put<_CharT, _OutputIter>::do_put(_OutputIter __s, ios_base& __f, _CharT __fill,
                                     long __val) const
{ return _STLP_PRIV __do_put_integer(__s, __f, __fill, __val); }

template <class _CharT, class _OutputIter>
_OutputIter
num_put<_CharT, _OutputIter>::do_put(_OutputIter __s, ios_base& __f, _CharT __fill,
                                     unsigned long __val) const
{ return _STLP_PRIV __do_put_integer(__s, __f, __fill, __val); }

template <class _CharT, class _OutputIter>
_OutputIter
num_put<_CharT, _OutputIter>::do_put(_OutputIter __s, ios_base& __f, _CharT __fill,
                                     double __val) const
{ return _STLP_PRIV __do_put_float(__s, __f, __fill, __val); }

#if !defined (_STLP_NO_LONG_DOUBLE)
template <class _CharT, class _OutputIter>
_OutputIter
num_put<_CharT, _OutputIter>::do_put(_OutputIter __s, ios_base& __f, _CharT __fill,
                                     long double __val) const
{ return _STLP_PRIV __do_put_float(__s, __f, __fill, __val); }
#endif

#if defined (_STLP_LONG_LONG)
template <class _CharT, class _OutputIter>
_OutputIter
num_put<_CharT, _OutputIter>::do_put(_OutputIter __s, ios_base& __f, _CharT __fill,
                                     _STLP_LONG_LONG __val) const
{ return _STLP_PRIV __do_put_integer(__s, __f, __fill, __val); }

template <class _CharT, class _OutputIter>
_OutputIter
num_put<_CharT, _OutputIter>::do_put(_OutputIter __s, ios_base& __f, _CharT __fill,
                                     unsigned _STLP_LONG_LONG __val) const
{ return _STLP_PRIV __do_put_integer(__s, __f, __fill, __val); }
#endif /* _STLP_LONG_LONG */


// lib.facet.num.put.virtuals "12 For conversion from void* the specifier is %p."
template <class _CharT, class _OutputIter>
_OutputIter
num_put<_CharT, _OutputIter>::do_put(_OutputIter __s, ios_base& __f, _CharT /*__fill*/,
                                     const void* __val) const {
  const ctype<_CharT>& __c_type = *__STATIC_CAST(const ctype<_CharT>*, __f._M_ctype_facet());
  ios_base::fmtflags __save_flags = __f.flags();

  __f.setf(ios_base::hex, ios_base::basefield);
  __f.setf(ios_base::showbase);
  __f.setf(ios_base::internal, ios_base::adjustfield);
  __f.width((sizeof(void*) * 2) + 2); // digits in pointer type plus '0x' prefix
# if defined(_STLP_LONG_LONG) && !defined(__MRC__) //*ty 11/24/2001 - MrCpp can not cast from void* to long long
  _OutputIter result = this->do_put(__s, __f, __c_type.widen('0'), __REINTERPRET_CAST(unsigned _STLP_LONG_LONG,__val));
# else
  _OutputIter result = this->do_put(__s, __f, __c_type.widen('0'), __REINTERPRET_CAST(unsigned long,__val));
# endif
  __f.flags(__save_flags);
  return result;
}

_STLP_END_NAMESPACE

#endif /* _STLP_NUM_PUT_C */

// Local Variables:
// mode:C++
// End:
