Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 79977 invoked from network); 6 Feb 2006 23:34:07 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 6 Feb 2006 23:34:07 -0000 Received: (qmail 23623 invoked by uid 500); 6 Feb 2006 23:34:05 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 23605 invoked by uid 500); 6 Feb 2006 23:34:05 -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 23594 invoked by uid 500); 6 Feb 2006 23:34:05 -0000 Delivered-To: apmail-incubator-stdcxx-cvs@incubator.apache.org Received: (qmail 23591 invoked by uid 99); 6 Feb 2006 23:34:05 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Feb 2006 15:34:04 -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; Mon, 06 Feb 2006 15:34:03 -0800 Received: (qmail 79642 invoked by uid 65534); 6 Feb 2006 23:33:34 -0000 Message-ID: <20060206233334.79639.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r375412 - /incubator/stdcxx/trunk/tests/algorithms/25.merge.cpp Date: Mon, 06 Feb 2006 23:33:21 -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: Mon Feb 6 15:33:15 2006 New Revision: 375412 URL: http://svn.apache.org/viewcvs?rev=375412&view=rev Log: 2006-02-06 Anton Pevtsov * 25.merge.cpp: New test exercising lib.alg.merge. Added: incubator/stdcxx/trunk/tests/algorithms/25.merge.cpp (with props) Added: incubator/stdcxx/trunk/tests/algorithms/25.merge.cpp URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/algorithms/25.merge.cpp?rev=375412&view=auto ============================================================================== --- incubator/stdcxx/trunk/tests/algorithms/25.merge.cpp (added) +++ incubator/stdcxx/trunk/tests/algorithms/25.merge.cpp Mon Feb 6 15:33:15 2006 @@ -0,0 +1,591 @@ +/*************************************************************************** + * + * 25.merge.cpp - test exercising 25.3.4 [lib.alg.merge] + * + * $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 merge, +#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 > > > +merge (InputIter > > >, + InputIter > > >, + InputIter > > >, + InputIter > > >, + OutputIter > > >); + +template +OutputIter > > > +merge (InputIter > > >, + InputIter > > >, + InputIter > > >, + InputIter > > >, + OutputIter > > >, + binary_predicate > > >); + +template +void +inplace_merge (BidirIter > > >, + BidirIter > > >, + BidirIter > > >); + +template +void +inplace_merge (BidirIter > > >, + BidirIter > > >, + BidirIter > > >, + binary_predicate > > >); + +#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION + +} // namespace std + +/**************************************************************************/ + +template +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 T &x, const T &y) /* non-const */ { + ++funcalls_; + return conv_to_bool::make (x.val_ < y.val_); + } + + static const char* name () { return "Less"; } + +private: + void operator= (StrictWeakLess&); // not assignable +}; + +template std::size_t Less::funcalls_; + +/**************************************************************************/ + +template +void test_merge (int line, + const char *src1, + const char *src2, + const std::size_t midinx, + const InputIter1 &it1, + const InputIter2 &it2, + const OutputIterator &out, + const BidirectIterator &bit, + const T*, + const Predicate *ppred, + bool inplace) +{ + const char* const it1name = + inplace ? type_name (bit, (T*)0) : type_name (it1, (T*)0); + const char* const it2name = type_name (it2, (T*)0); + const char* const outname = type_name (out, (T*)0); + const char* const fname = inplace ? "inplace_merge" : "merge"; + const char* const funname = Predicate::name(); + + const std::size_t nsrc1 = std::strlen (src1); + const std::size_t nsrc2 = std::strlen (src2); + + T* const xsrc1 = T::from_char (src1, nsrc1); + T* const xsrc2 = T::from_char (src2, nsrc2); + + const std::size_t ndst = nsrc1 + nsrc2; + T* const xdst = inplace ? xsrc1 : new T [ndst]; + + T* const xsrc1_end = xsrc1 + nsrc1; + T* const xsrc2_end = xsrc2 + nsrc2; + T* const xsrc_mid = xsrc1 + midinx; + T* const xdst_end = xdst + ndst; + + const InputIter1 first1 = make_iter (xsrc1, xsrc1, xsrc1_end, it1); + const InputIter1 last1 = make_iter (xsrc1_end, xsrc1, xsrc1_end, it1); + const InputIter2 first2 = make_iter (xsrc2, xsrc2, xsrc2_end, it2); + const InputIter2 last2 = make_iter (xsrc2_end, xsrc2, xsrc2_end, it2); + + const OutputIterator res_first = make_iter (xdst, xdst, xdst_end, out); + + const BidirectIterator first = make_iter (xsrc1, xsrc1, xsrc1_end, bit); + const BidirectIterator mid = make_iter (xsrc_mid, xsrc1, xsrc1_end, bit); + const BidirectIterator last = make_iter (xsrc1_end, xsrc1, xsrc1_end, bit); + + const Predicate pred (0, 0); + + const std::size_t last_n_op_lt = T::n_total_op_lt_; + OutputIterator result (0, 0, 0); + + if (inplace) { // inplace_merge + if (ppred) + std::inplace_merge (first, mid, last, pred); + else + std::inplace_merge (first, mid, last); + } + else { // merge + result = ppred ? + std::merge (first1, last1, first2, last2, res_first, pred) + : std::merge (first1, last1, first2, last2, res_first); + } + + const std::size_t n_ops_lt = ppred ? + Predicate::funcalls_ : T::n_total_op_lt_ - last_n_op_lt; + + bool success = true; + + // check output iterator for merge + if (!inplace) { + success = result.cur_ == xdst_end; + rw_assert (success, 0, line, + "line %d: %s<%s, %s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...)" + " return : expected first + %zu, got first + %td", + __LINE__, fname, it1name, it2name, outname, ppred, funname, + src1, src2, ndst, result.cur_ - res_first.cur_); + } + + // check that the sequence is sorted + success = is_sorted_lt (xdst, xdst_end); + rw_assert (success, 0, line, + "line %d: %s<%s%{?}, %s, %s%{;}%{?}, %s%{;}> " + "(\"%s\", %{?}\"%s\"%{;}%{?}%zu%{;}, ...) ==> \"%{X=*.*}\" " + "not sorted", + __LINE__, fname, it1name, !inplace, it2name, outname, + ppred, funname, src1, !inplace, src2, inplace, midinx, + int (ndst), -1, xdst); + + // check that the algorithm is stable + std::size_t i = 1; + for ( ; i < ndst; i++) { + if (xdst [i - 1].val_ == xdst [i].val_) { + success = xdst [i - 1].origin_ < xdst [i].origin_; + 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\"%{;}%{?}%zu%{;}, ...) ==> \"%{X=*.*}\" " + "not stable at %zu: got ids %d !< %d for values %#c == %#c", + __LINE__, fname, it1name, !inplace, it2name, outname, + ppred, funname, src1, !inplace, src2, inplace, midinx, + int (ndst), i, xdst, i, xdst [i - 1].origin_, + xdst [i].origin_, xdst [i - 1].val_, xdst [i].val_); + + // check the complexity + success = n_ops_lt <= ndst - 1; + rw_assert (success, 0, line, + "line %d: %s<%s%{?}, %s, %s%{;}%{?}, %s%{;}> " + "(\"%s\", %{?}\"%s\"%{;}%{?}%zu%{;}, ...) ==> \"%{X=*.*}\" " + "complexity: got %zu, expected no more than %zu", + __LINE__, fname, it1name, !inplace, it2name, outname, + ppred, funname, src1, !inplace, src2, inplace, midinx, + int (ndst), -1, xdst, n_ops_lt, ndst - 1); + + delete[] xsrc1; + delete[] xsrc2; + + if (!inplace) + delete[] xdst; +} + +/**************************************************************************/ + +template +void test_merge (const InputIter1 &it1, + const InputIter2 &it2, + const OutputIterator &out, + const T*, + const Predicate *ppred) +{ + const char* const it1name = type_name (it1, (T*)0); + const char* const it2name = type_name (it2, (T*)0); + const char* const outname = type_name (out, (T*)0); + const char* const fname = "merge"; + const char* const funname = Predicate::name(); + + static const BidirIter bidir_iter (0, 0, 0); + + rw_info (0, 0, 0, + "%s std::%s(%s, %3$s, %s, %4$s, %1$s%{?}, %s%{;})", + outname, fname, it1name, it2name, ppred, funname); + +#define TEST(src1, src2) \ + test_merge (__LINE__, src1, src2, 0, it1, it2, out, \ + bidir_iter, (T*)0, ppred, false) + + TEST ("ab", ""); + TEST ("", "ab"); + + TEST ("a", "b"); + TEST ("b", "a"); + TEST ("aa", "bb"); + TEST ("bb", "aa"); + + TEST ("acegi", "bdfhj"); + TEST ("aaegi", "bdfjj"); + TEST ("accgi", "bdhhj"); + TEST ("aceei", "bffhj"); + TEST ("acegg", "ddfhj"); + TEST ("aceii", "bbfhj"); + + TEST ("bdfhj", "acegi"); + TEST ("bdfjj", "aaegi"); + TEST ("bdhhj", "accgi"); + TEST ("bffhj", "aceei"); + TEST ("ddfhj", "acegg"); + TEST ("bbfhj", "aceii"); + + TEST ("abcde", "abcde"); + TEST ("aacde", "aacde"); + TEST ("abbde", "abbde"); + TEST ("abcce", "abcce"); + TEST ("abcdd", "abcdd"); + TEST ("abcee", "abcee"); + + TEST ("aaegi", "bdfjj"); + TEST ("accgi", "bdhhj"); + TEST ("aceei", "bffhj"); + TEST ("acegg", "ddfhj"); + TEST ("aceii", "bbfhj"); + + TEST ("a","abcdefghij"); + TEST ("ac","abcdefghi"); + TEST ("ace","abcdefgh"); + TEST ("aceg","abcdefg"); + + TEST ("j","abcdefghjj"); + TEST ("gj","abcdeggjj"); + TEST ("egj","abeeggjj"); + + TEST ("abcdefghij","a"); + TEST ("abcdefghi","ac"); + TEST ("abcdefgh","ace"); + TEST ("abcdefg","aceg"); + + TEST ("abcdefghjj","j"); + TEST ("abcdeggjj","gj"); + TEST ("abeeggjj","egj"); + + TEST ("aaaaa", "aaaaa"); + TEST ("bbbbb", "bbbbb"); +} + +/**************************************************************************/ + +template +void test_inplace_merge (const BidirectIterator &it, + const T*, + const Predicate *ppred) +{ + const char* const itname = type_name (it, (T*)0); + const char* const fname = "inplace_merge"; + const char* const funname = Predicate::name(); + + rw_info (0, 0, 0, + "std::%s(%s, %2$s, %2$s%{?}, %s%{;})", + fname, itname, ppred, funname); + +#undef TEST +#define TEST(src, mid) \ + test_merge (__LINE__, src, "", mid, it, it, it, \ + it, (T*)0, ppred, true) + + TEST ("a", 0); + TEST ("aa", 0); + TEST ("a", 1); + TEST ("aa", 2); + + TEST ("aa", 1); + TEST ("ab", 1); + TEST ("ba", 1); + + TEST ("abcdefghij", 5); + TEST ("aacdeffhij", 5); + TEST ("abbdefggij", 5); + TEST ("abccefghhj", 5); + TEST ("abcddfghii", 5); + TEST ("abceefghjj", 5); + + TEST ("abcdeabcde", 5); + TEST ("aacdeaacde", 5); + TEST ("abbdeabbde", 5); + TEST ("abcceabcce", 5); + TEST ("abcddabcdd", 5); + TEST ("abceeabcee", 5); + + TEST ("aabcdefghi", 1); + TEST ("aaacdefghi", 1); + TEST ("babcdefghi", 1); + TEST ("babbdefghi", 1); + + TEST ("abcdefghia", 9); + TEST ("aacdefghia", 9); + TEST ("abcdefghib", 9); + TEST ("abbdefghib", 9); +} + +/**************************************************************************/ + +/* extern */ int rw_opt_no_merge; // --no-merge +/* extern */ int rw_opt_no_inplace_merge; // --no-inplace_merge +/* 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 test_merge (const InputIterator1 &it1, + const InputIterator2 &it2, + const OutputIterator &out, + int tag1, + int tag2, + int tag3, + const T*, + const Predicate *ppred) +{ + static const InputIter input_iter (0, 0, 0); + static const OutputIter output_iter (0, 0, 0); + static const FwdIter fwd_iter (0, 0, 0); + static const BidirIter bidir_iter (0, 0, 0); + static const RandomAccessIter rand_iter (0, 0, 0); + + if (tag1 && tag2 && tag3) { + rw_info (0, 0, 0, + "template " + "%3$s std::merge(%1$s, %1$s, %2$s, %2$s, %3$s%{?}, %s%{;})", + "InputIterator1", "InputIterator2", "OutputIterator", + ppred, "Compare", ppred, "Compare"); + } + + // tag1, tag2 and tag3 indicates that an iterator needs to be generated + // at the corresponding position by a recursive call to test_merge + // for all tags: + // 0 means that no iterator is needed here + // (maybe it was already generated or just not needed) + // 1 means that the iterator is needed at this position + // (first for tag1, second for tag2, etc) + + //////////////////////////////////////////////////////////////////////// + if (rw_opt_no_input_iter) { + if (tag1 || tag2) + rw_note (0, __FILE__, __LINE__, "InputIterator test disabled"); + } + else { + if (tag1) { + test_merge (input_iter, it2, out, 0, tag2, tag3, (T*)0, ppred); + } + else if (tag1 == 0 && tag2) { + test_merge (it1, input_iter, out, tag1, 0, tag3, (T*)0, ppred); + } + } + + //////////////////////////////////////////////////////////////////////// + if (rw_opt_no_fwd_iter) { + if (tag1 || tag2 || tag3) + rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); + } + else { + if (tag1) { + test_merge (fwd_iter, it2, out, 0, tag2, tag3, (T*)0, ppred); + } + else if (tag1 == 0 && tag2) { + test_merge (it1, fwd_iter, out, tag1, 0, tag3, (T*)0, ppred); + } + else if (tag1 == 0 && tag2 == 0 && tag3) { + test_merge (it1, it2, fwd_iter, tag1, tag2, 0, (T*)0, ppred); + } + } + + //////////////////////////////////////////////////////////////////////// + if (rw_opt_no_bidir_iter) { + if (tag1 || tag2 || tag3) + rw_note (0, __FILE__, __LINE__, + "BidirectionalIterator test disabled"); + } + else { + if (tag1) { + test_merge (bidir_iter, it2, out, 0, tag2, tag3, (T*)0, ppred); + } + else if (tag1 == 0 && tag2) { + test_merge (it1, bidir_iter, out, tag1, 0, tag3, (T*)0, ppred); + } + else if (tag1 == 0 && tag2 == 0 && tag3) { + test_merge (it1, it2, bidir_iter, tag1, tag2, 0, (T*)0, ppred); + } + } + + //////////////////////////////////////////////////////////////////////// + if (rw_opt_no_rnd_iter) { + if (tag1 || tag2 || tag3) + rw_note (0, __FILE__, __LINE__, + "RandomAccessIterator test disabled"); + } + else { + if (tag1) { + test_merge (rand_iter, it2, out, 0, tag2, tag3, (T*)0, ppred); + } + else if (tag1 == 0 && tag2) { + test_merge (it1, rand_iter, out, tag1, 0, tag3, (T*)0, ppred); + } + else if (tag1 == 0 && tag2 == 0 && tag3) { + test_merge (it1, it2, rand_iter, tag1, tag2, 0, (T*)0, ppred); + } + } + + //////////////////////////////////////////////////////////////////////// + if (rw_opt_no_output_iter) { + if (!tag1 && !tag2 && tag3) + rw_note (0, __FILE__, __LINE__, + "OutputIterator test disabled"); + } + else { + if (tag1 == 0 && tag2 == 0 && tag3) { + test_merge (it1, it2, output_iter, tag1, tag2, 0, (T*)0, ppred); + } + } + + if (0 == tag1 && 0 == tag2 && 0 == tag3) + test_merge (it1, it2, out, (T*)0, ppred); +} + +/**************************************************************************/ + +template +void test_inplace_merge (const T*, + const Predicate *ppred) +{ + static const BidirIter bidir_iter (0, 0, 0); + static const RandomAccessIter rand_iter (0, 0, 0); + + rw_info (0, 0, 0, + "template " + "std::inplace_merge (%1$s, %1$s, %1$s%{?}, %s%{;})", + "BidirectionalIterator", ppred, "Compare", ppred, "Compare"); + + if (rw_opt_no_bidir_iter) { + rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); + } + else { + test_inplace_merge (bidir_iter, (T*)0, ppred); + } + + if (rw_opt_no_rnd_iter) { + rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); + } + else { + test_inplace_merge (rand_iter, (T*)0, ppred); + } +} + +/**************************************************************************/ + +static int run_test (int, char*[]) +{ + const Less less_pred(0, 0); + + if (rw_opt_no_merge) { + rw_note (0, __FILE__, __LINE__, + "std::merge test disabled"); + } + else { + static const FwdIter fwd_iter (0, 0, 0); + + test_merge (fwd_iter, fwd_iter, fwd_iter, 1, 1, 1, + (X*)0, (Less*)0); + + if (rw_opt_no_predicate) { + rw_note (0, __FILE__, __LINE__, + "std::merge predicate test disabled"); + } + else { + test_merge (fwd_iter, fwd_iter, fwd_iter, 1, 1, 1, + (X*)0, &less_pred); + } + } + + if (rw_opt_no_inplace_merge) { + rw_note (0, __FILE__, __LINE__, + "std::inplace_merge test disabled"); + } + else { + test_inplace_merge ((X*)0, (Less*)0); + + if (rw_opt_no_predicate) { + rw_note (0, __FILE__, __LINE__, + "std::inplace_merge predicate test disabled"); + } + else { + test_inplace_merge ((X*)0, &less_pred); + } + } + + return 0; +} + + +/**************************************************************************/ + +int main (int argc, char *argv[]) +{ + return rw_test (argc, argv, __FILE__, + "lib.alg.merge", + 0 /* no comment */, run_test, + "|-no-merge# " + "|-no-inplace_merge# " + "|-no-predicate#" + "|-no-InputIterator# " + "|-no-OutputIterator# " + "|-no-ForwardIterator# " + "|-no-BidirectionalIterator# " + "|-no-RandomAccessIterator#", + &rw_opt_no_merge, + &rw_opt_no_inplace_merge, + &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.merge.cpp ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/stdcxx/trunk/tests/algorithms/25.merge.cpp ------------------------------------------------------------------------------ svn:keywords = Id