c++ char_traits模板类的实现!!!
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++ char_traits模板类的实现!!!相关的知识,希望对你有一定的参考价值。
本人写过与此相关的两篇博客,一个是<cstring>头文件的实现,还有一个是<cwchar>的实现。这里的char_traits模板类在此基础上实现。
为了方便。将源码一起封装于名字空间mystd里。
代码例如以下!!!
// 此文件命名为 "char_traits.h" // vs2012 调试通过 #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 } #ifdef __cplusplus MYSTD_BEGIN //cstring.h typedef std::size_t size_type; typedef unsigned char UCHAR; // C语言版本号,void * memchr(const 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++重载 { assert(pointer != 0); return (void*)mystd::memchr((const void*)pointer,val,num); // 转调 } 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) { // 对于memmove函数的实现,c++之父在《c++ 程序设计语言》(十周年中文纪念版第16章开篇) //就说过,此函数无法由c++语言本身达到最优实现,实际应用时还是用标准库吧! 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--) // 倒序复制 *--des = *--src; return destination; } inline void* memcpy(void *destination,const void *source, size_type num) { assert(destination != 0 && source != 0); return 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; else return *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 = destination + mystd::strlen(destination); while(*ptr++ = *source++); return destination; } inline char *strncat(char *destination,const char *source,size_type num) { assert(destination != 0 && source != 0); char *ptr = destination + mystd::strlen(destination); while(num-- && *source) *ptr++ = *source++; *ptr = 0; // null-character 复制 return destination; } inline char *strcpy(char *destination,const char *source) { assert(destination != 0 && source != 0); char *des = destination; while(*des++ = *source++); return destination; // null-character被复制 } inline char *strncpy(char *destination,const char *source,size_type num) { assert(destination != 0 && source != 0); char *des = destination; while(num--) *des++ = *source++; return destination; // null-character可能没有被复制 } 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-- && *str1 && *str1 == *str2) ++str1, ++str2; if(num == size_type(-1)) // 包括了num == 0的情况 return 0; else return *str1 - *str2; } //C语言仅仅有一个版本号 char* strchr(const char *, int); inline const char* strchr(const char *str,int character) { assert(str != 0); // 语言标准规定character 为int,这里转换一下 const char chr = *(char*)&character; while(*str && *str != chr) ++str; if(*str) return str; else return 0; } inline char* strchr(char *str,int character) //c++重载 { assert(str != 0); return (char*)mystd::strchr((const char*)str,character); } inline const char* strrchr(const char *str,int character) { //这里的character 可能包括null-character assert(str != 0); // 语言标准规定character 为int,这里转换一下 const char chr = *(char*)&character; size_type len = mystd::strlen(str); const char *ptr = str + len; if(chr == 0) return ptr; --ptr; while(len--) if(*ptr == chr) return ptr; else --ptr; return 0; //无匹配的字符 } inline char* strrchr(char *str,int character) { assert(str != 0); return (char*)mystd::strrchr((const char*)str,character); // 转调 } //c语言版本号char* strstr(const char *,const char*); inline const char* strstr(const char* str1,const char* str2) { assert(str1 != 0 && str2 != 0); size_type len_1 = mystd::strlen(str1); size_type len_2 = mystd::strlen(str2); if(len_1 < len_2) return 0; const char *search_last = str1 + (len_1 - len_2); while(str1 <= search_last) { if(mystd::strncmp(str1,str2,len_2) == 0) return str1; else ++str1; } return 0; } inline char* strstr(char *str1,const char *str2) //c++重载 { assert(str1 != 0 && str2 != 0); return (char*)mystd::strstr((const char*)str1,str2); } inline bool is_inside(const char *str,char chr) // 辅助函数,内部使用 { 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; while(*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; while(*str1 && !is_inside(str2,*str1)) ++count, ++str1; return count; } // c语言版本号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; else return str1; } inline char* strpbrk(char *str1,const char *str2) //c++重载 { assert(str1 != 0 && str2 != 0); return (char*)strpbrk((const char*)str1,str2); //转调 } inline char* strtok(char *str,const char *delim) { #ifdef _DEBUG static bool first_switch = false; if(!first_switch) assert(str != 0); assert(delim != 0); #endif static char * p_location = 0; //记录搜索起始位置 if(str) p_location = str; char *ptr = mystd::strpbrk(p_location,delim); char *temp = p_location; if(ptr == 0) // 找不到分隔符,默觉得搜索结束 { #ifdef _DEBUG first_switch = false; // 搜索结束。first_switch置为false #endif p_location = 0; // 搜索结束。p_location 复位 return temp; } #ifdef _DEBUG first_switch = true; #endif *ptr = 0; p_location = ptr + 1; // 位置更新 return temp; } inline size_type strxfrm(char *destination,const char *source,size_type num); inline int strcoll(const char *str1,const char *str2); inline char* strerror(int errnum); MYSTD_END // end of namespace mystd MYSTD_BEGIN //宽字符版本号 typedef std::size_t size_type; typedef wchar_t char_type; inline size_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 && source != 0); char_type *des = destination; while(num--) *des++ = *source++; return destination; // 可能不包括null wide character } inline int wcscmp(const char_type *wcs1,const char_type *wcs2) { assert(wcs1 != 0 && wcs2 != 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)) // 包括了num == 0的情况 return 0; else return *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); while(num-- && *ptr_1 == *ptr_2) ++ptr_1, ++ptr_2; if(num == size_type(-1)) return 0; else return *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 destination; 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--) // 倒序复制 *--des = *--src; return destination; } inline char_type* wmemcpy(char_type *destination,const char_type *source,size_type num) { assert(destination != 0 && source != 0); return mystd::wmemmove(destination,source,num); } inline bool w_is_inside(const char_type *wcs,char_type val) // 辅助函数。内部使用 { assert(wcs != 0); while(*wcs) { if(*wcs == val) return true; else ++wcs; } return false; } inline size_type wcsspn(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, ++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, ++wcs1; return count; } inline const char_type* wcsstr(const char_type *wcs1,const char_type *wcs2) { assert(wcs1 != 0 && wcs2 != 0); size_type 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 ++wcs1; } 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) ++wcs; if(*wcs) return wcs; else return 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可能为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; //无匹配的字符 } inline char_type* wcsrchr(char_type *wcs,char_type val) { //val可能为null wide character assert(wcs != 0); return (char_type*)mystd::wcsrchr((const char_type*)wcs,val); // 转调 } 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; else return 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 _DEBUG static bool first_switch = false; if(!first_switch) assert(wcs != 0); assert(delim != 0); #endif static char_type * p_location = 0; //记录搜索起始位置 if(wcs) p_location = wcs; char_type *ptr = mystd::wcspbrk(p_location,delim); char_type *temp = p_location; if(ptr == 0) // 找不到分隔符,默觉得搜索结束 { #ifdef _DEBUG first_switch = false; // 搜索结束,first_switch置为false #endif p_location = 0; // 搜索结束,p_location 复位 return temp; } #ifdef _DEBUG first_switch = true; #endif *ptr = 0; p_location = ptr + 1; // 位置更新 return temp; } inline size_type wcsxfrm(char_type *destination,const char_type *source,size_type num); MYSTD_END MYSTD_BEGIN typedef unsigned short wint_t; template<class charT> struct char_traits{ typedef std::size_t size_type; }; template<> // char特化 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); // 注意C风格字符串 } 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::memmove(des,src,num); // 标准库版本号效率更高 #endif } static char_type* copy(char_type *des,const char_type *src,size_type num) throw() { assert(des != 0 && src != 0); #ifdef _DEBUG return (char_type*)mystd::memcpy(des,src,num); #else return (char_type*)std::memcpy(des,src,num); // 标准库版本号效率更高 #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)) // 不依赖于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<> // 宽字符版本号 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,num); // 标准库版本号效率更高 #endif } static char_type* copy(char_type *des,const char_type *src,size_type num) throw() { assert(des != 0 && src != 0); #ifdef _DEBUG return (char_type*)mystd::wmemcpy(des,src,num); #else return (char_type*)std::wmemcpy(des,src,num); // 标准库版本号效率更高 #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 // MYSTD_CHAR_TRAITS_H
希望高手批评指正。!!
以上是关于c++ char_traits模板类的实现!!!的主要内容,如果未能解决你的问题,请参考以下文章
[C++][原创]std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)’未定义的引用