first commit
This commit is contained in:
413
extern/stdcxx/4.2.1/include/loc/_money_put.cc
vendored
Normal file
413
extern/stdcxx/4.2.1/include/loc/_money_put.cc
vendored
Normal file
@@ -0,0 +1,413 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* _money_put.cc - definition of std::num_put members
|
||||
*
|
||||
* $Id: _money_put.cc 651012 2008-04-23 19:10:45Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 1994-2008 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <streambuf>
|
||||
#include <loc/_moneypunct.h>
|
||||
#include <loc/_ctype.h>
|
||||
|
||||
|
||||
_RWSTD_NAMESPACE (__rw) {
|
||||
|
||||
_RWSTD_EXPORT _RWSTD_SIZE_T
|
||||
__rw_put_num (char**, _RWSTD_SIZE_T, unsigned, int, _RWSTD_STREAMSIZE,
|
||||
const void*, const char*);
|
||||
|
||||
_RWSTD_EXPORT _RWSTD_SIZE_T
|
||||
__rw_put_groups (char **, _RWSTD_SIZE_T, _RWSTD_SIZE_T,
|
||||
const char*, const char*);
|
||||
|
||||
} // namespace __rw
|
||||
|
||||
|
||||
_RWSTD_NAMESPACE (std) {
|
||||
|
||||
|
||||
template <class _CharT, class _OutputIter>
|
||||
_RW::__rw_facet_id money_put<_CharT, _OutputIter>::id;
|
||||
|
||||
|
||||
template <class _CharT, class _OutputIter>
|
||||
/* private */ _TYPENAME money_put<_CharT, _OutputIter>::iter_type
|
||||
money_put<_CharT, _OutputIter>::
|
||||
_C_put (iter_type __it, int __opts, ios_base &__flags, char_type __fill,
|
||||
const char_type *__s, _RWSTD_SIZE_T __n, int __fd,
|
||||
const char *__groups, _RWSTD_SIZE_T __ngroups) const
|
||||
{
|
||||
// static const arrays of pointers to moneypunct<charT, Intl> members
|
||||
// to avoid "if (intl)" conditionals when retrieving punct values
|
||||
|
||||
const bool __intl = 0 != (__opts & _C_intl);
|
||||
const bool __num = 0 != (__opts & _C_ldbl);
|
||||
|
||||
typedef moneypunct<_CharT, false> _Punct0;
|
||||
typedef moneypunct<_CharT, true> _Punct1;
|
||||
|
||||
const _Punct0* __pun0;
|
||||
const _Punct1* __pun1;
|
||||
|
||||
#ifdef __GNUG__
|
||||
// silence bogus gcc -Wuninitialized warning:
|
||||
// object may be used uninitialized in this function
|
||||
// while avoiding bogus HP aCC/cadvise warning 20200:
|
||||
// potential null pointer dereference
|
||||
__pun0 = 0;
|
||||
__pun1 = 0;
|
||||
#endif // gcc
|
||||
|
||||
if (__intl) {
|
||||
__pun1 = &_RWSTD_USE_FACET (_Punct1, __flags.getloc ());
|
||||
}
|
||||
else {
|
||||
__pun0 = &_RWSTD_USE_FACET (_Punct0, __flags.getloc ());
|
||||
}
|
||||
|
||||
const ctype<_CharT> &__ctp =
|
||||
_RWSTD_USE_FACET (ctype<_CharT>,__flags.getloc ());
|
||||
|
||||
const char __signchar = __ctp.narrow (*__s, '\0');
|
||||
|
||||
money_base::pattern __fmat; // negative or positive format
|
||||
string_type __sign; // negative or positive sign
|
||||
|
||||
if ('-' == __signchar) {
|
||||
if (__intl) {
|
||||
__fmat = __pun1->neg_format ();
|
||||
__sign = __pun1->negative_sign ();
|
||||
}
|
||||
else {
|
||||
__fmat = __pun0->neg_format ();
|
||||
__sign = __pun0->negative_sign ();
|
||||
}
|
||||
++__s;
|
||||
--__n;
|
||||
}
|
||||
else {
|
||||
if (__intl) {
|
||||
__fmat = __pun1->pos_format ();
|
||||
__sign = __pun1->positive_sign ();
|
||||
}
|
||||
else {
|
||||
__fmat = __pun0->pos_format ();
|
||||
__sign = __pun0->positive_sign ();
|
||||
}
|
||||
if ('+' == __signchar) {
|
||||
++__s;
|
||||
--__n;
|
||||
}
|
||||
}
|
||||
|
||||
// optional currency sumbol
|
||||
const string_type __curr = (__flags.flags () & _RWSTD_IOS_SHOWBASE) ?
|
||||
__intl ? __pun1->curr_symbol () : __pun0->curr_symbol ()
|
||||
: string_type ();
|
||||
|
||||
// size of fractional and integral parts, respectively, to output
|
||||
long __dint = long (__n - __fd);
|
||||
|
||||
// must have at least one group (even if there are no thousands_sep)
|
||||
_RWSTD_ASSERT (__ngroups > 0);
|
||||
|
||||
// adjust padding by the sizes of each component, including the
|
||||
// number of thousands separators to be inserted
|
||||
long __pad = long (
|
||||
__flags.width () - __curr.size () - __sign.size ()
|
||||
- !__dint - !!__fd - (__dint > 0 ? __dint : -__dint) - __fd
|
||||
- ( money_base::space == __fmat.field [1]
|
||||
|| money_base::space == __fmat.field [2])
|
||||
- (__ngroups - 1));
|
||||
|
||||
const int __adj = __flags.flags () & _RWSTD_IOS_ADJUSTFIELD;
|
||||
|
||||
if (__adj != _RWSTD_IOS_INTERNAL && __adj != _RWSTD_IOS_LEFT) {
|
||||
|
||||
for (; __pad > 0; --__pad, ++__it)
|
||||
*__it = __fill;
|
||||
}
|
||||
|
||||
for (_RWSTD_SIZE_T __i = 0, __j; __i != sizeof __fmat; ++__i) {
|
||||
|
||||
switch (__fmat.field [__i]) {
|
||||
|
||||
case money_base::symbol: // exactly one occurrence required
|
||||
for (__j = 0; __j != __curr.size (); ++__j, ++__it)
|
||||
*__it = __curr [__j];
|
||||
break;
|
||||
|
||||
case money_base::sign: // exactly one occurrence required
|
||||
if (__sign.size ()) {
|
||||
// first character of sign only
|
||||
*__it = __sign [0];
|
||||
++__it;
|
||||
}
|
||||
break;
|
||||
|
||||
case money_base::space: // optional (required if none not present)
|
||||
// 22.2.6.3, p1: the value space, if present,
|
||||
// is neither first nor last.
|
||||
|
||||
_RWSTD_REQUIRES (0 != __i && sizeof __fmat != __i - 1,
|
||||
(_RWSTD_ERROR_RUNTIME_ERROR,
|
||||
_RWSTD_FUNC ("std::num_put<>::do_put()")));
|
||||
|
||||
// an ordinary space, not `fill', is required here
|
||||
// will precede any required padding
|
||||
*__it = __ctp.widen (' ');
|
||||
++__it;
|
||||
|
||||
case money_base::none: // optional (required if space not present)
|
||||
// 22.2.6.3, p1: the value none, if present, is not first
|
||||
|
||||
_RWSTD_REQUIRES (0 != __i,
|
||||
(_RWSTD_ERROR_RUNTIME_ERROR,
|
||||
_RWSTD_FUNC ("std::num_put<>::do_put()")));
|
||||
|
||||
if ( (__adj & _RWSTD_IOS_ADJUSTFIELD) == _RWSTD_IOS_INTERNAL
|
||||
&& sizeof __fmat != __i - 1)
|
||||
for (; __pad > 0; --__pad, ++__it)
|
||||
*__it = __fill;
|
||||
|
||||
break;
|
||||
|
||||
case money_base::value: { // exactly one occurrence required
|
||||
|
||||
if (__dint < 0 || 0 == __dint && __fd > 0) {
|
||||
const char_type __zero = __ctp.widen ('0');
|
||||
|
||||
// insert leading zero and decimal point
|
||||
*__it = __zero;
|
||||
++__it;
|
||||
|
||||
*__it = __intl ?
|
||||
__pun1->decimal_point () : __pun0->decimal_point ();
|
||||
++__it;
|
||||
|
||||
// insert leading fractional zeros
|
||||
for (; __dint++; ++__it)
|
||||
*__it = __zero;
|
||||
|
||||
// prevent insertion of the decimal point below
|
||||
__dint = -1;
|
||||
}
|
||||
|
||||
_RWSTD_SIZE_T __grplen = 0;
|
||||
|
||||
for (const char_type *__e = __s + __n; __s != __e; ++__it, ++__s) {
|
||||
|
||||
if (!__num && !__ctp.is (ctype_base::digit, *__s))
|
||||
break;
|
||||
|
||||
typedef unsigned char _UChar;
|
||||
|
||||
if (0 < __dint) {
|
||||
|
||||
_RWSTD_ASSERT (0 != __groups);
|
||||
|
||||
if (*__groups && __grplen == _UChar (*__groups)) {
|
||||
*__it = __intl ? __pun1->thousands_sep ()
|
||||
: __pun0->thousands_sep ();
|
||||
__grplen = 0;
|
||||
++__groups;
|
||||
++__it;
|
||||
}
|
||||
}
|
||||
else if (0 == __dint) {
|
||||
*__it = __intl ? __pun1->decimal_point ()
|
||||
: __pun0->decimal_point ();
|
||||
++__it;
|
||||
}
|
||||
|
||||
--__dint;
|
||||
++__grplen;
|
||||
|
||||
switch (*__s) {
|
||||
// replace either the period or the comma with the
|
||||
// decimal point in case a setlocale() call made by
|
||||
// the program changed the default '.' to ','
|
||||
case '.':
|
||||
case ',':
|
||||
*__it = __intl ? __pun1->decimal_point ()
|
||||
: __pun0->decimal_point ();
|
||||
break;
|
||||
|
||||
case ';':
|
||||
*__it = __intl ? __pun1->thousands_sep ()
|
||||
: __pun0->thousands_sep ();
|
||||
break;
|
||||
|
||||
default: *__it = *__s;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// output the remaining characters of sign (if any)
|
||||
for (_RWSTD_SIZE_T __k = 1; __k < __sign.size (); ++__k, ++__it)
|
||||
*__it = __sign [__k];
|
||||
|
||||
// left ajustment
|
||||
for (; __pad > 0; --__pad, ++__it)
|
||||
*__it = __fill;
|
||||
|
||||
// 22.2.6.2.2, p1: reset width()
|
||||
__flags.width (0);
|
||||
|
||||
return __it;
|
||||
}
|
||||
|
||||
|
||||
template <class _CharT, class _OutputIter>
|
||||
/* virtual */ _TYPENAME money_put<_CharT, _OutputIter>::iter_type
|
||||
money_put<_CharT, _OutputIter>::
|
||||
do_put (iter_type __i, bool __intl, ios_base &__flags, char_type __fill,
|
||||
long double __val) const
|
||||
{
|
||||
int __fd;
|
||||
string __grouping;
|
||||
|
||||
if (__intl) {
|
||||
typedef moneypunct<_CharT, true> _Punct;
|
||||
const _Punct &__pun = _RWSTD_USE_FACET (_Punct, __flags.getloc ());
|
||||
|
||||
__fd = __pun.frac_digits ();
|
||||
__grouping = __pun.grouping ();
|
||||
}
|
||||
else {
|
||||
typedef moneypunct<_CharT, false> _Punct;
|
||||
const _Punct &__pun = _RWSTD_USE_FACET (_Punct, __flags.getloc ());
|
||||
|
||||
__fd = __pun.frac_digits ();
|
||||
__grouping = __pun.grouping ();
|
||||
}
|
||||
|
||||
char __buf [304];
|
||||
char_type __wbuf [sizeof __buf];
|
||||
|
||||
char *__pbuf = __buf;
|
||||
|
||||
// format a floating point number in fixed precision into narrow buffer
|
||||
// will insert thousands_sep placeholders (';') accroding to grouping
|
||||
const _RWSTD_SIZE_T __n =
|
||||
_RW::__rw_put_num (&__pbuf, sizeof __buf, _RWSTD_IOS_FIXED,
|
||||
_C_ldouble | _C_ptr,
|
||||
_RWSTD_STATIC_CAST (_RWSTD_STREAMSIZE, -__fd),
|
||||
&__val, __grouping.c_str ());
|
||||
|
||||
// widen narrow buffer (necessary even if char_type == char)
|
||||
const ctype<_CharT> &__ctp =
|
||||
_RWSTD_USE_FACET (ctype<_CharT>, __flags.getloc ());
|
||||
|
||||
__ctp.widen (__buf, __buf + __n, __wbuf);
|
||||
|
||||
// write the widened buffer out, replacing any commas
|
||||
// with the actual thousands_sep punct character
|
||||
return _C_put (__i, (__intl ? _C_intl : 0) | _C_ldbl,
|
||||
__flags, __fill, __wbuf, __n, 0, "", 1);
|
||||
}
|
||||
|
||||
|
||||
template <class _CharT, class _OutputIter>
|
||||
/* virtual */ _TYPENAME money_put<_CharT, _OutputIter>::iter_type
|
||||
money_put<_CharT, _OutputIter>::
|
||||
do_put (iter_type __i, bool __intl, ios_base &__flags, char_type __fill,
|
||||
const string_type &__str) const
|
||||
{
|
||||
// fractional part does not undergo grouping and will be removed
|
||||
int __fd;
|
||||
|
||||
string __grouping;
|
||||
|
||||
if (__intl) {
|
||||
typedef moneypunct<_CharT, true> _Punct;
|
||||
|
||||
const _Punct &__pun = _RWSTD_USE_FACET (_Punct, __flags.getloc ());
|
||||
|
||||
__fd = __pun.frac_digits ();
|
||||
__grouping = __pun.grouping ();
|
||||
}
|
||||
else {
|
||||
typedef moneypunct<_CharT, false> _Punct;
|
||||
|
||||
const _Punct &__pun = _RWSTD_USE_FACET (_Punct, __flags.getloc ());
|
||||
|
||||
__fd = __pun.frac_digits ();
|
||||
__grouping = __pun.grouping ();
|
||||
}
|
||||
|
||||
_RWSTD_SIZE_T __ngroups = 1; // always at least one group
|
||||
_RWSTD_SIZE_T __strdigs = 0; // number of digits in `str'
|
||||
|
||||
typedef string::traits_type _Traits;
|
||||
typedef _TYPENAME string_type::const_iterator _StringIter;
|
||||
|
||||
char __buf [304]; // buffer for groups
|
||||
static char __nul = '\0'; // `groups' must be non-0
|
||||
char *__groups = __grouping.size () ? __buf : &__nul;
|
||||
|
||||
const ctype<_CharT> &__ctp =
|
||||
_RWSTD_USE_FACET (ctype<_CharT>, __flags.getloc ());
|
||||
|
||||
// narrow digits into a temporary buffer to determine grouping
|
||||
for (_StringIter __it = __str.begin (); __it != __str.end (); ++__it) {
|
||||
if (__ctp.is (ctype_base::digit, *__it)) {
|
||||
if (__groups != &__nul)
|
||||
_Traits::assign (*__groups++, __ctp.narrow (*__it, '\0'));
|
||||
}
|
||||
else if (__str.begin () != __it || '-' != __ctp.narrow (*__it, '\0'))
|
||||
break;
|
||||
++__strdigs;
|
||||
}
|
||||
|
||||
if (__groups != &__nul && __fd >= 0 && __fd < __groups - __buf) {
|
||||
__groups -= __fd;
|
||||
|
||||
// compute the size of each group relative to the formatted number
|
||||
// e.g., with `str' of "9876543210" and `grouping' of "\1\2\3",
|
||||
// `groups' will point at "\1\3\3\2\1" since `str' will be
|
||||
// formatted as "9,876,543,21,0" with thousands_sep's inserted
|
||||
|
||||
char *__pbuf = __buf;
|
||||
|
||||
*__pbuf = '\0';
|
||||
|
||||
__ngroups =
|
||||
_RW::__rw_put_groups (&__pbuf, __groups - __pbuf, sizeof __buf,
|
||||
0, __grouping.c_str ());
|
||||
__pbuf [__ngroups] = '\0';
|
||||
__groups = __pbuf;
|
||||
}
|
||||
|
||||
return _C_put (__i, __intl ? _C_intl : 0,
|
||||
__flags, __fill, __str.c_str (), __strdigs,
|
||||
__fd, __groups, __ngroups);
|
||||
}
|
||||
|
||||
|
||||
} // namespace std
|
||||
Reference in New Issue
Block a user