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
__insert_grouping_aux(Char * first,Char * last,const string & grouping,Char separator,Char Plus,Char Minus,int basechars)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
__insert_grouping_aux(Str & iostr,size_t __group_pos,const string & grouping,Char separator,Char Plus,Char Minus,int basechars)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
__hex_char_table_lo()118 _STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_lo()
119 { return "0123456789abcdefx"; }
120
__hex_char_table_hi()121 _STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_hi()
122 { return "0123456789ABCDEFX"; }
123
124 char* _STLP_CALL
__write_integer(char * buf,ios_base::fmtflags flags,long x)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
__insert_grouping(char * first,char * last,const string & grouping,char separator,char Plus,char Minus,int basechars)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
__insert_grouping(__iostring & str,size_t group_pos,const string & grouping,char separator,char Plus,char Minus,int basechars)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
__insert_grouping(wchar_t * first,wchar_t * last,const string & grouping,wchar_t separator,wchar_t Plus,wchar_t Minus,int basechars)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
__insert_grouping(__iowstring & str,size_t group_pos,const string & grouping,wchar_t separator,wchar_t Plus,wchar_t Minus,int basechars)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:
184