Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 77039 invoked from network); 17 Feb 2006 16:11:35 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 17 Feb 2006 16:11:35 -0000 Received: (qmail 43128 invoked by uid 500); 17 Feb 2006 16:11:35 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 43110 invoked by uid 500); 17 Feb 2006 16:11:35 -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 43097 invoked by uid 500); 17 Feb 2006 16:11:34 -0000 Delivered-To: apmail-incubator-stdcxx-cvs@incubator.apache.org Received: (qmail 43094 invoked by uid 99); 17 Feb 2006 16:11:34 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 Feb 2006 08:11:34 -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, 17 Feb 2006 08:11:33 -0800 Received: (qmail 76878 invoked by uid 65534); 17 Feb 2006 16:11:13 -0000 Message-ID: <20060217161113.76877.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r378555 - /incubator/stdcxx/trunk/tests/algorithms/25.set.intersection.cpp Date: Fri, 17 Feb 2006 16:11:12 -0000 To: stdcxx-cvs@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.0.6 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 Feb 17 08:11:10 2006 New Revision: 378555 URL: http://svn.apache.org/viewcvs?rev=378555&view=rev Log: 2006-02-17 Anton Pevtsov * 25.set.intersection.cpp: New test exercising lib.set.intersection. Added: incubator/stdcxx/trunk/tests/algorithms/25.set.intersection.cpp (with props) Added: incubator/stdcxx/trunk/tests/algorithms/25.set.intersection.cpp URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/algorithms/25.set.intersection.cpp?rev=378555&view=auto ============================================================================== --- incubator/stdcxx/trunk/tests/algorithms/25.set.intersection.cpp (added) +++ incubator/stdcxx/trunk/tests/algorithms/25.set.intersection.cpp Fri Feb 17 08:11:10 2006 @@ -0,0 +1,420 @@ +/*************************************************************************** + * + * 25. set.intersection.cpp - test exercising lib.set.intersection + * + * $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 set_intersection +#include // for strlen, size_t + +#include +#include // for rw_test() + +/**************************************************************************/ + +_RWSTD_NAMESPACE (std) { + +// disable explicit instantiation for compilers (like MSVC) +// that can't handle it +#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION + +template +OutputIter > > > +set_intersection (InputIter > > >, + InputIter > > >, + InputIter > > >, + InputIter > > >, + OutputIter > > >); + +template +OutputIter > > > +set_intersection (InputIter > > >, + InputIter > > >, + InputIter > > >, + InputIter > > >, + OutputIter > > >, + binary_predicate > > >); + +#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION + +} // namespace std + +/**************************************************************************/ + +struct Less +{ + static std::size_t funcalls_; + + // dummy arguments provided to prevent the class from being + // default constructible and implicit conversion from int + Less (int /* dummy */, int /* dummy */) { + funcalls_ = 0; + } + + // return a type other than bool but one that is implicitly + // convertible to bool to detect incorrect assumptions + conv_to_bool operator() (const X &x, const X &y) /* non-const */ { + ++funcalls_; + return conv_to_bool::make (x.val_ < y.val_); + } + +private: + void operator= (Less&); // not assignable +}; + +std::size_t Less::funcalls_; + +/**************************************************************************/ + +struct SetIntersectionBase +{ + virtual ~SetIntersectionBase() {} + + const char* iter_names [3]; + + // pure virtual + virtual X* + set_intersection (const X*, const X*, const X*, const X*, + X*, X*, const Less*) const = 0; +}; + +template +struct SetIntersection: SetIntersectionBase +{ + SetIntersection () { + iter_names [0] = type_name (InputIterator1 (0, 0, 0), (X*)0); + iter_names [1] = type_name (InputIterator2 (0, 0, 0), (X*)0); + iter_names [2] = type_name (OutputIterator (0, 0, 0), (X*)0); + } + + virtual X* + set_intersection (const X *xsrc1, const X *xsrc1_end, + const X *xsrc2, const X *xsrc2_end, + X *xdst, X *xdst_end, + const Less *ppred) const { + + const InputIterator1 first1 (xsrc1, xsrc1, xsrc1_end); + const InputIterator1 last1 (xsrc1_end, xsrc1, xsrc1_end); + const InputIterator2 first2 (xsrc2, xsrc2, xsrc2_end); + const InputIterator2 last2 (xsrc2_end, xsrc2, xsrc2_end); + + const OutputIterator result (xdst, xdst, xdst_end); + + const OutputIterator ret = ppred ? + std::set_intersection (first1, last1, first2, + last2, result, *ppred) + : std::set_intersection (first1, last1, first2, + last2, result); + + // silence EDG eccp 3.7 and prior remark #550-D: + // variable was set but never used + _RWSTD_UNUSED (ret); + + return ret.cur_; + } +}; + +/**************************************************************************/ + +void test_set_intersection (int line, + const char *src1, + const char *src2, + const char *res, + bool predicate, + const SetIntersectionBase &alg) +{ + const char* const it1name = alg.iter_names [0]; + const char* const it2name = alg.iter_names [1]; + const char* const outname = alg.iter_names [2]; + const char* const fname = "set_intersection"; + const char* const funname = predicate ? "Less" : 0; + + const std::size_t nsrc1 = std::strlen (src1); + const std::size_t nsrc2 = std::strlen (src2); + const std::size_t ndst = std::strlen (res); + + X* const xsrc1 = X::from_char (src1, nsrc1); + X* const xsrc2 = X::from_char (src2, nsrc2); + X* const xdst = new X[ndst]; + + const int max1_id = nsrc1 > 0 ? xsrc1[nsrc1 - 1].id_ : -1; + + X* const xsrc1_end = xsrc1 + nsrc1; + X* const xsrc2_end = xsrc2 + nsrc2; + X* const xdst_end = xdst + ndst; + + const std::size_t last_n_op_lt = X::n_total_op_lt_; + + const Less pred (0, 0); + const Less* const ppred = predicate ? &pred : 0; + + const X* const xdst_res = + alg.set_intersection (xsrc1, xsrc1_end, xsrc2, + xsrc2_end, xdst, xdst_end, ppred); + + // check the returned value + bool success = xdst_res == xdst_end; + rw_assert (success, 0, line, + "line %d: %s<%s, %s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) " + "got res + %td, expected res + %zu", + __LINE__, fname, it1name, it2name, outname, predicate, + funname, src1, src2, xdst_res - xdst, ndst); + + // quit here to avoid the running out of the array boundaries + if (!success) { + delete[] xsrc1; + delete[] xsrc2; + delete[] xdst; + return; + } + + const std::size_t n_ops_lt = ppred ? + Less::funcalls_ : X::n_total_op_lt_ - last_n_op_lt; + + // check the algorithm correctness + std::size_t i = 0; + std::size_t n1 = 0; + std::size_t n2 = 0; + for ( ; i < ndst; i++) { + xdst[i].origin_ <= max1_id ? n1++ : n2++; + success = xdst[i].val_ == res[i]; + if (!success) + break; + } + + // to avoid errors in --trace mode + i = i < ndst ? i : ndst - 1; + + rw_assert (success, 0, line, + "line %d: %s<%s, %s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) " + " ==> \"%{X=*.*}\", expected \"%s\"", + __LINE__, fname, it1name, it2name, outname, predicate, + funname, src1, src2, int (ndst), i, xdst, res); + + // check that the operation is stable : for two equal elements + // one from the first sequence should be taken + success = n2 == 0; + rw_assert (success, 0, line, + "line %d: %s<%s, %s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) " + " ==> \"%{X=*.*}\" got %zu elements from first sequence and " + "%zu from second, expected %zu from first and 0 from second", + __LINE__, fname, it1name, it2name, outname, predicate, funname, + src1, src2, int (ndst), -1, xdst, n1, n2, ndst); + + // check the complexity + const std::size_t n_exp_ops = + nsrc1 + nsrc2 > 0 ? 2 * (nsrc1 + nsrc2) - 1 : 0; + + rw_assert (n_ops_lt <= n_exp_ops, 0, line, + "line %d: %s<%s, %s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) " + "complexity: got %zu, expected no more than %zu", + __LINE__, fname, it1name, it2name, outname, predicate, funname, + src1, src2, n_ops_lt, n_exp_ops); + + delete[] xsrc1; + delete[] xsrc2; + delete[] xdst; +} + +/**************************************************************************/ + +void test_set_intersection (const SetIntersectionBase &alg, + bool predicate) +{ + const char* const it1name = alg.iter_names [0]; + const char* const it2name = alg.iter_names [1]; + const char* const outname = alg.iter_names [2]; + const char* const fname = "set_intersection"; + const char* const funname = predicate ? "Less" : 0; + + rw_info (0, 0, 0, + "%s std::%s(%s, %3$s, %s, %4$s, %1$s%{?}, %s%{;})", + outname, fname, it1name, it2name, predicate, funname); + +#define TEST(src1, src2, res) \ + test_set_intersection (__LINE__, src1, src2, res, predicate, alg) + + TEST ("a", "", ""); + TEST ("abcde", "", ""); + + TEST ("", "a", ""); + TEST ("", "abcde", ""); + + TEST ("a", "b", ""); + TEST ("b", "a", ""); + + TEST ("aa", "aa", "aa"); + TEST ("ab", "ab", "ab"); + + TEST ("aa", "ab", "a"); + TEST ("ab", "bb", "b"); + TEST ("aa", "bb", ""); + TEST ("ac", "bb", ""); + + TEST ("ace", "bdf", ""); + TEST ("acf", "bdf", "f"); + TEST ("ade", "bdf", "d"); + TEST ("bce", "bdf", "b"); + + TEST ("aacee", "aacee", "aacee"); + TEST ("aacee", "aaace", "aace"); + TEST ("aacee", "aaaae", "aae"); + TEST ("aacee", "aaaaa", "aa"); + TEST ("aaaae", "aacee", "aae"); + TEST ("aaaaa", "aacee", "aa"); + TEST ("aacee", "aaabd", "aa"); + TEST ("aaabd", "aacee", "aa"); + TEST ("aacee", "aabee", "aaee"); +} + +/**************************************************************************/ + +/* extern */ int rw_opt_no_predicate; // --no-predicate +/* 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 gen_set_intersection_test (const InputIterator1&, + const InputIterator2&, + const OutputIterator&, + bool predicate) +{ + const SetIntersection alg; + + test_set_intersection (alg, predicate); +} + +/**************************************************************************/ + +template +void gen_set_intersection_test (const InputIterator1 &it1, + const InputIterator2 &it2, + bool predicate) +{ + if (0 == rw_opt_no_output_iter) + gen_set_intersection_test ( + it1, it2, OutputIter(0, 0, 0), predicate); + if (0 == rw_opt_no_fwd_iter) + gen_set_intersection_test ( + it1, it2, FwdIter(0, 0, 0), predicate); + if (0 == rw_opt_no_bidir_iter) + gen_set_intersection_test ( + it1, it2, BidirIter(0, 0, 0), predicate); + if (0 == rw_opt_no_rnd_iter) + gen_set_intersection_test ( + it1, it2, RandomAccessIter(0, 0, 0), predicate); +} + +template +void gen_set_intersection_test (const InputIterator1 &it1, + bool predicate) +{ + if (0 == rw_opt_no_input_iter) + gen_set_intersection_test ( + it1, InputIter(0, 0, 0), predicate); + if (0 == rw_opt_no_fwd_iter) + gen_set_intersection_test ( + it1, ConstFwdIter(0, 0, 0), predicate); + if (0 == rw_opt_no_bidir_iter) + gen_set_intersection_test ( + it1, ConstBidirIter(0, 0, 0), predicate); + if (0 == rw_opt_no_rnd_iter) + gen_set_intersection_test ( + it1, ConstRandomAccessIter(0, 0, 0), predicate); +} + +// generates a specialization of the set_intersection test for each of +// the required iterator categopries +static void +gen_set_intersection_test (bool predicate) +{ + rw_info (0, 0, 0, + "template %3$s " + "set_intersection(%1$s, %1$s, %2$s, %2$s, %3$s%{?}, %s%{;})", + "InputIterator1", "InputIterator2", "OutputIterator", + predicate, "Compare", predicate, "Compare"); + + if (rw_opt_no_output_iter) + rw_note (0, 0, 0, "OutputIterator test disabled"); + + if (rw_opt_no_input_iter) + rw_note (0, 0, 0, "InputIterator test disabled"); + else + gen_set_intersection_test (InputIter(0, 0, 0), predicate); + + if (rw_opt_no_fwd_iter) + rw_note (0, 0, 0, "ForwardIterator test disabled"); + else + gen_set_intersection_test (ConstFwdIter(0, 0, 0), predicate); + + if (rw_opt_no_bidir_iter) + rw_note (0, 0, 0, "BidirectionalIterator test disabled"); + else + gen_set_intersection_test (ConstBidirIter(0, 0, 0), predicate); + + if (rw_opt_no_rnd_iter) + rw_note (0, 0, 0, "RandomAccessIterator test disabled"); + else + gen_set_intersection_test ( + ConstRandomAccessIter(0, 0, 0), predicate); +} + +/**************************************************************************/ + +static int +run_test (int, char*[]) +{ + if (rw_opt_no_predicate) + rw_note (0, 0, 0, "predicate test disabled"); + + const int niters = rw_opt_no_predicate ? 1 : 2; + + ////////////////////////////////////////////////////////////////// + for (int i = 0; i != niters; ++i) { + gen_set_intersection_test (1 == i); + } + + return 0; +} + +/**************************************************************************/ + +int main (int argc, char *argv[]) +{ + return rw_test (argc, argv, __FILE__, + "lib.set.intersection", + 0 /* no comment */, + run_test, + "|-no-predicate#" + "|-no-InputIterator# " + "|-no-OutputIterator# " + "|-no-ForwardIterator# " + "|-no-BidirectionalIterator# " + "|-no-RandomAccessIterator#", + &rw_opt_no_predicate, + &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.set.intersection.cpp ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/stdcxx/trunk/tests/algorithms/25.set.intersection.cpp ------------------------------------------------------------------------------ svn:keywords = Id