forked from boostorg/iterator
Move from boost-sandbox
[SVN r18960]
This commit is contained in:
14
test/Jamfile
Normal file
14
test/Jamfile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
|
||||||
|
include testing.jam ;
|
||||||
|
run unit_tests.cpp ;
|
||||||
|
run concept_tests.cpp ;
|
||||||
|
run iterator_adaptor_cc.cpp ;
|
||||||
|
run iterator_adaptor_test.cpp ;
|
||||||
|
compile iterator_archetype_cc.cpp ;
|
||||||
|
run transform_iterator_test.cpp ;
|
||||||
|
run indirect_iterator_test.cpp ;
|
||||||
|
run filter_iterator_test.cpp ;
|
||||||
|
run reverse_iterator_test.cpp ;
|
||||||
|
run counting_iterator_test.cpp ;
|
||||||
|
run is_convertible_fail.cpp ; # test changed to expected success, so that we catch compilation failures.
|
||||||
|
compile-fail interoperable_fail.cpp ;
|
174
test/concept_tests.cpp
Normal file
174
test/concept_tests.cpp
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
// (C) Copyright Jeremy Siek 2002. 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/iterator_concepts.hpp>
|
||||||
|
#include <boost/operators.hpp>
|
||||||
|
#include <boost/static_assert.hpp> // remove
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
#include "static_assert_same.hpp" // remove
|
||||||
|
|
||||||
|
struct new_iterator
|
||||||
|
: public boost::iterator< boost::iterator_tag<
|
||||||
|
boost::writable_lvalue_iterator_tag
|
||||||
|
, boost::random_access_traversal_tag>, int>
|
||||||
|
{
|
||||||
|
int& operator*() const { return *m_x; }
|
||||||
|
new_iterator& operator++() { return *this; }
|
||||||
|
new_iterator operator++(int) { return *this; }
|
||||||
|
new_iterator& operator--() { return *this; }
|
||||||
|
new_iterator operator--(int) { return *this; }
|
||||||
|
new_iterator& operator+=(std::ptrdiff_t) { return *this; }
|
||||||
|
new_iterator operator+(std::ptrdiff_t) { return *this; }
|
||||||
|
new_iterator& operator-=(std::ptrdiff_t) { return *this; }
|
||||||
|
std::ptrdiff_t operator-(const new_iterator&) const { return 0; }
|
||||||
|
new_iterator operator-(std::ptrdiff_t) const { return *this; }
|
||||||
|
bool operator==(const new_iterator&) const { return false; }
|
||||||
|
bool operator!=(const new_iterator&) const { return false; }
|
||||||
|
bool operator<(const new_iterator&) const { return false; }
|
||||||
|
int* m_x;
|
||||||
|
};
|
||||||
|
new_iterator operator+(std::ptrdiff_t, new_iterator x) { return x; }
|
||||||
|
|
||||||
|
struct old_iterator
|
||||||
|
: public boost::iterator<std::random_access_iterator_tag, int>
|
||||||
|
{
|
||||||
|
int& operator*() const { return *m_x; }
|
||||||
|
old_iterator& operator++() { return *this; }
|
||||||
|
old_iterator operator++(int) { return *this; }
|
||||||
|
old_iterator& operator--() { return *this; }
|
||||||
|
old_iterator operator--(int) { return *this; }
|
||||||
|
old_iterator& operator+=(std::ptrdiff_t) { return *this; }
|
||||||
|
old_iterator operator+(std::ptrdiff_t) { return *this; }
|
||||||
|
old_iterator& operator-=(std::ptrdiff_t) { return *this; }
|
||||||
|
old_iterator operator-(std::ptrdiff_t) const { return *this; }
|
||||||
|
std::ptrdiff_t operator-(const old_iterator&) const { return 0; }
|
||||||
|
bool operator==(const old_iterator&) const { return false; }
|
||||||
|
bool operator!=(const old_iterator&) const { return false; }
|
||||||
|
bool operator<(const old_iterator&) const { return false; }
|
||||||
|
int* m_x;
|
||||||
|
};
|
||||||
|
old_iterator operator+(std::ptrdiff_t, old_iterator x) { return x; }
|
||||||
|
|
||||||
|
struct my_writable_lvalue_iterator_tag
|
||||||
|
{
|
||||||
|
operator boost::writable_lvalue_iterator_tag() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct my_single_pass_traversal_tag
|
||||||
|
{
|
||||||
|
operator boost::single_pass_traversal_tag() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_tag_convertibility()
|
||||||
|
{
|
||||||
|
// This set of tests is by no means complete.
|
||||||
|
|
||||||
|
// Test that this is an input/output iterator
|
||||||
|
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||||
|
{
|
||||||
|
typedef boost::iterator_tag<
|
||||||
|
boost::writable_lvalue_iterator_tag
|
||||||
|
, boost::single_pass_traversal_tag
|
||||||
|
> tag;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_convertible<tag, std::output_iterator_tag>::value
|
||||||
|
));
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_convertible<tag, std::input_iterator_tag>::value
|
||||||
|
));
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
!boost::is_convertible<tag, std::forward_iterator_tag>::value
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it's possible to build new sub-tags without
|
||||||
|
// derivation. Convertibility should be enough
|
||||||
|
{
|
||||||
|
typedef boost::iterator_tag<
|
||||||
|
my_writable_lvalue_iterator_tag
|
||||||
|
, my_single_pass_traversal_tag
|
||||||
|
> tag;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_convertible<tag, std::output_iterator_tag>::value
|
||||||
|
));
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_convertible<tag, std::input_iterator_tag>::value
|
||||||
|
));
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
!boost::is_convertible<tag, std::forward_iterator_tag>::value
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a single-pass readable lvalue iterator is only an
|
||||||
|
// input iterator. Requires special case handling in
|
||||||
|
// categories.hpp
|
||||||
|
{
|
||||||
|
typedef boost::iterator_tag<
|
||||||
|
boost::readable_lvalue_iterator_tag
|
||||||
|
, boost::single_pass_traversal_tag
|
||||||
|
> tag;
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_convertible<tag, std::input_iterator_tag>::value
|
||||||
|
));
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
!boost::is_convertible<tag, std::output_iterator_tag>::value
|
||||||
|
));
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
!boost::is_convertible<tag, std::forward_iterator_tag>::value
|
||||||
|
));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
test_tag_convertibility();
|
||||||
|
|
||||||
|
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));
|
||||||
|
int test = static_assert_same<tag::access, boost::writable_lvalue_iterator_tag>::value;
|
||||||
|
test = static_assert_same<tag::traversal, boost::random_access_traversal_tag>::value;
|
||||||
|
|
||||||
|
// BOOST_STATIC_ASSERT((boost::detail::is_random_access_iterator<new_iterator::iterator_category>::value));
|
||||||
|
test = static_assert_same<new_iterator::iterator_category::access, boost::writable_lvalue_iterator_tag>::value;
|
||||||
|
test = static_assert_same<new_iterator::iterator_category::traversal, boost::random_access_traversal_tag>::value;
|
||||||
|
|
||||||
|
typedef boost::traversal_category<new_iterator>::type traversal_category;
|
||||||
|
|
||||||
|
// BOOST_STATIC_ASSERT(boost::detail::has_traversal<new_iterator::iterator_category>::value);
|
||||||
|
BOOST_STATIC_ASSERT(boost::detail::is_new_iterator_tag<new_iterator::iterator_category>::value);
|
||||||
|
|
||||||
|
|
||||||
|
test = static_assert_same<traversal_category, boost::random_access_traversal_tag>::value;
|
||||||
|
(void)test;
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
|
boost::function_requires<
|
||||||
|
boost_concepts::WritableLvalueIteratorConcept<int*> >();
|
||||||
|
boost::function_requires<
|
||||||
|
boost_concepts::RandomAccessTraversalConcept<int*> >();
|
||||||
|
|
||||||
|
boost::function_requires<
|
||||||
|
boost_concepts::ReadableLvalueIteratorConcept<const int*> >();
|
||||||
|
boost::function_requires<
|
||||||
|
boost_concepts::RandomAccessTraversalConcept<const int*> >();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
boost::function_requires<
|
||||||
|
boost_concepts::WritableLvalueIteratorConcept<new_iterator> >();
|
||||||
|
boost::function_requires<
|
||||||
|
boost_concepts::RandomAccessTraversalConcept<new_iterator> >();
|
||||||
|
|
||||||
|
boost::function_requires<
|
||||||
|
boost_concepts::WritableLvalueIteratorConcept<old_iterator> >();
|
||||||
|
boost::function_requires<
|
||||||
|
boost_concepts::RandomAccessTraversalConcept<old_iterator> >();
|
||||||
|
return 0;
|
||||||
|
}
|
295
test/counting_iterator_test.cpp
Normal file
295
test/counting_iterator_test.cpp
Normal 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;
|
||||||
|
}
|
87
test/filter_iterator_test.cpp
Normal file
87
test/filter_iterator_test.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright David Abrahams 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/filter_iterator.hpp>
|
||||||
|
#include <boost/iterator/reverse_iterator.hpp>
|
||||||
|
#include <boost/iterator/new_iterator_tests.hpp>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using boost::dummyT;
|
||||||
|
|
||||||
|
struct one_or_four
|
||||||
|
{
|
||||||
|
bool operator()(dummyT x) const
|
||||||
|
{
|
||||||
|
return x.foo() == 1 || x.foo() == 4;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
namespace boost { namespace detail
|
||||||
|
{
|
||||||
|
template<> struct iterator_traits<dummyT*>
|
||||||
|
: ptr_iter_traits<dummyT> {};
|
||||||
|
}}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class T> struct undefined;
|
||||||
|
|
||||||
|
// Test filter iterator
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
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::detail::is_tag<
|
||||||
|
boost::random_access_traversal_tag
|
||||||
|
, boost::traversal_category<filter_iter>::type
|
||||||
|
>::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 0;
|
||||||
|
}
|
253
test/indirect_iterator_test.cpp
Normal file
253
test/indirect_iterator_test.cpp
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
// (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
|
||||||
|
// 22 Nov 2002 Thomas Witt
|
||||||
|
// Added interoperability check.
|
||||||
|
// 08 Mar 2001 Jeremy Siek
|
||||||
|
// Moved test of indirect iterator into its own file. It to
|
||||||
|
// to be in iterator_adaptor_test.cpp.
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <boost/iterator/indirect_iterator.hpp>
|
||||||
|
#include <boost/iterator/iterator_concepts.hpp>
|
||||||
|
#include <boost/iterator/new_iterator_tests.hpp>
|
||||||
|
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#include <boost/concept_archetype.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#if !defined(__SGI_STL_PORT) \
|
||||||
|
&& (defined(BOOST_MSVC_STD_ITERATOR) \
|
||||||
|
|| BOOST_WORKAROUND(_CPPLIB_VER, <= 310) \
|
||||||
|
|| BOOST_WORKAROUND(__GNUC__, <= 2))
|
||||||
|
|
||||||
|
// std container random-access iterators don't support mutable/const
|
||||||
|
// interoperability (but may support const/mutable interop).
|
||||||
|
# define NO_MUTABLE_CONST_STD_DEQUE_ITERATOR_INTEROPERABILITY
|
||||||
|
# define NO_MUTABLE_CONST_STD_SET_ITERATOR_INTEROPERABILITY
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC_STD_ITERATOR) \
|
||||||
|
|| defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
|
|
||||||
|
// No working iterator_traits implementation, so we must use deque
|
||||||
|
# define RA_CONTAINER std::deque
|
||||||
|
# include <deque>
|
||||||
|
|
||||||
|
# ifdef NO_MUTABLE_CONST_STD_DEQUE_ITERATOR_INTEROPERABILITY
|
||||||
|
# define NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# define RA_CONTAINER std::vector
|
||||||
|
# include <vector>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||||
|
|
||||||
|
using boost::dummyT;
|
||||||
|
|
||||||
|
typedef RA_CONTAINER<int> storage;
|
||||||
|
typedef RA_CONTAINER<int*> pointer_ra_container;
|
||||||
|
typedef std::set<storage::iterator> iterator_set;
|
||||||
|
|
||||||
|
template <class Container>
|
||||||
|
struct indirect_iterator_pair_generator
|
||||||
|
{
|
||||||
|
typedef boost::indirect_iterator<typename Container::iterator> iterator;
|
||||||
|
|
||||||
|
typedef boost::indirect_iterator<
|
||||||
|
typename Container::iterator
|
||||||
|
, typename iterator::value_type const
|
||||||
|
> const_iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
namespace boost { namespace detail
|
||||||
|
{
|
||||||
|
template<> struct iterator_traits<int*>
|
||||||
|
: ptr_iter_traits<int> {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<dummyT*>
|
||||||
|
: ptr_iter_traits<dummyT> {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<dummyT*const>
|
||||||
|
: ptr_iter_traits<dummyT> {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<dummyT const*>
|
||||||
|
: ptr_iter_traits<dummyT, dummyT const> {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<dummyT**>
|
||||||
|
: ptr_iter_traits<dummyT*> {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<dummyT*const*>
|
||||||
|
: ptr_iter_traits<dummyT*const> {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<dummyT const*const*>
|
||||||
|
: ptr_iter_traits<dummyT const*, dummyT const*const> {};
|
||||||
|
}}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void more_indirect_iterator_tests()
|
||||||
|
{
|
||||||
|
# if 0
|
||||||
|
storage store(1000);
|
||||||
|
std::generate(store.begin(), store.end(), rand);
|
||||||
|
|
||||||
|
pointer_ra_container ptr_ra_container;
|
||||||
|
iterator_set iter_set;
|
||||||
|
|
||||||
|
for (storage::iterator p = store.begin(); p != store.end(); ++p)
|
||||||
|
{
|
||||||
|
ptr_ra_container.push_back(&*p);
|
||||||
|
iter_set.insert(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef indirect_iterator_pair_generator<pointer_ra_container> indirect_ra_container;
|
||||||
|
|
||||||
|
indirect_ra_container::iterator db(ptr_ra_container.begin());
|
||||||
|
indirect_ra_container::iterator de(ptr_ra_container.end());
|
||||||
|
assert(static_cast<std::size_t>(de - db) == store.size());
|
||||||
|
assert(db + store.size() == de);
|
||||||
|
indirect_ra_container::const_iterator dci = db;
|
||||||
|
|
||||||
|
assert(dci == db);
|
||||||
|
|
||||||
|
#ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
|
||||||
|
assert(db == dci);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert(dci != de);
|
||||||
|
assert(dci < de);
|
||||||
|
assert(dci <= de);
|
||||||
|
|
||||||
|
#ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
|
||||||
|
assert(de >= dci);
|
||||||
|
assert(de > dci);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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 typedefs here
|
||||||
|
typedef boost::indirect_iterator<iterator_set::iterator> indirect_set_iterator;
|
||||||
|
typedef boost::indirect_iterator<
|
||||||
|
iterator_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());
|
||||||
|
const_indirect_set_iterator sci(iter_set.begin());
|
||||||
|
assert(sci == sb);
|
||||||
|
|
||||||
|
# ifndef NO_MUTABLE_CONST_STD_SET_ITERATOR_INTEROPERABILITY
|
||||||
|
assert(se != sci);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
typedef RA_CONTAINER<boost::shared_ptr<dummyT> > shared_t;
|
||||||
|
shared_t shared;
|
||||||
|
|
||||||
|
// Concept checks
|
||||||
|
{
|
||||||
|
typedef boost::indirect_iterator<shared_t::iterator> iter_t;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
boost::detail::has_element_type<
|
||||||
|
boost::shared_ptr<dummyT>
|
||||||
|
// std::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::InteroperableConcept<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();
|
||||||
|
}
|
||||||
|
std::cout << "test successful " << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
22
test/interoperable_fail.cpp
Normal file
22
test/interoperable_fail.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// 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>
|
||||||
|
#include <boost/cstdlib.hpp>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
typedef boost::reverse_iterator<std::list<int*>::iterator> rev_iter;
|
||||||
|
typedef boost::indirect_iterator<std::list<int*>::iterator> ind_iter;
|
||||||
|
|
||||||
|
ind_iter() == rev_iter();
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::exit_success;
|
||||||
|
}
|
11
test/is_convertible_fail.cpp
Normal file
11
test/is_convertible_fail.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include <boost/iterator/reverse_iterator.hpp>
|
||||||
|
#include <boost/cstdlib.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
typedef boost::reverse_iterator<int*> rev_iter1;
|
||||||
|
typedef boost::reverse_iterator<char*> rev_iter2;
|
||||||
|
|
||||||
|
return boost::is_convertible<rev_iter1, rev_iter2>::value
|
||||||
|
? boost::exit_failure : boost::exit_success;
|
||||||
|
}
|
40
test/iterator_adaptor_cc.cpp
Normal file
40
test/iterator_adaptor_cc.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include <boost/iterator/reverse_iterator.hpp>
|
||||||
|
#include <boost/iterator/iterator_concepts.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
#include <boost/cstdlib.hpp>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
namespace boost { namespace detail
|
||||||
|
{
|
||||||
|
template<> struct iterator_traits<int*>
|
||||||
|
: ptr_iter_traits<int> {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<int const*>
|
||||||
|
: ptr_iter_traits<int, int const> {};
|
||||||
|
}}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
typedef boost::reverse_iterator<int*> rev_iter;
|
||||||
|
typedef boost::reverse_iterator<int const*> c_rev_iter;
|
||||||
|
|
||||||
|
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<rev_iter> >();
|
||||||
|
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<rev_iter> >();
|
||||||
|
boost::function_requires< boost::RandomAccessIteratorConcept<rev_iter> >();
|
||||||
|
boost::function_requires< boost_concepts::InteroperableConcept<rev_iter, c_rev_iter> >();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typedef boost::reverse_iterator<std::list<int>::iterator> rev_iter;
|
||||||
|
typedef boost::reverse_iterator<std::list<int>::const_iterator> c_rev_iter;
|
||||||
|
|
||||||
|
boost::function_requires< boost_concepts::ReadableLvalueIteratorConcept<c_rev_iter> >();
|
||||||
|
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<c_rev_iter> >();
|
||||||
|
boost::function_requires< boost::BidirectionalIteratorConcept<c_rev_iter> >();
|
||||||
|
boost::function_requires< boost_concepts::InteroperableConcept<rev_iter, c_rev_iter> >();
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::exit_success;
|
||||||
|
}
|
261
test/iterator_adaptor_test.cpp
Normal file
261
test/iterator_adaptor_test.cpp
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
// (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
|
||||||
|
// to its suitability for any purpose.
|
||||||
|
|
||||||
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
#include <boost/pending/iterator_tests.hpp>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
#include <set>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include "static_assert_same.hpp"
|
||||||
|
|
||||||
|
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 <class Pair>
|
||||||
|
struct select1st_
|
||||||
|
: public std::unary_function<Pair, typename Pair::first_type>
|
||||||
|
{
|
||||||
|
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<int> storage;
|
||||||
|
typedef std::deque<int*> pointer_deque;
|
||||||
|
typedef std::set<storage::iterator> iterator_set;
|
||||||
|
|
||||||
|
template <class T> struct foo;
|
||||||
|
|
||||||
|
void blah(int) { }
|
||||||
|
|
||||||
|
struct my_gen
|
||||||
|
{
|
||||||
|
typedef int result_type;
|
||||||
|
my_gen() : n(0) { }
|
||||||
|
int operator()() { return ++n; }
|
||||||
|
int n;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class V>
|
||||||
|
struct ptr_iterator
|
||||||
|
: boost::iterator_adaptor<
|
||||||
|
ptr_iterator<V>
|
||||||
|
, V*
|
||||||
|
, V
|
||||||
|
, std::random_access_iterator_tag
|
||||||
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
, V&
|
||||||
|
#endif
|
||||||
|
>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef boost::iterator_adaptor<
|
||||||
|
ptr_iterator<V>
|
||||||
|
, V*
|
||||||
|
, V
|
||||||
|
, std::random_access_iterator_tag
|
||||||
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
, V&
|
||||||
|
#endif
|
||||||
|
> super_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ptr_iterator() { }
|
||||||
|
ptr_iterator(V* d) : super_t(d) { }
|
||||||
|
|
||||||
|
template <class V2>
|
||||||
|
ptr_iterator(
|
||||||
|
const ptr_iterator<V2>& x
|
||||||
|
, typename boost::enable_if_convertible<V2*, V*>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(x.base())
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct fwd_iterator
|
||||||
|
: boost::iterator_adaptor<
|
||||||
|
fwd_iterator<T>
|
||||||
|
, boost::forward_iterator_archetype<T>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef boost::iterator_adaptor<
|
||||||
|
fwd_iterator<T>
|
||||||
|
, boost::forward_iterator_archetype<T>
|
||||||
|
> super_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
fwd_iterator() { }
|
||||||
|
fwd_iterator(boost::forward_iterator_archetype<T> d) : super_t(d) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct in_iterator
|
||||||
|
: boost::iterator_adaptor<
|
||||||
|
in_iterator<T>
|
||||||
|
, boost::input_iterator_archetype<T>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef boost::iterator_adaptor<
|
||||||
|
in_iterator<T>
|
||||||
|
, boost::input_iterator_archetype<T>
|
||||||
|
> super_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
in_iterator() { }
|
||||||
|
in_iterator(boost::input_iterator_archetype<T> d) : super_t(d) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Iter>
|
||||||
|
struct constant_iterator
|
||||||
|
: boost::iterator_adaptor<
|
||||||
|
constant_iterator<Iter>
|
||||||
|
, Iter
|
||||||
|
, typename std::iterator_traits<Iter>::value_type const
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef boost::iterator_adaptor<
|
||||||
|
constant_iterator<Iter>
|
||||||
|
, Iter
|
||||||
|
, typename std::iterator_traits<Iter>::value_type const
|
||||||
|
> base_t;
|
||||||
|
|
||||||
|
constant_iterator() {}
|
||||||
|
constant_iterator(Iter it)
|
||||||
|
: base_t(it) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
test = static_assert_same<Iter1::iterator_category::access, boost::readable_lvalue_iterator_tag>::value; test = static_assert_same<Iter1::pointer, const int*>::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
test = static_assert_same<Iter::pointer, int const*>::value;
|
||||||
|
|
||||||
|
test = static_assert_same<BaseIter::iterator_category::access, boost::writable_lvalue_iterator_tag>::value;
|
||||||
|
test = static_assert_same<Iter::iterator_category::access, boost::readable_lvalue_iterator_tag>::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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<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());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "test successful " << std::endl;
|
||||||
|
(void)test;
|
||||||
|
return 0;
|
||||||
|
}
|
25
test/iterator_archetype_cc.cpp
Normal file
25
test/iterator_archetype_cc.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// 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/iterator_archetypes.hpp>
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
#include <boost/iterator/iterator_concepts.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
typedef boost::iterator_archetype<int,
|
||||||
|
boost::writable_lvalue_iterator_tag,
|
||||||
|
boost::random_access_traversal_tag> iter;
|
||||||
|
|
||||||
|
boost::function_requires< boost_concepts::WritableLvalueIteratorConcept<iter> >();
|
||||||
|
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
|
||||||
|
}
|
||||||
|
return 0; // keep msvc happy
|
||||||
|
}
|
||||||
|
|
101
test/permutation_iterator_test.cpp
Normal file
101
test/permutation_iterator_test.cpp
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// (C) Copyright Toon Knapen 2001.
|
||||||
|
// (C) Copyright Roland Richter 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/config.hpp>
|
||||||
|
#include <boost/test/minimal.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/permutation_iterator.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
void permutation_test()
|
||||||
|
{
|
||||||
|
// Example taken from documentation of old permutation_iterator.
|
||||||
|
typedef std::vector< int > element_range_type;
|
||||||
|
typedef std::list< int > index_type;
|
||||||
|
|
||||||
|
const int element_range_size = 10;
|
||||||
|
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() );
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
|
||||||
|
typedef boost::permutation_iterator< element_range_type::iterator
|
||||||
|
, index_type::iterator
|
||||||
|
, boost::use_default
|
||||||
|
, boost::use_default
|
||||||
|
, element_range_type::reference > permutation_type;
|
||||||
|
|
||||||
|
permutation_type begin( elements.begin(), indices.begin() );
|
||||||
|
permutation_type it = begin;
|
||||||
|
permutation_type end( elements.begin(), indices.end() );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef boost::permutation_iterator< element_range_type::iterator, index_type::iterator > permutation_type;
|
||||||
|
permutation_type begin = boost::make_permutation_iterator( elements.begin(), indices.begin() );
|
||||||
|
permutation_type it = begin;
|
||||||
|
permutation_type end = boost::make_permutation_iterator( elements.begin(), indices.end() );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOOST_CHECK( it == begin );
|
||||||
|
BOOST_CHECK( it != end );
|
||||||
|
|
||||||
|
BOOST_CHECK( std::distance( begin, end ) == index_size );
|
||||||
|
|
||||||
|
for( index_type::iterator i_it = indices.begin(); it != end; ++i_it, ++it )
|
||||||
|
{
|
||||||
|
BOOST_CHECK( *it == elements[ *i_it ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
it = begin;
|
||||||
|
for( int i = 0; i < index_size ; i+=2, it+=2 )
|
||||||
|
{
|
||||||
|
index_type::iterator i_it = indices.begin(); std::advance( i_it, i );
|
||||||
|
BOOST_CHECK( *it == elements[ *i_it ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
it = begin + (index_size);
|
||||||
|
BOOST_CHECK( it != begin );
|
||||||
|
for( index_type::iterator i_it = --indices.end(); it-- != begin; --i_it )
|
||||||
|
{
|
||||||
|
BOOST_CHECK( *it == elements[ *i_it ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
it = begin + (index_size - 1);
|
||||||
|
for( int i = 0; i < index_size; i+=2, it-=2 )
|
||||||
|
{
|
||||||
|
index_type::iterator i_it = --indices.end(); std::advance( i_it, -i );
|
||||||
|
BOOST_CHECK( *it == elements[ *i_it ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int test_main(int, char *[])
|
||||||
|
{
|
||||||
|
permutation_test();
|
||||||
|
|
||||||
|
bool error_on_purpose = false;
|
||||||
|
//BOOST_CHECK( error_on_purpose );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
97
test/reverse_iterator_test.cpp
Normal file
97
test/reverse_iterator_test.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// 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>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
using boost::dummyT;
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template<> struct iterator_traits<dummyT*>
|
||||||
|
: ptr_iter_traits<dummyT> {};
|
||||||
|
template<> struct iterator_traits<dummyT const*>
|
||||||
|
: ptr_iter_traits<dummyT const> {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Test reverse_iterator_generator
|
||||||
|
{
|
||||||
|
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_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<
|
||||||
|
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(__BORLANDC__, BOOST_TESTED_AT(0x551)) \
|
||||||
|
&& !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 1)
|
||||||
|
|
||||||
|
boost::const_nonconst_iterator_test(i, ++j);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
31
test/static_assert_same.hpp
Normal file
31
test/static_assert_same.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright David Abrahams 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.
|
||||||
|
#ifndef STATIC_ASSERT_SAME_DWA2003530_HPP
|
||||||
|
# define STATIC_ASSERT_SAME_DWA2003530_HPP
|
||||||
|
|
||||||
|
# include <boost/type.hpp>
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
template <class T, class U>
|
||||||
|
struct static_assert_same;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct static_assert_same<T,T>
|
||||||
|
{
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
# include <boost/mpl/if.hpp>
|
||||||
|
# include <boost/mpl/bool.hpp>
|
||||||
|
# include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
|
template <class T, class U>
|
||||||
|
struct static_assert_same
|
||||||
|
: boost::mpl::if_<boost::is_same<T,U>,boost::mpl::true_,void>::type
|
||||||
|
{};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // STATIC_ASSERT_SAME_DWA2003530_HPP
|
248
test/transform_iterator_test.cpp
Normal file
248
test/transform_iterator_test.cpp
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
// (C) Copyright Jeremy Siek 2002. 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
|
||||||
|
// 22 Nov 2002 Thomas Witt
|
||||||
|
// Added interoperability check.
|
||||||
|
// 28 Oct 2002 Jeremy Siek
|
||||||
|
// Updated for new iterator adaptors.
|
||||||
|
// 08 Mar 2001 Jeremy Siek
|
||||||
|
// Moved test of transform iterator into its own file. It to
|
||||||
|
// to be in iterator_adaptor_test.cpp.
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
#include <boost/iterator/iterator_concepts.hpp>
|
||||||
|
#include <boost/iterator/new_iterator_tests.hpp>
|
||||||
|
#include <boost/pending/iterator_tests.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <boost/concept_check.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
namespace boost { namespace detail
|
||||||
|
{
|
||||||
|
template<> struct iterator_traits<int*>
|
||||||
|
: ptr_iter_traits<int> {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<std::pair<int, int>*>
|
||||||
|
: ptr_iter_traits<std::pair<int, int> > {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<int const*>
|
||||||
|
: ptr_iter_traits<int, int const> {};
|
||||||
|
|
||||||
|
template<> struct iterator_traits<std::pair<int, int> const*>
|
||||||
|
: ptr_iter_traits<std::pair<int, int>, std::pair<int, int> const> {};
|
||||||
|
|
||||||
|
}}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct mult_functor {
|
||||||
|
// 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct adaptable_mult_functor
|
||||||
|
: 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.
|
||||||
|
adaptable_mult_functor() { }
|
||||||
|
adaptable_mult_functor(int aa) : mult_functor(aa) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct select_first
|
||||||
|
{
|
||||||
|
typedef int& result_type;
|
||||||
|
|
||||||
|
int& operator()(std::pair<int, int>& p) const
|
||||||
|
{
|
||||||
|
return p.first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct select_second
|
||||||
|
{
|
||||||
|
typedef int& result_type;
|
||||||
|
|
||||||
|
int& operator()(std::pair<int, int>& p) const
|
||||||
|
{
|
||||||
|
return p.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct const_select_first
|
||||||
|
{
|
||||||
|
typedef int const& result_type;
|
||||||
|
|
||||||
|
int const& operator()(std::pair<int, int>const& p) const
|
||||||
|
{
|
||||||
|
return p.first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct value_select_first
|
||||||
|
{
|
||||||
|
typedef int result_type;
|
||||||
|
|
||||||
|
int operator()(std::pair<int, int>const& p) const
|
||||||
|
{
|
||||||
|
return p.first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int mult_2(int arg)
|
||||||
|
{
|
||||||
|
return arg*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
const int N = 10;
|
||||||
|
|
||||||
|
// Concept checks
|
||||||
|
{
|
||||||
|
typedef boost::transform_iterator<adaptable_mult_functor, int*> iter_t;
|
||||||
|
typedef boost::transform_iterator<adaptable_mult_functor, int const*> c_iter_t;
|
||||||
|
|
||||||
|
boost::function_requires< boost_concepts::InteroperableConcept<iter_t, c_iter_t> >();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
typedef boost::transform_iterator<adaptable_mult_functor, int*> iter_t;
|
||||||
|
iter_t i(y, adaptable_mult_functor(2));
|
||||||
|
boost::input_iterator_test(i, x[0], x[1]);
|
||||||
|
boost::input_iterator_test(iter_t(&y[0], adaptable_mult_functor(2)), x[0], x[1]);
|
||||||
|
|
||||||
|
boost::random_access_readable_iterator_test(i, N, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test transform_iterator non adaptable functor
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
typedef boost::transform_iterator<mult_functor, int*, int> iter_t;
|
||||||
|
iter_t i(y, mult_functor(2));
|
||||||
|
boost::input_iterator_test(i, x[0], x[1]);
|
||||||
|
boost::input_iterator_test(iter_t(&y[0], mult_functor(2)), x[0], x[1]);
|
||||||
|
|
||||||
|
boost::random_access_readable_iterator_test(i, N, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test transform_iterator default argument handling
|
||||||
|
{
|
||||||
|
{
|
||||||
|
typedef boost::transform_iterator<adaptable_mult_functor, int*, float> iter_t;
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::reference, float>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::value_type, float>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef boost::transform_iterator<adaptable_mult_functor, int*, boost::use_default, float> iter_t;
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::reference, int>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::value_type, float>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef boost::transform_iterator<adaptable_mult_functor, int*, float, double> iter_t;
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::reference, float>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::value_type, double>::value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test transform_iterator with function pointers
|
||||||
|
{
|
||||||
|
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::input_iterator_test(boost::make_transform_iterator(y, mult_2)
|
||||||
|
, x[0]
|
||||||
|
, x[1]);
|
||||||
|
|
||||||
|
boost::input_iterator_test(boost::make_transform_iterator(&y[0], mult_2)
|
||||||
|
, x[0]
|
||||||
|
, x[1]);
|
||||||
|
|
||||||
|
boost::random_access_readable_iterator_test(boost::make_transform_iterator(y, mult_2)
|
||||||
|
, N
|
||||||
|
, x);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test transform_iterator as projection iterator
|
||||||
|
{
|
||||||
|
typedef std::pair<int, int> pair_t;
|
||||||
|
|
||||||
|
int x[N];
|
||||||
|
int y[N];
|
||||||
|
pair_t values[N];
|
||||||
|
|
||||||
|
for(int i = 0; i < N; ++i) {
|
||||||
|
|
||||||
|
x[i] = i;
|
||||||
|
y[i] = N - (i + 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::copy(x,
|
||||||
|
x + N,
|
||||||
|
boost::make_transform_iterator((pair_t*)values, select_first()));
|
||||||
|
|
||||||
|
std::copy(y,
|
||||||
|
y + N,
|
||||||
|
boost::make_transform_iterator((pair_t*)values, select_second()));
|
||||||
|
|
||||||
|
boost::random_access_readable_iterator_test(boost::make_transform_iterator((pair_t*)values, value_select_first()),
|
||||||
|
N,
|
||||||
|
x);
|
||||||
|
|
||||||
|
boost::random_access_readable_iterator_test(boost::make_transform_iterator((pair_t*)values, const_select_first()),
|
||||||
|
N,
|
||||||
|
x);
|
||||||
|
|
||||||
|
boost::constant_lvalue_iterator_test(boost::make_transform_iterator((pair_t*)values, const_select_first()), x[0]);
|
||||||
|
|
||||||
|
boost::mutable_lvalue_iterator_test(boost::make_transform_iterator((pair_t*)values, select_first()), x[0], 17);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "test successful " << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
103
test/unit_tests.cpp
Normal file
103
test/unit_tests.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Copyright David Abrahams 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/iterator_adaptor.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include "static_assert_same.hpp"
|
||||||
|
|
||||||
|
struct X { int a; };
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
namespace boost { namespace detail {
|
||||||
|
template<> struct iterator_traits<X*>
|
||||||
|
: ptr_iter_traits<X> {};
|
||||||
|
}}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Xiter : boost::iterator_adaptor<Xiter,X*>
|
||||||
|
{
|
||||||
|
Xiter();
|
||||||
|
Xiter(X* p) : boost::iterator_adaptor<Xiter, X*>(p) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void take_xptr(X*) {}
|
||||||
|
void operator_arrow_test()
|
||||||
|
{
|
||||||
|
// check that the operator-> result is a pointer for lvalue iterators
|
||||||
|
X x;
|
||||||
|
take_xptr(Xiter(&x).operator->());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class U, class Min>
|
||||||
|
struct static_assert_min_cat
|
||||||
|
: static_assert_same<
|
||||||
|
typename boost::detail::minimum_category<T,U>::type, Min
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
|
||||||
|
void category_test()
|
||||||
|
{
|
||||||
|
using namespace boost;
|
||||||
|
using namespace boost::detail;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
!is_tag<
|
||||||
|
input_output_iterator_tag
|
||||||
|
, std::input_iterator_tag>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
!is_tag<
|
||||||
|
input_output_iterator_tag
|
||||||
|
, std::output_iterator_tag>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
is_tag<
|
||||||
|
std::input_iterator_tag
|
||||||
|
, input_output_iterator_tag>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
is_tag<
|
||||||
|
std::output_iterator_tag
|
||||||
|
, input_output_iterator_tag>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
is_tag<
|
||||||
|
input_output_iterator_tag
|
||||||
|
, std::forward_iterator_tag>::value));
|
||||||
|
|
||||||
|
int test = static_assert_min_cat<
|
||||||
|
std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag
|
||||||
|
>::value;
|
||||||
|
|
||||||
|
test = static_assert_min_cat<
|
||||||
|
input_output_iterator_tag,std::input_iterator_tag, std::input_iterator_tag
|
||||||
|
>::value;
|
||||||
|
|
||||||
|
test = static_assert_min_cat<
|
||||||
|
input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag
|
||||||
|
>::value;
|
||||||
|
|
||||||
|
test = static_assert_min_cat<
|
||||||
|
std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag
|
||||||
|
>::value;
|
||||||
|
|
||||||
|
test = static_assert_min_cat<
|
||||||
|
std::input_iterator_tag,std::random_access_iterator_tag, std::input_iterator_tag
|
||||||
|
>::value;
|
||||||
|
|
||||||
|
test = static_assert_min_cat<
|
||||||
|
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
|
||||||
|
>::value;
|
||||||
|
|
||||||
|
(void)test;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
category_test();
|
||||||
|
operator_arrow_test();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user