00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef CXXTOOLS_CHAR_H
00029 #define CXXTOOLS_CHAR_H
00030
00031 #include <cxxtools/api.h>
00032 #include <string>
00033 #include <cstring>
00034 #include <ios>
00035 #include <stdint.h>
00036
00037 namespace cxxtools
00038 {
00039
00065 class Char
00066 {
00067 public:
00069 Char()
00070 : _value(0)
00071 {}
00072
00074 Char(char ch)
00075 : _value( (uint32_t)((unsigned char)ch) )
00076 {}
00077
00079 Char(signed char ch)
00080 : _value( (uint32_t)((unsigned char)ch) )
00081 {}
00082
00084 Char(unsigned char ch)
00085 : _value( (uint32_t)(ch) )
00086 {}
00087
00089 Char(short val)
00090 : _value( (uint32_t)((unsigned short)val) )
00091 {}
00092
00094 Char(const int& val)
00095 : _value( (uint32_t)(val) )
00096 {}
00097
00099 Char(const unsigned int& val)
00100 : _value(val)
00101 {}
00102
00104 Char(const long value)
00105 : _value( (uint32_t)((unsigned long)value) )
00106 {}
00107
00109 Char(const unsigned long val)
00110 : _value(val)
00111 {}
00112
00125 char narrow(char def = '?') const;
00126
00127 static Char null()
00128 {
00129 return Char(0);
00130 }
00131
00137 Char& operator=(uint32_t value)
00138 { _value = value; return *this; }
00139
00140 Char& operator=(const Char& ch)
00141 { _value = ch._value; return *this; }
00142
00147 uint32_t value() const
00148 { return _value; }
00149
00158 operator int() const
00159 { return _value; }
00160
00168 Char& operator-=(const Char& value)
00169 {
00170 this->_value -= value._value;
00171 return *this;
00172 }
00173
00181 Char& operator+=(const Char& value)
00182 {
00183 this->_value += value._value;
00184 return *this;
00185 }
00186
00187 Char& operator>>=(const Char& value)
00188 {
00189 this->_value >>= value._value;
00190 return *this;
00191 }
00192
00193 Char& operator<<=(const Char& value)
00194 {
00195 this->_value <<= value._value;
00196 return *this;
00197 }
00198
00201 friend bool operator==(const Char& a, const Char& b)
00202 { return a.value() == b.value(); }
00203
00206 friend bool operator==(const Char& a, char b)
00207 { return a.value() == (unsigned char)b; }
00208
00211 friend bool operator==(const Char& a, int b)
00212 { return a.value() == (unsigned int)b; }
00213
00216 friend bool operator!=(const Char& a, const Char& b)
00217 { return a.value() != b.value(); }
00218
00221 friend bool operator!=(const Char& a, char b)
00222 { return a.value() != (unsigned char)b; }
00223
00226 friend bool operator!=(const Char& a, wchar_t b)
00227 { return a.value() != (unsigned int)b; }
00228
00231 friend bool operator!=(const Char& a, int b)
00232 { return a.value() != (unsigned int)b; }
00233
00236 friend bool operator<(const Char& a, const Char& b)
00237 { return a.value() < b.value(); }
00238
00241 friend bool operator>(const Char& a, const Char& b)
00242 { return a.value() > b.value(); }
00243
00246 friend bool operator<=(const Char& a, const Char& b)
00247 { return a.value() <= b.value(); }
00248
00249 friend bool operator<=(const Char& a, int b)
00250 { return a.value() <= static_cast<uint32_t>(b); }
00251
00254 friend bool operator>=(const Char& a, const Char& b)
00255 { return a.value() >= b.value(); }
00256
00257 friend bool operator>=(const Char& a, int b)
00258 { return a.value() >= static_cast<uint32_t>(b); }
00259
00262 friend Char operator+(const Char& a, const Char& b)
00263 { return a.value() + b.value(); }
00264
00267 friend Char operator+(const Char& a, char ch)
00268 { return a.value() + ch; }
00269
00270 friend Char operator+(const Char& a, int ch)
00271 { return a.value() + ch; }
00272
00275 friend Char operator-(const Char& a, const Char& b)
00276 { return a.value() - b.value(); }
00277
00280 friend Char operator-(const Char& a, char ch)
00281 { return a.value() - ch; }
00282
00285 friend Char operator|(const Char& a, const Char& b)
00286 { return a.value() | b.value(); }
00287
00290 friend Char operator&(const Char& a, const Char& b)
00291 { return a.value() & b.value(); }
00292
00293 friend Char operator&(const Char& a, int b)
00294 { return a.value() & b; }
00295
00296 private:
00297 uint32_t _value;
00298 };
00299
00300 struct MBState
00301 {
00302 MBState()
00303 : n(0)
00304 {}
00305
00306 int n;
00307 union {
00308 uint32_t wchars[4];
00309 char mbytes[16];
00310 } value;
00311 };
00312
00313 }
00314
00315
00316 namespace std {
00317
00319 template<>
00320 struct char_traits<cxxtools::Char>
00321 {
00322 typedef cxxtools::Char char_type;
00323 typedef uint32_t int_type;
00324 typedef std::streamoff off_type;
00325 typedef std::streampos pos_type;
00326 typedef cxxtools::MBState state_type;
00327
00328 inline static void assign(char_type& c1, const char_type& c2);
00329
00330 inline static bool eq(const char_type& c1, const char_type& c2);
00331
00332 inline static bool lt(const char_type& c1, const char_type& c2);
00333
00334 inline static int compare(const char_type* c1, const char_type* c2, size_t n);
00335
00336 inline static size_t length(const char_type* s);
00337
00338 inline static const char_type* find(const char_type* s, size_t n, const char_type& a);
00339
00340 inline static char_type* move(char_type* s1, const char_type* s2, int_type n);
00341
00342 inline static char_type* copy(char_type* s1, const char_type* s2, size_t n);
00343
00344 inline static char_type* assign(char_type* s, size_t n, char_type a);
00345
00346 inline static char_type to_char_type(const int_type& c);
00347
00348 inline static int_type to_int_type(const char_type& c);
00349
00350 inline static bool eq_int_type(const int_type& c1, const int_type& c2);
00351
00352 inline static int_type eof();
00353
00354 inline static int_type not_eof(const int_type& c);
00355 };
00356
00357
00358 inline void char_traits<cxxtools::Char>::assign(char_type& c1, const char_type& c2)
00359 {
00360 c1 = c2;
00361 }
00362
00363
00364 inline bool char_traits<cxxtools::Char>::eq(const char_type& c1, const char_type& c2)
00365 {
00366 return c1 == c2;
00367 }
00368
00369
00370 inline bool char_traits<cxxtools::Char>::lt(const char_type& c1, const char_type& c2)
00371 {
00372 return c1 < c2;
00373 }
00374
00375
00376 inline int char_traits<cxxtools::Char>::compare(const char_type* s1, const char_type* s2, size_t n)
00377 {
00378 while(n-- > 0)
00379 {
00380 if( !eq(*s1, *s2) )
00381 return lt(*s1, *s2) ? -1 : +1;
00382
00383 ++s1;
00384 ++s2;
00385 }
00386
00387 return 0;
00388 }
00389
00390
00391 inline size_t char_traits<cxxtools::Char>::length(const char_type* s)
00392 {
00393 static const cxxtools::Char term(0);
00394 std::size_t n = 0;
00395 while( !eq(s[n], term) )
00396 ++n;
00397
00398 return n;
00399 }
00400
00401
00402 inline const char_traits<cxxtools::Char>::char_type*
00403 char_traits<cxxtools::Char>::find(const char_type* s, size_t n, const char_type& a)
00404 {
00405 while(n-- > 0) {
00406 if (*s == a)
00407 return s;
00408 ++s;
00409 }
00410
00411 return 0;
00412 }
00413
00414
00415 inline char_traits<cxxtools::Char>::char_type*
00416 char_traits<cxxtools::Char>::move(char_type* s1, const char_type* s2, int_type n)
00417 {
00418 return (cxxtools::Char*)std::memmove(s1, s2, n * sizeof(cxxtools::Char));
00419 }
00420
00421
00422 inline char_traits<cxxtools::Char>::char_type*
00423 char_traits<cxxtools::Char>::copy(char_type* s1, const char_type* s2, size_t n)
00424 {
00425 return (cxxtools::Char*)std::memcpy(s1, s2, n * sizeof(cxxtools::Char));
00426 }
00427
00428
00429 inline char_traits<cxxtools::Char>::char_type*
00430 char_traits<cxxtools::Char>::assign(char_type* s, size_t n, char_type a)
00431 {
00432 while(n-- > 0) {
00433 *(s++) = a;
00434 }
00435
00436 return s;
00437 }
00438
00439
00440 inline char_traits<cxxtools::Char>::char_type
00441 char_traits<cxxtools::Char>::to_char_type(const int_type& c)
00442 {
00443 return char_type(c);
00444 }
00445
00446
00447 inline char_traits<cxxtools::Char>::int_type
00448 char_traits<cxxtools::Char>::to_int_type(const char_type& c)
00449 {
00450 return c.value();
00451 }
00452
00453
00454 inline bool char_traits<cxxtools::Char>::eq_int_type(const int_type& c1, const int_type& c2)
00455 {
00456 return c1 == c2;
00457 }
00458
00459
00460 inline char_traits<cxxtools::Char>::int_type char_traits<cxxtools::Char>::eof()
00461 {
00462 return static_cast<char_traits<cxxtools::Char>::int_type>( uint32_t(-1) );
00463 }
00464
00465
00466 inline char_traits<cxxtools::Char>::int_type char_traits<cxxtools::Char>::not_eof(const int_type& c)
00467 {
00468 return eq_int_type(c, eof()) ? 0 : c;
00469 }
00470
00471 }
00472
00473 namespace cxxtools {
00474
00475 inline char Char::narrow(char def) const
00476 {
00477 if( _value == std::char_traits<Char>::eof() )
00478 {
00479 return std::char_traits<char>::eof();
00480 }
00481
00482 if( _value <= 0xff )
00483 {
00484 return (char)_value;
00485 }
00486
00487 return def;
00488 }
00489 }
00490
00491 #ifdef CXXTOOLS_WITH_STD_LOCALE
00492
00493 #include <locale>
00494
00495 namespace std {
00496
00497 #if (defined _MSC_VER || defined __QNX__ || defined __xlC__)
00498
00502 template <>
00503 class CXXTOOLS_API ctype< cxxtools::Char > : public ctype_base {
00504
00505 #else
00506
00509 template <>
00510 class CXXTOOLS_API ctype<cxxtools::Char> : public ctype_base, public locale::facet {
00511
00512 #endif
00513
00514 public:
00515 typedef ctype_base::mask mask;
00516
00517 static locale::id id;
00518 virtual locale::id& __get_id (void) const { return id; }
00519
00520 public:
00521 explicit ctype(size_t refs = 0);
00522
00523 virtual ~ctype();
00524
00525 bool is(mask m, cxxtools::Char c) const
00526 { return this->do_is(m, c); }
00527
00528 const cxxtools::Char* is(const cxxtools::Char *lo, const cxxtools::Char *hi, mask *vec) const
00529 { return this->do_is(lo, hi, vec); }
00530
00531 const cxxtools::Char* scan_is(mask m, const cxxtools::Char* lo, const cxxtools::Char* hi) const
00532 { return this->do_scan_is(m, lo, hi); }
00533
00534 const cxxtools::Char* scan_not(mask m, const cxxtools::Char* lo, const cxxtools::Char* hi) const
00535 { return this->do_scan_not(m, lo, hi); }
00536
00537 cxxtools::Char toupper(cxxtools::Char c) const
00538 { return this->do_toupper(c); }
00539
00540 const cxxtools::Char* toupper(cxxtools::Char *lo, const cxxtools::Char* hi) const
00541 { return this->do_toupper(lo, hi); }
00542
00543 cxxtools::Char tolower(cxxtools::Char c) const
00544 { return this->do_tolower(c); }
00545
00546 const cxxtools::Char* tolower(cxxtools::Char* lo, const cxxtools::Char* hi) const
00547 { return this->do_tolower(lo, hi); }
00548
00549 cxxtools::Char widen(char c) const
00550 { return this->do_widen(c); }
00551
00552 const char* widen(const char* lo, const char* hi, cxxtools::Char* to) const
00553 { return this->do_widen(lo, hi, to); }
00554
00555 char narrow(cxxtools::Char c, char dfault) const
00556 { return this->do_narrow(c, dfault); }
00557
00558 const cxxtools::Char* narrow(const cxxtools::Char* lo, const cxxtools::Char* hi,
00559 char dfault, char *to) const
00560 { return this->do_narrow(lo, hi, dfault, to); }
00561
00562 protected:
00563 virtual bool do_is(mask m, cxxtools::Char c) const;
00564
00565 virtual const cxxtools::Char* do_is(const cxxtools::Char* lo, const cxxtools::Char* hi,
00566 mask* vec) const;
00567
00568 virtual const cxxtools::Char* do_scan_is(mask m, const cxxtools::Char* lo,
00569 const cxxtools::Char* hi) const;
00570
00571 virtual const cxxtools::Char* do_scan_not(mask m, const cxxtools::Char* lo,
00572 const cxxtools::Char* hi) const;
00573
00574 virtual cxxtools::Char do_toupper(cxxtools::Char) const;
00575
00576 virtual const cxxtools::Char* do_toupper(cxxtools::Char* lo, const cxxtools::Char* hi) const;
00577
00578 virtual cxxtools::Char do_tolower(cxxtools::Char) const;
00579
00580 virtual const cxxtools::Char* do_tolower(cxxtools::Char* lo, const cxxtools::Char* hi) const;
00581
00582 virtual cxxtools::Char do_widen(char) const;
00583
00584 virtual const char* do_widen(const char* lo, const char* hi,
00585 cxxtools::Char* dest) const;
00586
00587 virtual char do_narrow(cxxtools::Char, char dfault) const;
00588
00589 virtual const cxxtools::Char* do_narrow(const cxxtools::Char* lo, const cxxtools::Char* hi,
00590 char dfault, char* dest) const;
00591 };
00592
00593 }
00594
00595 #else
00596
00597 namespace std {
00598
00599 class ctype_base
00600 {
00601 public:
00602 enum {
00603 alpha = 1 << 5,
00604 cntrl = 1 << 2,
00605 digit = 1 << 6,
00606 lower = 1 << 4,
00607 print = 1 << 1,
00608 punct = 1 << 7,
00609 space = 1 << 0,
00610 upper = 1 << 3,
00611 xdigit = 1 << 8,
00612 alnum = alpha | digit,
00613 graph = alnum | punct
00614 };
00615
00616 typedef unsigned short mask;
00617
00618 ctype_base(size_t _refs = 0)
00619 { }
00620 };
00621
00622 }
00623
00624 #endif
00625
00626 namespace cxxtools {
00627
00628 CXXTOOLS_API std::ctype_base::mask ctypeMask(const Char& ch);
00629
00630 inline int isalpha(const Char& ch)
00631 {
00632 return ctypeMask(ch) & std::ctype_base::alpha;
00633 }
00634
00635 inline int isalnum(const Char& ch)
00636 {
00637 return ctypeMask(ch) & std::ctype_base::alnum;
00638 }
00639
00640 inline int ispunct(const Char& ch)
00641 {
00642 return ctypeMask(ch) & std::ctype_base::punct;
00643 }
00644
00645 inline int iscntrl(const Char& ch)
00646 {
00647 return ctypeMask(ch) & std::ctype_base::cntrl;
00648 }
00649
00650 inline int isdigit(const Char& ch)
00651 {
00652 return ctypeMask(ch) & std::ctype_base::digit;
00653 }
00654
00655 inline int isxdigit(const Char& ch)
00656 {
00657 return ctypeMask(ch) & std::ctype_base::xdigit;
00658 }
00659
00660 inline int isgraph(const Char& ch)
00661 {
00662 return ctypeMask(ch) & std::ctype_base::graph;
00663 }
00664
00665 inline int islower(const Char& ch)
00666 {
00667 return ctypeMask(ch) & std::ctype_base::lower;
00668 }
00669
00670 inline int isupper(const Char& ch)
00671 {
00672 return ctypeMask(ch) & std::ctype_base::upper;
00673 }
00674
00675 inline int isprint(const Char& ch)
00676 {
00677 return ctypeMask(ch) & std::ctype_base::print;
00678 }
00679
00680 inline int isspace(const Char& ch)
00681 {
00682 return ctypeMask(ch) & std::ctype_base::space;
00683 }
00684
00685 CXXTOOLS_API Char tolower(const Char& ch);
00686
00687 CXXTOOLS_API Char toupper(const Char& ch);
00688
00689 }
00690
00691 #ifdef CXXTOOLS_WITH_STD_LOCALE
00692 #include <cxxtools/facets.h>
00693 #endif
00694
00695 #endif