lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
char_traits.h
00001 /*****************************************************/
00002 /* lean Strings                 (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_STRINGS_CHAR_TRAITS
00006 #define LEAN_STRINGS_CHAR_TRAITS
00007 
00008 #include "../lean.h"
00009 #include <cstring>
00010 #include <cwchar>
00011 
00012 namespace lean
00013 {
00014 namespace strings
00015 {
00016 
00019 template <class Char>
00020 struct char_traits
00021 {
00023     typedef Char char_type;
00025     typedef typename int_type<sign_class::no_sign, sizeof(char_type)>::type int_type;
00027     typedef size_t size_type;
00028     
00030     static LEAN_INLINE bool null(const char_type &src)
00031     {
00032         return (src == static_cast<char_type>(0));
00033     }
00034 
00036     static LEAN_INLINE bool empty(const char_type *begin)
00037     {
00038         return null(*begin);
00039     }
00041     static size_type length(const char_type *begin)
00042     {
00043         size_t length = 0;
00044 
00045         while (!null(*begin++))
00046             ++length;
00047 
00048         return length;
00049     }
00051     static LEAN_INLINE size_type count(const char_type *begin)
00052     {
00053         return length(begin);
00054     }
00056     static LEAN_INLINE size_type count(const char_type *begin, const char_type *end)
00057     {
00058         return end - begin;
00059     }
00060 
00062     static bool equal(const char_type *begin1, const char_type *begin2)
00063     {
00064         while (*begin1 == *begin2)
00065         {
00066             if (null(*begin1))
00067                 return true;
00068 
00069             ++begin1;
00070             ++begin2;
00071         }
00072 
00073         return false;
00074     }
00076     static bool less(const char_type *begin1, const char_type *begin2)
00077     {
00078         while (*begin1 == *begin2)
00079         {
00080             if (null(*begin1))
00081                 return false;
00082 
00083             ++begin1;
00084             ++begin2;
00085         }
00086 
00087         // Compare unsigned, correctly handles null (end of string) as smallest number
00088         return static_cast<int_type>(*begin1) < static_cast<int_type>(*begin2);
00089     }
00090 };
00091 
00092 template <>
00093 struct char_traits<char>
00094 {
00095     typedef char char_type;
00096     typedef int_type<sign_class::no_sign, sizeof(char_type)>::type int_type;
00097     typedef size_t size_type;
00098     
00099     static LEAN_INLINE bool null(const char_type &src)
00100     {
00101         return (src == static_cast<char_type>(0));
00102     }
00103     
00104     static LEAN_INLINE bool empty(const char_type *begin)
00105     {
00106         return null(*begin);
00107     }
00108     static LEAN_INLINE size_type length(const char_type *begin)
00109     {
00110         using std::strlen;
00111         return strlen(begin);
00112     }
00113     static LEAN_INLINE size_type count(const char_type *begin)
00114     {
00115         return length(begin);
00116     }
00117     static LEAN_INLINE size_type count(const char_type *begin, const char_type *end)
00118     {
00119         return end - begin;
00120     }
00121 
00122     static bool equal(const char_type *begin1, const char_type *begin2)
00123     {
00124         using std::strcmp;
00125         return (strcmp(begin1, begin2) == 0);
00126     }
00127     static bool less(const char_type *begin1, const char_type *begin2)
00128     {
00129         using std::strcmp;
00130         return (strcmp(begin1, begin2) < 0);
00131     }
00132 };
00133 
00134 template <>
00135 struct char_traits<wchar_t>
00136 {
00137     typedef wchar_t char_type;
00138     typedef int_type<sign_class::no_sign, sizeof(char_type)>::type int_type;
00139     typedef size_t size_type;
00140     
00141     static LEAN_INLINE bool null(const char_type &src)
00142     {
00143         return (src == static_cast<char_type>(0));
00144     }
00145     
00146     static LEAN_INLINE bool empty(const char_type *begin)
00147     {
00148         return null(*begin);
00149     }
00150     static LEAN_INLINE size_type length(const char_type *begin)
00151     {
00152         using std::wcslen;
00153         return wcslen(begin);
00154     }
00155     static LEAN_INLINE size_type count(const char_type *begin)
00156     {
00157         return length(begin);
00158     }
00159     static LEAN_INLINE size_type count(const char_type *begin, const char_type *end)
00160     {
00161         return end - begin;
00162     }
00163 
00164     static bool equal(const char_type *begin1, const char_type *begin2)
00165     {
00166         using std::wcscmp;
00167         return (wcscmp(begin1, begin2) == 0);
00168     }
00169     static bool less(const char_type *begin1, const char_type *begin2)
00170     {
00171         using std::wcscmp;
00172         return (wcscmp(begin1, begin2) < 0);
00173     }
00174 };
00175 
00176 } // namespace
00177 
00178 using strings::char_traits;
00179 
00180 } // namespace
00181 
00182 #endif