/*************************************************************************** * * 25.mismatch.cpp - test exercising 25.1.7 [lib.mismatch] * * $Id: 25.mismatch.cpp 510970 2007-02-23 14:57:45Z 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 1994-2006 Rogue Wave Software. * **************************************************************************/ #include // for mismatch #include // for equal_to #include // for size_t #include #include // for UserClass #include // for rw_test()... /**************************************************************************/ // exercises std::mismatch() template void test_mismatch (std::size_t N, const InputIterator1 &it1_dummy, const InputIterator2 &it2_dummy, T*, const char *predicate) { static const char* const it1name = type_name (it1_dummy, (T*)0); static const char* const it2name = type_name (it2_dummy, (T*)0); rw_info (0, 0, 0, "std::mismatch (%s, %1$s, %s%{?}, %s%{;})", it1name, it2name, 0 != predicate, predicate); // generate sequential values for each default constructed UserClass // for both lists UserClass::gen_ = gen_seq_2lists; // use ::operator new() to prevent default initialization const std::size_t size = N * sizeof (UserClass); UserClass *buf1 = _RWSTD_STATIC_CAST (UserClass*, ::operator new (size)); UserClass *buf2 = _RWSTD_STATIC_CAST (UserClass*, ::operator new (size)); const std::size_t mid_inx = N / 2; for (std::size_t i = 0; i != N; ++i) { // default-construct a new UserClass at the end of the array new (buf1 + i) UserClass (); // build a nearly identical list only missing N/2 (the N/2th // element) from it's list if (i != mid_inx) new (buf2 + i) UserClass (); } new (buf2 + mid_inx) UserClass (); for (std::size_t i = 0; i != N; ++i) { // exercise 25.1.7 - std::mismatch<>() std::size_t last_n_op_eq = UserClass::n_total_op_eq_; UserClass* const buf1_end = buf1 + i + 1; UserClass* const buf2_end = buf2 + i + 1; const InputIterator1 first1 (buf1, buf1, buf1_end); const InputIterator1 last1 (buf1_end, buf1_end, buf1_end); const InputIterator2 first2 (buf2, buf2, buf2_end); const std::equal_to pred = std::equal_to(); const std::pair result = predicate ? std::mismatch (first1, last1, first2, pred) : std::mismatch (first1, last1, first2); // verify 25.1.7, p2 UserClass* const expected_buf1_end = (i < mid_inx) ? buf1_end : buf1 + mid_inx; UserClass* const expected_buf2_end = (i < mid_inx) ? buf2_end : buf2 + mid_inx; UserClass* const res_buf1_end = buf1 + (result.first.cur_ - first1.cur_); UserClass* const res_buf2_end = buf2 + (result.second.cur_ - first2.cur_); // check that the returned iterators are valid bool success = buf1 <= res_buf1_end && res_buf1_end <= buf1_end && buf2 <= res_buf2_end && res_buf2_end <= buf2_end; rw_assert (success, 0, __LINE__, "%zu. mismatch (%s, %2$s, %s%{?}, %s%{;}): " "result { %d, %d } out of range: expected " "{ [0, %d], [0, %d] }", i, it1name, it2name, 0 != predicate, predicate, res_buf1_end - buf1, res_buf2_end - buf2, buf1_end - buf1, buf2_end - buf2); // iterators are valid check that the algorithm works correctly success = res_buf1_end->data_.val_ == expected_buf1_end->data_.val_ && res_buf2_end->data_.val_ == expected_buf2_end->data_.val_; rw_assert (success, 0, __LINE__, "%zu. mismatch (%s, %2$s, %s%{?}, %s%{;}): " "correctness: got: %d " "expected: %d, got: %d expected: %d", i, it1name, it2name, 0 != predicate, predicate, res_buf1_end->data_.val_, expected_buf1_end->data_.val_, res_buf2_end->data_.val_, expected_buf2_end->data_.val_); // verify 25.1.7, p3 success = UserClass::n_total_op_eq_ - last_n_op_eq <= (N + 1); rw_assert (success, 0, __LINE__, "%zu. mismatch (%s, %2$s, %s%{?}, %s%{;}): " "complexity: %zu <= %zu", i, it1name, it2name, 0 != predicate, predicate, UserClass::n_total_op_eq_, i + 1); if (!success) break; } ::operator delete (buf1); ::operator delete (buf2); } /**************************************************************************/ /* extern */ int rw_opt_nloops = 32; // --nloops /* extern */ int rw_opt_no_input_iter; // --no-InputIterator /* 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 /* extern */ int rw_opt_no_predicate; // --no-Predicate template void test_mismatch (const InputIterator &dummy, T*, const char *predicate) { // check that the number of loops is non-negative rw_fatal (-1 < rw_opt_nloops, 0, 0, "number of loops must be non-negative, got %d", rw_opt_nloops); const std::size_t N = std::size_t (rw_opt_nloops); if (rw_opt_no_input_iter) { rw_note (0, __FILE__, __LINE__, "InputIterator test disabled"); } else { test_mismatch (N, dummy, InputIter(0, 0, 0), (UserClass*)0, predicate); } if (rw_opt_no_fwd_iter) { rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); } else { test_mismatch (N, dummy, FwdIter(), (UserClass*)0, predicate); } if (rw_opt_no_bidir_iter) { rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); } else { test_mismatch (N, dummy, BidirIter(), (UserClass*)0, predicate); } if (rw_opt_no_rnd_iter) { rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); } else { test_mismatch (N, dummy, RandomAccessIter(), (UserClass*)0, predicate); } } /**************************************************************************/ static void test_mismatch (const char *predicate) { rw_info (0, 0, 0, "template " "std::pair<%1$s, %2$s> " "std::mismatch (%1$s, %1$s, %2$s%{?}, %s%{;})", "InputIterator1", "InputIterator2", 0 != predicate, predicate); if (rw_opt_no_input_iter) { rw_note (0, __FILE__, __LINE__, "InputIterator test disabled"); } else { test_mismatch (InputIter(0, 0, 0), (UserClass*)0, predicate); } if (rw_opt_no_fwd_iter) { rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled"); } else { test_mismatch (ConstFwdIter(), (UserClass*)0, predicate); test_mismatch (FwdIter(), (UserClass*)0, predicate); } if (rw_opt_no_bidir_iter) { rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled"); } else { test_mismatch (ConstBidirIter(), (UserClass*)0, predicate); test_mismatch (BidirIter(), (UserClass*)0, predicate); } if (rw_opt_no_rnd_iter) { rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled"); } else { test_mismatch (ConstRandomAccessIter(), (UserClass*)0, predicate); test_mismatch (RandomAccessIter(), (UserClass*)0, predicate); } } /**************************************************************************/ static int run_test (int, char*[]) { test_mismatch (0); if (rw_opt_no_predicate) { rw_note (0, __FILE__, __LINE__, "Predicate test disabled"); } else { test_mismatch ("std::equal_to"); } return 0; } /**************************************************************************/ int main (int argc, char *argv[]) { return rw_test (argc, argv, __FILE__, "lib.alg.mismatch", 0 /* no comment */, run_test, "|-nloops#" "|-no-InputIterator#" "|-no-ForwardIterator#" "|-no-BidirectionalIterator#" "|-no-RandomAccessIterator#" "|-no-Predicate", &rw_opt_nloops, &rw_opt_no_input_iter, &rw_opt_no_fwd_iter, &rw_opt_no_bidir_iter, &rw_opt_no_rnd_iter, &rw_opt_no_predicate); }