num_put.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. #include "stlport_prefix.h"
  19. #include <locale>
  20. #include <ostream>
  21. _STLP_BEGIN_NAMESPACE
  22. // Note that grouping[0] is the number of digits in the *rightmost* group.
  23. // We assume, without checking, that *last is null and that there is enough
  24. // space in the buffer to extend the number past [first, last).
  25. template <class Char>
  26. static ptrdiff_t
  27. __insert_grouping_aux(Char* first, Char* last, const string& grouping,
  28. Char separator, Char Plus, Char Minus,
  29. int basechars) {
  30. typedef string::size_type str_size;
  31. if (first == last)
  32. return 0;
  33. int sign = 0;
  34. if (*first == Plus || *first == Minus) {
  35. sign = 1;
  36. ++first;
  37. }
  38. first += basechars;
  39. Char* cur_group = last; // Points immediately beyond the rightmost
  40. // digit of the current group.
  41. int groupsize = 0; // Size of the current group (if grouping.size() == 0, size
  42. // of group unlimited: we force condition (groupsize <= 0))
  43. for ( str_size n = 0; ; ) { // Index of the current group
  44. if ( n < grouping.size() ) {
  45. groupsize = __STATIC_CAST(int, grouping[n++] );
  46. }
  47. if ((groupsize <= 0) || (groupsize >= cur_group - first) || (groupsize == CHAR_MAX)) {
  48. break;
  49. }
  50. // Insert a separator character just before position cur_group - groupsize
  51. cur_group -= groupsize;
  52. ++last;
  53. copy_backward(cur_group, last, last + 1);
  54. *cur_group = separator;
  55. }
  56. return (last - first) + sign + basechars;
  57. }
  58. //Dynamic output buffer version.
  59. template <class Char, class Str>
  60. static void
  61. __insert_grouping_aux( /* __basic_iostring<Char> */ Str& iostr, size_t __group_pos,
  62. const string& grouping,
  63. Char separator, Char Plus, Char Minus,
  64. int basechars) {
  65. typedef string::size_type str_size;
  66. if (iostr.size() < __group_pos)
  67. return;
  68. int __first_pos = 0;
  69. Char __first = *iostr.begin();
  70. if (__first == Plus || __first == Minus) {
  71. ++__first_pos;
  72. }
  73. __first_pos += basechars;
  74. typename Str::iterator cur_group(iostr.begin() + __group_pos); // Points immediately beyond the rightmost
  75. // digit of the current group.
  76. int groupsize = 0; // Size of the current group (if grouping.size() == 0, size
  77. // of group unlimited: we force condition (groupsize <= 0))
  78. for ( str_size n = 0; ; ) { // Index of the current group
  79. if ( n < grouping.size() ) {
  80. groupsize = __STATIC_CAST( int, grouping[n++] );
  81. }
  82. if ( (groupsize <= 0) || (groupsize >= ((cur_group - iostr.begin()) - __first_pos)) ||
  83. (groupsize == CHAR_MAX)) {
  84. break;
  85. }
  86. // Insert a separator character just before position cur_group - groupsize
  87. cur_group -= groupsize;
  88. cur_group = iostr.insert(cur_group, separator);
  89. }
  90. }
  91. //----------------------------------------------------------------------
  92. // num_put
  93. _STLP_MOVE_TO_PRIV_NAMESPACE
  94. _STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_lo()
  95. { return "0123456789abcdefx"; }
  96. _STLP_DECLSPEC const char* _STLP_CALL __hex_char_table_hi()
  97. { return "0123456789ABCDEFX"; }
  98. char* _STLP_CALL
  99. __write_integer(char* buf, ios_base::fmtflags flags, long x) {
  100. char tmp[64];
  101. char* bufend = tmp+64;
  102. char* beg = __write_integer_backward(bufend, flags, x);
  103. return copy(beg, bufend, buf);
  104. }
  105. ///-------------------------------------
  106. ptrdiff_t _STLP_CALL
  107. __insert_grouping(char * first, char * last, const string& grouping,
  108. char separator, char Plus, char Minus, int basechars) {
  109. return __insert_grouping_aux(first, last, grouping,
  110. separator, Plus, Minus, basechars);
  111. }
  112. void _STLP_CALL
  113. __insert_grouping(__iostring &str, size_t group_pos, const string& grouping,
  114. char separator, char Plus, char Minus, int basechars) {
  115. __insert_grouping_aux(str, group_pos, grouping, separator, Plus, Minus, basechars);
  116. }
  117. #if !defined (_STLP_NO_WCHAR_T)
  118. ptrdiff_t _STLP_CALL
  119. __insert_grouping(wchar_t* first, wchar_t* last, const string& grouping,
  120. wchar_t separator, wchar_t Plus, wchar_t Minus,
  121. int basechars) {
  122. return __insert_grouping_aux(first, last, grouping, separator,
  123. Plus, Minus, basechars);
  124. }
  125. void _STLP_CALL
  126. __insert_grouping(__iowstring &str, size_t group_pos, const string& grouping,
  127. wchar_t separator, wchar_t Plus, wchar_t Minus,
  128. int basechars) {
  129. __insert_grouping_aux(str, group_pos, grouping, separator, Plus, Minus, basechars);
  130. }
  131. #endif
  132. _STLP_MOVE_TO_STD_NAMESPACE
  133. //----------------------------------------------------------------------
  134. // Force instantiation of num_put<>
  135. #if !defined(_STLP_NO_FORCE_INSTANTIATE)
  136. template class _STLP_CLASS_DECLSPEC ostreambuf_iterator<char, char_traits<char> >;
  137. // template class num_put<char, char*>;
  138. template class num_put<char, ostreambuf_iterator<char, char_traits<char> > >;
  139. # ifndef _STLP_NO_WCHAR_T
  140. template class ostreambuf_iterator<wchar_t, char_traits<wchar_t> >;
  141. template class num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
  142. // template class num_put<wchar_t, wchar_t*>;
  143. # endif /* INSTANTIATE_WIDE_STREAMS */
  144. #endif
  145. _STLP_END_NAMESPACE
  146. // Local Variables:
  147. // mode:C++
  148. // End: