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
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
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 #ifndef STLSOFT_INCL_H_STLSOFT
00090 # include "stlsoft.h"
00091 #endif
00092 #ifndef STLSOFT_INCL_H_STLSOFT_SIGN_TRAITS
00093 # include "stlsoft_sign_traits.h"
00094 #endif
00095 #if defined(__STLSOFT_CF_std_char_traits_AVAILABLE) && \
00096 defined(_STLSOFT_NO_NAMESPACE) && \
00097 !defined(__STLSOFT_CF_std_NAMESPACE)
00098 # include <string>
00099 #elif defined(__STLSOFT_COMPILER_IS_DMC) && \
00100 !defined(__STLSOFT_CF_std_NAMESPACE)
00101 # include <string>
00102 #endif
00103 #if !defined(STLSOFT_NO_CHAR_TRAITS_LIBRARY_CALLS) || \
00104 defined(_DEBUG)
00105 # include <string.h>
00106 # include <wchar.h>
00107 # if defined(__STLSOFT_COMPILER_IS_BORLAND) && \
00108 __BORLANDC__ >= 0x0560
00109 # include <mem.h>
00110 #endif
00111 #endif
00112
00113
00114
00115
00116
00117 #ifndef _STLSOFT_NO_NAMESPACE
00118 namespace stlsoft
00119 {
00120 #endif
00121
00122
00123
00124
00125
00126
00132
00133 >
00134 struct stlsoft_char_traits
00135 {
00136 public:
00138 typedef C char_type;
00140 typedef stlsoft_char_traits<C> class_type;
00142 typedef ss_int_t int_type;
00144 typedef ss_size_t size_type;
00146 typedef ss_streampos_t pos_type;
00148 typedef ss_streamoff_t off_type;
00149
00150 public:
00152 static void assign(char_type &lhs, char_type const &rhs)
00153 {
00154 lhs = rhs;
00155 }
00156
00158 static char_type *assign(char_type *dest, size_type cch, char_type const &c)
00159 {
00160 char_type * ret;
00161
00162 stlsoft_message_assert("char_traits<X>::assign called with NULL destination", 0 == cch || NULL != dest);
00163
00164 for(ret = dest; 0 < cch; --cch, ++dest)
00165 {
00166 assign(*dest, c);
00167 }
00168
00169 return ret;
00170 }
00171
00173 static ss_bool_t eq(char_type const &lhs, char_type const &rhs)
00174 {
00175 return lhs == rhs;
00176 }
00177
00179 static ss_bool_t lt(char_type const &lhs, char_type const &rhs)
00180 {
00181 return lhs < rhs;
00182 }
00183
00193 static int_type compare(char_type const *s1, char_type const *s2, size_type cch)
00194 {
00195 stlsoft_message_assert("char_traits<X>::compare called with NULL string", 0 == cch || NULL != s1);
00196 stlsoft_message_assert("char_traits<X>::compare called with NULL string", 0 == cch || NULL != s2);
00197
00198 for(size_type n = 0; n < cch; ++n, ++s1, ++s2)
00199 {
00200 if(!eq(*s1, *s2))
00201 {
00202 return lt(*s1, *s2) ? -1 : +1;
00203 }
00204 }
00205
00206 return 0;
00207 }
00208
00209 static int_type compare_max(char_type const *s1, char_type const *s2, size_type cch)
00210 {
00211 stlsoft_message_assert("char_traits<X>::compare_max called with NULL string", 0 == cch || NULL != s1);
00212 stlsoft_message_assert("char_traits<X>::compare_max called with NULL string", 0 == cch || NULL != s2);
00213
00214 for(size_type n = 0; n < cch; ++n, ++s1, ++s2)
00215 {
00216 if(!eq(*s1, *s2))
00217 {
00218 return lt(*s1, *s2) ? -1 : +1;
00219 }
00220 else if(eq(*s1, char_type(0)))
00221 {
00222 break;
00223 }
00224 }
00225
00226 return 0;
00227 }
00228
00230 static int_type compare_null(char_type const *s1, char_type const *s2, size_type cch)
00231 {
00232 int_type result;
00233
00234 if(NULL == s1)
00235 {
00236 result = (NULL == s2) ? 0 : -1;
00237 }
00238 else
00239 {
00240 result = (NULL == s2) ? 1 : compare(s1, s2, cch);
00241 }
00242
00243 return result;
00244 }
00245
00247 static int_type compare_maxnull(char_type const *s1, char_type const *s2, size_type cch)
00248 {
00249 int_type result;
00250
00251 if(NULL == s1)
00252 {
00253 result = (NULL == s2) ? 0 : -1;
00254 }
00255 else
00256 {
00257 result = (NULL == s2) ? 1 : compare_max(s1, s2, cch);
00258 }
00259
00260 return result;
00261 }
00262
00264 static size_type length(char_type const *s)
00265 {
00266 size_type cch;
00267
00268 stlsoft_message_assert("char_traits<X>::length called with NULL string", NULL != s);
00269
00270 for(cch = 0; !eq(*s, char_type(0)); ++s)
00271 {
00272 ++cch;
00273 }
00274
00275 return cch;
00276 }
00277
00279 static size_type length_null(char_type const *s)
00280 {
00281 return (NULL != s) ? length(s) : 0;
00282 }
00283
00289 static size_type length_max(char_type const *s, size_type limit)
00290 {
00291 size_type cch;
00292
00293 stlsoft_message_assert("char_traits<X>::length_max called with NULL string", NULL != s);
00294
00295 for(cch = 0; cch < limit && !eq(*s, char_type(0)); ++s)
00296 {
00297 ++cch;
00298 }
00299
00300 return cch;
00301 }
00302
00308 static size_type length_max_null(char_type const *s, size_type limit)
00309 {
00310 return (NULL != s) ? length_max(s, limit) : 0;
00311 }
00312
00314 static char_type *copy(char_type *dest, char_type const *src, size_type cch)
00315 {
00316 char_type *ret;
00317
00318 stlsoft_message_assert("char_traits<X>::copy called with NULL destination", 0 == cch || NULL != dest);
00319 stlsoft_message_assert("char_traits<X>::copy called with NULL source", 0 == cch || NULL != src);
00320
00321 #ifdef _DEBUG
00322 memset(dest, 0, cch * sizeof(char_type));
00323 #endif
00324
00325 for(ret = dest; 0 < cch; --cch, ++dest, ++src)
00326 {
00327 assign(*dest, *src);
00328 }
00329
00330 return ret;
00331 }
00332
00334 static char_type *move(char_type *dest, char_type const *src, size_type cch)
00335 {
00336 char_type *const ret = dest;
00337
00338 stlsoft_message_assert("char_traits<X>::move called with NULL destination", 0 == cch || NULL != dest);
00339 stlsoft_message_assert("char_traits<X>::move called with NULL source", 0 == cch || NULL != src);
00340
00341 if( src < dest &&
00342 dest < src + cch)
00343 {
00344 for(dest += cch, src += cch; 0 < cch; --cch)
00345 {
00346 assign(*--dest, *--src);
00347 }
00348 }
00349 else
00350 {
00351 for(; 0 < cch; --cch, ++dest, ++src)
00352 {
00353 assign(*dest, *src);
00354 }
00355 }
00356
00357 return ret;
00358 }
00359
00361 static char_type const *find(char_type const *s, size_type cch, char_type const &c)
00362 {
00363 stlsoft_message_assert("char_traits<X>::find called with NULL string", 0 == cch || NULL != s);
00364
00365 for(; 0 < cch; --cch, ++s)
00366 {
00367 if(eq(*s, c))
00368 {
00369 break;
00370 }
00371 }
00372
00373 return (0 < cch) ? s : NULL;
00374 }
00375
00377 static char_type to_char_type(int_type const &c)
00378 {
00379 return static_cast<char_type>(c);
00380 }
00381
00383 static int_type to_int_type(char_type const &c)
00384 {
00385 #if defined(__STLSOFT_COMPILER_IS_WATCOM)
00386 return (int_type)(c);
00387 #else
00388 return static_cast<int_type>(static_cast<ss_typename_type_k sign_traits<char_type>::unsigned_type>(c));
00389 #endif
00390 }
00391
00393 static ss_bool_t eq_int_type(int_type const &lhs, int_type const &rhs)
00394 {
00395 return lhs == rhs;
00396 }
00397
00399 static int_type eof()
00400 {
00401 return static_cast<int_type>(-1);
00402 }
00403
00405 static int_type not_eof(int_type const &c)
00406 {
00407 return (c != eof() ? c : !eof());
00408 }
00409 };
00410
00411
00417
00418 >
00419 struct stlsoft_char_traits_safe
00420 : private stlsoft_char_traits<C>
00421 {
00422 private:
00423 typedef stlsoft_char_traits<C> parent_class_type;
00424 public:
00426 typedef C char_type;
00428 typedef stlsoft_char_traits_safe<C> class_type;
00430 typedef ss_int_t int_type;
00432 typedef ss_size_t size_type;
00434 typedef ss_streampos_t pos_type;
00436 typedef ss_streamoff_t off_type;
00437
00438 public:
00440 static void assign(char_type &lhs, char_type const &rhs)
00441 {
00442 parent_class_type::assign(lhs, rhs);
00443 }
00444
00446 static char_type *assign(char_type *dest, size_type cch, char_type const &c)
00447 {
00448 stlsoft_message_assert("char_traits_safe<X>::assign called with NULL destination", NULL != dest);
00449
00450 return parent_class_type::assign(dest, cch, c);
00451 }
00452
00454 static ss_bool_t eq(char_type const &lhs, char_type const &rhs)
00455 {
00456 return parent_class_type::eq(lhs, rhs);
00457 }
00458
00460 static ss_bool_t lt(char_type const &lhs, char_type const &rhs)
00461 {
00462 return parent_class_type::lt(lhs, rhs);
00463 }
00464
00474 static int_type compare(char_type const *s1, char_type const *s2, size_type cch)
00475 {
00476 return compare_null(s1, s2, cch);
00477 }
00478
00479 static int_type compare_max(char_type const *s1, char_type const *s2, size_type cch)
00480 {
00481 return compare_maxnull(s1, s2, cch);
00482 }
00483
00485 static int_type compare_null(char_type const *s1, char_type const *s2, size_type cch)
00486 {
00487 return parent_class_type::compare(s1, s2, cch);
00488 }
00489
00491 static int_type compare_maxnull(char_type const *s1, char_type const *s2, size_type cch)
00492 {
00493 return parent_class_type::compare_maxnull(s1, s2, cch);
00494 }
00495
00501 static size_type length_max_null(char_type const *s, size_type limit)
00502 {
00503 return (NULL == s) ? 0 : parent_class_type::length_max(s, limit);
00504 }
00505
00511 static size_type length_max(char_type const *s, size_type limit)
00512 {
00513 return length_max_null(s, limit);
00514 }
00515
00517 static size_type length_null(char_type const *s)
00518 {
00519 return (NULL == s) ? 0 : parent_class_type::length(s);
00520 }
00521
00523 static size_type length(char_type const *s)
00524 {
00525 return length_null(s);
00526 }
00527
00529 static char_type *copy(char_type *dest, char_type const *src, size_type cch)
00530 {
00531 stlsoft_message_assert("char_traits_safe<X>::copy called with NULL destination", NULL != dest);
00532 stlsoft_message_assert("char_traits_safe<X>::copy called with NULL source", NULL != src);
00533
00534 return parent_class_type::copy(dest, src, cch);
00535 }
00536
00538 static char_type *move(char_type *dest, char_type const *src, size_type cch)
00539 {
00540 stlsoft_message_assert("char_traits_safe<X>::move called with NULL destination", NULL != dest);
00541 stlsoft_message_assert("char_traits_safe<X>::move called with NULL source", NULL != src);
00542
00543 return parent_class_type::move(dest, src, cch);
00544 }
00545
00547 static char_type const *find(char_type const *s, size_type cch, char_type const &c)
00548 {
00549 return (NULL == s) ? NULL : parent_class_type::find(s, cch, c);
00550 }
00551
00553 static char_type to_char_type(int_type const &c)
00554 {
00555 return parent_class_type::to_char_type(c);
00556 }
00557
00559 static int_type to_int_type(char_type const &c)
00560 {
00561 return parent_class_type::to_int_type(c);
00562 }
00563
00565 static ss_bool_t eq_int_type(int_type const &lhs, int_type const &rhs)
00566 {
00567 return parent_class_type::eq_int_type(lhs, rhs);
00568 }
00569
00571 static int_type eof()
00572 {
00573 return parent_class_type::eof();
00574 }
00575
00577 static int_type not_eof(int_type const &c)
00578 {
00579 return parent_class_type::not_eof();
00580 }
00581 };
00582
00583
00589
00590
00591 #if defined(__STLSOFT_COMPILER_IS_DMC) && \
00592 !defined(__STLSOFT_CF_std_NAMESPACE)
00593
00594 # if !defined(__SGI_STL_STRING_FWD_H)
00595 # error Unexpected
00596 # endif
00597 # if !defined(__SGI_STL_CHAR_TRAITS_H)
00598 # error Unexpected
00599 # endif
00600
00601 using ::char_traits;
00602 #else
00603
00604
00605
00606
00607 #if !defined(__STLSOFT_CF_std_char_traits_AVAILABLE) || \
00608 !defined(_STLSOFT_NO_NAMESPACE) || \
00609 defined(__STLSOFT_CF_std_NAMESPACE)
00610 template< ss_typename_param_k C
00611 >
00612 struct char_traits
00613 : public stlsoft_char_traits<C>
00614 {
00615 typedef stlsoft_char_traits<C> parent_class_type;
00616 public:
00618 typedef char_traits<C> class_type;
00620 typedef ss_typename_type_k parent_class_type::char_type char_type;
00621 typedef ss_typename_type_k parent_class_type::int_type int_type;
00622 typedef ss_typename_type_k parent_class_type::size_type size_type;
00623 typedef ss_typename_type_k parent_class_type::pos_type pos_type;
00624 typedef ss_typename_type_k parent_class_type::off_type off_type;
00625 };
00626 # endif
00627 #endif
00628
00629
00635
00636 >
00637 struct char_traits_safe
00638 : public stlsoft_char_traits_safe<C>
00639 {
00640 typedef stlsoft_char_traits_safe<C> parent_class_type;
00641 public:
00643 typedef char_traits_safe<C> class_type;
00645 typedef ss_typename_type_k parent_class_type::char_type char_type;
00646 typedef ss_typename_type_k parent_class_type::int_type int_type;
00647 typedef ss_typename_type_k parent_class_type::size_type size_type;
00648 typedef ss_typename_type_k parent_class_type::pos_type pos_type;
00649 typedef ss_typename_type_k parent_class_type::off_type off_type;
00650 };
00651
00652
00653
00654
00655
00656 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00657
00658 #if !defined(STLSOFT_NO_CHAR_TRAITS_LIBRARY_CALLS) && \
00659 !defined(__STLSOFT_COMPILER_IS_DMC) && \
00660 ( !defined(__STLSOFT_COMPILER_IS_MSVC) || \
00661 _MSC_VER >= 1100) && \
00662 !defined(__STLSOFT_COMPILER_IS_VECTORC) && \
00663 !defined(__STLSOFT_COMPILER_IS_WATCOM)
00664
00665
00666
00667 STLSOFT_TEMPLATE_SPECIALISATION
00668 inline char *stlsoft_char_traits<char>::assign(char *dest, ss_size_t cch, char const &c)
00669 {
00670 return static_cast<char*>(memset(dest, c, cch * sizeof(char)));
00671 }
00672
00673 STLSOFT_TEMPLATE_SPECIALISATION
00674 inline ss_int_t stlsoft_char_traits<char>::compare(char_type const *s1, char_type const *s2, ss_size_t cch)
00675 {
00676 return memcmp(s1, s2, cch);
00677 }
00678
00679 STLSOFT_TEMPLATE_SPECIALISATION
00680 inline char const *stlsoft_char_traits<char>::find(char_type const *s, size_type cch, char_type const &c)
00681 {
00682 #if defined(__STLSOFT_COMPILER_IS_BORLAND) && \
00683 __BORLANDC__ < 0x0560
00684 return static_cast<char const*>(memchr(s, c, cch));
00685 #else
00686 void const *p = memchr(s, c, cch);
00687
00688 return static_cast<char const*>(p);
00689 #endif
00690 }
00691
00692 STLSOFT_TEMPLATE_SPECIALISATION
00693 inline char *stlsoft_char_traits<char>::copy(char *dest, char const *src, ss_size_t cch)
00694 {
00695 #ifdef _DEBUG
00696 memset(dest, 0, cch * sizeof(char));
00697 #endif
00698
00699 return static_cast<char*>(memcpy(dest, src, cch * sizeof(char)));
00700 }
00701
00702 STLSOFT_TEMPLATE_SPECIALISATION
00703 inline ss_size_t stlsoft_char_traits<char>::length(char const *s)
00704 {
00705 return strlen(s);
00706 }
00707
00708
00709
00710 STLSOFT_TEMPLATE_SPECIALISATION
00711 inline ss_size_t stlsoft_char_traits<wchar_t>::length(wchar_t const *s)
00712 {
00713 return wcslen(s);
00714 }
00715
00716 #endif
00717
00718 #endif
00719
00721
00722
00723 #ifdef STLSOFT_UNITTEST
00724
00725 namespace unittest
00726 {
00727 ss_bool_t test_stlsoft_char_traits(unittest_reporter *r)
00728 {
00729 ss_bool_t bSuccess = true;
00730
00731 unittest_initialiser init(r, "STLSoft", "char_traits", __FILE__);
00732
00733 #if 0
00734 if(<<TODO>>)
00735 {
00736 r->report("<<TODO>> failed ", __LINE__);
00737 bSuccess = false;
00738 }
00739 #endif
00740
00741 return bSuccess;
00742 }
00743
00744 unittest_registrar unittest_stlsoft_char_traits(test_stlsoft_char_traits);
00745
00746 }
00747
00748 #endif
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760