diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/iterator/test | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/iterator/test')
46 files changed, 4800 insertions, 0 deletions
diff --git a/src/boost/libs/iterator/test/Jamfile.v2 b/src/boost/libs/iterator/test/Jamfile.v2 new file mode 100644 index 000000000..14b7b2a0c --- /dev/null +++ b/src/boost/libs/iterator/test/Jamfile.v2 @@ -0,0 +1,66 @@ +# 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 ] + + [ run next_prior_test.cpp ] + [ run advance_test.cpp ] + [ run distance_test.cpp ] + [ compile adl_test.cpp ] + [ compile range_distance_compat_test.cpp ] + + [ run shared_iterator_test.cpp ] +; diff --git a/src/boost/libs/iterator/test/adl_test.cpp b/src/boost/libs/iterator/test/adl_test.cpp new file mode 100644 index 000000000..5d5f69968 --- /dev/null +++ b/src/boost/libs/iterator/test/adl_test.cpp @@ -0,0 +1,25 @@ +// Copyright (C) 2017 Michel Morin. +// +// 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 <vector> +#include <boost/array.hpp> +#include <boost/iterator/advance.hpp> +#include <boost/iterator/distance.hpp> + +int main() +{ + // Test that boost::advance/distance are not found by ADL. + // (https://github.com/boostorg/iterator/issues/43) + + typedef boost::array<int, 1> boost_type; + std::vector<boost_type> std_boost(2); + std::vector<boost_type>::iterator it = std_boost.begin(); + + advance(it, 2); + (void)distance(it, it); + + return 0; +} diff --git a/src/boost/libs/iterator/test/advance_test.cpp b/src/boost/libs/iterator/test/advance_test.cpp new file mode 100644 index 000000000..85cd4ac68 --- /dev/null +++ b/src/boost/libs/iterator/test/advance_test.cpp @@ -0,0 +1,91 @@ +// Copyright (C) 2017 Michel Morin. +// +// 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 <vector> +#include <list> +#include <boost/container/slist.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/iterator/advance.hpp> +#include <boost/iterator/transform_iterator.hpp> + +int twice(int x) { return x + x; } + +template <typename Iterator> +void test_advance(Iterator it_from, Iterator it_to, int n) +{ + boost::advance(it_from, n); + BOOST_TEST(it_from == it_to); +} + +int main() +{ + int array[3] = {1, 2, 3}; + int* ptr1 = array; + int* ptr2 = array + 3; + + { + test_advance(ptr1, ptr2, 3); + test_advance(ptr2, ptr1, -3); + + test_advance( + boost::make_transform_iterator(ptr1, twice) + , boost::make_transform_iterator(ptr2, twice) + , 3 + ); + test_advance( + boost::make_transform_iterator(ptr2, twice) + , boost::make_transform_iterator(ptr1, twice) + , -3 + ); + } + + { + std::vector<int> ints(ptr1, ptr2); + test_advance(ints.begin(), ints.end(), 3); + test_advance(ints.end(), ints.begin(), -3); + + test_advance( + boost::make_transform_iterator(ints.begin(), twice) + , boost::make_transform_iterator(ints.end(), twice) + , 3 + ); + test_advance( + boost::make_transform_iterator(ints.end(), twice) + , boost::make_transform_iterator(ints.begin(), twice) + , -3 + ); + } + + { + std::list<int> ints(ptr1, ptr2); + test_advance(ints.begin(), ints.end(), 3); + test_advance(ints.end(), ints.begin(), -3); + + test_advance( + boost::make_transform_iterator(ints.begin(), twice) + , boost::make_transform_iterator(ints.end(), twice) + , 3 + ); + test_advance( + boost::make_transform_iterator(ints.end(), twice) + , boost::make_transform_iterator(ints.begin(), twice) + , -3 + ); + } + + { + boost::container::slist<int> ints(ptr1, ptr2); + test_advance(ints.begin(), ints.end(), 3); + + test_advance( + boost::make_transform_iterator(ints.begin(), twice) + , boost::make_transform_iterator(ints.end(), twice) + , 3 + ); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/iterator/test/concept_tests.cpp b/src/boost/libs/iterator/test/concept_tests.cpp new file mode 100644 index 000000000..091f6e52b --- /dev/null +++ b/src/boost/libs/iterator/test/concept_tests.cpp @@ -0,0 +1,107 @@ +// (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> + +#include <iterator> +#include <cstddef> + +struct new_random_access + : std::random_access_iterator_tag + , boost::random_access_traversal_tag +{}; + +struct new_iterator +{ + typedef new_random_access iterator_category; + typedef int value_type; + typedef std::ptrdiff_t difference_type; + typedef int* pointer; + typedef int& reference; + + 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 +{ + typedef std::random_access_iterator_tag iterator_category; + typedef int value_type; + typedef std::ptrdiff_t difference_type; + typedef int* pointer; + typedef int& reference; + + 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; +} diff --git a/src/boost/libs/iterator/test/constant_iter_arrow.cpp b/src/boost/libs/iterator/test/constant_iter_arrow.cpp new file mode 100644 index 000000000..3579c53ba --- /dev/null +++ b/src/boost/libs/iterator/test/constant_iter_arrow.cpp @@ -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 diff --git a/src/boost/libs/iterator/test/constant_iter_arrow_fail.cpp b/src/boost/libs/iterator/test/constant_iter_arrow_fail.cpp new file mode 100644 index 000000000..05f551a93 --- /dev/null +++ b/src/boost/libs/iterator/test/constant_iter_arrow_fail.cpp @@ -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; +} diff --git a/src/boost/libs/iterator/test/counting_iterator_test.cpp b/src/boost/libs/iterator/test/counting_iterator_test.cpp new file mode 100644 index 000000000..899b0455c --- /dev/null +++ b/src/boost/libs/iterator/test/counting_iterator_test.cpp @@ -0,0 +1,299 @@ +// (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/core/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; + + // 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(); +} diff --git a/src/boost/libs/iterator/test/detail/zip_iterator_test.ipp b/src/boost/libs/iterator/test/detail/zip_iterator_test.ipp new file mode 100644 index 000000000..7e0d2f7b0 --- /dev/null +++ b/src/boost/libs/iterator/test/detail/zip_iterator_test.ipp @@ -0,0 +1,85 @@ +// 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/core/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"); + } + + { + // Trac #12895 + boost::zip_iterator< + TUPLE<int*, std::string*> + > i(MAKE_TUPLE(&vi[0], &vs[0])); + + 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(); +} diff --git a/src/boost/libs/iterator/test/detail/zip_iterator_test_original.ipp b/src/boost/libs/iterator/test/detail/zip_iterator_test_original.ipp new file mode 100644 index 000000000..dc042214b --- /dev/null +++ b/src/boost/libs/iterator/test/detail/zip_iterator_test_original.ipp @@ -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; +} + diff --git a/src/boost/libs/iterator/test/distance_test.cpp b/src/boost/libs/iterator/test/distance_test.cpp new file mode 100644 index 000000000..91587d670 --- /dev/null +++ b/src/boost/libs/iterator/test/distance_test.cpp @@ -0,0 +1,84 @@ +// Copyright (C) 2017 Michel Morin. +// +// 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 <vector> +#include <list> +#include <boost/container/slist.hpp> +#include <boost/core/lightweight_test.hpp> +#include <boost/iterator/distance.hpp> +#include <boost/iterator/transform_iterator.hpp> + +int twice(int x) { return x + x; } + +template <typename Iterator> +void test_distance(Iterator it_from, Iterator it_to, int n) +{ + BOOST_TEST(boost::distance(it_from, it_to) == n); +} + +int main() +{ + int array[3] = {1, 2, 3}; + int* ptr1 = array; + int* ptr2 = array + 3; + + { + test_distance(ptr1, ptr2, 3); + test_distance(ptr2, ptr1, -3); + + test_distance( + boost::make_transform_iterator(ptr1, twice) + , boost::make_transform_iterator(ptr2, twice) + , 3 + ); + test_distance( + boost::make_transform_iterator(ptr2, twice) + , boost::make_transform_iterator(ptr1, twice) + , -3 + ); + } + + { + std::vector<int> ints(ptr1, ptr2); + test_distance(ints.begin(), ints.end(), 3); + test_distance(ints.end(), ints.begin(), -3); + + test_distance( + boost::make_transform_iterator(ints.begin(), twice) + , boost::make_transform_iterator(ints.end(), twice) + , 3 + ); + test_distance( + boost::make_transform_iterator(ints.end(), twice) + , boost::make_transform_iterator(ints.begin(), twice) + , -3 + ); + } + + { + std::list<int> ints(ptr1, ptr2); + test_distance(ints.begin(), ints.end(), 3); + + test_distance( + boost::make_transform_iterator(ints.begin(), twice) + , boost::make_transform_iterator(ints.end(), twice) + , 3 + ); + } + + { + boost::container::slist<int> ints(ptr1, ptr2); + test_distance(ints.begin(), ints.end(), 3); + + test_distance( + boost::make_transform_iterator(ints.begin(), twice) + , boost::make_transform_iterator(ints.end(), twice) + , 3 + ); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/iterator/test/filter_iterator_test.cpp b/src/boost/libs/iterator/test/filter_iterator_test.cpp new file mode 100644 index 000000000..cf850bcf7 --- /dev/null +++ b/src/boost/libs/iterator/test/filter_iterator_test.cpp @@ -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(); +} diff --git a/src/boost/libs/iterator/test/function_input_iterator_test.cpp b/src/boost/libs/iterator/test/function_input_iterator_test.cpp new file mode 100644 index 000000000..4843f0152 --- /dev/null +++ b/src/boost/libs/iterator/test/function_input_iterator_test.cpp @@ -0,0 +1,120 @@ +// 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 <cstddef> + +#include <algorithm> +#include <iterator> +#include <vector> + +#include <boost/config.hpp> + +#if !defined(BOOST_NO_CXX11_DECLTYPE) +// Force boost::result_of use decltype, even on compilers that don't support N3276. +// This enables this test to also verify if the iterator works with lambdas +// on such compilers with this config macro. Note that without the macro result_of +// (and consequently the iterator) is guaranteed to _not_ work, so this case is not +// worth testing anyway. +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#include <boost/core/lightweight_test.hpp> +#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() +{ + // 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) + ); + + BOOST_TEST_ALL_EQ(values.begin(), values.end(), generated.begin(), generated.end()); + + // 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) + ); + + BOOST_TEST_ALL_EQ(values.begin(), values.end(), generated.begin(), generated.end()); + + // 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) + ); + + BOOST_TEST_ALL_EQ(values.begin(), values.end(), generated.begin(), generated.end()); + + // 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) + ); + + BOOST_TEST_EQ(generated.size(), 10u); + BOOST_TEST_EQ(counter_generator.n, 42 + 10); + for(std::size_t i = 0; i != 10; ++i) + BOOST_TEST_EQ(generated[i], static_cast<int>(42 + i)); + +#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) \ + && defined(BOOST_RESULT_OF_USE_DECLTYPE) + // test the iterator with lambda expressions + int num = 42; + auto lambda_generator = [&num] { return num++; }; + vector<int>().swap(generated); + copy( + boost::make_function_input_iterator(lambda_generator, 0), + boost::make_function_input_iterator(lambda_generator, 10), + back_inserter(generated) + ); + + BOOST_TEST_EQ(generated.size(), 10u); + for(std::size_t i = 0; i != 10; ++i) + BOOST_TEST_EQ(generated[i], static_cast<int>(42 + i)); +#endif // BOOST_NO_CXX11_LAMBDAS + + return boost::report_errors(); +} diff --git a/src/boost/libs/iterator/test/generator_iterator_test.cpp b/src/boost/libs/iterator/test/generator_iterator_test.cpp new file mode 100644 index 000000000..c31bd66ad --- /dev/null +++ b/src/boost/libs/iterator/test/generator_iterator_test.cpp @@ -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/core/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(); +} diff --git a/src/boost/libs/iterator/test/indirect_iter_member_types.cpp b/src/boost/libs/iterator/test/indirect_iter_member_types.cpp new file mode 100644 index 000000000..240e664fb --- /dev/null +++ b/src/boost/libs/iterator/test/indirect_iter_member_types.cpp @@ -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; +} diff --git a/src/boost/libs/iterator/test/indirect_iterator_test.cpp b/src/boost/libs/iterator/test/indirect_iterator_test.cpp new file mode 100644 index 000000000..a08afa8b2 --- /dev/null +++ b/src/boost/libs/iterator/test/indirect_iterator_test.cpp @@ -0,0 +1,220 @@ +// (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/next_prior.hpp> + +#include <boost/mpl/has_xxx.hpp> + +#include <boost/core/lightweight_test.hpp> + +#include <vector> +#include <stdlib.h> +#include <set> +#include <iterator> + +#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< + std::iterator_traits<shared_t::iterator>::value_type + >::value + ); + + typedef boost::indirect_iterator< + shared_t::iterator + , boost::iterator_value<shared_t::iterator>::type const + > c_iter_t; + +# ifndef NO_MUTABLE_CONST_RA_ITERATOR_INTEROPERABILITY + boost::function_requires< boost_concepts::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(); +} diff --git a/src/boost/libs/iterator/test/interoperable.cpp b/src/boost/libs/iterator/test/interoperable.cpp new file mode 100644 index 000000000..ad4167262 --- /dev/null +++ b/src/boost/libs/iterator/test/interoperable.cpp @@ -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/core/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(); +} diff --git a/src/boost/libs/iterator/test/interoperable_fail.cpp b/src/boost/libs/iterator/test/interoperable_fail.cpp new file mode 100644 index 000000000..d6d249a42 --- /dev/null +++ b/src/boost/libs/iterator/test/interoperable_fail.cpp @@ -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; +} diff --git a/src/boost/libs/iterator/test/is_convertible_fail.cpp b/src/boost/libs/iterator/test/is_convertible_fail.cpp new file mode 100644 index 000000000..757b5c6ac --- /dev/null +++ b/src/boost/libs/iterator/test/is_convertible_fail.cpp @@ -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; +} diff --git a/src/boost/libs/iterator/test/is_lvalue_iterator.cpp b/src/boost/libs/iterator/test/is_lvalue_iterator.cpp new file mode 100644 index 000000000..ba880d70b --- /dev/null +++ b/src/boost/libs/iterator/test/is_lvalue_iterator.cpp @@ -0,0 +1,148 @@ +// 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 <cstddef> // std::ptrdiff_t +#include <boost/static_assert.hpp> +#include <boost/noncopyable.hpp> +#include <boost/iterator/is_lvalue_iterator.hpp> + +// Last, for BOOST_NO_LVALUE_RETURN_DETECTION +#include <boost/iterator/detail/config_def.hpp> + +struct v +{ + v(); + ~v(); +}; + + +struct value_iterator +{ + typedef std::input_iterator_tag iterator_category; + typedef v value_type; + typedef std::ptrdiff_t difference_type; + typedef v* pointer; + typedef v& reference; + + v operator*() const; +}; + +struct noncopyable_iterator +{ + typedef std::forward_iterator_tag iterator_category; + typedef boost::noncopyable value_type; + typedef std::ptrdiff_t difference_type; + typedef boost::noncopyable* pointer; + typedef boost::noncopyable& reference; + + boost::noncopyable const& operator*() const; +}; + +template <class T> +struct proxy_iterator +{ + typedef T value_type; + typedef std::output_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + typedef T* pointer; + typedef T& reference; + + 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; +} diff --git a/src/boost/libs/iterator/test/is_readable_iterator.cpp b/src/boost/libs/iterator/test/is_readable_iterator.cpp new file mode 100644 index 000000000..1d33a64ab --- /dev/null +++ b/src/boost/libs/iterator/test/is_readable_iterator.cpp @@ -0,0 +1,96 @@ +// 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 <cstddef> // std::ptrdiff_t +#include <boost/static_assert.hpp> +#include <boost/noncopyable.hpp> +#include <boost/iterator/is_readable_iterator.hpp> + +// Last, for BOOST_NO_LVALUE_RETURN_DETECTION +#include <boost/iterator/detail/config_def.hpp> + +struct v +{ + v(); + ~v(); +}; + + +struct value_iterator +{ + typedef std::input_iterator_tag iterator_category; + typedef v value_type; + typedef std::ptrdiff_t difference_type; + typedef v* pointer; + typedef v& reference; + + v operator*() const; +}; + +struct noncopyable_iterator +{ + typedef std::forward_iterator_tag iterator_category; + typedef boost::noncopyable value_type; + typedef std::ptrdiff_t difference_type; + typedef boost::noncopyable* pointer; + typedef boost::noncopyable& reference; + + boost::noncopyable const& operator*() const; +}; + +struct proxy_iterator +{ + typedef std::output_iterator_tag iterator_category; + typedef v value_type; + typedef std::ptrdiff_t difference_type; + typedef v* pointer; + typedef v& reference; + + struct proxy + { + operator v&(); + proxy& operator=(v) const; + }; + + proxy operator*() const; +}; + +struct proxy_iterator2 +{ + typedef std::output_iterator_tag iterator_category; + typedef v value_type; + typedef std::ptrdiff_t difference_type; + typedef v* pointer; + typedef v& reference; + + 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; +} diff --git a/src/boost/libs/iterator/test/iter_archetype_default_ctor.cpp b/src/boost/libs/iterator/test/iter_archetype_default_ctor.cpp new file mode 100644 index 000000000..7936bdd2f --- /dev/null +++ b/src/boost/libs/iterator/test/iter_archetype_default_ctor.cpp @@ -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; +} diff --git a/src/boost/libs/iterator/test/iterator_adaptor_cc.cpp b/src/boost/libs/iterator/test/iterator_adaptor_cc.cpp new file mode 100644 index 000000000..1ab676a29 --- /dev/null +++ b/src/boost/libs/iterator/test/iterator_adaptor_cc.cpp @@ -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; +} diff --git a/src/boost/libs/iterator/test/iterator_adaptor_test.cpp b/src/boost/libs/iterator/test/iterator_adaptor_test.cpp new file mode 100644 index 000000000..88a8a1bef --- /dev/null +++ b/src/boost/libs/iterator/test/iterator_adaptor_test.cpp @@ -0,0 +1,304 @@ +// (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/core/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; + +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(); +} diff --git a/src/boost/libs/iterator/test/iterator_archetype_cc.cpp b/src/boost/libs/iterator/test/iterator_archetype_cc.cpp new file mode 100644 index 000000000..98d32ae7d --- /dev/null +++ b/src/boost/libs/iterator/test/iterator_archetype_cc.cpp @@ -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; +} + diff --git a/src/boost/libs/iterator/test/iterator_facade.cpp b/src/boost/libs/iterator/test/iterator_facade.cpp new file mode 100644 index 000000000..d9e5eb6ee --- /dev/null +++ b/src/boost/libs/iterator/test/iterator_facade.cpp @@ -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&) 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(); +} diff --git a/src/boost/libs/iterator/test/iterator_traits_test.cpp b/src/boost/libs/iterator/test/iterator_traits_test.cpp new file mode 100644 index 000000000..4dd4e7af7 --- /dev/null +++ b/src/boost/libs/iterator/test/iterator_traits_test.cpp @@ -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/core/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(); +} diff --git a/src/boost/libs/iterator/test/lvalue_concept_fail.cpp b/src/boost/libs/iterator/test/lvalue_concept_fail.cpp new file mode 100644 index 000000000..735bb4ab8 --- /dev/null +++ b/src/boost/libs/iterator/test/lvalue_concept_fail.cpp @@ -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; +} diff --git a/src/boost/libs/iterator/test/minimum_category.cpp b/src/boost/libs/iterator/test/minimum_category.cpp new file mode 100644 index 000000000..3f89d6c6a --- /dev/null +++ b/src/boost/libs/iterator/test/minimum_category.cpp @@ -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(); +} diff --git a/src/boost/libs/iterator/test/minimum_category_compile_fail.cpp b/src/boost/libs/iterator/test/minimum_category_compile_fail.cpp new file mode 100644 index 000000000..736cc200d --- /dev/null +++ b/src/boost/libs/iterator/test/minimum_category_compile_fail.cpp @@ -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; +} diff --git a/src/boost/libs/iterator/test/next_prior_test.cpp b/src/boost/libs/iterator/test/next_prior_test.cpp new file mode 100644 index 000000000..c8643f77b --- /dev/null +++ b/src/boost/libs/iterator/test/next_prior_test.cpp @@ -0,0 +1,112 @@ +// Boost test program for next() and prior() utilities. + +// Copyright 2003 Daniel Walker. Use, modification, and distribution +// are subject to the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt.) + +// See http://www.boost.org/libs/utility for documentation. + +// Revision History 13 Dec 2003 Initial Version (Daniel Walker) + +// next() and prior() are replacements for operator+ and operator- for +// non-random-access iterators. The semantics of these operators are +// such that after executing j = i + n, std::distance(i, j) equals +// n. Tests are provided to ensure next() has the same +// result. Parallel tests are provided for prior(). The tests call +// next() and prior() several times. next() and prior() are very +// simple functions, though, and it would be very strange if these +// tests were to fail. + +#include <boost/core/lightweight_test.hpp> + +#include <list> +#include <vector> + +#include <boost/next_prior.hpp> + +template<class RandomAccessIterator, class ForwardIterator> +bool plus_one_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2) +{ + RandomAccessIterator i = first; + ForwardIterator j = first2; + while(i != last) + i = i + 1, j = boost::next(j); + return std::distance(first, i) == std::distance(first2, j); +} + +template<class RandomAccessIterator, class ForwardIterator> +bool plus_n_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2) +{ + RandomAccessIterator i = first; + ForwardIterator j = first2; + for(int n = 0; i != last; ++n) + i = first + n, j = boost::next(first2, n); + return std::distance(first, i) == std::distance(first2, j); +} + +template<class RandomAccessIterator, class BidirectionalIterator> +bool minus_one_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2) +{ + RandomAccessIterator i = last; + BidirectionalIterator j = last2; + while(i != first) + i = i - 1, j = boost::prior(j); + return std::distance(i, last) == std::distance(j, last2); +} + +template<class RandomAccessIterator, class BidirectionalIterator> +bool minus_n_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2) +{ + RandomAccessIterator i = last; + BidirectionalIterator j = last2; + for(int n = 0; i != first; ++n) + i = last - n, j = boost::prior(last2, n); + return std::distance(i, last) == std::distance(j, last2); +} + +template<class Iterator, class Distance> +bool minus_n_unsigned_test(Iterator first, Iterator last, Distance size) +{ + Iterator i = boost::prior(last, size); + return i == first; +} + +int main(int, char*[]) +{ + std::vector<int> x(8); + std::list<int> y(x.begin(), x.end()); + + // Tests with iterators + BOOST_TEST(plus_one_test(x.begin(), x.end(), y.begin())); + BOOST_TEST(plus_n_test(x.begin(), x.end(), y.begin())); + BOOST_TEST(minus_one_test(x.begin(), x.end(), y.end())); + BOOST_TEST(minus_n_test(x.begin(), x.end(), y.end())); + BOOST_TEST(minus_n_unsigned_test(x.begin(), x.end(), x.size())); + BOOST_TEST(minus_n_unsigned_test(y.begin(), y.end(), y.size())); + + BOOST_TEST(plus_one_test(x.rbegin(), x.rend(), y.begin())); + BOOST_TEST(plus_n_test(x.rbegin(), x.rend(), y.begin())); + BOOST_TEST(minus_one_test(x.rbegin(), x.rend(), y.end())); + BOOST_TEST(minus_n_test(x.rbegin(), x.rend(), y.end())); + BOOST_TEST(minus_n_unsigned_test(x.rbegin(), x.rend(), x.size())); + BOOST_TEST(minus_n_unsigned_test(x.rbegin(), x.rend(), y.size())); + + // Test with pointers + std::vector<int> z(x.size()); + int* p = &z[0]; + BOOST_TEST(plus_one_test(x.begin(), x.end(), p)); + BOOST_TEST(plus_n_test(x.begin(), x.end(), p)); + BOOST_TEST(minus_one_test(x.begin(), x.end(), p + z.size())); + BOOST_TEST(minus_n_test(x.begin(), x.end(), p + z.size())); + BOOST_TEST(minus_n_unsigned_test(p, p + z.size(), z.size())); + + // Tests with integers + BOOST_TEST(boost::next(5) == 6); + BOOST_TEST(boost::next(5, 7) == 12); + BOOST_TEST(boost::prior(5) == 4); + BOOST_TEST(boost::prior(5, 7) == -2); + BOOST_TEST(boost::prior(5, 7u) == -2); + + return boost::report_errors(); +} diff --git a/src/boost/libs/iterator/test/permutation_iterator_test.cpp b/src/boost/libs/iterator/test/permutation_iterator_test.cpp new file mode 100644 index 000000000..6fbeaadd0 --- /dev/null +++ b/src/boost/libs/iterator/test/permutation_iterator_test.cpp @@ -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; +} diff --git a/src/boost/libs/iterator/test/pointee.cpp b/src/boost/libs/iterator/test/pointee.cpp new file mode 100644 index 000000000..32e34962f --- /dev/null +++ b/src/boost/libs/iterator/test/pointee.cpp @@ -0,0 +1,83 @@ +// 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); + +#if defined(BOOST_NO_CXX11_SMART_PTR) + + 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); + +#else + + STATIC_ASSERT_SAME(boost::pointee<std::unique_ptr<int> >::type, int); + STATIC_ASSERT_SAME(boost::pointee<std::unique_ptr<X> >::type, X); + + STATIC_ASSERT_SAME(boost::pointee<std::unique_ptr<int const> >::type, int const); + STATIC_ASSERT_SAME(boost::pointee<std::unique_ptr<X const> >::type, X const); + +#endif + + 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; +} diff --git a/src/boost/libs/iterator/test/range_distance_compat_test.cpp b/src/boost/libs/iterator/test/range_distance_compat_test.cpp new file mode 100644 index 000000000..ef7e301da --- /dev/null +++ b/src/boost/libs/iterator/test/range_distance_compat_test.cpp @@ -0,0 +1,22 @@ +// Copyright (C) 2018 Andrey Semashev +// +// 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/range/distance.hpp> +#include <boost/range/iterator_range_core.hpp> +#include <boost/iterator/distance.hpp> + +int main() +{ + // Test that boost::distance from Boost.Range works with boost::distance from Boost.Iterator + // (https://github.com/boostorg/iterator/commit/b844c8df530c474ec1856870b9b0de5f487b84d4#commitcomment-30603668) + + typedef boost::iterator_range<const char*> range_type; + range_type range; + + (void)boost::distance(range); + + return 0; +} diff --git a/src/boost/libs/iterator/test/reverse_iterator_test.cpp b/src/boost/libs/iterator/test/reverse_iterator_test.cpp new file mode 100644 index 000000000..8ac5e10ef --- /dev/null +++ b/src/boost/libs/iterator/test/reverse_iterator_test.cpp @@ -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(); +} diff --git a/src/boost/libs/iterator/test/shared_iterator_test.cpp b/src/boost/libs/iterator/test/shared_iterator_test.cpp new file mode 100644 index 000000000..a943d3049 --- /dev/null +++ b/src/boost/libs/iterator/test/shared_iterator_test.cpp @@ -0,0 +1,64 @@ +// Copyright 2003 The Trustees of Indiana University. + +// 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) + +// Shared container iterator adaptor +// Author: Ronald Garcia +// See http://boost.org/libs/utility/shared_container_iterator.html +// for documentation. + +// +// shared_iterator_test.cpp - Regression tests for shared_container_iterator. +// + + +#include "boost/shared_container_iterator.hpp" +#include "boost/shared_ptr.hpp" +#include <boost/core/lightweight_test.hpp> +#include <vector> + +struct resource { + static int count; + resource() { ++count; } + resource(resource const&) { ++count; } + ~resource() { --count; } +}; +int resource::count = 0; + +typedef std::vector<resource> resources_t; + +typedef boost::shared_container_iterator< resources_t > iterator; + + +void set_range(iterator& i, iterator& end) { + + boost::shared_ptr< resources_t > objs(new resources_t()); + + for (int j = 0; j != 6; ++j) + objs->push_back(resource()); + + i = iterator(objs->begin(),objs); + end = iterator(objs->end(),objs); + BOOST_TEST_EQ(resource::count, 6); +} + + +int main() { + + BOOST_TEST_EQ(resource::count, 0); + + { + iterator i; + { + iterator end; + set_range(i,end); + BOOST_TEST_EQ(resource::count, 6); + } + BOOST_TEST_EQ(resource::count, 6); + } + BOOST_TEST_EQ(resource::count, 0); + + return boost::report_errors(); +} diff --git a/src/boost/libs/iterator/test/static_assert_same.hpp b/src/boost/libs/iterator/test/static_assert_same.hpp new file mode 100644 index 000000000..6df0506ba --- /dev/null +++ b/src/boost/libs/iterator/test/static_assert_same.hpp @@ -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 diff --git a/src/boost/libs/iterator/test/transform_iterator_test.cpp b/src/boost/libs/iterator/test/transform_iterator_test.cpp new file mode 100644 index 000000000..b22cb161f --- /dev/null +++ b/src/boost/libs/iterator/test/transform_iterator_test.cpp @@ -0,0 +1,284 @@ +// (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/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(); +} diff --git a/src/boost/libs/iterator/test/unit_tests.cpp b/src/boost/libs/iterator/test/unit_tests.cpp new file mode 100644 index 000000000..656e72ffa --- /dev/null +++ b/src/boost/libs/iterator/test/unit_tests.cpp @@ -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; +} + diff --git a/src/boost/libs/iterator/test/zip_iterator_test.cpp b/src/boost/libs/iterator/test/zip_iterator_test.cpp new file mode 100644 index 000000000..08c4581e4 --- /dev/null +++ b/src/boost/libs/iterator/test/zip_iterator_test.cpp @@ -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" diff --git a/src/boost/libs/iterator/test/zip_iterator_test2_fusion_deque.cpp b/src/boost/libs/iterator/test/zip_iterator_test2_fusion_deque.cpp new file mode 100644 index 000000000..82d3b78a7 --- /dev/null +++ b/src/boost/libs/iterator/test/zip_iterator_test2_fusion_deque.cpp @@ -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" diff --git a/src/boost/libs/iterator/test/zip_iterator_test2_fusion_list.cpp b/src/boost/libs/iterator/test/zip_iterator_test2_fusion_list.cpp new file mode 100644 index 000000000..d410032e1 --- /dev/null +++ b/src/boost/libs/iterator/test/zip_iterator_test2_fusion_list.cpp @@ -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" diff --git a/src/boost/libs/iterator/test/zip_iterator_test2_fusion_vector.cpp b/src/boost/libs/iterator/test/zip_iterator_test2_fusion_vector.cpp new file mode 100644 index 000000000..d9400b023 --- /dev/null +++ b/src/boost/libs/iterator/test/zip_iterator_test2_fusion_vector.cpp @@ -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" diff --git a/src/boost/libs/iterator/test/zip_iterator_test2_std_tuple.cpp b/src/boost/libs/iterator/test/zip_iterator_test2_std_tuple.cpp new file mode 100644 index 000000000..95eff8704 --- /dev/null +++ b/src/boost/libs/iterator/test/zip_iterator_test2_std_tuple.cpp @@ -0,0 +1,21 @@ +#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 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 diff --git a/src/boost/libs/iterator/test/zip_iterator_test_fusion.cpp b/src/boost/libs/iterator/test/zip_iterator_test_fusion.cpp new file mode 100644 index 000000000..542fd8824 --- /dev/null +++ b/src/boost/libs/iterator/test/zip_iterator_test_fusion.cpp @@ -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" diff --git a/src/boost/libs/iterator/test/zip_iterator_test_std_pair.cpp b/src/boost/libs/iterator/test/zip_iterator_test_std_pair.cpp new file mode 100644 index 000000000..4353b6dc2 --- /dev/null +++ b/src/boost/libs/iterator/test/zip_iterator_test_std_pair.cpp @@ -0,0 +1,33 @@ +// 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> +#include <boost/config/workaround.hpp> +#include <boost/config/pragma_message.hpp> + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1600) + +BOOST_PRAGMA_MESSAGE("Skipping test on msvc-9.0 and below") +int main() {} + +#elif defined(BOOST_GCC) && __cplusplus < 201100 + +BOOST_PRAGMA_MESSAGE("Skipping test on g++ in C++03 mode") +int main() {} + +#else + +#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" + +#endif diff --git a/src/boost/libs/iterator/test/zip_iterator_test_std_tuple.cpp b/src/boost/libs/iterator/test/zip_iterator_test_std_tuple.cpp new file mode 100644 index 000000000..02d648d31 --- /dev/null +++ b/src/boost/libs/iterator/test/zip_iterator_test_std_tuple.cpp @@ -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 + |