Return-Path: Delivered-To: apmail-incubator-stdcxx-dev-archive@www.apache.org Received: (qmail 6838 invoked from network); 18 Jan 2006 16:49:19 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 18 Jan 2006 16:49:19 -0000 Received: (qmail 99136 invoked by uid 500); 18 Jan 2006 16:48:22 -0000 Delivered-To: apmail-incubator-stdcxx-dev-archive@incubator.apache.org Received: (qmail 99006 invoked by uid 500); 18 Jan 2006 16:48:19 -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 98718 invoked by uid 99); 18 Jan 2006 16:48:15 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 18 Jan 2006 08:48:14 -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; Wed, 18 Jan 2006 08:41:47 -0800 Received: from [10.11.0.166] ([10.11.0.166]) by exmsk.moscow.vdiweb.com with Microsoft SMTPSVC(6.0.3790.1830); Wed, 18 Jan 2006 19:41:21 +0300 Message-ID: <43CE6FAC.3000507@moscow.vdiweb.com> Date: Wed, 18 Jan 2006 19:41:16 +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: Re: Re: test for lig.alg.swap Content-Type: multipart/mixed; boundary="------------020906070103050704000708" X-OriginalArrivalTime: 18 Jan 2006 16:41:21.0946 (UTC) FILETIME=[039067A0:01C61C4E] X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N --------------020906070103050704000708 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Martin Sebor wrote: >> Thanks! Your idea of reducing code duplication is neat. Unfortunately, > > there is a problem with it that prevents us from taking advantage of it in its current form: the library is designed to handle compilers that do not provide support or fully implement member templates (the configuration macro _RWSTD_NO_MEMBER_TEMPLATES). Thus the testsuite cannot assume that member templates are supported. [...] >> in a new simple forwarding function called from the first overload of > > test_swap() should do, don't you think? Great idea! Thank you! The attach contains the updated test version. With best wishes, Anton Pevtsov -----Original Message----- From: Martin Sebor [mailto:sebor@roguewave.com] Sent: Wednesday, January 18, 2006 05:00 To: stdcxx-dev@incubator.apache.org Subject: Re: test for lig.alg.swap Anton Pevtsov wrote: >> The attached file contains my attempt to update lib.alg.swap tests and > > >> port them to new test driver. > > Thanks! Your idea of reducing code duplication is neat. Unfortunately, there is a problem with it that prevents us from taking advantage of it in its current form: the library is designed to handle compilers that do not provide support or fully implement member templates (the configuration macro _RWSTD_NO_MEMBER_TEMPLATES). Thus the testsuite cannot assume that member templates are supported. [...] >> // classes used to exercise swap functions and to reduce code lines >> struct TestIterSwap { >> TestIterSwap (int dummy) : dummy_(dummy) {} >> >> template >> void test_swap (ForwardIterator1 it1, ForwardIterator2 it2, const >> T* ) > > This is the problem. But I think we should be able to deal with it quite easily. We don't need member templates to avoid code duplication -- a simple if (test_swap_ranges) test_swap_ranges (it1, it2, (T*)0); else test_iter_swap (it1, it2, (T*)0, true); in a new simple forwarding function called from the first overload of test_swap() should do, don't you think? Martin --------------020906070103050704000708 Content-Type: text/plain; name="25.swap.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="25.swap.cpp" /*************************************************************************** * * swap.cpp - test exercising 25.2.2 [lib.alg.swap] * * $Id: //stdlib/dev/tests/stdlib/algorithm/swap.cpp#18 $ * *************************************************************************** * * 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 swap, swap_ranges, iter_swap #include // for strlen #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 void swap (assign >&, assign >&); template FwdIter > > swap_ranges (FwdIter > >, FwdIter > >, FwdIter > >); template void iter_swap (FwdIter > >, FwdIter > >); #endif // _RWSTD_NO_EXPLICIT_INSTANTIATION } // namespace std /**************************************************************************/ template void test_iter_swap (int line, const char* seq, ForwardIterator1 dummy1, ForwardIterator2 dummy2, const T* , bool it_swap) { const char* const it1name = it_swap ? type_name (dummy1, (T*)0) : "X"; const char* const it2name = it_swap ? type_name (dummy2, (T*)0) : "X"; const char* const fname = it_swap ? "iter_swap" : "swap"; // generate sequential values for each default constructed T const std::size_t nseq = std::strlen (seq); // construct a sequence of `nseq' elements to pass to swap T* const tseq = T::from_char (seq, nseq); int a_val, b_val; bool success = true; std::size_t i = 1; for ( ; i < nseq; ++i) { const ForwardIterator1 it1 = make_iter (tseq, tseq, tseq + nseq, it1); const ForwardIterator2 it2 = make_iter (tseq + i, tseq, tseq + nseq, it2); a_val = (*it1).val_; b_val = (*it2).val_; it_swap ? std::iter_swap (it1, it2) : std::swap(*it1, *it2); // verify 25.2.2, p2, p7 success = a_val == (*it2).val_ && b_val == (*it1).val_; if (!success) break; } rw_assert (success, 0, line, "std::%s<%s%{?}, %s%{;}> ('%c', '%c'): got: ('%c', '%c') " "expected: ('%5$c', '%4$c') at step %zu", fname, it1name, it_swap, it2name, a_val, b_val, tseq->val_, (tseq + i)->val_, i); delete[] tseq; } template void test_iter_swap (ForwardIterator1 it1, ForwardIterator2 it2, const T* , bool it_swap) { const char* const it1name = it_swap ? type_name (it1, (T*)0) : "X"; const char* const it2name = it_swap ? type_name (it2, (T*)0) : "X"; const char* const fname = it_swap ? "iter_swap" : "swap"; rw_info (0, 0, 0, "std::%s (%s, %s)", fname, it1name, it2name); #undef TEST #define TEST(seq) \ test_iter_swap (__LINE__, seq, it1, it2, (T*)0, it_swap) TEST("ab"); TEST("abc"); TEST("abcd"); TEST("abcde"); TEST("abcdef"); TEST("abcdefg"); TEST("abcdefgh"); TEST("abcdefghi"); TEST("abcdefghij"); TEST("abcdefghijk"); } /**************************************************************************/ template void test_swap_ranges (int line, const char* seq1, const char* seq2, ForwardIterator1 it1, ForwardIterator2 it2, const T* ) { static const char* const it1name = type_name (it1, (T*)0); static const char* const it2name = type_name (it2, (T*)0); const std::size_t nseq = std::strlen (seq1); // construct a sequence of `nseq' elements to pass to swap_ranges T* const tseq1 = T::from_char (seq1, nseq); T* const tseq2 = T::from_char (seq2, nseq); const ForwardIterator1 first1 = make_iter (tseq1, tseq1, tseq1 + nseq, it1); const ForwardIterator1 last1 = make_iter (tseq1 + nseq, tseq1, tseq1 + nseq, it1); const ForwardIterator2 first2 = make_iter (tseq2, tseq2, tseq2 + nseq, it2); const ForwardIterator2 last2 = make_iter (tseq2 + nseq, tseq2, tseq2 + nseq, it2); T a, b; std::size_t last_n_op_assign = T::n_total_op_assign_; std::swap(a, b); std::size_t assigns_per_swap = T::n_total_op_assign_ - last_n_op_assign; // exercise 25.2.3 - std::swap_ranges<> () last_n_op_assign = T::n_total_op_assign_; const ForwardIterator2 res = std::swap_ranges(first1, last1, first2); // check the returned value, 25.2.2 p5 bool success = res.cur_ == last2.cur_; rw_assert (success, 0, line, "std::swap_ranges<%s, %s> (\"%s\", \"%s\") returns: " "got: %p, expected: %p", it1name, it2name, seq1, seq2, res.cur_, last2.cur_); // check that the sequences were swapped, 25.2.2 p4 std::size_t i = 0; for ( ; i < nseq; ++i) { success = (tseq1 + i)->val_ == seq2[i] && (tseq2 + i)->val_ == seq1[i]; if (!success) break; } rw_assert (success, 0, line, "std::swap_ranges<%s, %s> (\"%s\", \"%s\") error at pos %zu " "got ('%c', '%c'), expected ('%c', '%c')", it1name, it2name, seq1, seq2, i, (tseq1 + i)->val_, (tseq2 + i)->val_, seq2[i], seq1[i]); // check the complexity, 25.2.2 p6 std::size_t swaps_per_swap_ranges = (T::n_total_op_assign_ - last_n_op_assign) / assigns_per_swap; rw_assert (swaps_per_swap_ranges == nseq, 0, line, "std::swap_ranges<%s, %s> (\"%s\", \"%s\") complexity: " "got: %zu, expected: %zu swaps", it1name, it2name, seq1, seq2, swaps_per_swap_ranges, nseq); delete[] tseq1; delete[] tseq2; } template void test_swap_ranges (ForwardIterator1 it1, ForwardIterator2 it2, const T* ) { static const char* const it1name = type_name (it1, (T*)0); static const char* const it2name = type_name (it2, (T*)0); rw_info (0, 0, 0, "std::swap_ranges (%s, %1$s, %s)", it1name, it2name); #undef TEST #define TEST(seq1, seq2) \ test_swap_ranges (__LINE__, seq1, seq2, it1, it2, (T*)0) TEST("", ""); TEST("a", "z"); TEST("ab", "zy"); TEST("abc", "zyx"); TEST("abcd", "zyxw"); TEST("abcde", "zyxwv"); TEST("abcdef", "zyxwvu"); TEST("abcdefg", "zyxwvut"); TEST("abcdefgh", "zyxwvuts"); TEST("abcdefghi", "zyxwvutsr"); TEST("abcdefghij", "zyxwvutsrq"); TEST("abcdefghijk", "zyxwvutsrqp"); TEST("abcdefghijkl", "zyxwvutsrqpo"); TEST("abcdefghijklm", "zyxwvutsrqpon"); } /**************************************************************************/ /* extern */ int rw_opt_no_swap; // --no-swap /* extern */ int rw_opt_no_swap_ranges; // --no-swap_ranges /* extern */ int rw_opt_no_iter_swap; // --no-iter_swap /* 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_swap (ForwardIterator1 it1, const T* , bool test_ranges) { if (rw_opt_no_fwd_iter) { rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); } else { if (test_ranges) test_swap_ranges (it1, FwdIter(), (T*)0); else test_iter_swap (it1, FwdIter(), (T*)0, true); } if (rw_opt_no_bidir_iter) { rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); } else { if (test_ranges) test_swap_ranges (it1, BidirIter(), (T*)0); else test_iter_swap (it1, BidirIter(), (T*)0, true); } if (rw_opt_no_rnd_iter) { rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); } else { if (test_ranges) test_swap_ranges (it1, RandomAccessIter(), (T*)0); else test_iter_swap (it1, RandomAccessIter(), (T*)0, true); } } template void test_swap (const T* , bool test_ranges) { if (rw_opt_no_fwd_iter) { rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); } else { test_swap (FwdIter(), (T*)0, test_ranges); } if (rw_opt_no_bidir_iter) { rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); } else { test_swap (BidirIter(), (T*)0, test_ranges); } if (rw_opt_no_rnd_iter) { rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); } else { test_swap (RandomAccessIter(), (T*)0, test_ranges); } } /**************************************************************************/ static int run_test (int, char*[]) { if (rw_opt_no_swap) { rw_note (0, __FILE__, __LINE__, "std::swap test disabled"); } else { rw_info (0, 0, 0, "template void swap (T&, T&)"); test_iter_swap (FwdIter(), FwdIter(), (X*) 0, false); } if (rw_opt_no_swap_ranges) { rw_note (0, __FILE__, __LINE__, "std::swap_ranges test disabled"); } else { rw_info (0, 0, 0, "template %2$s " "swap_ranges (%1$s, %1$s, %2$s)", "ForwardIterator1", "ForwardIterator2"); test_swap ((X*) 0, true); } if (rw_opt_no_iter_swap) { rw_note (0, __FILE__, __LINE__, "std::iter_swap test disabled"); } else { rw_info (0, 0, 0, "template void iter_swap (%1$s, %2$s)", "ForwardIterator1", "ForwardIterator2"); test_swap ((X*) 0, false); } return 0; } /**************************************************************************/ int main (int argc, char *argv[]) { return rw_test (argc, argv, __FILE__, "lib.alg.swap", 0 /* no comment */, run_test, "|-no-swap# " "|-no-swap_ranges# " "|-no-iter_swap# " "|-no-ForwardIterator# " "|-no-BidirectionalIterator# " "|-no-RandomAccessIterator", &rw_opt_no_swap, &rw_opt_no_swap_ranges, &rw_opt_no_iter_swap, &rw_opt_no_fwd_iter, &rw_opt_no_bidir_iter, &rw_opt_no_rnd_iter); } --------------020906070103050704000708--