1 // (C) Copyright Dave Abrahams and Thomas Becker 2003. Distributed
2 // under the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
9 // zip_iterator_test_main.cpp
21 // Test driver for zip_iterator.hpp
25 // Metrowerks Codewarrior Pro 7.2, 8.3
28 // Microsoft VC 6sp5 (test fails due to some compiler bug)
29 // Microsoft VC 7 (works)
35 // Borland 5.5.1 (broken due to lack of support from Boost.Tuples)
37 /////////////////////////////////////////////////////////////////////////////
41 /////////////////////////////////////////////////////////////////////////////
43 #include <boost/iterator/zip_iterator.hpp>
44 #include <boost/iterator/zip_iterator.hpp> // 2nd #include tests #include guard.
51 #include <boost/iterator/transform_iterator.hpp>
52 #include <boost/iterator/is_readable_iterator.hpp>
53 #include <boost/type_traits/is_same.hpp>
54 #include <boost/detail/workaround.hpp>
58 /// Tests for https://svn.boost.org/trac/boost/ticket/1517
59 int to_value(int const &v)
69 boost::make_zip_iterator(
71 boost::make_transform_iterator(rng1.begin(), &to_value), // BidirectionalInput
72 rng2.begin() // RandomAccess
78 /////////////////////////////////////////////////////////////////////////////
82 /////////////////////////////////////////////////////////////////////////////
90 << "***********************************************\n"
92 << "* Test driver for boost::zip_iterator *\n"
93 << "* Copyright Thomas Becker 2003 *\n"
95 << "***********************************************\n\n"
98 size_t num_successful_tests = 0;
99 size_t num_failed_tests = 0;
101 /////////////////////////////////////////////////////////////////////////////
103 // Zip iterator construction and dereferencing
105 /////////////////////////////////////////////////////////////////////////////
107 std::cout << "Zip iterator construction and dereferencing: "
110 std::vector<double> vect1(3);
115 std::set<int> intset;
124 std::set<int>::iterator
125 , std::vector<double>::iterator
129 zit_mixed zip_it_mixed = zit_mixed(
136 ZI_TUPLE<int, double> val_tuple(
139 ZI_TUPLE<const int&, double&> ref_tuple(
142 double dblOldVal = ZI_TUPLE_GET(1)(ref_tuple);
143 ZI_TUPLE_GET(1)(ref_tuple) -= 41.;
145 if( 52 == ZI_TUPLE_GET(0)(val_tuple) &&
146 42. == ZI_TUPLE_GET(1)(val_tuple) &&
147 52 == ZI_TUPLE_GET(0)(ref_tuple) &&
148 1. == ZI_TUPLE_GET(1)(ref_tuple) &&
152 ++num_successful_tests;
153 std::cout << "OK" << std::endl;
158 std::cout << "not OK" << std::endl;
161 // Undo change to vect1
162 ZI_TUPLE_GET(1)(ref_tuple) = dblOldVal;
164 #if defined(ZI_USE_BOOST_TUPLE)
166 /////////////////////////////////////////////////////////////////////////////
168 // Zip iterator with 12 components
170 /////////////////////////////////////////////////////////////////////////////
172 std::cout << "Zip iterators with 12 components: "
175 // Declare 12 containers
181 std::vector<int> ve1;
188 std::vector<int> ve2;
195 std::vector<int> ve3;
202 std::vector<int> ve4;
205 // typedefs for cons lists of iterators.
206 typedef boost::tuples::cons<
207 std::set<int>::iterator,
209 std::vector<int>::iterator,
210 std::list<int>::iterator,
211 std::set<int>::iterator,
212 std::vector<int>::iterator,
213 std::list<int>::iterator,
214 std::set<int>::iterator,
215 std::vector<int>::iterator,
216 std::list<int>::iterator,
217 std::set<int>::iterator,
218 std::vector<int>::const_iterator
222 typedef boost::tuples::cons<
223 std::list<int>::const_iterator,
227 // typedefs for cons lists for dereferencing the zip iterator
228 // made from the cons list above.
229 typedef boost::tuples::cons<
245 typedef boost::tuples::cons<
250 // typedef for zip iterator with 12 elements
251 typedef boost::zip_iterator<cons_12_its_type> zip_it_12_type;
253 // Declare a 12-element zip iterator.
254 zip_it_12_type zip_it_12(
275 // Dereference, mess with the result a little.
276 cons_12_refs_type zip_it_12_dereferenced(*zip_it_12);
277 ZI_TUPLE_GET(9)(zip_it_12_dereferenced) = 42;
279 // Make a copy and move it a little to force some instantiations.
280 zip_it_12_type zip_it_12_copy(zip_it_12);
283 if( ZI_TUPLE_GET(11)(zip_it_12.get_iterator_tuple()) == ve4.begin() &&
284 ZI_TUPLE_GET(11)(zip_it_12_copy.get_iterator_tuple()) == ve4.end() &&
285 1 == ZI_TUPLE_GET(0)(zip_it_12_dereferenced) &&
286 12 == ZI_TUPLE_GET(11)(zip_it_12_dereferenced) &&
290 ++num_successful_tests;
291 std::cout << "OK" << std::endl;
296 std::cout << "not OK" << std::endl;
301 /////////////////////////////////////////////////////////////////////////////
303 // Zip iterator incrementing and dereferencing
305 /////////////////////////////////////////////////////////////////////////////
307 std::cout << "Zip iterator ++ and *: "
310 std::vector<double> vect2(3);
317 std::vector<double>::const_iterator,
318 std::vector<double>::const_iterator
330 std::vector<double>::const_iterator,
331 std::vector<double>::const_iterator
343 std::vector<double>::const_iterator,
344 std::vector<double>::const_iterator
354 if( zip_it_run == zip_it_begin &&
355 42. == ZI_TUPLE_GET(0)(*zip_it_run) &&
356 2.2 == ZI_TUPLE_GET(1)(*zip_it_run) &&
357 43. == ZI_TUPLE_GET(0)(*(++zip_it_run)) &&
358 3.3 == ZI_TUPLE_GET(1)(*zip_it_run) &&
359 44. == ZI_TUPLE_GET(0)(*(++zip_it_run)) &&
360 4.4 == ZI_TUPLE_GET(1)(*zip_it_run) &&
361 zip_it_end == ++zip_it_run
364 ++num_successful_tests;
365 std::cout << "OK" << std::endl;
370 std::cout << "not OK" << std::endl;
373 /////////////////////////////////////////////////////////////////////////////
375 // Zip iterator decrementing and dereferencing
377 /////////////////////////////////////////////////////////////////////////////
379 std::cout << "Zip iterator -- and *: "
382 if( zip_it_run == zip_it_end &&
383 zip_it_end == zip_it_run-- &&
384 44. == ZI_TUPLE_GET(0)(*zip_it_run) &&
385 4.4 == ZI_TUPLE_GET(1)(*zip_it_run) &&
386 43. == ZI_TUPLE_GET(0)(*(--zip_it_run)) &&
387 3.3 == ZI_TUPLE_GET(1)(*zip_it_run) &&
388 42. == ZI_TUPLE_GET(0)(*(--zip_it_run)) &&
389 2.2 == ZI_TUPLE_GET(1)(*zip_it_run) &&
390 zip_it_begin == zip_it_run
393 ++num_successful_tests;
394 std::cout << "OK" << std::endl;
399 std::cout << "not OK" << std::endl;
402 /////////////////////////////////////////////////////////////////////////////
404 // Zip iterator copy construction and equality
406 /////////////////////////////////////////////////////////////////////////////
408 std::cout << "Zip iterator copy construction and equality: "
413 std::vector<double>::const_iterator,
414 std::vector<double>::const_iterator
416 > zip_it_run_copy(zip_it_run);
418 if(zip_it_run == zip_it_run && zip_it_run == zip_it_run_copy)
420 ++num_successful_tests;
421 std::cout << "OK" << std::endl;
426 std::cout << "not OK" << std::endl;
429 /////////////////////////////////////////////////////////////////////////////
431 // Zip iterator inequality
433 /////////////////////////////////////////////////////////////////////////////
435 std::cout << "Zip iterator inequality: "
438 if(!(zip_it_run != zip_it_run_copy) && zip_it_run != ++zip_it_run_copy)
440 ++num_successful_tests;
441 std::cout << "OK" << std::endl;
446 std::cout << "not OK" << std::endl;
449 /////////////////////////////////////////////////////////////////////////////
451 // Zip iterator less than
453 /////////////////////////////////////////////////////////////////////////////
455 std::cout << "Zip iterator less than: "
458 // Note: zip_it_run_copy == zip_it_run + 1
460 if( zip_it_run < zip_it_run_copy &&
461 !( zip_it_run < --zip_it_run_copy) &&
462 zip_it_run == zip_it_run_copy
465 ++num_successful_tests;
466 std::cout << "OK" << std::endl;
471 std::cout << "not OK" << std::endl;
474 /////////////////////////////////////////////////////////////////////////////
476 // Zip iterator less than or equal
478 /////////////////////////////////////////////////////////////////////////////
480 std::cout << "zip iterator less than or equal: "
483 // Note: zip_it_run_copy == zip_it_run
486 zip_it_run_copy += 2;
488 if( zip_it_run <= zip_it_run_copy &&
489 zip_it_run <= --zip_it_run_copy &&
490 !( zip_it_run <= --zip_it_run_copy) &&
491 zip_it_run <= zip_it_run
494 ++num_successful_tests;
495 std::cout << "OK" << std::endl;
500 std::cout << "not OK" << std::endl;
503 /////////////////////////////////////////////////////////////////////////////
505 // Zip iterator greater than
507 /////////////////////////////////////////////////////////////////////////////
509 std::cout << "Zip iterator greater than: "
512 // Note: zip_it_run_copy == zip_it_run - 1
514 if( zip_it_run > zip_it_run_copy &&
515 !( zip_it_run > ++zip_it_run_copy) &&
516 zip_it_run == zip_it_run_copy
519 ++num_successful_tests;
520 std::cout << "OK" << std::endl;
525 std::cout << "not OK" << std::endl;
528 /////////////////////////////////////////////////////////////////////////////
530 // Zip iterator greater than or equal
532 /////////////////////////////////////////////////////////////////////////////
534 std::cout << "Zip iterator greater than or equal: "
539 // Note: zip_it_run == zip_it_run_copy + 1
541 if( zip_it_run >= zip_it_run_copy &&
542 --zip_it_run >= zip_it_run_copy &&
543 ! (zip_it_run >= ++zip_it_run_copy)
546 ++num_successful_tests;
547 std::cout << "OK" << std::endl;
552 std::cout << "not OK" << std::endl;
555 /////////////////////////////////////////////////////////////////////////////
557 // Zip iterator + int
559 /////////////////////////////////////////////////////////////////////////////
561 std::cout << "Zip iterator + int: "
564 // Note: zip_it_run == zip_it_run_copy - 1
566 zip_it_run = zip_it_run + 2;
569 if( zip_it_run == zip_it_run_copy && zip_it_run == zip_it_begin + 3 )
571 ++num_successful_tests;
572 std::cout << "OK" << std::endl;
577 std::cout << "not OK" << std::endl;
580 /////////////////////////////////////////////////////////////////////////////
582 // Zip iterator - int
584 /////////////////////////////////////////////////////////////////////////////
586 std::cout << "Zip iterator - int: "
589 // Note: zip_it_run == zip_it_run_copy, and both are at end position
591 zip_it_run = zip_it_run - 2;
595 if( zip_it_run == zip_it_run_copy && (zip_it_run - 1) == zip_it_begin )
597 ++num_successful_tests;
598 std::cout << "OK" << std::endl;
603 std::cout << "not OK" << std::endl;
606 /////////////////////////////////////////////////////////////////////////////
610 /////////////////////////////////////////////////////////////////////////////
612 std::cout << "Zip iterator +=: "
615 // Note: zip_it_run == zip_it_run_copy, and both are at begin + 1
618 if( zip_it_run == zip_it_begin + 3 )
620 ++num_successful_tests;
621 std::cout << "OK" << std::endl;
626 std::cout << "not OK" << std::endl;
629 /////////////////////////////////////////////////////////////////////////////
633 /////////////////////////////////////////////////////////////////////////////
635 std::cout << "Zip iterator -=: "
638 // Note: zip_it_run is at end position, zip_it_run_copy is at
642 if( zip_it_run == zip_it_run_copy )
644 ++num_successful_tests;
645 std::cout << "OK" << std::endl;
650 std::cout << "not OK" << std::endl;
653 /////////////////////////////////////////////////////////////////////////////
655 // Zip iterator getting member iterators
657 /////////////////////////////////////////////////////////////////////////////
659 std::cout << "Zip iterator member iterators: "
662 // Note: zip_it_run and zip_it_run_copy are both at
665 if( ZI_TUPLE_GET(0)(zip_it_run.get_iterator_tuple()) == vect1.begin() + 1 &&
666 ZI_TUPLE_GET(1)(zip_it_run.get_iterator_tuple()) == vect2.begin() + 1
669 ++num_successful_tests;
670 std::cout << "OK" << std::endl;
675 std::cout << "not OK" << std::endl;
678 /////////////////////////////////////////////////////////////////////////////
680 // Making zip iterators
682 /////////////////////////////////////////////////////////////////////////////
684 std::cout << "Making zip iterators: "
687 std::vector<ZI_TUPLE<double, double> >
691 boost::make_zip_iterator(
697 boost::make_zip_iterator(
703 vect_of_tuples.begin()
706 if( 42. == ZI_TUPLE_GET(0)(*vect_of_tuples.begin()) &&
707 2.2 == ZI_TUPLE_GET(1)(*vect_of_tuples.begin()) &&
708 43. == ZI_TUPLE_GET(0)(*(vect_of_tuples.begin() + 1)) &&
709 3.3 == ZI_TUPLE_GET(1)(*(vect_of_tuples.begin() + 1)) &&
710 44. == ZI_TUPLE_GET(0)(*(vect_of_tuples.begin() + 2)) &&
711 4.4 == ZI_TUPLE_GET(1)(*(vect_of_tuples.begin() + 2))
714 ++num_successful_tests;
715 std::cout << "OK" << std::endl;
720 std::cout << "not OK" << std::endl;
723 /////////////////////////////////////////////////////////////////////////////
725 // Zip iterator non-const --> const conversion
727 /////////////////////////////////////////////////////////////////////////////
729 std::cout << "Zip iterator non-const to const conversion: "
734 std::set<int>::const_iterator,
735 std::vector<double>::const_iterator
747 std::set<int>::iterator,
748 std::vector<double>::const_iterator
760 std::set<int>::iterator,
761 std::vector<double>::iterator
771 zip_it_half_const = ++zip_it_non_const;
772 zip_it_const = zip_it_half_const;
774 // zip_it_non_const = ++zip_it_const; // Error: can't convert from const to non-const
776 if( 54 == ZI_TUPLE_GET(0)(*zip_it_const) &&
777 4.4 == ZI_TUPLE_GET(1)(*zip_it_const) &&
778 53 == ZI_TUPLE_GET(0)(*zip_it_half_const) &&
779 3.3 == ZI_TUPLE_GET(1)(*zip_it_half_const)
782 ++num_successful_tests;
783 std::cout << "OK" << std::endl;
788 std::cout << "not OK" << std::endl;
792 #if defined(ZI_USE_BOOST_TUPLE)
794 /////////////////////////////////////////////////////////////////////////////
796 // Zip iterator categories
798 /////////////////////////////////////////////////////////////////////////////
800 std::cout << "Zip iterator categories: "
803 // The big iterator of the previous test has vector, list, and set iterators.
804 // Therefore, it must be bidirectional, but not random access.
805 bool bBigItIsBidirectionalIterator = boost::is_convertible<
806 boost::iterator_traversal<zip_it_12_type>::type
807 , boost::bidirectional_traversal_tag
810 bool bBigItIsRandomAccessIterator = boost::is_convertible<
811 boost::iterator_traversal<zip_it_12_type>::type
812 , boost::random_access_traversal_tag
815 // A combining iterator with all vector iterators must have random access
818 typedef boost::zip_iterator<
820 std::vector<double>::const_iterator,
821 std::vector<double>::const_iterator
825 bool bAllVectsIsRandomAccessIterator = boost::is_convertible<
826 boost::iterator_traversal<all_vects_type>::type
827 , boost::random_access_traversal_tag
831 if( bBigItIsBidirectionalIterator &&
832 ! bBigItIsRandomAccessIterator &&
833 bAllVectsIsRandomAccessIterator
836 ++num_successful_tests;
837 std::cout << "OK" << std::endl;
842 std::cout << "not OK" << std::endl;
849 std::cout << "\nTest Result:"
851 << "\nNumber of successful tests: " << static_cast<unsigned int>(num_successful_tests)
852 << "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests)
855 return num_failed_tests;