int main() { using boost::dummyT; dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), dummyT(3), dummyT(4), dummyT(5) }; typedef boost::iterator_adaptor<dummyT*, boost::default_iterator_policies, dummyT> my_iter; my_iter mi(array); { typedef boost::iterator_adaptor<my_iter, boost::default_iterator_policies, boost::reference_is<dummyT>, boost::iterator_category_is<std::input_iterator_tag> > iter_type; BOOST_STATIC_ASSERT((boost::is_same<iter_type::iterator_category*, std::input_iterator_tag*>::value)); BOOST_STATIC_ASSERT(( ! boost::is_convertible<iter_type::iterator_category*, std::forward_iterator_tag*>::value)); iter_type i(mi); boost::input_iterator_test(i, dummyT(0), dummyT(1)); } { typedef boost::iterator_adaptor<dummyT*, boost::default_iterator_policies, boost::value_type_is<dummyT>, boost::reference_is<const dummyT&>, boost::pointer_is<const dummyT*> , boost::iterator_category_is<std::forward_iterator_tag>, boost::difference_type_is<std::ptrdiff_t> > adaptor_type; adaptor_type i(array); boost::input_iterator_test(i, dummyT(0), dummyT(1)); int zero = 0; if (zero) // don't do this, just make sure it compiles assert((*i).m_x == i->foo()); } return 0; }
int main() { dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), dummyT(3), dummyT(4), dummyT(5) }; const int N = sizeof(array)/sizeof(dummyT); // sanity check, if this doesn't pass the test is buggy boost::random_access_iterator_test(array, N, array); // Test the iterator_adaptor { ptr_iterator<dummyT> i(array); boost::random_access_iterator_test(i, N, array); ptr_iterator<const dummyT> j(array); boost::random_access_iterator_test(j, N, array); boost::const_nonconst_iterator_test(i, ++j); } int test; // Test the iterator_traits { // Test computation of defaults typedef ptr_iterator<int> Iter1; // don't use std::iterator_traits here to avoid VC++ problems test = static_assert_same<Iter1::value_type, int>::value; test = static_assert_same<Iter1::reference, int&>::value; test = static_assert_same<Iter1::pointer, int*>::value; test = static_assert_same<Iter1::difference_type, std::ptrdiff_t>::value; #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value)); #endif } { // Test computation of default when the Value is const typedef ptr_iterator<int const> Iter1; test = static_assert_same<Iter1::value_type, int>::value; test = static_assert_same<Iter1::reference, const int&>::value; #if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value); # ifndef BOOST_NO_LVALUE_RETURN_DETECTION BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value); # endif #endif #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness test = static_assert_same<Iter1::pointer, int const*>::value; #endif } { // Test constant iterator idiom typedef ptr_iterator<int> BaseIter; typedef constant_iterator<BaseIter> Iter; test = static_assert_same<Iter::value_type, int>::value; test = static_assert_same<Iter::reference, int const&>::value; #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness test = static_assert_same<Iter::pointer, int const*>::value; #endif #ifndef BOOST_NO_LVALUE_RETURN_DETECTION BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value); BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value); #endif typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter; static_assert_traversal<BaseIter,boost::random_access_traversal_tag>(); static_assert_traversal<IncrementableIter,boost::incrementable_traversal_tag>(); } // Test the iterator_adaptor { ptr_iterator<dummyT> i(array); boost::random_access_iterator_test(i, N, array); ptr_iterator<const dummyT> j(array); boost::random_access_iterator_test(j, N, array); boost::const_nonconst_iterator_test(i, ++j); } // check operator-> with a forward iterator { boost::forward_iterator_archetype<dummyT> forward_iter; typedef fwd_iterator<dummyT> adaptor_type; adaptor_type i(forward_iter); int zero = 0; if (zero) // don't do this, just make sure it compiles assert((*i).m_x == i->foo()); } // check operator-> with an input iterator { boost::input_iterator_archetype_no_proxy<dummyT> input_iter; typedef in_iterator<dummyT> adaptor_type; adaptor_type i(input_iter); int zero = 0; if (zero) // don't do this, just make sure it compiles assert((*i).m_x == i->foo()); } // check that base_type is correct { // Test constant iterator idiom typedef ptr_iterator<int> BaseIter; test = static_assert_same<BaseIter::base_type,int*>::value; test = static_assert_same<constant_iterator<BaseIter>::base_type,BaseIter>::value; typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter; test = static_assert_same<IncrementableIter::base_type,BaseIter>::value; } std::cout << "test successful " << std::endl; (void)test; return 0; }
int main() { dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), dummyT(3), dummyT(4), dummyT(5) }; const int N = sizeof(array)/sizeof(dummyT); # if BOOST_WORKAROUND(BOOST_MSVC, == 1200) boost::shared_ptr<dummyT> zz((dummyT*)0); // Why? I don't know, but it suppresses a bad instantiation. # endif typedef std::vector<boost::shared_ptr<dummyT> > shared_t; shared_t shared; // Concept checks { typedef boost::indirect_iterator<shared_t::iterator> iter_t; BOOST_STATIC_ASSERT( has_element_type< boost::detail::iterator_traits<shared_t::iterator>::value_type >::value ); typedef boost::indirect_iterator< shared_t::iterator , boost::iterator_value<shared_t::iterator>::type const > c_iter_t; # ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY boost::function_requires< boost_concepts::InteroperableIteratorConcept<iter_t, c_iter_t> >(); # endif } // Test indirect_iterator_generator { for (int jj = 0; jj < N; ++jj) shared.push_back(boost::shared_ptr<dummyT>(new dummyT(jj))); dummyT* ptr[N]; for (int k = 0; k < N; ++k) ptr[k] = array + k; typedef boost::indirect_iterator<dummyT**> indirect_iterator; typedef boost::indirect_iterator<dummyT**, dummyT const> const_indirect_iterator; indirect_iterator i(ptr); boost::random_access_iterator_test(i, N, array); boost::random_access_iterator_test( boost::indirect_iterator<shared_t::iterator>(shared.begin()) , N, array); boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array); // check operator-> assert((*i).m_x == i->foo()); const_indirect_iterator j(ptr); boost::random_access_iterator_test(j, N, array); dummyT const*const* const_ptr = ptr; boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array); boost::const_nonconst_iterator_test(i, ++j); more_indirect_iterator_tests(); } return boost::report_errors(); }
// Test reverse iterator int main() { dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), dummyT(3), dummyT(4), dummyT(5) }; const int N = sizeof(array)/sizeof(dummyT); // Concept checks // Adapting old-style iterators { typedef boost::reverse_iterator<boost::bidirectional_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } { typedef boost::reverse_iterator<boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } // Adapting new-style iterators { typedef boost::iterator_archetype< const dummyT , boost::iterator_archetypes::readable_iterator_t , boost::bidirectional_traversal_tag > iter; typedef boost::reverse_iterator<iter> Iter; boost::function_requires< boost::InputIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } #if 0 // It does not seem feasible to make this work. Need to change docs to // require at lease Readable for the base iterator. -Jeremy { typedef boost::iterator_archetype< dummyT , boost::iterator_archetypes::writable_iterator_t , boost::bidirectional_traversal_tag > iter; typedef boost::reverse_iterator<iter> Iter; boost::function_requires< boost_concepts::WritableIteratorConcept<Iter, dummyT> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } #endif #if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker. { typedef boost::iterator_archetype< dummyT , boost::iterator_archetypes::readable_writable_iterator_t , boost::bidirectional_traversal_tag > iter; typedef boost::reverse_iterator<iter> Iter; boost::function_requires< boost::InputIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } { typedef boost::iterator_archetype< const dummyT , boost::iterator_archetypes::readable_lvalue_iterator_t , boost::bidirectional_traversal_tag > iter; typedef boost::reverse_iterator<iter> Iter; boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } { typedef boost::iterator_archetype< dummyT , boost::iterator_archetypes::writable_lvalue_iterator_t , boost::bidirectional_traversal_tag > iter; typedef boost::reverse_iterator<iter> Iter; boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } #endif // Test reverse_iterator { dummyT reversed[N]; std::copy(array, array + N, reversed); std::reverse(reversed, reversed + N); typedef boost::reverse_iterator<dummyT*> reverse_iterator; reverse_iterator i(reversed + N); boost::random_access_iterator_test(i, N, array); boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array); typedef boost::reverse_iterator<const dummyT*> const_reverse_iterator; const_reverse_iterator j(reversed + N); boost::random_access_iterator_test(j, N, array); const dummyT* const_reversed = reversed; boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array); boost::const_nonconst_iterator_test(i, ++j); } // Test reverse_iterator again, with traits fully deducible on all platforms { std::deque<dummyT> reversed_container; std::reverse_copy(array, array + N, std::back_inserter(reversed_container)); const std::deque<dummyT>::iterator reversed = reversed_container.begin(); typedef boost::reverse_iterator< std::deque<dummyT>::iterator> reverse_iterator; typedef boost::reverse_iterator< std::deque<dummyT>::const_iterator> const_reverse_iterator; // MSVC/STLport gives an INTERNAL COMPILER ERROR when any computation // (e.g. "reversed + N") is used in the constructor below. const std::deque<dummyT>::iterator finish = reversed_container.end(); reverse_iterator i(finish); boost::random_access_iterator_test(i, N, array); boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array); const_reverse_iterator j = reverse_iterator(finish); boost::random_access_iterator_test(j, N, array); const std::deque<dummyT>::const_iterator const_reversed = reversed; boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array); // Many compilers' builtin deque iterators don't interoperate well, though // STLport fixes that problem. #if defined(__SGI_STL_PORT) \ || !BOOST_WORKAROUND(__GNUC__, <= 2) \ && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, <= 1)) \ && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) \ && !BOOST_WORKAROUND(__LIBCOMO_VERSION__, BOOST_TESTED_AT(29)) \ && !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 1) boost::const_nonconst_iterator_test(i, ++j); #endif } std::cout << "test successful " << std::endl; return boost::exit_success; }
// Test filter iterator int main() { // Concept checks // Adapting old-style iterators { typedef boost::filter_iterator<one_or_four, boost::input_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::InputIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >(); } { typedef boost::filter_iterator<one_or_four, boost::input_output_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::InputIteratorConcept<Iter> >(); boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >(); } { typedef boost::filter_iterator<one_or_four, boost::forward_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::ForwardIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >(); } { typedef boost::filter_iterator<one_or_four, boost::mutable_forward_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >(); } { typedef boost::filter_iterator<one_or_four, boost::bidirectional_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } { typedef boost::filter_iterator<one_or_four, boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } { typedef boost::filter_iterator<one_or_four, boost::random_access_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } { typedef boost::filter_iterator<one_or_four, boost::mutable_random_access_iterator_archetype<dummyT> > Iter; boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } // Adapting new-style iterators { typedef boost::iterator_archetype< const dummyT , boost::iterator_archetypes::readable_iterator_t , boost::single_pass_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost::InputIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >(); } #if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker. { typedef boost::iterator_archetype< dummyT , boost::iterator_archetypes::readable_writable_iterator_t , boost::single_pass_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost::InputIteratorConcept<Iter> >(); boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >(); } #endif { typedef boost::iterator_archetype< const dummyT , boost::iterator_archetypes::readable_iterator_t , boost::forward_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost::InputIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >(); } #if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker. { typedef boost::iterator_archetype< dummyT , boost::iterator_archetypes::readable_writable_iterator_t , boost::forward_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >(); } { typedef boost::iterator_archetype< const dummyT , boost::iterator_archetypes::readable_lvalue_iterator_t , boost::forward_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost::ForwardIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >(); } { typedef boost::iterator_archetype< dummyT , boost::iterator_archetypes::writable_lvalue_iterator_t , boost::forward_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >(); } #endif { typedef boost::iterator_archetype< const dummyT , boost::iterator_archetypes::readable_iterator_t , boost::random_access_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost::InputIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } #if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker. { typedef boost::iterator_archetype< dummyT , boost::iterator_archetypes::readable_writable_iterator_t , boost::random_access_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } { typedef boost::iterator_archetype< const dummyT , boost::iterator_archetypes::readable_lvalue_iterator_t , boost::random_access_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } { typedef boost::iterator_archetype< dummyT , boost::iterator_archetypes::writable_lvalue_iterator_t , boost::random_access_traversal_tag > BaseIter; typedef boost::filter_iterator<one_or_four, BaseIter> Iter; boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >(); boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >(); } #endif // Run-time tests dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), dummyT(3), dummyT(4), dummyT(5) }; const int N = sizeof(array)/sizeof(dummyT); typedef boost::filter_iterator<one_or_four, dummyT*> filter_iter; boost::bidirectional_readable_iterator_test( filter_iter(one_or_four(), array, array+N) , dummyT(1), dummyT(4)); BOOST_STATIC_ASSERT( (!boost::is_convertible< boost::iterator_traversal<filter_iter>::type , boost::random_access_traversal_tag >::value )); //# endif // On compilers not supporting partial specialization, we can do more type // deduction with deque iterators than with pointers... unless the library // is broken ;-( std::deque<dummyT> array2; std::copy(array+0, array+N, std::back_inserter(array2)); boost::bidirectional_readable_iterator_test( boost::make_filter_iterator(one_or_four(), array2.begin(), array2.end()), dummyT(1), dummyT(4)); boost::bidirectional_readable_iterator_test( boost::make_filter_iterator(one_or_four(), array2.begin(), array2.end()), dummyT(1), dummyT(4)); boost::bidirectional_readable_iterator_test( boost::make_filter_iterator( one_or_four() , boost::make_reverse_iterator(array2.end()) , boost::make_reverse_iterator(array2.begin()) ), dummyT(4), dummyT(1)); boost::bidirectional_readable_iterator_test( filter_iter(array+0, array+N), dummyT(1), dummyT(4)); boost::bidirectional_readable_iterator_test( filter_iter(one_or_four(), array, array + N), dummyT(1), dummyT(4)); std::cout << "test successful " << std::endl; return boost::exit_success; }