This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
char_traits<wchar_t> patch
- To: libstdc++ at sourceware dot cygnus dot com
- Subject: char_traits<wchar_t> patch
- From: Steven King <sxking at uswest dot net>
- Date: Fri, 28 Apr 2000 16:29:55 -0700
- Organization: is the root of all evil
- Reply-To: sxking at uswest dot net
As the standard requires the wide char string utility functions, I made the
char_traits functions use those, which should correct the undefined behavior in
find. Also added char_traits<wchar_t> to the testsuite.
2000-04-28 Steven King <sxking@uswest.net>
* bits/char_traits.h: use wchar_t utility functions for
char_traits<wchar_t> methods.
* testsuite/21_string/char_traits.cc: New (test02): test
char_traits<wchar_t>
*** libstdc++-v3/bits/char_traits.h.orig Fri Apr 21 13:33:28 2000
--- libstdc++-v3/bits/char_traits.h Fri Apr 28 15:19:01 2000
***************
*** 241,288 ****
static int
compare(const char_type* __s1, const char_type* __s2, int_type __n)
! {
! for (int_type __i = 0; __i < __n; ++__i)
! if (!eq(__s1[__i], __s2[__i]))
! return lt(__s1[__i], __s2[__i]) ? -1 : 1;
! return 0;
! }
static size_t
length(const char_type* __s)
! {
! const char_type* __p = __s;
! while (*__p)
! ++__p;
! return (__p - __s);
! }
static const char_type*
find (const char_type* __s, int __n, const char_type& __a)
! {
! for (const char_type* __p = __s; __p < __s+__n; ++__p)
! if (*__p == __a)
! return __p;
! return 0;
! }
static char_type*
move(char_type* __s1, const char_type* __s2, int_type __n)
! { return static_cast<wchar_t*>(memmove(__s1, __s2,
! __n * sizeof(wchar_t))); }
static char_type*
copy(char_type* __s1, const char_type* __s2, int_type __n)
! { return static_cast<wchar_t*>(memcpy(__s1, __s2,
! __n * sizeof(wchar_t))); }
static char_type*
assign(char_type* __s, int_type __n, char_type __a)
! {
! for (char_type* __p = __s; __p < __s + __n; ++__p)
! assign(*__p, __a);
! return __s;
! }
static char_type
to_char_type(const int_type& __c) { return char_type(__c); }
--- 241,267 ----
static int
compare(const char_type* __s1, const char_type* __s2, int_type __n)
! { return wmemcmp(__s1, __s2, __n); }
static size_t
length(const char_type* __s)
! { return wcslen (__s); }
static const char_type*
find (const char_type* __s, int __n, const char_type& __a)
! { return wmemchr(__s, __a, __n); }
static char_type*
move(char_type* __s1, const char_type* __s2, int_type __n)
! { return wmemmove(__s1, __s2, __n); }
static char_type*
copy(char_type* __s1, const char_type* __s2, int_type __n)
! { return wmemcpy(__s1, __s2, __n); }
static char_type*
assign(char_type* __s, int_type __n, char_type __a)
! { return wmemset(__s, __a, __n); }
static char_type
to_char_type(const int_type& __c) { return char_type(__c); }
*** libstdc++-v3/testsuite/21_strings/char_traits.cc.orig Fri Apr 28 16:24:08 2000
--- libstdc++-v3/testsuite/21_strings/char_traits.cc Fri Apr 28 15:34:19 2000
***************
*** 110,119 ****
--- 110,205 ----
return test;
}
+ int test02(void)
+ {
+ bool test = true;
+ const std::wstring str_01(L"zuma beach");
+ const std::wstring str_02(L"montara and ocean beach");
+
+ // 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(wchar_t c, wchar_t d)
+ // assigns c = d;
+ wchar_t c1 = L'z';
+ wchar_t c2 = L'u';
+ test &= c1 != c2;
+ std::char_traits<wchar_t>::assign(c1,c2);
+ test &= c1 == L'u';
+
+ // char* X::move(char* s, const char* 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.
+ wchar_t array1[] = {L'z', L'u', L'm', L'a', L' ', L'b', L'e', L'a', L'c', L'h', 0};
+ const wchar_t str_lit1[] = L"montara and ocean beach";
+ int len = sizeof(str_lit1) + sizeof(array1) - 1; // two terminating chars
+ wchar_t array2[len];
+
+ test &= str_lit1[0] == 'm';
+ c1 = array2[0];
+ c2 = str_lit1[0];
+ wchar_t c3 = array2[1];
+ wchar_t c4 = str_lit1[1];
+ std::char_traits<wchar_t>::move(array2, str_lit1, 0);
+ test &= array2[0] == c1;
+ test &= str_lit1[0] == c2;
+ std::char_traits<wchar_t>::move(array2, str_lit1, 1);
+ test &= array2[0] == c2;
+ test &= str_lit1[0] == c2;
+ test &= array2[1] == c3;
+ test &= str_lit1[1] == c4;
+ std::char_traits<wchar_t>::move(array2, str_lit1, 2);
+ test &= array2[0] == c2;
+ test &= str_lit1[0] == c2;
+ test &= array2[1] == c4;
+ test &= str_lit1[1] == c4;
+
+ wchar_t* pc1 = array1 + 1;
+ c1 = pc1[0];
+ c2 = array1[0];
+ test &= c1 != c2;
+ wchar_t* pc2 = std::char_traits<wchar_t>::move(array1, pc1, 0);
+ c3 = pc1[0];
+ c4 = array1[0];
+ test &= c1 == c3;
+ test &= c2 == c4;
+ test &= pc2 == array1;
+
+ c1 = pc1[0];
+ c2 = array1[0];
+ wchar_t* pc3 = pc1;
+ pc2 = std::char_traits<wchar_t>::move(array1, pc1, 10);
+ c3 = pc1[0];
+ c4 = array1[0];
+ test &= c1 != c3; // underlying wchar_t array changed.
+ test &= c4 != c3;
+ test &= pc2 == array1;
+ test &= pc3 == pc1; // but pointers o-tay
+ c1 = *(str_01.data());
+ c2 = array1[0];
+ test &= c1 != c2;
+
+
+ #ifdef DEBUG_ASSERT
+ assert(test);
+ #endif
+
+ return test;
+ }
int main()
{
test01();
+ test02();
}
--
Steven King
sxking@uswest.net