diff --git a/counting_iterator_example.cpp b/counting_iterator_example.cpp index fd18ad1..87f946d 100644 --- a/counting_iterator_example.cpp +++ b/counting_iterator_example.cpp @@ -8,14 +8,30 @@ #include #include #include -#include -#include +#include +#include +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace boost { namespace detail +{ + template <> + struct iterator_traits + : ptr_iter_traits + { + }; + + template <> + struct iterator_traits + : ptr_iter_traits + { + }; +}} +#endif int main(int, char*[]) { // Example of using counting_iterator_generator std::cout << "counting from 0 to 4:" << std::endl; - boost::counting_iterator_generator::type first(0), last(4); + boost::counting_iterator first(0), last(4); std::copy(first, last, std::ostream_iterator(std::cout, " ")); std::cout << std::endl; @@ -37,13 +53,10 @@ int main(int, char*[]) // Use counting iterator to fill in the array of pointers. // causes an ICE with MSVC6 -#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) std::copy(boost::make_counting_iterator(numbers.begin()), boost::make_counting_iterator(numbers.end()), std::back_inserter(pointers)); -#endif -#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1300) // Use indirect iterator to print out numbers by accessing // them through the array of pointers. std::cout << "indirectly printing out the numbers from 0 to " @@ -52,6 +65,6 @@ int main(int, char*[]) boost::make_indirect_iterator(pointers.end()), std::ostream_iterator(std::cout, " ")); std::cout << std::endl; -#endif + return 0; } diff --git a/counting_iterator_test.cpp b/counting_iterator_test.cpp deleted file mode 100644 index 1994a2e..0000000 --- a/counting_iterator_test.cpp +++ /dev/null @@ -1,269 +0,0 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears in -// all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// See http://www.boost.org for most recent version including documentation. -// -// Revision History -// 16 Feb 2001 Added a missing const. Made the tests run (somewhat) with -// plain MSVC again. (David Abrahams) -// 11 Feb 2001 #if 0'd out use of counting_iterator on non-numeric types in -// MSVC without STLport, so that the other tests may proceed -// (David Abrahams) -// 04 Feb 2001 Added use of iterator_tests.hpp (David Abrahams) -// 28 Jan 2001 Removed not_an_iterator detritus (David Abrahams) -// 24 Jan 2001 Initial revision (David Abrahams) - -#include -#ifdef BOOST_MSVC -# pragma warning(disable:4786) // identifier truncated in debug info -#endif - -#include -#include -#include -#include -#include -#include -#include -#ifndef __BORLANDC__ -# include -#endif -#include -#include -#include -#ifndef BOOST_NO_LIMITS -# include -#endif -#ifndef BOOST_NO_SLIST -# include -#endif - -template struct is_numeric -{ - enum { value = -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - std::numeric_limits::is_specialized -#else - // Causes warnings with GCC, but how else can I detect numeric types at - // compile-time? - (boost::is_convertible::value && - boost::is_convertible::value) -#endif - }; -}; - -// Special tests for RandomAccess CountingIterators. -template -void category_test( - CountingIterator start, - CountingIterator finish, - std::random_access_iterator_tag) -{ - typedef typename - boost::detail::iterator_traits::difference_type - difference_type; - difference_type distance = boost::detail::distance(start, finish); - - // Pick a random position internal to the range - difference_type offset = (unsigned)rand() % distance; - assert(offset >= 0); - CountingIterator internal = start; - std::advance(internal, offset); - - // Try some binary searches on the range to show that it's ordered - assert(std::binary_search(start, finish, *internal)); - - // #including tuple crashed borland, so I had to give up on tie(). - std::pair xy( - std::equal_range(start, finish, *internal)); - CountingIterator x = xy.first, y = xy.second; - - assert(boost::detail::distance(x, y) == 1); - - // Show that values outside the range can't be found - assert(!std::binary_search(start, boost::prior(finish), *finish)); - - // Do the generic random_access_iterator_test - typedef typename CountingIterator::value_type value_type; - std::vector v; - for (value_type z = *start; z != *finish; ++z) - v.push_back(z); - if (v.size() >= 2) - { - // Note that this test requires a that the first argument is - // dereferenceable /and/ a valid iterator prior to the first argument - boost::random_access_iterator_test(start + 1, v.size() - 1, v.begin() + 1); - } -} - -// Special tests for bidirectional CountingIterators -template -void category_test(CountingIterator start, CountingIterator finish, std::bidirectional_iterator_tag) -{ - if (finish != start - && finish != boost::next(start) - && finish != boost::next(boost::next(start))) - { - // Note that this test requires a that the first argument is - // dereferenceable /and/ a valid iterator prior to the first argument - boost::bidirectional_iterator_test(boost::next(start), boost::next(*start), boost::next(boost::next(*start))); - } -} - -template -void category_test(CountingIterator start, CountingIterator finish, std::forward_iterator_tag) -{ - if (finish != start && finish != boost::next(start)) - boost::forward_iterator_test(start, *start, boost::next(*start)); -} - -template -void test_aux(CountingIterator start, CountingIterator finish) -{ - typedef typename CountingIterator::iterator_category category; - typedef typename CountingIterator::value_type value_type; - - // If it's a RandomAccessIterator we can do a few delicate tests - category_test(start, finish, category()); - - // Okay, brute force... - for (CountingIterator p = start; p != finish && boost::next(p) != finish; ++p) - { - assert(boost::next(*p) == *boost::next(p)); - } - - // prove that a reference can be formed to these values - typedef typename CountingIterator::value_type value; - const value* q = &*start; - (void)q; // suppress unused variable warning -} - -template -void test(Incrementable start, Incrementable finish) -{ - test_aux(boost::make_counting_iterator(start), boost::make_counting_iterator(finish)); -} - -template -void test_integer(Integer* = 0) // default arg works around MSVC bug -{ - Integer start = 0; - Integer finish = 120; - test(start, finish); -} - -template -void test_container(Container* = 0) // default arg works around MSVC bug -{ - Container c(1 + (unsigned)rand() % 1673); - - const typename Container::iterator start = c.begin(); - - // back off by 1 to leave room for dereferenceable value at the end - typename Container::iterator finish = start; - std::advance(finish, c.size() - 1); - - test(start, finish); - - typedef typename Container::const_iterator const_iterator; - test(const_iterator(start), const_iterator(finish)); -} - -class my_int1 { -public: - my_int1() { } - my_int1(int x) : m_int(x) { } - my_int1& operator++() { ++m_int; return *this; } - bool operator==(const my_int1& x) const { return m_int == x.m_int; } -private: - int m_int; -}; - -namespace boost { - template <> - struct counting_iterator_traits { - typedef std::ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; - }; -} - -class my_int2 { -public: - typedef void value_type; - typedef void pointer; - typedef void reference; - typedef std::ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - my_int2() { } - my_int2(int x) : m_int(x) { } - my_int2& operator++() { ++m_int; return *this; } - my_int2& operator--() { --m_int; return *this; } - bool operator==(const my_int2& x) const { return m_int == x.m_int; } -private: - int m_int; -}; - -class my_int3 { -public: - typedef void value_type; - typedef void pointer; - typedef void reference; - typedef std::ptrdiff_t difference_type; - typedef std::random_access_iterator_tag iterator_category; - - my_int3() { } - my_int3(int x) : m_int(x) { } - my_int3& operator++() { ++m_int; return *this; } - my_int3& operator+=(std::ptrdiff_t n) { m_int += n; return *this; } - std::ptrdiff_t operator-(const my_int3& x) const { return m_int - x.m_int; } - my_int3& operator--() { --m_int; return *this; } - bool operator==(const my_int3& x) const { return m_int == x.m_int; } - bool operator!=(const my_int3& x) const { return m_int != x.m_int; } - bool operator<(const my_int3& x) const { return m_int < x.m_int; } -private: - int m_int; -}; - -int main() -{ - // Test the built-in integer types. - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); -#if defined(BOOST_HAS_LONG_LONG) - test_integer(); - test_integer(); -#endif - - // wrapping an iterator or non-built-in integer type causes an INTERNAL - // COMPILER ERROR in MSVC without STLport. I'm clueless as to why. -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 || defined(__SGI_STL_PORT) - // Test user-defined type. - test_integer(); - test_integer(); - test_integer(); - - // Some tests on container iterators, to prove we handle a few different categories - test_container >(); - test_container >(); -# ifndef BOOST_NO_SLIST - test_container >(); -# endif - - // Also prove that we can handle raw pointers. - int array[2000]; - test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1)); -#endif - std::cout << "test successful " << std::endl; - return 0; -} diff --git a/filter_iterator_example.cpp b/filter_iterator_example.cpp index 9e4958a..c2c4693 100644 --- a/filter_iterator_example.cpp +++ b/filter_iterator_example.cpp @@ -11,24 +11,29 @@ #include #include #include -#include +#include struct is_positive_number { bool operator()(int x) { return 0 < x; } }; +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace boost { namespace detail +{ + template <> + struct iterator_traits + : ptr_iter_traits + { + }; +}} +#endif + int main() { int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 }; const int N = sizeof(numbers_)/sizeof(int); -#ifdef BOOST_NO_STD_ITERATOR_TRAITS - // Assume there won't be proper iterator traits for pointers. This - // is just a wrapper for int* which has the right traits. - typedef boost::iterator_adaptor base_iterator; -#else typedef int* base_iterator; -#endif base_iterator numbers(numbers_); // Example using make_filter_iterator() @@ -37,23 +42,30 @@ int main() std::ostream_iterator(std::cout, " ")); std::cout << std::endl; - // Example using filter_iterator_generator - typedef boost::filter_iterator_generator::type + // Example using filter_iterator + typedef boost::filter_iterator FilterIter; + is_positive_number predicate; - FilterIter::policies_type policies(predicate, numbers + N); - FilterIter filter_iter_first(numbers, policies); - FilterIter filter_iter_last(numbers + N, policies); + FilterIter filter_iter_first(predicate, numbers, numbers + N); + FilterIter filter_iter_last(predicate, numbers + N, numbers + N); std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator(std::cout, " ")); std::cout << std::endl; // Another example using make_filter_iterator() - std::copy(boost::make_filter_iterator(numbers, numbers + N, - std::bind2nd(std::greater(), -2)), - boost::make_filter_iterator(numbers + N, numbers + N, - std::bind2nd(std::greater(), -2)), - std::ostream_iterator(std::cout, " ")); + std::copy( + boost::make_filter_iterator( + std::bind2nd(std::greater(), -2) + , numbers, numbers + N) + + , boost::make_filter_iterator( + std::bind2nd(std::greater(), -2) + , numbers + N, numbers + N) + + , std::ostream_iterator(std::cout, " ") + ); + std::cout << std::endl; diff --git a/indirect_iterator_example.cpp b/indirect_iterator_example.cpp index 542dc66..22d1a21 100644 --- a/indirect_iterator_example.cpp +++ b/indirect_iterator_example.cpp @@ -8,7 +8,43 @@ #include #include #include -#include +#include +#include + +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace boost { namespace detail +{ + template <> + struct iterator_traits + : ptr_iter_traits + { + }; + + template <> + struct iterator_traits + : ptr_iter_traits + { + }; + + template <> + struct iterator_traits + : ptr_iter_traits + { + }; + + template <> + struct iterator_traits + : ptr_iter_traits + { + }; + + template <> + struct iterator_traits + : ptr_iter_traits + { + }; +}} +#endif int main(int, char*[]) { @@ -20,7 +56,7 @@ int main(int, char*[]) // Example of using indirect_iterator_generator - boost::indirect_iterator_generator::type + boost::indirect_iterator indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N); std::copy(indirect_first, indirect_last, std::ostream_iterator(std::cout, ",")); @@ -29,16 +65,14 @@ int main(int, char*[]) // Example of using indirect_iterator_pair_generator - typedef boost::indirect_iterator_pair_generator PairGen; - char mutable_characters[N]; char* pointers_to_mutable_chars[N]; for (int j = 0; j < N; ++j) pointers_to_mutable_chars[j] = &mutable_characters[j]; - PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars), + boost::indirect_iterator mutable_indirect_first(pointers_to_mutable_chars), mutable_indirect_last(pointers_to_mutable_chars + N); - PairGen::const_iterator const_indirect_first(pointers_to_chars), + boost::indirect_iterator const_indirect_first(pointers_to_chars), const_indirect_last(pointers_to_chars + N); std::transform(const_indirect_first, const_indirect_last, diff --git a/indirect_iterator_test.cpp b/indirect_iterator_test.cpp deleted file mode 100644 index 4b0c3e6..0000000 --- a/indirect_iterator_test.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify, -// sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// Revision History -// 08 Mar 2001 Jeremy Siek -// Moved test of indirect iterator into its own file. It to -// to be in iterator_adaptor_test.cpp. - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -struct my_iterator_tag : public std::random_access_iterator_tag { }; - -using boost::dummyT; - -typedef std::deque storage; -typedef std::deque pointer_deque; -typedef std::set iterator_set; - -void more_indirect_iterator_tests() -{ -// For some reason all heck breaks loose in the compiler under these conditions. -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 || !defined(__STL_DEBUG) - storage store(1000); - std::generate(store.begin(), store.end(), rand); - - pointer_deque ptr_deque; - iterator_set iter_set; - - for (storage::iterator p = store.begin(); p != store.end(); ++p) - { - ptr_deque.push_back(&*p); - iter_set.insert(p); - } - - typedef boost::indirect_iterator_pair_generator< - pointer_deque::iterator -#ifdef BOOST_NO_STD_ITERATOR_TRAITS - , int -#endif - > IndirectDeque; - - IndirectDeque::iterator db(ptr_deque.begin()); - IndirectDeque::iterator de(ptr_deque.end()); - assert(static_cast(de - db) == store.size()); - assert(db + store.size() == de); - IndirectDeque::const_iterator dci(db); - assert(db == dci); - assert(dci == db); - assert(dci != de); - assert(dci < de); - assert(dci <= de); - assert(de >= dci); - assert(de > dci); - dci = de; - assert(dci == de); - - boost::random_access_iterator_test(db + 1, store.size() - 1, boost::next(store.begin())); - - *db = 999; - assert(store.front() == 999); - - // Borland C++ is getting very confused about the typedef's here - - typedef boost::indirect_iterator_generator< - iterator_set::iterator -#ifdef BOOST_NO_STD_ITERATOR_TRAITS - , int -#endif - >::type indirect_set_iterator; - - typedef boost::indirect_iterator_generator< - iterator_set::iterator, - const int - >::type const_indirect_set_iterator; - - indirect_set_iterator sb(iter_set.begin()); - indirect_set_iterator se(iter_set.end()); - const_indirect_set_iterator sci(iter_set.begin()); - assert(sci == sb); - assert(sci != se); - sci = se; - assert(sci == se); - - *boost::prior(se) = 888; - assert(store.back() == 888); - assert(std::equal(sb, se, store.begin())); - - boost::bidirectional_iterator_test(boost::next(sb), store[1], store[2]); - assert(std::equal(db, de, store.begin())); - -#endif -} - -int -main() -{ - dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), - dummyT(3), dummyT(4), dummyT(5) }; - const int N = sizeof(array)/sizeof(dummyT); - - // Test indirect_iterator_generator - { - dummyT* ptr[N]; - for (int k = 0; k < N; ++k) - ptr[k] = array + k; - - typedef boost::indirect_iterator_generator::type indirect_iterator; - - typedef boost::indirect_iterator_generator::type const_indirect_iterator; - - indirect_iterator i(ptr); - boost::random_access_iterator_test(i, N, array); - -#ifndef BOOST_NO_STD_ITERATOR_TRAITS - boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array); -#endif - - // check operator-> - assert((*i).m_x == i->foo()); - - const_indirect_iterator j(ptr); - boost::random_access_iterator_test(j, N, array); - - dummyT*const* const_ptr = ptr; - -#ifndef BOOST_NO_STD_ITERATOR_TRAITS - boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array); -#endif - boost::const_nonconst_iterator_test(i, ++j); - - more_indirect_iterator_tests(); - } - std::cout << "test successful " << std::endl; - return 0; -} diff --git a/iter_adaptor_fail_expected1.cpp b/iter_adaptor_fail_expected1.cpp deleted file mode 100644 index 2d0288c..0000000 --- a/iter_adaptor_fail_expected1.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// Test boost/pending/iterator_adaptors.hpp - -// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify, -// sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// See http://www.boost.org for most recent version including documentation. - -// Revision History -// 21 Jan 01 Initial version (Jeremy Siek) - -#include -#include -#include - -int main() -{ - typedef boost::iterator_adaptor::iterator, - boost::default_iterator_policies, - int,int&,int*,std::bidirectional_iterator_tag> adaptor_type; - - adaptor_type i; - i += 4; - return 0; -} diff --git a/iter_adaptor_fail_expected2.cpp b/iter_adaptor_fail_expected2.cpp deleted file mode 100644 index 592801d..0000000 --- a/iter_adaptor_fail_expected2.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Test boost/pending/iterator_adaptors.hpp - -// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify, -// sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// See http://www.boost.org for most recent version including documentation. - -// Revision History -// 21 Jan 01 Initial version (Jeremy Siek) - -#include -#include -#include -#include - -int main() -{ - typedef boost::iterator_adaptor, - boost::default_iterator_policies, - int,int&,int*,std::input_iterator_tag> adaptor_type; - - adaptor_type iter; - --iter; - return 0; -} diff --git a/iter_traits_gen_test.cpp b/iter_traits_gen_test.cpp deleted file mode 100644 index ca214d4..0000000 --- a/iter_traits_gen_test.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, -// sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// 04 Nov 2001 Jeremy Siek -// Updated with respect to new named parameter interface. -// 08 Mar 2001 Jeremy Siek -// Initial checkin. - -#include -#include -#include - -class bar { }; -void foo(bar) { } - -int -main() -{ - using boost::dummyT; - dummyT array[] = { dummyT(0), dummyT(1), dummyT(2), - dummyT(3), dummyT(4), dummyT(5) }; - typedef boost::iterator_adaptor my_iter; - my_iter mi(array); - - { - typedef boost::iterator_adaptor, - boost::iterator_category_is > iter_type; - - BOOST_STATIC_ASSERT((boost::is_same::value)); - - BOOST_STATIC_ASSERT(( ! boost::is_convertible::value)); - - iter_type i(mi); - boost::input_iterator_test(i, dummyT(0), dummyT(1)); - } - { - typedef boost::iterator_adaptor, - boost::reference_is, - boost::pointer_is , - boost::iterator_category_is, - boost::difference_type_is > 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; -} diff --git a/iterator_adaptor_examples.cpp b/iterator_adaptor_examples.cpp index 917fd02..7c886e4 100644 --- a/iterator_adaptor_examples.cpp +++ b/iterator_adaptor_examples.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include int @@ -21,8 +21,8 @@ main(int, char*[]) int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; typedef std::binder1st< std::multiplies > Function; - typedef boost::transform_iterator_generator::type doubling_iterator; + + typedef boost::transform_iterator doubling_iterator; doubling_iterator i(x, std::bind1st(std::multiplies(), 2)), i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies(), 2)); diff --git a/iterator_adaptor_test.cpp b/iterator_adaptor_test.cpp deleted file mode 100644 index 4e5ae94..0000000 --- a/iterator_adaptor_test.cpp +++ /dev/null @@ -1,454 +0,0 @@ -// Test boost/iterator_adaptors.hpp - -// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify, -// sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// See http://www.boost.org for most recent version including documentation. - -// Revision History -// 30 Nov 01 Added permutation_iterator.(Toon Knapen) -// 19 Nov 01 Added generator_iterator. (Jens Maurer) -// 04 Nov 01 Updated with respect to change in named parameters. -// (Jeremy Siek) -// 08 Mar 01 Moved indirect and transform tests to separate files. -// (Jeremy Siek) -// 19 Feb 01 Take adavantage of improved iterator_traits to do more tests -// on MSVC. Hack around an MSVC-with-STLport internal compiler -// error. (David Abrahams) -// 11 Feb 01 Added test of operator-> for forward and input iterators. -// (Jeremy Siek) -// 11 Feb 01 Borland fixes (David Abrahams) -// 10 Feb 01 Use new adaptors interface. (David Abrahams) -// 10 Feb 01 Use new filter_ interface. (David Abrahams) -// 09 Feb 01 Use new reverse_ and indirect_ interfaces. Replace -// BOOST_NO_STD_ITERATOR_TRAITS with -// BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION to prove we've -// normalized to core compiler capabilities (David Abrahams) -// 08 Feb 01 Use Jeremy's new make_reverse_iterator form; add more -// comprehensive testing. Force-decay array function arguments to -// pointers. -// 07 Feb 01 Added tests for the make_xxx_iterator() helper functions. -// (Jeremy Siek) -// 07 Feb 01 Replaced use of xxx_pair_generator with xxx_generator where -// possible (which was all but the projection iterator). -// (Jeremy Siek) -// 06 Feb 01 Removed now-defaulted template arguments where possible -// Updated names to correspond to new generator naming convention. -// Added a trivial test for make_transform_iterator(). -// Gave traits for const iterators a mutable value_type, per std. -// Resurrected my original tests for indirect iterators. -// (David Abrahams) -// 04 Feb 01 Fix for compilers without standard iterator_traits -// (David Abrahams) -// 13 Jun 00 Added const version of the iterator tests (Jeremy Siek) -// 12 Dec 99 Initial version with iterator operators (Jeremy Siek) - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct my_iterator_tag : public std::random_access_iterator_tag { }; - -using boost::dummyT; - - -struct mult_functor { - typedef int result_type; - typedef int argument_type; - // Functors used with transform_iterator must be - // DefaultConstructible, as the transform_iterator must be - // DefaultConstructible to satisfy the requirements for - // TrivialIterator. - mult_functor() { } - mult_functor(int aa) : a(aa) { } - int operator()(int b) const { return a * b; } - int a; -}; - -template -struct select1st_ - : public std::unary_function -{ - const typename Pair::first_type& operator()(const Pair& x) const { - return x.first; - } - typename Pair::first_type& operator()(Pair& x) const { - return x.first; - } -}; - -struct one_or_four { - bool operator()(dummyT x) const { - return x.foo() == 1 || x.foo() == 4; - } -}; - -typedef std::deque storage; -typedef std::deque pointer_deque; -typedef std::set iterator_set; - -template struct foo; - -void blah(int) { } - -struct my_gen -{ - typedef int result_type; - my_gen() : n(0) { } - int operator()() { return ++n; } - int n; -}; - -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); - - // Check that the policy concept checks and the default policy - // implementation match up. - boost::function_requires< - boost::RandomAccessIteratorPoliciesConcept< - boost::default_iterator_policies, - boost::iterator_adaptor, - boost::iterator - > >(); - - // Test the named parameters - { - // Test computation of defaults - typedef boost::iterator_adaptor > Iter1; - // don't use std::iterator_traits here to avoid VC++ problems - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - } - { - // Test computation of default when the Value is const - typedef boost::iterator_adaptor::iterator, - boost::default_iterator_policies, - boost::value_type_is > Iter1; - BOOST_STATIC_ASSERT((boost::is_same::value)); - -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - // We currently don't know how to workaround this bug. - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); -#else - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); -#endif - } - { - // Test with no defaults - typedef boost::iterator_adaptor, - boost::pointer_is, - boost::value_type_is, - boost::iterator_category_is, - boost::difference_type_is - > Iter1; - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - BOOST_STATIC_ASSERT((boost::is_same::value)); - } - - // Test the iterator_adaptor - { - boost::iterator_adaptor i(array); - boost::random_access_iterator_test(i, N, array); - - boost::iterator_adaptor j(array); - boost::random_access_iterator_test(j, N, array); - boost::const_nonconst_iterator_test(i, ++j); - } - - // Test projection_iterator_pair_generator - { - typedef std::pair Pair; - Pair pair_array[N]; - for (int k = 0; k < N; ++k) - pair_array[k].first = array[k]; - - typedef boost::projection_iterator_pair_generator, - Pair*, const Pair* - > Projection; - - Projection::iterator i(pair_array); - boost::random_access_iterator_test(i, N, array); - - boost::random_access_iterator_test(boost::make_projection_iterator(pair_array, select1st_()), N, array); - boost::random_access_iterator_test(boost::make_projection_iterator< select1st_ >(pair_array), N, array); - - Projection::const_iterator j(pair_array); - boost::random_access_iterator_test(j, N, array); - - boost::random_access_iterator_test(boost::make_const_projection_iterator(pair_array, select1st_()), N, array); - boost::random_access_iterator_test(boost::make_const_projection_iterator >(pair_array), N, array); - - boost::const_nonconst_iterator_test(i, ++j); - } - - // Test reverse_iterator_generator - { - dummyT reversed[N]; - std::copy(array, array + N, reversed); - std::reverse(reversed, reversed + N); - - typedef boost::reverse_iterator_generator::type reverse_iterator; - - reverse_iterator i(reversed + N); - boost::random_access_iterator_test(i, N, array); - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) - boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array); -#endif - - typedef boost::reverse_iterator_generator::type const_reverse_iterator; - - const_reverse_iterator j(reversed + N); - boost::random_access_iterator_test(j, N, array); - - const dummyT* const_reversed = reversed; - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) - boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array); -#endif - - boost::const_nonconst_iterator_test(i, ++j); - } - - // Test reverse_iterator_generator again, with traits fully deducible on all platforms - { - std::deque reversed_container; - std::reverse_copy(array, array + N, std::back_inserter(reversed_container)); - const std::deque::iterator reversed = reversed_container.begin(); - - - typedef boost::reverse_iterator_generator< - std::deque::iterator>::type reverse_iterator; - typedef boost::reverse_iterator_generator< - std::deque::const_iterator, const dummyT>::type 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::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::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__, < 3) \ - && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) \ - && !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)) - - boost::const_nonconst_iterator_test(i, ++j); -#endif - } - - // Test integer_range's iterators - { - int int_array[] = { 0, 1, 2, 3, 4, 5 }; - boost::integer_range r(0, 5); - boost::random_access_iterator_test(r.begin(), r.size(), int_array); - } - - // Test filter iterator - { - // Using typedefs for filter_gen::type confused Borland terribly. - typedef boost::detail::non_bidirectional_category::type category; - - typedef boost::filter_iterator_generator::type filter_iter; - -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) - // Borland is choking on accessing the policies_type explicitly - // from the filter_iter. - boost::forward_iterator_test(make_filter_iterator(array, array+N, - one_or_four()), - dummyT(1), dummyT(4)); -#else - filter_iter i(array, filter_iter::policies_type(one_or_four(), array + N)); - boost::forward_iterator_test(i, dummyT(1), dummyT(4)); -#endif - -#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) - enum { is_forward = boost::is_same< - filter_iter::iterator_category, - std::forward_iterator_tag>::value }; - BOOST_STATIC_ASSERT(is_forward); -#endif - - // On compilers not supporting partial specialization, we can do more type - // deduction with deque iterators than with pointers... unless the library - // is broken ;-( -#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && !__SGI_STL_PORT) - std::deque array2; - std::copy(array+0, array+N, std::back_inserter(array2)); - boost::forward_iterator_test( - boost::make_filter_iterator(array2.begin(), array2.end(), one_or_four()), - dummyT(1), dummyT(4)); - - boost::forward_iterator_test( - boost::make_filter_iterator(array2.begin(), array2.end()), - dummyT(1), dummyT(4)); -#endif - -#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // This just freaks MSVC6 out completely - boost::forward_iterator_test( - boost::make_filter_iterator( - boost::make_reverse_iterator(array2.end()), - boost::make_reverse_iterator(array2.begin()) - ), - dummyT(4), dummyT(1)); -#endif - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) - boost::forward_iterator_test( - boost::make_filter_iterator(array+0, array+N, one_or_four()), - dummyT(1), dummyT(4)); - - boost::forward_iterator_test( - boost::make_filter_iterator(array, array + N), - dummyT(1), dummyT(4)); - -#endif - } - - // check operator-> with a forward iterator - { - boost::forward_iterator_archetype forward_iter; - -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) - typedef boost::iterator_adaptor, - boost::default_iterator_policies, - dummyT, const dummyT&, const dummyT*, - std::forward_iterator_tag, std::ptrdiff_t> adaptor_type; -#else - typedef boost::iterator_adaptor, - boost::default_iterator_policies, - boost::reference_is, - boost::pointer_is , - boost::iterator_category_is, - boost::value_type_is, - boost::difference_type_is - > adaptor_type; -#endif - 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 input_iter; - typedef boost::iterator_adaptor, - boost::default_iterator_policies, - dummyT, const dummyT&, const dummyT*, - std::input_iterator_tag, std::ptrdiff_t> 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 generator_iterator - my_gen g1; - boost::generator_iterator_generator::type gen = - boost::make_generator_iterator(g1); - assert(*gen == 1); - ++gen; - gen++; - assert(*gen == 3); - } - - { - // check permutation_iterator - typedef std::deque< int > element_range_type; - typedef std::list< int > index_type; - - static const int element_range_size = 10; - static const int index_size = 4; - - element_range_type elements( element_range_size ); - - for(element_range_type::iterator el_it = elements.begin(); - el_it != elements.end(); - ++el_it) - { - *el_it = std::distance( elements.begin(), el_it ); - } - - index_type indices( index_size ); - - for(index_type::iterator i_it = indices.begin(); - i_it != indices.end(); - ++i_it) - { - *i_it = element_range_size - index_size - + std::distance(indices.begin(), i_it ); - } - - std::reverse( indices.begin(), indices.end() ); - - typedef boost::permutation_iterator_generator< element_range_type::iterator, index_type::iterator >::type permutation_type; - permutation_type begin = boost::make_permutation_iterator( elements.begin(), indices.begin() ); - permutation_type end = boost::make_permutation_iterator( elements.begin(), indices.end() ); - - int expected_outcome[] = { 9, 8, 7, 6 }; - assert( std::equal( begin, end, expected_outcome ) ); - } - - std::cout << "test successful " << std::endl; - return 0; -} diff --git a/projection_iterator_example.cpp b/projection_iterator_example.cpp index 5405ced..ef57658 100644 --- a/projection_iterator_example.cpp +++ b/projection_iterator_example.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include struct personnel_record { personnel_record(std::string n, int id) : m_name(n), m_ID(id) { } @@ -19,7 +19,7 @@ struct personnel_record { struct select_name { typedef personnel_record argument_type; - typedef std::string result_type; + typedef std::string const& result_type; const std::string& operator()(const personnel_record& r) const { return r.m_name; } @@ -30,7 +30,7 @@ struct select_name { struct select_ID { typedef personnel_record argument_type; - typedef int result_type; + typedef int& result_type; const int& operator()(const personnel_record& r) const { return r.m_ID; } @@ -48,11 +48,16 @@ int main(int, char*[]) personnel_list.push_back(personnel_record("Wilma", 62454)); personnel_list.push_back(personnel_record("Betty", 20490)); - // Example of using projection_iterator_generator - // to print out the names in the personnel list. + // Example of using transform_iterator to print out the names in the + // personnel list using a projection. - boost::projection_iterator_generator::iterator>::type + boost::transform_iterator< + select_name + , std::list::iterator +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + , std::string +#endif + > personnel_first(personnel_list.begin()), personnel_last(personnel_list.end()); @@ -60,14 +65,12 @@ int main(int, char*[]) std::ostream_iterator(std::cout, "\n")); std::cout << std::endl; - // Example of using projection_iterator_pair_generator - // to assign new ID numbers to the personnel. + // Example of using transform_iterator with const_iterators to + // assign new ID numbers to the personnel. - typedef boost::projection_iterator_pair_generator::iterator, - std::list::const_iterator> PairGen; - - PairGen::iterator ID_first(personnel_list.begin()), + boost::transform_iterator< + select_ID, std::list::iterator + > ID_first(personnel_list.begin()), ID_last(personnel_list.end()); int new_id = 0; @@ -76,21 +79,25 @@ int main(int, char*[]) ++ID_first; } - PairGen::const_iterator const_ID_first(personnel_list.begin()), + boost::transform_iterator< + select_ID, std::list::const_iterator, int const& + > + const_ID_first(personnel_list.begin()), const_ID_last(personnel_list.end()); std::copy(const_ID_first, const_ID_last, std::ostream_iterator(std::cout, " ")); std::cout << std::endl; std::cout << std::endl; - + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // Example of using make_const_projection_iterator() // to print out the names in the personnel list again. + std::copy( + boost::make_transform_iterator(personnel_list.begin()) + , boost::make_transform_iterator(personnel_list.end()) + , std::ostream_iterator(std::cout, "\n")); +#endif - std::copy - (boost::make_const_projection_iterator(personnel_list.begin()), - boost::make_const_projection_iterator(personnel_list.end()), - std::ostream_iterator(std::cout, "\n")); - return 0; } diff --git a/reverse_iterator_example.cpp b/reverse_iterator_example.cpp index 39cabba..e2a8664 100644 --- a/reverse_iterator_example.cpp +++ b/reverse_iterator_example.cpp @@ -6,19 +6,24 @@ #include #include #include -#include +#include +#include +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace boost { namespace detail +{ + template <> + struct iterator_traits + : ptr_iter_traits + { + }; +}} +#endif int main(int, char*[]) { char letters_[] = "hello world!"; const int N = sizeof(letters_)/sizeof(char) - 1; -#ifdef BOOST_NO_STD_ITERATOR_TRAITS - // Assume there won't be proper iterator traits for pointers. This - // is just a wrapper for char* which has the right traits. - typedef boost::iterator_adaptor base_iterator; -#else typedef char* base_iterator; -#endif base_iterator letters(letters_); std::cout << "original sequence of letters:\t" @@ -29,7 +34,7 @@ int main(int, char*[]) // Use reverse_iterator_generator to print a sequence // of letters in reverse order. - boost::reverse_iterator_generator::type + boost::reverse_iterator reverse_letters_first(letters + N), reverse_letters_last(letters); diff --git a/transform_iterator_example.cpp b/transform_iterator_example.cpp index f65a493..a6973ec 100644 --- a/transform_iterator_example.cpp +++ b/transform_iterator_example.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include // What a bummer. We can't use std::binder1st with transform iterator // because it does not have a default constructor. Here's a version @@ -53,7 +53,7 @@ main(int, char*[]) const int N = sizeof(x)/sizeof(int); typedef boost::binder1st< std::multiplies > Function; - typedef boost::transform_iterator_generator::type doubling_iterator; + typedef boost::transform_iterator doubling_iterator; doubling_iterator i(x, boost::bind1st(std::multiplies(), 2)), i_end(x + N, boost::bind1st(std::multiplies(), 2)); diff --git a/transform_iterator_test.cpp b/transform_iterator_test.cpp deleted file mode 100644 index a1f173e..0000000 --- a/transform_iterator_test.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify, -// sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// Revision History -// 08 Mar 2001 Jeremy Siek -// Moved test of transform iterator into its own file. It to -// to be in iterator_adaptor_test.cpp. - -#include -#include -#include -#include -#include - -struct mult_functor { - typedef int result_type; - typedef int argument_type; - // Functors used with transform_iterator must be - // DefaultConstructible, as the transform_iterator must be - // DefaultConstructible to satisfy the requirements for - // TrivialIterator. - mult_functor() { } - mult_functor(int aa) : a(aa) { } - int operator()(int b) const { return a * b; } - int a; -}; - -int -main() -{ - const int N = 10; - - // Borland is getting confused about typedef's and constructors here - - // Test transform_iterator - { - int x[N], y[N]; - for (int k = 0; k < N; ++k) - x[k] = k; - std::copy(x, x + N, y); - - for (int k2 = 0; k2 < N; ++k2) - x[k2] = x[k2] * 2; - - boost::transform_iterator_generator::type i(y, mult_functor(2)); - boost::input_iterator_test(i, x[0], x[1]); - boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_functor(2)), x[0], x[1]); - } - std::cout << "test successful " << std::endl; - return 0; -}