Specializations of std::char_traits

Pétur Runólfsson peturr02@ru.is
Thu Jul 17 09:39:00 GMT 2003


Gabriel Dos Res wrote:
>We may use a suggestion made on the the LWG reflector:  define
>char_traits as
>
>   template<typename charT>
>      struct char_traits : __gnu_cxx::char_traits<charT> { };
>
>Users can specialize __gnu_cxx::char_traits<> at will on fundamental
>types.  We may provide a definition for the primary template
>__gnu_cxx::char_traits<>.  This we don't create the confusion that
>users can specialize std::templates on fundamental types.
>Comments?

Benjamin Kosnik wrote:
>I like this approach too.

Me too.

>Perhaps this is the time for some code...

I just happened to have this lying around:

  template<class T>
    struct char_traits
    {
      typedef T 		char_type;
      
      static void 
      assign(char_type& __c1, const char_type& __c2)
      { __c1 = __c2; }

      static bool 
      eq(const char_type& __c1, const char_type& __c2)
      { return __c1 == __c2; }

      static bool 
      lt(const char_type& __c1, const char_type& __c2)
      { return __c1 < __c2; }

      static int 
      compare(const char_type* __s1, const char_type* __s2, size_t __n)
      {
        while (__n--)
          {
            if (*__s1 < *__s2)
              return -1;
            else if (*__s1 > *__s2)
              return +1;

            ++__s1;
            ++__s2;
          }
        return 0;
      }

      static size_t
      length(const char_type* __s)
      {
        size_t __ret = 0;
        while (*__s++)
          ++__ret;
        return __ret;
      }

      static const char_type* 
      find(const char_type* __s, size_t __n, const char_type& __a)
      {
        while (__n--)
          {
            if (*__s == __a)
              return __s;
            ++__s;
          }
        return 0;
      }

      static char_type* 
      move(char_type* __s1, const char_type* __s2, size_t __n)
      {
        memmove(__s1, __s2, __n * sizeof(T));
        return __s1;
      }

      static char_type* 
      copy(char_type* __s1, const char_type* __s2, size_t __n)
      {
        memcpy(__s1, __s2, __n * sizeof(T));
        return __s1;
      }

      static char_type* 
      assign(char_type* __s, size_t __n, char_type __a)
      {
        char_type* __ret = __s;
        while (__n--)
          *__s++ = __a;
        return __ret;
      }
  };

move and copy can easily be written inline if non-POD types should
be supported.

This also means that enabling wstring support on Cygwin, and perhaps
other platforms is this close:

Index: stringfwd.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/stringfwd.h,v
retrieving revision 1.9
diff -c -3 -p -r1.9 stringfwd.h
*** stringfwd.h 5 Jul 2003 04:05:36 -0000       1.9
--- stringfwd.h 17 Jul 2003 09:26:00 -0000
*************** namespace std
*** 61,69 ****

  #ifdef _GLIBCXX_USE_WCHAR_T
    template<> struct char_traits<wchar_t>;

    typedef basic_string<wchar_t> wstring;
- #endif
  } // namespace std

  #endif        // _STRINGFWD_H
--- 61,69 ----

  #ifdef _GLIBCXX_USE_WCHAR_T
    template<> struct char_traits<wchar_t>;
+ #endif

    typedef basic_string<wchar_t> wstring;
  } // namespace std

  #endif        // _STRINGFWD_H

Petur



More information about the Libstdc++ mailing list