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