Many changes from Oxford

[SVN r1137]
This commit is contained in:
Dave Abrahams
2003-04-09 11:51:08 +00:00
parent 02c16f50a2
commit a846fe50d2
20 changed files with 1612 additions and 1032 deletions
+1
View File
@@ -2,6 +2,7 @@ SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
include testing.jam ;
run concept_tests.cpp ;
run iterator_adaptor_cc.cpp ;
run counting_iterator_test.cpp ;
run transform_iterator_test.cpp ;
run indirect_iterator_test.cpp ;
run filter_iterator_test.cpp ;
+4 -6
View File
@@ -10,7 +10,7 @@
struct new_iterator
: public boost::iterator< boost::iterator_tag<
boost::mutable_lvalue_iterator_tag
boost::writable_lvalue_iterator_tag
, boost::random_access_traversal_tag>, int>
{
int& operator*() const { return *m_x; }
@@ -53,16 +53,14 @@ old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
int
main()
{
BOOST_STATIC_ASSERT( boost::detail::is_random_access_traversal_iterator<boost::random_access_traversal_tag>::value );
typedef boost::iterator_tag< boost::mutable_lvalue_iterator_tag, boost::random_access_traversal_tag > tag;
typedef boost::iterator_tag< boost::writable_lvalue_iterator_tag, boost::random_access_traversal_tag > tag;
// BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator<tag>::value));
BOOST_STATIC_ASSERT((boost::is_same<tag::returns, boost::mutable_lvalue_iterator_tag>::value));
BOOST_STATIC_ASSERT((boost::is_same<tag::returns, boost::writable_lvalue_iterator_tag>::value));
BOOST_STATIC_ASSERT((boost::is_same<tag::traversal, boost::random_access_traversal_tag>::value));
// BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator<new_iterator::iterator_category>::value));
BOOST_STATIC_ASSERT((boost::is_same<new_iterator::iterator_category::returns, boost::mutable_lvalue_iterator_tag>::value));
BOOST_STATIC_ASSERT((boost::is_same<new_iterator::iterator_category::returns, boost::writable_lvalue_iterator_tag>::value));
BOOST_STATIC_ASSERT((boost::is_same<new_iterator::iterator_category::traversal, boost::random_access_traversal_tag>::value));
typedef boost::traversal_category<new_iterator>::type traversal_category;
+295
View File
@@ -0,0 +1,295 @@
// (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 <boost/config.hpp>
#ifdef __BORLANDC__ // Borland mis-detects our custom iterators
# pragma warn -8091 // template argument ForwardIterator passed to '...' is a output iterator
# pragma warn -8071 // Conversion may lose significant digits (due to counting_iterator<char> += n).
#endif
#ifdef BOOST_MSVC
# pragma warning(disable:4786) // identifier truncated in debug info
#endif
#include <boost/detail/iterator.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/next_prior.hpp>
#include <boost/mpl/if.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/limits.hpp>
#include <algorithm>
#include <climits>
#include <iterator>
#include <stdlib.h>
#ifndef __BORLANDC__
# include <boost/tuple/tuple.hpp>
#endif
#include <vector>
#include <list>
#include <cassert>
#ifndef BOOST_NO_SLIST
# include <slist>
#endif
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
template <class T>
struct signed_assert_nonnegative
{
static void test(T x) { assert(x >= 0); }
};
template <class T>
struct unsigned_assert_nonnegative
{
static void test(T x) {}
};
template <class T>
struct assert_nonnegative
: boost::mpl::if_c<
std::numeric_limits<T>::is_signed
, signed_assert_nonnegative<T>
, unsigned_assert_nonnegative<T>
>::type
{
};
#endif
// Special tests for RandomAccess CountingIterators.
template <class CountingIterator, class Value>
void category_test(
CountingIterator start,
CountingIterator finish,
Value,
std::random_access_iterator_tag)
{
typedef typename
boost::detail::iterator_traits<CountingIterator>::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;
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
assert(offset >= 0);
#else
assert_nonnegative<difference_type>::test(offset);
#endif
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<CountingIterator,CountingIterator> 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<value_type> v;
for (value_type z = *start; !(z == *finish); ++z)
v.push_back(z);
// 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, v.size(), v.begin());
}
// Special tests for bidirectional CountingIterators
template <class CountingIterator, class Value>
void category_test(CountingIterator start, Value v1, std::bidirectional_iterator_tag)
{
Value v2 = v1;
++v2;
// 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(start, v1, v2);
}
template <class CountingIterator, class Value>
void category_test(CountingIterator start, CountingIterator finish, Value v1, std::forward_iterator_tag)
{
Value v2 = v1;
++v2;
if (finish != start && finish != boost::next(start))
boost::forward_readable_iterator_test(start, finish, v1, v2);
}
template <class CountingIterator, class Value>
void test_aux(CountingIterator start, CountingIterator finish, Value v1)
{
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, v1, 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 <class Incrementable>
void test(Incrementable start, Incrementable finish)
{
test_aux(boost::make_counting_iterator(start), boost::make_counting_iterator(finish), start);
}
template <class Integer>
void test_integer(Integer* = 0) // default arg works around MSVC bug
{
Integer start = 0;
Integer finish = 120;
test(start, finish);
}
template <class Integer, class Category, class Difference>
void test_integer3(Integer* = 0, Category* = 0, Difference* = 0) // default arg works around MSVC bug
{
Integer start = 0;
Integer finish = 120;
typedef boost::counting_iterator<Integer,Category,Difference> iterator;
test_aux(iterator(start), iterator(finish), start);
}
template <class Container>
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;
};
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<char>();
test_integer<unsigned char>();
test_integer<signed char>();
test_integer<wchar_t>();
test_integer<short>();
test_integer<unsigned short>();
test_integer<int>();
test_integer<unsigned int>();
test_integer<long>();
test_integer<unsigned long>();
#if defined(BOOST_HAS_LONG_LONG)
test_integer<long long>();
test_integer<unsigned long long>();
#endif
// Test user-defined type.
test_integer3<my_int1, std::forward_iterator_tag, int>();
test_integer<my_int2>();
test_integer<my_int3>();
// Some tests on container iterators, to prove we handle a few different categories
test_container<std::vector<int> >();
test_container<std::list<int> >();
# ifndef BOOST_NO_SLIST
test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
# 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));
return 0;
}
+16 -9
View File
@@ -13,10 +13,12 @@
using boost::dummyT;
struct one_or_four {
bool operator()(dummyT x) const {
return x.foo() == 1 || x.foo() == 4;
}
struct one_or_four
{
bool operator()(dummyT x) const
{
return x.foo() == 1 || x.foo() == 4;
}
};
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
@@ -27,6 +29,7 @@ namespace boost { namespace detail
}}
#endif
template <class T> struct undefined;
// Test filter iterator
int main()
@@ -41,11 +44,15 @@ int main()
filter_iter(one_or_four(), array, array+N)
, dummyT(1), dummyT(4));
//# if 0
BOOST_STATIC_ASSERT(
(!boost::detail::is_bidirectional_traversal_iterator<
boost::traversal_category<filter_iter>::type
>::value) );
// Filter iterators can't be bidirectional, since we didn't choose
// to store the beginning of the range.
BOOST_STATIC_ASSERT((
!boost::detail::is_tag<
boost::bidirectional_traversal_tag
, boost::traversal_category<filter_iter>::type
>::value
));
//# endif
// On compilers not supporting partial specialization, we can do more type
+9 -16
View File
@@ -67,16 +67,6 @@ typedef RA_CONTAINER<int> storage;
typedef RA_CONTAINER<int*> pointer_ra_container;
typedef std::set<storage::iterator> iterator_set;
// Something has to be done about putting this in the lib
template <class Iter>
struct indirect_const_iterator_traits
: boost::detail::indirect_defaults<Iter>
{
typedef boost::detail::indirect_defaults<Iter> base;
typedef typename base::value_type const& reference;
typedef typename base::value_type const* pointer;
};
template <class Container>
struct indirect_iterator_pair_generator
{
@@ -84,7 +74,7 @@ struct indirect_iterator_pair_generator
typedef boost::indirect_iterator<
typename Container::iterator
, indirect_const_iterator_traits<typename Container::const_iterator>
, typename iterator::value_type const
> const_iterator;
};
@@ -114,8 +104,10 @@ namespace boost { namespace detail
}}
#endif
void more_indirect_iterator_tests()
{
# if 0
storage store(1000);
std::generate(store.begin(), store.end(), rand);
@@ -163,8 +155,8 @@ void more_indirect_iterator_tests()
typedef boost::indirect_iterator<iterator_set::iterator> indirect_set_iterator;
typedef boost::indirect_iterator<
iterator_set::iterator
, indirect_const_iterator_traits<iterator_set::const_iterator>
> const_indirect_set_iterator;
, iterator_set::iterator::value_type const
> const_indirect_set_iterator;
indirect_set_iterator sb(iter_set.begin());
indirect_set_iterator se(iter_set.end());
@@ -185,6 +177,7 @@ void more_indirect_iterator_tests()
boost::bidirectional_iterator_test(boost::next(sb), store[1], store[2]);
assert(std::equal(db, de, store.begin()));
#endif
}
int
@@ -210,8 +203,8 @@ main()
typedef boost::indirect_iterator<
shared_t::iterator
, indirect_const_iterator_traits<shared_t::const_iterator>
> c_iter_t;
, boost::iterator_value<shared_t::iterator>::type const
> c_iter_t;
# ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
boost::function_requires< boost_concepts::InteroperableConcept<iter_t, c_iter_t> >();
@@ -229,7 +222,7 @@ main()
typedef boost::indirect_iterator<dummyT**> indirect_iterator;
typedef boost::indirect_iterator<dummyT**, indirect_const_iterator_traits<dummyT* const*> >
typedef boost::indirect_iterator<dummyT**, dummyT const>
const_indirect_iterator;
indirect_iterator i(ptr);
+5
View File
@@ -1,3 +1,8 @@
// Copyright Thomas Witt 2003. 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.
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/concept_check.hpp>
+14 -272
View File
@@ -1,6 +1,4 @@
// Test boost/iterator_adaptors.hpp
// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify,
// (C) Copyright Thomas Witt 2003. 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
@@ -8,44 +6,6 @@
// 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 <boost/config.hpp>
#include <iostream>
@@ -125,23 +85,24 @@ struct my_gen
template <class V>
struct ptr_iterator
: boost::iterator_adaptor<ptr_iterator<V>
, V, V&, V*
, boost::iterator_tag<boost::mutable_lvalue_iterator_tag
,boost::random_access_traversal_tag>
, std::ptrdiff_t>
: boost::iterator_adaptor<
ptr_iterator<V>,
boost::iterator_traits_adaptor<V*,
V,
boost::iterator_tag< boost::writable_lvalue_iterator_tag
,boost::random_access_traversal_tag > >
>
{
private:
typedef iterator_adaptor super_t;
public:
ptr_iterator() { }
ptr_iterator(V* d) : m_base(d) { }
ptr_iterator(V* d) : super_t(d) { }
template <class V2>
ptr_iterator(const ptr_iterator<V2>& x) // should assert is_same add_cv<V> add_cv<V2>
: m_base(x.base()) { }
: super_t(x.base()) { }
V*& base() { return m_base; }
V* const& base() const { return m_base; }
private:
V* m_base;
};
int
@@ -164,9 +125,7 @@ main()
boost::const_nonconst_iterator_test(i, ++j);
}
#if 0
// Test the named parameters
// Test the iterator_traits
{
// Test computation of defaults
typedef boost::iterator_adaptor<int*, boost::default_iterator_policies,
@@ -218,175 +177,6 @@ main()
boost::const_nonconst_iterator_test(i, ++j);
}
// Test projection_iterator_pair_generator
{
typedef std::pair<dummyT,dummyT> Pair;
Pair pair_array[N];
for (int k = 0; k < N; ++k)
pair_array[k].first = array[k];
typedef boost::projection_iterator_pair_generator<select1st_<Pair>,
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_<Pair>()), N, array);
boost::random_access_iterator_test(boost::make_projection_iterator< select1st_<Pair> >(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_<Pair>()), N, array);
boost::random_access_iterator_test(boost::make_const_projection_iterator<select1st_<Pair> >(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<dummyT*
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT
#endif
>::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<const dummyT*
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT, const dummyT&, const dummyT
#endif
>::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<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_generator<
std::deque<dummyT>::iterator>::type reverse_iterator;
typedef boost::reverse_iterator_generator<
std::deque<dummyT>::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<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) || !defined(__GNUC__) && !defined(__BORLANDC__) && (!defined(BOOST_MSVC) || 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<int> 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<dummyT*>::type category;
typedef boost::filter_iterator_generator<one_or_four, dummyT*
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT
#endif
>::type filter_iter;
#if defined(__BORLANDC__)
// 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 !defined(__BORLANDC__)
//
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 !defined(BOOST_MSVC) || BOOST_MSVC > 1200 || defined(__SGI_STL_PORT)
std::deque<dummyT> 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<one_or_four>(array2.begin(), array2.end()),
dummyT(1), dummyT(4));
#endif
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 // This just freaks MSVC out completely
boost::forward_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));
#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<one_or_four>(array, array + N),
dummyT(1), dummyT(4));
#endif
}
// check operator-> with a forward iterator
{
boost::forward_iterator_archetype<dummyT> forward_iter;
@@ -423,54 +213,6 @@ main()
assert((*i).m_x == i->foo());
}
{
// check generator_iterator
my_gen g1;
boost::generator_iterator_generator<my_gen>::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 ) );
}
#endif
std::cout << "test successful " << std::endl;
return 0;
}
+87
View File
@@ -0,0 +1,87 @@
// Copyright Thomas Witt 2003. 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.
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
// Test reverse iterator
int main()
{
#if 0
// Test reverse_iterator_generator
{
dummyT reversed[N];
std::copy(array, array + N, reversed);
std::reverse(reversed, reversed + N);
typedef boost::reverse_iterator_generator<dummyT*
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT
#endif
>::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<const dummyT*
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT, const dummyT&, const dummyT
#endif
>::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<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_generator<
std::deque<dummyT>::iterator>::type reverse_iterator;
typedef boost::reverse_iterator_generator<
std::deque<dummyT>::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<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) || !defined(__GNUC__) && !defined(__BORLANDC__) && (!defined(BOOST_MSVC) || BOOST_MSVC > 1200)
boost::const_nonconst_iterator_test(i, ++j);
#endif
}
#endif
}