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: 184