Squashed 'boost/' content from commit b4feb19f2

git-subtree-dir: boost
git-subtree-split: b4feb19f287ee92d87a9624b5d36b7cf46aeadeb
This commit is contained in:
Bill Somerville
2018-06-09 21:48:32 +01:00
commit 4ebe6417a5
12444 changed files with 2327021 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
# Copyright David Abrahams 2003. Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
test-suite iterator
:
# These first two tests will run last, and are expected to fail
# for many less-capable compilers.
[ compile-fail interoperable_fail.cpp ]
# test uses expected success, so that we catch unrelated
# compilation problems.
[ run is_convertible_fail.cpp ]
[ run zip_iterator_test.cpp
: : :
# stlport's debug mode generates long symbols which overwhelm
# vc6
#<msvc-stlport><*><runtime-build>release
]
[ run zip_iterator_test2_std_tuple.cpp ]
[ run zip_iterator_test2_fusion_vector.cpp ]
[ run zip_iterator_test2_fusion_list.cpp ]
# [ run zip_iterator_test2_fusion_deque.cpp ] // See bug report for fusion https://svn.boost.org/trac/boost/ticket/11572
[ run zip_iterator_test_fusion.cpp ]
[ run zip_iterator_test_std_tuple.cpp ]
[ run zip_iterator_test_std_pair.cpp ]
# These tests should work for just about everything.
[ compile is_lvalue_iterator.cpp ]
[ compile is_readable_iterator.cpp ]
[ compile pointee.cpp ]
[ run unit_tests.cpp ]
[ run concept_tests.cpp ]
[ run iterator_adaptor_cc.cpp ]
[ run iterator_adaptor_test.cpp ]
[ compile iterator_archetype_cc.cpp ]
[ compile-fail iter_archetype_default_ctor.cpp ]
[ compile-fail lvalue_concept_fail.cpp ]
[ run transform_iterator_test.cpp ]
[ run indirect_iterator_test.cpp ]
[ compile indirect_iter_member_types.cpp ]
[ run filter_iterator_test.cpp ]
[ run iterator_facade.cpp ]
[ run reverse_iterator_test.cpp ]
[ run counting_iterator_test.cpp ]
[ run interoperable.cpp ]
[ run iterator_traits_test.cpp ]
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
]
[ run function_input_iterator_test.cpp ]
[ run generator_iterator_test.cpp ]
[ run minimum_category.cpp ]
[ compile-fail minimum_category_compile_fail.cpp ]
;
+94
View File
@@ -0,0 +1,94 @@
// (C) Copyright Jeremy Siek 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/operators.hpp>
struct new_random_access
: std::random_access_iterator_tag
, boost::random_access_traversal_tag
{};
struct new_iterator
: public boost::iterator< new_random_access, 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; }
int
main()
{
boost::iterator_traversal<new_iterator>::type tc;
boost::random_access_traversal_tag derived = tc;
(void)derived;
boost::function_requires<
boost_concepts::WritableIteratorConcept<int*> >();
boost::function_requires<
boost_concepts::LvalueIteratorConcept<int*> >();
boost::function_requires<
boost_concepts::RandomAccessTraversalConcept<int*> >();
boost::function_requires<
boost_concepts::ReadableIteratorConcept<const int*> >();
boost::function_requires<
boost_concepts::LvalueIteratorConcept<const int*> >();
boost::function_requires<
boost_concepts::RandomAccessTraversalConcept<const int*> >();
boost::function_requires<
boost_concepts::WritableIteratorConcept<new_iterator> >();
boost::function_requires<
boost_concepts::LvalueIteratorConcept<new_iterator> >();
boost::function_requires<
boost_concepts::RandomAccessTraversalConcept<new_iterator> >();
boost::function_requires<
boost_concepts::WritableIteratorConcept<old_iterator> >();
boost::function_requires<
boost_concepts::LvalueIteratorConcept<old_iterator> >();
boost::function_requires<
boost_concepts::RandomAccessTraversalConcept<old_iterator> >();
boost::function_requires<
boost_concepts::InteroperableIteratorConcept<int*, int const*> >();
return 0;
}
@@ -0,0 +1,16 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/iterator_adaptor.hpp>
#include <utility>
struct my_iter : boost::iterator_adaptor<my_iter, std::pair<int,int> const*>
{
my_iter(std::pair<int,int> const*);
my_iter();
};
std::pair<int,int> const x(1,1);
my_iter p(&x);
int y = p->first; // operator-> attempts to return an non-const pointer
@@ -0,0 +1,20 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/iterator_adaptor.hpp>
#include <utility>
struct my_iter : boost::iterator_adaptor<my_iter, std::pair<int,int> const*>
{
my_iter(std::pair<int,int> const*);
my_iter();
};
std::pair<int,int> const x(1,1);
my_iter p(&x);
void test()
{
p->first = 3;
}
@@ -0,0 +1,300 @@
// (C) Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// 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 <boost/detail/lightweight_test.hpp>
#ifndef BOOST_NO_SLIST
# ifdef BOOST_SLIST_HEADER
# include BOOST_SLIST_HEADER
# else
# include <slist>
# endif
#endif
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
template <class T>
struct signed_assert_nonnegative
{
static void test(T x) { BOOST_TEST(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
BOOST_TEST(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
BOOST_TEST(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;
BOOST_TEST(boost::detail::distance(x, y) == 1);
// Show that values outside the range can't be found
BOOST_TEST(!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)
{
BOOST_TEST(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< ::boost::long_long_type>();
test_integer< ::boost::ulong_long_type>();
#endif
// Test user-defined type.
test_integer3<my_int1, std::forward_iterator_tag, int>();
test_integer3<long, std::random_access_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 boost::report_errors();
}
@@ -0,0 +1,73 @@
// Copyright (c) 2014 Kohei Takahashi.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for most recent version including documentation.
#include <boost/detail/lightweight_test.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/iterator/zip_iterator.hpp>
#include <vector>
#include <string>
int main()
{
typedef TUPLE<
std::vector<int>::iterator,
std::vector<std::string>::iterator
> iterator_tuple;
std::vector<int> vi = boost::assign::list_of(42)(72);
std::vector<std::string> vs = boost::assign::list_of("kokoro")("pyonpyon");
{
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
boost::zip_iterator<iterator_tuple> i2 = i1;
BOOST_TEST( i1 == i2);
BOOST_TEST( i1++ == i2);
BOOST_TEST( i1 == (i2 + 1));
BOOST_TEST((i1 - 1) == i2);
BOOST_TEST( i1-- == ++i2);
BOOST_TEST( i1 == --i2);
}
{
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
boost::zip_iterator<iterator_tuple> i2 = i1 + 1;
BOOST_TEST( i1 != i2);
BOOST_TEST( i1++ != i2);
BOOST_TEST( i1 != (i2 + 1));
BOOST_TEST((i1 - 1) != i2);
BOOST_TEST( i1-- != ++i2);
BOOST_TEST( i1 != --i2);
}
{
boost::zip_iterator<iterator_tuple> i(MAKE_TUPLE(vi.begin(), vs.begin()));
BOOST_TEST(boost::fusion::at_c<0>(* i ) == 42);
BOOST_TEST(boost::fusion::at_c<1>(* i ) == "kokoro");
BOOST_TEST(boost::fusion::at_c<0>(*(i + 1)) == 72);
BOOST_TEST(boost::fusion::at_c<1>(*(i + 1)) == "pyonpyon");
}
{
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
boost::zip_iterator<iterator_tuple> i2(MAKE_TUPLE(vi.end(), vs.end()));
BOOST_TEST((i2 - i1) == 2);
++i1;
BOOST_TEST((i2 - i1) == 1);
--i2;
BOOST_TEST((i2 - i1) == 0);
}
return boost::report_errors();
}
@@ -0,0 +1,857 @@
// (C) Copyright Dave Abrahams and Thomas Becker 2003. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// File:
// =====
// zip_iterator_test_main.cpp
// Author:
// =======
// Thomas Becker
// Created:
// ========
// Jul 15, 2003
// Purpose:
// ========
// Test driver for zip_iterator.hpp
// Compilers Tested:
// =================
// Metrowerks Codewarrior Pro 7.2, 8.3
// gcc 2.95.3
// gcc 3.2
// Microsoft VC 6sp5 (test fails due to some compiler bug)
// Microsoft VC 7 (works)
// Microsoft VC 7.1
// Intel 5
// Intel 6
// Intel 7.1
// Intel 8
// Borland 5.5.1 (broken due to lack of support from Boost.Tuples)
/////////////////////////////////////////////////////////////////////////////
//
// Includes
//
/////////////////////////////////////////////////////////////////////////////
#include <boost/iterator/zip_iterator.hpp>
#include <boost/iterator/zip_iterator.hpp> // 2nd #include tests #include guard.
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <string>
#include <functional>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/is_readable_iterator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/detail/workaround.hpp>
#include <stddef.h>
/// Tests for https://svn.boost.org/trac/boost/ticket/1517
int to_value(int const &v)
{
return v;
}
void category_test()
{
std::list<int> rng1;
std::string rng2;
boost::make_zip_iterator(
ZI_MAKE_TUPLE(
boost::make_transform_iterator(rng1.begin(), &to_value), // BidirectionalInput
rng2.begin() // RandomAccess
)
);
}
///
/////////////////////////////////////////////////////////////////////////////
//
// Das Main Funktion
//
/////////////////////////////////////////////////////////////////////////////
int main( void )
{
category_test();
std::cout << "\n"
<< "***********************************************\n"
<< "* *\n"
<< "* Test driver for boost::zip_iterator *\n"
<< "* Copyright Thomas Becker 2003 *\n"
<< "* *\n"
<< "***********************************************\n\n"
<< std::flush;
size_t num_successful_tests = 0;
size_t num_failed_tests = 0;
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator construction and dereferencing
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator construction and dereferencing: "
<< std::flush;
std::vector<double> vect1(3);
vect1[0] = 42.;
vect1[1] = 43.;
vect1[2] = 44.;
std::set<int> intset;
intset.insert(52);
intset.insert(53);
intset.insert(54);
//
typedef
boost::zip_iterator<
ZI_TUPLE<
std::set<int>::iterator
, std::vector<double>::iterator
>
> zit_mixed;
zit_mixed zip_it_mixed = zit_mixed(
ZI_MAKE_TUPLE(
intset.begin()
, vect1.begin()
)
);
ZI_TUPLE<int, double> val_tuple(
*zip_it_mixed);
ZI_TUPLE<const int&, double&> ref_tuple(
*zip_it_mixed);
double dblOldVal = ZI_TUPLE_GET(1)(ref_tuple);
ZI_TUPLE_GET(1)(ref_tuple) -= 41.;
if( 52 == ZI_TUPLE_GET(0)(val_tuple) &&
42. == ZI_TUPLE_GET(1)(val_tuple) &&
52 == ZI_TUPLE_GET(0)(ref_tuple) &&
1. == ZI_TUPLE_GET(1)(ref_tuple) &&
1. == *vect1.begin()
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
// Undo change to vect1
ZI_TUPLE_GET(1)(ref_tuple) = dblOldVal;
#if defined(ZI_USE_BOOST_TUPLE)
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator with 12 components
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterators with 12 components: "
<< std::flush;
// Declare 12 containers
//
std::list<int> li1;
li1.push_back(1);
std::set<int> se1;
se1.insert(2);
std::vector<int> ve1;
ve1.push_back(3);
//
std::list<int> li2;
li2.push_back(4);
std::set<int> se2;
se2.insert(5);
std::vector<int> ve2;
ve2.push_back(6);
//
std::list<int> li3;
li3.push_back(7);
std::set<int> se3;
se3.insert(8);
std::vector<int> ve3;
ve3.push_back(9);
//
std::list<int> li4;
li4.push_back(10);
std::set<int> se4;
se4.insert(11);
std::vector<int> ve4;
ve4.push_back(12);
// typedefs for cons lists of iterators.
typedef boost::tuples::cons<
std::set<int>::iterator,
ZI_TUPLE<
std::vector<int>::iterator,
std::list<int>::iterator,
std::set<int>::iterator,
std::vector<int>::iterator,
std::list<int>::iterator,
std::set<int>::iterator,
std::vector<int>::iterator,
std::list<int>::iterator,
std::set<int>::iterator,
std::vector<int>::const_iterator
>::inherited
> cons_11_its_type;
//
typedef boost::tuples::cons<
std::list<int>::const_iterator,
cons_11_its_type
> cons_12_its_type;
// typedefs for cons lists for dereferencing the zip iterator
// made from the cons list above.
typedef boost::tuples::cons<
const int&,
ZI_TUPLE<
int&,
int&,
const int&,
int&,
int&,
const int&,
int&,
int&,
const int&,
const int&
>::inherited
> cons_11_refs_type;
//
typedef boost::tuples::cons<
const int&,
cons_11_refs_type
> cons_12_refs_type;
// typedef for zip iterator with 12 elements
typedef boost::zip_iterator<cons_12_its_type> zip_it_12_type;
// Declare a 12-element zip iterator.
zip_it_12_type zip_it_12(
cons_12_its_type(
li1.begin(),
cons_11_its_type(
se1.begin(),
ZI_MAKE_TUPLE(
ve1.begin(),
li2.begin(),
se2.begin(),
ve2.begin(),
li3.begin(),
se3.begin(),
ve3.begin(),
li4.begin(),
se4.begin(),
ve4.begin()
)
)
)
);
// Dereference, mess with the result a little.
cons_12_refs_type zip_it_12_dereferenced(*zip_it_12);
ZI_TUPLE_GET(9)(zip_it_12_dereferenced) = 42;
// Make a copy and move it a little to force some instantiations.
zip_it_12_type zip_it_12_copy(zip_it_12);
++zip_it_12_copy;
if( ZI_TUPLE_GET(11)(zip_it_12.get_iterator_tuple()) == ve4.begin() &&
ZI_TUPLE_GET(11)(zip_it_12_copy.get_iterator_tuple()) == ve4.end() &&
1 == ZI_TUPLE_GET(0)(zip_it_12_dereferenced) &&
12 == ZI_TUPLE_GET(11)(zip_it_12_dereferenced) &&
42 == *(li4.begin())
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator incrementing and dereferencing
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator ++ and *: "
<< std::flush;
std::vector<double> vect2(3);
vect2[0] = 2.2;
vect2[1] = 3.3;
vect2[2] = 4.4;
boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_begin(
ZI_MAKE_TUPLE(
vect1.begin(),
vect2.begin()
)
);
boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_run(
ZI_MAKE_TUPLE(
vect1.begin(),
vect2.begin()
)
);
boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_end(
ZI_MAKE_TUPLE(
vect1.end(),
vect2.end()
)
);
if( zip_it_run == zip_it_begin &&
42. == ZI_TUPLE_GET(0)(*zip_it_run) &&
2.2 == ZI_TUPLE_GET(1)(*zip_it_run) &&
43. == ZI_TUPLE_GET(0)(*(++zip_it_run)) &&
3.3 == ZI_TUPLE_GET(1)(*zip_it_run) &&
44. == ZI_TUPLE_GET(0)(*(++zip_it_run)) &&
4.4 == ZI_TUPLE_GET(1)(*zip_it_run) &&
zip_it_end == ++zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator decrementing and dereferencing
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator -- and *: "
<< std::flush;
if( zip_it_run == zip_it_end &&
zip_it_end == zip_it_run-- &&
44. == ZI_TUPLE_GET(0)(*zip_it_run) &&
4.4 == ZI_TUPLE_GET(1)(*zip_it_run) &&
43. == ZI_TUPLE_GET(0)(*(--zip_it_run)) &&
3.3 == ZI_TUPLE_GET(1)(*zip_it_run) &&
42. == ZI_TUPLE_GET(0)(*(--zip_it_run)) &&
2.2 == ZI_TUPLE_GET(1)(*zip_it_run) &&
zip_it_begin == zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator copy construction and equality
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator copy construction and equality: "
<< std::flush;
boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
> zip_it_run_copy(zip_it_run);
if(zip_it_run == zip_it_run && zip_it_run == zip_it_run_copy)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator inequality
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator inequality: "
<< std::flush;
if(!(zip_it_run != zip_it_run_copy) && zip_it_run != ++zip_it_run_copy)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator less than
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator less than: "
<< std::flush;
// Note: zip_it_run_copy == zip_it_run + 1
//
if( zip_it_run < zip_it_run_copy &&
!( zip_it_run < --zip_it_run_copy) &&
zip_it_run == zip_it_run_copy
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator less than or equal
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "zip iterator less than or equal: "
<< std::flush;
// Note: zip_it_run_copy == zip_it_run
//
++zip_it_run;
zip_it_run_copy += 2;
if( zip_it_run <= zip_it_run_copy &&
zip_it_run <= --zip_it_run_copy &&
!( zip_it_run <= --zip_it_run_copy) &&
zip_it_run <= zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator greater than
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator greater than: "
<< std::flush;
// Note: zip_it_run_copy == zip_it_run - 1
//
if( zip_it_run > zip_it_run_copy &&
!( zip_it_run > ++zip_it_run_copy) &&
zip_it_run == zip_it_run_copy
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator greater than or equal
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator greater than or equal: "
<< std::flush;
++zip_it_run;
// Note: zip_it_run == zip_it_run_copy + 1
//
if( zip_it_run >= zip_it_run_copy &&
--zip_it_run >= zip_it_run_copy &&
! (zip_it_run >= ++zip_it_run_copy)
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator + int
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator + int: "
<< std::flush;
// Note: zip_it_run == zip_it_run_copy - 1
//
zip_it_run = zip_it_run + 2;
++zip_it_run_copy;
if( zip_it_run == zip_it_run_copy && zip_it_run == zip_it_begin + 3 )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator - int
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator - int: "
<< std::flush;
// Note: zip_it_run == zip_it_run_copy, and both are at end position
//
zip_it_run = zip_it_run - 2;
--zip_it_run_copy;
--zip_it_run_copy;
if( zip_it_run == zip_it_run_copy && (zip_it_run - 1) == zip_it_begin )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator +=
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator +=: "
<< std::flush;
// Note: zip_it_run == zip_it_run_copy, and both are at begin + 1
//
zip_it_run += 2;
if( zip_it_run == zip_it_begin + 3 )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator -=
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator -=: "
<< std::flush;
// Note: zip_it_run is at end position, zip_it_run_copy is at
// begin plus one.
//
zip_it_run -= 2;
if( zip_it_run == zip_it_run_copy )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator getting member iterators
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator member iterators: "
<< std::flush;
// Note: zip_it_run and zip_it_run_copy are both at
// begin plus one.
//
if( ZI_TUPLE_GET(0)(zip_it_run.get_iterator_tuple()) == vect1.begin() + 1 &&
ZI_TUPLE_GET(1)(zip_it_run.get_iterator_tuple()) == vect2.begin() + 1
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Making zip iterators
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Making zip iterators: "
<< std::flush;
std::vector<ZI_TUPLE<double, double> >
vect_of_tuples(3);
std::copy(
boost::make_zip_iterator(
ZI_MAKE_TUPLE(
vect1.begin(),
vect2.begin()
)
),
boost::make_zip_iterator(
ZI_MAKE_TUPLE(
vect1.end(),
vect2.end()
)
),
vect_of_tuples.begin()
);
if( 42. == ZI_TUPLE_GET(0)(*vect_of_tuples.begin()) &&
2.2 == ZI_TUPLE_GET(1)(*vect_of_tuples.begin()) &&
43. == ZI_TUPLE_GET(0)(*(vect_of_tuples.begin() + 1)) &&
3.3 == ZI_TUPLE_GET(1)(*(vect_of_tuples.begin() + 1)) &&
44. == ZI_TUPLE_GET(0)(*(vect_of_tuples.begin() + 2)) &&
4.4 == ZI_TUPLE_GET(1)(*(vect_of_tuples.begin() + 2))
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator non-const --> const conversion
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator non-const to const conversion: "
<< std::flush;
boost::zip_iterator<
ZI_TUPLE<
std::set<int>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_const(
ZI_MAKE_TUPLE(
intset.begin(),
vect2.begin()
)
);
//
boost::zip_iterator<
ZI_TUPLE<
std::set<int>::iterator,
std::vector<double>::const_iterator
>
>
zip_it_half_const(
ZI_MAKE_TUPLE(
intset.begin(),
vect2.begin()
)
);
//
boost::zip_iterator<
ZI_TUPLE<
std::set<int>::iterator,
std::vector<double>::iterator
>
>
zip_it_non_const(
ZI_MAKE_TUPLE(
intset.begin(),
vect2.begin()
)
);
zip_it_half_const = ++zip_it_non_const;
zip_it_const = zip_it_half_const;
++zip_it_const;
// zip_it_non_const = ++zip_it_const; // Error: can't convert from const to non-const
if( 54 == ZI_TUPLE_GET(0)(*zip_it_const) &&
4.4 == ZI_TUPLE_GET(1)(*zip_it_const) &&
53 == ZI_TUPLE_GET(0)(*zip_it_half_const) &&
3.3 == ZI_TUPLE_GET(1)(*zip_it_half_const)
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
#if defined(ZI_USE_BOOST_TUPLE)
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator categories
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator categories: "
<< std::flush;
// The big iterator of the previous test has vector, list, and set iterators.
// Therefore, it must be bidirectional, but not random access.
bool bBigItIsBidirectionalIterator = boost::is_convertible<
boost::iterator_traversal<zip_it_12_type>::type
, boost::bidirectional_traversal_tag
>::value;
bool bBigItIsRandomAccessIterator = boost::is_convertible<
boost::iterator_traversal<zip_it_12_type>::type
, boost::random_access_traversal_tag
>::value;
// A combining iterator with all vector iterators must have random access
// traversal.
//
typedef boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
> all_vects_type;
bool bAllVectsIsRandomAccessIterator = boost::is_convertible<
boost::iterator_traversal<all_vects_type>::type
, boost::random_access_traversal_tag
>::value;
// The big test.
if( bBigItIsBidirectionalIterator &&
! bBigItIsRandomAccessIterator &&
bAllVectsIsRandomAccessIterator
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
#endif
// Done
//
std::cout << "\nTest Result:"
<< "\n============"
<< "\nNumber of successful tests: " << static_cast<unsigned int>(num_successful_tests)
<< "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests)
<< std::endl;
return num_failed_tests;
}
+272
View File
@@ -0,0 +1,272 @@
// Copyright David Abrahams 2003, Jeremy Siek 2004.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/filter_iterator.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/concept_check.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/iterator_archetypes.hpp>
#include <boost/cstdlib.hpp>
#include <deque>
#include <iostream>
using boost::dummyT;
struct one_or_four
{
bool operator()(dummyT x) const
{
return x.foo() == 1 || x.foo() == 4;
}
};
template <class T> struct undefined;
template <class T> struct see_type;
// Test filter iterator
int main()
{
// Concept checks
// Adapting old-style iterators
{
typedef boost::filter_iterator<one_or_four, boost::input_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::input_output_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::forward_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::mutable_forward_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::bidirectional_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::random_access_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::mutable_random_access_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
// Adapting new-style iterators
{
typedef boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::single_pass_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::single_pass_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
#endif
{
typedef boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_lvalue_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
#endif
{
typedef boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_lvalue_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
#endif
// Run-time tests
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
dummyT(3), dummyT(4), dummyT(5) };
const int N = sizeof(array)/sizeof(dummyT);
typedef boost::filter_iterator<one_or_four, dummyT*> filter_iter;
boost::bidirectional_readable_iterator_test(
filter_iter(one_or_four(), array, array+N)
, dummyT(1), dummyT(4));
BOOST_STATIC_ASSERT(
(!boost::is_convertible<
boost::iterator_traversal<filter_iter>::type
, boost::random_access_traversal_tag
>::value
));
//# endif
// On compilers not supporting partial specialization, we can do more type
// deduction with deque iterators than with pointers... unless the library
// is broken ;-(
std::deque<dummyT> array2;
std::copy(array+0, array+N, std::back_inserter(array2));
boost::bidirectional_readable_iterator_test(
boost::make_filter_iterator(one_or_four(), array2.begin(), array2.end()),
dummyT(1), dummyT(4));
boost::bidirectional_readable_iterator_test(
boost::make_filter_iterator(one_or_four(), array2.begin(), array2.end()),
dummyT(1), dummyT(4));
boost::bidirectional_readable_iterator_test(
boost::make_filter_iterator(
one_or_four()
, boost::make_reverse_iterator(array2.end())
, boost::make_reverse_iterator(array2.begin())
),
dummyT(4), dummyT(1));
boost::bidirectional_readable_iterator_test(
filter_iter(array+0, array+N),
dummyT(1), dummyT(4));
boost::bidirectional_readable_iterator_test(
filter_iter(one_or_four(), array, array + N),
dummyT(1), dummyT(4));
return boost::report_errors();
}
@@ -0,0 +1,101 @@
// Copyright 2010 (c) Dean Michael Berris
// Distributed under the Boost Software License Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <cassert>
#include <cstddef>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <boost/iterator/function_input_iterator.hpp>
namespace {
struct ones {
typedef int result_type;
result_type operator() () {
return 1;
}
};
int ones_function () {
return 1;
}
struct counter {
typedef int result_type;
int n;
explicit counter(int n_) : n(n_) { }
result_type operator() () {
return n++;
}
};
} // namespace
using namespace std;
int main(int argc, char * argv[])
{
// test the iterator with function objects
ones ones_generator;
vector<int> values(10);
generate(values.begin(), values.end(), ones());
vector<int> generated;
copy(
boost::make_function_input_iterator(ones_generator, 0),
boost::make_function_input_iterator(ones_generator, 10),
back_inserter(generated)
);
assert(values.size() == generated.size());
assert(equal(values.begin(), values.end(), generated.begin()));
cout << "function iterator test with function objects successful." << endl;
// test the iterator with normal functions
vector<int>().swap(generated);
copy(
boost::make_function_input_iterator(&ones_function, 0),
boost::make_function_input_iterator(&ones_function, 10),
back_inserter(generated)
);
assert(values.size() == generated.size());
assert(equal(values.begin(), values.end(), generated.begin()));
cout << "function iterator test with pointer to function successful." << endl;
// test the iterator with a reference to a function
vector<int>().swap(generated);
copy(
boost::make_function_input_iterator(ones_function, 0),
boost::make_function_input_iterator(ones_function, 10),
back_inserter(generated)
);
assert(values.size() == generated.size());
assert(equal(values.begin(), values.end(), generated.begin()));
cout << "function iterator test with reference to function successful." << endl;
// test the iterator with a stateful function object
counter counter_generator(42);
vector<int>().swap(generated);
copy(
boost::make_function_input_iterator(counter_generator, 0),
boost::make_function_input_iterator(counter_generator, 10),
back_inserter(generated)
);
assert(generated.size() == 10);
assert(counter_generator.n == 42 + 10);
for(std::size_t i = 0; i != 10; ++i)
assert(generated[i] == 42 + i);
cout << "function iterator test with stateful function object successful." << endl;
return 0;
}
@@ -0,0 +1,63 @@
//
// Copyright 2014 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/generator_iterator.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <algorithm>
class X
{
private:
int v;
public:
typedef int result_type;
X(): v( 0 )
{
}
int operator()()
{
return ++v;
}
};
template<class InputIterator, class Size, class OutputIterator> OutputIterator copy_n( InputIterator first, Size n, OutputIterator result )
{
while( n-- > 0 )
{
*result++ = *first++;
}
return result;
}
void copy_test()
{
X x;
boost::generator_iterator<X> in( &x );
int const N = 4;
int v[ N ] = { 0 };
::copy_n( in, 4, v );
BOOST_TEST_EQ( v[0], 1 );
BOOST_TEST_EQ( v[1], 2 );
BOOST_TEST_EQ( v[2], 3 );
BOOST_TEST_EQ( v[3], 4 );
}
int main()
{
copy_test();
return boost::report_errors();
}
@@ -0,0 +1,87 @@
// (C) Copyright Jeremy Siek 2004.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Revision History
// 03 Jan 2004 Jeremy Siek
// First draft.
#include <boost/config.hpp>
#include <iostream>
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/static_assert.hpp>
#include "static_assert_same.hpp"
#include <boost/type_traits/same_traits.hpp>
struct zow { };
struct my_ptr {
typedef zow const element_type;
zow const& operator*() const;
// typedef const zow& reference;
// typedef const zow* pointer;
// typedef void difference_type;
// typedef boost::no_traversal_tag iterator_category;
};
// Borland 5.6.4 and earlier drop const all over the place, so this
// test will fail in the lines marked with (**)
int main()
{
{
typedef boost::indirect_iterator<int**> Iter;
STATIC_ASSERT_SAME(Iter::value_type, int);
STATIC_ASSERT_SAME(Iter::reference, int&);
STATIC_ASSERT_SAME(Iter::pointer, int*);
STATIC_ASSERT_SAME(Iter::difference_type, std::ptrdiff_t);
BOOST_STATIC_ASSERT((boost::is_convertible<Iter::iterator_category,
std::random_access_iterator_tag>::value));
BOOST_STATIC_ASSERT((boost::is_convertible<boost::iterator_traversal<Iter>::type,
boost::random_access_traversal_tag>::value));
}
{
typedef boost::indirect_iterator<int const**> Iter;
STATIC_ASSERT_SAME(Iter::value_type, int);
STATIC_ASSERT_SAME(Iter::reference, const int&);
STATIC_ASSERT_SAME(Iter::pointer, const int*); // (**)
}
{
typedef boost::indirect_iterator<int**, int> Iter;
STATIC_ASSERT_SAME(Iter::value_type, int);
STATIC_ASSERT_SAME(Iter::reference, int&);
STATIC_ASSERT_SAME(Iter::pointer, int*);
}
{
typedef boost::indirect_iterator<int**, const int> Iter;
STATIC_ASSERT_SAME(Iter::value_type, int);
STATIC_ASSERT_SAME(Iter::reference, const int&);
STATIC_ASSERT_SAME(Iter::pointer, const int*); // (**)
}
{
typedef boost::indirect_iterator<my_ptr*> Iter;
STATIC_ASSERT_SAME(Iter::value_type, zow);
STATIC_ASSERT_SAME(Iter::reference, const zow&); // (**)
STATIC_ASSERT_SAME(Iter::pointer, const zow*); // (**)
STATIC_ASSERT_SAME(Iter::difference_type, std::ptrdiff_t);
BOOST_STATIC_ASSERT((boost::is_convertible<Iter::iterator_category,
std::random_access_iterator_tag>::value));
BOOST_STATIC_ASSERT((boost::is_convertible<boost::iterator_traversal<Iter>::type,
boost::random_access_traversal_tag>::value));
}
{
typedef boost::indirect_iterator<char**, int, std::random_access_iterator_tag, long&, short> Iter;
STATIC_ASSERT_SAME(Iter::value_type, int);
STATIC_ASSERT_SAME(Iter::reference, long&);
STATIC_ASSERT_SAME(Iter::pointer, int*);
STATIC_ASSERT_SAME(Iter::difference_type, short);
}
return 0;
}
@@ -0,0 +1,218 @@
// (C) Copyright Jeremy Siek 1999.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// 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 <boost/mpl/has_xxx.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <vector>
#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_SET_ITERATOR_INTEROPERABILITY
#endif
template <class T> struct see_type;
template <int I> struct see_val;
struct my_iterator_tag : public std::random_access_iterator_tag { };
using boost::dummyT;
typedef std::vector<int> storage;
typedef std::vector<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;
};
void more_indirect_iterator_tests()
{
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());
BOOST_TEST(static_cast<std::size_t>(de - db) == store.size());
BOOST_TEST(db + store.size() == de);
indirect_ra_container::const_iterator dci = db;
BOOST_TEST(dci == db);
#ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
BOOST_TEST(db == dci);
#endif
BOOST_TEST(dci != de);
BOOST_TEST(dci < de);
BOOST_TEST(dci <= de);
#ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
BOOST_TEST(de >= dci);
BOOST_TEST(de > dci);
#endif
dci = de;
BOOST_TEST(dci == de);
boost::random_access_iterator_test(db + 1, store.size() - 1, boost::next(store.begin()));
*db = 999;
BOOST_TEST(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());
BOOST_TEST(sci == sb);
# ifndef NO_MUTABLE_CONST_STD_SET_ITERATOR_INTEROPERABILITY
BOOST_TEST(se != sci);
# endif
BOOST_TEST(sci != se);
sci = se;
BOOST_TEST(sci == se);
*boost::prior(se) = 888;
BOOST_TEST(store.back() == 888);
BOOST_TEST(std::equal(sb, se, store.begin()));
boost::bidirectional_iterator_test(boost::next(sb), store[1], store[2]);
BOOST_TEST(std::equal(db, de, store.begin()));
}
// element_type detector; defaults to true so the test passes when
// has_xxx isn't implemented
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_element_type, element_type, true)
int
main()
{
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
dummyT(3), dummyT(4), dummyT(5) };
const int N = sizeof(array)/sizeof(dummyT);
# if BOOST_WORKAROUND(BOOST_MSVC, == 1200)
boost::shared_ptr<dummyT> zz((dummyT*)0); // Why? I don't know, but it suppresses a bad instantiation.
# endif
typedef std::vector<boost::shared_ptr<dummyT> > shared_t;
shared_t shared;
// Concept checks
{
typedef boost::indirect_iterator<shared_t::iterator> iter_t;
BOOST_STATIC_ASSERT(
has_element_type<
boost::detail::iterator_traits<shared_t::iterator>::value_type
>::value
);
typedef boost::indirect_iterator<
shared_t::iterator
, boost::iterator_value<shared_t::iterator>::type const
> c_iter_t;
# ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY
boost::function_requires< boost_concepts::InteroperableIteratorConcept<iter_t, c_iter_t> >();
# endif
}
// Test indirect_iterator_generator
{
for (int jj = 0; jj < N; ++jj)
shared.push_back(boost::shared_ptr<dummyT>(new dummyT(jj)));
dummyT* ptr[N];
for (int k = 0; k < N; ++k)
ptr[k] = array + k;
typedef boost::indirect_iterator<dummyT**> indirect_iterator;
typedef boost::indirect_iterator<dummyT**, dummyT const>
const_indirect_iterator;
indirect_iterator i(ptr);
boost::random_access_iterator_test(i, N, array);
boost::random_access_iterator_test(
boost::indirect_iterator<shared_t::iterator>(shared.begin())
, N, array);
boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array);
// check operator->
assert((*i).m_x == i->foo());
const_indirect_iterator j(ptr);
boost::random_access_iterator_test(j, N, array);
dummyT const*const* const_ptr = ptr;
boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
boost::const_nonconst_iterator_test(i, ++j);
more_indirect_iterator_tests();
}
return boost::report_errors();
}
+60
View File
@@ -0,0 +1,60 @@
// Copyright David Abrahams 2004. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/pending/iterator_tests.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <cassert>
struct mutable_it : boost::iterator_adaptor<mutable_it,int*>
{
typedef boost::iterator_adaptor<mutable_it,int*> super_t;
mutable_it();
explicit mutable_it(int* p) : super_t(p) {}
bool equal(mutable_it const& rhs) const
{
return this->base() == rhs.base();
}
};
struct constant_it : boost::iterator_adaptor<constant_it,int const*>
{
typedef boost::iterator_adaptor<constant_it,int const*> super_t;
constant_it();
explicit constant_it(int* p) : super_t(p) {}
constant_it(mutable_it const& x) : super_t(x.base()) {}
bool equal(constant_it const& rhs) const
{
return this->base() == rhs.base();
}
};
int main()
{
int data[] = { 49, 77 };
mutable_it i(data);
constant_it j(data + 1);
BOOST_TEST(i < j);
BOOST_TEST(j > i);
BOOST_TEST(i <= j);
BOOST_TEST(j >= i);
BOOST_TEST(j - i == 1);
BOOST_TEST(i - j == -1);
constant_it k = i;
BOOST_TEST(!(i < k));
BOOST_TEST(!(k > i));
BOOST_TEST(i <= k);
BOOST_TEST(k >= i);
BOOST_TEST(k - i == 0);
BOOST_TEST(i - k == 0);
return boost::report_errors();
}
+21
View File
@@ -0,0 +1,21 @@
// Copyright Thomas Witt 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#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;
}
@@ -0,0 +1,19 @@
//
// Copyright (c) Thomas Witt 2002.
//
// Use, modification and distribution is subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#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;
}
+141
View File
@@ -0,0 +1,141 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <deque>
#include <iterator>
#include <iostream>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/iterator/is_lvalue_iterator.hpp>
#include <boost/iterator.hpp>
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
#include <boost/iterator/detail/config_def.hpp>
struct v
{
v();
~v();
};
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
{
v operator*() const;
};
struct noncopyable_iterator : boost::iterator<std::forward_iterator_tag,boost::noncopyable>
{
boost::noncopyable const& operator*() const;
};
template <class T>
struct proxy_iterator
: boost::iterator<std::output_iterator_tag,T>
{
typedef T value_type;
#if BOOST_WORKAROUND(__GNUC__, == 2)
typedef boost::iterator<std::input_iterator_tag,value_type> base;
typedef base::iterator_category iterator_category;
typedef base::difference_type difference_type;
typedef base::pointer pointer;
typedef base::reference reference;
#endif
struct proxy
{
operator value_type&() const;
proxy& operator=(value_type) const;
};
proxy operator*() const;
};
template <class T>
struct lvalue_iterator
{
typedef T value_type;
typedef T& reference;
typedef T difference_type;
typedef std::input_iterator_tag iterator_category;
typedef T* pointer;
T& operator*() const;
lvalue_iterator& operator++();
lvalue_iterator operator++(int);
};
template <class T>
struct constant_lvalue_iterator
{
typedef T value_type;
typedef T const& reference;
typedef T difference_type;
typedef std::input_iterator_tag iterator_category;
typedef T const* pointer;
T const& operator*() const;
constant_lvalue_iterator& operator++();
constant_lvalue_iterator operator++(int);
};
int main()
{
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v*>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<int> >::value);
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<value_iterator>::value);
#endif
// Make sure inaccessible copy constructor doesn't prevent
// reference binding
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<float> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<float> >::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<v*>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<int> >::value);
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<value_iterator>::value);
#endif
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<v> >::value);
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<int> >::value);
#endif
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<float> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float> >::value);
return 0;
}
@@ -0,0 +1,90 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <deque>
#include <iterator>
#include <iostream>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/iterator/is_readable_iterator.hpp>
#include <boost/iterator.hpp>
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
#include <boost/iterator/detail/config_def.hpp>
struct v
{
v();
~v();
};
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
{
v operator*() const;
};
struct noncopyable_iterator : boost::iterator<std::forward_iterator_tag,boost::noncopyable>
{
boost::noncopyable const& operator*() const;
};
struct proxy_iterator : boost::iterator<std::output_iterator_tag,v>
{
#if BOOST_WORKAROUND(__GNUC__, == 2)
typedef boost::iterator<std::input_iterator_tag,v> base;
typedef base::iterator_category iterator_category;
typedef base::value_type value_type;
typedef base::difference_type difference_type;
typedef base::pointer pointer;
typedef base::reference reference;
#endif
struct proxy
{
operator v&();
proxy& operator=(v) const;
};
proxy operator*() const;
};
struct proxy_iterator2 : boost::iterator<std::output_iterator_tag,v>
{
#if BOOST_WORKAROUND(__GNUC__, == 2)
typedef boost::iterator<std::input_iterator_tag,v> base;
typedef base::iterator_category iterator_category;
typedef base::value_type value_type;
typedef base::difference_type difference_type;
typedef base::pointer pointer;
typedef base::reference reference;
#endif
struct proxy
{
proxy& operator=(v) const;
};
proxy operator*() const;
};
int main()
{
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v*>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<proxy_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<proxy_iterator2>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<value_iterator>::value);
// Make sure inaccessible copy constructor doesn't prevent
// readability
BOOST_STATIC_ASSERT(boost::is_readable_iterator<noncopyable_iterator>::value);
return 0;
}
@@ -0,0 +1,21 @@
//
// Copyright Thomas Witt 2004.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/iterator/iterator_archetypes.hpp>
int main()
{
typedef boost::iterator_archetype<
int
, boost::iterator_archetypes::readable_iterator_t
, boost::single_pass_traversal_tag
> iter;
// single_pass_traversal iterators are not required to be
// default constructible
iter it;
}
@@ -0,0 +1,46 @@
// Copyright (C) 2004 Jeremy Siek <jsiek@cs.indiana.edu>
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/concept_check.hpp>
#include <boost/cstdlib.hpp>
#include <list>
int main()
{
{
typedef boost::reverse_iterator<int*> rev_iter;
typedef boost::reverse_iterator<int const*> c_rev_iter;
boost::function_requires< boost_concepts::WritableIteratorConcept<rev_iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<rev_iter> >();
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<rev_iter> >();
boost::function_requires< boost::RandomAccessIteratorConcept<rev_iter> >();
boost::function_requires< boost_concepts::InteroperableIteratorConcept<rev_iter, c_rev_iter> >();
}
// Many compilers' builtin container iterators don't interoperate well, though
// STLport fixes that problem.
#if defined(__SGI_STL_PORT) \
|| !BOOST_WORKAROUND(__GNUC__, <= 2) \
&& !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, <= 1)) \
&& !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) \
&& !BOOST_WORKAROUND(__LIBCOMO_VERSION__, BOOST_TESTED_AT(29)) \
&& !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 1)
{
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::ReadableIteratorConcept<c_rev_iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<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::InteroperableIteratorConcept<rev_iter, c_rev_iter> >();
}
#endif
return boost::exit_success;
}
@@ -0,0 +1,335 @@
// (C) Copyright Thomas Witt 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// 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>
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
# include <boost/iterator/is_readable_iterator.hpp>
# include <boost/iterator/is_lvalue_iterator.hpp>
#endif
#include <boost/pending/iterator_tests.hpp>
# include <boost/detail/lightweight_test.hpp>
#include <stdlib.h>
#include <vector>
#include <deque>
#include <set>
#include <list>
#include "static_assert_same.hpp"
#include <boost/iterator/detail/config_def.hpp>
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
, boost::random_access_traversal_tag
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
, V&
#endif
>
{
private:
typedef boost::iterator_adaptor<
ptr_iterator<V>
, V*
, V
, boost::random_access_traversal_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())
{}
};
// Non-functional iterator for category modification checking
template <class Iter, class Traversal>
struct modify_traversal
: boost::iterator_adaptor<
modify_traversal<Iter, Traversal>
, Iter
, boost::use_default
, Traversal
>
{};
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_no_proxy<T>
>
{
private:
typedef boost::iterator_adaptor<
in_iterator<T>
, boost::input_iterator_archetype_no_proxy<T>
> super_t;
public:
in_iterator() { }
in_iterator(boost::input_iterator_archetype_no_proxy<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) {}
};
char (& traversal2(boost::incrementable_traversal_tag) )[1];
char (& traversal2(boost::single_pass_traversal_tag ) )[2];
char (& traversal2(boost::forward_traversal_tag ) )[3];
char (& traversal2(boost::bidirectional_traversal_tag) )[4];
char (& traversal2(boost::random_access_traversal_tag) )[5];
template <class Cat>
struct traversal3
{
static typename boost::iterator_category_to_traversal<Cat>::type x;
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(traversal2(x)));
typedef char (&type)[value];
};
template <class Cat>
typename traversal3<Cat>::type traversal(Cat);
template <class Iter, class Trav>
int static_assert_traversal(Iter* = 0, Trav* = 0)
{
typedef typename boost::iterator_category_to_traversal<
BOOST_DEDUCED_TYPENAME Iter::iterator_category
>::type t2;
return static_assert_same<Trav,t2>::value;
}
int
main()
{
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
dummyT(3), dummyT(4), dummyT(5) };
const int N = sizeof(array)/sizeof(dummyT);
// sanity check, if this doesn't pass the test is buggy
boost::random_access_iterator_test(array, N, array);
// Test the iterator_adaptor
{
ptr_iterator<dummyT> i(array);
boost::random_access_iterator_test(i, N, array);
ptr_iterator<const dummyT> j(array);
boost::random_access_iterator_test(j, N, array);
boost::const_nonconst_iterator_test(i, ++j);
}
int test;
// Test the iterator_traits
{
// Test computation of defaults
typedef ptr_iterator<int> Iter1;
// don't use std::iterator_traits here to avoid VC++ problems
test = static_assert_same<Iter1::value_type, int>::value;
test = static_assert_same<Iter1::reference, int&>::value;
test = static_assert_same<Iter1::pointer, int*>::value;
test = static_assert_same<Iter1::difference_type, std::ptrdiff_t>::value;
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value));
#endif
}
{
// Test computation of default when the Value is const
typedef ptr_iterator<int const> Iter1;
test = static_assert_same<Iter1::value_type, int>::value;
test = static_assert_same<Iter1::reference, const int&>::value;
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
# endif
#endif
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
test = static_assert_same<Iter1::pointer, int const*>::value;
#endif
}
{
// Test constant iterator idiom
typedef ptr_iterator<int> BaseIter;
typedef constant_iterator<BaseIter> Iter;
test = static_assert_same<Iter::value_type, int>::value;
test = static_assert_same<Iter::reference, int const&>::value;
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // borland drops constness
test = static_assert_same<Iter::pointer, int const*>::value;
#endif
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
#endif
typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
static_assert_traversal<BaseIter,boost::random_access_traversal_tag>();
static_assert_traversal<IncrementableIter,boost::incrementable_traversal_tag>();
}
// Test the iterator_adaptor
{
ptr_iterator<dummyT> i(array);
boost::random_access_iterator_test(i, N, array);
ptr_iterator<const dummyT> j(array);
boost::random_access_iterator_test(j, N, array);
boost::const_nonconst_iterator_test(i, ++j);
}
// check operator-> with a forward iterator
{
boost::forward_iterator_archetype<dummyT> forward_iter;
typedef fwd_iterator<dummyT> adaptor_type;
adaptor_type i(forward_iter);
int zero = 0;
if (zero) // don't do this, just make sure it compiles
BOOST_TEST((*i).m_x == i->foo());
}
// check operator-> with an input iterator
{
boost::input_iterator_archetype_no_proxy<dummyT> input_iter;
typedef in_iterator<dummyT> adaptor_type;
adaptor_type i(input_iter);
int zero = 0;
if (zero) // don't do this, just make sure it compiles
BOOST_TEST((*i).m_x == i->foo());
}
// check that base_type is correct
{
// Test constant iterator idiom
typedef ptr_iterator<int> BaseIter;
test = static_assert_same<BaseIter::base_type,int*>::value;
test = static_assert_same<constant_iterator<BaseIter>::base_type,BaseIter>::value;
typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;
test = static_assert_same<IncrementableIter::base_type,BaseIter>::value;
}
std::cout << "test successful " << std::endl;
(void)test;
return boost::report_errors();
}
@@ -0,0 +1,61 @@
//
// Copyright Thomas Witt 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/iterator/iterator_archetypes.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/concept_check.hpp>
#include <boost/cstdlib.hpp>
int main()
{
{
typedef boost::iterator_archetype<
int
, boost::iterator_archetypes::readable_iterator_t
, boost::random_access_traversal_tag
> iter;
boost::function_requires< boost_concepts::ReadableIteratorConcept<iter> >();
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
}
{
typedef boost::iterator_archetype<
int
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::random_access_traversal_tag
> iter;
boost::function_requires< boost_concepts::ReadableIteratorConcept<iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<iter> >();
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
}
{
typedef boost::iterator_archetype<
const int // I don't like adding const to Value. It is redundant. -JGS
, boost::iterator_archetypes::readable_lvalue_iterator_t
, boost::random_access_traversal_tag
> iter;
boost::function_requires< boost_concepts::ReadableIteratorConcept<iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<iter> >();
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
}
{
typedef boost::iterator_archetype<
int
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::random_access_traversal_tag
> iter;
boost::function_requires< boost_concepts::WritableIteratorConcept<iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<iter> >();
boost::function_requires< boost_concepts::RandomAccessTraversalConcept<iter> >();
}
return boost::exit_success;
}
+227
View File
@@ -0,0 +1,227 @@
// Copyright David Abrahams 2004. Distributed under the Boost
// Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This is really an incomplete test; should be fleshed out.
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/call_traits.hpp>
#include <boost/polymorphic_cast.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
// This is a really, really limited test so far. All we're doing
// right now is checking that the postfix++ proxy for single-pass
// iterators works properly.
template <class Ref>
class counter_iterator
: public boost::iterator_facade<
counter_iterator<Ref>
, int const
, boost::single_pass_traversal_tag
, Ref
>
{
public:
counter_iterator() {}
counter_iterator(int* state) : state(state) {}
void increment()
{
++*state;
}
Ref
dereference() const
{
return *state;
}
bool equal(counter_iterator const& y) const
{
return *this->state == *y.state;
}
int* state;
};
struct proxy
{
proxy(int& x) : state(x) {}
operator int const&() const
{
return state;
}
int& operator=(int x) { state = x; return state; }
int& state;
};
struct value
{
void mutator() {} // non-const member function
};
struct input_iter
: boost::iterator_facade<
input_iter
, value
, boost::single_pass_traversal_tag
, value
>
{
public:
input_iter() {}
void increment()
{
}
value
dereference() const
{
return value();
}
bool equal(input_iter const& y) const
{
return false;
}
};
template <class T>
struct wrapper
{
T m_x;
explicit wrapper(typename boost::call_traits<T>::param_type x)
: m_x(x)
{ }
template <class U>
wrapper(const wrapper<U>& other,
typename boost::enable_if< boost::is_convertible<U,T> >::type* = 0)
: m_x(other.m_x)
{ }
};
struct iterator_with_proxy_reference
: boost::iterator_facade<
iterator_with_proxy_reference
, wrapper<int>
, boost::incrementable_traversal_tag
, wrapper<int&>
>
{
int& m_x;
explicit iterator_with_proxy_reference(int& x)
: m_x(x)
{ }
void increment()
{ }
wrapper<int&> dereference() const
{ return wrapper<int&>(m_x); }
};
template <class T, class U>
void same_type(U const&)
{ BOOST_MPL_ASSERT((boost::is_same<T,U>)); }
template <class I, class A>
struct abstract_iterator
: boost::iterator_facade<
abstract_iterator<I, A>
, A &
// In order to be value type as a reference, traversal category has
// to satisfy least forward traversal.
, boost::forward_traversal_tag
, A &
>
{
abstract_iterator(I iter) : iter(iter) {}
void increment()
{ ++iter; }
A & dereference() const
{ return *iter; }
bool equal(abstract_iterator const& y) const
{ return iter == y.iter; }
I iter;
};
struct base
{
virtual void assign(const base &) = 0;
virtual bool equal(const base &) const = 0;
};
struct derived : base
{
derived(int state) : state(state) { }
derived(const derived &d) : state(d.state) { }
derived(const base &b) { derived::assign(b); }
virtual void assign(const base &b)
{
state = boost::polymorphic_cast<const derived *>(&b)->state;
}
virtual bool equal(const base &b) const
{
return state == boost::polymorphic_cast<const derived *>(&b)->state;
}
int state;
};
inline bool operator==(const base &lhs, const base &rhs)
{
return lhs.equal(rhs);
}
int main()
{
{
int state = 0;
boost::readable_iterator_test(counter_iterator<int const&>(&state), 0);
state = 3;
boost::readable_iterator_test(counter_iterator<proxy>(&state), 3);
boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7);
BOOST_TEST(state == 8);
}
{
// test for a fix to http://tinyurl.com/zuohe
// These two lines should be equivalent (and both compile)
input_iter p;
(*p).mutator();
p->mutator();
same_type<input_iter::pointer>(p.operator->());
}
{
int x = 0;
iterator_with_proxy_reference i(x);
BOOST_TEST(x == 0);
BOOST_TEST(i.m_x == 0);
++(*i).m_x;
BOOST_TEST(x == 1);
BOOST_TEST(i.m_x == 1);
++i->m_x;
BOOST_TEST(x == 2);
BOOST_TEST(i.m_x == 2);
}
{
derived d(1);
boost::readable_iterator_test(abstract_iterator<derived *, base>(&d), derived(1));
}
return boost::report_errors();
}
+218
View File
@@ -0,0 +1,218 @@
// (C) Copyright David Abrahams 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 04 Mar 2001 Patches for Intel C++ (Dave Abrahams)
// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests
// on MSVC. Reordered some #ifdefs for coherency.
// (David Abrahams)
// 13 Feb 2001 Test new VC6 workarounds (David Abrahams)
// 11 Feb 2001 Final fixes for Borland (David Abrahams)
// 11 Feb 2001 Some fixes for Borland get it closer on that compiler
// (David Abrahams)
// 07 Feb 2001 More comprehensive testing; factored out static tests for
// better reuse (David Abrahams)
// 21 Jan 2001 Quick fix to my_iterator, which wasn't returning a
// reference type from operator* (David Abrahams)
// 19 Jan 2001 Initial version with iterator operators (David Abrahams)
#include <boost/detail/iterator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/operators.hpp>
#include <boost/static_assert.hpp>
#include <iterator>
#include <vector>
#include <list>
#include <boost/detail/lightweight_test.hpp>
#include <iostream>
// A UDT for which we can specialize std::iterator_traits<element*> on
// compilers which don't support partial specialization. There's no
// other reasonable way to test pointers on those compilers.
struct element {};
// An iterator for which we can get traits.
struct my_iterator1
: boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&>
{
my_iterator1(const char* p) : m_p(p) {}
bool operator==(const my_iterator1& rhs) const
{ return this->m_p == rhs.m_p; }
my_iterator1& operator++() { ++this->m_p; return *this; }
const char& operator*() { return *m_p; }
private:
const char* m_p;
};
// Used to prove that we don't require std::iterator<> in the hierarchy under
// MSVC6, and that we can compute all the traits for a standard-conforming UDT
// iterator.
struct my_iterator2
: boost::equality_comparable<my_iterator2
, boost::incrementable<my_iterator2
, boost::dereferenceable<my_iterator2,const char*> > >
{
typedef char value_type;
typedef long difference_type;
typedef const char* pointer;
typedef const char& reference;
typedef std::forward_iterator_tag iterator_category;
my_iterator2(const char* p) : m_p(p) {}
bool operator==(const my_iterator2& rhs) const
{ return this->m_p == rhs.m_p; }
my_iterator2& operator++() { ++this->m_p; return *this; }
const char& operator*() { return *m_p; }
private:
const char* m_p;
};
// Used to prove that we're not overly confused by the existence of
// std::iterator<> in the hierarchy under MSVC6 - we should find that
// boost::detail::iterator_traits<my_iterator3>::difference_type is int.
struct my_iterator3 : my_iterator1
{
typedef int difference_type;
my_iterator3(const char* p)
: my_iterator1(p) {}
};
//
// Assertion tools. Used instead of BOOST_STATIC_ASSERT because that
// doesn't give us a nice stack backtrace
//
template <bool = false> struct assertion;
template <> struct assertion<true>
{
typedef char type;
};
template <class T, class U>
struct assert_same
: assertion<(::boost::is_same<T,U>::value)>
{
};
// Iterator tests
template <class Iterator,
class value_type, class difference_type, class pointer, class reference, class category>
struct non_portable_tests
{
typedef typename boost::detail::iterator_traits<Iterator>::pointer test_pt;
typedef typename boost::detail::iterator_traits<Iterator>::reference test_rt;
typedef typename assert_same<test_pt, pointer>::type a1;
typedef typename assert_same<test_rt, reference>::type a2;
};
template <class Iterator,
class value_type, class difference_type, class pointer, class reference, class category>
struct portable_tests
{
typedef typename boost::detail::iterator_traits<Iterator>::difference_type test_dt;
typedef typename boost::detail::iterator_traits<Iterator>::iterator_category test_cat;
typedef typename assert_same<test_dt, difference_type>::type a1;
typedef typename assert_same<test_cat, category>::type a2;
};
// Test iterator_traits
template <class Iterator,
class value_type, class difference_type, class pointer, class reference, class category>
struct input_iterator_test
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
{
typedef typename boost::detail::iterator_traits<Iterator>::value_type test_vt;
typedef typename assert_same<test_vt, value_type>::type a1;
};
template <class Iterator,
class value_type, class difference_type, class pointer, class reference, class category>
struct non_pointer_test
: input_iterator_test<Iterator,value_type,difference_type,pointer,reference,category>
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
{
};
template <class Iterator,
class value_type, class difference_type, class pointer, class reference, class category>
struct maybe_pointer_test
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
{
};
input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag>
istream_iterator_test;
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x564) && !defined(__SGI_STL_PORT)
typedef ::std::char_traits<char>::off_type distance;
non_pointer_test<std::ostream_iterator<int>,int,
distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
#elif defined(BOOST_MSVC_STD_ITERATOR)
non_pointer_test<std::ostream_iterator<int>,
int, void, int*, int&, std::output_iterator_tag>
ostream_iterator_test;
#elif BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(70190006))
non_pointer_test<std::ostream_iterator<int>,
int, long, int*, int&, std::output_iterator_tag>
ostream_iterator_test;
#else
non_pointer_test<std::ostream_iterator<int>,
void, void, void, void, std::output_iterator_tag>
ostream_iterator_test;
#endif
#ifdef __KCC
typedef long std_list_diff_type;
#else
typedef std::ptrdiff_t std_list_diff_type;
#endif
non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag>
list_iterator_test;
maybe_pointer_test<std::vector<int>::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
vector_iterator_test;
maybe_pointer_test<int*, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
int_pointer_test;
non_pointer_test<my_iterator1, char, long, const char*, const char&, std::forward_iterator_tag>
my_iterator1_test;
non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag>
my_iterator2_test;
non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag>
my_iterator3_test;
int main()
{
char chars[100];
int ints[100];
for (int length = 3; length < 100; length += length / 3)
{
std::list<int> l(length);
BOOST_TEST(boost::detail::distance(l.begin(), l.end()) == length);
std::vector<int> v(length);
BOOST_TEST(boost::detail::distance(v.begin(), v.end()) == length);
BOOST_TEST(boost::detail::distance(&ints[0], ints + length) == length);
BOOST_TEST(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length);
BOOST_TEST(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length);
BOOST_TEST(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length);
}
return boost::report_errors();
}
@@ -0,0 +1,20 @@
// Copyright (C) 2004 Jeremy Siek <jsiek@cs.indiana.edu>
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/iterator_archetypes.hpp>
#include <boost/cstdlib.hpp>
int main()
{
typedef boost::iterator_archetype<
int
, boost::iterator_archetypes::readable_iterator_t
, boost::single_pass_traversal_tag
> Iter;
boost::function_requires<
boost_concepts::LvalueIteratorConcept<Iter> >();
return boost::exit_success;
}
+22
View File
@@ -0,0 +1,22 @@
// Copyright Andrey Semashev 2014.
//
// Use, modification and distribution is subject to
// the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/minimum_category.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/type_traits/is_same.hpp>
#include <iterator>
using boost::is_same;
using boost::iterators::minimum_category;
int main(int, char*[])
{
BOOST_TEST_TRAIT_TRUE((is_same<minimum_category<std::forward_iterator_tag, std::random_access_iterator_tag>::type, std::forward_iterator_tag>));
BOOST_TEST_TRAIT_TRUE((is_same<minimum_category<std::random_access_iterator_tag, std::forward_iterator_tag>::type, std::forward_iterator_tag>));
BOOST_TEST_TRAIT_TRUE((is_same<minimum_category<std::random_access_iterator_tag, std::random_access_iterator_tag>::type, std::random_access_iterator_tag>));
return boost::report_errors();
}
@@ -0,0 +1,19 @@
// Copyright Andrey Semashev 2014.
//
// Use, modification and distribution is subject to
// the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/minimum_category.hpp>
using boost::iterators::minimum_category;
struct A {};
struct B {};
int main(int, char*[])
{
minimum_category<A, B>::type cat;
return 0;
}
@@ -0,0 +1,103 @@
// (C) Copyright Toon Knapen 2001.
// (C) Copyright Roland Richter 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include <boost/test/minimal.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <boost/static_assert.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/concept/assert.hpp>
#include <vector>
#include <list>
#include <algorithm>
// This test checks for convertibility/interoperability among similar
// permutation iterators. We're not using container iterators
// underneath, as in permutation_test, because of bugs in GCC-3.3's
// __normal_iterator that make is_convertible choke when testing
// convertibility.
void iterop_test()
{
typedef boost::permutation_iterator< double*, int const* > permutation_type;
typedef boost::permutation_iterator< double const*, int const* > permutation_const_type;
BOOST_CONCEPT_ASSERT((
boost_concepts::InteroperableIteratorConcept<
permutation_type
, permutation_const_type
>));
}
void permutation_test()
{
// Example taken from documentation of old permutation_iterator.
typedef std::vector< double > element_range_type;
typedef std::list< int > index_type;
const int element_range_size = 10;
const int index_size = 7;
BOOST_STATIC_ASSERT(index_size <= element_range_size);
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< 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() );
BOOST_CHECK( it == begin );
BOOST_CHECK( it != end );
BOOST_CHECK( std::distance( begin, end ) == index_size );
for( index_type::iterator i_it1 = indices.begin(); it != end; ++i_it1, ++it )
{
BOOST_CHECK( *it == elements[ *i_it1 ] );
}
it = begin;
for( int i1 = 0; i1 < index_size - 1 ; ++++i1, ++++it )
{
index_type::iterator i_it2 = indices.begin();
std::advance( i_it2, i1 );
BOOST_CHECK( *it == elements[ *i_it2 ] );
}
it = begin;
std::advance(it, index_size);
for( index_type::iterator i_it3 = indices.end(); it != begin; )
{
BOOST_CHECK( *--it == elements[ *--i_it3 ] );
}
it = begin;
std::advance(it, index_size);
for( int i2 = 0; i2 < index_size - 1; i2+=2, --it )
{
index_type::iterator i_it4 = --indices.end();
std::advance( i_it4, -i2 );
BOOST_CHECK( *--it == elements[ *i_it4 ] );
}
}
int test_main(int, char *[])
{
permutation_test();
return 0;
}
+71
View File
@@ -0,0 +1,71 @@
// Copyright David Abrahams 2004. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/pointee.hpp>
#include <boost/type_traits/add_const.hpp>
#include "static_assert_same.hpp"
#include <memory>
#include <list>
template <class T, class Ref>
struct proxy_ptr
{
typedef T element_type;
struct proxy
{
operator Ref() const;
};
proxy operator*() const;
};
template <class T>
struct proxy_ref_ptr : proxy_ptr<T,T&>
{
};
template <class T>
struct proxy_value_ptr : proxy_ptr<T,T>
{
typedef typename boost::add_const<T>::type element_type;
};
struct X {
template <class T> X(T const&);
template <class T> operator T&() const;
};
int main()
{
STATIC_ASSERT_SAME(boost::pointee<proxy_ref_ptr<int> >::type, int);
STATIC_ASSERT_SAME(boost::pointee<proxy_ref_ptr<X> >::type, X);
STATIC_ASSERT_SAME(boost::pointee<proxy_ref_ptr<int const> >::type, int const);
STATIC_ASSERT_SAME(boost::pointee<proxy_ref_ptr<X const> >::type, X const);
STATIC_ASSERT_SAME(boost::pointee<proxy_value_ptr<int> >::type, int const);
STATIC_ASSERT_SAME(boost::pointee<proxy_value_ptr<X> >::type, X const);
STATIC_ASSERT_SAME(boost::pointee<proxy_value_ptr<int const> >::type, int const);
STATIC_ASSERT_SAME(boost::pointee<proxy_value_ptr<X const> >::type, X const);
STATIC_ASSERT_SAME(boost::pointee<int*>::type, int);
STATIC_ASSERT_SAME(boost::pointee<int const*>::type, int const);
STATIC_ASSERT_SAME(boost::pointee<X*>::type, X);
STATIC_ASSERT_SAME(boost::pointee<X const*>::type, X const);
STATIC_ASSERT_SAME(boost::pointee<std::auto_ptr<int> >::type, int);
STATIC_ASSERT_SAME(boost::pointee<std::auto_ptr<X> >::type, X);
STATIC_ASSERT_SAME(boost::pointee<std::auto_ptr<int const> >::type, int const);
STATIC_ASSERT_SAME(boost::pointee<std::auto_ptr<X const> >::type, X const);
STATIC_ASSERT_SAME(boost::pointee<std::list<int>::iterator >::type, int);
STATIC_ASSERT_SAME(boost::pointee<std::list<X>::iterator >::type, X);
STATIC_ASSERT_SAME(boost::pointee<std::list<int>::const_iterator >::type, int const);
STATIC_ASSERT_SAME(boost::pointee<std::list<X>::const_iterator >::type, X const);
return 0;
}
@@ -0,0 +1,174 @@
// Copyright Thomas Witt 2003, Jeremy Siek 2004.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/concept_check.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/iterator_archetypes.hpp>
#include <boost/cstdlib.hpp>
#include <algorithm>
#include <deque>
#include <iostream>
using boost::dummyT;
// Test reverse iterator
int main()
{
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
dummyT(3), dummyT(4), dummyT(5) };
const int N = sizeof(array)/sizeof(dummyT);
// Concept checks
// Adapting old-style iterators
{
typedef boost::reverse_iterator<boost::bidirectional_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::reverse_iterator<boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
// Adapting new-style iterators
{
typedef boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::bidirectional_traversal_tag
> iter;
typedef boost::reverse_iterator<iter> Iter;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
#if 0
// It does not seem feasible to make this work. Need to change docs to
// require at lease Readable for the base iterator. -Jeremy
{
typedef boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::writable_iterator_t
, boost::bidirectional_traversal_tag
> iter;
typedef boost::reverse_iterator<iter> Iter;
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter, dummyT> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
#endif
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::bidirectional_traversal_tag
> iter;
typedef boost::reverse_iterator<iter> Iter;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_lvalue_iterator_t
, boost::bidirectional_traversal_tag
> iter;
typedef boost::reverse_iterator<iter> Iter;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::bidirectional_traversal_tag
> iter;
typedef boost::reverse_iterator<iter> Iter;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
#endif
// Test reverse_iterator
{
dummyT reversed[N];
std::copy(array, array + N, reversed);
std::reverse(reversed, reversed + N);
typedef boost::reverse_iterator<dummyT*> reverse_iterator;
reverse_iterator i(reversed + N);
boost::random_access_iterator_test(i, N, array);
boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array);
typedef boost::reverse_iterator<const dummyT*> const_reverse_iterator;
const_reverse_iterator j(reversed + N);
boost::random_access_iterator_test(j, N, array);
const dummyT* const_reversed = reversed;
boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
boost::const_nonconst_iterator_test(i, ++j);
}
// Test reverse_iterator again, with traits fully deducible on all platforms
{
std::deque<dummyT> reversed_container;
std::reverse_copy(array, array + N, std::back_inserter(reversed_container));
const std::deque<dummyT>::iterator reversed = reversed_container.begin();
typedef boost::reverse_iterator<
std::deque<dummyT>::iterator> reverse_iterator;
typedef boost::reverse_iterator<
std::deque<dummyT>::const_iterator> const_reverse_iterator;
// MSVC/STLport gives an INTERNAL COMPILER ERROR when any computation
// (e.g. "reversed + N") is used in the constructor below.
const std::deque<dummyT>::iterator finish = reversed_container.end();
reverse_iterator i(finish);
boost::random_access_iterator_test(i, N, array);
boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array);
const_reverse_iterator j = reverse_iterator(finish);
boost::random_access_iterator_test(j, N, array);
const std::deque<dummyT>::const_iterator const_reversed = reversed;
boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
// Many compilers' builtin deque iterators don't interoperate well, though
// STLport fixes that problem.
#if defined(__SGI_STL_PORT) \
|| !BOOST_WORKAROUND(__GNUC__, <= 2) \
&& !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, <= 1)) \
&& !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) \
&& !BOOST_WORKAROUND(__LIBCOMO_VERSION__, BOOST_TESTED_AT(29)) \
&& !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 1)
boost::const_nonconst_iterator_test(i, ++j);
#endif
}
return boost::report_errors();
}
+20
View File
@@ -0,0 +1,20 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef STATIC_ASSERT_SAME_DWA2003530_HPP
# define STATIC_ASSERT_SAME_DWA2003530_HPP
#include <boost/mpl/assert.hpp>
# include <boost/type_traits/is_same.hpp>
#define STATIC_ASSERT_SAME( T1,T2 ) BOOST_MPL_ASSERT((::boost::is_same< T1, T2 >))
template <class T1, class T2>
struct static_assert_same
{
BOOST_MPL_ASSERT((::boost::is_same< T1, T2 >));
enum { value = 1 };
};
#endif // STATIC_ASSERT_SAME_DWA2003530_HPP
@@ -0,0 +1,285 @@
// (C) Copyright Jeremy Siek 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// 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/assert.hpp>
#include <boost/config.hpp>
#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 function_object_result<int (*)(int)>
{
typedef int type;
};
}}
#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 const_select_first
{
typedef int const& result_type;
int const& operator()(std::pair<int, int>const& p) const
{
return p.first;
}
};
struct select_first
: const_select_first // derivation to allow conversions
{
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 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;
}
struct polymorphic_mult_functor
{
//Implement result_of protocol
template <class FArgs> struct result;
template <class F, class T> struct result<const F(T )> {typedef T type;};
template <class F, class T> struct result<const F(T& )> {typedef T type;};
template <class F, class T> struct result<const F(const T&)> {typedef T type;};
template <class F, class T> struct result<F(T )> {typedef void type;};
template <class F, class T> struct result<F(T& )> {typedef void type;};
template <class F, class T> struct result<F(const T&)> {typedef void type;};
template <class T>
T operator()(const T& _arg) const {return _arg*2;}
template <class T>
void operator()(const T& _arg) { BOOST_ASSERT(0); }
};
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::InteroperableIteratorConcept<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::non_const_lvalue_iterator_test(
boost::make_transform_iterator((pair_t*)values, select_first()), x[0], 17);
boost::const_nonconst_iterator_test(
++boost::make_transform_iterator((pair_t*)values, select_first())
, boost::make_transform_iterator((pair_t*)values, const_select_first())
);
}
// Test transform_iterator with polymorphic object function
{
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, polymorphic_mult_functor()), x[0], x[1]);
boost::input_iterator_test(
boost::make_transform_iterator(&y[0], polymorphic_mult_functor()), x[0], x[1]);
boost::random_access_readable_iterator_test(
boost::make_transform_iterator(y, polymorphic_mult_functor()), N, x);
}
return boost::report_errors();
}
+107
View File
@@ -0,0 +1,107 @@
// Copyright David Abrahams 2003.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/static_assert.hpp>
#include "static_assert_same.hpp"
#include <boost/iterator/minimum_category.hpp>
struct X { int a; };
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::iterators::minimum_category<T,U>::type, Min
>
{};
void category_test()
{
using namespace boost::iterators;
using namespace boost::iterators::detail;
BOOST_STATIC_ASSERT((
!boost::is_convertible<
std::input_iterator_tag
, input_output_iterator_tag>::value));
BOOST_STATIC_ASSERT((
!boost::is_convertible<
std::output_iterator_tag
, input_output_iterator_tag>::value));
BOOST_STATIC_ASSERT((
boost::is_convertible<
input_output_iterator_tag
, std::input_iterator_tag>::value));
BOOST_STATIC_ASSERT((
boost::is_convertible<
input_output_iterator_tag
, std::output_iterator_tag>::value));
#if 0 // This seems wrong; we're not advertising
// input_output_iterator_tag are we?
BOOST_STATIC_ASSERT((
boost::is_convertible<
std::forward_iterator_tag
, input_output_iterator_tag>::value));
#endif
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;
#if 0
test = static_assert_min_cat<
input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag
>::value;
#endif
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;
#if 0 // This would be wrong: a random access iterator is not
// neccessarily writable, as is an output iterator.
test = static_assert_min_cat<
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
>::value;
#endif
(void)test;
}
int main()
{
category_test();
operator_arrow_test();
return 0;
}
+8
View File
@@ -0,0 +1,8 @@
#include <boost/tuple/tuple.hpp>
#define ZI_TUPLE boost::tuples::tuple
#define ZI_MAKE_TUPLE boost::make_tuple
#define ZI_TUPLE_GET(n) boost::tuples::get<n>
#define ZI_USE_BOOST_TUPLE
#include "detail/zip_iterator_test_original.ipp"
@@ -0,0 +1,9 @@
#include <boost/fusion/include/deque.hpp>
#include <boost/fusion/include/make_deque.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#define ZI_TUPLE boost::fusion::deque
#define ZI_MAKE_TUPLE boost::fusion::make_deque
#define ZI_TUPLE_GET(n) boost::fusion::at_c<n>
#include "detail/zip_iterator_test_original.ipp"
@@ -0,0 +1,11 @@
#include <boost/config.hpp>
#include <boost/fusion/include/list.hpp>
#include <boost/fusion/include/make_list.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#define ZI_TUPLE boost::fusion::list
#define ZI_MAKE_TUPLE boost::fusion::make_list
#define ZI_TUPLE_GET(n) boost::fusion::at_c<n>
#include "detail/zip_iterator_test_original.ipp"
@@ -0,0 +1,11 @@
#include <boost/config.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#define ZI_TUPLE boost::fusion::vector
#define ZI_MAKE_TUPLE boost::fusion::make_vector
#define ZI_TUPLE_GET(n) boost::fusion::at_c<n>
#include "detail/zip_iterator_test_original.ipp"
@@ -0,0 +1,21 @@
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
#include <tuple>
#include <boost/fusion/adapted/std_tuple.hpp>
#define ZI_TUPLE std::tuple
#define ZI_MAKE_TUPLE std::make_tuple
#define ZI_TUPLE_GET(n) std::get<n>
#include "detail/zip_iterator_test_original.ipp"
#else
int main()
{
return 0;
}
#endif
@@ -0,0 +1,15 @@
// Copyright (c) 2014 Kohei Takahashi.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for most recent version including documentation.
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/make_vector.hpp>
#define TUPLE boost::fusion::vector
#define MAKE_TUPLE boost::fusion::make_vector
#include "detail/zip_iterator_test.ipp"
@@ -0,0 +1,16 @@
// Copyright (c) 2014 Kohei Takahashi.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for most recent version including documentation.
#include <utility>
#include <boost/fusion/adapted/std_pair.hpp>
#define TUPLE std::pair
#define MAKE_TUPLE std::make_pair
#include "detail/zip_iterator_test.ipp"
@@ -0,0 +1,29 @@
// Copyright (c) 2014 Kohei Takahashi.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for most recent version including documentation.
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <tuple>
#include <boost/fusion/adapted/std_tuple.hpp>
#define TUPLE std::tuple
#define MAKE_TUPLE std::make_tuple
#include "detail/zip_iterator_test.ipp"
#else
int main()
{
return 0;
}
#endif