Compare commits

...

57 Commits

Author SHA1 Message Date
Edward Diener
ed027c2cce Merge branch 'develop'
# Conflicts:
#	include/boost/iterator/reverse_iterator.hpp
2017-07-17 12:03:38 -04:00
Edward Diener
4791425000 Merge pull request #27 from Lastique/advance_generic_distance
Use a separate template parameter for distance in advance().
2017-07-12 12:20:34 -04:00
Edward Diener
b7e7e83a11 Merge pull request #28 from Lastique/patch-2
Avoid integer overflow on negating distance in reverse_iterator
2017-07-12 12:17:22 -04:00
Andrey Semashev
c148962bd9 Avoid integer overflow on negating distance 2017-07-10 14:57:40 +03:00
Andrey Semashev
5bfbfb7716 Use a separate template parameter for distance in advance().
This follows std::advance interface and also allows to use distance types
other than iterator's difference_type (if the iterator supports that).
2017-07-10 14:51:07 +03:00
Edward Diener
af5f6e49e0 Merge pull request #26 from Lastique/patch-2
Remove dependency on boost::prior.
2017-07-09 11:59:18 -04:00
Andrey Semashev
26ee5ba754 Remove dependency on boost::prior. 2017-07-09 18:31:06 +03:00
Edward Diener
67a2336cf4 Merge pull request #25 from morinmorin/add_readable_iterator_tests
Add more ReabableIterator tests for advance/distance
2017-07-09 11:14:04 -04:00
morinmorin
029277f3ed Add more tests for ReabableIterator 2017-07-08 13:30:28 +09:00
Edward Diener
847b2a1be3 Added Travis testing 2017-06-30 20:29:49 -04:00
Edward Diener
18268069d9 Merge pull request #24 from morinmorin/add_advance_and_distance
Add boost::advance and boost::distance
2017-06-29 15:02:38 -04:00
morinmorin
bb54ee7900 Update Jamfile.v2 for new tests 2017-06-29 22:49:05 +09:00
morinmorin
d5b67c7fab Add tests for boost::advance/distance 2017-06-29 22:09:26 +09:00
morinmorin
663a30f659 Implement BoostIteratorTraversalConcepts-aware boost::advance/distance 2017-06-29 22:06:12 +09:00
Edward Diener
177f719d15 Merge branch 'develop' 2017-04-24 12:24:21 -04:00
Edward Diener
cccbd8c6aa Test needs both std::typle support and variadic template support. 2017-04-08 16:53:02 -04:00
Edward Diener
d6cfed4b20 Merge pull request #23 from morinmorin/testcase_for_trac_12895
Testcase for PR #22 (trac ticket 12895)
2017-03-15 12:19:13 -04:00
Edward Diener
514ac53326 Merge pull request #22 from Dani-Hub/develop
Bug fix for ticket #12895: Apply remove_reference before remove_cv
2017-03-15 12:12:12 -04:00
morinmorin
ca3b7505ce Add a testcase for trac ticket 12895 2017-03-15 20:41:24 +09:00
drgler
d7c8cccd64 Bug fix for ticket #12895: Apply remove_reference before remove_cv 2017-03-14 20:45:48 +01:00
Edward Diener
7b627fa679 Merge branch 'develop' 2017-01-04 10:58:14 -05:00
Edward Diener
760da84f9c Merge branch 'develop' of https://github.com/eldiener/iterator into nekko1119-support-lambda-expression 2016-12-17 19:34:48 -05:00
Edward Diener
89d3ec7662 Add inclusion of config.hpp 2016-12-17 19:32:52 -05:00
Edward Diener
c86db2ec8a Merge branch 'support-lambda-expression' of https://github.com/nekko1119/iterator into nekko1119-support-lambda-expression 2016-12-16 04:22:44 -05:00
Edward Diener
0a18cfb255 Merge pull request #21 from Wilson-N/feature-bug-fix-8010
Remove incorrect documentation stating iterator_facade and iterator_a…
2016-12-01 08:53:05 -05:00
Edward Diener
11e3715f37 Updated to use unique_ptr instead of auto_ptr when appropriate. Removed unnecessary structs. 2016-11-07 14:01:19 -05:00
Rene Rivera
f2d07f76b5 Add, and update, documentation build targets. 2016-10-10 11:39:50 -05:00
Rene Rivera
53e8ac401f Add, and update, documentation build targets. 2016-10-07 23:07:34 -05:00
Nathan Wilson
434818cce7 Remove incorrect documentation stating iterator_facade and iterator_adapter had
been accepted into the TR1.

Fixes #8010
2016-01-27 22:22:55 -06:00
nekko1119
c09c8ca2b2 Support lambda expressions in function_input_iterator 2015-12-28 02:45:49 +09:00
Edward Diener
22dd100dfd Revert "Remove unused deprecated includes"
This reverts commit b2b9ab1568.
2015-10-15 23:55:35 -04:00
Edward Diener
2f72016049 Revert "Fix test compilation"
This reverts commit 443dfb9901.
2015-10-15 23:53:37 -04:00
Edward Diener
5b26a8b3fc Merge branch 'develop' 2015-10-14 23:59:55 -04:00
Edward Diener
711a0232f8 Merge pull request #19 from MarcelRaad/patch-1
Fix test compilation
2015-09-22 18:03:05 -07:00
Marcel Raad
443dfb9901 Fix test compilation
boost/iterator.hpp was implicitly dragged in via boost/operators.hpp, from which it was removed in cb6500161b. It's not needed anyway, all it does is map boost::iterator to std::iterator.
2015-09-22 00:33:50 +02:00
Edward Diener
c734f3bfa3 Merge pull request #18 from MarcelRaad/remove-deprecated-includes
Remove deprecated includes
2015-09-14 12:06:20 -04:00
Marcel Raad
b2b9ab1568 Remove unused deprecated includes
A comment in boost/iterator.hpp and boost/detail/iterator.hpp mentions that
the files are obsolete and will be deprecated. All they do is pull some types
from namespace std into namespace boost.
2015-09-14 14:28:38 +02:00
Edward Diener
8b23342969 Merge pull request #17 from boostorg/revert-16-remove-deprecated-includes
Revert "Remove unused deprecated includes"
2015-09-14 08:17:35 -04:00
Edward Diener
922296f8c8 Revert "Remove unused deprecated includes" 2015-09-14 08:16:43 -04:00
Edward Diener
c9a91a1fba Merge pull request #16 from MarcelRaad/remove-deprecated-includes
Remove unused deprecated includes
2015-09-14 08:08:53 -04:00
Marcel Raad
80e6f4a3bf Remove unused deprecated includes
A comment in boost/iterator.hpp and boost/detail/iterator.hpp mentions that
the files are obsolete and will be deprecated. All they do is pull some types
from namespace std into namespace boost.
2015-09-14 10:57:16 +02:00
Edward Diener
398bbe63bb Updated quickbook docs just fix problems exposed by upgrading to quickbook 1.6 2015-08-24 12:49:59 -04:00
Edward Diener
87d82527b1 Updated zip iterator abstract adds information about the iterator 'tuple'. 2015-08-24 07:18:03 -04:00
Edward Diener
b9448b5fae Updated with an explanation of the new 'tuple' type for a zip_iterator based on Boost fusion sequences. 2015-08-24 00:24:09 -04:00
Edward Diener
76519ea4a7 Merge branch 'Flast-pr/zip_iterator/fusionize' into develop 2015-08-23 23:56:13 -04:00
Edward Diener
878812c42f More tests with fusion sequence as tuple 2015-08-23 23:46:44 -04:00
Edward Diener
2283f084d9 Merge pull request #2 from Flast/pr/zip_iterator/fusionize
Fusion based zip_iterator, close #7526
2015-08-23 23:37:38 -04:00
Edward Diener
a0533d97f5 Merge branch 'pr/zip_iterator/fusionize' of https://github.com/Flast/iterator into Flast-pr/zip_iterator/fusionize 2015-08-21 22:09:37 -04:00
Kohei Takahashi
2511f21d62 Merge upstream branch 'develop' into pr/zip_iterator/fusionize 2014-08-25 00:36:36 +09:00
Kohei Takahashi
156c13a494 Merge upstream branch 'develop' into pr/zip_iterator/fusionize
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-07-12 15:57:03 +09:00
Kohei Takahashi
11f7d1bc18 Merge upstream branch 'develop' into pr/zip_iterator/fusionize
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-07-03 21:52:26 +09:00
Kohei Takahashi
aad767ed3f Merge upstream branch 'develop' into pr/zip_iterator/fusionize 2014-06-30 11:13:38 +09:00
Kohei Takahashi
9841d87212 Add tests for fusion based zip_iterator
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-14 15:59:31 +09:00
Kohei Takahashi
782313db8c Remove unnecessary specialization
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-14 15:59:31 +09:00
Kohei Takahashi
c040d4c38b make_zip_iterator should be inlined
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-14 15:59:31 +09:00
Kohei Takahashi
1ddaca8297 zip_iterator specialization for std::pair
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-14 15:59:31 +09:00
Kohei Takahashi
acf9b4d4cf Reimplement zip_iterator based on Boost.Fusion
By default, backward compatibility for Boost.Tuple is presented.

Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-12 01:05:36 +09:00
38 changed files with 1670 additions and 1242 deletions

40
.travis.yml Normal file
View File

@@ -0,0 +1,40 @@
# Copyright 2016 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
sudo: false
python: "2.7"
os:
- linux
- osx
branches:
only:
- master
- develop
install:
- cd ..
- git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init --depth 1 tools/build
- git submodule update --init --depth 1 libs/config
- git submodule update --init --depth 1 tools/boostdep
- cp -r $TRAVIS_BUILD_DIR/* libs/iterator
- python tools/boostdep/depinst/depinst.py iterator
- ./bootstrap.sh
- ./b2 headers
script:
- TOOLSET=gcc,clang
- if [ $TRAVIS_OS_NAME == osx ]; then TOOLSET=clang; fi
- ./b2 --verbose-test libs/config/test//config_info toolset=$TOOLSET || true
- ./b2 libs/iterator/test toolset=$TOOLSET
notifications:
email:
on_success: always

View File

@@ -20,4 +20,8 @@ boostbook standalone
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/iterator/doc
;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : standalone ;
explicit boostrelease ;

View File

@@ -115,8 +115,8 @@ __ iterator_facade.pdf
__ iterator_adaptor.pdf
Both |facade| and |adaptor| as well as many of the `specialized
adaptors`_ mentioned below have been proposed for standardization,
and accepted into the first C++ technical report; see our
adaptors`_ mentioned below have been proposed for standardization;
see our
`Standard Proposal For Iterator Facade and Adaptor`__ (PDF__)

View File

@@ -132,7 +132,7 @@ above are defined as follows:
iterator_adaptor();
[*Requires:] The `Base` type must be Default Constructible.\n
[*Requires:] The `Base` type must be Default Constructible.[br]
[*Returns:] An instance of `iterator_adaptor` with
`m_iterator` default constructed.
@@ -206,7 +206,7 @@ we're going to pick up right where it left off.
.. |fac_tut| replace:: `iterator_facade` tutorial
.. _fac_tut: iterator_facade.html#tutorial-example
[blurb [*`node_base*` really *is* an iterator]\n\n
[blurb [*`node_base*` really *is* an iterator][br][br]
It's not really a very interesting iterator, since `node_base`
is an abstract class: a pointer to a `node_base` just points
at some base subobject of an instance of some other class, and

View File

@@ -156,7 +156,7 @@ semantics.
[
[`++r`]
[`X&`]
[pre:\n`r` is dereferenceable;\npost:\n`r` is dereferenceable or\n`r` is past-the-end]
[pre:[br]`r` is dereferenceable;[br]post:[br]`r` is dereferenceable or[br]`r` is past-the-end]
]
[
[`a == b`]
@@ -227,7 +227,7 @@ the stated semantics.
[
[`--r`]
[`X&`]
[pre: there exists `s` such that `r == ++s`.\n post: `s` is dereferenceable. `--(++r) == r`. `--r == --s` implies `r == s`. `&r == &--r`.]
[pre: there exists `s` such that `r == ++s`.[br] post: `s` is dereferenceable. `--(++r) == r`. `--r == --s` implies `r == s`. `&r == &--r`.]
]
[
[`r--`]

View File

@@ -152,7 +152,7 @@ operations.
counting_iterator();
[*Requires: ] `Incrementable` is Default Constructible.\n
[*Requires: ] `Incrementable` is Default Constructible.[br]
[*Effects: ] Default construct the member `m_inc`.
@@ -174,13 +174,13 @@ operations.
counting_iterator& operator++();
[*Effects: ] `++m_inc`\n
[*Effects: ] `++m_inc`[br]
[*Returns: ] `*this`
counting_iterator& operator--();
[*Effects: ] `--m_inc`\n
[*Effects: ] `--m_inc`[br]
[*Returns: ] `*this`

View File

@@ -68,6 +68,7 @@ requirements.
[
[`i.dereference()`]
[Access the value referred to]
]
[
[`i.equal(j)`]
[Compare for equality with `j`]
@@ -83,6 +84,7 @@ requirements.
[
[`i.advance(n)`]
[Advance by `n` positions]
]
[
[`i.distance_to(j)`]
[Measure the distance to `j`]
@@ -487,7 +489,8 @@ w.m)` for some temporary object `w` of type `value_type`.
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
@@ -495,6 +498,7 @@ w.m)` for some temporary object `w` of type `value_type`.
Otherwise,
`((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@@ -505,6 +509,7 @@ w.m)` for some temporary object `w` of type `value_type`.
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
@@ -512,6 +517,7 @@ w.m)` for some temporary object `w` of type `value_type`.
Otherwise,
`!((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@@ -522,6 +528,7 @@ w.m)` for some temporary object `w` of type `value_type`.
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
@@ -529,6 +536,7 @@ w.m)` for some temporary object `w` of type `value_type`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@@ -539,6 +547,7 @@ w.m)` for some temporary object `w` of type `value_type`.
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
@@ -546,6 +555,7 @@ w.m)` for some temporary object `w` of type `value_type`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@@ -556,6 +566,7 @@ w.m)` for some temporary object `w` of type `value_type`.
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
@@ -563,6 +574,7 @@ w.m)` for some temporary object `w` of type `value_type`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@@ -573,6 +585,7 @@ w.m)` for some temporary object `w` of type `value_type`.
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
@@ -580,6 +593,7 @@ w.m)` for some temporary object `w` of type `value_type`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0`.
]
.. _minus:
@@ -592,6 +606,7 @@ w.m)` for some temporary object `w` of type `value_type`.
[*Return Type:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
@@ -600,9 +615,11 @@ w.m)` for some temporary object `w` of type `value_type`.
Otherwise
`difference` shall be `iterator_traits<Dr2>::difference_type`
]
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
@@ -610,6 +627,7 @@ w.m)` for some temporary object `w` of type `value_type`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)`.
]
[endsect]

View File

@@ -261,17 +261,17 @@ __ ../example/node_iterator1.cpp
[h2 A constant `node_iterator`]
[blurb *Constant and Mutable iterators*\n\n
[blurb *Constant and Mutable iterators*[br][br]
The term **mutable iterator** means an iterator through which
the object it references (its "referent") can be modified. A
**constant iterator** is one which doesn't allow modification of
its referent.\n\n
its referent.[br][br]
The words *constant* and *mutable* don't refer to the ability to
modify the iterator itself. For example, an `int const*` is a
non-\ `const` *constant iterator*, which can be incremented
but doesn't allow modification of its referent, and `int*
const` is a `const` *mutable iterator*, which cannot be
modified but which allows modification of its referent.\n\n
modified but which allows modification of its referent.[br][br]
Confusing? We agree, but those are the standard terms. It
probably doesn't help much that a container's constant iterator
is called `const_iterator`.
@@ -312,7 +312,7 @@ changes:
node_base **const**\ * m_node;
};
[blurb `const` and an iterator's `value_type`\n\n
[blurb `const` and an iterator's `value_type`[br][br]
The C++ standard requires an iterator's `value_type` *not* be
`const`\ -qualified, so `iterator_facade` strips the
`const` from its `Value` parameter in order to produce the

View File

@@ -178,7 +178,7 @@ operations.
filter_iterator();
[*Requires: ]`Predicate` and `Iterator` must be Default Constructible.\n
[*Requires: ]`Predicate` and `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs a `filter_iterator` whose`m_pred`, `m_iter`, and `m_end`
members are a default constructed.
@@ -195,7 +195,7 @@ operations.
filter_iterator(Iterator x, Iterator end = Iterator());
[*Requires: ] `Predicate` must be Default Constructible and
`Predicate` is a class type (not a function pointer).\n
`Predicate` is a class type (not a function pointer).[br]
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
the first position in the range `[x,end)` such that `m_pred(*m_iter) == true`
or else`m_iter == end`. The member `m_pred` is default constructed.
@@ -205,9 +205,9 @@ operations.
filter_iterator(
filter_iterator<Predicate, OtherIterator> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);`
);
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.\n
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs a filter iterator whose members are copied from `t`.
@@ -235,7 +235,7 @@ operations.
[*Effects: ] Increments `m_iter` and then continues to
increment `m_iter` until either `m_iter == m_end`
or `m_pred(*m_iter) == true`.\n
or `m_pred(*m_iter) == true`.[br]
[*Returns: ] `*this`

View File

@@ -203,7 +203,7 @@ following operations:
indirect_iterator();
[*Requires: ] `Iterator` must be Default Constructible.\n
[*Requires: ] `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs an instance of `indirect_iterator` with
a default-constructed `m_iterator`.
@@ -225,7 +225,7 @@ following operations:
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);
[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.\n
[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs an instance of `indirect_iterator` whose
`m_iterator` subobject is constructed from `y.base()`.
@@ -242,13 +242,13 @@ following operations:
indirect_iterator& operator++();
[*Effects: ] `++m_iterator`\n
[*Effects: ] `++m_iterator`[br]
[*Returns: ] `*this`
indirect_iterator& operator--();
[*Effects: ] `--m_iterator`\n
[*Effects: ] `--m_iterator`[br]
[*Returns: ] `*this`
[endsect]

View File

@@ -1,6 +1,7 @@
[library Boost.Iterator
[/ version 1.0.1]
[quickbook 1.6]
[authors [Abrahams, David], [Siek, Jeremy], [Witt, Thomas]]
[copyright 2003 2005 David Abrahams Jeremy Siek Thomas Witt]
[category iterator]
@@ -99,7 +100,7 @@ adaptors`_ mentioned below have been proposed for standardization
The iterator library supplies a useful suite of standard-conforming
iterator templates based on the Boost [link
intro.iterator_facade_and_adaptor iterator facade and adaptor]
iterator.intro.iterator_facade_and_adaptor iterator facade and adaptor]
templates.
[def _counting_ [@./counting_iterator.html `counting_iterator`]]

View File

@@ -189,7 +189,7 @@ following operations.
permutation_iterator& operator++();
[*Effects: ] `++m_order`\n
[*Effects: ] `++m_order`[br]
[*Returns: ] `*this`

View File

@@ -115,7 +115,7 @@ operations.
reverse_iterator();
[*Requires: ] `Iterator` must be Default Constructible.\n
[*Requires: ] `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator`
default constructed.
@@ -131,7 +131,7 @@ operations.
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.\n
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs instance of `reverse_iterator` whose
`m_iterator` subobject is constructed from `y.base()`.
@@ -149,12 +149,12 @@ operations.
reverse_iterator& operator++();
[*Effects: ] `--m_iterator`\n
[*Effects: ] `--m_iterator`[br]
[*Returns: ] `*this`
reverse_iterator& operator--();
[*Effects: ] `++m_iterator`\n
[*Effects: ] `++m_iterator`[br]
[*Returns: ] `*this`
[endsect]

View File

@@ -85,7 +85,7 @@ The source code for this example can be found
If `Reference` is `use_default` then the `reference` member of
`transform_iterator` is\n
`transform_iterator` is[br]
`result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
Otherwise, `reference` is `Reference`.
@@ -160,7 +160,7 @@ interoperable with `Y`.
[h3 Operations]
In addition to the operations required by the [link transform.concepts concepts] modeled by
In addition to the operations required by the [link iterator.specialized.transform.concepts concepts] modeled by
`transform_iterator`, `transform_iterator` provides the following
operations:
@@ -183,7 +183,7 @@ operations:
[*Returns: ] An instance of `transform_iterator` with `m_f`
initialized to `t.functor()` and `m_iterator` initialized to
`t.base()`.\n
`t.base()`.[br]
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.
@@ -204,13 +204,13 @@ operations:
transform_iterator& operator++();
[*Effects: ] `++m_iterator`\n
[*Effects: ] `++m_iterator`[br]
[*Returns: ] `*this`
transform_iterator& operator--();
[*Effects: ] `--m_iterator`\n
[*Effects: ] `--m_iterator`[br]
[*Returns: ] `*this`
[endsect]

View File

@@ -49,7 +49,7 @@ proxy references or return the pointee by value. When that
information is needed, call on `indirect_reference`.
Both of these templates are essential to the correct functioning of
[link boost_iterator.indirect `indirect_iterator`].
[link iterator.specialized.indirect `indirect_iterator`].
[h2 `minimum_category`]
@@ -103,9 +103,9 @@ or not), these additional tags are not considered.
if ( ++x is ill-formed )
{
return `Dereferenceable::element_type`
return Dereferenceable::element_type
}
else if (`*x` is a mutable reference to
else if (*x is a mutable reference to
std::iterator_traits<Dereferenceable>::value_type)
{
return iterator_traits<Dereferenceable>::value_type
@@ -135,7 +135,7 @@ or not), these additional tags are not considered.
`x` is an object of type `Dereferenceable`:
if ( ++x is ill-formed )
return `pointee<Dereferenceable>::type&`
return pointee<Dereferenceable>::type&
else
std::iterator_traits<Dereferenceable>::reference

View File

@@ -8,6 +8,16 @@ the zip iterator moves all the iterators in parallel.
Dereferencing the zip iterator returns a tuple that contains
the results of dereferencing the individual iterators.
The tuple of iterators is now implemented in terms of a Boost fusion sequence.
Because of this the 'tuple' may be any Boost fusion sequence and, for backwards
compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
Boost fusion adapter exists. This includes, among others, a std::tuple and a std::pair.
Just remember to include the appropriate Boost fusion adapter header files for these
other Boost fusion adapters. The zip_iterator header file already includes the
Boost fusion adapter header file for Boost tuple, so you need not include it yourself
to use a Boost tuple as your 'tuple'.
[section:zip_example Example]
There are two main types of applications of the `zip_iterator`. The first
@@ -218,7 +228,7 @@ operations.
, IteratorTuple>::type* = 0 // exposition only
);
[*Returns:] An instance of `zip_iterator` that is a copy of `other`.\n
[*Returns:] An instance of `zip_iterator` that is a copy of `other`.[br]
[*Requires:] `OtherIteratorTuple` is implicitly convertible to `IteratorTuple`.
@@ -235,13 +245,13 @@ operations.
zip_iterator& operator++();
[*Effects:] Increments each iterator in `m_iterator_tuple`.\n
[*Effects:] Increments each iterator in `m_iterator_tuple`.[br]
[*Returns:] `*this`
zip_iterator& operator--();
[*Effects:] Decrements each iterator in `m_iterator_tuple`.\n
[*Effects:] Decrements each iterator in `m_iterator_tuple`.[br]
[*Returns:] `*this`
template<typename IteratorTuple>

View File

@@ -8,3 +8,13 @@ iterator is constructed from a tuple of iterators. Moving
the zip iterator moves all the iterators in parallel.
Dereferencing the zip iterator returns a tuple that contains
the results of dereferencing the individual iterators.
The tuple of iterators is now implemented in terms of a Boost fusion sequence.
Because of this the 'tuple' may be any Boost fusion sequence and, for backwards
compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
Boost fusion adapter exists. This includes, among others, a std::tuple and a std::pair.
Just remember to include the appropriate Boost fusion adapter header files for these
other Boost fusion adapters. The zip_iterator header file already includes the
Boost fusion adapter header file for Boost tuple, so you need not include it yourself
to use a Boost tuple as your 'tuple'.

View File

@@ -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)
#ifndef BOOST_ITERATOR_ADVANCE_HPP
#define BOOST_ITERATOR_ADVANCE_HPP
#include <boost/config.hpp>
#include <boost/iterator/iterator_categories.hpp>
namespace boost {
namespace iterators {
namespace detail {
template <typename InputIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
InputIterator& it
, Distance n
, incrementable_traversal_tag
)
{
while (n > 0) {
++it;
--n;
}
}
template <typename BidirectionalIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
BidirectionalIterator& it
, Distance n
, bidirectional_traversal_tag
)
{
if (n >= 0) {
while (n > 0) {
++it;
--n;
}
}
else {
while (n < 0) {
--it;
++n;
}
}
}
template <typename RandomAccessIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
RandomAccessIterator& it
, Distance n
, random_access_traversal_tag
)
{
it += n;
}
}
namespace advance_adl_barrier {
template <typename InputIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance(InputIterator& it, Distance n)
{
detail::advance_impl(
it, n, typename iterator_traversal<InputIterator>::type()
);
}
}
using namespace advance_adl_barrier;
} // namespace iterators
using iterators::advance;
} // namespace boost
#endif

View File

@@ -0,0 +1,65 @@
// 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)
#ifndef BOOST_ITERATOR_DISTANCE_HPP
#define BOOST_ITERATOR_DISTANCE_HPP
#include <boost/config.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_traits.hpp>
namespace boost {
namespace iterators {
namespace detail {
template <typename SinglePassIterator>
inline BOOST_CXX14_CONSTEXPR typename iterator_difference<SinglePassIterator>::type
distance_impl(
SinglePassIterator first
, SinglePassIterator last
, single_pass_traversal_tag
)
{
typename iterator_difference<SinglePassIterator>::type n = 0;
while (first != last) {
++first;
++n;
}
return n;
}
template <typename RandomAccessIterator>
inline BOOST_CXX14_CONSTEXPR typename iterator_difference<RandomAccessIterator>::type
distance_impl(
RandomAccessIterator first
, RandomAccessIterator last
, random_access_traversal_tag
)
{
return last - first;
}
}
namespace distance_adl_barrier {
template <typename SinglePassIterator>
inline BOOST_CXX14_CONSTEXPR typename iterator_difference<SinglePassIterator>::type
distance(SinglePassIterator first, SinglePassIterator last)
{
return detail::distance_impl(
first, last, typename iterator_traversal<SinglePassIterator>::type()
);
}
}
using namespace distance_adl_barrier;
} // namespace iterators
using iterators::distance;
} // namespace boost
#endif

View File

@@ -9,6 +9,7 @@
#ifndef BOOST_FUNCTION_INPUT_ITERATOR
#define BOOST_FUNCTION_INPUT_ITERATOR
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/mpl/if.hpp>
#include <boost/function_types/is_function_pointer.hpp>
@@ -17,6 +18,7 @@
#include <boost/iterator/iterator_facade.hpp>
#include <boost/none.hpp>
#include <boost/optional/optional.hpp>
#include <boost/utility/result_of.hpp>
namespace boost {
@@ -28,9 +30,9 @@ namespace iterators {
class function_input_iterator
: public iterator_facade<
function_input_iterator<Function, Input>,
typename Function::result_type,
BOOST_DEDUCED_TYPENAME result_of<Function ()>::type,
single_pass_traversal_tag,
typename Function::result_type const &
BOOST_DEDUCED_TYPENAME result_of<Function ()>::type const &
>
{
public:
@@ -46,7 +48,7 @@ namespace iterators {
++state;
}
typename Function::result_type const &
BOOST_DEDUCED_TYPENAME result_of<Function ()>::type const &
dereference() const {
return (value ? value : value = (*f)()).get();
}
@@ -58,7 +60,7 @@ namespace iterators {
private:
Function * f;
Input state;
mutable optional<typename Function::result_type> value;
mutable optional<BOOST_DEDUCED_TYPENAME result_of<Function ()>::type> value;
};
template <class Function, class Input>

View File

@@ -7,7 +7,6 @@
#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
#include <boost/next_prior.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
@@ -40,14 +39,19 @@ namespace iterators {
{}
private:
typename super_t::reference dereference() const { return *boost::prior(this->base()); }
typename super_t::reference dereference() const
{
Iterator it = this->base_reference();
--it;
return *it;
}
void increment() { --this->base_reference(); }
void decrement() { ++this->base_reference(); }
void advance(typename super_t::difference_type n)
{
this->base_reference() += -n;
this->base_reference() -= n;
}
template <class OtherIterator>

View File

@@ -1,6 +1,8 @@
// Copyright David Abrahams and Thomas Becker 2000-2006. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// Copyright David Abrahams and Thomas Becker 2000-2006.
// Copyright Kohei Takahashi 2012-2014.
//
// 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 BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
@@ -12,19 +14,26 @@
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
#include <boost/iterator/iterator_categories.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/iterator/minimum_category.hpp>
#include <boost/tuple/tuple.hpp>
#include <utility> // for std::pair
#include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/algorithm/transformation/transform.hpp>
#include <boost/fusion/sequence/convert.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#include <boost/fusion/sequence/comparison/equal_to.hpp>
#include <boost/fusion/support/tag_of_fwd.hpp>
namespace boost {
namespace iterators {
@@ -33,24 +42,6 @@ namespace iterators {
template<typename IteratorTuple>
class zip_iterator;
// One important design goal of the zip_iterator is to isolate all
// functionality whose implementation relies on the current tuple
// implementation. This goal has been achieved as follows: Inside
// the namespace detail there is a namespace tuple_impl_specific.
// This namespace encapsulates all functionality that is specific
// to the current Boost tuple implementation. More precisely, the
// namespace tuple_impl_specific provides the following tuple
// algorithms and meta-algorithms for the current Boost tuple
// implementation:
//
// tuple_meta_transform
// tuple_meta_accumulate
// tuple_transform
// tuple_for_each
//
// If the tuple implementation changes, all that needs to be
// replaced is the implementation of these four (meta-)algorithms.
namespace detail
{
@@ -73,313 +64,96 @@ namespace iterators {
struct increment_iterator
{
template<typename Iterator>
void operator()(Iterator& it)
void operator()(Iterator& it) const
{ ++it; }
};
//
struct decrement_iterator
{
template<typename Iterator>
void operator()(Iterator& it)
void operator()(Iterator& it) const
{ --it; }
};
//
struct dereference_iterator
{
template<typename Iterator>
struct apply
template<typename>
struct result;
template<typename This, typename Iterator>
struct result<This(Iterator)>
{
typedef typename
boost::detail::iterator_traits<Iterator>::reference
type;
remove_cv<typename remove_reference<Iterator>::type>::type
iterator;
typedef typename iterator_reference<iterator>::type type;
};
template<typename Iterator>
typename apply<Iterator>::type operator()(Iterator const& it)
typename result<dereference_iterator(Iterator)>::type
operator()(Iterator const& it) const
{ return *it; }
};
// The namespace tuple_impl_specific provides two meta-
// algorithms and two algorithms for tuples.
//
namespace tuple_impl_specific
{
// Meta-transform algorithm for tuples
//
template<typename Tuple, class UnaryMetaFun>
struct tuple_meta_transform;
template<typename Tuple, class UnaryMetaFun>
struct tuple_meta_transform_impl
{
typedef tuples::cons<
typename mpl::apply1<
typename mpl::lambda<UnaryMetaFun>::type
, typename Tuple::head_type
>::type
, typename tuple_meta_transform<
typename Tuple::tail_type
, UnaryMetaFun
>::type
> type;
};
template<typename Tuple, class UnaryMetaFun>
struct tuple_meta_transform
: mpl::eval_if<
boost::is_same<Tuple, tuples::null_type>
, mpl::identity<tuples::null_type>
, tuple_meta_transform_impl<Tuple, UnaryMetaFun>
>
{
};
// Meta-accumulate algorithm for tuples. Note: The template
// parameter StartType corresponds to the initial value in
// ordinary accumulation.
//
template<class Tuple, class BinaryMetaFun, class StartType>
struct tuple_meta_accumulate;
template<
typename Tuple
, class BinaryMetaFun
, typename StartType
>
struct tuple_meta_accumulate_impl
{
typedef typename mpl::apply2<
typename mpl::lambda<BinaryMetaFun>::type
, typename Tuple::head_type
, typename tuple_meta_accumulate<
typename Tuple::tail_type
, BinaryMetaFun
, StartType
>::type
>::type type;
};
template<
typename Tuple
, class BinaryMetaFun
, typename StartType
>
struct tuple_meta_accumulate
: mpl::eval_if<
boost::is_same<Tuple, tuples::null_type>
, mpl::identity<StartType>
, tuple_meta_accumulate_impl<
Tuple
, BinaryMetaFun
, StartType
>
>
{
};
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|| ( \
BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, != 0) && defined(_MSC_VER) \
)
// Not sure why intel's partial ordering fails in this case, but I'm
// assuming int's an MSVC bug-compatibility feature.
# define BOOST_TUPLE_ALGO_DISPATCH
# define BOOST_TUPLE_ALGO(algo) algo##_impl
# define BOOST_TUPLE_ALGO_TERMINATOR , int
# define BOOST_TUPLE_ALGO_RECURSE , ...
#else
# define BOOST_TUPLE_ALGO(algo) algo
# define BOOST_TUPLE_ALGO_TERMINATOR
# define BOOST_TUPLE_ALGO_RECURSE
#endif
// transform algorithm for tuples. The template parameter Fun
// must be a unary functor which is also a unary metafunction
// class that computes its return type based on its argument
// type. For example:
//
// struct to_ptr
// {
// template <class Arg>
// struct apply
// {
// typedef Arg* type;
// }
//
// template <class Arg>
// Arg* operator()(Arg x);
// };
template<typename Fun>
inline tuples::null_type BOOST_TUPLE_ALGO(tuple_transform)
(tuples::null_type const&, Fun BOOST_TUPLE_ALGO_TERMINATOR)
{ return tuples::null_type(); }
template<typename Tuple, typename Fun>
inline typename tuple_meta_transform<
Tuple
, Fun
>::type
BOOST_TUPLE_ALGO(tuple_transform)(
const Tuple& t,
Fun f
BOOST_TUPLE_ALGO_RECURSE
)
{
typedef typename tuple_meta_transform<
BOOST_DEDUCED_TYPENAME Tuple::tail_type
, Fun
>::type transformed_tail_type;
return tuples::cons<
BOOST_DEDUCED_TYPENAME mpl::apply1<
Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type
>::type
, transformed_tail_type
>(
f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f)
);
}
#ifdef BOOST_TUPLE_ALGO_DISPATCH
template<typename Tuple, typename Fun>
inline typename tuple_meta_transform<
Tuple
, Fun
>::type
tuple_transform(
const Tuple& t,
Fun f
)
{
return tuple_transform_impl(t, f, 1);
}
#endif
// for_each algorithm for tuples.
//
template<typename Fun>
inline Fun BOOST_TUPLE_ALGO(tuple_for_each)(
tuples::null_type
, Fun f BOOST_TUPLE_ALGO_TERMINATOR
)
{ return f; }
template<typename Tuple, typename Fun>
inline Fun BOOST_TUPLE_ALGO(tuple_for_each)(
Tuple& t
, Fun f BOOST_TUPLE_ALGO_RECURSE)
{
f( t.get_head() );
return tuple_for_each(t.get_tail(), f);
}
#ifdef BOOST_TUPLE_ALGO_DISPATCH
template<typename Tuple, typename Fun>
inline Fun
tuple_for_each(
Tuple& t,
Fun f
)
{
return tuple_for_each_impl(t, f, 1);
}
#endif
// Equality of tuples. NOTE: "==" for tuples currently (7/2003)
// has problems under some compilers, so I just do my own.
// No point in bringing in a bunch of #ifdefs here. This is
// going to go away with the next tuple implementation anyway.
//
inline bool tuple_equal(tuples::null_type, tuples::null_type)
{ return true; }
template<typename Tuple1, typename Tuple2>
inline bool tuple_equal(Tuple1 const& t1, Tuple2 const& t2)
{
return t1.get_head() == t2.get_head() &&
tuple_equal(t1.get_tail(), t2.get_tail());
}
}
//
// end namespace tuple_impl_specific
template<typename Iterator>
struct iterator_reference
{
typedef typename boost::detail::iterator_traits<Iterator>::reference type;
};
#ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. Instantiating the nested apply template also
// requires instantiating iterator_traits on the
// placeholder. Instead we just specialize it as a metafunction
// class.
template<>
struct iterator_reference<mpl::_1>
{
template <class T>
struct apply : iterator_reference<T> {};
};
#endif
// Metafunction to obtain the type of the tuple whose element types
// are the reference types of an iterator tuple.
//
template<typename IteratorTuple>
struct tuple_of_references
: tuple_impl_specific::tuple_meta_transform<
: mpl::transform<
IteratorTuple,
iterator_reference<mpl::_1>
>
{
};
// Specialization for std::pair
template<typename Iterator1, typename Iterator2>
struct tuple_of_references<std::pair<Iterator1, Iterator2> >
{
typedef std::pair<
typename iterator_reference<Iterator1>::type
, typename iterator_reference<Iterator2>::type
> type;
};
// Metafunction to obtain the minimal traversal tag in a tuple
// of iterators.
//
template<typename IteratorTuple>
struct minimum_traversal_category_in_iterator_tuple
{
typedef typename tuple_impl_specific::tuple_meta_transform<
typedef typename mpl::transform<
IteratorTuple
, pure_traversal_tag<iterator_traversal<> >
>::type tuple_of_traversal_tags;
typedef typename tuple_impl_specific::tuple_meta_accumulate<
typedef typename mpl::fold<
tuple_of_traversal_tags
, minimum_category<>
, random_access_traversal_tag
, minimum_category<>
>::type type;
};
// We need to call tuple_meta_accumulate with mpl::and_ as the
// accumulating functor. To this end, we need to wrap it into
// a struct that has exactly two arguments (that is, template
// parameters) and not five, like mpl::and_ does.
//
template<typename Arg1, typename Arg2>
struct and_with_two_args
: mpl::and_<Arg1, Arg2>
{
};
template<typename Iterator1, typename Iterator2>
struct minimum_traversal_category_in_iterator_tuple<std::pair<Iterator1, Iterator2> >
{
typedef typename pure_traversal_tag<
typename iterator_traversal<Iterator1>::type
>::type iterator1_traversal;
typedef typename pure_traversal_tag<
typename iterator_traversal<Iterator2>::type
>::type iterator2_traversal;
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. In this case I think it's an MPL bug
template<>
struct and_with_two_args<mpl::_1,mpl::_2>
{
template <class A1, class A2>
struct apply : mpl::and_<A1,A2>
{};
};
# endif
typedef typename minimum_category<
iterator1_traversal
, typename minimum_category<
iterator2_traversal
, random_access_traversal_tag
>::type
>::type type;
};
///////////////////////////////////////////////////////////////////
//
@@ -401,9 +175,9 @@ namespace iterators {
typedef reference value_type;
// Difference type is the first iterator's difference type
typedef typename boost::detail::iterator_traits<
typename tuples::element<0, IteratorTuple>::type
>::difference_type difference_type;
typedef typename iterator_difference<
typename mpl::at_c<IteratorTuple, 0>::type
>::type difference_type;
// Traversal catetgory is the minimum traversal category in the
// iterator tuple.
@@ -429,6 +203,30 @@ namespace iterators {
{
typedef int type;
};
template <typename reference>
struct converter
{
template <typename Seq>
static reference call(Seq seq)
{
typedef typename fusion::traits::tag_of<reference>::type tag;
return fusion::convert<tag>(seq);
}
};
template <typename Reference1, typename Reference2>
struct converter<std::pair<Reference1, Reference2> >
{
typedef std::pair<Reference1, Reference2> reference;
template <typename Seq>
static reference call(Seq seq)
{
return reference(
fusion::at_c<0>(seq)
, fusion::at_c<1>(seq));
}
};
}
/////////////////////////////////////////////////////////////////////
@@ -484,10 +282,11 @@ namespace iterators {
// iterators in the iterator tuple.
typename super_t::reference dereference() const
{
return detail::tuple_impl_specific::tuple_transform(
get_iterator_tuple(),
detail::dereference_iterator()
);
typedef typename super_t::reference reference;
typedef detail::converter<reference> gen;
return gen::call(fusion::transform(
get_iterator_tuple(),
detail::dereference_iterator()));
}
// Two zip iterators are equal if all iterators in the iterator
@@ -503,39 +302,35 @@ namespace iterators {
template<typename OtherIteratorTuple>
bool equal(const zip_iterator<OtherIteratorTuple>& other) const
{
return detail::tuple_impl_specific::tuple_equal(
get_iterator_tuple(),
other.get_iterator_tuple()
);
return fusion::equal_to(
get_iterator_tuple(),
other.get_iterator_tuple());
}
// Advancing a zip iterator means to advance all iterators in the
// iterator tuple.
void advance(typename super_t::difference_type n)
{
detail::tuple_impl_specific::tuple_for_each(
fusion::for_each(
m_iterator_tuple,
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)
);
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n));
}
// Incrementing a zip iterator means to increment all iterators in
// the iterator tuple.
void increment()
{
detail::tuple_impl_specific::tuple_for_each(
m_iterator_tuple,
detail::increment_iterator()
);
fusion::for_each(
m_iterator_tuple,
detail::increment_iterator());
}
// Decrementing a zip iterator means to decrement all iterators in
// the iterator tuple.
void decrement()
{
detail::tuple_impl_specific::tuple_for_each(
m_iterator_tuple,
detail::decrement_iterator()
);
fusion::for_each(
m_iterator_tuple,
detail::decrement_iterator());
}
// Distance is calculated using the first iterator in the tuple.
@@ -544,8 +339,8 @@ namespace iterators {
const zip_iterator<OtherIteratorTuple>& other
) const
{
return boost::tuples::get<0>(other.get_iterator_tuple()) -
boost::tuples::get<0>(this->get_iterator_tuple());
return fusion::at_c<0>(other.get_iterator_tuple()) -
fusion::at_c<0>(this->get_iterator_tuple());
}
// Data Members

View File

@@ -14,11 +14,17 @@ test-suite iterator
[ 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 ]
@@ -49,4 +55,7 @@ test-suite iterator
[ run minimum_category.cpp ]
[ compile-fail minimum_category_compile_fail.cpp ]
[ run advance_test.cpp ]
[ run distance_test.cpp ]
;

91
test/advance_test.cpp Normal file
View File

@@ -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();
}

View File

@@ -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/detail/lightweight_test.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/iterator/zip_iterator.hpp>
#include <vector>
#include <string>
int main()
{
typedef TUPLE<
std::vector<int>::iterator,
std::vector<std::string>::iterator
> iterator_tuple;
std::vector<int> vi = boost::assign::list_of(42)(72);
std::vector<std::string> vs = boost::assign::list_of("kokoro")("pyonpyon");
{
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
boost::zip_iterator<iterator_tuple> i2 = i1;
BOOST_TEST( i1 == i2);
BOOST_TEST( i1++ == i2);
BOOST_TEST( i1 == (i2 + 1));
BOOST_TEST((i1 - 1) == i2);
BOOST_TEST( i1-- == ++i2);
BOOST_TEST( i1 == --i2);
}
{
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
boost::zip_iterator<iterator_tuple> i2 = i1 + 1;
BOOST_TEST( i1 != i2);
BOOST_TEST( i1++ != i2);
BOOST_TEST( i1 != (i2 + 1));
BOOST_TEST((i1 - 1) != i2);
BOOST_TEST( i1-- != ++i2);
BOOST_TEST( i1 != --i2);
}
{
boost::zip_iterator<iterator_tuple> i(MAKE_TUPLE(vi.begin(), vs.begin()));
BOOST_TEST(boost::fusion::at_c<0>(* i ) == 42);
BOOST_TEST(boost::fusion::at_c<1>(* i ) == "kokoro");
BOOST_TEST(boost::fusion::at_c<0>(*(i + 1)) == 72);
BOOST_TEST(boost::fusion::at_c<1>(*(i + 1)) == "pyonpyon");
}
{
// Trac #12895
boost::zip_iterator<
TUPLE<int*, std::string*>
> i(MAKE_TUPLE(vi.data(), vs.data()));
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();
}

View File

@@ -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;
}

84
test/distance_test.cpp Normal file
View File

@@ -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();
}

View File

@@ -11,6 +11,7 @@
#include <iterator>
#include <vector>
#include <boost/config.hpp>
#include <boost/iterator/function_input_iterator.hpp>
namespace {
@@ -96,6 +97,23 @@ int main(int argc, char * argv[])
assert(generated[i] == 42 + i);
cout << "function iterator test with stateful function object successful." << endl;
#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
// 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)
);
assert(generated.size() == 10);
for(std::size_t i = 0; i != 10; ++i)
assert(generated[i] == 42 + i);
cout << "function iterator test with lambda expressions successful." << endl;
#endif // BOOST_NO_CXX11_LAMBDAS
return 0;
}

View File

@@ -33,37 +33,6 @@
using boost::dummyT;
struct mult_functor {
typedef int result_type;
typedef int argument_type;
// Functors used with transform_iterator must be
// DefaultConstructible, as the transform_iterator must be
// DefaultConstructible to satisfy the requirements for
// TrivialIterator.
mult_functor() { }
mult_functor(int aa) : a(aa) { }
int operator()(int b) const { return a * b; }
int a;
};
template <class Pair>
struct select1st_
: public std::unary_function<Pair, typename Pair::first_type>
{
const typename Pair::first_type& operator()(const Pair& x) const {
return x.first;
}
typename Pair::first_type& operator()(Pair& x) const {
return x.first;
}
};
struct one_or_four {
bool operator()(dummyT x) const {
return x.foo() == 1 || x.foo() == 4;
}
};
typedef std::deque<int> storage;
typedef std::deque<int*> pointer_deque;
typedef std::set<storage::iterator> iterator_set;

View File

@@ -56,12 +56,24 @@ int main()
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);

View File

@@ -1,850 +1,8 @@
// (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/tuple/tuple.hpp>
#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>
#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
/// 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(
boost::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<
boost::tuples::tuple<
std::set<int>::iterator
, std::vector<double>::iterator
>
> zit_mixed;
zit_mixed zip_it_mixed = zit_mixed(
boost::make_tuple(
intset.begin()
, vect1.begin()
)
);
boost::tuples::tuple<int, double> val_tuple(
*zip_it_mixed);
boost::tuples::tuple<const int&, double&> ref_tuple(
*zip_it_mixed);
double dblOldVal = boost::tuples::get<1>(ref_tuple);
boost::tuples::get<1>(ref_tuple) -= 41.;
if( 52 == boost::tuples::get<0>(val_tuple) &&
42. == boost::tuples::get<1>(val_tuple) &&
52 == boost::tuples::get<0>(ref_tuple) &&
1. == boost::tuples::get<1>(ref_tuple) &&
1. == *vect1.begin()
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
// Undo change to vect1
boost::tuples::get<1>(ref_tuple) = dblOldVal;
/////////////////////////////////////////////////////////////////////////////
//
// 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,
boost::tuples::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&,
boost::tuples::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(),
boost::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);
boost::tuples::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( boost::tuples::get<11>(zip_it_12.get_iterator_tuple()) == ve4.begin() &&
boost::tuples::get<11>(zip_it_12_copy.get_iterator_tuple()) == ve4.end() &&
1 == boost::tuples::get<0>(zip_it_12_dereferenced) &&
12 == boost::tuples::get<11>(zip_it_12_dereferenced) &&
42 == *(li4.begin())
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// 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<
boost::tuples::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_begin(
boost::make_tuple(
vect1.begin(),
vect2.begin()
)
);
boost::zip_iterator<
boost::tuples::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_run(
boost::make_tuple(
vect1.begin(),
vect2.begin()
)
);
boost::zip_iterator<
boost::tuples::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_end(
boost::make_tuple(
vect1.end(),
vect2.end()
)
);
if( zip_it_run == zip_it_begin &&
42. == boost::tuples::get<0>(*zip_it_run) &&
2.2 == boost::tuples::get<1>(*zip_it_run) &&
43. == boost::tuples::get<0>(*(++zip_it_run)) &&
3.3 == boost::tuples::get<1>(*zip_it_run) &&
44. == boost::tuples::get<0>(*(++zip_it_run)) &&
4.4 == boost::tuples::get<1>(*zip_it_run) &&
zip_it_end == ++zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
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. == boost::tuples::get<0>(*zip_it_run) &&
4.4 == boost::tuples::get<1>(*zip_it_run) &&
43. == boost::tuples::get<0>(*(--zip_it_run)) &&
3.3 == boost::tuples::get<1>(*zip_it_run) &&
42. == boost::tuples::get<0>(*(--zip_it_run)) &&
2.2 == boost::tuples::get<1>(*zip_it_run) &&
zip_it_begin == zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
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<
boost::tuples::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 = 0;
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 = 0;
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 = 0;
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 = 0;
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 = 0;
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 = 0;
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 = 0;
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 = 0;
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 = 0;
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 = 0;
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( boost::tuples::get<0>(zip_it_run.get_iterator_tuple()) == vect1.begin() + 1 &&
boost::tuples::get<1>(zip_it_run.get_iterator_tuple()) == vect2.begin() + 1
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Making zip iterators
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Making zip iterators: "
<< std::flush;
std::vector<boost::tuples::tuple<double, double> >
vect_of_tuples(3);
std::copy(
boost::make_zip_iterator(
boost::make_tuple(
vect1.begin(),
vect2.begin()
)
),
boost::make_zip_iterator(
boost::make_tuple(
vect1.end(),
vect2.end()
)
),
vect_of_tuples.begin()
);
if( 42. == boost::tuples::get<0>(*vect_of_tuples.begin()) &&
2.2 == boost::tuples::get<1>(*vect_of_tuples.begin()) &&
43. == boost::tuples::get<0>(*(vect_of_tuples.begin() + 1)) &&
3.3 == boost::tuples::get<1>(*(vect_of_tuples.begin() + 1)) &&
44. == boost::tuples::get<0>(*(vect_of_tuples.begin() + 2)) &&
4.4 == boost::tuples::get<1>(*(vect_of_tuples.begin() + 2))
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
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<
boost::tuples::tuple<
std::set<int>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_const(
boost::make_tuple(
intset.begin(),
vect2.begin()
)
);
//
boost::zip_iterator<
boost::tuples::tuple<
std::set<int>::iterator,
std::vector<double>::const_iterator
>
>
zip_it_half_const(
boost::make_tuple(
intset.begin(),
vect2.begin()
)
);
//
boost::zip_iterator<
boost::tuples::tuple<
std::set<int>::iterator,
std::vector<double>::iterator
>
>
zip_it_non_const(
boost::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 == boost::tuples::get<0>(*zip_it_const) &&
4.4 == boost::tuples::get<1>(*zip_it_const) &&
53 == boost::tuples::get<0>(*zip_it_half_const) &&
3.3 == boost::tuples::get<1>(*zip_it_half_const)
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests = 0;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// 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<
boost::tuples::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 = 0;
std::cout << "not OK" << std::endl;
}
// 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;
}
#include "detail/zip_iterator_test_original.ipp"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -0,0 +1,16 @@
// Copyright (c) 2014 Kohei Takahashi.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for most recent version including documentation.
#include <utility>
#include <boost/fusion/adapted/std_pair.hpp>
#define TUPLE std::pair
#define MAKE_TUPLE std::make_pair
#include "detail/zip_iterator_test.ipp"

View File

@@ -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