| // (C) Copyright Dave Abrahams and Thomas Becker 2003. Distributed |
| // under the Boost Software License, Version 1.0. (See accompanying |
| // file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| // |
| |
| // File: |
| // ===== |
| // zip_iterator_test_main.cpp |
| |
| // Author: |
| // ======= |
| // Thomas Becker |
| |
| // Created: |
| // ======== |
| // Jul 15, 2003 |
| |
| // Purpose: |
| // ======== |
| // Test driver for zip_iterator.hpp |
| |
| // Compilers Tested: |
| // ================= |
| // Metrowerks Codewarrior Pro 7.2, 8.3 |
| // gcc 2.95.3 |
| // gcc 3.2 |
| // Microsoft VC 6sp5 (test fails due to some compiler bug) |
| // Microsoft VC 7 (works) |
| // Microsoft VC 7.1 |
| // Intel 5 |
| // Intel 6 |
| // Intel 7.1 |
| // Intel 8 |
| // Borland 5.5.1 (broken due to lack of support from Boost.Tuples) |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Includes |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| #include <boost/iterator/zip_iterator.hpp> |
| #include <boost/iterator/zip_iterator.hpp> // 2nd #include tests #include guard. |
| #include <iostream> |
| #include <vector> |
| #include <list> |
| #include <set> |
| #include <functional> |
| #include <boost/tuple/tuple.hpp> |
| #include <boost/iterator/transform_iterator.hpp> |
| #include <boost/iterator/is_readable_iterator.hpp> |
| #include <boost/type_traits/is_same.hpp> |
| #include <boost/detail/workaround.hpp> |
| #include <stddef.h> |
| |
| template <class It> |
| struct pure_traversal |
| : boost::detail::pure_traversal_tag< |
| typename boost::iterator_traversal<It>::type |
| > |
| {}; |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Das Main Funktion |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| int main( void ) |
| { |
| |
| std::cout << "\n" |
| << "***********************************************\n" |
| << "* *\n" |
| << "* Test driver for boost::zip_iterator *\n" |
| << "* Copyright Thomas Becker 2003 *\n" |
| << "* *\n" |
| << "***********************************************\n\n" |
| << std::flush; |
| |
| size_t num_successful_tests = 0; |
| size_t num_failed_tests = 0; |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator construction and dereferencing |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator construction and dereferencing: " |
| << std::flush; |
| |
| std::vector<double> vect1(3); |
| vect1[0] = 42.; |
| vect1[1] = 43.; |
| vect1[2] = 44.; |
| |
| std::set<int> intset; |
| intset.insert(52); |
| intset.insert(53); |
| intset.insert(54); |
| // |
| |
| typedef |
| boost::zip_iterator< |
| boost::tuples::tuple< |
| std::set<int>::iterator |
| , std::vector<double>::iterator |
| > |
| > zit_mixed; |
| |
| zit_mixed zip_it_mixed = zit_mixed( |
| boost::make_tuple( |
| intset.begin() |
| , vect1.begin() |
| ) |
| ); |
| |
| boost::tuples::tuple<int, double> val_tuple( |
| *zip_it_mixed); |
| |
| boost::tuples::tuple<const int&, double&> ref_tuple( |
| *zip_it_mixed); |
| |
| double dblOldVal = boost::tuples::get<1>(ref_tuple); |
| boost::tuples::get<1>(ref_tuple) -= 41.; |
| |
| if( 52 == boost::tuples::get<0>(val_tuple) && |
| 42. == boost::tuples::get<1>(val_tuple) && |
| 52 == boost::tuples::get<0>(ref_tuple) && |
| 1. == boost::tuples::get<1>(ref_tuple) && |
| 1. == *vect1.begin() |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| // Undo change to vect1 |
| boost::tuples::get<1>(ref_tuple) = dblOldVal; |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator with 12 components |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterators with 12 components: " |
| << std::flush; |
| |
| // Declare 12 containers |
| // |
| std::list<int> li1; |
| li1.push_back(1); |
| std::set<int> se1; |
| se1.insert(2); |
| std::vector<int> ve1; |
| ve1.push_back(3); |
| // |
| std::list<int> li2; |
| li2.push_back(4); |
| std::set<int> se2; |
| se2.insert(5); |
| std::vector<int> ve2; |
| ve2.push_back(6); |
| // |
| std::list<int> li3; |
| li3.push_back(7); |
| std::set<int> se3; |
| se3.insert(8); |
| std::vector<int> ve3; |
| ve3.push_back(9); |
| // |
| std::list<int> li4; |
| li4.push_back(10); |
| std::set<int> se4; |
| se4.insert(11); |
| std::vector<int> ve4; |
| ve4.push_back(12); |
| |
| // typedefs for cons lists of iterators. |
| typedef boost::tuples::cons< |
| std::set<int>::iterator, |
| boost::tuples::tuple< |
| std::vector<int>::iterator, |
| std::list<int>::iterator, |
| std::set<int>::iterator, |
| std::vector<int>::iterator, |
| std::list<int>::iterator, |
| std::set<int>::iterator, |
| std::vector<int>::iterator, |
| std::list<int>::iterator, |
| std::set<int>::iterator, |
| std::vector<int>::const_iterator |
| >::inherited |
| > cons_11_its_type; |
| // |
| typedef boost::tuples::cons< |
| std::list<int>::const_iterator, |
| cons_11_its_type |
| > cons_12_its_type; |
| |
| // typedefs for cons lists for dereferencing the zip iterator |
| // made from the cons list above. |
| typedef boost::tuples::cons< |
| const int&, |
| boost::tuples::tuple< |
| int&, |
| int&, |
| const int&, |
| int&, |
| int&, |
| const int&, |
| int&, |
| int&, |
| const int&, |
| const int& |
| >::inherited |
| > cons_11_refs_type; |
| // |
| typedef boost::tuples::cons< |
| const int&, |
| cons_11_refs_type |
| > cons_12_refs_type; |
| |
| // typedef for zip iterator with 12 elements |
| typedef boost::zip_iterator<cons_12_its_type> zip_it_12_type; |
| |
| // Declare a 12-element zip iterator. |
| zip_it_12_type zip_it_12( |
| cons_12_its_type( |
| li1.begin(), |
| cons_11_its_type( |
| se1.begin(), |
| boost::make_tuple( |
| ve1.begin(), |
| li2.begin(), |
| se2.begin(), |
| ve2.begin(), |
| li3.begin(), |
| se3.begin(), |
| ve3.begin(), |
| li4.begin(), |
| se4.begin(), |
| ve4.begin() |
| ) |
| ) |
| ) |
| ); |
| |
| // Dereference, mess with the result a little. |
| cons_12_refs_type zip_it_12_dereferenced(*zip_it_12); |
| boost::tuples::get<9>(zip_it_12_dereferenced) = 42; |
| |
| // Make a copy and move it a little to force some instantiations. |
| zip_it_12_type zip_it_12_copy(zip_it_12); |
| ++zip_it_12_copy; |
| |
| if( boost::tuples::get<11>(zip_it_12.get_iterator_tuple()) == ve4.begin() && |
| boost::tuples::get<11>(zip_it_12_copy.get_iterator_tuple()) == ve4.end() && |
| 1 == boost::tuples::get<0>(zip_it_12_dereferenced) && |
| 12 == boost::tuples::get<11>(zip_it_12_dereferenced) && |
| 42 == *(li4.begin()) |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator incrementing and dereferencing |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator ++ and *: " |
| << std::flush; |
| |
| std::vector<double> vect2(3); |
| vect2[0] = 2.2; |
| vect2[1] = 3.3; |
| vect2[2] = 4.4; |
| |
| boost::zip_iterator< |
| boost::tuples::tuple< |
| std::vector<double>::const_iterator, |
| std::vector<double>::const_iterator |
| > |
| > |
| zip_it_begin( |
| boost::make_tuple( |
| vect1.begin(), |
| vect2.begin() |
| ) |
| ); |
| |
| boost::zip_iterator< |
| boost::tuples::tuple< |
| std::vector<double>::const_iterator, |
| std::vector<double>::const_iterator |
| > |
| > |
| zip_it_run( |
| boost::make_tuple( |
| vect1.begin(), |
| vect2.begin() |
| ) |
| ); |
| |
| boost::zip_iterator< |
| boost::tuples::tuple< |
| std::vector<double>::const_iterator, |
| std::vector<double>::const_iterator |
| > |
| > |
| zip_it_end( |
| boost::make_tuple( |
| vect1.end(), |
| vect2.end() |
| ) |
| ); |
| |
| if( zip_it_run == zip_it_begin && |
| 42. == boost::tuples::get<0>(*zip_it_run) && |
| 2.2 == boost::tuples::get<1>(*zip_it_run) && |
| 43. == boost::tuples::get<0>(*(++zip_it_run)) && |
| 3.3 == boost::tuples::get<1>(*zip_it_run) && |
| 44. == boost::tuples::get<0>(*(++zip_it_run)) && |
| 4.4 == boost::tuples::get<1>(*zip_it_run) && |
| zip_it_end == ++zip_it_run |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator decrementing and dereferencing |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator -- and *: " |
| << std::flush; |
| |
| if( zip_it_run == zip_it_end && |
| zip_it_end == zip_it_run-- && |
| 44. == boost::tuples::get<0>(*zip_it_run) && |
| 4.4 == boost::tuples::get<1>(*zip_it_run) && |
| 43. == boost::tuples::get<0>(*(--zip_it_run)) && |
| 3.3 == boost::tuples::get<1>(*zip_it_run) && |
| 42. == boost::tuples::get<0>(*(--zip_it_run)) && |
| 2.2 == boost::tuples::get<1>(*zip_it_run) && |
| zip_it_begin == zip_it_run |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator copy construction and equality |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator copy construction and equality: " |
| << std::flush; |
| |
| boost::zip_iterator< |
| boost::tuples::tuple< |
| std::vector<double>::const_iterator, |
| std::vector<double>::const_iterator |
| > |
| > zip_it_run_copy(zip_it_run); |
| |
| if(zip_it_run == zip_it_run && zip_it_run == zip_it_run_copy) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator inequality |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator inequality: " |
| << std::flush; |
| |
| if(!(zip_it_run != zip_it_run_copy) && zip_it_run != ++zip_it_run_copy) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator less than |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator less than: " |
| << std::flush; |
| |
| // Note: zip_it_run_copy == zip_it_run + 1 |
| // |
| if( zip_it_run < zip_it_run_copy && |
| !( zip_it_run < --zip_it_run_copy) && |
| zip_it_run == zip_it_run_copy |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator less than or equal |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "zip iterator less than or equal: " |
| << std::flush; |
| |
| // Note: zip_it_run_copy == zip_it_run |
| // |
| ++zip_it_run; |
| zip_it_run_copy += 2; |
| |
| if( zip_it_run <= zip_it_run_copy && |
| zip_it_run <= --zip_it_run_copy && |
| !( zip_it_run <= --zip_it_run_copy) && |
| zip_it_run <= zip_it_run |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator greater than |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator greater than: " |
| << std::flush; |
| |
| // Note: zip_it_run_copy == zip_it_run - 1 |
| // |
| if( zip_it_run > zip_it_run_copy && |
| !( zip_it_run > ++zip_it_run_copy) && |
| zip_it_run == zip_it_run_copy |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator greater than or equal |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator greater than or equal: " |
| << std::flush; |
| |
| ++zip_it_run; |
| |
| // Note: zip_it_run == zip_it_run_copy + 1 |
| // |
| if( zip_it_run >= zip_it_run_copy && |
| --zip_it_run >= zip_it_run_copy && |
| ! (zip_it_run >= ++zip_it_run_copy) |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator + int |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator + int: " |
| << std::flush; |
| |
| // Note: zip_it_run == zip_it_run_copy - 1 |
| // |
| zip_it_run = zip_it_run + 2; |
| ++zip_it_run_copy; |
| |
| if( zip_it_run == zip_it_run_copy && zip_it_run == zip_it_begin + 3 ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator - int |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator - int: " |
| << std::flush; |
| |
| // Note: zip_it_run == zip_it_run_copy, and both are at end position |
| // |
| zip_it_run = zip_it_run - 2; |
| --zip_it_run_copy; |
| --zip_it_run_copy; |
| |
| if( zip_it_run == zip_it_run_copy && (zip_it_run - 1) == zip_it_begin ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator += |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator +=: " |
| << std::flush; |
| |
| // Note: zip_it_run == zip_it_run_copy, and both are at begin + 1 |
| // |
| zip_it_run += 2; |
| if( zip_it_run == zip_it_begin + 3 ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator -= |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator -=: " |
| << std::flush; |
| |
| // Note: zip_it_run is at end position, zip_it_run_copy is at |
| // begin plus one. |
| // |
| zip_it_run -= 2; |
| if( zip_it_run == zip_it_run_copy ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator getting member iterators |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator member iterators: " |
| << std::flush; |
| |
| // Note: zip_it_run and zip_it_run_copy are both at |
| // begin plus one. |
| // |
| if( boost::tuples::get<0>(zip_it_run.get_iterator_tuple()) == vect1.begin() + 1 && |
| boost::tuples::get<1>(zip_it_run.get_iterator_tuple()) == vect2.begin() + 1 |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Making zip iterators |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Making zip iterators: " |
| << std::flush; |
| |
| std::vector<boost::tuples::tuple<double, double> > |
| vect_of_tuples(3); |
| |
| std::copy( |
| boost::make_zip_iterator( |
| boost::make_tuple( |
| vect1.begin(), |
| vect2.begin() |
| ) |
| ), |
| boost::make_zip_iterator( |
| boost::make_tuple( |
| vect1.end(), |
| vect2.end() |
| ) |
| ), |
| vect_of_tuples.begin() |
| ); |
| |
| if( 42. == boost::tuples::get<0>(*vect_of_tuples.begin()) && |
| 2.2 == boost::tuples::get<1>(*vect_of_tuples.begin()) && |
| 43. == boost::tuples::get<0>(*(vect_of_tuples.begin() + 1)) && |
| 3.3 == boost::tuples::get<1>(*(vect_of_tuples.begin() + 1)) && |
| 44. == boost::tuples::get<0>(*(vect_of_tuples.begin() + 2)) && |
| 4.4 == boost::tuples::get<1>(*(vect_of_tuples.begin() + 2)) |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator non-const --> const conversion |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator non-const to const conversion: " |
| << std::flush; |
| |
| boost::zip_iterator< |
| boost::tuples::tuple< |
| std::set<int>::const_iterator, |
| std::vector<double>::const_iterator |
| > |
| > |
| zip_it_const( |
| boost::make_tuple( |
| intset.begin(), |
| vect2.begin() |
| ) |
| ); |
| // |
| boost::zip_iterator< |
| boost::tuples::tuple< |
| std::set<int>::iterator, |
| std::vector<double>::const_iterator |
| > |
| > |
| zip_it_half_const( |
| boost::make_tuple( |
| intset.begin(), |
| vect2.begin() |
| ) |
| ); |
| // |
| boost::zip_iterator< |
| boost::tuples::tuple< |
| std::set<int>::iterator, |
| std::vector<double>::iterator |
| > |
| > |
| zip_it_non_const( |
| boost::make_tuple( |
| intset.begin(), |
| vect2.begin() |
| ) |
| ); |
| |
| zip_it_half_const = ++zip_it_non_const; |
| zip_it_const = zip_it_half_const; |
| ++zip_it_const; |
| // zip_it_non_const = ++zip_it_const; // Error: can't convert from const to non-const |
| |
| if( 54 == boost::tuples::get<0>(*zip_it_const) && |
| 4.4 == boost::tuples::get<1>(*zip_it_const) && |
| 53 == boost::tuples::get<0>(*zip_it_half_const) && |
| 3.3 == boost::tuples::get<1>(*zip_it_half_const) |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| // |
| // Zip iterator categories |
| // |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| std::cout << "Zip iterator categories: " |
| << std::flush; |
| |
| // The big iterator of the previous test has vector, list, and set iterators. |
| // Therefore, it must be bidirectional, but not random access. |
| bool bBigItIsBidirectionalIterator = boost::is_convertible< |
| boost::iterator_traversal<zip_it_12_type>::type |
| , boost::bidirectional_traversal_tag |
| >::value; |
| |
| bool bBigItIsRandomAccessIterator = boost::is_convertible< |
| boost::iterator_traversal<zip_it_12_type>::type |
| , boost::random_access_traversal_tag |
| >::value; |
| |
| // A combining iterator with all vector iterators must have random access |
| // traversal. |
| // |
| typedef boost::zip_iterator< |
| boost::tuples::tuple< |
| std::vector<double>::const_iterator, |
| std::vector<double>::const_iterator |
| > |
| > all_vects_type; |
| |
| bool bAllVectsIsRandomAccessIterator = boost::is_convertible< |
| boost::iterator_traversal<all_vects_type>::type |
| , boost::random_access_traversal_tag |
| >::value; |
| |
| // The big test. |
| if( bBigItIsBidirectionalIterator && |
| ! bBigItIsRandomAccessIterator && |
| bAllVectsIsRandomAccessIterator |
| ) |
| { |
| ++num_successful_tests; |
| std::cout << "OK" << std::endl; |
| } |
| else |
| { |
| ++num_failed_tests = 0; |
| std::cout << "not OK" << std::endl; |
| } |
| |
| // Done |
| // |
| std::cout << "\nTest Result:" |
| << "\n============" |
| << "\nNumber of successful tests: " << static_cast<unsigned int>(num_successful_tests) |
| << "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests) |
| << std::endl; |
| |
| return num_failed_tests; |
| } |
| |