From stdcxx-dev-return-1045-apmail-incubator-stdcxx-dev-archive=incubator.apache.org@incubator.apache.org Tue Mar 07 16:37:36 2006 Return-Path: Delivered-To: apmail-incubator-stdcxx-dev-archive@www.apache.org Received: (qmail 55034 invoked from network); 7 Mar 2006 16:37:36 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 7 Mar 2006 16:37:36 -0000 Received: (qmail 19807 invoked by uid 500); 7 Mar 2006 16:37:36 -0000 Delivered-To: apmail-incubator-stdcxx-dev-archive@incubator.apache.org Received: (qmail 19792 invoked by uid 500); 7 Mar 2006 16:37:36 -0000 Mailing-List: contact stdcxx-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-dev@incubator.apache.org Received: (qmail 19781 invoked by uid 99); 7 Mar 2006 16:37:36 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Mar 2006 08:37:36 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: domain of AntonP@moscow.vdiweb.com designates 195.210.189.132 as permitted sender) Received: from [195.210.189.132] (HELO exmsk.moscow.vdiweb.com) (195.210.189.132) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Mar 2006 08:37:35 -0800 Received: from [10.11.0.125] ([10.11.0.125]) by exmsk.moscow.vdiweb.com with Microsoft SMTPSVC(6.0.3790.1830); Tue, 7 Mar 2006 19:36:52 +0300 Message-ID: <440DB6A3.7060701@moscow.vdiweb.com> Date: Tue, 07 Mar 2006 19:36:51 +0300 From: Anton Pevtsov User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7) Gecko/20040514 X-Accept-Language: en-us, en MIME-Version: 1.0 To: stdcxx-dev@incubator.apache.org Subject: test for 21.string::erase Content-Type: multipart/mixed; boundary="------------020304070203040408080709" X-OriginalArrivalTime: 07 Mar 2006 16:36:52.0365 (UTC) FILETIME=[56B59BD0:01C64205] X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N --------------020304070203040408080709 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit The attached file contains the test for 21.string::erase. Here I used classes from the rw_char.h header. I plan to extend this test with UserChar, but there is a problem with the formatting output of the strings with UserChar's. Does the %{#*S} directive support the strings of UserChars'? With best wishes, Anton Pevtsov --------------020304070203040408080709 Content-Type: text/plain; name="21.string.erase.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="21.string.erase.cpp" /*************************************************************************** * * erase.cpp - string test exercising [lib.string::erase] * and the lifetime of iterators and references * * $Id: //stdlib/dev/tests/stdlib/string/erase.cpp#13 $ * *************************************************************************** * * Copyright 2006 The Apache Software Foundation or its licensors, * as applicable. * * Copyright 2006 Rogue Wave Software. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **************************************************************************/ #include #include #include #include #include #include /**************************************************************************/ struct MemFun { enum charT { Char, WChar }; enum Traits { DefaultTraits, UserTraits }; enum FunTag { // which erase function version to exercise erase, erase_iters }; MemFun (charT cid, const char *cname, Traits tid, const char *tname) : cid_ (cid), tid_ (tid), mfun_ (), cname_ (cname), tname_ (tname), aname_ ("allocator"), fname_ ("erase") { /* empty */ } charT cid_; // character type id (char or wchar_t) Traits tid_; // traits type id (default or user-defined) FunTag mfun_; // member function id const char *cname_; // character type name const char *tname_; // traits name const char *aname_; // allocator name const char *fname_; // function name }; static const int long_string_len = 4096; static char long_string [long_string_len]; /**************************************************************************/ template void widen (charT *buf, const char *str, const std::size_t str_len) { typedef unsigned char UChar; buf[0] = charT (UChar ('\0')); RW_ASSERT (str_len < sizeof long_string); if (str) { for (std::size_t i = 0; i < str_len; i++) buf[i] = charT (UChar (str[i])); } } /**************************************************************************/ template void test_erase (charT, Traits, MemFun* pfid, int line, const char *str, std::size_t str_len, int pos, int cnt, const char *res, std::size_t res_len, bool should_throw) { typedef std::allocator Allocator; typedef std::basic_string TestString; if (!rw_enabled (line)) { rw_note (0, 0, 0, "test on line %d disabled", line); return; } // widen the source sequence into the (possibly wide) character buffer static charT wstr [long_string_len]; widen (wstr, str, str_len); static charT wres [long_string_len]; if (0 != res) widen (wres, res, res_len); charT* pwres = 0 == str ? 0 : wres; TestString str_ob(wstr, str_len); TestString str_def; TestString* pstr = 0 != str ? &str_ob : &str_def; TestString& s_res = *pstr; #ifndef _RWSTD_NO_EXCEPTIONS const char* const expected = should_throw ? "out_of_range" : 0; const char* caught = 0; try { #endif // _RWSTD_NO_EXCEPTIONS s_res = -1 == pos ? pstr->erase () : -1 == cnt ? pstr->erase(pos) : pstr->erase (pos, cnt); #define CALLFMAT \ "line %d. basic_string<%s, %s<%2$s>, %s<%2$s>>(%#s)" \ ".erase(%{?}%zu%{;}%{?}, %zu%{;}))" #define CALLARGS \ __LINE__, pfid->cname_, pfid->tname_, pfid->aname_, \ str, -1 != pos, pos, -1 != cnt, cnt #ifndef _RWSTD_NO_EXCEPTIONS } catch (std::out_of_range e) { _RWSTD_UNUSED (e); caught = expected; } catch (...) { caught = "unknown exception"; } rw_assert (caught == expected, 0, line, CALLFMAT " %{?}expected %s, caught %s" "%{:}unexpectedly caught %s%{;}", CALLARGS, 0 != expected, expected, caught, caught); if (should_throw || caught) return; #else // if defined (_RWSTD_NO_EXCEPTIONS) _RWSTD_UNUSED (should_throw); #endif // _RWSTD_NO_EXCEPTIONS std::string::size_type res_sz = pstr->size(); // verify the returned value rw_assert (s_res == *pstr, 0, line, CALLFMAT " != *this", CALLARGS); // check the results bool success = res_len == res_sz; rw_assert (success, 0, line, CALLFMAT " : size() == %zu, expected %zu", CALLARGS, res_sz, res_len); if (0 == res_sz) return; success = !TestString::traits_type::compare (pstr->c_str(), pwres, res_sz); rw_assert (success, 0, line, CALLFMAT " : got %{#*S}, expected %#s", CALLARGS, int (sizeof (charT)), pstr, res); } /**************************************************************************/ template void test_erase_iters (charT, Traits, MemFun* pfid, int line, const char *str, std::size_t str_len, int first, int last, const char *res, std::size_t res_len, bool should_throw) { typedef std::allocator Allocator; typedef std::basic_string TestString; _RWSTD_UNUSED (should_throw); if (!rw_enabled (line)) { rw_note (0, 0, 0, "test on line %d disabled", line); return; } // widen the source sequence into the (possibly wide) character buffer static charT wstr [long_string_len]; widen (wstr, str, str_len); static charT wres [long_string_len]; if (0 != res) widen (wres, res, res_len); charT* pwres = 0 == str ? 0 : wres; TestString str_ob(wstr, str_len); TestString str_def; TestString* pstr = 0 != str ? &str_ob : &str_def; typename TestString::iterator it_first (pstr->begin() + first); typename TestString::iterator it_last (-1 == last ? it_first : std::size_t (last) == str_len ? pstr->end() : pstr->begin() + last); std::string::size_type sz = pstr->size(); const int f_diff = it_first - pstr->begin(); const int l_diff = it_last - pstr->begin(); typename TestString::iterator it_res = -1 == last ? pstr->erase (it_first) : pstr->erase (it_first, it_last); const typename TestString::iterator begin = pstr->begin(); const typename TestString::iterator end = pstr->end(); const std::string::size_type res_sz = pstr->size(); #undef CALLFMAT #define CALLFMAT \ "line %d. basic_string<%s, %s<%2$s>, %s<%2$s>>(%#s)" \ ".erase(begin + %td%{?}, begin + %td%{;}) " #undef CALLARGS #define CALLARGS \ __LINE__, pfid->cname_, pfid->tname_, pfid->aname_, \ str, f_diff, -1 != last, l_diff bool success = begin <= it_res && it_res <= end; rw_assert (success, 0, line, CALLFMAT "returned invalid iterator, " "difference with begin is %td", CALLARGS, it_res - begin); std::size_t idx = -1 == last ? std::size_t (first + 1) : std::size_t (last); if (idx == sz) { rw_assert (it_res == end, 0, line, CALLFMAT " != end()", CALLARGS); } else { rw_assert (*it_res == wstr[idx], 0, line, CALLFMAT "== %#c, expected %#c", CALLARGS, *it_res, str[idx]); } // check the results rw_assert (res_len == res_sz, 0, line, CALLFMAT " : size() == %zu, expected %zu", CALLARGS, res_sz, res_len); if (0 == res_sz) return; success = !TestString::traits_type::compare (pstr->c_str(), pwres, res_sz); rw_assert (success, 0, line, CALLFMAT ": got %{#*S}, expected %#s", CALLARGS, int (sizeof (charT)), pstr, res); } /**************************************************************************/ void test_erase (MemFun *pfid, int line, const char *str, std::size_t str_len, int pos, int npos, const char *res, std::size_t res_len, bool should_throw) { #undef TEST #define TEST(charT, Traits) \ MemFun::erase == pfid->mfun_ ? \ test_erase (charT (), Traits (), pfid, line, \ str, str_len, pos, npos, res, res_len, should_throw) \ : test_erase_iters (charT (), Traits (), pfid, line, \ str, str_len, pos, npos, res, res_len, should_throw) if (!rw_enabled (line)) { rw_note (0, 0, __LINE__, "test on line %d disabled", line); return; } if (MemFun:: DefaultTraits == pfid->tid_) { if (MemFun::Char == pfid->cid_) TEST (char, std::char_traits); #ifndef _RWSTD_NO_WCHAR_T else TEST (wchar_t, std::char_traits); #endif // _RWSTD_NO_WCHAR_T } else { if (MemFun::Char == pfid->cid_) TEST (char, UserTraits); #ifndef _RWSTD_NO_WCHAR_T else TEST (wchar_t, UserTraits); #endif // _RWSTD_NO_WCHAR_T } } /**************************************************************************/ void test_erase (MemFun *pfid) { rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::" "erase (size_type pos, size_type n)", pfid->cname_, pfid->tname_, pfid->aname_); pfid->mfun_ = MemFun::erase; #undef TEST #define TEST(str, pos, cnt, res, should_throw) \ test_erase (pfid, __LINE__, str, sizeof str - 1, \ pos, cnt, res, sizeof res - 1, should_throw) // +--------------------------------------- controlled sequence // | +----------------------- erase() pos argument // | | +-- erase() n argument // | | | +-- expected result sequence // | | | | +-- exception // | | | | | expected? // V V V V V TEST (0, 0, 0, "", false); TEST ("", 0, 0, "", false); TEST ("\0", -1, -1, "", false); TEST ("\0", 0, 1, "", false); TEST ("abc", -1, -1, "", false); TEST ("abc", 0, -1, "", false); TEST ("abc", 0, 1, "bc", false); TEST ("abc", 1, 1, "ac", false); TEST ("abc", 2, 1, "ab", false); TEST ("abc", 0, 2, "c", false); TEST ("abc", 1, 2, "a", false); TEST ("t\000 s", 0, 1, "\0 s", false); TEST ("t\000 s", 1, 1, "t s", false); TEST ("t\000 s", 2, 2, "t\0", false); TEST ("t\000 s", 1, 2, "ts", false); TEST ("t\000 s", 0, 2, " s", false); TEST ("t\000 s", -1, -1, "", false); TEST ("\0a\0b", 0, 3, "b", false); TEST ("\0a\0b", 1, 1, "\0\0b", false); TEST ("\0a\0b", 3, 1, "\0a\0", false); TEST ("a\0\0\0b", 1, 3, "ab", false); TEST ("a\0\0\0b", 0, 1, "\0\0\0b", false); TEST ("a\0\0\0b", 2, -1, "a\0", false); TEST ("a\0b\0\0c", -1, -1, "", false); TEST ("a\0b\0\0c", 0, 2, "b\0\0c", false); TEST ("a\0b\0\0c", 1, 2, "a\0\0c", false); TEST ("test string", 1, 3, "t string", false); TEST ("Test\0string", 0, 2, "st\0string", false); TEST ("Test\0string", 1, 4, "Tstring", false); TEST ("Test\0string", 1, -1, "T", false); #ifndef _RWSTD_NO_EXCEPTIONS TEST ("\0", 2, 1, "\0", true); TEST ("a", 2, 1, "a", true); TEST (long_string, long_string_len + 1, 1, long_string, true); #endif // _RWSTD_NO_EXCEPTIONS #undef TEST #define TEST(str, pos, cnt, res, res_len, should_throw) \ test_erase (pfid, __LINE__, str, sizeof str - 1, \ pos, cnt, res, res_len, should_throw) // +--------------------------------------- controlled sequence // | +------------------------- erase() pos argument // | | +-------------------- erase() n argument // | | | +-- expected result sequence // | | | | +-- result length // | | | | | +-- exception // | | | | | | expected? // V V V V V V TEST (long_string, -1, -1, "", 0, false); TEST (long_string, 0, -1, "", 0, false); TEST (long_string, 0, long_string_len - 1, "", 0, false); TEST (long_string, 0, long_string_len - 2, "x", 1, false); TEST (long_string, 1, long_string_len - 2, "x", 1, false); TEST (long_string, 1, long_string_len - 3, "xx", 2, false); TEST (long_string, 0, 1, (long_string + 1), long_string_len - 2, false); TEST (long_string, long_string_len - 2, 1, (long_string + 1), long_string_len - 2, false); } void test_erase_iters (MemFun *pfid) { rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::" "erase (iterator p)", pfid->cname_, pfid->tname_, pfid->aname_); pfid->mfun_ = MemFun::erase_iters; #undef TEST #define TEST(str, first, res) \ test_erase (pfid, __LINE__, str, sizeof str - 1, \ first, -1, res, sizeof res - 1, false) // +--------------------------------------- controlled sequence // | +----------------------- erase() "p" argument // | | +-------------------- expected result sequence // | | | // | | | // | | | // V V V TEST ("\0", 0, ""); TEST ("s", 0, ""); TEST ("abc", 0, "bc"); TEST ("abc", 1, "ac"); TEST ("abc", 2, "ab"); TEST ("t\000 s", 0, "\0 s"); TEST ("t\000 s", 1, "t s"); TEST ("t\000 s", 2, "t\0s"); TEST ("\0a\0b", 0, "a\0b"); TEST ("\0a\0b", 1, "\0\0b"); TEST ("\0a\0b", 3, "\0a\0"); TEST ("a\0\0\0b", 1, "a\0\0b"); TEST ("a\0\0\0b", 0, "\0\0\0b"); TEST ("a\0b\0\0c", 0, "\0b\0\0c"); TEST ("a\0b\0\0c", 1, "ab\0\0c"); TEST ("Test\0string", 1, "Tst\0string"); TEST ("Test\0string", 4, "Teststring"); #undef TEST #define TEST(str, first, res, res_len) \ test_erase (pfid, __LINE__, str, sizeof str - 1, \ first, -1, res, res_len, false) TEST (long_string, 0, (long_string + 1), long_string_len - 2); TEST (long_string, long_string_len - 2, (long_string + 1), long_string_len - 2); } void test_erase_iters2 (MemFun *pfid) { rw_info (0, 0, 0, "std::basic_string<%s, %s<%1$s>, %s<%1$s>>::" "erase (iterator first, iterator last)", pfid->cname_, pfid->tname_, pfid->aname_); pfid->mfun_ = MemFun::erase_iters; #undef TEST #define TEST(str, first, last, res) \ test_erase (pfid, __LINE__, str, sizeof str - 1, \ first, last, res, sizeof res - 1, false) // +--------------------------------------- controlled sequence // | +----------------------- erase() "first" argument // | | +------------------- erase() "last" argument // | | | +---------------- expected result sequence // | | | | // | | | | // V V V V TEST (0, 0, 0, ""); TEST ("", 0, 0, ""); TEST ("\0", 0, 1, ""); TEST ("abc", 0, 1, "bc"); TEST ("abc", 1, 2, "ac"); TEST ("abc", 2, 3, "ab"); TEST ("abc", 0, 2, "c"); TEST ("abc", 1, 3, "a"); TEST ("abc", 0, 3, ""); TEST ("t\000 s", 0, 1, "\0 s"); TEST ("t\000 s", 1, 2, "t s"); TEST ("t\000 s", 2, 4, "t\0"); TEST ("t\000 s", 1, 3, "ts"); TEST ("t\000 s", 0, 2, " s"); TEST ("t\000 s", 0, 4, ""); TEST ("\0a\0b", 0, 3, "b"); TEST ("\0a\0b", 1, 2, "\0\0b"); TEST ("\0a\0b", 3, 4, "\0a\0"); TEST ("a\0\0\0b", 1, 4, "ab"); TEST ("a\0\0\0b", 0, 1, "\0\0\0b"); TEST ("a\0b\0\0c", 0, 2, "b\0\0c"); TEST ("a\0b\0\0c", 1, 3, "a\0\0c"); TEST ("test string", 1, 4, "t string"); TEST ("Test\0string", 0, 2, "st\0string"); TEST ("Test\0string", 1, 5, "Tstring"); TEST ("Test\0string", 0, 4, "\0string"); TEST ("Test\0string", 0, 5, "string"); TEST ("Test\0string", 0, 11, ""); #undef TEST #define TEST(str, first, last, res, res_len) \ test_erase (pfid, __LINE__, str, sizeof str - 1, \ first, last, res, res_len, false) // +--------------------------------------- controlled sequence // | +-------------------------- erase() "first" argument // | | +----------------------- erase() "last" argument // | | | +---- expected result sequence // | | | | +-- result length // | | | | | // V V V V V TEST (long_string, 0, long_string_len - 1, "", 0); TEST (long_string, 0, long_string_len - 2, "x", 1); TEST (long_string, 1, long_string_len - 1, "x", 1); TEST (long_string, 1, long_string_len - 2, "xx", 2); TEST (long_string, 0, 1, (long_string + 1), long_string_len - 2); TEST (long_string, long_string_len - 2, long_string_len - 1, (long_string + 1), long_string_len - 2); } /**************************************************************************/ static int rw_opt_no_char_traits; // for --no-char_traits static int rw_opt_no_user_traits; // for --no-user_traits /**************************************************************************/ static void run_test (MemFun *pfid) { if (pfid->tname_ && rw_opt_no_user_traits) { rw_note (1 < rw_opt_no_user_traits++, 0, 0, "user defined traits test disabled"); } else if (!pfid->tname_ && rw_opt_no_char_traits) { rw_note (1 < rw_opt_no_char_traits++, 0, 0, "char_traits test disabled"); } else { test_erase (pfid); test_erase_iters (pfid); test_erase_iters2 (pfid); } } /**************************************************************************/ int run_test (int, char*[]) { if ('\0' == long_string [0]) { // initialize long_string for (std::size_t i = 0; i != sizeof long_string - 1; ++i) long_string [i] = 'x'; } if (rw_enabled ("char")) { MemFun fid (MemFun::Char, "char", MemFun::DefaultTraits, 0); fid.tname_ = "char_traits"; run_test (&fid); fid.tid_ = MemFun::UserTraits; fid.tname_ = "UserTraits"; run_test (&fid); } else rw_note (0, 0, 0, "string::erase char tests disabled"); if (rw_enabled ("wchar_t")) { MemFun fid (MemFun::WChar, "wchar_t", MemFun::DefaultTraits, 0); fid.tname_ = "char_traits"; run_test (&fid); fid.tid_ = MemFun::UserTraits; fid.tname_ = "UserTraits"; run_test (&fid); } else rw_note (0, 0, 0, "string::erase wchar tests disabled"); return 0; } /**************************************************************************/ int main (int argc, char** argv) { return rw_test (argc, argv, __FILE__, "lib.string.erase", 0 /* no comment */, run_test, "|-no-char_traits# " "|-no-user_traits", &rw_opt_no_char_traits, &rw_opt_no_user_traits); } --------------020304070203040408080709--