Marine Library  1.0
C++ library for Linux Networking Development
to_string.hh
1 #ifndef DOZERG_TO_STRING_H_20130411
2 #define DOZERG_TO_STRING_H_20130411
3 
4 /*
5  将任意类型转换成可读字符串,std::ostringstream替代品
6  类型:
7  CToString std::ostringstream替代品
8  操作符:
9  boolalpha 将true/false转换成"true"/"false",默认
10  noboolalpha 将true/false转换成"1"/"0"
11  setw 设置填充字符个数,仅对下一次输出有效
12  fill 设置填充字符,默认' '
13  left 输出内容靠左对齐,填充字符在右边 right 输出内容靠右对齐,填充字符在左边,默认 setbase 设置整数进制,默认10 dec 设置整数进制为10 hex 设置整数进制为16 oct 设置整数进制为8 bin 设置整数进制为2 showbase 输出整数进制的标识,例如:0x,0X(16进制), 0(8进制), 0b,0B(2进制),默认 noshowbase 不输出整数进制的标识 uppercase 整数里的字符采用大写 nouppercase 整数里的字符采用小写 autocase 进制字符用小写,数值字符用大写,例如:"0xABC", "0b1001",默认 showpos 10进制正整数前加'+' noshowpos 10进制正整数前无'+',默认 endl 输出换行符'\n' ends 输出结束符'\0' //*/ #include <stdint.h> #include <cassert> #include <cstdio> #include <cstring> #include <string> #include <limits> //std::numeric_limits #include <algorithm> //std::fill_n #include "template.hh" //CTypeTraits #include "impl/to_string_impl.hh" NS_SERVER_BEGIN class CToString { typedef CToString __Myt; struct __Flags{ char fill_; uint8_t width_; uint8_t base_:2; //print number at base of 10(0) or 16(1) or 8(2) or 2(3) uint8_t nobase_:1; //print base(0, 0x, 0X, 0b, 0B)(1) or not(0) uint8_t autocase_:2; //print number with autocase(0), uppercase(1) or lowercase(2) uint8_t adjustleft_:1; //adjust to left(1) or right(0) uint8_t boolnum_:1; //print bool as number uint8_t showpos_:1; //print non-negative numerical values preceded by a plus sign(+) __Flags():fill_(' '),width_(0),base_(0),nobase_(0),autocase_(0),adjustleft_(0),boolnum_(0),showpos_(0){} }; //number base static const uint8_t kDec = 0; static const uint8_t kHex = 1; static const uint8_t kOct = 2; static const uint8_t kBin = 3; public: //char case static const uint8_t kAutoCase = 0; static const uint8_t kUpperCase = 1; static const uint8_t kLowerCase = 2; //设置/获取是否将bool值显示成字符串 void boolalpha(bool c){flags_.boolnum_ = (c ? 0 : 1);} bool boolalpha() const{return (0 == flags_.boolnum_);} //设置/获取下次的填充字符数(0-255) //注意:仅对下一次输出有效 void width(int n){flags_.width_ = (n >= 0 ? (n <= 255 ? n : 255) : 0);} int width() const{return flags_.width_;} //设置/获取右对齐(true)还是左对齐(false) void adjustright(bool v){flags_.adjustleft_ = (v ? 0 : 1);} bool adjustright() const{return (0 == flags_.adjustleft_);} //设置/获取填充字符 void fill(char c){flags_.fill_ = c;} char fill() const{return flags_.fill_;} //设置/获取整数的进制 //base: // 10 以10进制输出整数 // 16 以16进制输出整数 // 8 以8进制输出整数 // 2 以2进制输出整数 // 其他 以10进制输出整数 void base(int base){ switch(base){ case 16:flags_.base_ = kHex;break; case 8:flags_.base_ = kOct;break; case 2:flags_.base_ = kBin;break; default:flags_.base_ = kDec; } } int base() const{return (kDec == fbase() ? 10 : (kHex == fbase() ? 16 : (kOct == fbase() ? 8 : 2)));} //设置/获取是否显示进制(0x, 0X, 0, 0b, 0B) void showbase(bool v){flags_.nobase_ = (v ? 0 : 1);} bool showbase() const{return (0 == flags_.nobase_);} //设置/获取字符大小写方式 //return: // 0 autocase // 1 uppercase // 2 lowercase // 其他 未知 void charcase(int v){flags_.autocase_ = (v & 3);} int charcase() const{return (flags_.autocase_ & 3);} //设置/获取正整数前面是否加'+' void showpos(bool c){flags_.showpos_ = (c ? 1 : 0);} bool showpos() const{return (0 != flags_.showpos_);} //print basic types __Myt & operator <<(bool c){ if(boolalpha()) return (c ? printStr("true", 4) : printStr("false", 5)); return printChar(c ? '1' : '0'); } __Myt & operator <<(char c){return printChar(c);} __Myt & operator <<(signed char c){return printChar(c);} __Myt & operator <<(unsigned char c){return printChar(c);} __Myt & operator <<(short c){return printInt(c);} __Myt & operator <<(unsigned short c){return printInt(c);} __Myt & operator <<(int c){return printInt(c);} __Myt & operator <<(unsigned int c){return printInt(c);} __Myt & operator <<(long c){return printInt(c);} __Myt & operator <<(unsigned long c){return printInt(c);} __Myt & operator <<(long long c){return printInt(c);} __Myt & operator <<(unsigned long long c){return printInt(c);} __Myt & operator <<(float c); //TODO: precision, max length, scientific ... __Myt & operator <<(double c); //TODO __Myt & operator <<(const char * c){return printStr(c);} __Myt & operator <<(char * c){return operator <<(static_cast<const char *>(c));} __Myt & operator <<(const std::string & c){ if(c.empty()) return *this; return printStr(c.c_str(), c.length()); } __Myt & operator <<(const void * c){return printInt(reinterpret_cast<long>(c), true, kHex, kLowerCase);} __Myt & operator <<(void * c){return operator <<(static_cast<const void *>(c));} //manipulators __Myt & operator <<(const NS_IMPL::CToStringBase & c){ base(c.base_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringWidth & c){ width(c.w_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringFill & c){ fill(c.fill_); return *this; } __Myt & operator <<(__Myt & (*func)(__Myt &)){ if(func) func(*this); return *this; } //设置/获取结果字符串 void str(const std::string & str){buf_ = str;} const std::string & str() const{return buf_;} private: uint8_t fbase() const{return flags_.base_;}; static bool baseUpper(int ccase){return (kUpperCase == ccase);} static bool valueUpper(int ccase){return (kLowerCase != ccase);} template<typename Int> bool realShowPos(Int c) const{ typedef std::numeric_limits<Int> __Limits; return (__Limits::is_signed #ifdef __0_NO_POSITIVE && 0 != c #endif && showpos()); } template<typename Int> __Myt & printInt(Int c){return printInt(c, showbase(), fbase(), charcase());} template<typename Int> __Myt & printInt(Int c, bool showbase, uint8_t base, int ccase){ char tmp[72]; //max for all bases(2, 8, 10, 16) char * e = tmp + sizeof tmp; char * s = NULL; if(kDec == base) s = int2Str10(e, c); else s = int2Str(e, c, base, showbase, ccase); setWidth(s, e - s); return *this; } __Myt & printChar(char c){ setWidth(&c, 1); return *this; } __Myt & printStr(const char * c, size_t len = 0){ if(NULL == c) return printStr("(NULL)", 6); if(!len) len = ::strlen(c); if(len) setWidth(c, len); return *this; } template<typename Int> char * int2Str10(char * e, Int c){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const char * const kDig99 = "00010203040506070809" "10111213141516171819" "20212223242526272829" "30313233343536373839" "40414243444546474849" "50515253545556575859" "60616263646566676869" "70717273747576777879" "80818283848586878889" "90919293949596979899"; __Unsigned cc = c; const bool negtive = !(c > 0 || c == 0); if(negtive) cc = -cc; for(__Unsigned i;cc > 99;){ i = cc; cc /= 100; memcpy((e -= 2), kDig99 + ((i << 1) - cc * 200), 2); } if(cc < 10){ *--e = '0' + cc; }else memcpy((e -= 2), kDig99 + cc * 2, 2); if(negtive) *--e = '-'; else if(realShowPos(c)) *--e = '+'; return e; } template<typename Int> char * int2Str(char * e, Int c, uint8_t base, bool showbase, int ccase){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const bool sb = (showbase && 0 != c); //0 need not showbase __Unsigned cc = c; size_t i = 0; switch(base){ case kHex: i = (valueUpper(ccase) ? 0 : 16); do{ *--e = "0123456789ABCDEF0123456789abcdef"[(cc & 0xF) + i]; cc >>= 4; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'X' : 'x'); *--e = '0'; } break; case kOct: do{ *--e = (cc & 7) + '0'; cc >>= 3; }while(cc); if(sb) *--e = '0'; break; case kBin: do{ *--e = (cc & 1) + '0'; cc >>= 1; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'B' : 'b'); *--e = '0'; } break; default:assert(0); } return e; } void setWidth(const char * s, size_t len){ assert(s && len); size_t w = width(); assert(w <= 255); const bool r = adjustright(); if(!r) buf_.append(s, len); if(len < w) buf_.append(w - len, fill()); if(r) buf_.append(s, len); width(0); } //fields std::string buf_; __Flags flags_; }; namespace Manip{ inline CToString & boolalpha(CToString & tos) { tos.boolalpha(true); return tos; } inline CToString & noboolalpha(CToString & tos) { tos.boolalpha(false); return tos; } inline NS_IMPL::CToStringWidth setw(int w) { return NS_IMPL::CToStringWidth(w); } inline NS_IMPL::CToStringFill fill(char c) { return NS_IMPL::CToStringFill(c); } inline CToString & left(CToString & tos) { tos.adjustright(false); return tos; } inline CToString & right(CToString & tos) { tos.adjustright(true); return tos; } inline NS_IMPL::CToStringBase setbase(int base) { return NS_IMPL::CToStringBase(base); } inline CToString & dec(CToString & tos) { return (tos<<setbase(10)); } inline CToString & hex(CToString & tos) { return (tos<<setbase(16)); } inline CToString & oct(CToString & tos) { return (tos<<setbase(8)); } inline CToString & bin(CToString & tos) { return (tos<<setbase(2)); } inline CToString & showbase(CToString & tos) { tos.showbase(true); return tos; } inline CToString & noshowbase(CToString & tos) { tos.showbase(false); return tos; } inline CToString & autocase(CToString & tos) { tos.charcase(CToString::kAutoCase); return tos; } inline CToString & uppercase(CToString & tos) { tos.charcase(CToString::kUpperCase); return tos; } inline CToString & nouppercase(CToString & tos) { tos.charcase(CToString::kLowerCase); return tos; } inline CToString & showpos(CToString & tos) { tos.showpos(true); return tos; } inline CToString & noshowpos(CToString & tos) { tos.showpos(false); return tos; } inline CToString & endl(CToString & tos) { return (tos<<'\n'); } inline CToString & ends(CToString & tos) { return (tos<<'\0'); } }//namespace Manip NS_SERVER_END #endif
14  right 输出内容靠右对齐,填充字符在左边,默认
15  setbase 设置整数进制,默认10
16  dec 设置整数进制为10
17  hex 设置整数进制为16
18  oct 设置整数进制为8
19  bin 设置整数进制为2
20  showbase 输出整数进制的标识,例如:0x,0X(16进制), 0(8进制), 0b,0B(2进制),默认
21  noshowbase 不输出整数进制的标识
22  uppercase 整数里的字符采用大写
23  nouppercase 整数里的字符采用小写
24  autocase 进制字符用小写,数值字符用大写,例如:"0xABC", "0b1001",默认
25  showpos 10进制正整数前加'+'
26  noshowpos 10进制正整数前无'+',默认
27  endl 输出换行符'\n'
28  ends 输出结束符'\0'
29 //*/
30 
31 #include <stdint.h>
32 #include <cassert>
33 #include <cstdio>
34 #include <cstring>
35 #include <string>
36 #include <limits> //std::numeric_limits
37 #include <algorithm> //std::fill_n
38 #include "template.hh" //CTypeTraits
39 #include "impl/to_string_impl.hh"
40 
41 NS_SERVER_BEGIN
42 
43 class CToString
44 {
45  typedef CToString __Myt;
46  struct __Flags{
47  char fill_;
48  uint8_t width_;
49  uint8_t base_:2; //print number at base of 10(0) or 16(1) or 8(2) or 2(3)
50  uint8_t nobase_:1; //print base(0, 0x, 0X, 0b, 0B)(1) or not(0)
51  uint8_t autocase_:2; //print number with autocase(0), uppercase(1) or lowercase(2)
52  uint8_t adjustleft_:1; //adjust to left(1) or right(0)
53  uint8_t boolnum_:1; //print bool as number
54  uint8_t showpos_:1; //print non-negative numerical values preceded by a plus sign(+)
55  __Flags():fill_(' '),width_(0),base_(0),nobase_(0),autocase_(0),adjustleft_(0),boolnum_(0),showpos_(0){}
56  };
57  //number base
58  static const uint8_t kDec = 0;
59  static const uint8_t kHex = 1;
60  static const uint8_t kOct = 2;
61  static const uint8_t kBin = 3;
62 public:
63  //char case
64  static const uint8_t kAutoCase = 0;
65  static const uint8_t kUpperCase = 1;
66  static const uint8_t kLowerCase = 2;
67  //设置/获取是否将bool值显示成字符串
68  void boolalpha(bool c){flags_.boolnum_ = (c ? 0 : 1);}
69  bool boolalpha() const{return (0 == flags_.boolnum_);}
70  //设置/获取下次的填充字符数(0-255)
71  //注意:仅对下一次输出有效
72  void width(int n){flags_.width_ = (n >= 0 ? (n <= 255 ? n : 255) : 0);}
73  int width() const{return flags_.width_;}
74  //设置/获取右对齐(true)还是左对齐(false)
75  void adjustright(bool v){flags_.adjustleft_ = (v ? 0 : 1);}
76  bool adjustright() const{return (0 == flags_.adjustleft_);}
77  //设置/获取填充字符 void fill(char c){flags_.fill_ = c;} char fill() const{return flags_.fill_;} //设置/获取整数的进制 //base: // 10 以10进制输出整数 // 16 以16进制输出整数 // 8 以8进制输出整数 // 2 以2进制输出整数 // 其他 以10进制输出整数 void base(int base){ switch(base){ case 16:flags_.base_ = kHex;break; case 8:flags_.base_ = kOct;break; case 2:flags_.base_ = kBin;break; default:flags_.base_ = kDec; } } int base() const{return (kDec == fbase() ? 10 : (kHex == fbase() ? 16 : (kOct == fbase() ? 8 : 2)));} //设置/获取是否显示进制(0x, 0X, 0, 0b, 0B) void showbase(bool v){flags_.nobase_ = (v ? 0 : 1);} bool showbase() const{return (0 == flags_.nobase_);} //设置/获取字符大小写方式 //return: // 0 autocase // 1 uppercase // 2 lowercase // 其他 未知 void charcase(int v){flags_.autocase_ = (v & 3);} int charcase() const{return (flags_.autocase_ & 3);} //设置/获取正整数前面是否加'+' void showpos(bool c){flags_.showpos_ = (c ? 1 : 0);} bool showpos() const{return (0 != flags_.showpos_);} //print basic types __Myt & operator <<(bool c){ if(boolalpha()) return (c ? printStr("true", 4) : printStr("false", 5)); return printChar(c ? '1' : '0'); } __Myt & operator <<(char c){return printChar(c);} __Myt & operator <<(signed char c){return printChar(c);} __Myt & operator <<(unsigned char c){return printChar(c);} __Myt & operator <<(short c){return printInt(c);} __Myt & operator <<(unsigned short c){return printInt(c);} __Myt & operator <<(int c){return printInt(c);} __Myt & operator <<(unsigned int c){return printInt(c);} __Myt & operator <<(long c){return printInt(c);} __Myt & operator <<(unsigned long c){return printInt(c);} __Myt & operator <<(long long c){return printInt(c);} __Myt & operator <<(unsigned long long c){return printInt(c);} __Myt & operator <<(float c); //TODO: precision, max length, scientific ... __Myt & operator <<(double c); //TODO __Myt & operator <<(const char * c){return printStr(c);} __Myt & operator <<(char * c){return operator <<(static_cast<const char *>(c));} __Myt & operator <<(const std::string & c){ if(c.empty()) return *this; return printStr(c.c_str(), c.length()); } __Myt & operator <<(const void * c){return printInt(reinterpret_cast<long>(c), true, kHex, kLowerCase);} __Myt & operator <<(void * c){return operator <<(static_cast<const void *>(c));} //manipulators __Myt & operator <<(const NS_IMPL::CToStringBase & c){ base(c.base_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringWidth & c){ width(c.w_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringFill & c){ fill(c.fill_); return *this; } __Myt & operator <<(__Myt & (*func)(__Myt &)){ if(func) func(*this); return *this; } //设置/获取结果字符串 void str(const std::string & str){buf_ = str;} const std::string & str() const{return buf_;} private: uint8_t fbase() const{return flags_.base_;}; static bool baseUpper(int ccase){return (kUpperCase == ccase);} static bool valueUpper(int ccase){return (kLowerCase != ccase);} template<typename Int> bool realShowPos(Int c) const{ typedef std::numeric_limits<Int> __Limits; return (__Limits::is_signed #ifdef __0_NO_POSITIVE && 0 != c #endif && showpos()); } template<typename Int> __Myt & printInt(Int c){return printInt(c, showbase(), fbase(), charcase());} template<typename Int> __Myt & printInt(Int c, bool showbase, uint8_t base, int ccase){ char tmp[72]; //max for all bases(2, 8, 10, 16) char * e = tmp + sizeof tmp; char * s = NULL; if(kDec == base) s = int2Str10(e, c); else s = int2Str(e, c, base, showbase, ccase); setWidth(s, e - s); return *this; } __Myt & printChar(char c){ setWidth(&c, 1); return *this; } __Myt & printStr(const char * c, size_t len = 0){ if(NULL == c) return printStr("(NULL)", 6); if(!len) len = ::strlen(c); if(len) setWidth(c, len); return *this; } template<typename Int> char * int2Str10(char * e, Int c){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const char * const kDig99 = "00010203040506070809" "10111213141516171819" "20212223242526272829" "30313233343536373839" "40414243444546474849" "50515253545556575859" "60616263646566676869" "70717273747576777879" "80818283848586878889" "90919293949596979899"; __Unsigned cc = c; const bool negtive = !(c > 0 || c == 0); if(negtive) cc = -cc; for(__Unsigned i;cc > 99;){ i = cc; cc /= 100; memcpy((e -= 2), kDig99 + ((i << 1) - cc * 200), 2); } if(cc < 10){ *--e = '0' + cc; }else memcpy((e -= 2), kDig99 + cc * 2, 2); if(negtive) *--e = '-'; else if(realShowPos(c)) *--e = '+'; return e; } template<typename Int> char * int2Str(char * e, Int c, uint8_t base, bool showbase, int ccase){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const bool sb = (showbase && 0 != c); //0 need not showbase __Unsigned cc = c; size_t i = 0; switch(base){ case kHex: i = (valueUpper(ccase) ? 0 : 16); do{ *--e = "0123456789ABCDEF0123456789abcdef"[(cc & 0xF) + i]; cc >>= 4; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'X' : 'x'); *--e = '0'; } break; case kOct: do{ *--e = (cc & 7) + '0'; cc >>= 3; }while(cc); if(sb) *--e = '0'; break; case kBin: do{ *--e = (cc & 1) + '0'; cc >>= 1; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'B' : 'b'); *--e = '0'; } break; default:assert(0); } return e; } void setWidth(const char * s, size_t len){ assert(s && len); size_t w = width(); assert(w <= 255); const bool r = adjustright(); if(!r) buf_.append(s, len); if(len < w) buf_.append(w - len, fill()); if(r) buf_.append(s, len); width(0); } //fields std::string buf_; __Flags flags_; }; namespace Manip{ inline CToString & boolalpha(CToString & tos) { tos.boolalpha(true); return tos; } inline CToString & noboolalpha(CToString & tos) { tos.boolalpha(false); return tos; } inline NS_IMPL::CToStringWidth setw(int w) { return NS_IMPL::CToStringWidth(w); } inline NS_IMPL::CToStringFill fill(char c) { return NS_IMPL::CToStringFill(c); } inline CToString & left(CToString & tos) { tos.adjustright(false); return tos; } inline CToString & right(CToString & tos) { tos.adjustright(true); return tos; } inline NS_IMPL::CToStringBase setbase(int base) { return NS_IMPL::CToStringBase(base); } inline CToString & dec(CToString & tos) { return (tos<<setbase(10)); } inline CToString & hex(CToString & tos) { return (tos<<setbase(16)); } inline CToString & oct(CToString & tos) { return (tos<<setbase(8)); } inline CToString & bin(CToString & tos) { return (tos<<setbase(2)); } inline CToString & showbase(CToString & tos) { tos.showbase(true); return tos; } inline CToString & noshowbase(CToString & tos) { tos.showbase(false); return tos; } inline CToString & autocase(CToString & tos) { tos.charcase(CToString::kAutoCase); return tos; } inline CToString & uppercase(CToString & tos) { tos.charcase(CToString::kUpperCase); return tos; } inline CToString & nouppercase(CToString & tos) { tos.charcase(CToString::kLowerCase); return tos; } inline CToString & showpos(CToString & tos) { tos.showpos(true); return tos; } inline CToString & noshowpos(CToString & tos) { tos.showpos(false); return tos; } inline CToString & endl(CToString & tos) { return (tos<<'\n'); } inline CToString & ends(CToString & tos) { return (tos<<'\0'); } }//namespace Manip NS_SERVER_END #endif
78  void fill(char c){flags_.fill_ = c;}
79  char fill() const{return flags_.fill_;}
80  //设置/获取整数的进制 //base: // 10 以10进制输出整数 // 16 以16进制输出整数 // 8 以8进制输出整数 // 2 以2进制输出整数 // 其他 以10进制输出整数 void base(int base){ switch(base){ case 16:flags_.base_ = kHex;break; case 8:flags_.base_ = kOct;break; case 2:flags_.base_ = kBin;break; default:flags_.base_ = kDec; } } int base() const{return (kDec == fbase() ? 10 : (kHex == fbase() ? 16 : (kOct == fbase() ? 8 : 2)));} //设置/获取是否显示进制(0x, 0X, 0, 0b, 0B) void showbase(bool v){flags_.nobase_ = (v ? 0 : 1);} bool showbase() const{return (0 == flags_.nobase_);} //设置/获取字符大小写方式 //return: // 0 autocase // 1 uppercase // 2 lowercase // 其他 未知 void charcase(int v){flags_.autocase_ = (v & 3);} int charcase() const{return (flags_.autocase_ & 3);} //设置/获取正整数前面是否加'+' void showpos(bool c){flags_.showpos_ = (c ? 1 : 0);} bool showpos() const{return (0 != flags_.showpos_);} //print basic types __Myt & operator <<(bool c){ if(boolalpha()) return (c ? printStr("true", 4) : printStr("false", 5)); return printChar(c ? '1' : '0'); } __Myt & operator <<(char c){return printChar(c);} __Myt & operator <<(signed char c){return printChar(c);} __Myt & operator <<(unsigned char c){return printChar(c);} __Myt & operator <<(short c){return printInt(c);} __Myt & operator <<(unsigned short c){return printInt(c);} __Myt & operator <<(int c){return printInt(c);} __Myt & operator <<(unsigned int c){return printInt(c);} __Myt & operator <<(long c){return printInt(c);} __Myt & operator <<(unsigned long c){return printInt(c);} __Myt & operator <<(long long c){return printInt(c);} __Myt & operator <<(unsigned long long c){return printInt(c);} __Myt & operator <<(float c); //TODO: precision, max length, scientific ... __Myt & operator <<(double c); //TODO __Myt & operator <<(const char * c){return printStr(c);} __Myt & operator <<(char * c){return operator <<(static_cast<const char *>(c));} __Myt & operator <<(const std::string & c){ if(c.empty()) return *this; return printStr(c.c_str(), c.length()); } __Myt & operator <<(const void * c){return printInt(reinterpret_cast<long>(c), true, kHex, kLowerCase);} __Myt & operator <<(void * c){return operator <<(static_cast<const void *>(c));} //manipulators __Myt & operator <<(const NS_IMPL::CToStringBase & c){ base(c.base_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringWidth & c){ width(c.w_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringFill & c){ fill(c.fill_); return *this; } __Myt & operator <<(__Myt & (*func)(__Myt &)){ if(func) func(*this); return *this; } //设置/获取结果字符串 void str(const std::string & str){buf_ = str;} const std::string & str() const{return buf_;} private: uint8_t fbase() const{return flags_.base_;}; static bool baseUpper(int ccase){return (kUpperCase == ccase);} static bool valueUpper(int ccase){return (kLowerCase != ccase);} template<typename Int> bool realShowPos(Int c) const{ typedef std::numeric_limits<Int> __Limits; return (__Limits::is_signed #ifdef __0_NO_POSITIVE && 0 != c #endif && showpos()); } template<typename Int> __Myt & printInt(Int c){return printInt(c, showbase(), fbase(), charcase());} template<typename Int> __Myt & printInt(Int c, bool showbase, uint8_t base, int ccase){ char tmp[72]; //max for all bases(2, 8, 10, 16) char * e = tmp + sizeof tmp; char * s = NULL; if(kDec == base) s = int2Str10(e, c); else s = int2Str(e, c, base, showbase, ccase); setWidth(s, e - s); return *this; } __Myt & printChar(char c){ setWidth(&c, 1); return *this; } __Myt & printStr(const char * c, size_t len = 0){ if(NULL == c) return printStr("(NULL)", 6); if(!len) len = ::strlen(c); if(len) setWidth(c, len); return *this; } template<typename Int> char * int2Str10(char * e, Int c){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const char * const kDig99 = "00010203040506070809" "10111213141516171819" "20212223242526272829" "30313233343536373839" "40414243444546474849" "50515253545556575859" "60616263646566676869" "70717273747576777879" "80818283848586878889" "90919293949596979899"; __Unsigned cc = c; const bool negtive = !(c > 0 || c == 0); if(negtive) cc = -cc; for(__Unsigned i;cc > 99;){ i = cc; cc /= 100; memcpy((e -= 2), kDig99 + ((i << 1) - cc * 200), 2); } if(cc < 10){ *--e = '0' + cc; }else memcpy((e -= 2), kDig99 + cc * 2, 2); if(negtive) *--e = '-'; else if(realShowPos(c)) *--e = '+'; return e; } template<typename Int> char * int2Str(char * e, Int c, uint8_t base, bool showbase, int ccase){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const bool sb = (showbase && 0 != c); //0 need not showbase __Unsigned cc = c; size_t i = 0; switch(base){ case kHex: i = (valueUpper(ccase) ? 0 : 16); do{ *--e = "0123456789ABCDEF0123456789abcdef"[(cc & 0xF) + i]; cc >>= 4; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'X' : 'x'); *--e = '0'; } break; case kOct: do{ *--e = (cc & 7) + '0'; cc >>= 3; }while(cc); if(sb) *--e = '0'; break; case kBin: do{ *--e = (cc & 1) + '0'; cc >>= 1; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'B' : 'b'); *--e = '0'; } break; default:assert(0); } return e; } void setWidth(const char * s, size_t len){ assert(s && len); size_t w = width(); assert(w <= 255); const bool r = adjustright(); if(!r) buf_.append(s, len); if(len < w) buf_.append(w - len, fill()); if(r) buf_.append(s, len); width(0); } //fields std::string buf_; __Flags flags_; }; namespace Manip{ inline CToString & boolalpha(CToString & tos) { tos.boolalpha(true); return tos; } inline CToString & noboolalpha(CToString & tos) { tos.boolalpha(false); return tos; } inline NS_IMPL::CToStringWidth setw(int w) { return NS_IMPL::CToStringWidth(w); } inline NS_IMPL::CToStringFill fill(char c) { return NS_IMPL::CToStringFill(c); } inline CToString & left(CToString & tos) { tos.adjustright(false); return tos; } inline CToString & right(CToString & tos) { tos.adjustright(true); return tos; } inline NS_IMPL::CToStringBase setbase(int base) { return NS_IMPL::CToStringBase(base); } inline CToString & dec(CToString & tos) { return (tos<<setbase(10)); } inline CToString & hex(CToString & tos) { return (tos<<setbase(16)); } inline CToString & oct(CToString & tos) { return (tos<<setbase(8)); } inline CToString & bin(CToString & tos) { return (tos<<setbase(2)); } inline CToString & showbase(CToString & tos) { tos.showbase(true); return tos; } inline CToString & noshowbase(CToString & tos) { tos.showbase(false); return tos; } inline CToString & autocase(CToString & tos) { tos.charcase(CToString::kAutoCase); return tos; } inline CToString & uppercase(CToString & tos) { tos.charcase(CToString::kUpperCase); return tos; } inline CToString & nouppercase(CToString & tos) { tos.charcase(CToString::kLowerCase); return tos; } inline CToString & showpos(CToString & tos) { tos.showpos(true); return tos; } inline CToString & noshowpos(CToString & tos) { tos.showpos(false); return tos; } inline CToString & endl(CToString & tos) { return (tos<<'\n'); } inline CToString & ends(CToString & tos) { return (tos<<'\0'); } }//namespace Manip NS_SERVER_END #endif
81  //base:
82  // 10 以10进制输出整数 // 16 以16进制输出整数 // 8 以8进制输出整数 // 2 以2进制输出整数 // 其他 以10进制输出整数 void base(int base){ switch(base){ case 16:flags_.base_ = kHex;break; case 8:flags_.base_ = kOct;break; case 2:flags_.base_ = kBin;break; default:flags_.base_ = kDec; } } int base() const{return (kDec == fbase() ? 10 : (kHex == fbase() ? 16 : (kOct == fbase() ? 8 : 2)));} //设置/获取是否显示进制(0x, 0X, 0, 0b, 0B) void showbase(bool v){flags_.nobase_ = (v ? 0 : 1);} bool showbase() const{return (0 == flags_.nobase_);} //设置/获取字符大小写方式 //return: // 0 autocase // 1 uppercase // 2 lowercase // 其他 未知 void charcase(int v){flags_.autocase_ = (v & 3);} int charcase() const{return (flags_.autocase_ & 3);} //设置/获取正整数前面是否加'+' void showpos(bool c){flags_.showpos_ = (c ? 1 : 0);} bool showpos() const{return (0 != flags_.showpos_);} //print basic types __Myt & operator <<(bool c){ if(boolalpha()) return (c ? printStr("true", 4) : printStr("false", 5)); return printChar(c ? '1' : '0'); } __Myt & operator <<(char c){return printChar(c);} __Myt & operator <<(signed char c){return printChar(c);} __Myt & operator <<(unsigned char c){return printChar(c);} __Myt & operator <<(short c){return printInt(c);} __Myt & operator <<(unsigned short c){return printInt(c);} __Myt & operator <<(int c){return printInt(c);} __Myt & operator <<(unsigned int c){return printInt(c);} __Myt & operator <<(long c){return printInt(c);} __Myt & operator <<(unsigned long c){return printInt(c);} __Myt & operator <<(long long c){return printInt(c);} __Myt & operator <<(unsigned long long c){return printInt(c);} __Myt & operator <<(float c); //TODO: precision, max length, scientific ... __Myt & operator <<(double c); //TODO __Myt & operator <<(const char * c){return printStr(c);} __Myt & operator <<(char * c){return operator <<(static_cast<const char *>(c));} __Myt & operator <<(const std::string & c){ if(c.empty()) return *this; return printStr(c.c_str(), c.length()); } __Myt & operator <<(const void * c){return printInt(reinterpret_cast<long>(c), true, kHex, kLowerCase);} __Myt & operator <<(void * c){return operator <<(static_cast<const void *>(c));} //manipulators __Myt & operator <<(const NS_IMPL::CToStringBase & c){ base(c.base_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringWidth & c){ width(c.w_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringFill & c){ fill(c.fill_); return *this; } __Myt & operator <<(__Myt & (*func)(__Myt &)){ if(func) func(*this); return *this; } //设置/获取结果字符串 void str(const std::string & str){buf_ = str;} const std::string & str() const{return buf_;} private: uint8_t fbase() const{return flags_.base_;}; static bool baseUpper(int ccase){return (kUpperCase == ccase);} static bool valueUpper(int ccase){return (kLowerCase != ccase);} template<typename Int> bool realShowPos(Int c) const{ typedef std::numeric_limits<Int> __Limits; return (__Limits::is_signed #ifdef __0_NO_POSITIVE && 0 != c #endif && showpos()); } template<typename Int> __Myt & printInt(Int c){return printInt(c, showbase(), fbase(), charcase());} template<typename Int> __Myt & printInt(Int c, bool showbase, uint8_t base, int ccase){ char tmp[72]; //max for all bases(2, 8, 10, 16) char * e = tmp + sizeof tmp; char * s = NULL; if(kDec == base) s = int2Str10(e, c); else s = int2Str(e, c, base, showbase, ccase); setWidth(s, e - s); return *this; } __Myt & printChar(char c){ setWidth(&c, 1); return *this; } __Myt & printStr(const char * c, size_t len = 0){ if(NULL == c) return printStr("(NULL)", 6); if(!len) len = ::strlen(c); if(len) setWidth(c, len); return *this; } template<typename Int> char * int2Str10(char * e, Int c){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const char * const kDig99 = "00010203040506070809" "10111213141516171819" "20212223242526272829" "30313233343536373839" "40414243444546474849" "50515253545556575859" "60616263646566676869" "70717273747576777879" "80818283848586878889" "90919293949596979899"; __Unsigned cc = c; const bool negtive = !(c > 0 || c == 0); if(negtive) cc = -cc; for(__Unsigned i;cc > 99;){ i = cc; cc /= 100; memcpy((e -= 2), kDig99 + ((i << 1) - cc * 200), 2); } if(cc < 10){ *--e = '0' + cc; }else memcpy((e -= 2), kDig99 + cc * 2, 2); if(negtive) *--e = '-'; else if(realShowPos(c)) *--e = '+'; return e; } template<typename Int> char * int2Str(char * e, Int c, uint8_t base, bool showbase, int ccase){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const bool sb = (showbase && 0 != c); //0 need not showbase __Unsigned cc = c; size_t i = 0; switch(base){ case kHex: i = (valueUpper(ccase) ? 0 : 16); do{ *--e = "0123456789ABCDEF0123456789abcdef"[(cc & 0xF) + i]; cc >>= 4; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'X' : 'x'); *--e = '0'; } break; case kOct: do{ *--e = (cc & 7) + '0'; cc >>= 3; }while(cc); if(sb) *--e = '0'; break; case kBin: do{ *--e = (cc & 1) + '0'; cc >>= 1; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'B' : 'b'); *--e = '0'; } break; default:assert(0); } return e; } void setWidth(const char * s, size_t len){ assert(s && len); size_t w = width(); assert(w <= 255); const bool r = adjustright(); if(!r) buf_.append(s, len); if(len < w) buf_.append(w - len, fill()); if(r) buf_.append(s, len); width(0); } //fields std::string buf_; __Flags flags_; }; namespace Manip{ inline CToString & boolalpha(CToString & tos) { tos.boolalpha(true); return tos; } inline CToString & noboolalpha(CToString & tos) { tos.boolalpha(false); return tos; } inline NS_IMPL::CToStringWidth setw(int w) { return NS_IMPL::CToStringWidth(w); } inline NS_IMPL::CToStringFill fill(char c) { return NS_IMPL::CToStringFill(c); } inline CToString & left(CToString & tos) { tos.adjustright(false); return tos; } inline CToString & right(CToString & tos) { tos.adjustright(true); return tos; } inline NS_IMPL::CToStringBase setbase(int base) { return NS_IMPL::CToStringBase(base); } inline CToString & dec(CToString & tos) { return (tos<<setbase(10)); } inline CToString & hex(CToString & tos) { return (tos<<setbase(16)); } inline CToString & oct(CToString & tos) { return (tos<<setbase(8)); } inline CToString & bin(CToString & tos) { return (tos<<setbase(2)); } inline CToString & showbase(CToString & tos) { tos.showbase(true); return tos; } inline CToString & noshowbase(CToString & tos) { tos.showbase(false); return tos; } inline CToString & autocase(CToString & tos) { tos.charcase(CToString::kAutoCase); return tos; } inline CToString & uppercase(CToString & tos) { tos.charcase(CToString::kUpperCase); return tos; } inline CToString & nouppercase(CToString & tos) { tos.charcase(CToString::kLowerCase); return tos; } inline CToString & showpos(CToString & tos) { tos.showpos(true); return tos; } inline CToString & noshowpos(CToString & tos) { tos.showpos(false); return tos; } inline CToString & endl(CToString & tos) { return (tos<<'\n'); } inline CToString & ends(CToString & tos) { return (tos<<'\0'); } }//namespace Manip NS_SERVER_END #endif
83  // 16 以16进制输出整数 // 8 以8进制输出整数 // 2 以2进制输出整数 // 其他 以10进制输出整数 void base(int base){ switch(base){ case 16:flags_.base_ = kHex;break; case 8:flags_.base_ = kOct;break; case 2:flags_.base_ = kBin;break; default:flags_.base_ = kDec; } } int base() const{return (kDec == fbase() ? 10 : (kHex == fbase() ? 16 : (kOct == fbase() ? 8 : 2)));} //设置/获取是否显示进制(0x, 0X, 0, 0b, 0B) void showbase(bool v){flags_.nobase_ = (v ? 0 : 1);} bool showbase() const{return (0 == flags_.nobase_);} //设置/获取字符大小写方式 //return: // 0 autocase // 1 uppercase // 2 lowercase // 其他 未知 void charcase(int v){flags_.autocase_ = (v & 3);} int charcase() const{return (flags_.autocase_ & 3);} //设置/获取正整数前面是否加'+' void showpos(bool c){flags_.showpos_ = (c ? 1 : 0);} bool showpos() const{return (0 != flags_.showpos_);} //print basic types __Myt & operator <<(bool c){ if(boolalpha()) return (c ? printStr("true", 4) : printStr("false", 5)); return printChar(c ? '1' : '0'); } __Myt & operator <<(char c){return printChar(c);} __Myt & operator <<(signed char c){return printChar(c);} __Myt & operator <<(unsigned char c){return printChar(c);} __Myt & operator <<(short c){return printInt(c);} __Myt & operator <<(unsigned short c){return printInt(c);} __Myt & operator <<(int c){return printInt(c);} __Myt & operator <<(unsigned int c){return printInt(c);} __Myt & operator <<(long c){return printInt(c);} __Myt & operator <<(unsigned long c){return printInt(c);} __Myt & operator <<(long long c){return printInt(c);} __Myt & operator <<(unsigned long long c){return printInt(c);} __Myt & operator <<(float c); //TODO: precision, max length, scientific ... __Myt & operator <<(double c); //TODO __Myt & operator <<(const char * c){return printStr(c);} __Myt & operator <<(char * c){return operator <<(static_cast<const char *>(c));} __Myt & operator <<(const std::string & c){ if(c.empty()) return *this; return printStr(c.c_str(), c.length()); } __Myt & operator <<(const void * c){return printInt(reinterpret_cast<long>(c), true, kHex, kLowerCase);} __Myt & operator <<(void * c){return operator <<(static_cast<const void *>(c));} //manipulators __Myt & operator <<(const NS_IMPL::CToStringBase & c){ base(c.base_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringWidth & c){ width(c.w_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringFill & c){ fill(c.fill_); return *this; } __Myt & operator <<(__Myt & (*func)(__Myt &)){ if(func) func(*this); return *this; } //设置/获取结果字符串 void str(const std::string & str){buf_ = str;} const std::string & str() const{return buf_;} private: uint8_t fbase() const{return flags_.base_;}; static bool baseUpper(int ccase){return (kUpperCase == ccase);} static bool valueUpper(int ccase){return (kLowerCase != ccase);} template<typename Int> bool realShowPos(Int c) const{ typedef std::numeric_limits<Int> __Limits; return (__Limits::is_signed #ifdef __0_NO_POSITIVE && 0 != c #endif && showpos()); } template<typename Int> __Myt & printInt(Int c){return printInt(c, showbase(), fbase(), charcase());} template<typename Int> __Myt & printInt(Int c, bool showbase, uint8_t base, int ccase){ char tmp[72]; //max for all bases(2, 8, 10, 16) char * e = tmp + sizeof tmp; char * s = NULL; if(kDec == base) s = int2Str10(e, c); else s = int2Str(e, c, base, showbase, ccase); setWidth(s, e - s); return *this; } __Myt & printChar(char c){ setWidth(&c, 1); return *this; } __Myt & printStr(const char * c, size_t len = 0){ if(NULL == c) return printStr("(NULL)", 6); if(!len) len = ::strlen(c); if(len) setWidth(c, len); return *this; } template<typename Int> char * int2Str10(char * e, Int c){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const char * const kDig99 = "00010203040506070809" "10111213141516171819" "20212223242526272829" "30313233343536373839" "40414243444546474849" "50515253545556575859" "60616263646566676869" "70717273747576777879" "80818283848586878889" "90919293949596979899"; __Unsigned cc = c; const bool negtive = !(c > 0 || c == 0); if(negtive) cc = -cc; for(__Unsigned i;cc > 99;){ i = cc; cc /= 100; memcpy((e -= 2), kDig99 + ((i << 1) - cc * 200), 2); } if(cc < 10){ *--e = '0' + cc; }else memcpy((e -= 2), kDig99 + cc * 2, 2); if(negtive) *--e = '-'; else if(realShowPos(c)) *--e = '+'; return e; } template<typename Int> char * int2Str(char * e, Int c, uint8_t base, bool showbase, int ccase){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const bool sb = (showbase && 0 != c); //0 need not showbase __Unsigned cc = c; size_t i = 0; switch(base){ case kHex: i = (valueUpper(ccase) ? 0 : 16); do{ *--e = "0123456789ABCDEF0123456789abcdef"[(cc & 0xF) + i]; cc >>= 4; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'X' : 'x'); *--e = '0'; } break; case kOct: do{ *--e = (cc & 7) + '0'; cc >>= 3; }while(cc); if(sb) *--e = '0'; break; case kBin: do{ *--e = (cc & 1) + '0'; cc >>= 1; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'B' : 'b'); *--e = '0'; } break; default:assert(0); } return e; } void setWidth(const char * s, size_t len){ assert(s && len); size_t w = width(); assert(w <= 255); const bool r = adjustright(); if(!r) buf_.append(s, len); if(len < w) buf_.append(w - len, fill()); if(r) buf_.append(s, len); width(0); } //fields std::string buf_; __Flags flags_; }; namespace Manip{ inline CToString & boolalpha(CToString & tos) { tos.boolalpha(true); return tos; } inline CToString & noboolalpha(CToString & tos) { tos.boolalpha(false); return tos; } inline NS_IMPL::CToStringWidth setw(int w) { return NS_IMPL::CToStringWidth(w); } inline NS_IMPL::CToStringFill fill(char c) { return NS_IMPL::CToStringFill(c); } inline CToString & left(CToString & tos) { tos.adjustright(false); return tos; } inline CToString & right(CToString & tos) { tos.adjustright(true); return tos; } inline NS_IMPL::CToStringBase setbase(int base) { return NS_IMPL::CToStringBase(base); } inline CToString & dec(CToString & tos) { return (tos<<setbase(10)); } inline CToString & hex(CToString & tos) { return (tos<<setbase(16)); } inline CToString & oct(CToString & tos) { return (tos<<setbase(8)); } inline CToString & bin(CToString & tos) { return (tos<<setbase(2)); } inline CToString & showbase(CToString & tos) { tos.showbase(true); return tos; } inline CToString & noshowbase(CToString & tos) { tos.showbase(false); return tos; } inline CToString & autocase(CToString & tos) { tos.charcase(CToString::kAutoCase); return tos; } inline CToString & uppercase(CToString & tos) { tos.charcase(CToString::kUpperCase); return tos; } inline CToString & nouppercase(CToString & tos) { tos.charcase(CToString::kLowerCase); return tos; } inline CToString & showpos(CToString & tos) { tos.showpos(true); return tos; } inline CToString & noshowpos(CToString & tos) { tos.showpos(false); return tos; } inline CToString & endl(CToString & tos) { return (tos<<'\n'); } inline CToString & ends(CToString & tos) { return (tos<<'\0'); } }//namespace Manip NS_SERVER_END #endif
84  // 8 以8进制输出整数 // 2 以2进制输出整数 // 其他 以10进制输出整数 void base(int base){ switch(base){ case 16:flags_.base_ = kHex;break; case 8:flags_.base_ = kOct;break; case 2:flags_.base_ = kBin;break; default:flags_.base_ = kDec; } } int base() const{return (kDec == fbase() ? 10 : (kHex == fbase() ? 16 : (kOct == fbase() ? 8 : 2)));} //设置/获取是否显示进制(0x, 0X, 0, 0b, 0B) void showbase(bool v){flags_.nobase_ = (v ? 0 : 1);} bool showbase() const{return (0 == flags_.nobase_);} //设置/获取字符大小写方式 //return: // 0 autocase // 1 uppercase // 2 lowercase // 其他 未知 void charcase(int v){flags_.autocase_ = (v & 3);} int charcase() const{return (flags_.autocase_ & 3);} //设置/获取正整数前面是否加'+' void showpos(bool c){flags_.showpos_ = (c ? 1 : 0);} bool showpos() const{return (0 != flags_.showpos_);} //print basic types __Myt & operator <<(bool c){ if(boolalpha()) return (c ? printStr("true", 4) : printStr("false", 5)); return printChar(c ? '1' : '0'); } __Myt & operator <<(char c){return printChar(c);} __Myt & operator <<(signed char c){return printChar(c);} __Myt & operator <<(unsigned char c){return printChar(c);} __Myt & operator <<(short c){return printInt(c);} __Myt & operator <<(unsigned short c){return printInt(c);} __Myt & operator <<(int c){return printInt(c);} __Myt & operator <<(unsigned int c){return printInt(c);} __Myt & operator <<(long c){return printInt(c);} __Myt & operator <<(unsigned long c){return printInt(c);} __Myt & operator <<(long long c){return printInt(c);} __Myt & operator <<(unsigned long long c){return printInt(c);} __Myt & operator <<(float c); //TODO: precision, max length, scientific ... __Myt & operator <<(double c); //TODO __Myt & operator <<(const char * c){return printStr(c);} __Myt & operator <<(char * c){return operator <<(static_cast<const char *>(c));} __Myt & operator <<(const std::string & c){ if(c.empty()) return *this; return printStr(c.c_str(), c.length()); } __Myt & operator <<(const void * c){return printInt(reinterpret_cast<long>(c), true, kHex, kLowerCase);} __Myt & operator <<(void * c){return operator <<(static_cast<const void *>(c));} //manipulators __Myt & operator <<(const NS_IMPL::CToStringBase & c){ base(c.base_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringWidth & c){ width(c.w_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringFill & c){ fill(c.fill_); return *this; } __Myt & operator <<(__Myt & (*func)(__Myt &)){ if(func) func(*this); return *this; } //设置/获取结果字符串 void str(const std::string & str){buf_ = str;} const std::string & str() const{return buf_;} private: uint8_t fbase() const{return flags_.base_;}; static bool baseUpper(int ccase){return (kUpperCase == ccase);} static bool valueUpper(int ccase){return (kLowerCase != ccase);} template<typename Int> bool realShowPos(Int c) const{ typedef std::numeric_limits<Int> __Limits; return (__Limits::is_signed #ifdef __0_NO_POSITIVE && 0 != c #endif && showpos()); } template<typename Int> __Myt & printInt(Int c){return printInt(c, showbase(), fbase(), charcase());} template<typename Int> __Myt & printInt(Int c, bool showbase, uint8_t base, int ccase){ char tmp[72]; //max for all bases(2, 8, 10, 16) char * e = tmp + sizeof tmp; char * s = NULL; if(kDec == base) s = int2Str10(e, c); else s = int2Str(e, c, base, showbase, ccase); setWidth(s, e - s); return *this; } __Myt & printChar(char c){ setWidth(&c, 1); return *this; } __Myt & printStr(const char * c, size_t len = 0){ if(NULL == c) return printStr("(NULL)", 6); if(!len) len = ::strlen(c); if(len) setWidth(c, len); return *this; } template<typename Int> char * int2Str10(char * e, Int c){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const char * const kDig99 = "00010203040506070809" "10111213141516171819" "20212223242526272829" "30313233343536373839" "40414243444546474849" "50515253545556575859" "60616263646566676869" "70717273747576777879" "80818283848586878889" "90919293949596979899"; __Unsigned cc = c; const bool negtive = !(c > 0 || c == 0); if(negtive) cc = -cc; for(__Unsigned i;cc > 99;){ i = cc; cc /= 100; memcpy((e -= 2), kDig99 + ((i << 1) - cc * 200), 2); } if(cc < 10){ *--e = '0' + cc; }else memcpy((e -= 2), kDig99 + cc * 2, 2); if(negtive) *--e = '-'; else if(realShowPos(c)) *--e = '+'; return e; } template<typename Int> char * int2Str(char * e, Int c, uint8_t base, bool showbase, int ccase){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const bool sb = (showbase && 0 != c); //0 need not showbase __Unsigned cc = c; size_t i = 0; switch(base){ case kHex: i = (valueUpper(ccase) ? 0 : 16); do{ *--e = "0123456789ABCDEF0123456789abcdef"[(cc & 0xF) + i]; cc >>= 4; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'X' : 'x'); *--e = '0'; } break; case kOct: do{ *--e = (cc & 7) + '0'; cc >>= 3; }while(cc); if(sb) *--e = '0'; break; case kBin: do{ *--e = (cc & 1) + '0'; cc >>= 1; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'B' : 'b'); *--e = '0'; } break; default:assert(0); } return e; } void setWidth(const char * s, size_t len){ assert(s && len); size_t w = width(); assert(w <= 255); const bool r = adjustright(); if(!r) buf_.append(s, len); if(len < w) buf_.append(w - len, fill()); if(r) buf_.append(s, len); width(0); } //fields std::string buf_; __Flags flags_; }; namespace Manip{ inline CToString & boolalpha(CToString & tos) { tos.boolalpha(true); return tos; } inline CToString & noboolalpha(CToString & tos) { tos.boolalpha(false); return tos; } inline NS_IMPL::CToStringWidth setw(int w) { return NS_IMPL::CToStringWidth(w); } inline NS_IMPL::CToStringFill fill(char c) { return NS_IMPL::CToStringFill(c); } inline CToString & left(CToString & tos) { tos.adjustright(false); return tos; } inline CToString & right(CToString & tos) { tos.adjustright(true); return tos; } inline NS_IMPL::CToStringBase setbase(int base) { return NS_IMPL::CToStringBase(base); } inline CToString & dec(CToString & tos) { return (tos<<setbase(10)); } inline CToString & hex(CToString & tos) { return (tos<<setbase(16)); } inline CToString & oct(CToString & tos) { return (tos<<setbase(8)); } inline CToString & bin(CToString & tos) { return (tos<<setbase(2)); } inline CToString & showbase(CToString & tos) { tos.showbase(true); return tos; } inline CToString & noshowbase(CToString & tos) { tos.showbase(false); return tos; } inline CToString & autocase(CToString & tos) { tos.charcase(CToString::kAutoCase); return tos; } inline CToString & uppercase(CToString & tos) { tos.charcase(CToString::kUpperCase); return tos; } inline CToString & nouppercase(CToString & tos) { tos.charcase(CToString::kLowerCase); return tos; } inline CToString & showpos(CToString & tos) { tos.showpos(true); return tos; } inline CToString & noshowpos(CToString & tos) { tos.showpos(false); return tos; } inline CToString & endl(CToString & tos) { return (tos<<'\n'); } inline CToString & ends(CToString & tos) { return (tos<<'\0'); } }//namespace Manip NS_SERVER_END #endif
85  // 2 以2进制输出整数 // 其他 以10进制输出整数 void base(int base){ switch(base){ case 16:flags_.base_ = kHex;break; case 8:flags_.base_ = kOct;break; case 2:flags_.base_ = kBin;break; default:flags_.base_ = kDec; } } int base() const{return (kDec == fbase() ? 10 : (kHex == fbase() ? 16 : (kOct == fbase() ? 8 : 2)));} //设置/获取是否显示进制(0x, 0X, 0, 0b, 0B) void showbase(bool v){flags_.nobase_ = (v ? 0 : 1);} bool showbase() const{return (0 == flags_.nobase_);} //设置/获取字符大小写方式 //return: // 0 autocase // 1 uppercase // 2 lowercase // 其他 未知 void charcase(int v){flags_.autocase_ = (v & 3);} int charcase() const{return (flags_.autocase_ & 3);} //设置/获取正整数前面是否加'+' void showpos(bool c){flags_.showpos_ = (c ? 1 : 0);} bool showpos() const{return (0 != flags_.showpos_);} //print basic types __Myt & operator <<(bool c){ if(boolalpha()) return (c ? printStr("true", 4) : printStr("false", 5)); return printChar(c ? '1' : '0'); } __Myt & operator <<(char c){return printChar(c);} __Myt & operator <<(signed char c){return printChar(c);} __Myt & operator <<(unsigned char c){return printChar(c);} __Myt & operator <<(short c){return printInt(c);} __Myt & operator <<(unsigned short c){return printInt(c);} __Myt & operator <<(int c){return printInt(c);} __Myt & operator <<(unsigned int c){return printInt(c);} __Myt & operator <<(long c){return printInt(c);} __Myt & operator <<(unsigned long c){return printInt(c);} __Myt & operator <<(long long c){return printInt(c);} __Myt & operator <<(unsigned long long c){return printInt(c);} __Myt & operator <<(float c); //TODO: precision, max length, scientific ... __Myt & operator <<(double c); //TODO __Myt & operator <<(const char * c){return printStr(c);} __Myt & operator <<(char * c){return operator <<(static_cast<const char *>(c));} __Myt & operator <<(const std::string & c){ if(c.empty()) return *this; return printStr(c.c_str(), c.length()); } __Myt & operator <<(const void * c){return printInt(reinterpret_cast<long>(c), true, kHex, kLowerCase);} __Myt & operator <<(void * c){return operator <<(static_cast<const void *>(c));} //manipulators __Myt & operator <<(const NS_IMPL::CToStringBase & c){ base(c.base_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringWidth & c){ width(c.w_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringFill & c){ fill(c.fill_); return *this; } __Myt & operator <<(__Myt & (*func)(__Myt &)){ if(func) func(*this); return *this; } //设置/获取结果字符串 void str(const std::string & str){buf_ = str;} const std::string & str() const{return buf_;} private: uint8_t fbase() const{return flags_.base_;}; static bool baseUpper(int ccase){return (kUpperCase == ccase);} static bool valueUpper(int ccase){return (kLowerCase != ccase);} template<typename Int> bool realShowPos(Int c) const{ typedef std::numeric_limits<Int> __Limits; return (__Limits::is_signed #ifdef __0_NO_POSITIVE && 0 != c #endif && showpos()); } template<typename Int> __Myt & printInt(Int c){return printInt(c, showbase(), fbase(), charcase());} template<typename Int> __Myt & printInt(Int c, bool showbase, uint8_t base, int ccase){ char tmp[72]; //max for all bases(2, 8, 10, 16) char * e = tmp + sizeof tmp; char * s = NULL; if(kDec == base) s = int2Str10(e, c); else s = int2Str(e, c, base, showbase, ccase); setWidth(s, e - s); return *this; } __Myt & printChar(char c){ setWidth(&c, 1); return *this; } __Myt & printStr(const char * c, size_t len = 0){ if(NULL == c) return printStr("(NULL)", 6); if(!len) len = ::strlen(c); if(len) setWidth(c, len); return *this; } template<typename Int> char * int2Str10(char * e, Int c){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const char * const kDig99 = "00010203040506070809" "10111213141516171819" "20212223242526272829" "30313233343536373839" "40414243444546474849" "50515253545556575859" "60616263646566676869" "70717273747576777879" "80818283848586878889" "90919293949596979899"; __Unsigned cc = c; const bool negtive = !(c > 0 || c == 0); if(negtive) cc = -cc; for(__Unsigned i;cc > 99;){ i = cc; cc /= 100; memcpy((e -= 2), kDig99 + ((i << 1) - cc * 200), 2); } if(cc < 10){ *--e = '0' + cc; }else memcpy((e -= 2), kDig99 + cc * 2, 2); if(negtive) *--e = '-'; else if(realShowPos(c)) *--e = '+'; return e; } template<typename Int> char * int2Str(char * e, Int c, uint8_t base, bool showbase, int ccase){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const bool sb = (showbase && 0 != c); //0 need not showbase __Unsigned cc = c; size_t i = 0; switch(base){ case kHex: i = (valueUpper(ccase) ? 0 : 16); do{ *--e = "0123456789ABCDEF0123456789abcdef"[(cc & 0xF) + i]; cc >>= 4; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'X' : 'x'); *--e = '0'; } break; case kOct: do{ *--e = (cc & 7) + '0'; cc >>= 3; }while(cc); if(sb) *--e = '0'; break; case kBin: do{ *--e = (cc & 1) + '0'; cc >>= 1; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'B' : 'b'); *--e = '0'; } break; default:assert(0); } return e; } void setWidth(const char * s, size_t len){ assert(s && len); size_t w = width(); assert(w <= 255); const bool r = adjustright(); if(!r) buf_.append(s, len); if(len < w) buf_.append(w - len, fill()); if(r) buf_.append(s, len); width(0); } //fields std::string buf_; __Flags flags_; }; namespace Manip{ inline CToString & boolalpha(CToString & tos) { tos.boolalpha(true); return tos; } inline CToString & noboolalpha(CToString & tos) { tos.boolalpha(false); return tos; } inline NS_IMPL::CToStringWidth setw(int w) { return NS_IMPL::CToStringWidth(w); } inline NS_IMPL::CToStringFill fill(char c) { return NS_IMPL::CToStringFill(c); } inline CToString & left(CToString & tos) { tos.adjustright(false); return tos; } inline CToString & right(CToString & tos) { tos.adjustright(true); return tos; } inline NS_IMPL::CToStringBase setbase(int base) { return NS_IMPL::CToStringBase(base); } inline CToString & dec(CToString & tos) { return (tos<<setbase(10)); } inline CToString & hex(CToString & tos) { return (tos<<setbase(16)); } inline CToString & oct(CToString & tos) { return (tos<<setbase(8)); } inline CToString & bin(CToString & tos) { return (tos<<setbase(2)); } inline CToString & showbase(CToString & tos) { tos.showbase(true); return tos; } inline CToString & noshowbase(CToString & tos) { tos.showbase(false); return tos; } inline CToString & autocase(CToString & tos) { tos.charcase(CToString::kAutoCase); return tos; } inline CToString & uppercase(CToString & tos) { tos.charcase(CToString::kUpperCase); return tos; } inline CToString & nouppercase(CToString & tos) { tos.charcase(CToString::kLowerCase); return tos; } inline CToString & showpos(CToString & tos) { tos.showpos(true); return tos; } inline CToString & noshowpos(CToString & tos) { tos.showpos(false); return tos; } inline CToString & endl(CToString & tos) { return (tos<<'\n'); } inline CToString & ends(CToString & tos) { return (tos<<'\0'); } }//namespace Manip NS_SERVER_END #endif
86  // 其他 以10进制输出整数 void base(int base){ switch(base){ case 16:flags_.base_ = kHex;break; case 8:flags_.base_ = kOct;break; case 2:flags_.base_ = kBin;break; default:flags_.base_ = kDec; } } int base() const{return (kDec == fbase() ? 10 : (kHex == fbase() ? 16 : (kOct == fbase() ? 8 : 2)));} //设置/获取是否显示进制(0x, 0X, 0, 0b, 0B) void showbase(bool v){flags_.nobase_ = (v ? 0 : 1);} bool showbase() const{return (0 == flags_.nobase_);} //设置/获取字符大小写方式 //return: // 0 autocase // 1 uppercase // 2 lowercase // 其他 未知 void charcase(int v){flags_.autocase_ = (v & 3);} int charcase() const{return (flags_.autocase_ & 3);} //设置/获取正整数前面是否加'+' void showpos(bool c){flags_.showpos_ = (c ? 1 : 0);} bool showpos() const{return (0 != flags_.showpos_);} //print basic types __Myt & operator <<(bool c){ if(boolalpha()) return (c ? printStr("true", 4) : printStr("false", 5)); return printChar(c ? '1' : '0'); } __Myt & operator <<(char c){return printChar(c);} __Myt & operator <<(signed char c){return printChar(c);} __Myt & operator <<(unsigned char c){return printChar(c);} __Myt & operator <<(short c){return printInt(c);} __Myt & operator <<(unsigned short c){return printInt(c);} __Myt & operator <<(int c){return printInt(c);} __Myt & operator <<(unsigned int c){return printInt(c);} __Myt & operator <<(long c){return printInt(c);} __Myt & operator <<(unsigned long c){return printInt(c);} __Myt & operator <<(long long c){return printInt(c);} __Myt & operator <<(unsigned long long c){return printInt(c);} __Myt & operator <<(float c); //TODO: precision, max length, scientific ... __Myt & operator <<(double c); //TODO __Myt & operator <<(const char * c){return printStr(c);} __Myt & operator <<(char * c){return operator <<(static_cast<const char *>(c));} __Myt & operator <<(const std::string & c){ if(c.empty()) return *this; return printStr(c.c_str(), c.length()); } __Myt & operator <<(const void * c){return printInt(reinterpret_cast<long>(c), true, kHex, kLowerCase);} __Myt & operator <<(void * c){return operator <<(static_cast<const void *>(c));} //manipulators __Myt & operator <<(const NS_IMPL::CToStringBase & c){ base(c.base_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringWidth & c){ width(c.w_); return *this; } __Myt & operator <<(const NS_IMPL::CToStringFill & c){ fill(c.fill_); return *this; } __Myt & operator <<(__Myt & (*func)(__Myt &)){ if(func) func(*this); return *this; } //设置/获取结果字符串 void str(const std::string & str){buf_ = str;} const std::string & str() const{return buf_;} private: uint8_t fbase() const{return flags_.base_;}; static bool baseUpper(int ccase){return (kUpperCase == ccase);} static bool valueUpper(int ccase){return (kLowerCase != ccase);} template<typename Int> bool realShowPos(Int c) const{ typedef std::numeric_limits<Int> __Limits; return (__Limits::is_signed #ifdef __0_NO_POSITIVE && 0 != c #endif && showpos()); } template<typename Int> __Myt & printInt(Int c){return printInt(c, showbase(), fbase(), charcase());} template<typename Int> __Myt & printInt(Int c, bool showbase, uint8_t base, int ccase){ char tmp[72]; //max for all bases(2, 8, 10, 16) char * e = tmp + sizeof tmp; char * s = NULL; if(kDec == base) s = int2Str10(e, c); else s = int2Str(e, c, base, showbase, ccase); setWidth(s, e - s); return *this; } __Myt & printChar(char c){ setWidth(&c, 1); return *this; } __Myt & printStr(const char * c, size_t len = 0){ if(NULL == c) return printStr("(NULL)", 6); if(!len) len = ::strlen(c); if(len) setWidth(c, len); return *this; } template<typename Int> char * int2Str10(char * e, Int c){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const char * const kDig99 = "00010203040506070809" "10111213141516171819" "20212223242526272829" "30313233343536373839" "40414243444546474849" "50515253545556575859" "60616263646566676869" "70717273747576777879" "80818283848586878889" "90919293949596979899"; __Unsigned cc = c; const bool negtive = !(c > 0 || c == 0); if(negtive) cc = -cc; for(__Unsigned i;cc > 99;){ i = cc; cc /= 100; memcpy((e -= 2), kDig99 + ((i << 1) - cc * 200), 2); } if(cc < 10){ *--e = '0' + cc; }else memcpy((e -= 2), kDig99 + cc * 2, 2); if(negtive) *--e = '-'; else if(realShowPos(c)) *--e = '+'; return e; } template<typename Int> char * int2Str(char * e, Int c, uint8_t base, bool showbase, int ccase){ typedef typename CTypeTraits<Int>::__Unsigned __Unsigned; assert(e); const bool sb = (showbase && 0 != c); //0 need not showbase __Unsigned cc = c; size_t i = 0; switch(base){ case kHex: i = (valueUpper(ccase) ? 0 : 16); do{ *--e = "0123456789ABCDEF0123456789abcdef"[(cc & 0xF) + i]; cc >>= 4; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'X' : 'x'); *--e = '0'; } break; case kOct: do{ *--e = (cc & 7) + '0'; cc >>= 3; }while(cc); if(sb) *--e = '0'; break; case kBin: do{ *--e = (cc & 1) + '0'; cc >>= 1; }while(cc); if(sb){ *--e = (baseUpper(ccase) ? 'B' : 'b'); *--e = '0'; } break; default:assert(0); } return e; } void setWidth(const char * s, size_t len){ assert(s && len); size_t w = width(); assert(w <= 255); const bool r = adjustright(); if(!r) buf_.append(s, len); if(len < w) buf_.append(w - len, fill()); if(r) buf_.append(s, len); width(0); } //fields std::string buf_; __Flags flags_; }; namespace Manip{ inline CToString & boolalpha(CToString & tos) { tos.boolalpha(true); return tos; } inline CToString & noboolalpha(CToString & tos) { tos.boolalpha(false); return tos; } inline NS_IMPL::CToStringWidth setw(int w) { return NS_IMPL::CToStringWidth(w); } inline NS_IMPL::CToStringFill fill(char c) { return NS_IMPL::CToStringFill(c); } inline CToString & left(CToString & tos) { tos.adjustright(false); return tos; } inline CToString & right(CToString & tos) { tos.adjustright(true); return tos; } inline NS_IMPL::CToStringBase setbase(int base) { return NS_IMPL::CToStringBase(base); } inline CToString & dec(CToString & tos) { return (tos<<setbase(10)); } inline CToString & hex(CToString & tos) { return (tos<<setbase(16)); } inline CToString & oct(CToString & tos) { return (tos<<setbase(8)); } inline CToString & bin(CToString & tos) { return (tos<<setbase(2)); } inline CToString & showbase(CToString & tos) { tos.showbase(true); return tos; } inline CToString & noshowbase(CToString & tos) { tos.showbase(false); return tos; } inline CToString & autocase(CToString & tos) { tos.charcase(CToString::kAutoCase); return tos; } inline CToString & uppercase(CToString & tos) { tos.charcase(CToString::kUpperCase); return tos; } inline CToString & nouppercase(CToString & tos) { tos.charcase(CToString::kLowerCase); return tos; } inline CToString & showpos(CToString & tos) { tos.showpos(true); return tos; } inline CToString & noshowpos(CToString & tos) { tos.showpos(false); return tos; } inline CToString & endl(CToString & tos) { return (tos<<'\n'); } inline CToString & ends(CToString & tos) { return (tos<<'\0'); } }//namespace Manip NS_SERVER_END #endif
87  void base(int base){
88  switch(base){
89  case 16:flags_.base_ = kHex;break;
90  case 8:flags_.base_ = kOct;break;
91  case 2:flags_.base_ = kBin;break;
92  default:flags_.base_ = kDec;
93  }
94  }
95  int base() const{return (kDec == fbase() ? 10 : (kHex == fbase() ? 16 : (kOct == fbase() ? 8 : 2)));}
96  //设置/获取是否显示进制(0x, 0X, 0, 0b, 0B)
97  void showbase(bool v){flags_.nobase_ = (v ? 0 : 1);}
98  bool showbase() const{return (0 == flags_.nobase_);}
99  //设置/获取字符大小写方式
100  //return:
101  // 0 autocase
102  // 1 uppercase
103  // 2 lowercase
104  // 其他 未知
105  void charcase(int v){flags_.autocase_ = (v & 3);}
106  int charcase() const{return (flags_.autocase_ & 3);}
107  //设置/获取正整数前面是否加'+'
108  void showpos(bool c){flags_.showpos_ = (c ? 1 : 0);}
109  bool showpos() const{return (0 != flags_.showpos_);}
110  //print basic types
111  __Myt & operator <<(bool c){
112  if(boolalpha())
113  return (c ? printStr("true", 4) : printStr("false", 5));
114  return printChar(c ? '1' : '0');
115  }
116  __Myt & operator <<(char c){return printChar(c);}
117  __Myt & operator <<(signed char c){return printChar(c);}
118  __Myt & operator <<(unsigned char c){return printChar(c);}
119  __Myt & operator <<(short c){return printInt(c);}
120  __Myt & operator <<(unsigned short c){return printInt(c);}
121  __Myt & operator <<(int c){return printInt(c);}
122  __Myt & operator <<(unsigned int c){return printInt(c);}
123  __Myt & operator <<(long c){return printInt(c);}
124  __Myt & operator <<(unsigned long c){return printInt(c);}
125  __Myt & operator <<(long long c){return printInt(c);}
126  __Myt & operator <<(unsigned long long c){return printInt(c);}
127  __Myt & operator <<(float c); //TODO: precision, max length, scientific ...
128  __Myt & operator <<(double c); //TODO
129  __Myt & operator <<(const char * c){return printStr(c);}
130  __Myt & operator <<(char * c){return operator <<(static_cast<const char *>(c));}
131  __Myt & operator <<(const std::string & c){
132  if(c.empty())
133  return *this;
134  return printStr(c.c_str(), c.length());
135  }
136  __Myt & operator <<(const void * c){return printInt(reinterpret_cast<long>(c), true, kHex, kLowerCase);}
137  __Myt & operator <<(void * c){return operator <<(static_cast<const void *>(c));}
138  //manipulators
139  __Myt & operator <<(const NS_IMPL::CToStringBase & c){
140  base(c.base_);
141  return *this;
142  }
143  __Myt & operator <<(const NS_IMPL::CToStringWidth & c){
144  width(c.w_);
145  return *this;
146  }
147  __Myt & operator <<(const NS_IMPL::CToStringFill & c){
148  fill(c.fill_);
149  return *this;
150  }
151  __Myt & operator <<(__Myt & (*func)(__Myt &)){
152  if(func)
153  func(*this);
154  return *this;
155  }
156  //设置/获取结果字符串
157  void str(const std::string & str){buf_ = str;}
158  const std::string & str() const{return buf_;}
159 private:
160  uint8_t fbase() const{return flags_.base_;};
161  static bool baseUpper(int ccase){return (kUpperCase == ccase);}
162  static bool valueUpper(int ccase){return (kLowerCase != ccase);}
163  template<typename Int>
164  bool realShowPos(Int c) const{
165  typedef std::numeric_limits<Int> __Limits;
166  return (__Limits::is_signed
167 #ifdef __0_NO_POSITIVE
168  && 0 != c
169 #endif
170  && showpos());
171  }
172  template<typename Int>
173  __Myt & printInt(Int c){return printInt(c, showbase(), fbase(), charcase());}
174  template<typename Int>
175  __Myt & printInt(Int c, bool showbase, uint8_t base, int ccase){
176  char tmp[72]; //max for all bases(2, 8, 10, 16)
177  char * e = tmp + sizeof tmp;
178  char * s = NULL;
179  if(kDec == base)
180  s = int2Str10(e, c);
181  else
182  s = int2Str(e, c, base, showbase, ccase);
183  setWidth(s, e - s);
184  return *this;
185  }
186  __Myt & printChar(char c){
187  setWidth(&c, 1);
188  return *this;
189  }
190  __Myt & printStr(const char * c, size_t len = 0){
191  if(NULL == c)
192  return printStr("(NULL)", 6);
193  if(!len)
194  len = ::strlen(c);
195  if(len)
196  setWidth(c, len);
197  return *this;
198  }
199  template<typename Int>
200  char * int2Str10(char * e, Int c){
201  typedef typename CTypeTraits<Int>::__Unsigned __Unsigned;
202  assert(e);
203  const char * const kDig99 =
204  "00010203040506070809"
205  "10111213141516171819"
206  "20212223242526272829"
207  "30313233343536373839"
208  "40414243444546474849"
209  "50515253545556575859"
210  "60616263646566676869"
211  "70717273747576777879"
212  "80818283848586878889"
213  "90919293949596979899";
214  __Unsigned cc = c;
215  const bool negtive = !(c > 0 || c == 0);
216  if(negtive)
217  cc = -cc;
218  for(__Unsigned i;cc > 99;){
219  i = cc;
220  cc /= 100;
221  memcpy((e -= 2), kDig99 + ((i << 1) - cc * 200), 2);
222  }
223  if(cc < 10){
224  *--e = '0' + cc;
225  }else
226  memcpy((e -= 2), kDig99 + cc * 2, 2);
227  if(negtive)
228  *--e = '-';
229  else if(realShowPos(c))
230  *--e = '+';
231  return e;
232  }
233  template<typename Int>
234  char * int2Str(char * e, Int c, uint8_t base, bool showbase, int ccase){
235  typedef typename CTypeTraits<Int>::__Unsigned __Unsigned;
236  assert(e);
237  const bool sb = (showbase && 0 != c); //0 need not showbase
238  __Unsigned cc = c;
239  size_t i = 0;
240  switch(base){
241  case kHex:
242  i = (valueUpper(ccase) ? 0 : 16);
243  do{
244  *--e = "0123456789ABCDEF0123456789abcdef"[(cc & 0xF) + i];
245  cc >>= 4;
246  }while(cc);
247  if(sb){
248  *--e = (baseUpper(ccase) ? 'X' : 'x');
249  *--e = '0';
250  }
251  break;
252  case kOct:
253  do{
254  *--e = (cc & 7) + '0';
255  cc >>= 3;
256  }while(cc);
257  if(sb)
258  *--e = '0';
259  break;
260  case kBin:
261  do{
262  *--e = (cc & 1) + '0';
263  cc >>= 1;
264  }while(cc);
265  if(sb){
266  *--e = (baseUpper(ccase) ? 'B' : 'b');
267  *--e = '0';
268  }
269  break;
270  default:assert(0);
271  }
272  return e;
273  }
274  void setWidth(const char * s, size_t len){
275  assert(s && len);
276  size_t w = width();
277  assert(w <= 255);
278  const bool r = adjustright();
279  if(!r)
280  buf_.append(s, len);
281  if(len < w)
282  buf_.append(w - len, fill());
283  if(r)
284  buf_.append(s, len);
285  width(0);
286  }
287  //fields
288  std::string buf_;
289  __Flags flags_;
290 };
291 
292 namespace Manip{
293 
294  inline CToString & boolalpha(CToString & tos)
295  {
296  tos.boolalpha(true);
297  return tos;
298  }
299 
300  inline CToString & noboolalpha(CToString & tos)
301  {
302  tos.boolalpha(false);
303  return tos;
304  }
305 
306  inline NS_IMPL::CToStringWidth setw(int w)
307  {
308  return NS_IMPL::CToStringWidth(w);
309  }
310 
311  inline NS_IMPL::CToStringFill fill(char c)
312  {
313  return NS_IMPL::CToStringFill(c);
314  }
315 
316  inline CToString & left(CToString & tos)
317  {
318  tos.adjustright(false);
319  return tos;
320  }
321 
322  inline CToString & right(CToString & tos)
323  {
324  tos.adjustright(true);
325  return tos;
326  }
327 
328  inline NS_IMPL::CToStringBase setbase(int base)
329  {
330  return NS_IMPL::CToStringBase(base);
331  }
332 
333  inline CToString & dec(CToString & tos)
334  {
335  return (tos<<setbase(10));
336  }
337 
338  inline CToString & hex(CToString & tos)
339  {
340  return (tos<<setbase(16));
341  }
342 
343  inline CToString & oct(CToString & tos)
344  {
345  return (tos<<setbase(8));
346  }
347 
348  inline CToString & bin(CToString & tos)
349  {
350  return (tos<<setbase(2));
351  }
352 
353  inline CToString & showbase(CToString & tos)
354  {
355  tos.showbase(true);
356  return tos;
357  }
358 
359  inline CToString & noshowbase(CToString & tos)
360  {
361  tos.showbase(false);
362  return tos;
363  }
364 
365  inline CToString & autocase(CToString & tos)
366  {
367  tos.charcase(CToString::kAutoCase);
368  return tos;
369  }
370 
371  inline CToString & uppercase(CToString & tos)
372  {
373  tos.charcase(CToString::kUpperCase);
374  return tos;
375  }
376 
377  inline CToString & nouppercase(CToString & tos)
378  {
379  tos.charcase(CToString::kLowerCase);
380  return tos;
381  }
382 
383  inline CToString & showpos(CToString & tos)
384  {
385  tos.showpos(true);
386  return tos;
387  }
388 
389  inline CToString & noshowpos(CToString & tos)
390  {
391  tos.showpos(false);
392  return tos;
393  }
394 
395  inline CToString & endl(CToString & tos)
396  {
397  return (tos<<'\n');
398  }
399 
400  inline CToString & ends(CToString & tos)
401  {
402  return (tos<<'\0');
403  }
404 
405 }//namespace Manip
406 
407 NS_SERVER_END
408 
409 #endif
410 
Definition: to_string.hh:43
Definition: template.hh:23
Manipulators for stream interface APIs.
Definition: data_stream.hh:41