Webmaster  |  Imprint 
C++ Server Pages
Main  |  License  |  Documentation  |  Download 

/home/tommi/cxxtools/include/cxxtools/char.h

00001 /*
00002  * Copyright (C) 2005-2007 Marc Boris Duerner
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  * 
00009  * As a special exception, you may use this file as part of a free
00010  * software library without restriction. Specifically, if other files
00011  * instantiate templates or use macros or inline functions from this
00012  * file, or you compile this file and link it with other files to
00013  * produce an executable, this file does not by itself cause the
00014  * resulting executable to be covered by the GNU General Public
00015  * License. This exception does not however invalidate any other
00016  * reasons why the executable file might be covered by the GNU Library
00017  * General Public License.
00018  * 
00019  * This library is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00022  * Lesser General Public License for more details.
00023  * 
00024  * You should have received a copy of the GNU Lesser General Public
00025  * License along with this library; if not, write to the Free Software
00026  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
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 } // namespace cxxtools
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 } // namespace std
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 } // namespace cxxtools
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 } // namespace std
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 } // namespace cxxtools
00690 
00691 #ifdef CXXTOOLS_WITH_STD_LOCALE
00692 #include <cxxtools/facets.h>
00693 #endif
00694 
00695 #endif
Copyright © 2008 The Tntnet Development Team
Tntnet 1.6