OSDN Git Service

* /include/bits/char_traits.h (class char_traits): Put all the
authoraustern <austern@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 Jul 2003 05:32:23 +0000 (05:32 +0000)
committeraustern <austern@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 Jul 2003 05:32:23 +0000 (05:32 +0000)
real work into the new class template __gnu_cxx::char_traits.
Gave generic definitions for member functions.  Types are taken
from the new class template __gnu_cxx::_Char_types.
* testsuite/21_strings/char_traits/requirements/short/1.cc: New
file.  Test of std::char_traits<short>, which serves as a test of
the char_traits primary template.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69772 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/char_traits.h
libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc [new file with mode: 0644]

index 75dcdcc..f2925d0 100644 (file)
@@ -1,3 +1,13 @@
+2003-07-24  Matt Austern  <austern@apple.com>
+
+       * /include/bits/char_traits.h (class char_traits): Put all the
+       real work into the new class template __gnu_cxx::char_traits.
+       Gave generic definitions for member functions.  Types are taken
+       from the new class template __gnu_cxx::_Char_types.
+       * testsuite/21_strings/char_traits/requirements/short/1.cc: New
+       file.  Test of std::char_traits<short>, which serves as a test of
+       the char_traits primary template.
+
 2003-07-24  Benjamin Kosnik  <bkoz@redhat.com>
 
        * testsuite/*: Change __gnu_cxx_test to __gnu_test.
index 8073694..23b69f3 100644 (file)
 #pragma GCC system_header
 
 #include <cstring>            // For memmove, memset, memchr
+#include <bits/stl_algobase.h>// For copy, lexicographical_compare, fill_n
 #include <bits/fpos.h>        // For streampos
 
-namespace std 
+namespace __gnu_cxx
 {
-  // 21.1
+
   /**
-   *  @brief  Basis for explicit traits specializations.
+   *  @brief  Mapping from character type to associated types.
+   * 
    *
-   *  @note  For any given actual character type, this definition is
-   *  probably wrong.
+   *  @note This is an implementation class for the generic version
+   *  of char_traits.  It defines int_type, off_type, pos_type, and
+   *  state_type.  By default these are unsigned long, streamoff,
+   *  streampos, and mbstate_t.  Users who need a different set of 
+   *  types, but who don't need to change the definitions of any function
+   *  defined in char_traits, can specialize __gnu_cxx::_Char_types
+   *  while leaving __gnu_cxx::char_traits alone. */
+  template <class _CharT>
+    struct _Char_types
+    {
+      typedef unsigned long   int_type;
+      typedef std::streampos  pos_type;
+      typedef std::streamoff  off_type;
+      typedef std::mbstate_t  state_type;
+    };
+
+
+  /**
+   *  @brief  Base class used to implement std::char_traits.
+   *
+   *  @note For any given actual character type, this definition is
+   *  probably wrong.  (Most of the member functions are likely to be
+   *  right, but the int_type and state_type typedefs, and the eof()
+   *  member function, are likely to be wrong.)  The reason this class
+   *  exists is so users can specialize it.  Classes in namespace std
+   *  may not be specialized for fundamentl types, but classes in
+   *  namespace __gnu_cxx may be.
    *
    *  See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
    *  for advice on how to make use of this class for "unusual" character
-   *  types. Also, check out include/ext/pod_char_traits.h.
-  */
-  template<class _CharT>
+   *  types. Also, check out include/ext/pod_char_traits.h.  */
+  template<typename _CharT>
     struct char_traits
     {
-      typedef _CharT           char_type;
-      typedef unsigned long    int_type;
-      typedef streampos        pos_type;
-      typedef streamoff        off_type;
-      typedef mbstate_t        state_type;
+      typedef _CharT                                    char_type;
+      typedef typename _Char_types<_CharT>::int_type    int_type;
+      typedef typename _Char_types<_CharT>::pos_type    pos_type;
+      typedef typename _Char_types<_CharT>::off_type    off_type;
+      typedef typename _Char_types<_CharT>::state_type  state_type;
       
       static void 
-      assign(char_type& __c1, const char_type& __c2);
+      assign(char_type& __c1, const char_type& __c2)
+      { __c1 = __c2; }
 
       static bool 
-      eq(const char_type& __c1, const char_type& __c2);
+      eq(const char_type& __c1, const char_type& __c2)
+      { return __c1 == __c2; }
 
       static bool 
-      lt(const char_type& __c1, const char_type& __c2);
+      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);
+      compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
 
-      static size_t
+      static std::size_t
       length(const char_type* __s);
 
       static const char_type* 
-      find(const char_type* __s, size_t __n, const char_type& __a);
+      find(const char_type* __s, std::size_t __n, const char_type& __a);
 
       static char_type* 
-      move(char_type* __s1, const char_type* __s2, size_t __n);
+      move(char_type* __s1, const char_type* __s2, std::size_t __n);
 
       static char_type* 
-      copy(char_type* __s1, const char_type* __s2, size_t __n);
+      copy(char_type* __s1, const char_type* __s2, std::size_t __n);
 
       static char_type* 
-      assign(char_type* __s, size_t __n, char_type __a);
+      assign(char_type* __s, std::size_t __n, char_type __a);
 
       static char_type 
-      to_char_type(const int_type& __c);
+      to_char_type(const int_type& __c)
+      { return static_cast<char_type>(__c); }
 
       static int_type 
-      to_int_type(const char_type& __c);
+      to_int_type(const char_type& __c)
+      { return static_cast<int_type>(__c); }
 
       static bool 
-      eq_int_type(const int_type& __c1, const int_type& __c2);
+      eq_int_type(const int_type& __c1, const int_type& __c2)
+      { return __c1 == __c2; }
 
       static int_type 
-      eof(); 
+      eof()
+      { return static_cast<int_type>(EOF); }
 
       static int_type 
-      not_eof(const int_type& __c);
+      not_eof(const int_type& __c)
+      { return !eq_int_type(__c, eof()) ? __c : char_type(); }
     };
 
+  template<typename _CharT>
+    int
+    char_traits<_CharT>::
+    compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
+    {
+      for (size_t __i = 0; __i < __n; ++__i)
+       if (lt(__s1[__i], __s2[__i]))
+         return -1;
+       else if (lt(__s2[__i], __s1[__i]))
+         return 1;
+      return 0;
+    }
+
+  template<typename _CharT>
+    std::size_t
+    char_traits<_CharT>::
+    length(const char_type* __p)
+    {
+      std::size_t __i = 0;
+      while (!eq(__p[__i], char_type()))
+        ++__i;
+      return __i;
+    }
+
+  template<typename _CharT>
+    const typename char_traits<_CharT>::char_type* 
+    char_traits<_CharT>::
+    find(const char_type* __s, std::size_t __n, const char_type& __a)
+    {
+      for (std::size_t __i = 0; __i < __n; ++__i)
+        if (eq(__s[__i], __a))
+          return __s + __i;
+      return 0;
+    }
+
+  template<typename _CharT>
+    typename char_traits<_CharT>::char_type*
+    char_traits<_CharT>::
+    move(char_type* __s1, const char_type* __s2, std::size_t __n)
+    {
+      return static_cast<_CharT*>(std::memmove(__s1, __s2,
+                                              __n * sizeof(char_type)));
+    }
+
+  template<typename _CharT>
+    typename char_traits<_CharT>::char_type* 
+    char_traits<_CharT>::
+    copy(char_type* __s1, const char_type* __s2, std::size_t __n)
+    {
+      std::copy(__s2, __s2 + __n, __s1);
+      return __s1;
+    }
+
+  template<typename _CharT>
+    typename char_traits<_CharT>::char_type* 
+    char_traits<_CharT>::
+    assign(char_type* __s, std::size_t __n, char_type __a)
+    {
+      std::fill_n(__s, __n, __a);
+      return __s;
+    }
+}
+
+namespace std 
+{
+  // 21.1
+  /**
+   *  @brief  Basis for explicit traits specializations.
+   *
+   *  @note  For any given actual character type, this definition is
+   *  probably wrong.  Since this is just a thin wrapper around
+   *  __gnu_cxx::char_traits, it is possible to achieve a more
+   *  appropriate definition by specializing __gnu_cxx::char_traits.
+   *
+   *  See http://gcc.gnu.org/onlinedocs/libstdc++/21_strings/howto.html#5
+   *  for advice on how to make use of this class for "unusual" character
+   *  types. Also, check out include/ext/pod_char_traits.h.
+  */
+  template<class _CharT>
+    struct char_traits
+      : public __gnu_cxx::char_traits<_CharT>
+    { };
+
 
   /// 21.1.3.1  char_traits specializations
   template<>
     struct char_traits<char>
     {
-      typedef char             char_type;
-      typedef int              int_type;
-      typedef streampos        pos_type;
-      typedef streamoff        off_type;
-      typedef mbstate_t        state_type;
+      typedef char              char_type;
+      typedef int               int_type;
+      typedef streampos         pos_type;
+      typedef streamoff         off_type;
+      typedef mbstate_t         state_type;
 
       static void 
       assign(char_type& __c1, const char_type& __c2)
@@ -185,11 +302,11 @@ namespace std
   template<>
     struct char_traits<wchar_t>
     {
-      typedef wchar_t          char_type;
-      typedef wint_t           int_type;
-      typedef streamoff        off_type;
-      typedef wstreampos       pos_type;
-      typedef mbstate_t        state_type;
+      typedef wchar_t           char_type;
+      typedef wint_t            int_type;
+      typedef streamoff         off_type;
+      typedef wstreampos        pos_type;
+      typedef mbstate_t         state_type;
       
       static void 
       assign(char_type& __c1, const char_type& __c2)
diff --git a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc
new file mode 100644 (file)
index 0000000..4a61942
--- /dev/null
@@ -0,0 +1,172 @@
+// 1999-06-03 bkoz
+// 2003-07-22 Matt Austern
+
+// Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 21.1.1 Character traits requirements
+// Make sure we can instantiate char_traits and basic_string for
+// charT = 'short', and make sure the char_traits memeber functions
+// satisfy the requirements of 21.1.1.
+
+#include <string>
+#include <testsuite_hooks.h>
+
+void test02(void)
+{
+  bool test = true;
+  // 21.1.1 character traits requirements
+
+  // Key for decoding what function signatures really mean:
+  // X                == char_traits<_CharT>
+  // [c,d]    == _CharT
+  // [p,q]    == const _CharT*
+  // s                == _CharT*
+  // [n,i,j]  == size_t
+  // f                == X::int_type
+  // pos      == X::pos_type
+  // state    == X::state_type
+
+  // void X::assign(short c, short d)
+  // assigns c = d;
+  short c1 = 'z';
+  short c2 = 'u';
+  VERIFY( c1 != c2 );
+  std::char_traits<short>::assign(c1,c2);
+  VERIFY( c1 == 'u' );
+
+  // bool X::eq(short c, short d)
+  c1 = 'z';
+  c2 = 'u';
+  VERIFY ( !std::char_traits<short>::eq(c1, c2) );
+  VERIFY ( std::char_traits<short>::eq(c1, c1) );
+  VERIFY ( std::char_traits<short>::eq(c2, c2) );
+
+  // bool X::lt(short c, short d)
+  c1 = 'z';
+  c2 = 'u';
+  VERIFY ( std::char_traits<short>::lt(c2, c1) );
+  VERIFY ( !std::char_traits<short>::lt(c1, c2) );
+  VERIFY ( !std::char_traits<short>::lt(c1, c1) );
+  VERIFY ( !std::char_traits<short>::lt(c2, c2) );
+
+  // short* X::move(short* s, const short* p, size_t n)
+  // for each i in [0,n) performs X::assign(s[i], p[i]). Copies
+  // correctly even where p is in [s, s + n), and yields s.   
+  short array1[] = {'z', 'u', 'm', 'a', ' ', 'b', 'e', 'a', 'c', 'h',  0};
+  const std::basic_string<short> str_01(array1 + 0, array1 + 10);
+
+  const short str_lit1[] = {'m', 'o', 'n', 't', 'a', 'r', 'a', ' ', 'a', 'n', 'd', ' ', 'o', 'c', 'e', 'a', 'n', ' ', 'b', 'e', 'a', 'c', 'h', 0};
+
+  int len = sizeof(str_lit1)/sizeof(short) + sizeof(array1)/sizeof(short) - 1;
+  // two terminating chars
+  short array2[len];
+
+  VERIFY( str_lit1[0] == 'm' );
+  c1 = array2[0];
+  c2 = str_lit1[0];
+  short c3 = array2[1];
+  short c4 = str_lit1[1];
+  std::char_traits<short>::move(array2, str_lit1, 0);
+  VERIFY( array2[0] == c1 );
+  VERIFY( str_lit1[0] == c2 );
+  std::char_traits<short>::move(array2, str_lit1, 1);
+  VERIFY( array2[0] == c2 );
+  VERIFY( str_lit1[0] == c2 );
+  VERIFY( array2[1] == c3 );
+  VERIFY( str_lit1[1] == c4 );
+  std::char_traits<short>::move(array2, str_lit1, 2);
+  VERIFY( array2[0] == c2 );
+  VERIFY( str_lit1[0] == c2 );
+  VERIFY( array2[1] == c4 );
+  VERIFY( str_lit1[1] == c4 );
+  short* pc1 = array1 + 1;
+  c1 = pc1[0];
+  c2 = array1[0];
+  VERIFY( c1 != c2 );
+  short* pc2 = std::char_traits<short>::move(array1, pc1, 0);
+  c3 = pc1[0];
+  c4 = array1[0];
+  VERIFY( c1 == c3 );
+  VERIFY( c2 == c4 );
+  VERIFY( pc2 == array1 );
+
+  c1 = pc1[0];
+  c2 = array1[0];
+  short* pc3 = pc1;
+  pc2 = std::char_traits<short>::move(array1, pc1, 10);
+  c3 = pc1[0];
+  c4 = array1[0];
+  VERIFY( c1 != c3 ); // underlying short array changed.
+  VERIFY( c4 != c3 );
+  VERIFY( pc2 == array1 );
+  VERIFY( pc3 == pc1 ); // but pointers o-tay
+  c1 = *(str_01.data());
+  c2 = array1[0];
+  VERIFY( c1 != c2 );
+
+  // size_t X::length(const short* p)
+  len = std::char_traits<short>::length(str_lit1);
+  VERIFY( len == sizeof(str_lit1) / sizeof(short) - 1 );
+
+  // const short* X::find(const short* s, size_t n, short c)
+  const int N4 = sizeof(str_lit1) / sizeof(short);
+  const short* pc4 = std::char_traits<short>::find(str_lit1, N4, 'a');
+  VERIFY( pc4 != 0 );
+  VERIFY( *pc4 == 'a' );
+
+  pc4 = std::char_traits<short>::find(str_lit1, N4, 0x0a73);
+  VERIFY( pc4 == 0 );
+
+  // short* X::assign(short* s, size_t n, short c)
+  len = sizeof(array2) / sizeof(short);
+  memset(array2, 0xaf, len * sizeof(short));
+  VERIFY( array2[0] != 0x15a8 );
+
+  pc1 = std::char_traits<short>::assign (array2, len, 0x15a8);
+  VERIFY( pc1 == array2 );
+  for (int i = 0; i < len; ++i)
+    VERIFY( array2[i] == 0x15a8 );
+
+  // short* X::copy(short* s, const short* p, size_t n)
+  int n1 = sizeof(str_lit1) / sizeof(short);
+  pc1 = std::char_traits<short>::copy(array2, str_lit1, n1);
+  len = std::char_traits<short>::length(array2);
+  VERIFY( len == n1 - 1 );
+  for (int i = 0; i < len; ++i)
+    VERIFY( str_lit1[i] == array2[i] );
+
+  // int X::compare(const short* p, const short* q, size_t n)
+  const short* pconst1 = str_01.data();
+  const short* pconst2 = str_lit1;
+
+  VERIFY( std::char_traits<short>::compare(pconst1, pconst2, 10) > 0 );
+  VERIFY( std::char_traits<short>::compare(pconst2, pconst1, 10) < 0 );
+  VERIFY( std::char_traits<short>::compare(pconst1, pconst1, 10) == 0 );
+  VERIFY( std::char_traits<short>::compare(pconst2, pconst2, 10) == 0 );
+}
+
+
+
+int main()
+{ 
+  test02();
+  return 0;
+}