| 1 |
/* |
| 2 |
* Copyright (c) 1999 |
| 3 |
* Silicon Graphics Computer Systems, Inc. |
| 4 |
* |
| 5 |
* Copyright (c) 1999 |
| 6 |
* Boris Fomitchev |
| 7 |
* |
| 8 |
* This material is provided "as is", with absolutely no warranty expressed |
| 9 |
* or implied. Any use is at your own risk. |
| 10 |
* |
| 11 |
* Permission to use or copy this software for any purpose is hereby granted |
| 12 |
* without fee, provided the above notices are retained on all copies. |
| 13 |
* Permission to modify the code and to distribute modified code is granted, |
| 14 |
* provided the above notices are retained, and a notice that the code was |
| 15 |
* modified is included with the above copyright notice. |
| 16 |
* |
| 17 |
*/ |
| 18 |
|
| 19 |
#include "stlport_prefix.h" |
| 20 |
|
| 21 |
#include <locale> |
| 22 |
#include <ostream> |
| 23 |
|
| 24 |
_STLP_BEGIN_NAMESPACE |
| 25 |
|
| 26 |
// Note that grouping[0] is the number of digits in the *rightmost* group. |
| 27 |
// We assume, without checking, that *last is null and that there is enough |
| 28 |
// space in the buffer to extend the number past [first, last). |
| 29 |
template <class Char> |
| 30 |
static ptrdiff_t |
| 31 |
__insert_grouping_aux(Char* first, Char* last, const string& grouping, |
| 32 |
Char separator, Char Plus, Char Minus, |
| 33 |
int basechars) { |
| 34 |
typedef string::size_type str_size; |
| 35 |
|
| 36 |
if (first == last) |
| 37 |
return 0; |
| 38 |
|
| 39 |
int sign = 0; |
| 40 |
|
| 41 |
if (*first == Plus || *first == Minus) { |
| 42 |
sign = 1; |
| 43 |
++first; |
| 44 |
} |
| 45 |
|
| 46 |
first += basechars; |
| 47 |
Char* cur_group = last; // Points immediately beyond the rightmost |
| 48 |
// digit of the current group. |
| 49 |
int groupsize = 0; // Size of the current group (if grouping.size() == 0, size |
| 50 |
// of group unlimited: we force condition (groupsize <= 0)) |
| 51 |
|
| 52 |
for ( str_size n = 0; ; ) { // Index of the current group |
| 53 |
if ( n < grouping.size() ) { |
| 54 |
groupsize = __STATIC_CAST(int, grouping[n++] ); |
| 55 |
} |
| 56 |
|
| 57 |
if ((groupsize <= 0) || (groupsize >= cur_group - first) || (groupsize == CHAR_MAX)) { |
| 58 |
break; |
| 59 |
} |
| 60 |
|
| 61 |
// Insert a separator character just before position cur_group - groupsize |
| 62 |
cur_group -= groupsize; |
| 63 |
++last; |
| 64 |
copy_backward(cur_group, last, last + 1); |
| 65 |
*cur_group = separator; |
| 66 |
} |
| 67 |
|
| 68 |
return (last - first) + sign + basechars; |
| 69 |
} |
| 70 |
|
| 71 |
//Dynamic output buffer version. |
| 72 |
template <class Char, class Str> |
| 73 |
static void |
| 74 |
__insert_grouping_aux( /* __basic_iostring<Char> */ Str& iostr, size_t __group_pos, |
| 75 |
const string& grouping, |
| 76 |
Char separator, Char Plus, Char Minus, |
| 77 |
int basechars) { |
| 78 |
typedef string::size_type str_size; |
| 79 |
|
| 80 |
if (iostr.size() < __group_pos) |
| 81 |
return; |
| 82 |
|
| 83 |
int __first_pos = 0; |
| 84 |
Char __first = *iostr.begin(); |
| 85 |
|
| 86 |
if (__first == Plus || __first == Minus) { |
| 87 |
++__first_pos; |
| 88 |
} |
| 89 |
|
| 90 |
__first_pos += basechars; |
| 91 |
|
| 92 |
typename Str::iterator cur_group(iostr.begin() + __group_pos); // Points immediately beyond the rightmost |
| 93 |
// digit of the current group. |
| 94 |
int groupsize = 0; // Size of the current group (if grouping.size() == 0, size |
| 95 |
// of group unlimited: we force condition (groupsize <= 0)) |
| 96 |
|
| 97 |
for ( str_size n = 0; ; ) { // Index of the current group |
| 98 |
if ( n < grouping.size() ) { |
| 99 |
groupsize = __STATIC_CAST( int, grouping[n++] ); |
| 100 |
} |
| 101 |
|
| 102 |
if ( (groupsize <= 0) || (groupsize >= ((cur_group - iostr.begin()) - __first_pos)) || |
| 103 |
(groupsize == CHAR_MAX)) { |
| 104 |
break; |
| 105 |
} |
| 106 |
|
| 107 |
// Insert a separator character just before position cur_group - groupsize |
| 108 |
cur_group -= groupsize; |
| 109 |
cur_group = iostr.insert(cur_group, separator); |
| 110 |
} |
| 111 |
} |
| 112 |
|
| 113 |
//---------------------------------------------------------------------- |
| 114 |
// num_put |
| 115 |
|
| 116 |
_STLP_MOVE_TO_PRIV_NAMESPACE |
| 117 |
|
| 118 |
_STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_lo() |
| 119 |
{ return "0123456789abcdefx"; } |
| 120 |
|
| 121 |
_STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_hi() |
| 122 |
{ return "0123456789ABCDEFX"; } |
| 123 |
|
| 124 |
char* _STLP_CALL |
| 125 |
__write_integer(char* buf, ios_base::fmtflags flags, long x) { |
| 126 |
char tmp[64]; |
| 127 |
char* bufend = tmp+64; |
| 128 |
char* beg = __write_integer_backward(bufend, flags, x); |
| 129 |
return copy(beg, bufend, buf); |
| 130 |
} |
| 131 |
|
| 132 |
///------------------------------------- |
| 133 |
|
| 134 |
ptrdiff_t _STLP_CALL |
| 135 |
__insert_grouping(char * first, char * last, const string& grouping, |
| 136 |
char separator, char Plus, char Minus, int basechars) { |
| 137 |
return __insert_grouping_aux(first, last, grouping, |
| 138 |
separator, Plus, Minus, basechars); |
| 139 |
} |
| 140 |
|
| 141 |
void _STLP_CALL |
| 142 |
__insert_grouping(__iostring &str, size_t group_pos, const string& grouping, |
| 143 |
char separator, char Plus, char Minus, int basechars) { |
| 144 |
__insert_grouping_aux(str, group_pos, grouping, separator, Plus, Minus, basechars); |
| 145 |
} |
| 146 |
|
| 147 |
#if !defined (_STLP_NO_WCHAR_T) |
| 148 |
ptrdiff_t _STLP_CALL |
| 149 |
__insert_grouping(wchar_t* first, wchar_t* last, const string& grouping, |
| 150 |
wchar_t separator, wchar_t Plus, wchar_t Minus, |
| 151 |
int basechars) { |
| 152 |
return __insert_grouping_aux(first, last, grouping, separator, |
| 153 |
Plus, Minus, basechars); |
| 154 |
} |
| 155 |
|
| 156 |
void _STLP_CALL |
| 157 |
__insert_grouping(__iowstring &str, size_t group_pos, const string& grouping, |
| 158 |
wchar_t separator, wchar_t Plus, wchar_t Minus, |
| 159 |
int basechars) { |
| 160 |
__insert_grouping_aux(str, group_pos, grouping, separator, Plus, Minus, basechars); |
| 161 |
} |
| 162 |
#endif |
| 163 |
|
| 164 |
_STLP_MOVE_TO_STD_NAMESPACE |
| 165 |
|
| 166 |
//---------------------------------------------------------------------- |
| 167 |
// Force instantiation of num_put<> |
| 168 |
#if !defined(_STLP_NO_FORCE_INSTANTIATE) |
| 169 |
template class _STLP_CLASS_DECLSPEC ostreambuf_iterator<char, char_traits<char> >; |
| 170 |
// template class num_put<char, char*>; |
| 171 |
template class num_put<char, ostreambuf_iterator<char, char_traits<char> > >; |
| 172 |
# ifndef _STLP_NO_WCHAR_T |
| 173 |
template class ostreambuf_iterator<wchar_t, char_traits<wchar_t> >; |
| 174 |
template class num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >; |
| 175 |
// template class num_put<wchar_t, wchar_t*>; |
| 176 |
# endif /* INSTANTIATE_WIDE_STREAMS */ |
| 177 |
#endif |
| 178 |
|
| 179 |
_STLP_END_NAMESPACE |
| 180 |
|
| 181 |
// Local Variables: |
| 182 |
// mode:C++ |
| 183 |
// End: |