00001 #ifndef _PFC_STRING_H_
00002 #define _PFC_STRING_H_
00003
00004 namespace pfc {
00005
00006 class NOVTABLE string_receiver {
00007 public:
00008 virtual void add_string(const char * p_string,t_size p_string_size = infinite) = 0;
00009
00010 void add_char(t_uint32 c);
00011 void add_byte(char c) {add_string(&c,1);}
00012 void add_chars(t_uint32 p_char,t_size p_count) {for(;p_count;p_count--) add_char(p_char);}
00013 protected:
00014 string_receiver() {}
00015 ~string_receiver() {}
00016 };
00017
00018 t_size scan_filename(const char * ptr);
00019
00020 bool is_path_separator(unsigned c);
00021 bool is_path_bad_char(unsigned c);
00022 bool is_valid_utf8(const char * param,t_size max = infinite);
00023 bool is_lower_ascii(const char * param);
00024 bool is_multiline(const char * p_string,t_size p_len = infinite);
00025 bool has_path_bad_chars(const char * param);
00026 void recover_invalid_utf8(const char * src,char * out,unsigned replace);
00027 void convert_to_lower_ascii(const char * src,t_size max,char * out,char replace = '?');
00028
00029 inline char ascii_tolower(char c) {if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; return c;}
00030 inline char ascii_toupper(char c) {if (c >= 'a' && c <= 'z') c += 'A' - 'a'; return c;}
00031
00032 t_size string_find_first(const char * p_string,char p_tofind,t_size p_start = 0);
00033 t_size string_find_last(const char * p_string,char p_tofind,t_size p_start = ~0);
00034 t_size string_find_first(const char * p_string,const char * p_tofind,t_size p_start = 0);
00035 t_size string_find_last(const char * p_string,const char * p_tofind,t_size p_start = ~0);
00036
00037 t_size string_find_first_ex(const char * p_string,t_size p_string_length,char p_tofind,t_size p_start = 0);
00038 t_size string_find_last_ex(const char * p_string,t_size p_string_length,char p_tofind,t_size p_start = ~0);
00039 t_size string_find_first_ex(const char * p_string,t_size p_string_length,const char * p_tofind,t_size p_tofind_length,t_size p_start = 0);
00040 t_size string_find_last_ex(const char * p_string,t_size p_string_length,const char * p_tofind,t_size p_tofind_length,t_size p_start = ~0);
00041
00042
00043 template<typename t_char>
00044 t_size strlen_max_t(const t_char * ptr,t_size max) {
00045 if (ptr == NULL) return 0;
00046 t_size n = 0;
00047 while(n<max && ptr[n] != 0) n++;
00048 return n;
00049 }
00050
00051 inline t_size strlen_max(const char * ptr,t_size max) {return strlen_max_t(ptr,max);}
00052 inline t_size wcslen_max(const wchar_t * ptr,t_size max) {return strlen_max_t(ptr,max);}
00053
00054 #ifdef _WINDOWS
00055 inline t_size tcslen_max(const TCHAR * ptr,t_size max) {return strlen_max_t(ptr,max);}
00056 #endif
00057
00058 bool string_is_numeric(const char * p_string,t_size p_length = infinite);
00059 inline bool char_is_numeric(char p_char) {return p_char >= '0' && p_char <= '9';}
00060 inline bool char_is_ascii_alpha_upper(char p_char) {return p_char >= 'A' && p_char <= 'Z';}
00061 inline bool char_is_ascii_alpha_lower(char p_char) {return p_char >= 'a' && p_char <= 'z';}
00062 inline bool char_is_ascii_alpha(char p_char) {return char_is_ascii_alpha_lower(p_char) || char_is_ascii_alpha_upper(p_char);}
00063 inline bool char_is_ascii_alphanumeric(char p_char) {return char_is_ascii_alpha(p_char) || char_is_numeric(p_char);}
00064
00065 unsigned atoui_ex(const char * ptr,t_size max);
00066 t_int64 atoi64_ex(const char * ptr,t_size max);
00067 t_uint64 atoui64_ex(const char * ptr,t_size max);
00068
00069 t_size strlen_utf8(const char * s,t_size num = ~0);
00070 t_size utf8_char_len(const char * s,t_size max = ~0);
00071 t_size utf8_char_len_from_header(char c);
00072 t_size utf8_chars_to_bytes(const char * string,t_size count);
00073
00074 t_size strcpy_utf8_truncate(const char * src,char * out,t_size maxbytes);
00075
00076 t_size utf8_decode_char(const char * src,unsigned * out,t_size src_bytes = ~0);
00077 t_size utf8_encode_char(unsigned c,char * out);
00078 t_size utf16_decode_char(const wchar_t * p_source,unsigned * p_out,t_size p_source_length = ~0);
00079 t_size utf16_encode_char(unsigned c,wchar_t * out);
00080
00081
00082 t_size strstr_ex(const char * p_string,t_size p_string_len,const char * p_substring,t_size p_substring_len);
00083
00084 int strcmp_partial(const char * p_string,const char * p_substring);
00085 int strcmp_partial_ex(const char * p_string,t_size p_string_length,const char * p_substring,t_size p_substring_length);
00086
00087 t_size skip_utf8_chars(const char * ptr,t_size count);
00088 char * strdup_n(const char * src,t_size len);
00089 int stricmp_ascii(const char * s1,const char * s2);
00090 int stricmp_ascii_ex(const char * s1,t_size len1,const char * s2,t_size len2);
00091
00092 int strcmp_ex(const char* p1,t_size n1,const char* p2,t_size n2);
00093
00094 unsigned utf8_get_char(const char * src);
00095
00096 inline bool utf8_advance(const char * & var) {
00097 t_size delta = utf8_char_len(var);
00098 var += delta;
00099 return delta>0;
00100 }
00101
00102 inline bool utf8_advance(char * & var) {
00103 t_size delta = utf8_char_len(var);
00104 var += delta;
00105 return delta>0;
00106 }
00107
00108 inline const char * utf8_char_next(const char * src) {return src + utf8_char_len(src);}
00109 inline char * utf8_char_next(char * src) {return src + utf8_char_len(src);}
00110
00111 class NOVTABLE string_base : public pfc::string_receiver {
00112 public:
00113 virtual const char * get_ptr() const = 0;
00114 virtual void add_string(const char * p_string,t_size p_length = ~0) = 0;
00115 virtual void set_string(const char * p_string,t_size p_length = ~0) {reset();add_string(p_string,p_length);}
00116 virtual void truncate(t_size len)=0;
00117 virtual t_size get_length() const {return strlen(get_ptr());}
00118 virtual char * lock_buffer(t_size p_requested_length) = 0;
00119 virtual void unlock_buffer() = 0;
00120
00122 inline t_size length() const {return get_length();}
00123
00124 inline void reset() {truncate(0);}
00125
00126 inline bool is_empty() const {return *get_ptr()==0;}
00127
00128 void skip_trailing_char(unsigned c = ' ');
00129
00130 bool is_valid_utf8() {return pfc::is_valid_utf8(get_ptr());}
00131
00132 void convert_to_lower_ascii(const char * src,char replace = '?');
00133
00134 inline const string_base & operator= (const char * src) {set_string(src);return *this;}
00135 inline const string_base & operator+= (const char * src) {add_string(src);return *this;}
00136 inline const string_base & operator= (const string_base & src) {set_string(src);return *this;}
00137 inline const string_base & operator+= (const string_base & src) {add_string(src);return *this;}
00138
00139 inline operator const char * () const {return get_ptr();}
00140
00141 t_size scan_filename() const {return pfc::scan_filename(get_ptr());}
00142
00143 t_size find_first(char p_char,t_size p_start = 0) {return pfc::string_find_first(get_ptr(),p_char,p_start);}
00144 t_size find_last(char p_char,t_size p_start = ~0) {return pfc::string_find_last(get_ptr(),p_char,p_start);}
00145 t_size find_first(const char * p_string,t_size p_start = 0) {return pfc::string_find_first(get_ptr(),p_string,p_start);}
00146 t_size find_last(const char * p_string,t_size p_start = ~0) {return pfc::string_find_last(get_ptr(),p_string,p_start);}
00147
00148 void fix_dir_separator(char p_char);
00149 protected:
00150 string_base() {}
00151 ~string_base() {}
00152 };
00153
00154 template<t_size max_length>
00155 class string_fixed_t : public pfc::string_base {
00156 public:
00157 inline string_fixed_t() {init();}
00158 inline string_fixed_t(const string_fixed_t<max_length> & p_source) {init(); *this = p_source;}
00159 inline string_fixed_t(const char * p_source) {init(); set_string(p_source);}
00160
00161 inline const string_fixed_t<max_length> & operator=(const string_fixed_t<max_length> & p_source) {set_string(p_source);return *this;}
00162 inline const string_fixed_t<max_length> & operator=(const char * p_source) {set_string(p_source);return *this;}
00163
00164 char * lock_buffer(t_size p_requested_length) {
00165 if (p_requested_length >= max_length) return NULL;
00166 memset(m_data,0,sizeof(m_data));
00167 return m_data;
00168 }
00169 void unlock_buffer() {
00170 m_length = strlen(m_data);
00171 }
00172
00173 inline operator const char * () const {return m_data;}
00174
00175 const char * get_ptr() const {return m_data;}
00176
00177 void add_string(const char * ptr,t_size len) {
00178 len = strlen_max(ptr,len);
00179 if (m_length + len < m_length || m_length + len > max_length) throw pfc::exception_overflow();
00180 for(t_size n=0;n<len;n++) {
00181 m_data[m_length++] = ptr[n];
00182 }
00183 m_data[m_length] = 0;
00184 }
00185 void truncate(t_size len) {
00186 if (len > max_length) len = max_length;
00187 if (m_length > len) {
00188 m_length = len;
00189 m_data[len] = 0;
00190 }
00191 }
00192 t_size get_length() const {return m_length;}
00193 private:
00194 inline void init() {
00195 pfc::static_assert<(max_length>1)>();
00196 m_length = 0; m_data[0] = 0;
00197 }
00198 t_size m_length;
00199 char m_data[max_length+1];
00200 };
00201
00202 template<template<typename> class t_alloc>
00203 class string8_t : public pfc::string_base {
00204 private:
00205 typedef string8_t<t_alloc> t_self;
00206 protected:
00207 pfc::array_t<char,t_alloc> m_data;
00208 t_size used;
00209
00210 inline void makespace(t_size s)
00211 {
00212 t_size old_size = m_data.get_size();
00213 if (old_size < s)
00214 m_data.set_size(s+16);
00215 else if (old_size > s + 32)
00216 m_data.set_size(s);
00217 }
00218
00219 inline const char * __get_ptr() const throw() {return used > 0 ? m_data.get_ptr() : "";}
00220
00221 public:
00222 inline const t_self & operator= (const char * src) {set_string(src);return *this;}
00223 inline const t_self & operator+= (const char * src) {add_string(src);return *this;}
00224 inline const t_self & operator= (const string_base & src) {set_string(src);return *this;}
00225 inline const t_self & operator+= (const string_base & src) {add_string(src);return *this;}
00226 inline const t_self & operator= (const t_self & src) {set_string(src);return *this;}
00227 inline const t_self & operator+= (const t_self & src) {add_string(src);return *this;}
00228
00229 inline operator const char * () const throw() {return __get_ptr();}
00230
00231 string8_t() : used(0) {}
00232 string8_t(const char * p_string) : used(0) {set_string(p_string);}
00233 string8_t(const char * p_string,t_size p_length) : used(0) {set_string(p_string,p_length);}
00234 string8_t(const t_self & p_string) : used(0) {set_string(p_string);}
00235 string8_t(const string_base & p_string) : used(0) {set_string(p_string);}
00236
00237 void prealloc(t_size p_size) {m_data.prealloc(p_size+1);}
00238
00239 const char * get_ptr() const throw() {return __get_ptr();}
00240
00241 void add_string(const char * p_string,t_size p_length = ~0);
00242 void set_string(const char * p_string,t_size p_length = ~0);
00243
00244 void truncate(t_size len)
00245 {
00246 if (used>len) {used=len;m_data[len]=0;makespace(used+1);}
00247 }
00248
00249 t_size get_length() const throw() {return used;}
00250
00251
00252 void set_char(unsigned offset,char c);
00253
00254 t_size replace_nontext_chars(char p_replace = '_');
00255 t_size replace_char(unsigned c1,unsigned c2,t_size start = 0);
00256 t_size replace_byte(char c1,char c2,t_size start = 0);
00257 void fix_filename_chars(char def = '_',char leave=0);
00258 void remove_chars(t_size first,t_size count);
00259 void insert_chars(t_size first,const char * src, t_size count);
00260 void insert_chars(t_size first,const char * src);
00261 bool truncate_eol(t_size start = 0);
00262 bool fix_eol(const char * append = " (...)",t_size start = 0);
00263 bool limit_length(t_size length_in_chars,const char * append = " (...)");
00264
00265
00266 char * lock_buffer(t_size n)
00267 {
00268 makespace(n+1);
00269 pfc::memset_t(m_data,(char)0);
00270 return m_data.get_ptr();;
00271 }
00272
00273 void unlock_buffer() {
00274 used=strlen(m_data.get_ptr());
00275 makespace(used+1);
00276 }
00277
00278 void force_reset() {used=0;m_data.force_reset();}
00279
00280 inline static void g_swap(t_self & p_item1,t_self & p_item2) {
00281 pfc::swap_t(p_item1.m_data,p_item2.m_data);
00282 pfc::swap_t(p_item1.used,p_item2.used);
00283 }
00284 };
00285
00286 typedef string8_t<pfc::alloc_standard> string8;
00287 typedef string8_t<pfc::alloc_fast> string8_fast;
00288 typedef string8_t<pfc::alloc_fast_aggressive> string8_fast_aggressive;
00289
00290 typedef string8_t<pfc::alloc_fast_aggressive> string8_fastalloc;
00291
00292
00293 template<template<typename> class t_alloc> class traits_t<string8_t<t_alloc> > : public pfc::combine_traits<pfc::traits_vtable,pfc::traits_t<pfc::array_t<char,t_alloc> > > {
00294 public:
00295 enum {
00296 needs_constructor = true,
00297 };
00298 };
00299 }
00300
00301
00302
00303 #include "string8_impl.h"
00304
00305 #define PFC_DEPRECATE_PRINTF PFC_DEPRECATE("Use string8/string_fixed_t with operator<< overloads instead.")
00306
00307 namespace pfc {
00308
00309 class string_buffer {
00310 private:
00311 string_base & m_owner;
00312 char * m_buffer;
00313 public:
00314 explicit string_buffer(string_base & p_string,t_size p_requeted_length) : m_owner(p_string) {m_buffer = m_owner.lock_buffer(p_requeted_length);}
00315 ~string_buffer() {m_owner.unlock_buffer();}
00316 operator char* () {return m_buffer;}
00317 };
00318
00319 class PFC_DEPRECATE_PRINTF string_printf : public string8_fastalloc {
00320 public:
00321 static void g_run(string_base & out,const char * fmt,va_list list);
00322 void run(const char * fmt,va_list list);
00323
00324 explicit string_printf(const char * fmt,...);
00325 };
00326
00327 class PFC_DEPRECATE_PRINTF string_printf_va : public string8_fastalloc {
00328 public:
00329 string_printf_va(const char * fmt,va_list list);
00330 };
00331
00332 class format_time {
00333 public:
00334 format_time(t_uint64 p_seconds);
00335 const char * get_ptr() const {return m_buffer;}
00336 operator const char * () const {return m_buffer;}
00337 protected:
00338 string_fixed_t<127> m_buffer;
00339 };
00340
00341
00342 class format_time_ex {
00343 public:
00344 format_time_ex(double p_seconds,unsigned p_extra = 3);
00345 const char * get_ptr() const {return m_buffer;}
00346 operator const char * () const {return m_buffer;}
00347 private:
00348 string_fixed_t<127> m_buffer;
00349 };
00350
00351
00352
00353
00354 class string_filename : public string8 {
00355 public:
00356 explicit string_filename(const char * fn);
00357 };
00358
00359 class string_filename_ext : public string8 {
00360 public:
00361 explicit string_filename_ext(const char * fn);
00362 };
00363
00364 class string_extension
00365 {
00366 char buffer[32];
00367 public:
00368 inline const char * get_ptr() const {return buffer;}
00369 inline t_size length() const {return strlen(buffer);}
00370 inline operator const char * () const {return buffer;}
00371 explicit string_extension(const char * src);
00372 };
00373
00374
00375 class string_replace_extension
00376 {
00377 public:
00378 string_replace_extension(const char * p_path,const char * p_ext);
00379 inline operator const char*() const {return m_data;}
00380 private:
00381 string8 m_data;
00382 };
00383
00384 class string_directory
00385 {
00386 public:
00387 string_directory(const char * p_path);
00388 inline operator const char*() const {return m_data;}
00389 private:
00390 string8 m_data;
00391 };
00392
00393 void float_to_string(char * out,t_size out_max,double val,unsigned precision,bool force_sign = false);
00394 double string_to_float(const char * src,t_size len = infinite);
00395
00396 template<>
00397 inline void swap_t(string8 & p_item1,string8 & p_item2)
00398 {
00399 string8::g_swap(p_item1,p_item2);
00400 }
00401
00402 class format_float
00403 {
00404 public:
00405 format_float(double p_val,unsigned p_width,unsigned p_prec);
00406 format_float(const format_float & p_source) {*this = p_source;}
00407
00408 inline const char * get_ptr() const {return m_buffer.get_ptr();}
00409 inline operator const char*() const {return m_buffer.get_ptr();}
00410 private:
00411 string8 m_buffer;
00412 };
00413
00414 class format_int
00415 {
00416 public:
00417 format_int(t_int64 p_val,unsigned p_width = 0,unsigned p_base = 10);
00418 format_int(const format_int & p_source) {*this = p_source;}
00419 inline const char * get_ptr() const {return m_buffer;}
00420 inline operator const char*() const {return m_buffer;}
00421 private:
00422 char m_buffer[64];
00423 };
00424
00425
00426 class format_uint
00427 {
00428 public:
00429 format_uint(t_uint64 p_val,unsigned p_width = 0,unsigned p_base = 10);
00430 format_uint(const format_uint & p_source) {*this = p_source;}
00431 inline const char * get_ptr() const {return m_buffer;}
00432 inline operator const char*() const {return m_buffer;}
00433 private:
00434 char m_buffer[64];
00435 };
00436
00437 class format_hex
00438 {
00439 public:
00440 format_hex(t_uint64 p_val,unsigned p_width = 0);
00441 format_hex(const format_hex & p_source) {*this = p_source;}
00442 inline const char * get_ptr() const {return m_buffer;}
00443 inline operator const char*() const {return m_buffer;}
00444 private:
00445 char m_buffer[17];
00446 };
00447
00448 class format_hex_lowercase
00449 {
00450 public:
00451 format_hex_lowercase(t_uint64 p_val,unsigned p_width = 0);
00452 format_hex_lowercase(const format_hex_lowercase & p_source) {*this = p_source;}
00453 inline const char * get_ptr() const {return m_buffer;}
00454 inline operator const char*() const {return m_buffer;}
00455 private:
00456 char m_buffer[17];
00457 };
00458
00459
00460 typedef string8_fastalloc string_formatter;
00461
00462 class format_hexdump
00463 {
00464 public:
00465 format_hexdump(const void * p_buffer,t_size p_bytes,const char * p_spacing = " ");
00466
00467 inline const char * get_ptr() const {return m_formatter;}
00468 inline operator const char * () const {return m_formatter;}
00469
00470 private:
00471 string_formatter m_formatter;
00472 };
00473
00474 class format_hexdump_lowercase
00475 {
00476 public:
00477 format_hexdump_lowercase(const void * p_buffer,t_size p_bytes,const char * p_spacing = " ");
00478
00479 inline const char * get_ptr() const {return m_formatter;}
00480 inline operator const char * () const {return m_formatter;}
00481
00482 private:
00483 string_formatter m_formatter;
00484 };
00485
00486 class format_fixedpoint
00487 {
00488 public:
00489 format_fixedpoint(t_int64 p_val,unsigned p_point);
00490 inline const char * get_ptr() const {return m_buffer;}
00491 inline operator const char*() const {return m_buffer;}
00492 private:
00493 string_formatter m_buffer;
00494 };
00495
00496 class format_char {
00497 public:
00498 format_char(char p_char) {m_buffer[0] = p_char; m_buffer[1] = 0;}
00499 inline const char * get_ptr() const {return m_buffer;}
00500 inline operator const char*() const {return m_buffer;}
00501 private:
00502 char m_buffer[2];
00503 };
00504
00505 template<typename t_stringbuffer = pfc::string8_fastalloc>
00506 class format_pad_left {
00507 public:
00508 format_pad_left(t_size p_chars,t_uint32 p_padding ,const char * p_string,t_size p_string_length = infinite) {
00509 t_size source_len = 0, source_walk = 0;
00510
00511 while(source_walk < p_string_length && source_len < p_chars) {
00512 unsigned dummy;
00513 t_size delta = pfc::utf8_decode_char(p_string + source_walk, &dummy, p_string_length - source_walk);
00514 if (delta == 0) break;
00515 source_len++;
00516 source_walk += delta;
00517 }
00518
00519 m_buffer.add_string(p_string,source_walk);
00520 m_buffer.add_chars(p_padding,p_chars - source_len);
00521 }
00522 inline const char * get_ptr() const {return m_buffer;}
00523 inline operator const char*() const {return m_buffer;}
00524 private:
00525 t_stringbuffer m_buffer;
00526 };
00527
00528 template<typename t_stringbuffer = pfc::string8_fastalloc>
00529 class format_pad_right {
00530 public:
00531 format_pad_right(t_size p_chars,t_uint32 p_padding ,const char * p_string,t_size p_string_length = infinite) {
00532 t_size source_len = 0, source_walk = 0;
00533
00534 while(source_walk < p_string_length && source_len < p_chars) {
00535 unsigned dummy;
00536 t_size delta = pfc::utf8_decode_char(p_string + source_walk, &dummy, p_string_length - source_walk);
00537 if (delta == 0) break;
00538 source_len++;
00539 source_walk += delta;
00540 }
00541
00542 m_buffer.add_chars(p_padding,p_chars - source_len);
00543 m_buffer.add_string(p_string,source_walk);
00544 }
00545 inline const char * get_ptr() const {return m_buffer;}
00546 inline operator const char*() const {return m_buffer;}
00547 private:
00548 t_stringbuffer m_buffer;
00549 };
00550 }
00551
00552 inline pfc::string_base & operator<<(pfc::string_base & p_fmt,const char * p_source) {p_fmt.add_string(p_source); return p_fmt;}
00553 inline pfc::string_base & operator<<(pfc::string_base & p_fmt,t_int32 p_val) {return p_fmt << pfc::format_int(p_val);}
00554 inline pfc::string_base & operator<<(pfc::string_base & p_fmt,t_uint32 p_val) {return p_fmt << pfc::format_uint(p_val);}
00555 inline pfc::string_base & operator<<(pfc::string_base & p_fmt,t_int64 p_val) {return p_fmt << pfc::format_int(p_val);}
00556 inline pfc::string_base & operator<<(pfc::string_base & p_fmt,t_uint64 p_val) {return p_fmt << pfc::format_uint(p_val);}
00557 inline pfc::string_base & operator<<(pfc::string_base & p_fmt,double p_val) {return p_fmt << pfc::format_float(p_val,0,7);}
00558
00559 inline pfc::string_base & operator<<(pfc::string_base & p_fmt,std::exception const & p_exception) {return p_fmt << p_exception.what();}
00560
00561
00562
00563
00564
00565
00566 namespace pfc {
00567 template<typename t_char>
00568 class string_simple_t {
00569 private:
00570 typedef string_simple_t<t_char> t_self;
00571 public:
00572 t_size length(t_size p_limit = infinite) const {return pfc::strlen_t(get_ptr(),infinite);}
00573 bool is_empty() const {return length(1) == 0;}
00574 void set_string(const t_char * p_source,t_size p_length = infinite) {
00575 t_size length = pfc::strlen_t(p_source,p_length);
00576 m_buffer.set_size(length + 1);
00577 pfc::memcpy_t(m_buffer.get_ptr(),p_source,length);
00578 m_buffer[length] = 0;
00579 }
00580 string_simple_t() {}
00581 string_simple_t(const t_char * p_source,t_size p_length = infinite) {set_string(p_source,p_length);}
00582 const t_self & operator=(const t_char * p_source) {set_string(p_source);return *this;}
00583 operator const t_char* () const {return get_ptr();}
00584 const t_char * get_ptr() const {return m_buffer.get_size() > 0 ? m_buffer.get_ptr() : pfc::empty_string_t<t_char>();}
00585 private:
00586 pfc::array_t<t_char> m_buffer;
00587 };
00588
00589 typedef string_simple_t<char> string_simple;
00590
00591 template<typename t_char> class traits_t<string_simple_t<t_char> > : public traits_t<array_t<t_char> > {};
00592 }
00593
00594
00595 namespace pfc {
00596
00597
00598 class comparator_strcmp {
00599 public:
00600 inline static int compare(const char * p_item1,const char * p_item2) {return strcmp(p_item1,p_item2);}
00601 };
00602
00603 class comparator_stricmp_ascii {
00604 public:
00605 inline static int compare(const char * p_item1,const char * p_item2) {return pfc::stricmp_ascii(p_item1,p_item2);}
00606 };
00607
00608 }
00609
00610 #endif //_PFC_STRING_H_