Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 20629 invoked from network); 23 Dec 2005 22:37:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 23 Dec 2005 22:37:03 -0000 Received: (qmail 75786 invoked by uid 500); 23 Dec 2005 22:37:03 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 75772 invoked by uid 500); 23 Dec 2005 22:37:03 -0000 Mailing-List: contact stdcxx-commits-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-commits@incubator.apache.org Received: (qmail 75761 invoked by uid 500); 23 Dec 2005 22:37:02 -0000 Delivered-To: apmail-incubator-stdcxx-cvs@incubator.apache.org Received: (qmail 75758 invoked by uid 99); 23 Dec 2005 22:37:02 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 23 Dec 2005 14:37:02 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Fri, 23 Dec 2005 14:37:01 -0800 Received: (qmail 20593 invoked by uid 65534); 23 Dec 2005 22:36:41 -0000 Message-ID: <20051223223641.20592.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r358878 - /incubator/stdcxx/trunk/tests/algorithms/25.replace.cpp Date: Fri, 23 Dec 2005 22:36:40 -0000 To: stdcxx-cvs@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: sebor Date: Fri Dec 23 14:36:36 2005 New Revision: 358878 URL: http://svn.apache.org/viewcvs?rev=358878&view=rev Log: 2005-12-23 Anton Pevtsov Martin Sebor STDCXX-4 * 25.replace.cpp: New test exercising lib.alg.replace. Added: incubator/stdcxx/trunk/tests/algorithms/25.replace.cpp (with props) Added: incubator/stdcxx/trunk/tests/algorithms/25.replace.cpp URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/algorithms/25.replace.cpp?rev=358878&view=auto ============================================================================== --- incubator/stdcxx/trunk/tests/algorithms/25.replace.cpp (added) +++ incubator/stdcxx/trunk/tests/algorithms/25.replace.cpp Fri Dec 23 14:36:36 2005 @@ -0,0 +1,682 @@ +/*************************************************************************** + * + * 25.replace.cpp - test exercising 25.2.4 [lib.alg.replace] + * + * $Id$ + * + *************************************************************************** + * + * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave + * Software division. 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 // for replace(), replace_copy() +#include // for strlen() +#include // for free(), size_t + +#include +#include // for rw_test() +#include // for rw_asnprintf() + +/**************************************************************************/ + +_RWSTD_NAMESPACE (std) { + +// disable explicit instantiation for compilers (like MSVC) +// that can't handle it +#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION + +template +void replace (FwdIter > > >, + FwdIter > > >, + const eq_comp > >&, + const eq_comp > >&); + +template +void replace_if (FwdIter > > , + FwdIter > > , + predicate > > , + const assign > &); + +template +OutputIter > > > +replace_copy (InputIter > > >, + InputIter > > >, + OutputIter > > >, + const eq_comp > >&, + const eq_comp > >&); + +template +OutputIter > > +replace_copy_if (InputIter > > , + InputIter > > , + OutputIter > > , + predicate > > , + const assign > &); + +#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION + +} // namespace std + +/**************************************************************************/ + +// names of tested functions +const char* const fnames[] = { "replace", "replace_copy" }; +const char* const fnames_if[] = { "replace_if", "replace_copy_if" }; + +// tags to select replace or replace_copy at compile time +struct ReplaceTag { + enum { fname_inx = 0 }; + int use_predicate; +}; + +struct ReplaceCopyTag { + enum { fname_inx = 1 }; + int use_predicate; +}; + +// used as a dummy template argument to test functions exercising replace() +// and replace_if() (to differentiate from replace_copy() and replace_copy_if()) +struct NoIterator { }; +const char* type_name (NoIterator, const X*) +{ + return 0; +} + +typedef unsigned char UChar; + +/**************************************************************************/ + +const char nul_char = '\0'; + +template +class ToString +{ +public: + ToString (const T *first, const T *last, int pos, bool use_id = false) + : str_ (0) { + + std::size_t buf_sz = 0; + + if (first > last) { + rw_asnprintf (&str_, &buf_sz, "%s", "bad range"); + return; + } + + char* res = (char*)&nul_char; + char* tmp = 0; + + for (const T *cur = first; cur != last; ++cur) { + rw_asnprintf (&tmp, &buf_sz, + "%s%{?}>%{;}%{?}%d:%{;}%{lc}%{?}<%{;}", + res, + cur - first == pos, // '>' + use_id, cur->id_, // ":" + cur->val_, // + cur - first == pos); // '<' + + if (res != &nul_char) + std::free (res); + + res = tmp; + tmp = 0; + } + + str_ = res; + } + + ~ToString () { + if (str_ != &nul_char) + std::free (str_); + } + + operator const char* () const { + return str_; + } + +private: + + char* str_; +}; + +/**************************************************************************/ + +// predicate used as an argument to replace_if() and replace_copy_if() +template +struct EqualityPredicate +{ + static std::size_t funcalls_; + + EqualityPredicate (const T &val, int /* dummy */) + : val_ (val) { + funcalls_ = 0; + } + + class ConvertibleToBool { + bool result_; + public: + ConvertibleToBool (bool res): result_ (res) { /* empty */ } + operator bool() const { return result_; } + }; + + // return a type other than bool but one that is implicitly + // convertible to bool to detect incorrect assumptions + ConvertibleToBool operator() (const T &arg) { + ++funcalls_; + return ConvertibleToBool (arg == val_); + } + +private: + void operator= (EqualityPredicate&); + const T &val_; +}; + +template +std::size_t EqualityPredicate::funcalls_; + +/**************************************************************************/ + +// exercises std::replace() and std::replace_if() +template +void test_replace (int line, + const char *src, // source sequence + char val, // value to replace + char new_val, // value to replace it with + Iterator dummy, // not used + NoIterator, + const T*, + const Predicate*, + ReplaceTag tag) // replace() or replace_if() +{ + static const char* const itname = type_name (Iterator (), (T*)0); + static const char* const fname = tag.use_predicate ? + fnames_if [tag.fname_inx] : fnames [tag.fname_inx]; + + // compute the length of the source sequence + const std::size_t nsrc = std::strlen (src); + + // construct a sequence of `nsrc' elements to pass to replace + // (make sure there's always at least 1 element, even if the + // sequence is otherwise empty, to avoid undefined behavior + // when de-referencing xsrc[0] in inactive diagnostic messages) + T* const xsrc = T::from_char (src, nsrc + 1); + T* const xsrc_end = xsrc + nsrc; + + // construct an element to replace + T to_replace; + to_replace.val_ = val; + + // construct an element to replace it with + T replace_with; + replace_with.val_ = new_val; + + // construct a predicate object (used with replace_if() only) + const Predicate pred (to_replace, 0); + + // construct iterators pointing to the beginning and end + // of the source sequence + const Iterator first = make_iter (xsrc, xsrc, xsrc_end, dummy); + const Iterator last = make_iter (xsrc_end, xsrc_end, xsrc_end, dummy); + + // zero out predicate counters + T::n_total_op_eq_ = 0; + + // call replace() or replace_if() + if (tag.use_predicate) + std::replace_if (first, last, pred, replace_with); + else + std::replace (first, last, to_replace, replace_with); + + // verify that the value to be replaced has been replaced + // with the replacement value + bool success = true; + std::size_t i = 0; + for ( ; i != nsrc; ++i) { + success = to_replace.val_ != xsrc [i].val_; + if (!success) + break; + } + + rw_assert (success, 0, line, + "line %d: %s<%s>(\"%s\", ..., '%c', '%c') ==> \"%s\"; " + "unexpected element value %c", + __LINE__, fname, itname, src, val, new_val, + (const char*) ToString(xsrc, xsrc_end, i), + src [i]); + + // check the id (not just the value) of the matching element + // to make sure it has really been replaced + for (i = 0; i != nsrc; ++i) { + + success = + val != src [i] + || val == src [i] + && replace_with.origin_ == xsrc [i].origin_; + + if (!success) + break; + } + + rw_assert (success, 0, line, + "line %d: %s<%s>(\"%s\", ..., '%c', '%c') ==> \"%s\"; " + "failed to replace element %zu: " + "origin %d (%d, %d), expected %d (%d)", + __LINE__, fname, itname, src, val, new_val, + (const char*)ToString(xsrc, xsrc_end, i), + i, xsrc [i].origin_, xsrc [i].id_, xsrc [i].src_id_, + replace_with.origin_, replace_with.id_); + + // verify the number of applications of the predicate: p 25.2.4.3 + if (tag.use_predicate) { + rw_assert (pred.funcalls_ == nsrc, 0, line, + "line %d: %s<%s>(\"%s\", ..., '%c') called " + "Predicate::operator() %zu times, %zu expected", + __LINE__, fname, itname, src, val, + pred.funcalls_, nsrc); + } + else { + rw_assert (T::n_total_op_eq_ == nsrc, 0, line, + "line %d: %s<%s>(\"%s\", ..., '%c') called " + "T::operator< %zu times, %zu expected", + __LINE__, fname, itname, src, val, + T::n_total_op_eq_, nsrc); + } + + delete[] xsrc; +} + +/**************************************************************************/ + +// exercises std::replace_copy() +template +void test_replace (int line, + const char *src, // source sequence + char val, // value to replace + char new_val, // value to replace it with + Iterator it, + OutputIterator dummy, + const T*, + const Predicate*, + ReplaceCopyTag tag) // replace_copy or replace_copy_if +{ + static const char* const itname = type_name (it, (T*)0); + static const char* const fname = tag.use_predicate ? + fnames_if [tag.fname_inx] : fnames [tag.fname_inx]; + + const std::size_t nsrc = std::strlen (src); + + // construct a sequence of `nsrc' elements to pass to replace + // (make sure there's always at least 1 element, even if the + // sequence is otherwise empty, to avoid undefined behavior + // when de-referencing xsrc[0] in inactive diagnostic messages) + T* const xsrc = T::from_char (src, nsrc + 1); + T* const xdst = T::from_char (src, nsrc + 1); + + T* const xsrc_end = xsrc + nsrc; + T* const xdst_end = xdst + nsrc; + + T to_replace; + to_replace.val_ = val; + + T replace_with; + replace_with.val_ = new_val; + + const Predicate pred (to_replace, 0); + + const Iterator first = make_iter (xsrc, xsrc, xsrc_end, it); + const Iterator last = make_iter (xsrc_end, xsrc_end, xsrc_end, it); + + const OutputIterator result = make_iter (xdst, xdst, xdst_end, dummy); + + // zero out predicate counters + T::n_total_op_eq_ = 0; + + const OutputIterator end = tag.use_predicate + ? std::replace_copy_if (first, last, result, pred, replace_with) + : std::replace_copy (first, last, result, to_replace, replace_with); + + // verify that the returned iterator is set as expected + rw_assert (end.cur_ == result.cur_ + nsrc, 0, line, + "line %d: %s<%s>(\"%s\", ..., '%c') == %p, " + "got %p", __LINE__, fname, itname, src, val, + first.cur_ + nsrc, end.cur_); + + // verify that the value to be replaced does not appear anywhere + // in the range [result, end) + bool success = true; + std::size_t i = 0; + for ( ; i != nsrc; ++i) { + success = UChar (val) != xdst [i].val_; + if (!success) + break; + } + + rw_assert (success, 0, line, + "line %d: %s<%s>(\"%s\", ..., '%c') ==> \"%s\"; " + "unexpected element value %c", + __LINE__, fname, itname, src, val, + (const char*)ToString(xdst, xdst_end, i), src [i]); + + // check the id (not just the value) of the matching element + // to make sure it has really been copied + for (i = 0; i != nsrc; ++i) { + success = + val != src [i] + || val == src [i] + && replace_with.origin_ == xdst [i].origin_; + + if (!success) + break; + } + + rw_assert (success, 0, line, + "line %d: %s<%s>(\"%s\", ..., '%c', '%c') ==> \"%s\"; " + "failed to copy and replace element %zu: " + "origin %d (%d, %d), expected %d (%d)", + __LINE__, fname, itname, src, val, new_val, + (const char*)ToString(xdst, xdst_end, i), + i, xdst [i].origin_, xdst [i].id_, xdst [i].src_id_, + replace_with.origin_, replace_with.id_); + + // verify the number of applications of the predicate: p 25.2.4.7 + if (tag.use_predicate) { + rw_assert (pred.funcalls_ == nsrc, 0, line, + "line %d: %s<%s>(\"%s\", ..., '%c') called " + "Predicate::operator() %zu times, %zu expected", + __LINE__, fname, itname, src, val, + pred.funcalls_, nsrc); + } + else { + rw_assert (T::n_total_op_eq_ == nsrc, 0, line, + "line %d: %s<%s>(\"%s\", ..., '%c') called " + "T::operator< %zu times, %zu expected", + __LINE__, fname, itname, src, val, + T::n_total_op_eq_, nsrc); + } + + delete[] xsrc; + delete[] xdst; +} + +/**************************************************************************/ + +// exercises all four function templates +template +void test_replace (Iterator1 it1, Iterator2 it2, const T*, + const Predicate* pred, Tag tag) +{ + static const char* const it1name = type_name (it1, (T*)0); + static const char* const it2name = type_name (it2, (T*)0); + + if (tag.fname_inx) { // replace_copy(), replace_copy_if() + rw_info (0, 0, 0, + "std::%s (%s, %s, %s, %s, const T&)", + tag.use_predicate ? "replace_copy_if" : "replace_copy", + it1name, it1name, it2name, + tag.use_predicate ? "UnaryPredicate" : "const T&"); + } + else { // replace, replace_if() + rw_info (0, 0, 0, + "std::%s (%s, %s, %s, const T&)", + tag.use_predicate ? "replace_if" : "replace", + it1name, it1name, + tag.use_predicate ? "UnaryPredicate" : "const T&"); + } + + +#define TEST(src, val, new_val) \ + test_replace (__LINE__, src, val, new_val, it1, it2, (T*)0, pred, tag) + + // +----------------------- original sequence + // | +------- value to replace + // | | +- value to replace it with + // | | | + // v v v + TEST ("", 'a', 'b'); + TEST ("a", 'a', 'b'); + TEST ("aa", 'a', 'b'); + TEST ("aaa", 'a', 'b'); + TEST ("aaaa", 'a', 'b'); + TEST ("aaaaa", 'a', 'b'); + TEST ("aaaaaa", 'a', 'b'); + TEST ("aaaaaaa", 'a', 'b'); + TEST ("aaaaaaaa", 'a', 'b'); + TEST ("aaaaaaaaa", 'a', 'b'); + TEST ("aaaaaaaaaa", 'a', 'b'); + + TEST ("b", 'a', 'b'); + TEST ("bb", 'a', 'b'); + TEST ("ba", 'a', 'b'); + TEST ("ab", 'a', 'b'); + TEST ("abc", 'a', 'b'); + TEST ("bac", 'a', 'b'); + TEST ("bca", 'a', 'b'); + TEST ("aba", 'a', 'b'); + TEST ("abab", 'a', 'b'); + TEST ("ababa", 'a', 'b'); + TEST ("bababa", 'a', 'b'); + TEST ("bababab", 'a', 'b'); + TEST ("babababa", 'a', 'b'); + TEST ("bbbbbbbbb", 'a', 'b'); +} + +/**************************************************************************/ + +/* extern */ int rw_opt_no_replace; // --no-replace +/* extern */ int rw_opt_no_replace_if; // --no-replace_if +/* extern */ int rw_opt_no_replace_copy; // --no-replace_copy +/* extern */ int rw_opt_no_replace_copy_if; // --no-replace_copy_if +/* extern */ int rw_opt_no_input_iter; // --no-InputIterator +/* extern */ int rw_opt_no_output_iter; // --no-OutputIterator +/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator +/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator +/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator + +template +void test_replace (const T* , const Predicate* pred, Tag tag) +{ + rw_info (0, 0, 0, + "template " + "std::%s (ForwardIterator, ForwardIterator, " + "%s, const T&)", + tag.use_predicate ? "replace_if" : "replace", + tag.use_predicate ? "Predicate" : "const T&"); + + if (rw_opt_no_fwd_iter) { + rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); + } + else { + test_replace (FwdIter(), NoIterator (), (T*)0, pred, tag); + } + + if (rw_opt_no_bidir_iter) { + rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); + } + else { + test_replace (BidirIter(), NoIterator (), (T*)0, pred, tag); + } + + if (rw_opt_no_rnd_iter) { + rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); + } + else { + test_replace (RandomAccessIter(), NoIterator (), (T*)0, pred, tag); + } +} + +/**************************************************************************/ + +template +void test_replace (const T* ) +{ + const ReplaceTag replace_tag = { false }; + const ReplaceTag replace_if_tag = { true }; + + if (rw_opt_no_replace) { + rw_note (0, __FILE__, __LINE__, "std::replace test disabled"); + } + else { + const EqualityPredicate* const pred = (EqualityPredicate*) 0; + test_replace((T*)0, pred, replace_tag); + } + + if (rw_opt_no_replace_if) { + rw_note (0, __FILE__, __LINE__, "std::replace_if test disabled"); + } + else { + const EqualityPredicate* const pred = (EqualityPredicate*) 1; + test_replace((T*)0, pred, replace_if_tag); + } +} + +/**************************************************************************/ + +template +void test_replace_copy (const InputIterator& iter, const T*, + const Predicate* pred, Tag tag) +{ + if (rw_opt_no_output_iter) { + rw_note (0, __FILE__, __LINE__, "OutputIterator test disabled"); + } + else { + test_replace (iter, OutputIter(0, 0, 0), (T*)0, pred, tag); + } + + if (rw_opt_no_fwd_iter) { + rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); + } + else { + test_replace (iter, FwdIter(), (T*)0, pred, tag); + } + + if (rw_opt_no_bidir_iter) { + rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); + } + else { + test_replace (iter, BidirIter(), (T*)0, pred, tag); + } + + if (rw_opt_no_rnd_iter) { + rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); + } + else { + test_replace (iter, RandomAccessIter(), (T*)0, pred, tag); + } +} + +/**************************************************************************/ + +template +void test_replace_copy (const T*, const Predicate* pred, Tag tag) +{ + rw_info (0, 0, 0, + "template " + " " + "std::%s (InputIterator, InputIterator, " + "OutputIterator, %s, const T&)", + tag.use_predicate ? "replace_copy_if" : "replace_copy", + tag.use_predicate ? "Predicate" : "const T&"); + + if (rw_opt_no_input_iter) { + rw_note (0, __FILE__, __LINE__, "InputIterator test disabled"); + } + else { + test_replace_copy (InputIter(0, 0, 0), (T*)0, pred, tag); + } + + if (rw_opt_no_fwd_iter) { + rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); + } + else { + test_replace_copy (FwdIter(), (T*)0, pred, tag); + } + + if (rw_opt_no_bidir_iter) { + rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); + } + else { + test_replace_copy (BidirIter(), (T*)0, pred, tag); + } + + if (rw_opt_no_rnd_iter) { + rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); + } + else { + test_replace_copy (RandomAccessIter(), (T*)0, pred, tag); + } +} + +/**************************************************************************/ + +template +void test_replace_copy (const T* ) +{ + const ReplaceCopyTag replace_copy_tag = { false }; + const ReplaceCopyTag replace_copy_if_tag = { true }; + + if (rw_opt_no_replace_copy) { + rw_note (0, __FILE__, __LINE__, "std::replace_copy test disabled"); + } + else { + const EqualityPredicate* const pred = (EqualityPredicate*) 0; + test_replace_copy ((T*)0, pred, replace_copy_tag); + } + + if (rw_opt_no_replace_copy_if) { + rw_note (0, __FILE__, __LINE__, "std::replace_copy_if test disabled"); + } + else { + const EqualityPredicate* const pred = (EqualityPredicate*)1; + test_replace_copy ((T*)0, pred, replace_copy_if_tag); + } +} + +/**************************************************************************/ + +static int +run_test (int, char*[]) +{ + test_replace ((X*)0); + + test_replace_copy ((X*)0); + + return 0; +} + +/**************************************************************************/ + +int main (int argc, char *argv[]) +{ + return rw_test (argc, argv, __FILE__, + "lib.alg.replace", + 0 /* no comment */, + run_test, + "|-no-replace# " + "|-no-replace_if# " + "|-no-replace_copy# " + "|-no-replace_copy_if# " + "|-no-InputIterator# " + "|-no-OutputIterator# " + "|-no-ForwardIterator# " + "|-no-BidirectionalIterator# " + "|-no-RandomAccessIterator#", + &rw_opt_no_replace, + &rw_opt_no_replace_if, + &rw_opt_no_replace_copy, + &rw_opt_no_replace_copy_if, + &rw_opt_no_input_iter, + &rw_opt_no_output_iter, + &rw_opt_no_fwd_iter, + &rw_opt_no_bidir_iter, + &rw_opt_no_rnd_iter); +} Propchange: incubator/stdcxx/trunk/tests/algorithms/25.replace.cpp ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/stdcxx/trunk/tests/algorithms/25.replace.cpp ------------------------------------------------------------------------------ svn:keywords = Id