zoukankan      html  css  js  c++  java
  • 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


    希望高手批评指正。!!








  • 相关阅读:
    Asp.Net细节性问题精萃(转)
    开发OFFICE插件总结(转)
    校内网开心网数据同步引发的讨论(转)
    C++指针探讨 (三) 成员函数指针 (转)
    C++指针探讨 (二) 函数指针 (转)
    【原创】编程获取PE文件信息的方法(转)
    为.net开发者提供的一份关于存储过程的评论(转)
    C++指针探讨 (一)数据指针 (转)
    如何批量修改PPT字体、大小、颜色(转)
    搜索引擎里的爱人(转)
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5184588.html
Copyright © 2011-2022 走看看