前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >c++ char_traits模板类的实现!!!

c++ char_traits模板类的实现!!!

作者头像
用户7886150
修改2021-02-25 10:19:59
7980
修改2021-02-25 10:19:59
举报
文章被收录于专栏:bit哲学院

参考链接: C++ wmemcpy()

本人写过与此相关的两篇博客,一个是<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

希望高手批评指正!!!

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档