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 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00048 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS
00049 #define STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS
00050 
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define STLSOFT_VER_STLSOFT_STRING_HPP_CHAR_TRAITS_MAJOR    4
00053 # define STLSOFT_VER_STLSOFT_STRING_HPP_CHAR_TRAITS_MINOR    0
00054 # define STLSOFT_VER_STLSOFT_STRING_HPP_CHAR_TRAITS_REVISION 3
00055 # define STLSOFT_VER_STLSOFT_STRING_HPP_CHAR_TRAITS_EDIT     70
00056 #endif 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00093 # include <stlsoft/stlsoft.h>
00094 #endif 
00095 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_SIGN_TRAITS
00096 # include <stlsoft/util/sign_traits.hpp>
00097 #endif 
00098 #if defined(STLSOFT_CF_std_char_traits_AVAILABLE) && \
00099     defined(_STLSOFT_NO_NAMESPACE) && \
00100     !defined(STLSOFT_CF_std_NAMESPACE)
00101 # include <string>                  
00102 #elif defined(STLSOFT_COMPILER_IS_DMC) && \
00103       !defined(STLSOFT_CF_std_NAMESPACE)
00104 # include <string>                  
00105 #endif 
00106 #if !defined(STLSOFT_NO_CHAR_TRAITS_LIBRARY_CALLS) || \
00107     defined(_DEBUG)
00108 # include <string.h>
00109 # include <wchar.h>
00110 # if defined(STLSOFT_COMPILER_IS_BORLAND) && \
00111      __BORLANDC__ >= 0x0560
00112 #  include <mem.h>
00113 #endif 
00114 #endif 
00115 
00116 
00117 
00118 
00119 
00120 #ifndef _STLSOFT_NO_NAMESPACE
00121 namespace stlsoft
00122 {
00123 #endif 
00124 
00125 
00126 
00127 
00128 
00129 
00138 template<   ss_typename_param_k C
00139         >
00140 struct stlsoft_char_traits
00141 {
00142 public:
00144     typedef C                                   char_type;
00146     typedef stlsoft_char_traits<C>              class_type;
00148     typedef ss_int_t                            int_type;
00150     typedef ss_size_t                           size_type;
00152     typedef ss_streampos_t                      pos_type;
00154     typedef ss_streamoff_t                      off_type;
00155 
00156 public:
00158     static void assign(char_type &lhs, char_type const& rhs)
00159     {
00160         lhs = rhs;
00161     }
00162 
00164     static char_type *assign(char_type *dest, size_type cch, char_type const& c)
00165     {
00166         char_type * ret;
00167 
00168         STLSOFT_MESSAGE_ASSERT("char_traits<X>::assign called with NULL destination", (0 == cch || NULL != dest));
00169 
00170         for(ret = dest; 0 < cch; --cch, ++dest)
00171         {
00172             assign(*dest, c);
00173         }
00174 
00175         return ret;
00176     }
00177 
00179     static ss_bool_t eq(char_type const& lhs, char_type const& rhs)
00180     {
00181         return lhs == rhs;
00182     }
00183 
00185     static ss_bool_t lt(char_type const& lhs, char_type const& rhs)
00186     {
00187         return lhs < rhs;
00188     }
00189 
00199     static int_type compare(char_type const* s1, char_type const* s2, size_type cch)
00200     {
00201         STLSOFT_MESSAGE_ASSERT("char_traits<X>::compare called with NULL string", (0 == cch || NULL != s1));
00202         STLSOFT_MESSAGE_ASSERT("char_traits<X>::compare called with NULL string", (0 == cch || NULL != s2));
00203 
00204         for(size_type n = 0; n < cch; ++n, ++s1, ++s2)
00205         {
00206             if(!eq(*s1, *s2))
00207             {
00208                 return lt(*s1, *s2) ? -1 : +1;
00209             }
00210         }
00211 
00212         return 0;
00213     }
00214 
00215     static int_type compare_max(char_type const* s1, char_type const* s2, size_type cch)
00216     {
00217         STLSOFT_MESSAGE_ASSERT("char_traits<X>::compare_max called with NULL string", (0 == cch || NULL != s1));
00218         STLSOFT_MESSAGE_ASSERT("char_traits<X>::compare_max called with NULL string", (0 == cch || NULL != s2));
00219 
00220         for(size_type n = 0; n < cch; ++n, ++s1, ++s2)
00221         {
00222             if(!eq(*s1, *s2))
00223             {
00224                 return lt(*s1, *s2) ? -1 : +1;
00225             }
00226             else if(eq(*s1, char_type(0)))
00227             {
00228                 break;
00229             }
00230         }
00231 
00232         return 0;
00233     }
00234 
00236     static int_type compare_null(char_type const* s1, char_type const* s2, size_type cch)
00237     {
00238         int_type    result;
00239 
00240         if(NULL == s1)
00241         {
00242             result = (NULL == s2) ? 0 : -1;
00243         }
00244         else
00245         {
00246             result = (NULL == s2) ? 1 : compare(s1, s2, cch);
00247         }
00248 
00249         return result;
00250     }
00251 
00253     static int_type compare_maxnull(char_type const* s1, char_type const* s2, size_type cch)
00254     {
00255         int_type    result;
00256 
00257         if(NULL == s1)
00258         {
00259             result = (NULL == s2) ? 0 : -1;
00260         }
00261         else
00262         {
00263             result = (NULL == s2) ? 1 : compare_max(s1, s2, cch);
00264         }
00265 
00266         return result;
00267     }
00268 
00270     static size_type length(char_type const* s)
00271     {
00272         size_type cch;
00273 
00274         STLSOFT_MESSAGE_ASSERT("char_traits<X>::length called with NULL string", NULL != s);
00275 
00276         for(cch = 0; !eq(*s, char_type(0)); ++s)
00277         {
00278             ++cch;
00279         }
00280 
00281         return cch;
00282     }
00283 
00285     static size_type length_null(char_type const* s)
00286     {
00287         return (NULL != s) ? length(s) : 0;
00288     }
00289 
00295     static size_type length_max(char_type const* s, size_type limit)
00296     {
00297         size_type cch;
00298 
00299         STLSOFT_MESSAGE_ASSERT("char_traits<X>::length_max called with NULL string", NULL != s);
00300 
00301         for(cch = 0; cch < limit && !eq(*s, char_type(0)); ++s)
00302         {
00303             ++cch;
00304         }
00305 
00306         return cch;
00307     }
00308 
00314     static size_type length_max_null(char_type const* s, size_type limit)
00315     {
00316         return (NULL != s) ? length_max(s, limit) : 0;
00317     }
00318 
00320     static char_type *copy(char_type *dest, char_type const* src, size_type cch)
00321     {
00322         char_type   *ret;
00323 
00324         STLSOFT_MESSAGE_ASSERT("char_traits<X>::copy called with NULL destination", (0 == cch || NULL != dest));
00325         STLSOFT_MESSAGE_ASSERT("char_traits<X>::copy called with NULL source", (0 == cch || NULL != src));
00326 
00327 #ifdef _DEBUG
00328         ::memset(dest, 0, cch * sizeof(char_type));
00329 #endif 
00330 
00331         for(ret = dest; 0 < cch; --cch, ++dest, ++src)
00332         {
00333             assign(*dest, *src);
00334         }
00335 
00336         return ret;
00337     }
00338 
00340     static char_type *move(char_type *dest, char_type const* src, size_type cch)
00341     {
00342         char_type *const ret = dest;
00343 
00344         STLSOFT_MESSAGE_ASSERT("char_traits<X>::move called with NULL destination", (0 == cch || NULL != dest));
00345         STLSOFT_MESSAGE_ASSERT("char_traits<X>::move called with NULL source", (0 == cch || NULL != src));
00346 
00347         if( src < dest &&
00348             dest < src + cch)
00349         {
00350             for(dest += cch, src += cch; 0 < cch; --cch)
00351             {
00352                 assign(*--dest, *--src);
00353             }
00354         }
00355         else
00356         {
00357             for(; 0 < cch; --cch, ++dest, ++src)
00358             {
00359                 assign(*dest, *src);
00360             }
00361         }
00362 
00363         return ret;
00364     }
00365 
00367     static char_type const* find(char_type const* s, size_type cch, char_type const& c)
00368     {
00369         STLSOFT_MESSAGE_ASSERT("char_traits<X>::find called with NULL string", (0 == cch || NULL != s));
00370 
00371         for(; 0 < cch; --cch, ++s)
00372         {
00373             if(eq(*s, c))
00374             {
00375                 break;
00376             }
00377         }
00378 
00379         return (0 < cch) ? s : NULL;
00380     }
00381 
00383     static char_type to_char_type(int_type const& c)
00384     {
00385         return static_cast<char_type>(c);
00386     }
00387 
00389     static int_type to_int_type(char_type const& c)
00390     {
00391 #if defined(STLSOFT_COMPILER_IS_WATCOM)
00392         return (int_type)(c);
00393 #else 
00394         return static_cast<int_type>(static_cast<ss_typename_type_k sign_traits<char_type>::unsigned_type>(c));
00395 #endif 
00396     }
00397 
00399     static ss_bool_t eq_int_type(int_type const& lhs, int_type const& rhs)
00400     {
00401         return lhs == rhs;
00402     }
00403 
00405     static int_type eof()
00406     {
00407         return static_cast<int_type>(-1);
00408     }
00409 
00411     static int_type not_eof(int_type const& c)
00412     {
00413         return (c != eof() ? c : !eof());
00414     }
00415 };
00416 
00417 
00426 template<   ss_typename_param_k C
00427         >
00428 struct stlsoft_char_traits_safe
00429     : private stlsoft_char_traits<C>
00430 {
00431 private:
00432     typedef stlsoft_char_traits<C>              parent_class_type;
00433 public:
00435     typedef C                                   char_type;
00437     typedef stlsoft_char_traits_safe<C>         class_type;
00439     typedef ss_int_t                            int_type;
00441     typedef ss_size_t                           size_type;
00443     typedef ss_streampos_t                      pos_type;
00445     typedef ss_streamoff_t                      off_type;
00446 
00447 public:
00449     static void assign(char_type &lhs, char_type const& rhs)
00450     {
00451         parent_class_type::assign(lhs, rhs);
00452     }
00453 
00455     static char_type *assign(char_type *dest, size_type cch, char_type const& c)
00456     {
00457         STLSOFT_MESSAGE_ASSERT("char_traits_safe<X>::assign called with NULL destination", NULL != dest);
00458 
00459         return parent_class_type::assign(dest, cch, c);
00460     }
00461 
00463     static ss_bool_t eq(char_type const& lhs, char_type const& rhs)
00464     {
00465         return parent_class_type::eq(lhs, rhs);
00466     }
00467 
00469     static ss_bool_t lt(char_type const& lhs, char_type const& rhs)
00470     {
00471         return parent_class_type::lt(lhs, rhs);
00472     }
00473 
00483     static int_type compare(char_type const* s1, char_type const* s2, size_type cch)
00484     {
00485         return compare_null(s1, s2, cch);
00486     }
00487 
00488     static int_type compare_max(char_type const* s1, char_type const* s2, size_type cch)
00489     {
00490         return compare_maxnull(s1, s2, cch);
00491     }
00492 
00494     static int_type compare_null(char_type const* s1, char_type const* s2, size_type cch)
00495     {
00496         return parent_class_type::compare(s1, s2, cch);
00497     }
00498 
00500     static int_type compare_maxnull(char_type const* s1, char_type const* s2, size_type cch)
00501     {
00502         return parent_class_type::compare_maxnull(s1, s2, cch);
00503     }
00504 
00510     static size_type length_max_null(char_type const* s, size_type limit)
00511     {
00512         return (NULL == s) ? 0 : parent_class_type::length_max(s, limit);
00513     }
00514 
00520     static size_type length_max(char_type const* s, size_type limit)
00521     {
00522         return length_max_null(s, limit);
00523     }
00524 
00526     static size_type length_null(char_type const* s)
00527     {
00528         return (NULL == s) ? 0 : parent_class_type::length(s);
00529     }
00530 
00532     static size_type length(char_type const* s)
00533     {
00534         return length_null(s);
00535     }
00536 
00538     static char_type *copy(char_type *dest, char_type const* src, size_type cch)
00539     {
00540         STLSOFT_MESSAGE_ASSERT("char_traits_safe<X>::copy called with NULL destination", NULL != dest);
00541         STLSOFT_MESSAGE_ASSERT("char_traits_safe<X>::copy called with NULL source", NULL != src);
00542 
00543         return parent_class_type::copy(dest, src, cch);
00544     }
00545 
00547     static char_type *move(char_type *dest, char_type const* src, size_type cch)
00548     {
00549         STLSOFT_MESSAGE_ASSERT("char_traits_safe<X>::move called with NULL destination", NULL != dest);
00550         STLSOFT_MESSAGE_ASSERT("char_traits_safe<X>::move called with NULL source", NULL != src);
00551 
00552         return parent_class_type::move(dest, src, cch);
00553     }
00554 
00556     static char_type const* find(char_type const* s, size_type cch, char_type const& c)
00557     {
00558         return (NULL == s) ? NULL : parent_class_type::find(s, cch, c);
00559     }
00560 
00562     static char_type to_char_type(int_type const& c)
00563     {
00564         return parent_class_type::to_char_type(c);
00565     }
00566 
00568     static int_type to_int_type(char_type const& c)
00569     {
00570         return parent_class_type::to_int_type(c);
00571     }
00572 
00574     static ss_bool_t eq_int_type(int_type const& lhs, int_type const& rhs)
00575     {
00576         return parent_class_type::eq_int_type(lhs, rhs);
00577     }
00578 
00580     static int_type eof()
00581     {
00582         return parent_class_type::eof();
00583     }
00584 
00586     static int_type not_eof(int_type const& c)
00587     {
00588         return parent_class_type::not_eof();
00589     }
00590 };
00591 
00592 
00602 
00603 #if defined(STLSOFT_COMPILER_IS_DMC) &&    \
00604     !defined(STLSOFT_CF_std_NAMESPACE)    
00605 
00606 # if !defined(__SGI_STL_STRING_FWD_H)
00607 #  error Unexpected
00608 # endif 
00609 # if !defined(__SGI_STL_CHAR_TRAITS_H)
00610 #  error Unexpected
00611 # endif 
00612 
00613 using ::char_traits;
00614 #else 
00615 
00616 
00617 
00618 
00619  #if !defined(STLSOFT_CF_std_char_traits_AVAILABLE) ||  \
00620      !defined(_STLSOFT_NO_NAMESPACE) ||                  \
00621      defined(STLSOFT_CF_std_NAMESPACE)
00622 template<   ss_typename_param_k C
00623         >
00624 struct char_traits
00625     : public stlsoft_char_traits<C>
00626 {
00627     typedef stlsoft_char_traits<C>                          parent_class_type;
00628 public:
00630     typedef char_traits<C>                                  class_type;
00632     typedef ss_typename_type_k parent_class_type::char_type char_type;
00633     typedef ss_typename_type_k parent_class_type::int_type  int_type;
00634     typedef ss_typename_type_k parent_class_type::size_type size_type;
00635     typedef ss_typename_type_k parent_class_type::pos_type  pos_type;
00636     typedef ss_typename_type_k parent_class_type::off_type  off_type;
00637 };
00638 # endif 
00639 #endif 
00640 
00641 
00650 template<   ss_typename_param_k C
00651         >
00652 struct char_traits_safe
00653     : public stlsoft_char_traits_safe<C>
00654 {
00655     typedef stlsoft_char_traits_safe<C>                     parent_class_type;
00656 public:
00658     typedef char_traits_safe<C>                             class_type;
00660     typedef ss_typename_type_k parent_class_type::char_type char_type;
00661     typedef ss_typename_type_k parent_class_type::int_type  int_type;
00662     typedef ss_typename_type_k parent_class_type::size_type size_type;
00663     typedef ss_typename_type_k parent_class_type::pos_type  pos_type;
00664     typedef ss_typename_type_k parent_class_type::off_type  off_type;
00665 };
00666 
00667 
00668 
00669 
00670 
00671 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00672 
00673 #if !defined(STLSOFT_NO_CHAR_TRAITS_LIBRARY_CALLS) && \
00674     !defined(STLSOFT_COMPILER_IS_DMC) && \
00675     (   !defined(STLSOFT_COMPILER_IS_MSVC) || \
00676         _MSC_VER >= 1100) && \
00677     !defined(STLSOFT_COMPILER_IS_VECTORC) && \
00678     !defined(STLSOFT_COMPILER_IS_WATCOM)
00679 
00680 
00681 
00682 STLSOFT_TEMPLATE_SPECIALISATION
00683 inline char *stlsoft_char_traits<char>::assign(char *dest, ss_size_t cch, char const& c)
00684 {
00685     return static_cast<char*>(::memset(dest, c, cch * sizeof(char)));
00686 }
00687 
00688 STLSOFT_TEMPLATE_SPECIALISATION
00689 inline ss_int_t stlsoft_char_traits<char>::compare(char_type const* s1, char_type const* s2, ss_size_t cch)
00690 {
00691     return ::memcmp(s1, s2, cch);
00692 }
00693 
00694 STLSOFT_TEMPLATE_SPECIALISATION
00695 inline char const* stlsoft_char_traits<char>::find(char_type const* s, size_type cch, char_type const& c)
00696 {
00697 #if defined(STLSOFT_COMPILER_IS_BORLAND) && \
00698     __BORLANDC__ < 0x0560
00699     return static_cast<char const*>(memchr(s, c, cch));
00700 #else 
00701     void const  *p = ::memchr(s, c, cch);
00702 
00703     return static_cast<char const*>(p);
00704 #endif 
00705 }
00706 
00707 STLSOFT_TEMPLATE_SPECIALISATION
00708 inline char *stlsoft_char_traits<char>::copy(char *dest, char const* src, ss_size_t cch)
00709 {
00710 #ifdef _DEBUG
00711     ::memset(dest, 0, cch * sizeof(char));
00712 #endif 
00713 
00714     return static_cast<char*>(memcpy(dest, src, cch * sizeof(char)));
00715 }
00716 
00717 STLSOFT_TEMPLATE_SPECIALISATION
00718 inline ss_size_t stlsoft_char_traits<char>::length(char const* s)
00719 {
00720     return ::strlen(s);
00721 }
00722 
00723 
00724 
00725 STLSOFT_TEMPLATE_SPECIALISATION
00726 inline ss_size_t stlsoft_char_traits<wchar_t>::length(wchar_t const* s)
00727 {
00728     return ::wcslen(s);
00729 }
00730 
00731 #endif 
00732 
00733 #endif 
00734 
00736 
00737 
00738 #ifdef STLSOFT_UNITTEST
00739 # include "./unittest/char_traits_unittest_.h"
00740 #endif 
00741 
00742 
00743 
00744 #ifndef _STLSOFT_NO_NAMESPACE
00745 } 
00746 #endif 
00747 
00748 
00749 
00750 #endif 
00751 
00752