/*************************************************************************** * * unique.cpp - test exercising 25.2.8 [lib.alg.unique] * * $Id: 25.unique.cpp 510071 2007-02-21 15:58:53Z faridz $ * *************************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you 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. * * Copyright 2000-2006 Rogue Wave Software. * **************************************************************************/ #include // for unique, unique_copy #include // for strlen #include // for BinaryPredicate #include // for UserClass #include // for rw_test() /**************************************************************************/ _RWSTD_NAMESPACE (std) { #ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION // also exercise LWG issue 241: // http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#241 template FwdIter > > > unique (FwdIter > > >, FwdIter > > >); template FwdIter > > > unique (FwdIter > > >, FwdIter > > >, binary_predicate > > >); template OutputIter > > > unique_copy (InputIter > > >, InputIter > > >, OutputIter > > >); template OutputIter > > > unique_copy (InputIter > > >, InputIter > > >, OutputIter > > >, binary_predicate > > >); #endif // _RWSTD_NO_EXPLICIT_INSTANTIATION } // namespace std /**************************************************************************/ // exercises std::unique and std::unique_copy() template void test_unique (int line, const char *src, const char *dst, const FwdIterator &it, const FwdCopyIterator &itc, const OutIterator &out, const T*, const Predicate *ppred, bool use_copy) { const char* const outname = type_name (out, (T*)0); const char* const itname = use_copy ? type_name (itc, (T*)0) : type_name (it, (T*)0); const char* const fname = use_copy ? "unique_copy" : "unique"; const char* const funname = ppred ? "BinaryPredicate" : "operator==()"; const std::size_t nsrc = std::strlen (src); const std::size_t ndst = std::strlen (dst); T* const xsrc = T::from_char (src, nsrc); T* xdst = use_copy ? T::from_char (dst, ndst) : xsrc; T* const xsrc_end = xsrc + nsrc; T* const xdst_end = xdst + ndst; const FwdIterator first = make_iter (xsrc, xsrc, xsrc_end, it); const FwdIterator last = make_iter (xsrc_end, xsrc, xsrc_end, it); const FwdCopyIterator first_c = make_iter (xsrc, xsrc, xsrc_end, itc); const FwdCopyIterator last_c = make_iter (xsrc_end, xsrc, xsrc_end, itc); const OutIterator result = make_iter (xdst, xdst, xdst_end, out); // compute the actual number of invocations of operator==() or predicate std::size_t n_total_ops = ppred ? Predicate::n_total_op_fcall_ : T::n_total_op_eq_; OutIterator res_c (0, 0, 0); FwdIterator res (0, 0, 0); if (use_copy) res_c = ppred ? std::unique_copy (first_c, last_c, result, *ppred) : std::unique_copy (first_c, last_c, result); else res = ppred ? std::unique (first, last, *ppred) : std::unique (first, last); const T* const f_cur = use_copy ? result.cur_ : first.cur_; const T* const r_cur = use_copy ? res_c.cur_ : res.cur_; bool success = r_cur == f_cur + ndst; rw_assert (success, 0, line, "line %d: std::%s <%s%{?}, %s%{;}%{?}, %s%{;}>(\"%s\", ...) " "== (res + %zu), got (res + %td)", __LINE__, fname, itname, use_copy, outname, 0 != ppred, funname, src, ndst, r_cur - f_cur); // verify that the copied sequence matches the expected range const T* const mismatch = T::mismatch (xdst, dst, ndst); rw_assert (0 == mismatch, 0, line, "line %d: std::%s <%s%{?}, %s%{;}%{?}, %s%{;}>(\"%s\", ...) " "==> \"%s\", got \"%{X=*.@}\"", __LINE__, fname, itname, use_copy, outname, 0 != ppred, funname, src, dst, int (ndst), mismatch, xdst); if (ppred) n_total_ops = ppred->n_total_op_fcall_ - n_total_ops; else n_total_ops = T::n_total_op_eq_ - n_total_ops; // compute the expected number of invocations of operator==() or predicate const std::size_t n_expect_ops = nsrc ? nsrc - 1 : 0; // verify the number of applications of operator==() or predicate rw_assert (n_total_ops <= n_expect_ops, 0, line, "line %d: std::%s <%s%{?}, %s%{;}%{?}, %s%{;}>(\"%s\", ...) " "%s called %zu times, %zu expected", __LINE__, fname, itname, use_copy, outname, 0 != ppred, funname, src, funname, n_total_ops, n_expect_ops); } /**************************************************************************/ template void test_unique (const FwdIterator &it, const FwdCopyIterator &itc, const OutIterator &out, const T*, const Predicate *ppred, bool use_copy) { const char* const outname = type_name (out, (T*)0); const char* const itname = use_copy ? type_name (itc, (T*)0) : type_name (it, (T*)0); const char* const fname = use_copy ? "unique_copy" : "unique"; const char* const funname = ppred ? "BinaryPredicate" : "operator==()"; rw_info (0, 0, 0, "std::%s (%s, %2$s%{?}, %s%{;}%{?}, %s%{;})", fname, itname, use_copy, outname, ppred, funname); #define TEST(src, dst) \ test_unique (__LINE__, src, dst, it, itc, out, (T*)0, \ ppred, use_copy) // +---------------- source sequence // | +- destination sequence // | | // v v TEST ("", ""); TEST ("a", "a"); TEST ("ab", "ab"); TEST ("abc", "abc"); TEST ("abcd", "abcd"); TEST ("abcde", "abcde"); TEST ("abcdef", "abcdef"); TEST ("abcdefg", "abcdefg"); TEST ("abcdefgh", "abcdefgh"); TEST ("abcdefghi", "abcdefghi"); TEST ("abcdefghij", "abcdefghij"); TEST ("abcdefghijk", "abcdefghijk"); TEST ("abcabc", "abcabc"); TEST ("abcabcabc", "abcabcabc"); TEST ("abcdabcd", "abcdabcd"); TEST ("abcdabcdabcd","abcdabcdabcd"); TEST ("aa", "a"); TEST ("aaa", "a"); TEST ("aab", "ab"); TEST ("aaa", "a"); TEST ("aaaa", "a"); TEST ("aaabb", "ab"); TEST ("aaabbb", "ab"); TEST ("abba", "aba"); TEST ("abbba", "aba"); TEST ("aaabbba", "aba"); TEST ("aaabbbaa", "aba"); TEST ("aaabbbaaa", "aba"); TEST ("aaabbbaaab", "abab"); TEST ("aaabbbaaabb", "abab"); TEST ("abbbbbaaabb", "abab"); TEST ("abaaaaaaabb", "abab"); TEST ("ababbbbbbbb", "abab"); } /**************************************************************************/ /* extern */ int rw_opt_no_unique; // --no-unique /* extern */ int rw_opt_no_unique_copy; // --no-unique_copy /* 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_unique (const FwdIterator &it, 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 (rw_opt_no_fwd_iter) { rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); } else { test_unique (fwd_iter, it, fwd_iter, (T*)0, ppred, true); } if (rw_opt_no_bidir_iter) { rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); } else { test_unique (bidir_iter, it, bidir_iter, (T*)0, ppred, true); } if (rw_opt_no_rnd_iter) { rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); } else { test_unique (rand_iter, it, rand_iter, (T*)0, ppred, true); } if (rw_opt_no_output_iter) { rw_note (0, __FILE__, __LINE__, "OutputIterator test disabled"); } else { test_unique (fwd_iter, it, output_iter, (T*)0, ppred, true); } } /**************************************************************************/ template void test_unique (const T*, const Predicate *ppred, bool use_copy) { static const InputIter input_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); rw_info (0, 0, 0, "template " "%s std::%s (%1$s, %1$s%{?}, %3$s%{;}%{?}, %5$s%{;})", use_copy ? "InputIterator" : "ForwardIterator", use_copy, "OutputIterator", 0 != ppred, "Predicate", use_copy ? "OutputIterator" : "ForwardIterator", use_copy ? "unique_copy" : "unique", use_copy, 0 != ppred); if (use_copy) { if (rw_opt_no_input_iter) { rw_note (0, __FILE__, __LINE__, "InputIterator test disabled"); } else { test_unique (input_iter, (T*)0, ppred); } } if (rw_opt_no_fwd_iter) { rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); } else { if (use_copy) test_unique (fwd_iter, (T*)0, ppred); else test_unique (fwd_iter, fwd_iter, fwd_iter, (T*)0, ppred, false); } if (rw_opt_no_bidir_iter) { rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); } else { if (use_copy) test_unique (bidir_iter, (T*)0, ppred); else test_unique (bidir_iter, bidir_iter, bidir_iter, (T*)0, ppred, false); } if (rw_opt_no_rnd_iter) { rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); } else { if (use_copy) test_unique (rand_iter, (T*)0, ppred); else test_unique (rand_iter, rand_iter, rand_iter, (T*)0, ppred, false); } } /**************************************************************************/ static int run_test (int, char*[]) { const BinaryPredicate pred (BinaryPredicate::op_equals); if (rw_opt_no_unique) { rw_note (0, __FILE__, __LINE__, "std::unique test disabled"); } else { test_unique ((UserClass*)0, (BinaryPredicate*)0, false); if (rw_opt_no_predicate) { rw_note (0, __FILE__, __LINE__, "std::unique predicate test disabled"); } else { test_unique ((UserClass*)0, &pred, false); } } if (rw_opt_no_unique_copy) { rw_note (0, __FILE__, __LINE__, "std::unique_copy test disabled"); } else { test_unique ((UserClass*) 0, (BinaryPredicate*)0, true); if (rw_opt_no_predicate) { rw_note (0, __FILE__, __LINE__, "std::unique_copy predicate test disabled"); } else { test_unique ((UserClass*)0, &pred, true); } } return 0; } /**************************************************************************/ int main (int argc, char *argv[]) { return rw_test (argc, argv, __FILE__, "lib.alg.unique", 0 /* no comment */, run_test, "|-no-unique# " "|-no-unique_copy# " "|-no-InputIterator# " "|-no-OutputIterator# " "|-no-ForwardIterator# " "|-no-BidirectionalIterator# " "|-no-RandomAccessIterator# " "|-no-predicate", &rw_opt_no_unique, &rw_opt_no_unique_copy, &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, &rw_opt_no_predicate); }