I wrote two blog related to this, one is the implementation of the <cstring> header file, and the other is the implementation of <cwchar>, here the Char_traits template class is implemented on this basis.
For convenience, the source code is packaged together in the namespace MYSTD.
Code below!!!
This file is named "Char_traits.h"//vs2012 debug via #pragma once #ifndef mystd_char_traits_h#define mystd_char_traits_h#include< cstddef>//std::size_t #include <cassert> #pragma push_macro ("EOF") #undef EOF #define EOF ( -1) #pragma push_ Macro ("weof") #undef weof #define WEOF (unsigned short) (0xFFFF) #define Mystd_begin namespace mystd{#define Mystd_end} #if def __cplusplusmystd_begin//cstring.htypedef std::size_t size_type;typedef unsigned char uchar;//C language version, void * MEMCHR (c onst void *,int,size_type); Inline const void* MEMCHR (const void *pointer,int val, size_type num) {ASSERT (pointer! = 0); UCHAR *ptr = (uchar*) pointer; for (Size_type i = 0; i < num; ++i) {if (*ptr = = val) break;++ptr;} return ptr;} inline void* memchr (void *pointer, int val,size_type num)//c++ overloads {assert (pointer! = 0); return (void*) MYSTD::MEMCHR (( Const void*) pointer,val,num); Transpose}inline size_type strlen (const char *str) {assert (str! = 0); Size_type count = 0;while (*str++) ++count;return count;} Inline void* memmove (voiD *destination,const void *source, Size_type num) {//For the implementation of the Memmove function, the father of C + + begins with the C + + programming language (16th chapter of the 10 Anniversary Chinese Commemorative Edition)//said that this function cannot be managed by C + + The language itself achieves the best realization, the actual application still uses the standard library bar! ASSERT (Destination! = 0 && Source! = 0); if (destination = = Source | | num = = 0) return destination; UCHAR *des = (uchar*) destination; Const UCHAR *SRC = (uchar*) source; if (des < src | | des >= src + num) {while (num--) *des++ = *src++;return destination;} Des + = num;src + num;while (num--)//Reverse Copy *--des = *--src;return destination;} inline void* memcpy (void *destination,const void *source, Size_type num) {assert (Destination! = 0 && Source! = 0); r Eturn Mystd::memmove (destination,source,num);} inline int memcmp (const void *pointer_1,const void *pointer_2,size_type num) {assert (pointer_1! = 0 && pointer_2! = 0); const UCHAR *ptr_1 = (uchar*) pointer_1;const UCHAR *ptr_2 = (uchar*) pointer_2;while (num--&& *ptr_1 = *ptr_2) ++ptr_1,++ptr_2;if (num = = Size_type ( -1)) return 0;elsereturn *ptr_1-*ptr_2;} Inline void* mEmset (void *pointer,int val,size_type num) {ASSERT (pointer! = 0); UCHAR *ptr = (uchar*) pointer;while (num--) *ptr++ = Val;return pointer;} Inline char* strcat (char *destination,const char *source) {assert (Destination! = 0 && Source! = 0); char *ptr = dest Ination + mystd::strlen (destination), while (*ptr++ = *source++); return destination;} inline Char *strncat (char *destination,const char *source,size_type num) {assert (Destination! = 0 && Source! = 0); c Har *ptr = destination + mystd::strlen (destination), while (num--&& *source) *ptr++ = *source++;*ptr = 0; Null-character copy return destination;} inline Char *strcpy (char *destination,const char *source) {assert (Destination! = 0 && Source! = 0); char *des = dest Ination;while (*des++ = *source++); return destination; Null-character is copied}inline Char *strncpy (char *destination,const char *source,size_type num) {assert (Destination! = 0 & amp;& Source! = 0); char *des = Destination;while (num--) *des++ = *source++; Return desTination; Null-character may not be copied}inline int strcmp (const char *str1,const char *str2) {assert (str1! = 0 && str2! = 0) ; while (*str1 && *str1 = = *str2) ++str1, ++STR2; return *STR1-*str2;} inline int strncmp (const char *str1,const char *str2,size_type num) {assert (str1! = 0 && str2! = 0); while (num--&am p;& *str1 && *str1 = *str2) ++str1, ++str2;if (num = = Size_type (-1))//contains num = = 0 in case return 0;elsereturn *STR 1-*str2;} C language has only one version char* STRCHR (const char *, int); Inline const char* STRCHR (const char *str,int character) {assert (str! = 0);//The language standard stipulates that character is int, here convert const char CHR = * (char*) &character;while (*str && *str = chr) ++str;if (*STR) return Str;elsereturn 0;} Inline char* strchr (char *str,int character)//c++ overload {assert (str! = 0); return (char*) MYSTD::STRCHR ((const char*) str, character);} Inline const char* STRRCHR (const char *str,int character) {//character here may include Null-characterassert (str! = 0);//language Standard Rules Cha Racter for int, here to convertA bit const char CHR = * (char*) &character;size_type len = Mystd::strlen (str); const char *ptr = str + len;if (chr = = 0) retur n Ptr;--ptr;while (len--) if (*ptr = CHR) return Ptr;else--ptr;return 0; No matching characters} inline char* strrchr (char *str,int character) {assert (str! = 0); return (char*) MYSTD::STRRCHR ((const char*) str, character); Transpose}//c language version char* strstr (const char *,const char*), inline const char* STRSTR (const char* str1,const char* str2) {Assert (St R1! = 0 && str2! = 0); Size_type len_1 = Mystd::strlen (str1); Size_type len_2 = Mystd::strlen (STR2); if (Len_1 < le n_2) return 0;const char *search_last = str1 + (len_1-len_2), while (str1 <= search_last) {if (mystd::strncmp (str1,str2,l en_2) = = 0) return str1;else++str1;} return 0;} Inline char* strstr (char *str1,const char *str2)//c++ overload {assert (str1! = 0 && str2! = 0); return (char*) Mystd::strst R ((const char*) str1,str2);} inline bool Is_inside (const char *str,char CHR)//auxiliary function, internally using {assert (str! = 0), while (*STR) {if (*str = CHR) retuRN True;else ++str;} return false;} Inline Size_type strspn (const char* Str1,const char *str2) {assert (str1! = 0 && str2! = 0); Size_type count = 0;whil E (*str1 && is_inside (STR2,*STR1)) ++count, ++str1;return count;} Inline Size_type strcspn (const char* Str1,const char *str2) {assert (str1! = 0 && str2! = 0); Size_type count = 0;whi Le (*str1 &&!is_inside (STR2,*STR1)) ++count, ++str1;return count;} C language version char* strpbrk (const char *,const char *); Inline const char* STRPBRK (const char *str1,const char *str2) {assert (str1! = 0 && str2! = 0); while (*str1 && ;!is_inside (STR2,*STR1)) ++str1;if (*str1 = = 0) return 0;elsereturn str1;} Inline char* strpbrk (char *str1,const char *str2)//c++ overloads {assert (str1! = 0 && str2! = 0); return (char*) STRPBRK (CO NST char*) str1,str2); Transpose}inline char* strtok (char *str,const char *delim) {#ifdef _debugstatic bool First_switch = false;if (!first_switch) A Ssert (str! = 0); assert (Delim! = 0); #endifstatic char * p_location = 0; Record Search start position if (str) p_location = Str;char *ptr = mystd::strpbrk (p_location,delim); char *temp = p_location;if (ptr = = 0)//not found Delimiter, default to search end {#ifdef _debugfirst_switch = false; End of search, First_switch false #endifp_location = 0; End of search, p_location reset return temp;} #ifdef _debugfirst_switch = true; #endif *ptr = 0;p_location = ptr + 1; Location update return temp;} Inline Size_type strxfrm (char *destination,const char *source,size_type num), inline int strcoll (const char *str1,const CH Ar *str2); inline char* strerror (int errnum); Mystd_end//END of namespace MYSTD mystd_begin//Wide character version typedef std::size_t SIZE_TYPE;TYPEDEF wchar_t char_type;inline s Ize_type wcslen (const char_type* WCS) {assert (WCS! = 0); Size_type count = 0; while (*wcs++) ++count; return count;} Inline char_type* wcscat (char_type* destination,const char_type *source) {assert (Destination! = 0 && Source! = 0); Char_type *des = destination + mystd::wcslen (destination), while (*des++ = *source++); return destination;} Inline Char_type* Wcsncat (char_type* destination,const char_type *source,size_type num) {assert (Destination! = 0 && Source! = 0); Char_type *des = destination + mystd::wcslen (destination), while (num--&& *source) *des++ = *source++;*des = 0; return destination;} Inline char_type* wcscpy (char_type *destination,const char_type *source) {assert (Destination! = 0 && Source! = 0); Char_type *des = destination;while (*des++ = *source++); return destination;} Inline char_type* wcsncpy (char_type *destination,const char_type *source,size_type num) {assert (Destination! = 0 && Amp SOURCE! = 0); Char_type *des = Destination;while (num--) *des++ = *source++; return destination; may not contain null wide character}inline int wcscmp (const char_type *wcs1,const char_type *wcs2) {assert (WCS1! = 0 && WC S2! = 0); while (*wcs1 && *wcs1 = = *wcs2) ++wcs1, ++wcs2;return *wcs1-*wcs2;} inline int wcsncmp (const char_type *wcs1,const char_type *wcs2,size_type num) {assert (WCS1! = 0 && WCS2! = 0); whIle (num--&& *wcs1 && *wcs1 = = *wcs2) ++wcs1, ++wcs2;if (num = = Size_type (-1))//contains num = = 0 Case return 0;el Sereturn *wcs1-*WCS2;} Inline const char_type* WMEMCHR (const char_type* pointer,char_type val,size_type num) {ASSERT (pointer! = 0); Char_type * ptr = (char_type*) pointer; for (Size_type i = 0; i < num; ++i) {if (*ptr = = val) break;++ptr;} return ptr;} Inline char_type* wmemchr (char_type* pointer,char_type val,size_type num) {ASSERT (pointer! = 0); return (char_type*) WMEMCHR ((const char_type*) pointer,val,num);} inline int wmemcmp (const char_type *ptr_1,const char_type *ptr_2,size_type num) {assert (ptr_1! = 0 && ptr_2! = 0); w Hile (num--&& *ptr_1 = *ptr_2) ++ptr_1, ++ptr_2;if (num = = Size_type ( -1)) return 0;elsereturn *ptr_1-*ptr_2;} Inline char_type* wmemset (char_type *pointer,char_type val,size_type num) {ASSERT (pointer! = 0); Char_type *ptr = pointer; while (num--) *ptr++ = Val;return pointer;} Inline char_type* wmemmove (char_type *destination,const char_type *source,size_type num) {assert (Destination! = 0 && Source! = 0); if (destination = = Source | | num = = 0) return de Stination;char_type *des = (char_type*) destination; Const Char_type *SRC = (char_type*) source; if (des < src | | des >= src + num) {while (num--) *des++ = *src++;return destination;} Des + = num;src + num;while (num--)//Reverse Copy *--des = *--src;return destination;} Inline char_type* wmemcpy (char_type *destination,const char_type *source,size_type num) {assert (Destination! = 0 && Amp SOURCE! = 0); return Mystd::wmemmove (Destination,source,num);} inline bool W_is_inside (const Char_type *wcs,char_type val)//auxiliary function, internally using {assert (WCS! = 0), while (*WCS) {if (*wcs = val) retu RN True;else ++wcs;} return false;} Inline Size_type wcsspn (const char_type *wcs1,const char_type *wcs2) {assert (WCS1! = 0 && WCS2! = 0); Size_type coun t = 0;while (*wcs1 && w_is_inside (WCS2,*WCS1)) ++count, ++wcs1;return count;} Inline Size_type wcscspn (const char_type *wcs1,const char_type *WCS2){assert (WCS1! = 0 && WCS2! = 0); Size_type count = 0;while (*wcs1 &&!w_is_inside (WCS2,*WCS1)) ++count, ++wcs 1;return count;} Inline const char_type* WCSSTR (const char_type *wcs1,const char_type *wcs2) {assert (WCS1! = 0 && WCS2! = 0); size_ty PE len_1 = Mystd::wcslen (WCS1); Size_type len_2 = Mystd::wcslen (WCS2); if (Len_1 < len_2) return 0;const Char_type *search _last = wcs1 + (len_1-len_2), while (WCS1 <= search_last) {if (mystd::wcsncmp (wcs1,wcs2,len_2) = = 0) return WCS1;ELSE++WC S1;} return 0;} Inline char_type* wcsstr (char_type *wcs1,const char_type *wcs2) {assert (WCS1! = 0 && WCS2! = 0); return (char_type*) MYSTD::WCSSTR ((const char_type*) WCS1,WCS2);} Inline const char_type* WCSCHR (const Char_type *wcs,char_type val) {assert (WCS! = 0); while (*wcs && *wcs = val) ++wc S;if (*WCS) return Wcs;elsereturn 0;} Inline char_type* wcschr (Char_type *wcs,char_type val) {assert (WCS! = 0); return (char_type*) MYSTD::WCSCHR ((const CHAR_ type*) wcs,val);} Inline Const char_type* WCSRCHR (const Char_type *wcs,char_type val) {//Val may be null wide character assert (WCS! = 0); Size_type len = Mystd::wcslen ( WCS); const Char_type *PTR = WCS + len;if (val = = 0) return Ptr;--ptr;while (len--) if (*ptr = val) return Ptr;else--ptr;return 0; No matching characters}inline char_type* wcsrchr (Char_type *wcs,char_type val) {//val may be null wide character assert (WCS! = 0); return (CH ar_type*) MYSTD::WCSRCHR ((const char_type*) wcs,val); Transpose} inline const char_type* WCSPBRK (const char_type *wcs1,const char_type *wcs2) {assert (WCS1! = 0 && WCS2! = 0); while (*wcs1 &&!w_is_inside (WCS2,*WCS1)) ++wcs1;if (*wcs1 = = 0) return 0;elsereturn WCS1;} Inline char_type* wcspbrk (char_type *wcs1,const char_type *wcs2) {assert (WCS1! = 0 && WCS2! = 0); return (char_type* ) mystd::wcspbrk ((const char_type*) WCS1,WCS2);} Inline char_type* wcstok (char_type *wcs,const char_type *delim) {#ifdef _debugstatic bool First_switch = false;if (!first_ Switch) assert (WCS! = 0); assert (Delim! = 0); #endifstatic Char_type * p_location = 0; Record Search Start location if (WCS) p_location = Wcs;char_type *ptr = mystd::wcspbrk (P_location,delim); Char_type *temp = P_location;if ( ptr = = 0)//Cannot find delimiter, default is Search end {#ifdef _debugfirst_switch = false; End of search, First_switch false #endifp_location = 0; End of search, p_location reset return temp;} #ifdef _debugfirst_switch = true; #endif *ptr = 0;p_location = ptr + 1; Location update return temp;} Inline Size_type wcsxfrm (char_type *destination,const char_type *source,size_type num); mystd_endmystd_begin typedef unsigned short wint_t;template<class chart>struct char_traits{typedef std::size_t Size_type;}; template<>//char special struct char_traits<char>{typedef int int_type;typedef char char_type;public:static Size_type Length (const char_type *str) throw () {assert (str! = 0); return Mystd::strlen (str);} static void Assign (char_type& chr,const char_type& val) throw () {chr = val; } static Char_type Assign (Char_type *ptr,size_type num,char_type chr) throw () {assert (PTR ! = 0); Mystd::memset (Ptr,chr,num); return CHR; } static int Compare (const char_type *str1,const char_type *str2,size_type num) throw () {assert (str1! = 0 && ; Str2! = 0); Return mystd::strncmp (Str1,str2,num); Note C-style string} static char_type* Move (char_type *des,const char_type *src,size_type num) throw () {assert (des! = 0 && src! = 0); #ifdef _DEBUG return (char_type*) mystd::memmove (des,src,num); #else return (char_type*) Std::memmov E (des,src,num); The standard library version is more efficient #endif} static char_type* copy (Char_type *des,const char_type *src,size_type num) throw () {Assert (DE s! = 0 && src! = 0); #ifdef _DEBUG return (char_type*) mystd::memcpy (des,src,num); #else return (Char_typ e*) std::memcpy (des,src,num); Standard library version more efficient #endif} static bool eq (const char_type& chr_1,const char_type& chr_2) {return chr_1 = = chr_2 ; } Static const char_type* find (const char_type* ptr,size_t num,const char_type& chr) {assert (ptr! =0); while (num--&& *ptr! = CHR) ++ptr; if (*ptr = CHR && num! = Size_type (-1))//not dependent on null character return PTR; else return 0; } Static Char_type To_char_type (const int_type& CHR) throw () {assert (Chr < 0xFF); return * (char_type*) &chr; } Static Int_type To_int_type (const char_type& CHR) throw () {return static_cast<char_type> (CHR); } static Int_type eof () throw () {return EOF; }};template<>//Wide character version struct Char_traits<wchar_t>{typedef wint_t int_type;typedef wchar_t char_type; Public:static size_type Length (const char_type *wcs) throw () {return Mystd::wcslen (WCS);} static void Assign (char_type& wc,const char_type& val) throw () {WC = val; } static Char_type Assign (Char_type *ptr,size_type num,char_type WC) throw () {assert (ptr! = 0); while (num--) *ptr++ = WC; return WC; } static int Compare (const char_type *wcs1,const char_type *wcs2,size_type num) throw (){assert (WCS1! = 0 && WCS2! = 0); Return mystd::wcsncmp (Wcs1,wcs2,num); } Static char_type* Move (char_type *des,const char_type *src,size_type num) throw () {assert (des! = 0 && src ! = 0); #ifdef _DEBUG return (char_type*) mystd::wmemmove (des,src,num); #else return (char_type*) Std::wmemmove (des,src,n UM); The standard library version is more efficient #endif} static char_type* copy (Char_type *des,const char_type *src,size_type num) throw () {Assert (DE s! = 0 && src! = 0); #ifdef _DEBUG return (char_type*) mystd::wmemcpy (des,src,num); #else return (char_type*) std: : wmemcpy (Des,src,num); Standard library version is more efficient #endif} static bool eq (const char_type& wc_1,const char_type& wc_2) {return wc_1 = = wc_2; } Static const char_type* find (const char_type* ptr,size_t num,const char_type& WC) {assert (ptr! = 0); while (*ptr && num--&& *ptr! = WC) ++ptr; if (*ptr = = WC) return ptr; else return 0; } Static Char_type To_char_type (const Int_type& WC) throw () {assert (WC < 0xFFFF); return WC; } Static Int_type To_int_type (const char_type& WC) throw () {assert (WC < 0xFFFF); return WC; } static Int_type eof () throw () {return weof; }}; Mystd_end//END of namespace MYSTD #endif//__cplusplus #pragma pop_macro ("weof") #pragma pop_macro ("EOF") #endif//MYST D_char_traits_h
I hope the master criticism!!!
C + + Char_traits template class implementation!!!