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


希望高手批评指正!!!








阅读更多
换一批

没有更多推荐了,返回首页