mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2026-06-02 22:14:56 -04:00
Squashed 'boost/' content from commit b4feb19f2
git-subtree-dir: boost git-subtree-split: b4feb19f287ee92d87a9624b5d36b7cf46aeadeb
This commit is contained in:
@@ -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 ]
|
||||
;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user