mirror of
https://github.com/boostorg/iterator.git
synced 2025-06-27 21:11:02 +02:00
Compare commits
251 Commits
svn-branch
...
boost-1.65
Author | SHA1 | Date | |
---|---|---|---|
ed027c2cce | |||
4791425000 | |||
b7e7e83a11 | |||
c148962bd9 | |||
5bfbfb7716 | |||
af5f6e49e0 | |||
26ee5ba754 | |||
67a2336cf4 | |||
029277f3ed | |||
847b2a1be3 | |||
18268069d9 | |||
bb54ee7900 | |||
d5b67c7fab | |||
663a30f659 | |||
177f719d15 | |||
cccbd8c6aa | |||
d6cfed4b20 | |||
514ac53326 | |||
ca3b7505ce | |||
d7c8cccd64 | |||
7b627fa679 | |||
760da84f9c | |||
89d3ec7662 | |||
c86db2ec8a | |||
0a18cfb255 | |||
11e3715f37 | |||
f2d07f76b5 | |||
53e8ac401f | |||
434818cce7 | |||
c09c8ca2b2 | |||
22dd100dfd | |||
2f72016049 | |||
5b26a8b3fc | |||
711a0232f8 | |||
443dfb9901 | |||
c734f3bfa3 | |||
b2b9ab1568 | |||
8b23342969 | |||
922296f8c8 | |||
c9a91a1fba | |||
80e6f4a3bf | |||
398bbe63bb | |||
87d82527b1 | |||
b9448b5fae | |||
76519ea4a7 | |||
878812c42f | |||
2283f084d9 | |||
a0533d97f5 | |||
ece225bbda | |||
b62dc6ba9d | |||
20dc7b1abe | |||
0dbbb61bec | |||
2de2111db2 | |||
db04fafe21 | |||
4e0fc90b60 | |||
53cbba6c09 | |||
8be623d733 | |||
d12d60fa12 | |||
ec7d398578 | |||
3d3560c12d | |||
46f9e1753f | |||
2511f21d62 | |||
adee905c51 | |||
82779f78ec | |||
a569c97969 | |||
aad821d28d | |||
23934d7c0d | |||
1073b7f7bc | |||
f158dba6ad | |||
8fe632d6b1 | |||
810b58cfb0 | |||
156c13a494 | |||
785680d929 | |||
269de2691a | |||
11f7d1bc18 | |||
4a403cd3eb | |||
dc96d371fa | |||
e000b676cc | |||
045a05f81f | |||
25139e1311 | |||
aad767ed3f | |||
7fa65a4278 | |||
fd94cc7d78 | |||
36988fcf98 | |||
4283d20261 | |||
91f782ec52 | |||
9841d87212 | |||
782313db8c | |||
c040d4c38b | |||
1ddaca8297 | |||
acf9b4d4cf | |||
e88b3f475c | |||
01cffbed98 | |||
187bc896f6 | |||
6883d083d2 | |||
0345db959b | |||
d814423414 | |||
eb288b2908 | |||
0e23f15623 | |||
6b2a5cccc4 | |||
a803b5b42d | |||
d8284fa602 | |||
8d96469cb4 | |||
09549a613e | |||
daac0f2ab1 | |||
8e5b8025d8 | |||
c142956936 | |||
21afa3d8ec | |||
2d9362fe89 | |||
8779e0e715 | |||
3546643667 | |||
70ac888f75 | |||
854d39f58a | |||
7bb83d4646 | |||
bb27f3ee25 | |||
96d2e9638c | |||
f2137c58b7 | |||
0dfc7bd53c | |||
ae1d0d0dfe | |||
9ddc974825 | |||
1cde579a68 | |||
73ccc2bac0 | |||
9b13de9bfe | |||
35cf24d413 | |||
a83b13f4e6 | |||
c6f70f8394 | |||
0b33da51dd | |||
39c44e0da3 | |||
d1c93d3574 | |||
208400a1d0 | |||
dae3cf2a9d | |||
0c44051189 | |||
4fcb23f8e0 | |||
8a004c12f6 | |||
3695e48b68 | |||
ac3a206eb9 | |||
f9095485a2 | |||
1c4527d58e | |||
455a039c33 | |||
5d7289ad3e | |||
40fd24e5b5 | |||
290cea8289 | |||
e6babb8bf9 | |||
84cd6e1be4 | |||
2325b6070a | |||
91b2854e4a | |||
27b44876bc | |||
123bf514ac | |||
ac7b14253f | |||
69df402f70 | |||
e600d3f65b | |||
f6e5aa2462 | |||
21102938e8 | |||
a1c0cf8373 | |||
220a11883c | |||
913df78ec0 | |||
01f9b396d8 | |||
67d418a5c6 | |||
d853e444ce | |||
e6d5c24b91 | |||
98db5b4f9a | |||
739c95411f | |||
8ce330a111 | |||
3eef8090d6 | |||
d291c7b43e | |||
1471102bfc | |||
2e099caceb | |||
3fd1c34411 | |||
dec42098db | |||
d4d51389d1 | |||
4a82a5646f | |||
fecf28a440 | |||
bc34e54f6c | |||
f543f1e7b6 | |||
9f661c9112 | |||
04bc178fc1 | |||
1b2fbfaaca | |||
a6a8fd00d7 | |||
30a13b8141 | |||
db29a874f1 | |||
8345293f94 | |||
512298cb5c | |||
6d0b2d4f8a | |||
7dbd0f5a89 | |||
c9463e941f | |||
1ce1296320 | |||
9025bbfc2a | |||
c6f3269f4a | |||
31c3971720 | |||
2db78eec90 | |||
c7fc3470d0 | |||
ad90dac61d | |||
964a29979c | |||
fbbdcf8c99 | |||
5d72ae48da | |||
1ca1caddff | |||
5c477dc695 | |||
d45b57c33c | |||
caa0e5035a | |||
5a88e6f958 | |||
36565eae63 | |||
14b1075d6b | |||
752fc7c185 | |||
de4ef14f9b | |||
15f3bf9352 | |||
d469568de7 | |||
251b9f8057 | |||
2786268510 | |||
6bb82230b9 | |||
f65f03afcc | |||
c07f55ff65 | |||
ac522bc9e1 | |||
4c60e26bf8 | |||
d11c7a3ec4 | |||
cfc04ce11e | |||
76fd8e27fb | |||
25d4d34ebe | |||
ea26e9f109 | |||
f2433c63d5 | |||
264c186eac | |||
55c08b706c | |||
835498603d | |||
b0ec5a759b | |||
2ece3ac5c2 | |||
e06c4b3279 | |||
78effefadb | |||
37c46f7da5 | |||
6d0f901b2e | |||
db0e0b7b91 | |||
23d53055f9 | |||
ff73538b5b | |||
30685528c7 | |||
c849f35965 | |||
aa483f4961 | |||
93c010eb51 | |||
0dc017b1a8 | |||
92c92bbbf8 | |||
f51591cb04 | |||
624131ce46 | |||
47da2546f9 | |||
8a53abc1e8 | |||
b258a435cc | |||
43e4f1a766 | |||
02d22c12ae | |||
70ef2f0e81 | |||
b7283c93c6 | |||
5184d64b80 | |||
f482354ffd | |||
7a2b9d66a9 | |||
d79112ee5a | |||
4a5e8f175a |
40
.travis.yml
Normal file
40
.travis.yml
Normal 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
|
@ -13,8 +13,15 @@ boostbook standalone
|
|||||||
:
|
:
|
||||||
iterator
|
iterator
|
||||||
:
|
:
|
||||||
|
<xsl:param>boost.root=../../../..
|
||||||
<xsl:param>toc.max.depth=3
|
<xsl:param>toc.max.depth=3
|
||||||
<xsl:param>toc.section.depth=3
|
<xsl:param>toc.section.depth=3
|
||||||
<xsl:param>chunk.section.depth=4
|
<xsl:param>chunk.section.depth=4
|
||||||
|
<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 ;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
|
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
|
||||||
<tr><th class="docinfo-name">Date:</th>
|
<tr><th class="docinfo-name">Date:</th>
|
||||||
<td>2006-09-11</td></tr>
|
<td>2006-09-11</td></tr>
|
||||||
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html">N1530</a>=03-0113, which was
|
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html">N1530</a>=03-0113, which was
|
||||||
accepted for Technical Report 1 by the C++ standard
|
accepted for Technical Report 1 by the C++ standard
|
||||||
committee's library working group.</td>
|
committee's library working group.</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -239,29 +239,29 @@ Iterator Concepts.</p>
|
|||||||
<div class="section" id="iterator-concepts">
|
<div class="section" id="iterator-concepts">
|
||||||
<h2><a class="toc-backref" href="#id18">Iterator Concepts</a></h2>
|
<h2><a class="toc-backref" href="#id18">Iterator Concepts</a></h2>
|
||||||
<p>This proposal is formulated in terms of the new <tt class="docutils literal"><span class="pre">iterator</span> <span class="pre">concepts</span></tt>
|
<p>This proposal is formulated in terms of the new <tt class="docutils literal"><span class="pre">iterator</span> <span class="pre">concepts</span></tt>
|
||||||
as proposed in <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a>, since user-defined and especially adapted
|
as proposed in <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a>, since user-defined and especially adapted
|
||||||
iterators suffer from the well known categorization problems that are
|
iterators suffer from the well known categorization problems that are
|
||||||
inherent to the current iterator categories.</p>
|
inherent to the current iterator categories.</p>
|
||||||
<p>This proposal does not strictly depend on proposal <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a>, as there
|
<p>This proposal does not strictly depend on proposal <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a>, as there
|
||||||
is a direct mapping between new and old categories. This proposal
|
is a direct mapping between new and old categories. This proposal
|
||||||
could be reformulated using this mapping if <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a> was not accepted.</p>
|
could be reformulated using this mapping if <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a> was not accepted.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="interoperability">
|
<div class="section" id="interoperability">
|
||||||
<h2><a class="toc-backref" href="#id19">Interoperability</a></h2>
|
<h2><a class="toc-backref" href="#id19">Interoperability</a></h2>
|
||||||
<p>The question of iterator interoperability is poorly addressed in the
|
<p>The question of iterator interoperability is poorly addressed in the
|
||||||
current standard. There are currently two defect reports that are
|
current standard. There are currently two defect reports that are
|
||||||
concerned with interoperability issues.</p>
|
concerned with interoperability issues.</p>
|
||||||
<p>Issue <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a> concerns the fact that mutable container iterator types
|
<p>Issue <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a> concerns the fact that mutable container iterator types
|
||||||
are only required to be convertible to the corresponding constant
|
are only required to be convertible to the corresponding constant
|
||||||
iterator types, but objects of these types are not required to
|
iterator types, but objects of these types are not required to
|
||||||
interoperate in comparison or subtraction expressions. This situation
|
interoperate in comparison or subtraction expressions. This situation
|
||||||
is tedious in practice and out of line with the way built in types
|
is tedious in practice and out of line with the way built in types
|
||||||
work. This proposal implements the proposed resolution to issue
|
work. This proposal implements the proposed resolution to issue
|
||||||
<a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a>, as most standard library implementations do nowadays. In other
|
<a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a>, as most standard library implementations do nowadays. In other
|
||||||
words, if an iterator type A has an implicit or user defined
|
words, if an iterator type A has an implicit or user defined
|
||||||
conversion to an iterator type B, the iterator types are interoperable
|
conversion to an iterator type B, the iterator types are interoperable
|
||||||
and the usual set of operators are available.</p>
|
and the usual set of operators are available.</p>
|
||||||
<p>Issue <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280">280</a> concerns the current lack of interoperability between
|
<p>Issue <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#280">280</a> concerns the current lack of interoperability between
|
||||||
reverse iterator types. The proposed new reverse_iterator template
|
reverse iterator types. The proposed new reverse_iterator template
|
||||||
fixes the issues raised in 280. It provides the desired
|
fixes the issues raised in 280. It provides the desired
|
||||||
interoperability without introducing unwanted overloads.</p>
|
interoperability without introducing unwanted overloads.</p>
|
||||||
@ -422,8 +422,8 @@ member (e.g. <a class="reference internal" href="#counting"><tt class="docutils
|
|||||||
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
|
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
|
||||||
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
|
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
|
||||||
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
|
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
|
||||||
semantics required by the preferred resolution to <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
|
semantics required by the preferred resolution to <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
|
||||||
adopted by proposal <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a>: the result of <tt class="docutils literal"><span class="pre">p[n]</span></tt> is an object
|
adopted by proposal <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a>: the result of <tt class="docutils literal"><span class="pre">p[n]</span></tt> is an object
|
||||||
convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is
|
convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is
|
||||||
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
|
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
|
||||||
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach
|
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
.. Version 1.9 of this ReStructuredText document corresponds to
|
.. Version 1.9 of this ReStructuredText document corresponds to
|
||||||
n1530_, the paper accepted by the LWG.
|
n1530_, the paper accepted by the LWG.
|
||||||
|
|
||||||
.. _n1530: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html
|
.. _n1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html
|
||||||
|
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ as proposed in n1550_, since user-defined and especially adapted
|
|||||||
iterators suffer from the well known categorization problems that are
|
iterators suffer from the well known categorization problems that are
|
||||||
inherent to the current iterator categories.
|
inherent to the current iterator categories.
|
||||||
|
|
||||||
.. _n1550: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html
|
.. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
|
||||||
|
|
||||||
This proposal does not strictly depend on proposal n1550_, as there
|
This proposal does not strictly depend on proposal n1550_, as there
|
||||||
is a direct mapping between new and old categories. This proposal
|
is a direct mapping between new and old categories. This proposal
|
||||||
@ -169,8 +169,8 @@ reverse iterator types. The proposed new reverse_iterator template
|
|||||||
fixes the issues raised in 280. It provides the desired
|
fixes the issues raised in 280. It provides the desired
|
||||||
interoperability without introducing unwanted overloads.
|
interoperability without introducing unwanted overloads.
|
||||||
|
|
||||||
.. _179: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179
|
.. _179: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179
|
||||||
.. _280: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280
|
.. _280: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#280
|
||||||
|
|
||||||
|
|
||||||
Iterator Facade
|
Iterator Facade
|
||||||
|
142
doc/function_input_iterator.html
Normal file
142
doc/function_input_iterator.html
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
|
||||||
|
<title></title>
|
||||||
|
<meta name="author" content="Dean Michael Berris" />
|
||||||
|
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="document">
|
||||||
|
|
||||||
|
<table class="docinfo" frame="void" rules="none">
|
||||||
|
<col class="docinfo-name" />
|
||||||
|
<col class="docinfo-content" />
|
||||||
|
<tbody valign="top">
|
||||||
|
<tr><th class="docinfo-name">Author:</th>
|
||||||
|
<td><a class="first reference external" href="mailto:mikhailberis@gmail.com">Dean Michael Berris</a></td></tr>
|
||||||
|
<tr class="field"><th class="docinfo-name">License:</th><td class="field-body">Distributed under the Boost Software License, Version 1.0
|
||||||
|
(See accompanying file LICENSE_1_0.txt or copy at <a class="reference external" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="section" id="function-input-iterator">
|
||||||
|
<h1>Function Input Iterator</h1>
|
||||||
|
<p>The Function Input Iterator allows for creating iterators that encapsulate
|
||||||
|
a nullary function object and a state object which tracks the number of times
|
||||||
|
the iterator has been incremented. A Function Input Iterator models the
|
||||||
|
<a class="reference external" href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> concept and is useful for creating bounded input iterators.</p>
|
||||||
|
<p>Like the Generator Iterator, the Function Input Iterator takes a function
|
||||||
|
that models the <a class="reference external" href="http://www.sgi.com/tech/stl/Generator.html">Generator</a> concept (which is basically a nullary or 0-arity
|
||||||
|
function object). Each increment of the function Function Input Iterator
|
||||||
|
invokes the generator function and stores the value in the iterator. When
|
||||||
|
the iterator is dereferenced the stored value is returned.</p>
|
||||||
|
<p>The Function Input Iterator encapsulates a state object which models the
|
||||||
|
<a class="reference internal" href="#incrementable-concept">Incrementable Concept</a> and the <a class="reference external" href="http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</a> Concept. These concepts are
|
||||||
|
described below as:</p>
|
||||||
|
<div class="section" id="incrementable-concept">
|
||||||
|
<h2>Incrementable Concept</h2>
|
||||||
|
<p>A type models the Incrementable Concept when it supports the pre- and post-
|
||||||
|
increment operators. For a given object <tt class="docutils literal"><span class="pre">i</span></tt> with type <tt class="docutils literal"><span class="pre">I</span></tt>, the following
|
||||||
|
constructs should be valid:</p>
|
||||||
|
<table border="1" class="docutils">
|
||||||
|
<colgroup>
|
||||||
|
<col width="24%" />
|
||||||
|
<col width="46%" />
|
||||||
|
<col width="30%" />
|
||||||
|
</colgroup>
|
||||||
|
<tbody valign="top">
|
||||||
|
<tr><td colspan="3">Construct Description Return Type</td>
|
||||||
|
</tr>
|
||||||
|
<tr><td>i++</td>
|
||||||
|
<td>Post-increment i.</td>
|
||||||
|
<td>I</td>
|
||||||
|
</tr>
|
||||||
|
<tr><td>++i</td>
|
||||||
|
<td>Pre-increment i.</td>
|
||||||
|
<td>I&</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p>NOTE: An Incrementable type should also be <a class="reference external" href="http://www.sgi.com/tech/stl/DefaultConstructible.html">DefaultConstructible</a>.</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="synopsis">
|
||||||
|
<h2>Synopsis</h2>
|
||||||
|
<pre class="literal-block">
|
||||||
|
namespace {
|
||||||
|
template <class Function, class State>
|
||||||
|
class function_input_iterator;
|
||||||
|
|
||||||
|
template <class Function, class State>
|
||||||
|
typename function_input_iterator<Function, State>
|
||||||
|
make_function_input_iterator(Function & f);
|
||||||
|
|
||||||
|
struct infinite;
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="function-input-iterator-class">
|
||||||
|
<h2>Function Input Iterator Class</h2>
|
||||||
|
<p>The class Function Input Iterator class takes two template parameters
|
||||||
|
<tt class="docutils literal"><span class="pre">Function</span></tt> and <tt class="docutils literal"><span class="pre">State</span></tt>. These two template parameters tell the
|
||||||
|
Function Input Iterator the type of the function to encapsulate and
|
||||||
|
the type of the internal state value to hold.</p>
|
||||||
|
<p>The <tt class="docutils literal"><span class="pre">State</span></tt> parameter is important in cases where you want to
|
||||||
|
control the type of the counter which determines whether two iterators
|
||||||
|
are at the same state. This allows for creating a pair of iterators which
|
||||||
|
bound the range of the invocations of the encapsulated functions.</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" id="examples">
|
||||||
|
<h2>Examples</h2>
|
||||||
|
<p>The following example shows how we use the function input iterator class
|
||||||
|
in cases where we want to create bounded (lazy) generated ranges.</p>
|
||||||
|
<pre class="literal-block">
|
||||||
|
struct generator {
|
||||||
|
typedef int result_type;
|
||||||
|
generator() { srand(time(0)); }
|
||||||
|
result_type operator() () const {
|
||||||
|
return rand();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char * argv[]) {
|
||||||
|
generator f;
|
||||||
|
copy(
|
||||||
|
make_function_input_iterator(f, 0),
|
||||||
|
make_function_input_iterator(f, 10),
|
||||||
|
ostream_iterator<int>(cout, " ")
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<p>Here we can see that we've bounded the number of invocations using an <tt class="docutils literal"><span class="pre">int</span></tt>
|
||||||
|
that counts from <tt class="docutils literal"><span class="pre">0</span></tt> to <tt class="docutils literal"><span class="pre">10</span></tt>. Say we want to create an endless stream
|
||||||
|
of random numbers and encapsulate that in a pair of integers, we can do
|
||||||
|
it with the <tt class="docutils literal"><span class="pre">boost::infinite</span></tt> helper class.</p>
|
||||||
|
<pre class="literal-block">
|
||||||
|
copy(
|
||||||
|
make_function_input_iterator(f,infinite()),
|
||||||
|
make_function_input_iterator(f,infinite()),
|
||||||
|
ostream_iterator<int>(count, " ")
|
||||||
|
);
|
||||||
|
</pre>
|
||||||
|
<p>Above, instead of creating a huge vector we rely on the STL copy algorithm
|
||||||
|
to traverse the function input iterator and call the function object f
|
||||||
|
as it increments the iterator. The special property of <tt class="docutils literal"><span class="pre">boost::infinite</span></tt>
|
||||||
|
is that equating two instances always yield false -- and that incrementing
|
||||||
|
an instance of <tt class="docutils literal"><span class="pre">boost::infinite</span></tt> doesn't do anything. This is an efficient
|
||||||
|
way of stating that the iterator range provided by two iterators with an
|
||||||
|
encapsulated infinite state will definitely be infinite.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<hr class="footer" />
|
||||||
|
<a class="reference external" href="function_input_iterator.rst">View document source</a>.
|
||||||
|
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
132
doc/function_input_iterator.rst
Normal file
132
doc/function_input_iterator.rst
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
:Author:
|
||||||
|
`Dean Michael Berris <mailto:me@deanberris.com>`_
|
||||||
|
|
||||||
|
:License:
|
||||||
|
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)
|
||||||
|
|
||||||
|
:Copyright:
|
||||||
|
Copyright 2012 Google, Inc.
|
||||||
|
|
||||||
|
Function Input Iterator
|
||||||
|
=======================
|
||||||
|
|
||||||
|
The Function Input Iterator allows for creating iterators that encapsulate
|
||||||
|
a nullary function object and a state object which tracks the number of times
|
||||||
|
the iterator has been incremented. A Function Input Iterator models the
|
||||||
|
`InputIterator`_ concept and is useful for creating bounded input iterators.
|
||||||
|
|
||||||
|
.. _InputIterator: http://www.sgi.com/tech/stl/InputIterator.html
|
||||||
|
|
||||||
|
The Function Input Iterator takes a function that models the Generator_ concept
|
||||||
|
(which is basically a nullary or 0-arity function object). The first dereference
|
||||||
|
of the iterator at a given position invokes the generator function and stores
|
||||||
|
and returns the result; subsequent dereferences at the same position simply
|
||||||
|
return the same stored result. Incrementing the iterator places it at a new
|
||||||
|
position, hence a subsequent dereference will generate a new value via another
|
||||||
|
invokation of the generator function. This ensures the generator function is
|
||||||
|
invoked precisely when the iterator is requested to return a (new) value.
|
||||||
|
|
||||||
|
.. _Generator: http://www.sgi.com/tech/stl/Generator.html
|
||||||
|
|
||||||
|
The Function Input Iterator encapsulates a state object which models the
|
||||||
|
`Incrementable Concept`_ and the EqualityComparable_ Concept. These concepts are
|
||||||
|
described below as:
|
||||||
|
|
||||||
|
.. _EqualityComparable: http://www.sgi.com/tech/stl/EqualityComparable.html
|
||||||
|
|
||||||
|
Incrementable Concept
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
A type models the Incrementable Concept when it supports the pre- and post-
|
||||||
|
increment operators. For a given object ``i`` with type ``I``, the following
|
||||||
|
constructs should be valid:
|
||||||
|
|
||||||
|
========= ================= ===========
|
||||||
|
Construct Description Return Type
|
||||||
|
-----------------------------------------
|
||||||
|
i++ Post-increment i. I
|
||||||
|
++i Pre-increment i. I&
|
||||||
|
========= ================= ===========
|
||||||
|
|
||||||
|
NOTE: An Incrementable type should also be DefaultConstructible_.
|
||||||
|
|
||||||
|
.. _DefaultConstructible: http://www.sgi.com/tech/stl/DefaultConstructible.html
|
||||||
|
|
||||||
|
Synopsis
|
||||||
|
--------
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <class Function, class State>
|
||||||
|
class function_input_iterator;
|
||||||
|
|
||||||
|
template <class Function, class State>
|
||||||
|
typename function_input_iterator<Function, State>
|
||||||
|
make_function_input_iterator(Function & f, State s);
|
||||||
|
|
||||||
|
struct infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Input Iterator Class
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
The class Function Input Iterator class takes two template parameters
|
||||||
|
``Function`` and ``State``. These two template parameters tell the
|
||||||
|
Function Input Iterator the type of the function to encapsulate and
|
||||||
|
the type of the internal state value to hold.
|
||||||
|
|
||||||
|
The ``State`` parameter is important in cases where you want to
|
||||||
|
control the type of the counter which determines whether two iterators
|
||||||
|
are at the same state. This allows for creating a pair of iterators which
|
||||||
|
bound the range of the invocations of the encapsulated functions.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
The following example shows how we use the function input iterator class
|
||||||
|
in cases where we want to create bounded (lazy) generated ranges.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
struct generator {
|
||||||
|
typedef int result_type;
|
||||||
|
generator() { srand(time(0)); }
|
||||||
|
result_type operator() () const {
|
||||||
|
return rand();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char * argv[]) {
|
||||||
|
generator f;
|
||||||
|
copy(
|
||||||
|
make_function_input_iterator(f, 0),
|
||||||
|
make_function_input_iterator(f, 10),
|
||||||
|
ostream_iterator<int>(cout, " ")
|
||||||
|
);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Here we can see that we've bounded the number of invocations using an ``int``
|
||||||
|
that counts from ``0`` to ``10``. Say we want to create an endless stream
|
||||||
|
of random numbers and encapsulate that in a pair of integers, we can do
|
||||||
|
it with the ``boost::infinite`` helper class.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
copy(
|
||||||
|
make_function_input_iterator(f,infinite()),
|
||||||
|
make_function_input_iterator(f,infinite()),
|
||||||
|
ostream_iterator<int>(cout, " ")
|
||||||
|
);
|
||||||
|
|
||||||
|
Above, instead of creating a huge vector we rely on the STL copy algorithm
|
||||||
|
to traverse the function input iterator and call the function object f
|
||||||
|
as it increments the iterator. The special property of ``boost::infinite``
|
||||||
|
is that equating two instances always yield false -- and that incrementing
|
||||||
|
an instance of ``boost::infinite`` doesn't do anything. This is an efficient
|
||||||
|
way of stating that the iterator range provided by two iterators with an
|
||||||
|
encapsulated infinite state will definitely be infinite.
|
||||||
|
|
||||||
|
|
163
doc/generator_iterator.htm
Normal file
163
doc/generator_iterator.htm
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Language" content="en-us">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
|
||||||
|
|
||||||
|
<title>Generator Iterator Adaptor Documentation</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body bgcolor="#FFFFFF" text="#000000">
|
||||||
|
<img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle"
|
||||||
|
width="277" height="86">
|
||||||
|
|
||||||
|
<h1>Generator Iterator Adaptor</h1>
|
||||||
|
|
||||||
|
<p>Defined in header <a href=
|
||||||
|
"../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a></p>
|
||||||
|
|
||||||
|
<p>The generator iterator adaptor makes it easier to create custom input
|
||||||
|
iterators from 0-ary functions and function objects. The adaptor takes a
|
||||||
|
<a href="http://www.sgi.com/tech/stl/Generator.html">Generator</a> and
|
||||||
|
creates a model of <a href=
|
||||||
|
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>. Each
|
||||||
|
increment retrieves an item from the generator and makes it available to be
|
||||||
|
retrieved by dereferencing. The motivation for this iterator is that some
|
||||||
|
concepts can be more naturally expressed as a generator, while most STL
|
||||||
|
algorithms expect an iterator. An example is the <a href=
|
||||||
|
"../random/index.html">Random Number</a> library.</p>
|
||||||
|
|
||||||
|
<h2>Synopsis</h2>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
namespace boost {
|
||||||
|
template <class Generator>
|
||||||
|
class generator_iterator_policies;
|
||||||
|
|
||||||
|
template <class Generator>
|
||||||
|
class generator_iterator_generator;
|
||||||
|
|
||||||
|
template <class Generator>
|
||||||
|
typename generator_iterator_generator<Generator>::type
|
||||||
|
make_generator_iterator(Generator & gen);
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2>The Generator Iterator Generator Class</h2>
|
||||||
|
|
||||||
|
<p>The class generator_iterator_generator is a helper class whose purpose
|
||||||
|
is to construct a generator iterator type. The template parameter for this
|
||||||
|
class is the Generator function object type that is being wrapped. The
|
||||||
|
generator iterator adaptor only holds a reference (or pointer) to the
|
||||||
|
function object, therefore the function object must outlive the generator
|
||||||
|
iterator adaptor constructed from it.</p>
|
||||||
|
<pre>
|
||||||
|
template <class Generator>
|
||||||
|
class generator_iterator_generator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef <i>unspecified</i> type; // the resulting generator iterator type
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3>Template Parameters</h3>
|
||||||
|
|
||||||
|
<table border summary="">
|
||||||
|
<tr>
|
||||||
|
<th>Parameter</th>
|
||||||
|
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><tt><a href=
|
||||||
|
"http://www.sgi.com/tech/stl/Generator.html">Generator</a></tt></td>
|
||||||
|
|
||||||
|
<td>The generator (0-ary function object) type being wrapped. The
|
||||||
|
return type of the function must be defined as
|
||||||
|
<tt>Generator::result_type</tt>. The function object must be a model of
|
||||||
|
<a href=
|
||||||
|
"http://www.sgi.com/tech/stl/Generator.html">Generator</a>.</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3>Concept Model</h3>
|
||||||
|
|
||||||
|
<p>The generator iterator class is a model of <a href=
|
||||||
|
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.</p>
|
||||||
|
|
||||||
|
<h3>Members</h3>
|
||||||
|
|
||||||
|
<p>The generator iterator implements the member functions and operators
|
||||||
|
required of the <a href=
|
||||||
|
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>
|
||||||
|
concept.<br></p>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2><a name="make_generator_iterator" id="make_generator_iterator">The
|
||||||
|
Generator Iterator Object Generator</a></h2>
|
||||||
|
|
||||||
|
<p>The <tt>make_generator_iterator()</tt> function provides a convenient
|
||||||
|
way to create generator iterator objects. The function saves the user the
|
||||||
|
trouble of explicitly writing out the iterator types.</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
template <class Generator>
|
||||||
|
typename generator_iterator_generator<Generator>::type
|
||||||
|
make_generator_iterator(Generator & gen);
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h3>Example</h3>
|
||||||
|
|
||||||
|
<p>The following program shows how <code>generator_iterator</code>
|
||||||
|
transforms a generator into an input iterator.</p>
|
||||||
|
|
||||||
|
<blockquote>
|
||||||
|
<pre>
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/generator_iterator.hpp>
|
||||||
|
|
||||||
|
class my_generator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef int result_type;
|
||||||
|
my_generator() : state(0) { }
|
||||||
|
int operator()() { return ++state; }
|
||||||
|
private:
|
||||||
|
int state;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
my_generator gen;
|
||||||
|
boost::generator_iterator_generator<my_generator>::type it = boost::make_generator_iterator(gen);
|
||||||
|
for(int i = 0; i < 10; ++i, ++it)
|
||||||
|
std::cout << *it << std::endl;
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
</blockquote>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
|
||||||
|
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
|
||||||
|
height="31" width="88"></a></p>
|
||||||
|
|
||||||
|
<p>Revised
|
||||||
|
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
|
||||||
|
|
||||||
|
<p><i>Copyright © 2001 <a href=
|
||||||
|
"http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a></i></p>
|
||||||
|
|
||||||
|
<p><i>Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
|
||||||
|
copy at <a href=
|
||||||
|
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -3,7 +3,7 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
|
||||||
<title>The Boost.Iterator Library Boost</title>
|
<title>The Boost.Iterator Library Boost</title>
|
||||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||||
</head>
|
</head>
|
||||||
@ -11,9 +11,6 @@
|
|||||||
<div class="document" id="the-boost-iterator-library-logo">
|
<div class="document" id="the-boost-iterator-library-logo">
|
||||||
<h1 class="title">The Boost.Iterator Library <a class="reference external" href="../../../index.htm"><img alt="Boost" src="../../../boost.png" /></a></h1>
|
<h1 class="title">The Boost.Iterator Library <a class="reference external" href="../../../index.htm"><img alt="Boost" src="../../../boost.png" /></a></h1>
|
||||||
|
|
||||||
<!-- 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) -->
|
|
||||||
<!-- Distributed under the Boost -->
|
<!-- Distributed under the Boost -->
|
||||||
<!-- Software License, Version 1.0. (See accompanying -->
|
<!-- Software License, Version 1.0. (See accompanying -->
|
||||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||||
@ -60,21 +57,21 @@ older Boost Iterator Adaptor Library.</td>
|
|||||||
<div class="contents topic" id="table-of-contents">
|
<div class="contents topic" id="table-of-contents">
|
||||||
<p class="topic-title first"><strong>Table of Contents</strong></p>
|
<p class="topic-title first"><strong>Table of Contents</strong></p>
|
||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
<li><a class="reference internal" href="#new-style-iterators" id="id22">New-Style Iterators</a></li>
|
<li><a class="reference internal" href="#new-style-iterators" id="id23">New-Style Iterators</a></li>
|
||||||
<li><a class="reference internal" href="#iterator-facade-and-adaptor" id="id23">Iterator Facade and Adaptor</a></li>
|
<li><a class="reference internal" href="#iterator-facade-and-adaptor" id="id24">Iterator Facade and Adaptor</a></li>
|
||||||
<li><a class="reference internal" href="#specialized-adaptors" id="id24">Specialized Adaptors</a></li>
|
<li><a class="reference internal" href="#specialized-adaptors" id="id25">Specialized Adaptors</a></li>
|
||||||
<li><a class="reference internal" href="#iterator-utilities" id="id25">Iterator Utilities</a><ul>
|
<li><a class="reference internal" href="#iterator-utilities" id="id26">Iterator Utilities</a><ul>
|
||||||
<li><a class="reference internal" href="#traits" id="id26">Traits</a></li>
|
<li><a class="reference internal" href="#traits" id="id27">Traits</a></li>
|
||||||
<li><a class="reference internal" href="#testing-and-concept-checking" id="id27">Testing and Concept Checking</a></li>
|
<li><a class="reference internal" href="#testing-and-concept-checking" id="id28">Testing and Concept Checking</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="reference internal" href="#upgrading-from-the-old-boost-iterator-adaptor-library" id="id28">Upgrading from the old Boost Iterator Adaptor Library</a></li>
|
<li><a class="reference internal" href="#upgrading-from-the-old-boost-iterator-adaptor-library" id="id29">Upgrading from the old Boost Iterator Adaptor Library</a></li>
|
||||||
<li><a class="reference internal" href="#history" id="id29">History</a></li>
|
<li><a class="reference internal" href="#history" id="id30">History</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<hr class="docutils" />
|
<hr class="docutils" />
|
||||||
<div class="section" id="new-style-iterators">
|
<div class="section" id="new-style-iterators">
|
||||||
<h1><a class="toc-backref" href="#id22">New-Style Iterators</a></h1>
|
<h1><a class="toc-backref" href="#id23">New-Style Iterators</a></h1>
|
||||||
<p>The iterator categories defined in C++98 are extremely limiting
|
<p>The iterator categories defined in C++98 are extremely limiting
|
||||||
because they bind together two orthogonal concepts: traversal and
|
because they bind together two orthogonal concepts: traversal and
|
||||||
element access. For example, because a random access iterator is
|
element access. For example, because a random access iterator is
|
||||||
@ -93,7 +90,7 @@ concepts, see our</p>
|
|||||||
<a class="reference external" href="new-iter-concepts.html">Standard Proposal For New-Style Iterators</a> (<a class="reference external" href="new-iter-concepts.pdf">PDF</a>)</blockquote>
|
<a class="reference external" href="new-iter-concepts.html">Standard Proposal For New-Style Iterators</a> (<a class="reference external" href="new-iter-concepts.pdf">PDF</a>)</blockquote>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="iterator-facade-and-adaptor">
|
<div class="section" id="iterator-facade-and-adaptor">
|
||||||
<h1><a class="toc-backref" href="#id23">Iterator Facade and Adaptor</a></h1>
|
<h1><a class="toc-backref" href="#id24">Iterator Facade and Adaptor</a></h1>
|
||||||
<p>Writing standard-conforming iterators is tricky, but the need comes
|
<p>Writing standard-conforming iterators is tricky, but the need comes
|
||||||
up often. In order to ease the implementation of new iterators,
|
up often. In order to ease the implementation of new iterators,
|
||||||
the Boost.Iterator library provides the <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> class template,
|
the Boost.Iterator library provides the <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> class template,
|
||||||
@ -120,7 +117,7 @@ and accepted into the first C++ technical report; see our</p>
|
|||||||
<p>for more details.</p>
|
<p>for more details.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="specialized-adaptors">
|
<div class="section" id="specialized-adaptors">
|
||||||
<h1><a class="toc-backref" href="#id24">Specialized Adaptors</a></h1>
|
<h1><a class="toc-backref" href="#id25">Specialized Adaptors</a></h1>
|
||||||
<p>The iterator library supplies a useful suite of standard-conforming
|
<p>The iterator library supplies a useful suite of standard-conforming
|
||||||
iterator templates based on the Boost <a class="reference internal" href="#iterator-facade-and-adaptor">iterator facade and adaptor</a>.</p>
|
iterator templates based on the Boost <a class="reference internal" href="#iterator-facade-and-adaptor">iterator facade and adaptor</a>.</p>
|
||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
@ -128,6 +125,9 @@ iterator templates based on the Boost <a class="reference internal" href="#itera
|
|||||||
Implements a "lazy sequence"</li>
|
Implements a "lazy sequence"</li>
|
||||||
<li><a class="reference external" href="filter_iterator.html"><tt class="docutils literal"><span class="pre">filter_iterator</span></tt></a> (<a class="reference external" href="filter_iterator.pdf">PDF</a>): an iterator over the subset of elements of some
|
<li><a class="reference external" href="filter_iterator.html"><tt class="docutils literal"><span class="pre">filter_iterator</span></tt></a> (<a class="reference external" href="filter_iterator.pdf">PDF</a>): an iterator over the subset of elements of some
|
||||||
sequence which satisfy a given predicate</li>
|
sequence which satisfy a given predicate</li>
|
||||||
|
<li><a class="reference external" href="function_input_iterator.html"><tt class="docutils literal"><span class="pre">function_input_iterator</span></tt></a> (<a class="reference external" href="function_input_iterator.pdf">PDF</a>): an input iterator wrapping a generator (nullary
|
||||||
|
function object); each time the iterator is dereferenced, the function object
|
||||||
|
is called to get the value to return.</li>
|
||||||
<li><a class="reference external" href="function_output_iterator.html"><tt class="docutils literal"><span class="pre">function_output_iterator</span></tt></a> (<a class="reference external" href="function_output_iterator.pdf">PDF</a>): an output iterator wrapping a unary function
|
<li><a class="reference external" href="function_output_iterator.html"><tt class="docutils literal"><span class="pre">function_output_iterator</span></tt></a> (<a class="reference external" href="function_output_iterator.pdf">PDF</a>): an output iterator wrapping a unary function
|
||||||
object; each time an element is written into the dereferenced
|
object; each time an element is written into the dereferenced
|
||||||
iterator, it is passed as a parameter to the function object.</li>
|
iterator, it is passed as a parameter to the function object.</li>
|
||||||
@ -149,9 +149,9 @@ positions of heterogeneous underlying iterators.</li>
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="iterator-utilities">
|
<div class="section" id="iterator-utilities">
|
||||||
<h1><a class="toc-backref" href="#id25">Iterator Utilities</a></h1>
|
<h1><a class="toc-backref" href="#id26">Iterator Utilities</a></h1>
|
||||||
<div class="section" id="traits">
|
<div class="section" id="traits">
|
||||||
<h2><a class="toc-backref" href="#id26">Traits</a></h2>
|
<h2><a class="toc-backref" href="#id27">Traits</a></h2>
|
||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
<li><a class="reference external" href="pointee.html"><tt class="docutils literal"><span class="pre">pointee.hpp</span></tt></a> (<a class="reference external" href="pointee.pdf">PDF</a>): Provides the capability to deduce the referent types
|
<li><a class="reference external" href="pointee.html"><tt class="docutils literal"><span class="pre">pointee.hpp</span></tt></a> (<a class="reference external" href="pointee.pdf">PDF</a>): Provides the capability to deduce the referent types
|
||||||
of pointers, smart pointers and iterators in generic code. Used
|
of pointers, smart pointers and iterators in generic code. Used
|
||||||
@ -165,7 +165,7 @@ testing iterator interoperability -->
|
|||||||
<!-- comment! __ interoperable.pdf -->
|
<!-- comment! __ interoperable.pdf -->
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="testing-and-concept-checking">
|
<div class="section" id="testing-and-concept-checking">
|
||||||
<h2><a class="toc-backref" href="#id27">Testing and Concept Checking</a></h2>
|
<h2><a class="toc-backref" href="#id28">Testing and Concept Checking</a></h2>
|
||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
<li><a class="reference external" href="iterator_concepts.html"><tt class="docutils literal"><span class="pre">iterator_concepts.hpp</span></tt></a> (<a class="reference external" href="iterator_concepts.pdf">PDF</a>): Concept checking classes for the new iterator concepts.</li>
|
<li><a class="reference external" href="iterator_concepts.html"><tt class="docutils literal"><span class="pre">iterator_concepts.hpp</span></tt></a> (<a class="reference external" href="iterator_concepts.pdf">PDF</a>): Concept checking classes for the new iterator concepts.</li>
|
||||||
<li><a class="reference external" href="iterator_archetypes.html"><tt class="docutils literal"><span class="pre">iterator_archetypes.hpp</span></tt></a> (<a class="reference external" href="iterator_archetypes.pdf">PDF</a>): Concept archetype classes for the new iterators concepts.</li>
|
<li><a class="reference external" href="iterator_archetypes.html"><tt class="docutils literal"><span class="pre">iterator_archetypes.hpp</span></tt></a> (<a class="reference external" href="iterator_archetypes.pdf">PDF</a>): Concept archetype classes for the new iterators concepts.</li>
|
||||||
@ -173,7 +173,7 @@ testing iterator interoperability -->
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="upgrading-from-the-old-boost-iterator-adaptor-library">
|
<div class="section" id="upgrading-from-the-old-boost-iterator-adaptor-library">
|
||||||
<h1><a class="toc-backref" href="#id28">Upgrading from the old Boost Iterator Adaptor Library</a></h1>
|
<h1><a class="toc-backref" href="#id29">Upgrading from the old Boost Iterator Adaptor Library</a></h1>
|
||||||
<p id="upgrading">If you have been using the old Boost Iterator Adaptor library to
|
<p id="upgrading">If you have been using the old Boost Iterator Adaptor library to
|
||||||
implement iterators, you probably wrote a <tt class="docutils literal"><span class="pre">Policies</span></tt> class which
|
implement iterators, you probably wrote a <tt class="docutils literal"><span class="pre">Policies</span></tt> class which
|
||||||
captures the core operations of your iterator. In the new library
|
captures the core operations of your iterator. In the new library
|
||||||
@ -183,7 +183,7 @@ you probably wrote a <a class="reference external" href="http://www.boost.org/mo
|
|||||||
<tt class="docutils literal"><span class="pre">iterator_adaptor</span></tt> specialization you needed; in the new library
|
<tt class="docutils literal"><span class="pre">iterator_adaptor</span></tt> specialization you needed; in the new library
|
||||||
design you don't need a type generator (though may want to keep it
|
design you don't need a type generator (though may want to keep it
|
||||||
around as a compatibility aid for older code) because, due to the
|
around as a compatibility aid for older code) because, due to the
|
||||||
use of the Curiously Recurring Template Pattern (CRTP) <a class="citation-reference" href="#cop95" id="id21">[Cop95]</a>,
|
use of the Curiously Recurring Template Pattern (CRTP) <a class="citation-reference" href="#cop95" id="id22">[Cop95]</a>,
|
||||||
you can now define the iterator class yourself and acquire
|
you can now define the iterator class yourself and acquire
|
||||||
functionality through inheritance from <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> or
|
functionality through inheritance from <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> or
|
||||||
<tt class="docutils literal"><span class="pre">iterator_adaptor</span></tt>. As a result, you also get much finer control
|
<tt class="docutils literal"><span class="pre">iterator_adaptor</span></tt>. As a result, you also get much finer control
|
||||||
@ -198,7 +198,7 @@ type, <tt class="docutils literal"><span class="pre">transform_iterator</span></
|
|||||||
<tt class="docutils literal"><span class="pre">projection_iterator</span></tt> used to.</p>
|
<tt class="docutils literal"><span class="pre">projection_iterator</span></tt> used to.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="history">
|
<div class="section" id="history">
|
||||||
<h1><a class="toc-backref" href="#id29">History</a></h1>
|
<h1><a class="toc-backref" href="#id30">History</a></h1>
|
||||||
<p>In 2000 Dave Abrahams was writing an iterator for a container of
|
<p>In 2000 Dave Abrahams was writing an iterator for a container of
|
||||||
pointers, which would access the pointed-to elements when
|
pointers, which would access the pointed-to elements when
|
||||||
dereferenced. Naturally, being a library writer, he decided to
|
dereferenced. Naturally, being a library writer, he decided to
|
||||||
@ -226,7 +226,7 @@ library you see today.</p>
|
|||||||
<table class="docutils citation" frame="void" id="cop95" rules="none">
|
<table class="docutils citation" frame="void" id="cop95" rules="none">
|
||||||
<colgroup><col class="label" /><col /></colgroup>
|
<colgroup><col class="label" /><col /></colgroup>
|
||||||
<tbody valign="top">
|
<tbody valign="top">
|
||||||
<tr><td class="label"><a class="fn-backref" href="#id21">[Cop95]</a></td><td>[Coplien, 1995] Coplien, J., Curiously Recurring Template
|
<tr><td class="label"><a class="fn-backref" href="#id22">[Cop95]</a></td><td>[Coplien, 1995] Coplien, J., Curiously Recurring Template
|
||||||
Patterns, C++ Report, February 1995, pp. 24-27.</td></tr>
|
Patterns, C++ Report, February 1995, pp. 24-27.</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -115,8 +115,8 @@ __ iterator_facade.pdf
|
|||||||
__ iterator_adaptor.pdf
|
__ iterator_adaptor.pdf
|
||||||
|
|
||||||
Both |facade| and |adaptor| as well as many of the `specialized
|
Both |facade| and |adaptor| as well as many of the `specialized
|
||||||
adaptors`_ mentioned below have been proposed for standardization,
|
adaptors`_ mentioned below have been proposed for standardization;
|
||||||
and accepted into the first C++ technical report; see our
|
see our
|
||||||
|
|
||||||
`Standard Proposal For Iterator Facade and Adaptor`__ (PDF__)
|
`Standard Proposal For Iterator Facade and Adaptor`__ (PDF__)
|
||||||
|
|
||||||
@ -138,7 +138,11 @@ iterator templates based on the Boost `iterator facade and adaptor`_.
|
|||||||
* |filter|_ (PDF__): an iterator over the subset of elements of some
|
* |filter|_ (PDF__): an iterator over the subset of elements of some
|
||||||
sequence which satisfy a given predicate
|
sequence which satisfy a given predicate
|
||||||
|
|
||||||
* |function|_ (PDF__): an output iterator wrapping a unary function
|
* |function_input|_ (PDF__): an input iterator wrapping a generator (nullary
|
||||||
|
function object); each time the iterator is dereferenced, the function object
|
||||||
|
is called to get the value to return.
|
||||||
|
|
||||||
|
* |function_output|_ (PDF__): an output iterator wrapping a unary function
|
||||||
object; each time an element is written into the dereferenced
|
object; each time an element is written into the dereferenced
|
||||||
iterator, it is passed as a parameter to the function object.
|
iterator, it is passed as a parameter to the function object.
|
||||||
|
|
||||||
@ -171,8 +175,12 @@ __ counting_iterator.pdf
|
|||||||
.. _filter: filter_iterator.html
|
.. _filter: filter_iterator.html
|
||||||
__ filter_iterator.pdf
|
__ filter_iterator.pdf
|
||||||
|
|
||||||
.. |function| replace:: ``function_output_iterator``
|
.. |function_input| replace:: ``function_input_iterator``
|
||||||
.. _function: function_output_iterator.html
|
.. _function_input: function_input_iterator.html
|
||||||
|
__ function_input_iterator.pdf
|
||||||
|
|
||||||
|
.. |function_output| replace:: ``function_output_iterator``
|
||||||
|
.. _function_output: function_output_iterator.html
|
||||||
__ function_output_iterator.pdf
|
__ function_output_iterator.pdf
|
||||||
|
|
||||||
.. |indirect| replace:: ``indirect_iterator``
|
.. |indirect| replace:: ``indirect_iterator``
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
.. _N1550: http://www.boost-consulting.com/writing/n1550.html
|
.. _N1550: http://www.boost-consulting.com/writing/n1550.html
|
||||||
.. _N1530: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html
|
.. _N1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html
|
||||||
|
|
||||||
:Author: David Abrahams and Jeremy Siek
|
:Author: David Abrahams and Jeremy Siek
|
||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
||||||
|
@ -242,8 +242,8 @@ member (e.g. <a class="reference external" href="counting_iterator.html"><tt cla
|
|||||||
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
|
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
|
||||||
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
|
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
|
||||||
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
|
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
|
||||||
semantics required by the preferred resolution to <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
|
semantics required by the preferred resolution to <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
|
||||||
adopted by proposal <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a>: the result of <tt class="docutils literal"><span class="pre">p[n]</span></tt> is an object
|
adopted by proposal <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a>: the result of <tt class="docutils literal"><span class="pre">p[n]</span></tt> is an object
|
||||||
convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is
|
convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is
|
||||||
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
|
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
|
||||||
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach
|
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach
|
||||||
|
@ -167,9 +167,9 @@ the implementation of her iterator is free to implement an
|
|||||||
class; it will hide the one supplied by ``iterator_facade`` from
|
class; it will hide the one supplied by ``iterator_facade`` from
|
||||||
clients of her iterator.
|
clients of her iterator.
|
||||||
|
|
||||||
.. _n1550: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html
|
.. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
|
||||||
|
|
||||||
.. _`issue 299`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
|
.. _`issue 299`: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299
|
||||||
|
|
||||||
.. _`operator arrow`:
|
.. _`operator arrow`:
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ The ``iterator_category`` member of ``iterator_facade`` is
|
|||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
|
|
||||||
*iterator-category*\ (CategoryOrTraversal, value_type, reference)
|
*iterator-category*\ (CategoryOrTraversal, reference, value_type)
|
||||||
|
|
||||||
where *iterator-category* is defined as follows:
|
where *iterator-category* is defined as follows:
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
|
||||||
<title>Iterator Traits</title>
|
<title>Iterator Traits</title>
|
||||||
<meta name="author" content="David Abrahams" />
|
<meta name="author" content="David Abrahams" />
|
||||||
<meta name="organization" content="Boost Consulting" />
|
<meta name="organization" content="Boost Consulting" />
|
||||||
<meta name="date" content="2006-09-11" />
|
<meta name="date" content="$Date$" />
|
||||||
<meta name="copyright" content="Copyright David Abrahams 2004." />
|
<meta name="copyright" content="Copyright David Abrahams 2004." />
|
||||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||||
</head>
|
</head>
|
||||||
@ -25,7 +25,7 @@
|
|||||||
<tr><th class="docinfo-name">Organization:</th>
|
<tr><th class="docinfo-name">Organization:</th>
|
||||||
<td><a class="first last reference external" href="http://www.boost-consulting.com">Boost Consulting</a></td></tr>
|
<td><a class="first last reference external" href="http://www.boost-consulting.com">Boost Consulting</a></td></tr>
|
||||||
<tr><th class="docinfo-name">Date:</th>
|
<tr><th class="docinfo-name">Date:</th>
|
||||||
<td>2006-09-11</td></tr>
|
<td>$Date$</td></tr>
|
||||||
<tr><th class="docinfo-name">Copyright:</th>
|
<tr><th class="docinfo-name">Copyright:</th>
|
||||||
<td>Copyright David Abrahams 2004.</td></tr>
|
<td>Copyright David Abrahams 2004.</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -37,7 +37,7 @@
|
|||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
<col class="field-body" />
|
<col class="field-body" />
|
||||||
<tbody valign="top">
|
<tbody valign="top">
|
||||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">Header <tt class="docutils literal"><span class="pre"><boost/iterator/iterator_traits.hpp></span></tt> provides
|
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">Header <tt class="docutils literal"><boost/iterator/iterator_traits.hpp></tt> provides
|
||||||
the ability to access an iterator's associated types using
|
the ability to access an iterator's associated types using
|
||||||
MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</td>
|
MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -46,15 +46,15 @@ MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#meta
|
|||||||
<div class="section" id="overview">
|
<div class="section" id="overview">
|
||||||
<h1>Overview</h1>
|
<h1>Overview</h1>
|
||||||
<p><tt class="docutils literal"><span class="pre">std::iterator_traits</span></tt> provides access to five associated types
|
<p><tt class="docutils literal"><span class="pre">std::iterator_traits</span></tt> provides access to five associated types
|
||||||
of any iterator: its <tt class="docutils literal"><span class="pre">value_type</span></tt>, <tt class="docutils literal"><span class="pre">reference</span></tt>, <tt class="docutils literal"><span class="pre">pointer</span></tt>,
|
of any iterator: its <tt class="docutils literal">value_type</tt>, <tt class="docutils literal">reference</tt>, <tt class="docutils literal">pointer</tt>,
|
||||||
<tt class="docutils literal"><span class="pre">iterator_category</span></tt>, and <tt class="docutils literal"><span class="pre">difference_type</span></tt>. Unfortunately,
|
<tt class="docutils literal">iterator_category</tt>, and <tt class="docutils literal">difference_type</tt>. Unfortunately,
|
||||||
such a "multi-valued" traits template can be difficult to use in a
|
such a "multi-valued" traits template can be difficult to use in a
|
||||||
metaprogramming context. <tt class="docutils literal"><span class="pre"><boost/iterator/iterator_traits.hpp></span></tt>
|
metaprogramming context. <tt class="docutils literal"><boost/iterator/iterator_traits.hpp></tt>
|
||||||
provides access to these types using a standard <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</p>
|
provides access to these types using a standard <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="summary">
|
<div class="section" id="summary">
|
||||||
<h1>Summary</h1>
|
<h1>Summary</h1>
|
||||||
<p>Header <tt class="docutils literal"><span class="pre"><boost/iterator/iterator_traits.hpp></span></tt>:</p>
|
<p>Header <tt class="docutils literal"><boost/iterator/iterator_traits.hpp></tt>:</p>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
template <class Iterator>
|
template <class Iterator>
|
||||||
struct iterator_value
|
struct iterator_value
|
||||||
@ -98,21 +98,6 @@ struct iterator_category
|
|||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="broken-compiler-notes">
|
|
||||||
<h1>Broken Compiler Notes</h1>
|
|
||||||
<p>Because of workarounds in Boost, you may find that these
|
|
||||||
<a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a> actually work better than the facilities provided by
|
|
||||||
your compiler's standard library.</p>
|
|
||||||
<p>On compilers that don't support partial specialization, such as
|
|
||||||
Microsoft Visual C++ 6.0 or 7.0, you may need to manually invoke
|
|
||||||
<a class="reference external" href="../../type_traits/index.html#transformations">BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION</a> on the
|
|
||||||
<tt class="docutils literal"><span class="pre">value_type</span></tt> of pointers that are passed to these metafunctions.</p>
|
|
||||||
<p>Because of bugs in the implementation of GCC-2.9x, the name of
|
|
||||||
<tt class="docutils literal"><span class="pre">iterator_category</span></tt> is changed to <tt class="docutils literal"><span class="pre">iterator_category_</span></tt> on that
|
|
||||||
compiler. A macro, <tt class="docutils literal"><span class="pre">BOOST_ITERATOR_CATEGORY</span></tt>, that expands to
|
|
||||||
either <tt class="docutils literal"><span class="pre">iterator_category</span></tt> or <tt class="docutils literal"><span class="pre">iterator_category_</span></tt>, as
|
|
||||||
appropriate to the platform, is provided for portability.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<hr class="footer" />
|
<hr class="footer" />
|
||||||
|
@ -75,24 +75,3 @@ Header ``<boost/iterator/iterator_traits.hpp>``::
|
|||||||
detail::iterator_traits<Iterator>::iterator_category
|
detail::iterator_traits<Iterator>::iterator_category
|
||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
|
|
||||||
Broken Compiler Notes
|
|
||||||
=====================
|
|
||||||
|
|
||||||
Because of workarounds in Boost, you may find that these
|
|
||||||
metafunctions_ actually work better than the facilities provided by
|
|
||||||
your compiler's standard library.
|
|
||||||
|
|
||||||
On compilers that don't support partial specialization, such as
|
|
||||||
Microsoft Visual C++ 6.0 or 7.0, you may need to manually invoke
|
|
||||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION_ on the
|
|
||||||
``value_type`` of pointers that are passed to these metafunctions.
|
|
||||||
|
|
||||||
Because of bugs in the implementation of GCC-2.9x, the name of
|
|
||||||
``iterator_category`` is changed to ``iterator_category_`` on that
|
|
||||||
compiler. A macro, ``BOOST_ITERATOR_CATEGORY``, that expands to
|
|
||||||
either ``iterator_category`` or ``iterator_category_``, as
|
|
||||||
appropriate to the platform, is provided for portability.
|
|
||||||
|
|
||||||
.. _BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION: ../../type_traits/index.html#transformations
|
|
||||||
|
|
||||||
|
@ -27,10 +27,10 @@
|
|||||||
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
|
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
|
||||||
<tr><th class="docinfo-name">Date:</th>
|
<tr><th class="docinfo-name">Date:</th>
|
||||||
<td>2006-09-11</td></tr>
|
<td>2006-09-11</td></tr>
|
||||||
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1550.html">n1550</a>=03-0133, which was
|
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1550.htm">n1550</a>=03-0133, which was
|
||||||
accepted for Technical Report 1 by the C++ standard
|
accepted for Technical Report 1 by the C++ standard
|
||||||
committee's library working group. This proposal is a
|
committee's library working group. This proposal is a
|
||||||
revision of paper <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html">n1297</a>, <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1477.html">n1477</a>, and <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1531.html">n1531</a>.</td>
|
revision of paper <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1297.html">n1297</a>, <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1477.html">n1477</a>, and <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1531.html">n1531</a>.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><th class="docinfo-name">Copyright:</th>
|
<tr><th class="docinfo-name">Copyright:</th>
|
||||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt
|
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt
|
||||||
@ -127,12 +127,12 @@ requirements in the iterator categories.</p>
|
|||||||
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt></td>
|
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td>Forward Iterator</td>
|
<tr><td>Forward Iterator</td>
|
||||||
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is <tt class="docutils literal"><span class="pre">T&</span></tt> (or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">T&</span></tt> once <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200">issue 200</a>
|
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is <tt class="docutils literal"><span class="pre">T&</span></tt> (or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">T&</span></tt> once <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#200">issue 200</a>
|
||||||
is resolved)</td>
|
is resolved)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td>Random Access Iterator</td>
|
<tr><td>Random Access Iterator</td>
|
||||||
<td><tt class="docutils literal"><span class="pre">i[n]</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt> (also <tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt>
|
<td><tt class="docutils literal"><span class="pre">i[n]</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt> (also <tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt>
|
||||||
is required for mutable iterators once <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>
|
is required for mutable iterators once <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>
|
||||||
is resolved)</td>
|
is resolved)</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -141,7 +141,7 @@ is resolved)</td>
|
|||||||
single hierarchy, many useful iterators can not be appropriately
|
single hierarchy, many useful iterators can not be appropriately
|
||||||
categorized. For example, <tt class="docutils literal"><span class="pre">vector<bool>::iterator</span></tt> is almost a
|
categorized. For example, <tt class="docutils literal"><span class="pre">vector<bool>::iterator</span></tt> is almost a
|
||||||
random access iterator, but the return type is not <tt class="docutils literal"><span class="pre">bool&</span></tt> (see
|
random access iterator, but the return type is not <tt class="docutils literal"><span class="pre">bool&</span></tt> (see
|
||||||
<a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96">issue 96</a> and Herb Sutter's paper J16/99-0008 = WG21
|
<a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#96">issue 96</a> and Herb Sutter's paper J16/99-0008 = WG21
|
||||||
N1185). Therefore, the iterators of <tt class="docutils literal"><span class="pre">vector<bool></span></tt> only meet the
|
N1185). Therefore, the iterators of <tt class="docutils literal"><span class="pre">vector<bool></span></tt> only meet the
|
||||||
requirements of input iterator and output iterator. This is so
|
requirements of input iterator and output iterator. This is so
|
||||||
nonintuitive that the C++ standard contradicts itself on this point.
|
nonintuitive that the C++ standard contradicts itself on this point.
|
||||||
@ -344,7 +344,7 @@ approach for specifying <tt class="docutils literal"><span class="pre">operator[
|
|||||||
direction would mean that an iterator satisfying the old Random Access
|
direction would mean that an iterator satisfying the old Random Access
|
||||||
Iterator requirements would not necessarily be a model of Readable or
|
Iterator requirements would not necessarily be a model of Readable or
|
||||||
Writable Lvalue Iterator. Instead we have chosen a design that
|
Writable Lvalue Iterator. Instead we have chosen a design that
|
||||||
matches the preferred resolution of <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>: <tt class="docutils literal"><span class="pre">operator[]</span></tt> is
|
matches the preferred resolution of <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>: <tt class="docutils literal"><span class="pre">operator[]</span></tt> is
|
||||||
only required to return something convertible to the <tt class="docutils literal"><span class="pre">value_type</span></tt>
|
only required to return something convertible to the <tt class="docutils literal"><span class="pre">value_type</span></tt>
|
||||||
(for a Readable Iterator), and is required to support assignment
|
(for a Readable Iterator), and is required to support assignment
|
||||||
<tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt> (for a Writable Iterator).</p>
|
<tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt> (for a Writable Iterator).</p>
|
||||||
@ -976,7 +976,7 @@ struct random_access_traversal_tag : bidirectional_traversal_tag { };
|
|||||||
<div class="section" id="addition-to-lib-iterator-traits">
|
<div class="section" id="addition-to-lib-iterator-traits">
|
||||||
<h2><a class="toc-backref" href="#id23">Addition to [lib.iterator.traits]</a></h2>
|
<h2><a class="toc-backref" href="#id23">Addition to [lib.iterator.traits]</a></h2>
|
||||||
<p>The <tt class="docutils literal"><span class="pre">is_readable_iterator</span></tt> class
|
<p>The <tt class="docutils literal"><span class="pre">is_readable_iterator</span></tt> class
|
||||||
template satisfies the <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">UnaryTypeTrait</a> requirements.</p>
|
template satisfies the <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">UnaryTypeTrait</a> requirements.</p>
|
||||||
<p>Given an iterator type <tt class="docutils literal"><span class="pre">X</span></tt>, <tt class="docutils literal"><span class="pre">is_readable_iterator<X>::value</span></tt>
|
<p>Given an iterator type <tt class="docutils literal"><span class="pre">X</span></tt>, <tt class="docutils literal"><span class="pre">is_readable_iterator<X>::value</span></tt>
|
||||||
yields <tt class="docutils literal"><span class="pre">true</span></tt> if, for an object <tt class="docutils literal"><span class="pre">a</span></tt> of type <tt class="docutils literal"><span class="pre">X</span></tt>, <tt class="docutils literal"><span class="pre">*a</span></tt> is
|
yields <tt class="docutils literal"><span class="pre">true</span></tt> if, for an object <tt class="docutils literal"><span class="pre">a</span></tt> of type <tt class="docutils literal"><span class="pre">X</span></tt>, <tt class="docutils literal"><span class="pre">*a</span></tt> is
|
||||||
convertible to <tt class="docutils literal"><span class="pre">iterator_traits<X>::value_type</span></tt>, and <tt class="docutils literal"><span class="pre">false</span></tt>
|
convertible to <tt class="docutils literal"><span class="pre">iterator_traits<X>::value_type</span></tt>, and <tt class="docutils literal"><span class="pre">false</span></tt>
|
||||||
@ -1007,7 +1007,7 @@ otherwise.</p>
|
|||||||
</div>
|
</div>
|
||||||
<div class="section" id="footnotes">
|
<div class="section" id="footnotes">
|
||||||
<h1><a class="toc-backref" href="#id24">Footnotes</a></h1>
|
<h1><a class="toc-backref" href="#id24">Footnotes</a></h1>
|
||||||
<p>The UnaryTypeTrait concept is defined in <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">n1519</a>; the LWG is
|
<p>The UnaryTypeTrait concept is defined in <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">n1519</a>; the LWG is
|
||||||
considering adding the requirement that specializations are derived
|
considering adding the requirement that specializations are derived
|
||||||
from their nested <tt class="docutils literal"><span class="pre">::type</span></tt>.</p>
|
from their nested <tt class="docutils literal"><span class="pre">::type</span></tt>.</p>
|
||||||
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
||||||
|
@ -38,10 +38,10 @@
|
|||||||
|
|
||||||
.. contents:: Table of Contents
|
.. contents:: Table of Contents
|
||||||
|
|
||||||
.. _n1297: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html
|
.. _n1297: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1297.html
|
||||||
.. _n1477: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1477.html
|
.. _n1477: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1477.html
|
||||||
.. _n1531: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1531.html
|
.. _n1531: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1531.html
|
||||||
.. _n1550: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1550.html
|
.. _n1550: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1550.htm
|
||||||
|
|
||||||
============
|
============
|
||||||
Motivation
|
Motivation
|
||||||
@ -76,8 +76,8 @@ requirements in the iterator categories.
|
|||||||
| |is resolved) |
|
| |is resolved) |
|
||||||
+------------------------+-----------------------------------------------------+
|
+------------------------+-----------------------------------------------------+
|
||||||
|
|
||||||
.. _issue 200: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200
|
.. _issue 200: http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#200
|
||||||
.. _issue 299: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299
|
.. _issue 299: http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#299
|
||||||
|
|
||||||
|
|
||||||
Because iterator traversal and value access are mixed together in a
|
Because iterator traversal and value access are mixed together in a
|
||||||
@ -91,7 +91,7 @@ nonintuitive that the C++ standard contradicts itself on this point.
|
|||||||
In paragraph 23.2.4/1 it says that a ``vector`` is a sequence that
|
In paragraph 23.2.4/1 it says that a ``vector`` is a sequence that
|
||||||
supports random access iterators.
|
supports random access iterators.
|
||||||
|
|
||||||
.. _issue 96: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96
|
.. _issue 96: http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#96
|
||||||
|
|
||||||
Another difficult-to-categorize iterator is the transform iterator, an
|
Another difficult-to-categorize iterator is the transform iterator, an
|
||||||
adaptor which applies a unary function object to the dereferenced
|
adaptor which applies a unary function object to the dereferenced
|
||||||
@ -791,7 +791,7 @@ The UnaryTypeTrait concept is defined in n1519_; the LWG is
|
|||||||
considering adding the requirement that specializations are derived
|
considering adding the requirement that specializations are derived
|
||||||
from their nested ``::type``.
|
from their nested ``::type``.
|
||||||
|
|
||||||
.. _n1519: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm
|
.. _n1519: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1519.htm
|
||||||
|
|
||||||
..
|
..
|
||||||
LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
||||||
|
@ -132,7 +132,7 @@ above are defined as follows:
|
|||||||
|
|
||||||
iterator_adaptor();
|
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
|
[*Returns:] An instance of `iterator_adaptor` with
|
||||||
`m_iterator` default constructed.
|
`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| replace:: `iterator_facade` tutorial
|
||||||
.. _fac_tut: iterator_facade.html#tutorial-example
|
.. _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`
|
It's not really a very interesting iterator, since `node_base`
|
||||||
is an abstract class: a pointer to a `node_base` just points
|
is an abstract class: a pointer to a `node_base` just points
|
||||||
at some base subobject of an instance of some other class, and
|
at some base subobject of an instance of some other class, and
|
||||||
|
@ -156,7 +156,7 @@ semantics.
|
|||||||
[
|
[
|
||||||
[`++r`]
|
[`++r`]
|
||||||
[`X&`]
|
[`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`]
|
[`a == b`]
|
||||||
@ -227,7 +227,7 @@ the stated semantics.
|
|||||||
[
|
[
|
||||||
[`--r`]
|
[`--r`]
|
||||||
[`X&`]
|
[`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--`]
|
[`r--`]
|
||||||
|
@ -152,7 +152,7 @@ operations.
|
|||||||
|
|
||||||
counting_iterator();
|
counting_iterator();
|
||||||
|
|
||||||
[*Requires: ] `Incrementable` is Default Constructible.\n
|
[*Requires: ] `Incrementable` is Default Constructible.[br]
|
||||||
[*Effects: ] Default construct the member `m_inc`.
|
[*Effects: ] Default construct the member `m_inc`.
|
||||||
|
|
||||||
|
|
||||||
@ -174,13 +174,13 @@ operations.
|
|||||||
|
|
||||||
counting_iterator& operator++();
|
counting_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `++m_inc`\n
|
[*Effects: ] `++m_inc`[br]
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
counting_iterator& operator--();
|
counting_iterator& operator--();
|
||||||
|
|
||||||
[*Effects: ] `--m_inc`\n
|
[*Effects: ] `--m_inc`[br]
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ requirements.
|
|||||||
[
|
[
|
||||||
[`i.dereference()`]
|
[`i.dereference()`]
|
||||||
[Access the value referred to]
|
[Access the value referred to]
|
||||||
|
]
|
||||||
[
|
[
|
||||||
[`i.equal(j)`]
|
[`i.equal(j)`]
|
||||||
[Compare for equality with `j`]
|
[Compare for equality with `j`]
|
||||||
@ -83,6 +84,7 @@ requirements.
|
|||||||
[
|
[
|
||||||
[`i.advance(n)`]
|
[`i.advance(n)`]
|
||||||
[Advance by `n` positions]
|
[Advance by `n` positions]
|
||||||
|
]
|
||||||
[
|
[
|
||||||
[`i.distance_to(j)`]
|
[`i.distance_to(j)`]
|
||||||
[Measure the distance to `j`]
|
[Measure the distance to `j`]
|
||||||
@ -165,9 +167,9 @@ the implementation of her iterator is free to implement an
|
|||||||
class; it will hide the one supplied by `iterator_facade` from
|
class; it will hide the one supplied by `iterator_facade` from
|
||||||
clients of her iterator.
|
clients of her iterator.
|
||||||
|
|
||||||
.. _n1550: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html
|
.. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
|
||||||
|
|
||||||
.. _`issue 299`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
|
.. _`issue 299`: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299
|
||||||
|
|
||||||
.. _`operator arrow`:
|
.. _`operator arrow`:
|
||||||
|
|
||||||
@ -488,6 +490,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
[*Returns:]
|
[*Returns:]
|
||||||
|
|
||||||
|
[pre
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
@ -495,6 +498,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
|
`((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
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:]
|
[*Returns:]
|
||||||
|
|
||||||
|
[pre
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
@ -512,6 +517,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`!((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
|
`!((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
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:]
|
[*Returns:]
|
||||||
|
|
||||||
|
[pre
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
@ -529,6 +536,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0`.
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
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:]
|
[*Returns:]
|
||||||
|
|
||||||
|
[pre
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
@ -546,6 +555,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0`.
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
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:]
|
[*Returns:]
|
||||||
|
|
||||||
|
[pre
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
@ -563,6 +574,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0`.
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
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:]
|
[*Returns:]
|
||||||
|
|
||||||
|
[pre
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
@ -580,6 +593,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0`.
|
||||||
|
]
|
||||||
|
|
||||||
.. _minus:
|
.. _minus:
|
||||||
|
|
||||||
@ -592,6 +606,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
[*Return Type:]
|
[*Return Type:]
|
||||||
|
|
||||||
|
[pre
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
@ -600,9 +615,11 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
Otherwise
|
Otherwise
|
||||||
`difference` shall be `iterator_traits<Dr2>::difference_type`
|
`difference` shall be `iterator_traits<Dr2>::difference_type`
|
||||||
|
]
|
||||||
|
|
||||||
[*Returns:]
|
[*Returns:]
|
||||||
|
|
||||||
|
[pre
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
@ -610,6 +627,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)`.
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@ -261,17 +261,17 @@ __ ../example/node_iterator1.cpp
|
|||||||
|
|
||||||
[h2 A constant `node_iterator`]
|
[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 term **mutable iterator** means an iterator through which
|
||||||
the object it references (its "referent") can be modified. A
|
the object it references (its "referent") can be modified. A
|
||||||
**constant iterator** is one which doesn't allow modification of
|
**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
|
The words *constant* and *mutable* don't refer to the ability to
|
||||||
modify the iterator itself. For example, an `int const*` is a
|
modify the iterator itself. For example, an `int const*` is a
|
||||||
non-\ `const` *constant iterator*, which can be incremented
|
non-\ `const` *constant iterator*, which can be incremented
|
||||||
but doesn't allow modification of its referent, and `int*
|
but doesn't allow modification of its referent, and `int*
|
||||||
const` is a `const` *mutable iterator*, which cannot be
|
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
|
Confusing? We agree, but those are the standard terms. It
|
||||||
probably doesn't help much that a container's constant iterator
|
probably doesn't help much that a container's constant iterator
|
||||||
is called `const_iterator`.
|
is called `const_iterator`.
|
||||||
@ -312,7 +312,7 @@ changes:
|
|||||||
node_base **const**\ * m_node;
|
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
|
The C++ standard requires an iterator's `value_type` *not* be
|
||||||
`const`\ -qualified, so `iterator_facade` strips the
|
`const`\ -qualified, so `iterator_facade` strips the
|
||||||
`const` from its `Value` parameter in order to produce the
|
`const` from its `Value` parameter in order to produce the
|
||||||
|
@ -178,7 +178,7 @@ operations.
|
|||||||
|
|
||||||
filter_iterator();
|
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`
|
[*Effects: ] Constructs a `filter_iterator` whose`m_pred`, `m_iter`, and `m_end`
|
||||||
members are a default constructed.
|
members are a default constructed.
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ operations.
|
|||||||
filter_iterator(Iterator x, Iterator end = Iterator());
|
filter_iterator(Iterator x, Iterator end = Iterator());
|
||||||
|
|
||||||
[*Requires: ] `Predicate` must be Default Constructible and
|
[*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
|
[*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`
|
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.
|
or else`m_iter == end`. The member `m_pred` is default constructed.
|
||||||
@ -205,9 +205,9 @@ operations.
|
|||||||
filter_iterator(
|
filter_iterator(
|
||||||
filter_iterator<Predicate, OtherIterator> const& t
|
filter_iterator<Predicate, OtherIterator> const& t
|
||||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
, 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`.
|
[*Effects: ] Constructs a filter iterator whose members are copied from `t`.
|
||||||
|
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ operations.
|
|||||||
|
|
||||||
[*Effects: ] Increments `m_iter` and then continues to
|
[*Effects: ] Increments `m_iter` and then continues to
|
||||||
increment `m_iter` until either `m_iter == m_end`
|
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`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ following operations:
|
|||||||
|
|
||||||
indirect_iterator();
|
indirect_iterator();
|
||||||
|
|
||||||
[*Requires: ] `Iterator` must be Default Constructible.\n
|
[*Requires: ] `Iterator` must be Default Constructible.[br]
|
||||||
[*Effects: ] Constructs an instance of `indirect_iterator` with
|
[*Effects: ] Constructs an instance of `indirect_iterator` with
|
||||||
a default-constructed `m_iterator`.
|
a default-constructed `m_iterator`.
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ following operations:
|
|||||||
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
|
, 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
|
[*Effects: ] Constructs an instance of `indirect_iterator` whose
|
||||||
`m_iterator` subobject is constructed from `y.base()`.
|
`m_iterator` subobject is constructed from `y.base()`.
|
||||||
|
|
||||||
@ -242,13 +242,13 @@ following operations:
|
|||||||
|
|
||||||
indirect_iterator& operator++();
|
indirect_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `++m_iterator`\n
|
[*Effects: ] `++m_iterator`[br]
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
indirect_iterator& operator--();
|
indirect_iterator& operator--();
|
||||||
|
|
||||||
[*Effects: ] `--m_iterator`\n
|
[*Effects: ] `--m_iterator`[br]
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
[library Boost.Iterator
|
[library Boost.Iterator
|
||||||
[/ version 1.0.1]
|
[/ version 1.0.1]
|
||||||
|
[quickbook 1.6]
|
||||||
[authors [Abrahams, David], [Siek, Jeremy], [Witt, Thomas]]
|
[authors [Abrahams, David], [Siek, Jeremy], [Witt, Thomas]]
|
||||||
[copyright 2003 2005 David Abrahams Jeremy Siek Thomas Witt]
|
[copyright 2003 2005 David Abrahams Jeremy Siek Thomas Witt]
|
||||||
[category iterator]
|
[category iterator]
|
||||||
@ -99,7 +100,7 @@ adaptors`_ mentioned below have been proposed for standardization
|
|||||||
|
|
||||||
The iterator library supplies a useful suite of standard-conforming
|
The iterator library supplies a useful suite of standard-conforming
|
||||||
iterator templates based on the Boost [link
|
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.
|
templates.
|
||||||
|
|
||||||
[def _counting_ [@./counting_iterator.html `counting_iterator`]]
|
[def _counting_ [@./counting_iterator.html `counting_iterator`]]
|
||||||
|
@ -189,7 +189,7 @@ following operations.
|
|||||||
|
|
||||||
permutation_iterator& operator++();
|
permutation_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `++m_order`\n
|
[*Effects: ] `++m_order`[br]
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ operations.
|
|||||||
|
|
||||||
reverse_iterator();
|
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`
|
[*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator`
|
||||||
default constructed.
|
default constructed.
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ operations.
|
|||||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
, 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
|
[*Effects: ] Constructs instance of `reverse_iterator` whose
|
||||||
`m_iterator` subobject is constructed from `y.base()`.
|
`m_iterator` subobject is constructed from `y.base()`.
|
||||||
|
|
||||||
@ -149,12 +149,12 @@ operations.
|
|||||||
|
|
||||||
reverse_iterator& operator++();
|
reverse_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `--m_iterator`\n
|
[*Effects: ] `--m_iterator`[br]
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
reverse_iterator& operator--();
|
reverse_iterator& operator--();
|
||||||
|
|
||||||
[*Effects: ] `++m_iterator`\n
|
[*Effects: ] `++m_iterator`[br]
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -52,21 +52,4 @@ Header `<boost/iterator/iterator_traits.hpp>`:
|
|||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
|
|
||||||
[h2 Broken Compiler Notes]
|
|
||||||
|
|
||||||
Because of workarounds in Boost, you may find that these
|
|
||||||
[@../../mpl/doc/index.html#metafunctions metafunctions] actually work better than the facilities provided by
|
|
||||||
your compiler's standard library.
|
|
||||||
|
|
||||||
On compilers that don't support partial specialization, such as
|
|
||||||
Microsoft Visual C++ 6.0 or 7.0, you may need to manually invoke
|
|
||||||
[@../../type_traits/index.html#transformations BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION] on the
|
|
||||||
`value_type` of pointers that are passed to these metafunctions.
|
|
||||||
|
|
||||||
Because of bugs in the implementation of GCC-2.9x, the name of
|
|
||||||
`iterator_category` is changed to `iterator_category_` on that
|
|
||||||
compiler. A macro, `BOOST_ITERATOR_CATEGORY`, that expands to
|
|
||||||
either `iterator_category` or `iterator_category_`, as
|
|
||||||
appropriate to the platform, is provided for portability.
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -85,7 +85,7 @@ The source code for this example can be found
|
|||||||
|
|
||||||
|
|
||||||
If `Reference` is `use_default` then the `reference` member of
|
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`.
|
`result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
|
||||||
Otherwise, `reference` is `Reference`.
|
Otherwise, `reference` is `Reference`.
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ interoperable with `Y`.
|
|||||||
|
|
||||||
[h3 Operations]
|
[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
|
`transform_iterator`, `transform_iterator` provides the following
|
||||||
operations:
|
operations:
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ operations:
|
|||||||
|
|
||||||
[*Returns: ] An instance of `transform_iterator` with `m_f`
|
[*Returns: ] An instance of `transform_iterator` with `m_f`
|
||||||
initialized to `t.functor()` and `m_iterator` initialized to
|
initialized to `t.functor()` and `m_iterator` initialized to
|
||||||
`t.base()`.\n
|
`t.base()`.[br]
|
||||||
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.
|
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.
|
||||||
|
|
||||||
|
|
||||||
@ -204,13 +204,13 @@ operations:
|
|||||||
|
|
||||||
transform_iterator& operator++();
|
transform_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `++m_iterator`\n
|
[*Effects: ] `++m_iterator`[br]
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
transform_iterator& operator--();
|
transform_iterator& operator--();
|
||||||
|
|
||||||
[*Effects: ] `--m_iterator`\n
|
[*Effects: ] `--m_iterator`[br]
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@ -49,11 +49,40 @@ proxy references or return the pointee by value. When that
|
|||||||
information is needed, call on `indirect_reference`.
|
information is needed, call on `indirect_reference`.
|
||||||
|
|
||||||
Both of these templates are essential to the correct functioning of
|
Both of these templates are essential to the correct functioning of
|
||||||
[link indirecct `indirect_iterator`].
|
[link iterator.specialized.indirect `indirect_iterator`].
|
||||||
|
|
||||||
|
[h2 `minimum_category`]
|
||||||
|
|
||||||
|
`minimum_category` takes two iterator categories or two iterator traversal tags
|
||||||
|
and returns the one that is the weakest (i.e. least advanced). For example:
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
is_same<
|
||||||
|
minimum_category<
|
||||||
|
std::forward_iterator_tag,
|
||||||
|
std::random_access_iterator_tag
|
||||||
|
>::type,
|
||||||
|
std::forward_iterator_tag
|
||||||
|
>::value,
|
||||||
|
"Unexpected minimum_category result"
|
||||||
|
);
|
||||||
|
|
||||||
|
[h2 Iterator category and traversal tags manipulation]
|
||||||
|
|
||||||
|
The library provides several utilities to simplify conversions between iterator categories
|
||||||
|
and traversal tags:
|
||||||
|
|
||||||
|
* `iterator_category_to_traversal<C>::type` - the metafunction takes an iterator category `C` and returns
|
||||||
|
the corresponding traversal tag.
|
||||||
|
* `iterator_traversal<T>::type` - a shorthand for `iterator_category_to_traversal<iterator_category<T>::type>::type`.
|
||||||
|
* `pure_traversal_tag<T>::type` - the metafunction takes a tag `T` which derives from one of the iterator traversal tags
|
||||||
|
and returns that traversal tag. `T` may also derive from other tags describing the iterator (e.g. whether this is a `const`-iterator
|
||||||
|
or not), these additional tags are not considered.
|
||||||
|
* `pure_iterator_traversal<T>::type` - a shorthand for `pure_traversal_tag<iterator_traversal<T>::type>::type`.
|
||||||
|
|
||||||
[h2 Reference]
|
[h2 Reference]
|
||||||
|
|
||||||
[h3 `pointeee`]
|
[h3 `pointee`]
|
||||||
|
|
||||||
template <class Dereferenceable>
|
template <class Dereferenceable>
|
||||||
struct pointee
|
struct pointee
|
||||||
@ -74,9 +103,9 @@ Both of these templates are essential to the correct functioning of
|
|||||||
|
|
||||||
if ( ++x is ill-formed )
|
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)
|
std::iterator_traits<Dereferenceable>::value_type)
|
||||||
{
|
{
|
||||||
return iterator_traits<Dereferenceable>::value_type
|
return iterator_traits<Dereferenceable>::value_type
|
||||||
@ -106,10 +135,81 @@ Both of these templates are essential to the correct functioning of
|
|||||||
`x` is an object of type `Dereferenceable`:
|
`x` is an object of type `Dereferenceable`:
|
||||||
|
|
||||||
if ( ++x is ill-formed )
|
if ( ++x is ill-formed )
|
||||||
return `pointee<Dereferenceable>::type&`
|
return pointee<Dereferenceable>::type&
|
||||||
else
|
else
|
||||||
std::iterator_traits<Dereferenceable>::reference
|
std::iterator_traits<Dereferenceable>::reference
|
||||||
|
|
||||||
|
[h3 `minimum_category`]
|
||||||
|
|
||||||
|
template <typename C1, typename C2>
|
||||||
|
struct minimum_category
|
||||||
|
{
|
||||||
|
typedef /* see below */ type;
|
||||||
|
};
|
||||||
|
|
||||||
|
[*Requires:] Both `C1` and `C2` shall be standard iterator categories or
|
||||||
|
iterator traversal tags.
|
||||||
|
|
||||||
|
`type` is determined according to the following algorithm, where `c1` is an
|
||||||
|
object of type `C1` and `c2` is an object of type `C2`:
|
||||||
|
|
||||||
|
if (c1 is convertible to c2)
|
||||||
|
return C2;
|
||||||
|
else
|
||||||
|
return C1;
|
||||||
|
|
||||||
|
[note The above definition relies on the fact that the more restricting categories
|
||||||
|
and traversal tags are convertible to the less restricting ones.]
|
||||||
|
|
||||||
|
[h3 `iterator_category_to_traversal`]
|
||||||
|
|
||||||
|
template <typename C>
|
||||||
|
struct iterator_category_to_traversal
|
||||||
|
{
|
||||||
|
typedef /* see below */ type;
|
||||||
|
};
|
||||||
|
|
||||||
|
[*Requires:] `C` shall be a standard iterator category or an
|
||||||
|
iterator traversal tag.
|
||||||
|
|
||||||
|
If `C` is an iterator traversal tag or convertible to one, `type` equivalent to `C`.
|
||||||
|
Otherwise, `type` is defined to the closest iterator traversal tag matching `C`.
|
||||||
|
|
||||||
|
[h3 `iterator_traversal`]
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
struct iterator_traversal
|
||||||
|
{
|
||||||
|
typedef typename iterator_category_to_traversal<
|
||||||
|
typename iterator_category<Iterator>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
[*Requires:] `Iterator` shall be an iterator.
|
||||||
|
|
||||||
|
[h3 `pure_traversal_tag`]
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct pure_traversal_tag
|
||||||
|
{
|
||||||
|
typedef /* see below */ type;
|
||||||
|
};
|
||||||
|
|
||||||
|
[*Requires:] `T` shall be convertible to an iterator traversal tag.
|
||||||
|
|
||||||
|
`type` is defined to be the most advanced traversal tag `Tag` so that `T` is convertible to `Tag`.
|
||||||
|
|
||||||
|
[h3 `pure_iterator_traversal`]
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
struct pure_iterator_traversal
|
||||||
|
{
|
||||||
|
typedef typename pure_traversal_tag<
|
||||||
|
typename iterator_traversal<Iterator>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
[*Requires:] `Iterator` shall be an iterator.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
@ -8,6 +8,16 @@ the zip iterator moves all the iterators in parallel.
|
|||||||
Dereferencing the zip iterator returns a tuple that contains
|
Dereferencing the zip iterator returns a tuple that contains
|
||||||
the results of dereferencing the individual iterators.
|
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]
|
[section:zip_example Example]
|
||||||
|
|
||||||
There are two main types of applications of the `zip_iterator`. The first
|
There are two main types of applications of the `zip_iterator`. The first
|
||||||
@ -218,7 +228,7 @@ operations.
|
|||||||
, IteratorTuple>::type* = 0 // exposition only
|
, 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`.
|
[*Requires:] `OtherIteratorTuple` is implicitly convertible to `IteratorTuple`.
|
||||||
|
|
||||||
|
|
||||||
@ -235,13 +245,13 @@ operations.
|
|||||||
|
|
||||||
zip_iterator& operator++();
|
zip_iterator& operator++();
|
||||||
|
|
||||||
[*Effects:] Increments each iterator in `m_iterator_tuple`.\n
|
[*Effects:] Increments each iterator in `m_iterator_tuple`.[br]
|
||||||
[*Returns:] `*this`
|
[*Returns:] `*this`
|
||||||
|
|
||||||
|
|
||||||
zip_iterator& operator--();
|
zip_iterator& operator--();
|
||||||
|
|
||||||
[*Effects:] Decrements each iterator in `m_iterator_tuple`.\n
|
[*Effects:] Decrements each iterator in `m_iterator_tuple`.[br]
|
||||||
[*Returns:] `*this`
|
[*Returns:] `*this`
|
||||||
|
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
.. _N1550: http://www.boost-consulting.com/writing/n1550.html
|
.. _N1550: http://www.boost-consulting.com/writing/n1550.html
|
||||||
.. _N1530: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html
|
.. _N1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html
|
||||||
|
|
||||||
:Author: David Abrahams and Jeremy Siek
|
:Author: David Abrahams and Jeremy Siek
|
||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
||||||
|
@ -6,6 +6,7 @@ sources = [
|
|||||||
'counting_iterator.rst',
|
'counting_iterator.rst',
|
||||||
'facade-and-adaptor.rst',
|
'facade-and-adaptor.rst',
|
||||||
'filter_iterator.rst',
|
'filter_iterator.rst',
|
||||||
|
'function_input_iterator.rst',
|
||||||
'function_output_iterator.rst',
|
'function_output_iterator.rst',
|
||||||
'index.rst',
|
'index.rst',
|
||||||
'indirect_iterator.rst',
|
'indirect_iterator.rst',
|
||||||
|
@ -99,7 +99,7 @@ private:
|
|||||||
</pre>
|
</pre>
|
||||||
<p>If <tt class="docutils literal"><span class="pre">Reference</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">reference</span></tt> member of
|
<p>If <tt class="docutils literal"><span class="pre">Reference</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">reference</span></tt> member of
|
||||||
<tt class="docutils literal"><span class="pre">transform_iterator</span></tt> is
|
<tt class="docutils literal"><span class="pre">transform_iterator</span></tt> is
|
||||||
<tt class="docutils literal"><span class="pre">result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>.
|
<tt class="docutils literal"><span class="pre">result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>.
|
||||||
Otherwise, <tt class="docutils literal"><span class="pre">reference</span></tt> is <tt class="docutils literal"><span class="pre">Reference</span></tt>.</p>
|
Otherwise, <tt class="docutils literal"><span class="pre">reference</span></tt> is <tt class="docutils literal"><span class="pre">Reference</span></tt>.</p>
|
||||||
<p>If <tt class="docutils literal"><span class="pre">Value</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">value_type</span></tt> member is
|
<p>If <tt class="docutils literal"><span class="pre">Value</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">value_type</span></tt> member is
|
||||||
<tt class="docutils literal"><span class="pre">remove_cv<remove_reference<reference></span> <span class="pre">>::type</span></tt>. Otherwise,
|
<tt class="docutils literal"><span class="pre">remove_cv<remove_reference<reference></span> <span class="pre">>::type</span></tt>. Otherwise,
|
||||||
@ -117,10 +117,10 @@ convertible to <tt class="docutils literal"><span class="pre">input_iterator_tag
|
|||||||
<div class="section" id="transform-iterator-requirements">
|
<div class="section" id="transform-iterator-requirements">
|
||||||
<h1><a class="toc-backref" href="#id3"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
|
<h1><a class="toc-backref" href="#id3"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
|
||||||
<p>The type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and
|
<p>The type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and
|
||||||
the expression <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be valid where <tt class="docutils literal"><span class="pre">f</span></tt> is an object of
|
the expression <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be valid where <tt class="docutils literal"><span class="pre">f</span></tt> is a const object of
|
||||||
type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt>, <tt class="docutils literal"><span class="pre">i</span></tt> is an object of type <tt class="docutils literal"><span class="pre">Iterator</span></tt>, and
|
type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt>, <tt class="docutils literal"><span class="pre">i</span></tt> is an object of type <tt class="docutils literal"><span class="pre">Iterator</span></tt>, and
|
||||||
where the type of <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be
|
where the type of <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be
|
||||||
<tt class="docutils literal"><span class="pre">result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>.</p>
|
<tt class="docutils literal"><span class="pre">result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>.</p>
|
||||||
<p>The argument <tt class="docutils literal"><span class="pre">Iterator</span></tt> shall model Readable Iterator.</p>
|
<p>The argument <tt class="docutils literal"><span class="pre">Iterator</span></tt> shall model Readable Iterator.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="transform-iterator-models">
|
<div class="section" id="transform-iterator-models">
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
If ``Reference`` is ``use_default`` then the ``reference`` member of
|
If ``Reference`` is ``use_default`` then the ``reference`` member of
|
||||||
``transform_iterator`` is
|
``transform_iterator`` is
|
||||||
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
|
``result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
|
||||||
Otherwise, ``reference`` is ``Reference``.
|
Otherwise, ``reference`` is ``Reference``.
|
||||||
|
|
||||||
If ``Value`` is ``use_default`` then the ``value_type`` member is
|
If ``Value`` is ``use_default`` then the ``value_type`` member is
|
||||||
@ -64,10 +64,10 @@ convertible to ``input_iterator_tag``.
|
|||||||
...................................
|
...................................
|
||||||
|
|
||||||
The type ``UnaryFunction`` must be Assignable, Copy Constructible, and
|
The type ``UnaryFunction`` must be Assignable, Copy Constructible, and
|
||||||
the expression ``f(*i)`` must be valid where ``f`` is an object of
|
the expression ``f(*i)`` must be valid where ``f`` is a const object of
|
||||||
type ``UnaryFunction``, ``i`` is an object of type ``Iterator``, and
|
type ``UnaryFunction``, ``i`` is an object of type ``Iterator``, and
|
||||||
where the type of ``f(*i)`` must be
|
where the type of ``f(*i)`` must be
|
||||||
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
|
``result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
|
||||||
|
|
||||||
The argument ``Iterator`` shall model Readable Iterator.
|
The argument ``Iterator`` shall model Readable Iterator.
|
||||||
|
|
||||||
|
@ -8,3 +8,13 @@ iterator is constructed from a tuple of iterators. Moving
|
|||||||
the zip iterator moves all the iterators in parallel.
|
the zip iterator moves all the iterators in parallel.
|
||||||
Dereferencing the zip iterator returns a tuple that contains
|
Dereferencing the zip iterator returns a tuple that contains
|
||||||
the results of dereferencing the individual iterators.
|
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'.
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
template <class UnaryFunction>
|
template <class UnaryFunction>
|
||||||
class function_output_iterator {
|
class function_output_iterator {
|
||||||
@ -51,6 +52,11 @@ namespace boost {
|
|||||||
return function_output_iterator<UnaryFunction>(f);
|
return function_output_iterator<UnaryFunction>(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::function_output_iterator;
|
||||||
|
using iterators::make_function_output_iterator;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
||||||
|
85
include/boost/generator_iterator.hpp
Normal file
85
include/boost/generator_iterator.hpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// (C) Copyright Jens Maurer 2001.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// Revision History:
|
||||||
|
|
||||||
|
// 15 Nov 2001 Jens Maurer
|
||||||
|
// created.
|
||||||
|
|
||||||
|
// See http://www.boost.org/libs/utility/iterator_adaptors.htm for documentation.
|
||||||
|
|
||||||
|
#ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
||||||
|
#define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
||||||
|
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
|
#include <boost/ref.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
|
template<class Generator>
|
||||||
|
class generator_iterator
|
||||||
|
: public iterator_facade<
|
||||||
|
generator_iterator<Generator>
|
||||||
|
, typename Generator::result_type
|
||||||
|
, single_pass_traversal_tag
|
||||||
|
, typename Generator::result_type const&
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef iterator_facade<
|
||||||
|
generator_iterator<Generator>
|
||||||
|
, typename Generator::result_type
|
||||||
|
, single_pass_traversal_tag
|
||||||
|
, typename Generator::result_type const&
|
||||||
|
> super_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
generator_iterator() {}
|
||||||
|
generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {}
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
m_value = (*m_g)();
|
||||||
|
}
|
||||||
|
|
||||||
|
const typename Generator::result_type&
|
||||||
|
dereference() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal(generator_iterator const& y) const
|
||||||
|
{
|
||||||
|
return this->m_g == y.m_g && this->m_value == y.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Generator* m_g;
|
||||||
|
typename Generator::result_type m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Generator>
|
||||||
|
struct generator_iterator_generator
|
||||||
|
{
|
||||||
|
typedef generator_iterator<Generator> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Generator>
|
||||||
|
inline generator_iterator<Generator>
|
||||||
|
make_generator_iterator(Generator & gen)
|
||||||
|
{
|
||||||
|
typedef generator_iterator<Generator> result_t;
|
||||||
|
return result_t(&gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::generator_iterator;
|
||||||
|
using iterators::generator_iterator_generator;
|
||||||
|
using iterators::make_generator_iterator;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
43
include/boost/indirect_reference.hpp
Normal file
43
include/boost/indirect_reference.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef INDIRECT_REFERENCE_DWA200415_HPP
|
||||||
|
# define INDIRECT_REFERENCE_DWA200415_HPP
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copyright David Abrahams 2004. Use, modification and distribution is
|
||||||
|
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// typename indirect_reference<P>::type provides the type of *p.
|
||||||
|
//
|
||||||
|
// http://www.boost.org/libs/iterator/doc/pointee.html
|
||||||
|
//
|
||||||
|
|
||||||
|
# include <boost/detail/is_incrementable.hpp>
|
||||||
|
# include <boost/iterator/iterator_traits.hpp>
|
||||||
|
# include <boost/type_traits/remove_cv.hpp>
|
||||||
|
# include <boost/mpl/eval_if.hpp>
|
||||||
|
# include <boost/pointee.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template <class P>
|
||||||
|
struct smart_ptr_reference
|
||||||
|
{
|
||||||
|
typedef typename boost::pointee<P>::type& type;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class P>
|
||||||
|
struct indirect_reference
|
||||||
|
: mpl::eval_if<
|
||||||
|
detail::is_incrementable<P>
|
||||||
|
, iterator_reference<P>
|
||||||
|
, detail::smart_ptr_reference<P>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // INDIRECT_REFERENCE_DWA200415_HPP
|
@ -1,59 +0,0 @@
|
|||||||
// interator.hpp workarounds for non-conforming standard libraries ---------//
|
|
||||||
|
|
||||||
// (C) Copyright Beman Dawes 2000. 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/libs/utility for documentation.
|
|
||||||
|
|
||||||
// Revision History
|
|
||||||
// 12 Jan 01 added <cstddef> for std::ptrdiff_t (Jens Maurer)
|
|
||||||
// 28 Jun 00 Workarounds to deal with known MSVC bugs (David Abrahams)
|
|
||||||
// 26 Jun 00 Initial version (Jeremy Siek)
|
|
||||||
|
|
||||||
#ifndef BOOST_ITERATOR_HPP
|
|
||||||
#define BOOST_ITERATOR_HPP
|
|
||||||
|
|
||||||
#include <iterator>
|
|
||||||
#include <cstddef> // std::ptrdiff_t
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
# if defined(BOOST_NO_STD_ITERATOR) && !defined(BOOST_MSVC_STD_ITERATOR)
|
|
||||||
template <class Category, class T,
|
|
||||||
class Distance = std::ptrdiff_t,
|
|
||||||
class Pointer = T*, class Reference = T&>
|
|
||||||
struct iterator
|
|
||||||
{
|
|
||||||
typedef T value_type;
|
|
||||||
typedef Distance difference_type;
|
|
||||||
typedef Pointer pointer;
|
|
||||||
typedef Reference reference;
|
|
||||||
typedef Category iterator_category;
|
|
||||||
};
|
|
||||||
# else
|
|
||||||
|
|
||||||
// declare iterator_base in namespace detail to work around MSVC bugs which
|
|
||||||
// prevent derivation from an identically-named class in a different namespace.
|
|
||||||
namespace detail {
|
|
||||||
template <class Category, class T, class Distance, class Pointer, class Reference>
|
|
||||||
# if !defined(BOOST_MSVC_STD_ITERATOR)
|
|
||||||
struct iterator_base : std::iterator<Category, T, Distance, Pointer, Reference> {};
|
|
||||||
# else
|
|
||||||
struct iterator_base : std::iterator<Category, T, Distance>
|
|
||||||
{
|
|
||||||
typedef Reference reference;
|
|
||||||
typedef Pointer pointer;
|
|
||||||
typedef Distance difference_type;
|
|
||||||
};
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Category, class T, class Distance = std::ptrdiff_t,
|
|
||||||
class Pointer = T*, class Reference = T&>
|
|
||||||
struct iterator : boost::detail::iterator_base<Category, T, Distance, Pointer, Reference> {};
|
|
||||||
# endif
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_HPP
|
|
84
include/boost/iterator/advance.hpp
Normal file
84
include/boost/iterator/advance.hpp
Normal 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
|
@ -13,6 +13,7 @@
|
|||||||
# include <boost/mpl/eval_if.hpp>
|
# include <boost/mpl/eval_if.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class Incrementable
|
class Incrementable
|
||||||
@ -52,7 +53,7 @@ namespace detail
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct is_numeric
|
struct is_numeric
|
||||||
: mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
|
: mpl::bool_<(::boost::iterators::detail::is_numeric_impl<T>::value)>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
# if defined(BOOST_HAS_LONG_LONG)
|
# if defined(BOOST_HAS_LONG_LONG)
|
||||||
@ -136,7 +137,7 @@ namespace detail
|
|||||||
{
|
{
|
||||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||||
{
|
{
|
||||||
return numeric_distance(x, y);
|
return boost::detail::numeric_distance(x, y);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -209,7 +210,11 @@ make_counting_iterator(Incrementable x)
|
|||||||
return result_t(x);
|
return result_t(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
} // namespace boost::iterator
|
using iterators::counting_iterator;
|
||||||
|
using iterators::make_counting_iterator;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
#endif // COUNTING_ITERATOR_DWA200348_HPP
|
#endif // COUNTING_ITERATOR_DWA200348_HPP
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP
|
#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||||
# define ANY_CONVERSION_EATER_DWA20031117_HPP
|
# define ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||||
|
|
||||||
namespace boost { namespace detail {
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
// This type can be used in traits to "eat" up the one user-defined
|
// This type can be used in traits to "eat" up the one user-defined
|
||||||
// implicit conversion allowed.
|
// implicit conversion allowed.
|
||||||
@ -14,6 +16,6 @@ struct any_conversion_eater
|
|||||||
any_conversion_eater(T const&);
|
any_conversion_eater(T const&);
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace boost::detail
|
}}} // namespace boost::iterators::detail
|
||||||
|
|
||||||
#endif // ANY_CONVERSION_EATER_DWA20031117_HPP
|
#endif // ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||||
|
@ -46,8 +46,7 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x5A0)) \
|
||||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531)) \
|
|
||||||
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \
|
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \
|
||||||
|| BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) \
|
|| BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) \
|
||||||
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||||
@ -88,8 +87,7 @@
|
|||||||
# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types"
|
# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(__GNUC__, == 2) \
|
#if BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \
|
||||||
|| BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \
|
|
||||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
# define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile:
|
# define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile:
|
||||||
|
|
||||||
@ -116,16 +114,9 @@
|
|||||||
# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||||
# define BOOST_ARG_DEPENDENT_TYPENAME typename
|
|
||||||
# else
|
|
||||||
# define BOOST_ARG_DEPENDENT_TYPENAME
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(__GNUC__, == 2) && BOOST_WORKAROUND(__GNUC_MINOR__, BOOST_TESTED_AT(95)) \
|
// GCC-2.95 (obsolete) eagerly instantiates templated constructors and conversion
|
||||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
|
||||||
|
|
||||||
// GCC-2.95 eagerly instantiates templated constructors and conversion
|
|
||||||
// operators in convertibility checks, causing premature errors.
|
// operators in convertibility checks, causing premature errors.
|
||||||
//
|
//
|
||||||
// Borland's problems are harder to diagnose due to lack of an
|
// Borland's problems are harder to diagnose due to lack of an
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#undef BOOST_NO_IS_CONVERTIBLE
|
#undef BOOST_NO_IS_CONVERTIBLE
|
||||||
#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
|
#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
|
||||||
#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||||
#undef BOOST_ARG_DEPENDENT_TYPENAME
|
|
||||||
#undef BOOST_NO_LVALUE_RETURN_DETECTION
|
#undef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||||
#undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
|
#undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
|
||||||
|
|
||||||
|
@ -72,9 +72,6 @@ namespace boost
|
|||||||
: mpl::identity<Return>
|
: mpl::identity<Return>
|
||||||
# endif
|
# endif
|
||||||
{
|
{
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
typedef Return type;
|
|
||||||
# endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace iterators
|
} // namespace iterators
|
||||||
|
@ -30,10 +30,13 @@
|
|||||||
// iterator_category deduction for iterator_facade
|
// iterator_category deduction for iterator_facade
|
||||||
//
|
//
|
||||||
|
|
||||||
// forward declaration
|
namespace boost {
|
||||||
namespace boost { struct use_default; }
|
namespace iterators {
|
||||||
|
|
||||||
namespace boost { namespace detail {
|
// forward declaration
|
||||||
|
struct use_default;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
struct input_output_iterator_tag
|
struct input_output_iterator_tag
|
||||||
: std::input_iterator_tag
|
: std::input_iterator_tag
|
||||||
@ -73,16 +76,10 @@ struct iterator_writability_disabled
|
|||||||
// Convert an iterator_facade's traversal category, Value parameter,
|
// Convert an iterator_facade's traversal category, Value parameter,
|
||||||
// and ::reference type to an appropriate old-style category.
|
// and ::reference type to an appropriate old-style category.
|
||||||
//
|
//
|
||||||
// If writability has been disabled per the above metafunction, the
|
// Due to changeset 21683, this now never results in a category convertible
|
||||||
// result will not be convertible to output_iterator_tag.
|
// to output_iterator_tag.
|
||||||
//
|
|
||||||
// Otherwise, if Traversal == single_pass_traversal_tag, the following
|
|
||||||
// conditions will result in a tag that is convertible both to
|
|
||||||
// input_iterator_tag and output_iterator_tag:
|
|
||||||
//
|
|
||||||
// 1. Reference is a reference to non-const
|
|
||||||
// 2. Reference is not a reference and is convertible to Value
|
|
||||||
//
|
//
|
||||||
|
// Change at: https://svn.boost.org/trac/boost/changeset/21683
|
||||||
template <class Traversal, class ValueParam, class Reference>
|
template <class Traversal, class ValueParam, class Reference>
|
||||||
struct iterator_facade_default_category
|
struct iterator_facade_default_category
|
||||||
: mpl::eval_if<
|
: mpl::eval_if<
|
||||||
@ -138,7 +135,6 @@ template <class Category, class Traversal>
|
|||||||
struct iterator_category_with_traversal
|
struct iterator_category_with_traversal
|
||||||
: Category, Traversal
|
: Category, Traversal
|
||||||
{
|
{
|
||||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
|
||||||
// Make sure this isn't used to build any categories where
|
// Make sure this isn't used to build any categories where
|
||||||
// convertibility to Traversal is redundant. Should just use the
|
// convertibility to Traversal is redundant. Should just use the
|
||||||
// Category element in that case.
|
// Category element in that case.
|
||||||
@ -154,7 +150,6 @@ struct iterator_category_with_traversal
|
|||||||
# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
|
# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
|
||||||
BOOST_MPL_ASSERT((is_iterator_traversal<Traversal>));
|
BOOST_MPL_ASSERT((is_iterator_traversal<Traversal>));
|
||||||
# endif
|
# endif
|
||||||
# endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Computes an iterator_category tag whose traversal is Traversal and
|
// Computes an iterator_category tag whose traversal is Traversal and
|
||||||
@ -162,9 +157,7 @@ struct iterator_category_with_traversal
|
|||||||
template <class Traversal, class ValueParam, class Reference>
|
template <class Traversal, class ValueParam, class Reference>
|
||||||
struct facade_iterator_category_impl
|
struct facade_iterator_category_impl
|
||||||
{
|
{
|
||||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
|
||||||
BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
|
BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
|
||||||
# endif
|
|
||||||
|
|
||||||
typedef typename iterator_facade_default_category<
|
typedef typename iterator_facade_default_category<
|
||||||
Traversal,ValueParam,Reference
|
Traversal,ValueParam,Reference
|
||||||
@ -193,7 +186,7 @@ struct facade_iterator_category
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace boost::detail
|
}}} // namespace boost::iterators::detail
|
||||||
|
|
||||||
# include <boost/iterator/detail/config_undef.hpp>
|
# include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
|
||||||
|
@ -4,113 +4,16 @@
|
|||||||
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP
|
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP
|
||||||
# define MINIMUM_CATEGORY_DWA20031119_HPP
|
# define MINIMUM_CATEGORY_DWA20031119_HPP
|
||||||
|
|
||||||
# include <boost/type_traits/is_convertible.hpp>
|
# include <boost/iterator/minimum_category.hpp>
|
||||||
# include <boost/type_traits/is_same.hpp>
|
|
||||||
|
|
||||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
namespace boost {
|
||||||
|
|
||||||
namespace boost { namespace detail {
|
// This import below (as well as the whole header) is for backward compatibility
|
||||||
//
|
// with boost/token_iterator.hpp. It should be removed as soon as that header is fixed.
|
||||||
// Returns the minimum category type or error_type
|
namespace detail {
|
||||||
// if T1 and T2 are unrelated.
|
using iterators::minimum_category;
|
||||||
//
|
} // namespace detail
|
||||||
// For compilers not supporting is_convertible this only
|
|
||||||
// works with the new boost return and traversal category
|
|
||||||
// types. The exact boost _types_ are required. No derived types
|
|
||||||
// will work.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
template <bool GreaterEqual, bool LessEqual>
|
|
||||||
struct minimum_category_impl
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
{
|
|
||||||
template <class T1, class T2> struct apply
|
|
||||||
{
|
|
||||||
typedef T2 type;
|
|
||||||
};
|
|
||||||
typedef void type;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
;
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
} // namespace boost
|
||||||
struct error_not_related_by_convertibility;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct minimum_category_impl<true,false>
|
|
||||||
{
|
|
||||||
template <class T1, class T2> struct apply
|
|
||||||
{
|
|
||||||
typedef T2 type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct minimum_category_impl<false,true>
|
|
||||||
{
|
|
||||||
template <class T1, class T2> struct apply
|
|
||||||
{
|
|
||||||
typedef T1 type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct minimum_category_impl<true,true>
|
|
||||||
{
|
|
||||||
template <class T1, class T2> struct apply
|
|
||||||
{
|
|
||||||
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
|
|
||||||
typedef T1 type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct minimum_category_impl<false,false>
|
|
||||||
{
|
|
||||||
template <class T1, class T2> struct apply
|
|
||||||
: error_not_related_by_convertibility<T1,T2>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T1 = mpl::_1, class T2 = mpl::_2>
|
|
||||||
struct minimum_category
|
|
||||||
{
|
|
||||||
typedef minimum_category_impl<
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
|
|
||||||
is_same<T2,int>::value ||
|
|
||||||
# endif
|
|
||||||
::boost::is_convertible<T1,T2>::value
|
|
||||||
, ::boost::is_convertible<T2,T1>::value
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
|
|
||||||
|| is_same<T1,int>::value
|
|
||||||
# endif
|
|
||||||
> outer;
|
|
||||||
|
|
||||||
typedef typename outer::template apply<T1,T2> inner;
|
|
||||||
typedef typename inner::type type;
|
|
||||||
|
|
||||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct minimum_category<mpl::_1,mpl::_2>
|
|
||||||
{
|
|
||||||
template <class T1, class T2>
|
|
||||||
struct apply : minimum_category<T1,T2>
|
|
||||||
{};
|
|
||||||
|
|
||||||
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2))
|
|
||||||
};
|
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
|
|
||||||
template <>
|
|
||||||
struct minimum_category<int,int>
|
|
||||||
{
|
|
||||||
typedef int type;
|
|
||||||
};
|
|
||||||
# endif
|
|
||||||
|
|
||||||
}} // namespace boost::detail
|
|
||||||
|
|
||||||
#endif // MINIMUM_CATEGORY_DWA20031119_HPP
|
#endif // MINIMUM_CATEGORY_DWA20031119_HPP
|
||||||
|
65
include/boost/iterator/distance.hpp
Normal file
65
include/boost/iterator/distance.hpp
Normal 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
|
@ -14,8 +14,9 @@
|
|||||||
#include <boost/type_traits/is_class.hpp>
|
#include <boost/type_traits/is_class.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost {
|
||||||
{
|
namespace iterators {
|
||||||
|
|
||||||
template <class Predicate, class Iterator>
|
template <class Predicate, class Iterator>
|
||||||
class filter_iterator;
|
class filter_iterator;
|
||||||
|
|
||||||
@ -108,28 +109,29 @@ namespace boost
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class Predicate, class Iterator>
|
template <class Predicate, class Iterator>
|
||||||
filter_iterator<Predicate,Iterator>
|
inline filter_iterator<Predicate,Iterator>
|
||||||
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
|
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
|
||||||
{
|
{
|
||||||
return filter_iterator<Predicate,Iterator>(f,x,end);
|
return filter_iterator<Predicate,Iterator>(f,x,end);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Predicate, class Iterator>
|
template <class Predicate, class Iterator>
|
||||||
filter_iterator<Predicate,Iterator>
|
inline filter_iterator<Predicate,Iterator>
|
||||||
make_filter_iterator(
|
make_filter_iterator(
|
||||||
typename iterators::enable_if<
|
typename iterators::enable_if<
|
||||||
is_class<Predicate>
|
is_class<Predicate>
|
||||||
, Iterator
|
, Iterator
|
||||||
>::type x
|
>::type x
|
||||||
, Iterator end = Iterator()
|
, Iterator end = Iterator())
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
, Predicate* = 0
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return filter_iterator<Predicate,Iterator>(x,end);
|
return filter_iterator<Predicate,Iterator>(x,end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::filter_iterator;
|
||||||
|
using iterators::make_filter_iterator;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP
|
#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP
|
||||||
|
171
include/boost/iterator/function_input_iterator.hpp
Normal file
171
include/boost/iterator/function_input_iterator.hpp
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
// Copyright 2009 (C) Dean Michael Berris <me@deanberris.com>
|
||||||
|
// Copyright 2012 (C) Google, Inc.
|
||||||
|
// Copyright 2012 (C) Jeffrey Lee Hellrung, Jr.
|
||||||
|
// 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_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>
|
||||||
|
#include <boost/function_types/is_function_reference.hpp>
|
||||||
|
#include <boost/function_types/result_type.hpp>
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
|
#include <boost/none.hpp>
|
||||||
|
#include <boost/optional/optional.hpp>
|
||||||
|
#include <boost/utility/result_of.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
template <class Function, class Input>
|
||||||
|
class function_input_iterator
|
||||||
|
: public iterator_facade<
|
||||||
|
function_input_iterator<Function, Input>,
|
||||||
|
BOOST_DEDUCED_TYPENAME result_of<Function ()>::type,
|
||||||
|
single_pass_traversal_tag,
|
||||||
|
BOOST_DEDUCED_TYPENAME result_of<Function ()>::type const &
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
function_input_iterator() {}
|
||||||
|
function_input_iterator(Function & f_, Input state_ = Input())
|
||||||
|
: f(&f_), state(state_) {}
|
||||||
|
|
||||||
|
void increment() {
|
||||||
|
if(value)
|
||||||
|
value = none;
|
||||||
|
else
|
||||||
|
(*f)();
|
||||||
|
++state;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_DEDUCED_TYPENAME result_of<Function ()>::type const &
|
||||||
|
dereference() const {
|
||||||
|
return (value ? value : value = (*f)()).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal(function_input_iterator const & other) const {
|
||||||
|
return f == other.f && state == other.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Function * f;
|
||||||
|
Input state;
|
||||||
|
mutable optional<BOOST_DEDUCED_TYPENAME result_of<Function ()>::type> value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Function, class Input>
|
||||||
|
class function_pointer_input_iterator
|
||||||
|
: public iterator_facade<
|
||||||
|
function_pointer_input_iterator<Function, Input>,
|
||||||
|
typename function_types::result_type<Function>::type,
|
||||||
|
single_pass_traversal_tag,
|
||||||
|
typename function_types::result_type<Function>::type const &
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
function_pointer_input_iterator() {}
|
||||||
|
function_pointer_input_iterator(Function &f_, Input state_ = Input())
|
||||||
|
: f(f_), state(state_) {}
|
||||||
|
|
||||||
|
void increment() {
|
||||||
|
if(value)
|
||||||
|
value = none;
|
||||||
|
else
|
||||||
|
(*f)();
|
||||||
|
++state;
|
||||||
|
}
|
||||||
|
|
||||||
|
typename function_types::result_type<Function>::type const &
|
||||||
|
dereference() const {
|
||||||
|
return (value ? value : value = (*f)()).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal(function_pointer_input_iterator const & other) const {
|
||||||
|
return f == other.f && state == other.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Function f;
|
||||||
|
Input state;
|
||||||
|
mutable optional<typename function_types::result_type<Function>::type> value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Function, class Input>
|
||||||
|
class function_reference_input_iterator
|
||||||
|
: public function_pointer_input_iterator<Function*,Input>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
function_reference_input_iterator(Function & f_, Input state_ = Input())
|
||||||
|
: function_pointer_input_iterator<Function*,Input>(&f_, state_)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace impl
|
||||||
|
|
||||||
|
template <class Function, class Input>
|
||||||
|
class function_input_iterator
|
||||||
|
: public mpl::if_<
|
||||||
|
function_types::is_function_pointer<Function>,
|
||||||
|
impl::function_pointer_input_iterator<Function,Input>,
|
||||||
|
typename mpl::if_<
|
||||||
|
function_types::is_function_reference<Function>,
|
||||||
|
impl::function_reference_input_iterator<Function,Input>,
|
||||||
|
impl::function_input_iterator<Function,Input>
|
||||||
|
>::type
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
function_types::is_function_pointer<Function>,
|
||||||
|
impl::function_pointer_input_iterator<Function,Input>,
|
||||||
|
typename mpl::if_<
|
||||||
|
function_types::is_function_reference<Function>,
|
||||||
|
impl::function_reference_input_iterator<Function,Input>,
|
||||||
|
impl::function_input_iterator<Function,Input>
|
||||||
|
>::type
|
||||||
|
>::type base_type;
|
||||||
|
public:
|
||||||
|
function_input_iterator(Function & f, Input i)
|
||||||
|
: base_type(f, i) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Function, class Input>
|
||||||
|
inline function_input_iterator<Function, Input>
|
||||||
|
make_function_input_iterator(Function & f, Input state) {
|
||||||
|
typedef function_input_iterator<Function, Input> result_t;
|
||||||
|
return result_t(f, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Function, class Input>
|
||||||
|
inline function_input_iterator<Function*, Input>
|
||||||
|
make_function_input_iterator(Function * f, Input state) {
|
||||||
|
typedef function_input_iterator<Function*, Input> result_t;
|
||||||
|
return result_t(f, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct infinite {
|
||||||
|
infinite & operator++() { return *this; }
|
||||||
|
infinite & operator++(int) { return *this; }
|
||||||
|
bool operator==(infinite &) const { return false; };
|
||||||
|
bool operator==(infinite const &) const { return false; };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::function_input_iterator;
|
||||||
|
using iterators::make_function_input_iterator;
|
||||||
|
using iterators::infinite;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -34,8 +34,9 @@
|
|||||||
|
|
||||||
#include <boost/iterator/detail/config_def.hpp> // must be last #include
|
#include <boost/iterator/detail/config_def.hpp> // must be last #include
|
||||||
|
|
||||||
namespace boost
|
namespace boost {
|
||||||
{
|
namespace iterators {
|
||||||
|
|
||||||
template <class Iter, class Value, class Category, class Reference, class Difference>
|
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||||
class indirect_iterator;
|
class indirect_iterator;
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ namespace boost
|
|||||||
template <class Iter, class Value, class Category, class Reference, class Difference>
|
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||||
struct indirect_base
|
struct indirect_base
|
||||||
{
|
{
|
||||||
typedef typename iterator_traits<Iter>::value_type dereferenceable;
|
typedef typename boost::detail::iterator_traits<Iter>::value_type dereferenceable;
|
||||||
|
|
||||||
typedef iterator_adaptor<
|
typedef iterator_adaptor<
|
||||||
indirect_iterator<Iter, Value, Category, Reference, Difference>
|
indirect_iterator<Iter, Value, Category, Reference, Difference>
|
||||||
@ -110,7 +111,7 @@ namespace boost
|
|||||||
private:
|
private:
|
||||||
typename super_t::reference dereference() const
|
typename super_t::reference dereference() const
|
||||||
{
|
{
|
||||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
# if BOOST_WORKAROUND(__BORLANDC__, < 0x5A0 )
|
||||||
return const_cast<super_t::reference>(**this->base());
|
return const_cast<super_t::reference>(**this->base());
|
||||||
# else
|
# else
|
||||||
return **this->base();
|
return **this->base();
|
||||||
@ -132,6 +133,11 @@ namespace boost
|
|||||||
return indirect_iterator<Iter, Traits>(x);
|
return indirect_iterator<Iter, Traits>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::indirect_iterator;
|
||||||
|
using iterators::make_indirect_iterator;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#include <boost/iterator/detail/config_undef.hpp>
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
# include <boost/iterator/detail/config_def.hpp> // must appear last
|
# include <boost/iterator/detail/config_def.hpp> // must appear last
|
||||||
|
|
||||||
namespace boost
|
namespace boost {
|
||||||
{
|
namespace iterators {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Meta function that determines whether two
|
// Meta function that determines whether two
|
||||||
@ -43,6 +43,10 @@ namespace boost
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::is_interoperable;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
# include <boost/iterator/detail/config_undef.hpp>
|
# include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
@ -9,16 +9,21 @@
|
|||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/detail/iterator.hpp>
|
#include <boost/detail/iterator.hpp>
|
||||||
|
|
||||||
|
#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||||
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
||||||
|
#include <boost/mpl/bool.hpp>
|
||||||
|
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||||
|
|
||||||
// should be the last #includes
|
// should be the last #includes
|
||||||
#include <boost/type_traits/detail/bool_trait_def.hpp>
|
#include <boost/type_traits/integral_constant.hpp>
|
||||||
#include <boost/iterator/detail/config_def.hpp>
|
#include <boost/iterator/detail/config_def.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||||
@ -50,7 +55,7 @@ namespace detail
|
|||||||
// convertible to Value const&
|
// convertible to Value const&
|
||||||
struct conversion_eater
|
struct conversion_eater
|
||||||
{
|
{
|
||||||
conversion_eater(Value&);
|
conversion_eater(typename add_lvalue_reference<Value>::type);
|
||||||
};
|
};
|
||||||
|
|
||||||
static char tester(conversion_eater, int);
|
static char tester(conversion_eater, int);
|
||||||
@ -132,19 +137,29 @@ namespace detail
|
|||||||
{};
|
{};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// Define the trait with full mpl lambda capability and various broken
|
template< typename T > struct is_lvalue_iterator
|
||||||
// compiler workarounds
|
: public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_lvalue_iterator_impl<T>::value>
|
||||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
{
|
||||||
is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl<T>::value)
|
public:
|
||||||
|
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_lvalue_iterator,(T))
|
||||||
|
};
|
||||||
|
|
||||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
template< typename T > struct is_non_const_lvalue_iterator
|
||||||
is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
|
: public ::boost::integral_constant<bool,::boost::iterators::detail::is_non_const_lvalue_iterator_impl<T>::value>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_non_const_lvalue_iterator,(T))
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::is_lvalue_iterator;
|
||||||
|
using iterators::is_non_const_lvalue_iterator;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/iterator/detail/config_undef.hpp>
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
#include <boost/type_traits/detail/bool_trait_undef.hpp>
|
|
||||||
|
|
||||||
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP
|
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||||
|
@ -5,18 +5,22 @@
|
|||||||
# define IS_READABLE_ITERATOR_DWA2003112_HPP
|
# define IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||||
|
|
||||||
#include <boost/mpl/bool.hpp>
|
#include <boost/mpl/bool.hpp>
|
||||||
|
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||||
#include <boost/detail/iterator.hpp>
|
#include <boost/detail/iterator.hpp>
|
||||||
|
#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||||
|
|
||||||
#include <boost/type_traits/detail/bool_trait_def.hpp>
|
|
||||||
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
||||||
|
|
||||||
// should be the last #include
|
// should be the last #include
|
||||||
|
#include <boost/type_traits/integral_constant.hpp>
|
||||||
#include <boost/iterator/detail/config_def.hpp>
|
#include <boost/iterator/detail/config_def.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
// Guts of is_readable_iterator. Value is the iterator's value_type
|
// Guts of is_readable_iterator. Value is the iterator's value_type
|
||||||
@ -24,7 +28,7 @@ namespace detail
|
|||||||
template <class Value>
|
template <class Value>
|
||||||
struct is_readable_iterator_impl
|
struct is_readable_iterator_impl
|
||||||
{
|
{
|
||||||
static char tester(Value&, int);
|
static char tester(typename add_lvalue_reference<Value>::type, int);
|
||||||
static char (& tester(any_conversion_eater, ...) )[2];
|
static char (& tester(any_conversion_eater, ...) )[2];
|
||||||
|
|
||||||
template <class It>
|
template <class It>
|
||||||
@ -94,10 +98,16 @@ namespace detail
|
|||||||
{};
|
{};
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// Define the trait with full mpl lambda capability and various broken
|
template< typename T > struct is_readable_iterator
|
||||||
// compiler workarounds
|
: public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_iterator_impl2<T>::value>
|
||||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
{
|
||||||
is_readable_iterator,T,::boost::detail::is_readable_iterator_impl2<T>::value)
|
public:
|
||||||
|
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_readable_iterator,(T))
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::is_readable_iterator;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
@ -24,29 +24,33 @@
|
|||||||
|
|
||||||
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||||
# include <boost/type_traits/remove_reference.hpp>
|
# include <boost/type_traits/remove_reference.hpp>
|
||||||
#else
|
|
||||||
# include <boost/type_traits/add_reference.hpp>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <boost/type_traits/add_reference.hpp>
|
||||||
#include <boost/iterator/detail/config_def.hpp>
|
#include <boost/iterator/detail/config_def.hpp>
|
||||||
|
|
||||||
#include <boost/iterator/iterator_traits.hpp>
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost {
|
||||||
{
|
namespace iterators {
|
||||||
|
|
||||||
// Used as a default template argument internally, merely to
|
// Used as a default template argument internally, merely to
|
||||||
// indicate "use the default", this can also be passed by users
|
// indicate "use the default", this can also be passed by users
|
||||||
// explicitly in order to specify that the default should be used.
|
// explicitly in order to specify that the default should be used.
|
||||||
struct use_default;
|
struct use_default;
|
||||||
|
|
||||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::use_default;
|
||||||
|
|
||||||
// the incompleteness of use_default causes massive problems for
|
// the incompleteness of use_default causes massive problems for
|
||||||
// is_convertible (naturally). This workaround is fortunately not
|
// is_convertible (naturally). This workaround is fortunately not
|
||||||
// needed for vc6/vc7.
|
// needed for vc6/vc7.
|
||||||
template<class To>
|
template<class To>
|
||||||
struct is_convertible<use_default,To>
|
struct is_convertible<use_default,To>
|
||||||
: mpl::false_ {};
|
: mpl::false_ {};
|
||||||
# endif
|
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
@ -100,30 +104,15 @@ namespace boost
|
|||||||
// false positives for user/library defined iterator types. See comments
|
// false positives for user/library defined iterator types. See comments
|
||||||
// on operator implementation for consequences.
|
// on operator implementation for consequences.
|
||||||
//
|
//
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
# if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
|
||||||
|
|
||||||
template<typename From, typename To>
|
|
||||||
struct enable_if_convertible
|
|
||||||
{
|
|
||||||
typedef typename mpl::if_<
|
|
||||||
mpl::or_<
|
|
||||||
is_same<From,To>
|
|
||||||
, is_convertible<From, To>
|
|
||||||
>
|
|
||||||
, boost::detail::enable_type
|
|
||||||
, int&
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
# elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
|
|
||||||
|
|
||||||
template <class From, class To>
|
template <class From, class To>
|
||||||
struct enable_if_convertible
|
struct enable_if_convertible
|
||||||
{
|
{
|
||||||
typedef boost::detail::enable_type type;
|
typedef boost::iterators::detail::enable_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
|
# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292))
|
||||||
|
|
||||||
// For some reason vc7.1 needs us to "cut off" instantiation
|
// For some reason vc7.1 needs us to "cut off" instantiation
|
||||||
// of is_convertible in a few cases.
|
// of is_convertible in a few cases.
|
||||||
@ -134,7 +123,7 @@ namespace boost
|
|||||||
is_same<From,To>
|
is_same<From,To>
|
||||||
, is_convertible<From, To>
|
, is_convertible<From, To>
|
||||||
>
|
>
|
||||||
, boost::detail::enable_type
|
, boost::iterators::detail::enable_type
|
||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
@ -144,7 +133,7 @@ namespace boost
|
|||||||
struct enable_if_convertible
|
struct enable_if_convertible
|
||||||
: iterators::enable_if<
|
: iterators::enable_if<
|
||||||
is_convertible<From, To>
|
is_convertible<From, To>
|
||||||
, boost::detail::enable_type
|
, boost::iterators::detail::enable_type
|
||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
@ -183,7 +172,7 @@ namespace boost
|
|||||||
Derived
|
Derived
|
||||||
|
|
||||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||||
, typename boost::detail::ia_dflt_help<
|
, typename boost::iterators::detail::ia_dflt_help<
|
||||||
Value
|
Value
|
||||||
, mpl::eval_if<
|
, mpl::eval_if<
|
||||||
is_same<Reference,use_default>
|
is_same<Reference,use_default>
|
||||||
@ -192,17 +181,17 @@ namespace boost
|
|||||||
>
|
>
|
||||||
>::type
|
>::type
|
||||||
# else
|
# else
|
||||||
, typename boost::detail::ia_dflt_help<
|
, typename boost::iterators::detail::ia_dflt_help<
|
||||||
Value, iterator_value<Base>
|
Value, iterator_value<Base>
|
||||||
>::type
|
>::type
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
, typename boost::detail::ia_dflt_help<
|
, typename boost::iterators::detail::ia_dflt_help<
|
||||||
Traversal
|
Traversal
|
||||||
, iterator_traversal<Base>
|
, iterator_traversal<Base>
|
||||||
>::type
|
>::type
|
||||||
|
|
||||||
, typename boost::detail::ia_dflt_help<
|
, typename boost::iterators::detail::ia_dflt_help<
|
||||||
Reference
|
Reference
|
||||||
, mpl::eval_if<
|
, mpl::eval_if<
|
||||||
is_same<Value,use_default>
|
is_same<Value,use_default>
|
||||||
@ -211,7 +200,7 @@ namespace boost
|
|||||||
>
|
>
|
||||||
>::type
|
>::type
|
||||||
|
|
||||||
, typename boost::detail::ia_dflt_help<
|
, typename boost::iterators::detail::ia_dflt_help<
|
||||||
Difference, iterator_difference<Base>
|
Difference, iterator_difference<Base>
|
||||||
>::type
|
>::type
|
||||||
>
|
>
|
||||||
@ -260,14 +249,14 @@ namespace boost
|
|||||||
, class Difference = use_default
|
, class Difference = use_default
|
||||||
>
|
>
|
||||||
class iterator_adaptor
|
class iterator_adaptor
|
||||||
: public boost::detail::iterator_adaptor_base<
|
: public boost::iterators::detail::iterator_adaptor_base<
|
||||||
Derived, Base, Value, Traversal, Reference, Difference
|
Derived, Base, Value, Traversal, Reference, Difference
|
||||||
>::type
|
>::type
|
||||||
{
|
{
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef typename boost::detail::iterator_adaptor_base<
|
typedef typename boost::iterators::detail::iterator_adaptor_base<
|
||||||
Derived, Base, Value, Traversal, Reference, Difference
|
Derived, Base, Value, Traversal, Reference, Difference
|
||||||
>::type super_t;
|
>::type super_t;
|
||||||
public:
|
public:
|
||||||
@ -323,7 +312,7 @@ namespace boost
|
|||||||
>::type my_traversal;
|
>::type my_traversal;
|
||||||
|
|
||||||
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
|
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
|
||||||
boost::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
|
boost::iterators::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
|
||||||
|
|
||||||
void advance(typename super_t::difference_type n)
|
void advance(typename super_t::difference_type n)
|
||||||
{
|
{
|
||||||
@ -359,6 +348,11 @@ namespace boost
|
|||||||
Base m_iterator;
|
Base m_iterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::iterator_adaptor;
|
||||||
|
using iterators::enable_if_convertible;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#include <boost/iterator/detail/config_undef.hpp>
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include <boost/concept_archetype.hpp>
|
#include <boost/concept_archetype.hpp>
|
||||||
|
|
||||||
#include <boost/mpl/aux_/msvc_eti_base.hpp>
|
|
||||||
#include <boost/mpl/bitand.hpp>
|
#include <boost/mpl/bitand.hpp>
|
||||||
#include <boost/mpl/int.hpp>
|
#include <boost/mpl/int.hpp>
|
||||||
#include <boost/mpl/equal_to.hpp>
|
#include <boost/mpl/equal_to.hpp>
|
||||||
@ -32,6 +31,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
template <class Value, class AccessCategory>
|
template <class Value, class AccessCategory>
|
||||||
struct access_archetype;
|
struct access_archetype;
|
||||||
@ -39,7 +39,7 @@ struct access_archetype;
|
|||||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
||||||
struct traversal_archetype;
|
struct traversal_archetype;
|
||||||
|
|
||||||
namespace iterator_archetypes
|
namespace archetypes
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
readable_iterator_bit = 1
|
readable_iterator_bit = 1
|
||||||
@ -119,19 +119,18 @@ namespace detail
|
|||||||
|
|
||||||
template <class Value, class AccessCategory, class TraversalCategory>
|
template <class Value, class AccessCategory, class TraversalCategory>
|
||||||
struct operator_brackets
|
struct operator_brackets
|
||||||
: mpl::aux::msvc_eti_base<
|
: mpl::eval_if<
|
||||||
typename mpl::eval_if<
|
|
||||||
is_convertible<TraversalCategory, random_access_traversal_tag>
|
is_convertible<TraversalCategory, random_access_traversal_tag>
|
||||||
, mpl::eval_if<
|
, mpl::eval_if<
|
||||||
iterator_archetypes::has_access<
|
archetypes::has_access<
|
||||||
AccessCategory
|
AccessCategory
|
||||||
, iterator_archetypes::writable_iterator_t
|
, archetypes::writable_iterator_t
|
||||||
>
|
>
|
||||||
, mpl::identity<writable_operator_brackets<Value> >
|
, mpl::identity<writable_operator_brackets<Value> >
|
||||||
, mpl::if_<
|
, mpl::if_<
|
||||||
iterator_archetypes::has_access<
|
archetypes::has_access<
|
||||||
AccessCategory
|
AccessCategory
|
||||||
, iterator_archetypes::readable_iterator_t
|
, archetypes::readable_iterator_t
|
||||||
>
|
>
|
||||||
, readable_operator_brackets<Value>
|
, readable_operator_brackets<Value>
|
||||||
, no_operator_brackets
|
, no_operator_brackets
|
||||||
@ -139,7 +138,6 @@ namespace detail
|
|||||||
>
|
>
|
||||||
, mpl::identity<no_operator_brackets>
|
, mpl::identity<no_operator_brackets>
|
||||||
>::type
|
>::type
|
||||||
>::type
|
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template <class TraversalCategory>
|
template <class TraversalCategory>
|
||||||
@ -154,9 +152,7 @@ namespace detail
|
|||||||
|
|
||||||
template <class Derived, class Value, class TraversalCategory>
|
template <class Derived, class Value, class TraversalCategory>
|
||||||
struct traversal_archetype_
|
struct traversal_archetype_
|
||||||
: mpl::aux::msvc_eti_base<
|
: traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||||
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
|
||||||
>::type
|
|
||||||
{
|
{
|
||||||
typedef typename
|
typedef typename
|
||||||
traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||||
@ -205,12 +201,6 @@ namespace detail
|
|||||||
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
|
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
|
||||||
// doesn't seem to pick up != from equality_comparable
|
|
||||||
template <class Derived, class Value>
|
|
||||||
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
|
||||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
|
|
||||||
#endif
|
|
||||||
template <>
|
template <>
|
||||||
struct traversal_archetype_impl<forward_traversal_tag>
|
struct traversal_archetype_impl<forward_traversal_tag>
|
||||||
{
|
{
|
||||||
@ -309,17 +299,15 @@ struct iterator_access_archetype_impl
|
|||||||
|
|
||||||
template <class Value, class AccessCategory>
|
template <class Value, class AccessCategory>
|
||||||
struct iterator_access_archetype
|
struct iterator_access_archetype
|
||||||
: mpl::aux::msvc_eti_base<
|
: iterator_access_archetype_impl<
|
||||||
typename iterator_access_archetype_impl<
|
|
||||||
AccessCategory
|
AccessCategory
|
||||||
>::template archetype<Value>
|
>::template archetype<Value>
|
||||||
>::type
|
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct iterator_access_archetype_impl<
|
struct iterator_access_archetype_impl<
|
||||||
iterator_archetypes::readable_iterator_t
|
archetypes::readable_iterator_t
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
template <class Value>
|
template <class Value>
|
||||||
@ -337,15 +325,13 @@ struct iterator_access_archetype_impl<
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct iterator_access_archetype_impl<
|
struct iterator_access_archetype_impl<
|
||||||
iterator_archetypes::writable_iterator_t
|
archetypes::writable_iterator_t
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
template <class Value>
|
template <class Value>
|
||||||
struct archetype
|
struct archetype
|
||||||
{
|
{
|
||||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
|
||||||
BOOST_STATIC_ASSERT(!is_const<Value>::value);
|
BOOST_STATIC_ASSERT(!is_const<Value>::value);
|
||||||
# endif
|
|
||||||
typedef void value_type;
|
typedef void value_type;
|
||||||
typedef void reference;
|
typedef void reference;
|
||||||
typedef void pointer;
|
typedef void pointer;
|
||||||
@ -356,13 +342,13 @@ struct iterator_access_archetype_impl<
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct iterator_access_archetype_impl<
|
struct iterator_access_archetype_impl<
|
||||||
iterator_archetypes::readable_writable_iterator_t
|
archetypes::readable_writable_iterator_t
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
template <class Value>
|
template <class Value>
|
||||||
struct archetype
|
struct archetype
|
||||||
: public virtual iterator_access_archetype<
|
: public virtual iterator_access_archetype<
|
||||||
Value, iterator_archetypes::readable_iterator_t
|
Value, archetypes::readable_iterator_t
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
typedef detail::read_write_proxy<Value> reference;
|
typedef detail::read_write_proxy<Value> reference;
|
||||||
@ -372,12 +358,12 @@ struct iterator_access_archetype_impl<
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
|
struct iterator_access_archetype_impl<archetypes::readable_lvalue_iterator_t>
|
||||||
{
|
{
|
||||||
template <class Value>
|
template <class Value>
|
||||||
struct archetype
|
struct archetype
|
||||||
: public virtual iterator_access_archetype<
|
: public virtual iterator_access_archetype<
|
||||||
Value, iterator_archetypes::readable_iterator_t
|
Value, archetypes::readable_iterator_t
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
typedef Value& reference;
|
typedef Value& reference;
|
||||||
@ -388,17 +374,15 @@ struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_itera
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>
|
struct iterator_access_archetype_impl<archetypes::writable_lvalue_iterator_t>
|
||||||
{
|
{
|
||||||
template <class Value>
|
template <class Value>
|
||||||
struct archetype
|
struct archetype
|
||||||
: public virtual iterator_access_archetype<
|
: public virtual iterator_access_archetype<
|
||||||
Value, iterator_archetypes::readable_lvalue_iterator_t
|
Value, archetypes::readable_lvalue_iterator_t
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
|
||||||
BOOST_STATIC_ASSERT((!is_const<Value>::value));
|
BOOST_STATIC_ASSERT((!is_const<Value>::value));
|
||||||
# endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -433,8 +417,8 @@ namespace detail
|
|||||||
typedef typename detail::facade_iterator_category<
|
typedef typename detail::facade_iterator_category<
|
||||||
TraversalCategory
|
TraversalCategory
|
||||||
, typename mpl::eval_if<
|
, typename mpl::eval_if<
|
||||||
iterator_archetypes::has_access<
|
archetypes::has_access<
|
||||||
AccessCategory, iterator_archetypes::writable_iterator_t
|
AccessCategory, archetypes::writable_iterator_t
|
||||||
>
|
>
|
||||||
, remove_const<Value>
|
, remove_const<Value>
|
||||||
, add_const<Value>
|
, add_const<Value>
|
||||||
@ -509,7 +493,17 @@ struct iterator_archetype
|
|||||||
# endif
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
// Backward compatibility names
|
||||||
|
namespace iterator_archetypes = iterators::archetypes;
|
||||||
|
using iterators::access_archetype;
|
||||||
|
using iterators::traversal_archetype;
|
||||||
|
using iterators::iterator_archetype;
|
||||||
|
using iterators::undefined;
|
||||||
|
using iterators::iterator_access_archetype_impl;
|
||||||
|
using iterators::traversal_archetype_base;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_ARCHETYPES_HPP
|
#endif // BOOST_ITERATOR_ARCHETYPES_HPP
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
# include <boost/static_assert.hpp>
|
# include <boost/static_assert.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Traversal Categories
|
// Traversal Categories
|
||||||
@ -97,51 +98,8 @@ namespace detail
|
|||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
template <>
|
|
||||||
struct old_category_to_traversal<int>
|
|
||||||
{
|
|
||||||
typedef int type;
|
|
||||||
};
|
|
||||||
# endif
|
|
||||||
|
|
||||||
template <class Traversal>
|
|
||||||
struct pure_traversal_tag
|
|
||||||
: mpl::eval_if<
|
|
||||||
is_convertible<Traversal,random_access_traversal_tag>
|
|
||||||
, mpl::identity<random_access_traversal_tag>
|
|
||||||
, mpl::eval_if<
|
|
||||||
is_convertible<Traversal,bidirectional_traversal_tag>
|
|
||||||
, mpl::identity<bidirectional_traversal_tag>
|
|
||||||
, mpl::eval_if<
|
|
||||||
is_convertible<Traversal,forward_traversal_tag>
|
|
||||||
, mpl::identity<forward_traversal_tag>
|
|
||||||
, mpl::eval_if<
|
|
||||||
is_convertible<Traversal,single_pass_traversal_tag>
|
|
||||||
, mpl::identity<single_pass_traversal_tag>
|
|
||||||
, mpl::eval_if<
|
|
||||||
is_convertible<Traversal,incrementable_traversal_tag>
|
|
||||||
, mpl::identity<incrementable_traversal_tag>
|
|
||||||
, void
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
template <>
|
|
||||||
struct pure_traversal_tag<int>
|
|
||||||
{
|
|
||||||
typedef int type;
|
|
||||||
};
|
|
||||||
# endif
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Convert an iterator category into a traversal tag
|
// Convert an iterator category into a traversal tag
|
||||||
//
|
//
|
||||||
@ -150,7 +108,7 @@ struct iterator_category_to_traversal
|
|||||||
: mpl::eval_if< // if already convertible to a traversal tag, we're done.
|
: mpl::eval_if< // if already convertible to a traversal tag, we're done.
|
||||||
is_convertible<Cat,incrementable_traversal_tag>
|
is_convertible<Cat,incrementable_traversal_tag>
|
||||||
, mpl::identity<Cat>
|
, mpl::identity<Cat>
|
||||||
, boost::detail::old_category_to_traversal<Cat>
|
, boost::iterators::detail::old_category_to_traversal<Cat>
|
||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
@ -181,6 +139,75 @@ struct iterator_traversal<mpl::_>
|
|||||||
{};
|
{};
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Convert an iterator traversal to one of the traversal tags.
|
||||||
|
//
|
||||||
|
template <class Traversal>
|
||||||
|
struct pure_traversal_tag
|
||||||
|
: mpl::eval_if<
|
||||||
|
is_convertible<Traversal,random_access_traversal_tag>
|
||||||
|
, mpl::identity<random_access_traversal_tag>
|
||||||
|
, mpl::eval_if<
|
||||||
|
is_convertible<Traversal,bidirectional_traversal_tag>
|
||||||
|
, mpl::identity<bidirectional_traversal_tag>
|
||||||
|
, mpl::eval_if<
|
||||||
|
is_convertible<Traversal,forward_traversal_tag>
|
||||||
|
, mpl::identity<forward_traversal_tag>
|
||||||
|
, mpl::eval_if<
|
||||||
|
is_convertible<Traversal,single_pass_traversal_tag>
|
||||||
|
, mpl::identity<single_pass_traversal_tag>
|
||||||
|
, mpl::eval_if<
|
||||||
|
is_convertible<Traversal,incrementable_traversal_tag>
|
||||||
|
, mpl::identity<incrementable_traversal_tag>
|
||||||
|
, void
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trait to retrieve one of the iterator traversal tags from the iterator category or traversal.
|
||||||
|
//
|
||||||
|
template <class Iterator = mpl::_1>
|
||||||
|
struct pure_iterator_traversal
|
||||||
|
: pure_traversal_tag<typename iterator_traversal<Iterator>::type>
|
||||||
|
{};
|
||||||
|
|
||||||
|
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
|
||||||
|
template <>
|
||||||
|
struct pure_iterator_traversal<mpl::_1>
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
struct apply : pure_iterator_traversal<T>
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct pure_iterator_traversal<mpl::_>
|
||||||
|
: pure_iterator_traversal<mpl::_1>
|
||||||
|
{};
|
||||||
|
# endif
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::no_traversal_tag;
|
||||||
|
using iterators::incrementable_traversal_tag;
|
||||||
|
using iterators::single_pass_traversal_tag;
|
||||||
|
using iterators::forward_traversal_tag;
|
||||||
|
using iterators::bidirectional_traversal_tag;
|
||||||
|
using iterators::random_access_traversal_tag;
|
||||||
|
using iterators::iterator_category_to_traversal;
|
||||||
|
using iterators::iterator_traversal;
|
||||||
|
|
||||||
|
// This import is needed for backward compatibility with Boost.Range:
|
||||||
|
// boost/range/detail/demote_iterator_traversal_tag.hpp
|
||||||
|
// It should be removed when that header is fixed.
|
||||||
|
namespace detail {
|
||||||
|
using iterators::pure_traversal_tag;
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#include <boost/iterator/detail/config_undef.hpp>
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
@ -248,17 +248,8 @@ namespace boost_concepts
|
|||||||
BOOST_concept(InteroperableIterator,(Iterator)(ConstIterator))
|
BOOST_concept(InteroperableIterator,(Iterator)(ConstIterator))
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef typename boost::detail::pure_traversal_tag<
|
typedef typename boost::iterators::pure_iterator_traversal<Iterator>::type traversal_category;
|
||||||
typename boost::iterator_traversal<
|
typedef typename boost::iterators::pure_iterator_traversal<ConstIterator>::type const_traversal_category;
|
||||||
Iterator
|
|
||||||
>::type
|
|
||||||
>::type traversal_category;
|
|
||||||
|
|
||||||
typedef typename boost::detail::pure_traversal_tag<
|
|
||||||
typename boost::iterator_traversal<
|
|
||||||
ConstIterator
|
|
||||||
>::type
|
|
||||||
>::type const_traversal_category;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BOOST_CONCEPT_ASSERT((SinglePassIterator<Iterator>));
|
BOOST_CONCEPT_ASSERT((SinglePassIterator<Iterator>));
|
||||||
|
@ -7,19 +7,22 @@
|
|||||||
#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
|
#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
|
||||||
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
|
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
#include <boost/iterator.hpp>
|
#include <boost/iterator.hpp>
|
||||||
#include <boost/iterator/interoperable.hpp>
|
#include <boost/iterator/interoperable.hpp>
|
||||||
#include <boost/iterator/iterator_traits.hpp>
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
|
|
||||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||||
#include <boost/iterator/detail/enable_if.hpp>
|
#include <boost/iterator/detail/enable_if.hpp>
|
||||||
|
|
||||||
#include <boost/implicit_cast.hpp>
|
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/utility/addressof.hpp>
|
||||||
|
|
||||||
#include <boost/type_traits/is_same.hpp>
|
#include <boost/type_traits/is_same.hpp>
|
||||||
#include <boost/type_traits/add_const.hpp>
|
#include <boost/type_traits/add_const.hpp>
|
||||||
#include <boost/type_traits/add_pointer.hpp>
|
#include <boost/type_traits/add_pointer.hpp>
|
||||||
|
#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||||
#include <boost/type_traits/remove_const.hpp>
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include <boost/type_traits/is_convertible.hpp>
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
@ -36,8 +39,9 @@
|
|||||||
|
|
||||||
#include <boost/iterator/detail/config_def.hpp> // this goes last
|
#include <boost/iterator/detail/config_def.hpp> // this goes last
|
||||||
|
|
||||||
namespace boost
|
namespace boost {
|
||||||
{
|
namespace iterators {
|
||||||
|
|
||||||
// This forward declaration is required for the friend declaration
|
// This forward declaration is required for the friend declaration
|
||||||
// in iterator_core_access
|
// in iterator_core_access
|
||||||
template <class I, class V, class TC, class R, class D> class iterator_facade;
|
template <class I, class V, class TC, class R, class D> class iterator_facade;
|
||||||
@ -56,6 +60,12 @@ namespace boost
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The type trait checks if the category or traversal is at least as advanced as the specified required traversal
|
||||||
|
template< typename CategoryOrTraversal, typename Required >
|
||||||
|
struct is_traversal_at_least :
|
||||||
|
public boost::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
|
||||||
|
{};
|
||||||
|
|
||||||
//
|
//
|
||||||
// enable if for use in operator implementation.
|
// enable if for use in operator implementation.
|
||||||
//
|
//
|
||||||
@ -64,28 +74,31 @@ namespace boost
|
|||||||
, class Facade2
|
, class Facade2
|
||||||
, class Return
|
, class Return
|
||||||
>
|
>
|
||||||
struct enable_if_interoperable
|
struct enable_if_interoperable :
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
public boost::iterators::enable_if<
|
||||||
{
|
is_interoperable< Facade1, Facade2 >
|
||||||
typedef typename mpl::if_<
|
|
||||||
mpl::or_<
|
|
||||||
is_convertible<Facade1, Facade2>
|
|
||||||
, is_convertible<Facade2, Facade1>
|
|
||||||
>
|
|
||||||
, Return
|
, Return
|
||||||
, int[3]
|
>
|
||||||
>::type type;
|
{};
|
||||||
};
|
|
||||||
#else
|
//
|
||||||
: ::boost::iterators::enable_if<
|
// enable if for use in implementation of operators specific for random access traversal.
|
||||||
mpl::or_<
|
//
|
||||||
is_convertible<Facade1, Facade2>
|
template <
|
||||||
, is_convertible<Facade2, Facade1>
|
class Facade1
|
||||||
|
, class Facade2
|
||||||
|
, class Return
|
||||||
|
>
|
||||||
|
struct enable_if_interoperable_and_random_access_traversal :
|
||||||
|
public boost::iterators::enable_if<
|
||||||
|
mpl::and_<
|
||||||
|
is_interoperable< Facade1, Facade2 >
|
||||||
|
, is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >
|
||||||
|
, is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
|
||||||
>
|
>
|
||||||
, Return
|
, Return
|
||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Generates associated types for an iterator_facade with the
|
// Generates associated types for an iterator_facade with the
|
||||||
@ -105,8 +118,9 @@ namespace boost
|
|||||||
|
|
||||||
typedef typename remove_const<ValueParam>::type value_type;
|
typedef typename remove_const<ValueParam>::type value_type;
|
||||||
|
|
||||||
|
// Not the real associated pointer type
|
||||||
typedef typename mpl::eval_if<
|
typedef typename mpl::eval_if<
|
||||||
boost::detail::iterator_writability_disabled<ValueParam,Reference>
|
boost::iterators::detail::iterator_writability_disabled<ValueParam,Reference>
|
||||||
, add_pointer<const value_type>
|
, add_pointer<const value_type>
|
||||||
, add_pointer<value_type>
|
, add_pointer<value_type>
|
||||||
>::type pointer;
|
>::type pointer;
|
||||||
@ -146,7 +160,7 @@ namespace boost
|
|||||||
|
|
||||||
// Returning a mutable reference allows nonsense like
|
// Returning a mutable reference allows nonsense like
|
||||||
// (*r++).mutate(), but it imposes fewer assumptions about the
|
// (*r++).mutate(), but it imposes fewer assumptions about the
|
||||||
// behavior of the value_type. In particular, recall taht
|
// behavior of the value_type. In particular, recall that
|
||||||
// (*r).mutate() is legal if operator* returns by value.
|
// (*r).mutate() is legal if operator* returns by value.
|
||||||
value_type&
|
value_type&
|
||||||
operator*() const
|
operator*() const
|
||||||
@ -271,7 +285,15 @@ namespace boost
|
|||||||
: mpl::eval_if<
|
: mpl::eval_if<
|
||||||
mpl::and_<
|
mpl::and_<
|
||||||
// A proxy is only needed for readable iterators
|
// A proxy is only needed for readable iterators
|
||||||
is_convertible<Reference,Value const&>
|
is_convertible<
|
||||||
|
Reference
|
||||||
|
// Use add_lvalue_reference to form `reference to Value` due to
|
||||||
|
// some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
|
||||||
|
// 'reference-to-reference' in the template which described in CWG
|
||||||
|
// DR106.
|
||||||
|
// http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
|
||||||
|
, typename add_lvalue_reference<Value const>::type
|
||||||
|
>
|
||||||
|
|
||||||
// No multipass iterator can have values that disappear
|
// No multipass iterator can have values that disappear
|
||||||
// before positions can be re-visited
|
// before positions can be re-visited
|
||||||
@ -293,48 +315,36 @@ namespace boost
|
|||||||
|
|
||||||
// operator->() needs special support for input iterators to strictly meet the
|
// operator->() needs special support for input iterators to strictly meet the
|
||||||
// standard's requirements. If *i is not a reference type, we must still
|
// standard's requirements. If *i is not a reference type, we must still
|
||||||
// produce a lvalue to which a pointer can be formed. We do that by
|
// produce an lvalue to which a pointer can be formed. We do that by
|
||||||
// returning an instantiation of this special proxy class template.
|
// returning a proxy object containing an instance of the reference object.
|
||||||
template <class T>
|
template <class Reference, class Pointer>
|
||||||
struct operator_arrow_proxy
|
struct operator_arrow_dispatch // proxy references
|
||||||
{
|
{
|
||||||
operator_arrow_proxy(T const* px) : m_value(*px) {}
|
struct proxy
|
||||||
T* operator->() const { return &m_value; }
|
{
|
||||||
// This function is needed for MWCW and BCC, which won't call operator->
|
explicit proxy(Reference const & x) : m_ref(x) {}
|
||||||
// again automatically per 13.3.1.2 para 8
|
Reference* operator->() { return boost::addressof(m_ref); }
|
||||||
operator T*() const { return &m_value; }
|
// This function is needed for MWCW and BCC, which won't call
|
||||||
mutable T m_value;
|
// operator-> again automatically per 13.3.1.2 para 8
|
||||||
|
operator Reference*() { return boost::addressof(m_ref); }
|
||||||
|
Reference m_ref;
|
||||||
};
|
};
|
||||||
|
typedef proxy result_type;
|
||||||
// A metafunction that gets the result type for operator->. Also
|
static result_type apply(Reference const & x)
|
||||||
// has a static function make() which builds the result from a
|
|
||||||
// Reference
|
|
||||||
template <class ValueType, class Reference, class Pointer>
|
|
||||||
struct operator_arrow_result
|
|
||||||
{
|
{
|
||||||
// CWPro8.3 won't accept "operator_arrow_result::type", and we
|
return result_type(x);
|
||||||
// need that type below, so metafunction forwarding would be a
|
|
||||||
// losing proposition here.
|
|
||||||
typedef typename mpl::if_<
|
|
||||||
is_reference<Reference>
|
|
||||||
, Pointer
|
|
||||||
, operator_arrow_proxy<ValueType>
|
|
||||||
>::type type;
|
|
||||||
|
|
||||||
static type make(Reference x)
|
|
||||||
{
|
|
||||||
return implicit_cast<type>(&x);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
template <class T, class Pointer>
|
||||||
// Deal with ETI
|
struct operator_arrow_dispatch<T&, Pointer> // "real" references
|
||||||
template<>
|
|
||||||
struct operator_arrow_result<int, int, int>
|
|
||||||
{
|
{
|
||||||
typedef int type;
|
typedef Pointer result_type;
|
||||||
|
static result_type apply(T& x)
|
||||||
|
{
|
||||||
|
return boost::addressof(x);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
# endif
|
|
||||||
|
|
||||||
// A proxy return type for operator[], needed to deal with
|
// A proxy return type for operator[], needed to deal with
|
||||||
// iterators that may invalidate referents upon destruction.
|
// iterators that may invalidate referents upon destruction.
|
||||||
@ -410,12 +420,6 @@ namespace boost
|
|||||||
:
|
:
|
||||||
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
|
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
|
||||||
iterator_difference<I1>
|
iterator_difference<I1>
|
||||||
# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
mpl::if_<
|
|
||||||
is_convertible<I2,I1>
|
|
||||||
, typename I1::difference_type
|
|
||||||
, typename I2::difference_type
|
|
||||||
>
|
|
||||||
# else
|
# else
|
||||||
mpl::eval_if<
|
mpl::eval_if<
|
||||||
is_convertible<I2,I1>
|
is_convertible<I2,I1>
|
||||||
@ -426,12 +430,24 @@ namespace boost
|
|||||||
{};
|
{};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <
|
||||||
|
class Derived
|
||||||
|
, class Value
|
||||||
|
, class CategoryOrTraversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
, bool IsBidirectionalTraversal
|
||||||
|
, bool IsRandomAccessTraversal
|
||||||
|
>
|
||||||
|
class iterator_facade_base;
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
// Macros which describe the declarations of binary operators
|
// Macros which describe the declarations of binary operators
|
||||||
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||||
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
|
||||||
template < \
|
template < \
|
||||||
class Derived1, class V1, class TC1, class Reference1, class Difference1 \
|
class Derived1, class V1, class TC1, class Reference1, class Difference1 \
|
||||||
, class Derived2, class V2, class TC2, class Reference2, class Difference2 \
|
, class Derived2, class V2, class TC2, class Reference2, class Difference2 \
|
||||||
@ -441,12 +457,12 @@ namespace boost
|
|||||||
iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
|
iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
|
||||||
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
|
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
|
||||||
# else
|
# else
|
||||||
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
|
||||||
template < \
|
template < \
|
||||||
class Derived1, class V1, class TC1, class Reference1, class Difference1 \
|
class Derived1, class V1, class TC1, class Reference1, class Difference1 \
|
||||||
, class Derived2, class V2, class TC2, class Reference2, class Difference2 \
|
, class Derived2, class V2, class TC2, class Reference2, class Difference2 \
|
||||||
> \
|
> \
|
||||||
prefix typename boost::detail::enable_if_interoperable< \
|
prefix typename enabler< \
|
||||||
Derived1, Derived2 \
|
Derived1, Derived2 \
|
||||||
, typename mpl::apply2<result_type,Derived1,Derived2>::type \
|
, typename mpl::apply2<result_type,Derived1,Derived2>::type \
|
||||||
>::type \
|
>::type \
|
||||||
@ -455,9 +471,18 @@ namespace boost
|
|||||||
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
|
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
|
||||||
|
|
||||||
|
# define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type) \
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
|
||||||
|
|
||||||
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
|
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
|
||||||
template <class Derived, class V, class TC, class R, class D> \
|
template <class Derived, class V, class TC, class R, class D> \
|
||||||
prefix Derived operator+ args
|
prefix typename boost::iterators::enable_if< \
|
||||||
|
boost::iterators::detail::is_traversal_at_least< TC, boost::iterators::random_access_traversal_tag >, \
|
||||||
|
Derived \
|
||||||
|
>::type operator+ args
|
||||||
|
|
||||||
//
|
//
|
||||||
// Helper class for granting access to the iterator core interface.
|
// Helper class for granting access to the iterator core interface.
|
||||||
@ -470,29 +495,36 @@ namespace boost
|
|||||||
//
|
//
|
||||||
class iterator_core_access
|
class iterator_core_access
|
||||||
{
|
{
|
||||||
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
|
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
|
||||||
// Tasteless as this may seem, making all members public allows member templates
|
// Tasteless as this may seem, making all members public allows member templates
|
||||||
// to work in the absence of member template friends.
|
// to work in the absence of member template friends.
|
||||||
public:
|
public:
|
||||||
# else
|
# else
|
||||||
|
|
||||||
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
|
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
|
||||||
|
template <class I, class V, class TC, class R, class D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal>
|
||||||
|
friend class detail::iterator_facade_base;
|
||||||
|
|
||||||
# define BOOST_ITERATOR_FACADE_RELATION(op) \
|
# define BOOST_ITERATOR_FACADE_RELATION(op) \
|
||||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::detail::always_bool2);
|
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::iterators::detail::always_bool2);
|
||||||
|
|
||||||
BOOST_ITERATOR_FACADE_RELATION(==)
|
BOOST_ITERATOR_FACADE_RELATION(==)
|
||||||
BOOST_ITERATOR_FACADE_RELATION(!=)
|
BOOST_ITERATOR_FACADE_RELATION(!=)
|
||||||
|
|
||||||
BOOST_ITERATOR_FACADE_RELATION(<)
|
|
||||||
BOOST_ITERATOR_FACADE_RELATION(>)
|
|
||||||
BOOST_ITERATOR_FACADE_RELATION(<=)
|
|
||||||
BOOST_ITERATOR_FACADE_RELATION(>=)
|
|
||||||
# undef BOOST_ITERATOR_FACADE_RELATION
|
# undef BOOST_ITERATOR_FACADE_RELATION
|
||||||
|
|
||||||
BOOST_ITERATOR_FACADE_INTEROP_HEAD(
|
# define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op) \
|
||||||
friend, -, boost::detail::choose_difference_type)
|
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend,op, boost::iterators::detail::always_bool2);
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
|
||||||
|
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
|
||||||
|
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
|
||||||
|
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
|
||||||
|
|
||||||
|
# undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(
|
||||||
|
friend, -, boost::iterators::detail::choose_difference_type)
|
||||||
;
|
;
|
||||||
|
|
||||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
BOOST_ITERATOR_FACADE_PLUS_HEAD(
|
||||||
@ -576,31 +608,65 @@ namespace boost
|
|||||||
return *static_cast<I const*>(&facade);
|
return *static_cast<I const*>(&facade);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
// objects of this class are useless
|
// objects of this class are useless
|
||||||
iterator_core_access(); //undefined
|
BOOST_DELETED_FUNCTION(iterator_core_access())
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
namespace detail {
|
||||||
// iterator_facade - use as a public base class for defining new
|
|
||||||
// standard-conforming iterators.
|
// Implementation for forward traversal iterators
|
||||||
//
|
|
||||||
template <
|
template <
|
||||||
class Derived // The derived iterator type being constructed
|
class Derived
|
||||||
, class Value
|
, class Value
|
||||||
, class CategoryOrTraversal
|
, class CategoryOrTraversal
|
||||||
, class Reference = Value&
|
, class Reference
|
||||||
, class Difference = std::ptrdiff_t
|
, class Difference
|
||||||
>
|
>
|
||||||
class iterator_facade
|
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
|
||||||
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
||||||
: public boost::detail::iterator_facade_types<
|
: public boost::iterators::detail::iterator_facade_types<
|
||||||
Value, CategoryOrTraversal, Reference, Difference
|
Value, CategoryOrTraversal, Reference, Difference
|
||||||
>::base
|
>::base
|
||||||
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
|
||||||
# endif
|
# endif
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
typedef boost::iterators::detail::iterator_facade_types<
|
||||||
|
Value, CategoryOrTraversal, Reference, Difference
|
||||||
|
> associated_types;
|
||||||
|
|
||||||
|
typedef boost::iterators::detail::operator_arrow_dispatch<
|
||||||
|
Reference
|
||||||
|
, typename associated_types::pointer
|
||||||
|
> operator_arrow_dispatch_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename associated_types::value_type value_type;
|
||||||
|
typedef Reference reference;
|
||||||
|
typedef Difference difference_type;
|
||||||
|
|
||||||
|
typedef typename operator_arrow_dispatch_::result_type pointer;
|
||||||
|
|
||||||
|
typedef typename associated_types::iterator_category iterator_category;
|
||||||
|
|
||||||
|
public:
|
||||||
|
reference operator*() const
|
||||||
|
{
|
||||||
|
return iterator_core_access::dereference(this->derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer operator->() const
|
||||||
|
{
|
||||||
|
return operator_arrow_dispatch_::apply(*this->derived());
|
||||||
|
}
|
||||||
|
|
||||||
|
Derived& operator++()
|
||||||
|
{
|
||||||
|
iterator_core_access::increment(this->derived());
|
||||||
|
return this->derived();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
//
|
//
|
||||||
// Curiously Recurring Template interface.
|
// Curiously Recurring Template interface.
|
||||||
//
|
//
|
||||||
@ -613,70 +679,20 @@ namespace boost
|
|||||||
{
|
{
|
||||||
return *static_cast<Derived const*>(this);
|
return *static_cast<Derived const*>(this);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
typedef boost::detail::iterator_facade_types<
|
// Implementation for bidirectional traversal iterators
|
||||||
Value, CategoryOrTraversal, Reference, Difference
|
template <
|
||||||
> associated_types;
|
class Derived
|
||||||
|
, class Value
|
||||||
protected:
|
, class CategoryOrTraversal
|
||||||
// For use by derived classes
|
, class Reference
|
||||||
typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
|
, class Difference
|
||||||
|
>
|
||||||
|
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
|
||||||
|
public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef typename associated_types::value_type value_type;
|
|
||||||
typedef Reference reference;
|
|
||||||
typedef Difference difference_type;
|
|
||||||
typedef typename associated_types::pointer pointer;
|
|
||||||
typedef typename associated_types::iterator_category iterator_category;
|
|
||||||
|
|
||||||
reference operator*() const
|
|
||||||
{
|
|
||||||
return iterator_core_access::dereference(this->derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
typename boost::detail::operator_arrow_result<
|
|
||||||
value_type
|
|
||||||
, reference
|
|
||||||
, pointer
|
|
||||||
>::type
|
|
||||||
operator->() const
|
|
||||||
{
|
|
||||||
return boost::detail::operator_arrow_result<
|
|
||||||
value_type
|
|
||||||
, reference
|
|
||||||
, pointer
|
|
||||||
>::make(*this->derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
typename boost::detail::operator_brackets_result<Derived,Value,reference>::type
|
|
||||||
operator[](difference_type n) const
|
|
||||||
{
|
|
||||||
typedef boost::detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
|
|
||||||
|
|
||||||
return boost::detail::make_operator_brackets_result<Derived>(
|
|
||||||
this->derived() + n
|
|
||||||
, use_proxy()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Derived& operator++()
|
|
||||||
{
|
|
||||||
iterator_core_access::increment(this->derived());
|
|
||||||
return this->derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
typename boost::detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
|
|
||||||
operator++(int)
|
|
||||||
{
|
|
||||||
typename boost::detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
|
|
||||||
tmp(this->derived());
|
|
||||||
++*this;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
Derived& operator--()
|
Derived& operator--()
|
||||||
{
|
{
|
||||||
iterator_core_access::decrement(this->derived());
|
iterator_core_access::decrement(this->derived());
|
||||||
@ -689,6 +705,37 @@ namespace boost
|
|||||||
--*this;
|
--*this;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implementation for random access traversal iterators
|
||||||
|
template <
|
||||||
|
class Derived
|
||||||
|
, class Value
|
||||||
|
, class CategoryOrTraversal
|
||||||
|
, class Reference
|
||||||
|
, class Difference
|
||||||
|
>
|
||||||
|
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
|
||||||
|
public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > base_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
|
typedef typename base_type::difference_type difference_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typename boost::iterators::detail::operator_brackets_result<Derived, Value, reference>::type
|
||||||
|
operator[](difference_type n) const
|
||||||
|
{
|
||||||
|
typedef boost::iterators::detail::use_operator_brackets_proxy<Value, Reference> use_proxy;
|
||||||
|
|
||||||
|
return boost::iterators::detail::make_operator_brackets_result<Derived>(
|
||||||
|
this->derived() + n
|
||||||
|
, use_proxy()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Derived& operator+=(difference_type n)
|
Derived& operator+=(difference_type n)
|
||||||
{
|
{
|
||||||
@ -707,36 +754,51 @@ namespace boost
|
|||||||
Derived result(this->derived());
|
Derived result(this->derived());
|
||||||
return result -= x;
|
return result -= x;
|
||||||
}
|
}
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
// There appears to be a bug which trashes the data of classes
|
|
||||||
// derived from iterator_facade when they are assigned unless we
|
|
||||||
// define this assignment operator. This bug is only revealed
|
|
||||||
// (so far) in STLPort debug mode, but it's clearly a codegen
|
|
||||||
// problem so we apply the workaround for all MSVC6.
|
|
||||||
iterator_facade& operator=(iterator_facade const&)
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
} // namespace detail
|
||||||
|
|
||||||
|
//
|
||||||
|
// iterator_facade - use as a public base class for defining new
|
||||||
|
// standard-conforming iterators.
|
||||||
|
//
|
||||||
|
template <
|
||||||
|
class Derived // The derived iterator type being constructed
|
||||||
|
, class Value
|
||||||
|
, class CategoryOrTraversal
|
||||||
|
, class Reference = Value&
|
||||||
|
, class Difference = std::ptrdiff_t
|
||||||
|
>
|
||||||
|
class iterator_facade :
|
||||||
|
public detail::iterator_facade_base<
|
||||||
|
Derived,
|
||||||
|
Value,
|
||||||
|
CategoryOrTraversal,
|
||||||
|
Reference,
|
||||||
|
Difference,
|
||||||
|
detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
|
||||||
|
detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
|
||||||
|
>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
// For use by derived classes
|
||||||
|
typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
|
||||||
|
};
|
||||||
|
|
||||||
template <class I, class V, class TC, class R, class D>
|
template <class I, class V, class TC, class R, class D>
|
||||||
inline typename boost::detail::postfix_increment_result<I,V,R,TC>::type
|
inline typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
|
||||||
operator++(
|
operator++(
|
||||||
iterator_facade<I,V,TC,R,D>& i
|
iterator_facade<I,V,TC,R,D>& i
|
||||||
, int
|
, int
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
typename boost::detail::postfix_increment_result<I,V,R,TC>::type
|
typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
|
||||||
tmp(*static_cast<I*>(&i));
|
tmp(*static_cast<I*>(&i));
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -829,7 +891,7 @@ namespace boost
|
|||||||
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
|
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
|
||||||
BOOST_ITERATOR_FACADE_INTEROP( \
|
BOOST_ITERATOR_FACADE_INTEROP( \
|
||||||
op \
|
op \
|
||||||
, boost::detail::always_bool2 \
|
, boost::iterators::detail::always_bool2 \
|
||||||
, return_prefix \
|
, return_prefix \
|
||||||
, base_op \
|
, base_op \
|
||||||
)
|
)
|
||||||
@ -837,21 +899,50 @@ namespace boost
|
|||||||
BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
|
BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
|
||||||
BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
|
BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
|
||||||
|
|
||||||
BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_from)
|
|
||||||
BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_from)
|
|
||||||
BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_from)
|
|
||||||
BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_from)
|
|
||||||
# undef BOOST_ITERATOR_FACADE_RELATION
|
# undef BOOST_ITERATOR_FACADE_RELATION
|
||||||
|
|
||||||
|
|
||||||
|
# define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type) \
|
||||||
|
{ \
|
||||||
|
/* For those compilers that do not support enable_if */ \
|
||||||
|
BOOST_STATIC_ASSERT(( \
|
||||||
|
is_interoperable< Derived1, Derived2 >::value && \
|
||||||
|
boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived1 >::type, random_access_traversal_tag >::value && \
|
||||||
|
boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived2 >::type, random_access_traversal_tag >::value \
|
||||||
|
)); \
|
||||||
|
return_prefix iterator_core_access::base_op( \
|
||||||
|
*static_cast<Derived1 const*>(&lhs) \
|
||||||
|
, *static_cast<Derived2 const*>(&rhs) \
|
||||||
|
, BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
# define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
|
||||||
|
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \
|
||||||
|
op \
|
||||||
|
, boost::iterators::detail::always_bool2 \
|
||||||
|
, return_prefix \
|
||||||
|
, base_op \
|
||||||
|
)
|
||||||
|
|
||||||
|
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
|
||||||
|
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
|
||||||
|
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
|
||||||
|
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
|
||||||
|
|
||||||
|
# undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
|
||||||
|
|
||||||
// operator- requires an additional part in the static assertion
|
// operator- requires an additional part in the static assertion
|
||||||
BOOST_ITERATOR_FACADE_INTEROP(
|
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
|
||||||
-
|
-
|
||||||
, boost::detail::choose_difference_type
|
, boost::iterators::detail::choose_difference_type
|
||||||
, return
|
, return
|
||||||
, distance_from
|
, distance_from
|
||||||
)
|
)
|
||||||
|
|
||||||
# undef BOOST_ITERATOR_FACADE_INTEROP
|
# undef BOOST_ITERATOR_FACADE_INTEROP
|
||||||
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
|
# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
|
||||||
|
|
||||||
# define BOOST_ITERATOR_FACADE_PLUS(args) \
|
# define BOOST_ITERATOR_FACADE_PLUS(args) \
|
||||||
BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
|
BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
|
||||||
@ -869,9 +960,19 @@ BOOST_ITERATOR_FACADE_PLUS((
|
|||||||
typename Derived::difference_type n
|
typename Derived::difference_type n
|
||||||
, iterator_facade<Derived, V, TC, R, D> const& i
|
, iterator_facade<Derived, V, TC, R, D> const& i
|
||||||
))
|
))
|
||||||
|
|
||||||
# undef BOOST_ITERATOR_FACADE_PLUS
|
# undef BOOST_ITERATOR_FACADE_PLUS
|
||||||
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
|
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
|
||||||
|
|
||||||
|
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
|
||||||
|
# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
|
||||||
|
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::iterator_core_access;
|
||||||
|
using iterators::iterator_facade;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#include <boost/iterator/detail/config_undef.hpp>
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
@ -9,19 +9,11 @@
|
|||||||
# include <boost/detail/workaround.hpp>
|
# include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
// Unfortunately, g++ 2.95.x chokes when we define a class template
|
// Macro for supporting old compilers, no longer needed but kept
|
||||||
// iterator_category which has the same name as its
|
// for backwards compatibility (it was documented).
|
||||||
// std::iterator_category() function, probably due in part to the
|
|
||||||
// "std:: is visible globally" hack it uses. Use
|
|
||||||
// BOOST_ITERATOR_CATEGORY to write code that's portable to older
|
|
||||||
// GCCs.
|
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(__GNUC__, <= 2)
|
|
||||||
# define BOOST_ITERATOR_CATEGORY iterator_category_
|
|
||||||
# else
|
|
||||||
#define BOOST_ITERATOR_CATEGORY iterator_category
|
#define BOOST_ITERATOR_CATEGORY iterator_category
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
template <class Iterator>
|
template <class Iterator>
|
||||||
@ -50,43 +42,19 @@ struct iterator_difference
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class Iterator>
|
template <class Iterator>
|
||||||
struct BOOST_ITERATOR_CATEGORY
|
struct iterator_category
|
||||||
{
|
{
|
||||||
typedef typename boost::detail::iterator_traits<Iterator>::iterator_category type;
|
typedef typename boost::detail::iterator_traits<Iterator>::iterator_category type;
|
||||||
};
|
};
|
||||||
|
|
||||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
} // namespace iterators
|
||||||
template <>
|
|
||||||
struct iterator_value<int>
|
|
||||||
{
|
|
||||||
typedef void type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
using iterators::iterator_value;
|
||||||
struct iterator_reference<int>
|
using iterators::iterator_reference;
|
||||||
{
|
using iterators::iterator_pointer;
|
||||||
typedef void type;
|
using iterators::iterator_difference;
|
||||||
};
|
using iterators::iterator_category;
|
||||||
|
|
||||||
template <>
|
} // namespace boost
|
||||||
struct iterator_pointer<int>
|
|
||||||
{
|
|
||||||
typedef void type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct iterator_difference<int>
|
|
||||||
{
|
|
||||||
typedef void type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct BOOST_ITERATOR_CATEGORY<int>
|
|
||||||
{
|
|
||||||
typedef void type;
|
|
||||||
};
|
|
||||||
# endif
|
|
||||||
|
|
||||||
} // namespace boost::iterator
|
|
||||||
|
|
||||||
#endif // ITERATOR_TRAITS_DWA200347_HPP
|
#endif // ITERATOR_TRAITS_DWA200347_HPP
|
||||||
|
95
include/boost/iterator/minimum_category.hpp
Normal file
95
include/boost/iterator/minimum_category.hpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||||
|
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
#ifndef BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||||
|
# define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||||
|
|
||||||
|
# include <boost/static_assert.hpp>
|
||||||
|
# include <boost/type_traits/is_convertible.hpp>
|
||||||
|
# include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
|
# include <boost/mpl/placeholders.hpp>
|
||||||
|
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <bool GreaterEqual, bool LessEqual>
|
||||||
|
struct minimum_category_impl;
|
||||||
|
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct error_not_related_by_convertibility;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct minimum_category_impl<true,false>
|
||||||
|
{
|
||||||
|
template <class T1, class T2> struct apply
|
||||||
|
{
|
||||||
|
typedef T2 type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct minimum_category_impl<false,true>
|
||||||
|
{
|
||||||
|
template <class T1, class T2> struct apply
|
||||||
|
{
|
||||||
|
typedef T1 type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct minimum_category_impl<true,true>
|
||||||
|
{
|
||||||
|
template <class T1, class T2> struct apply
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
|
||||||
|
typedef T1 type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct minimum_category_impl<false,false>
|
||||||
|
{
|
||||||
|
template <class T1, class T2> struct apply
|
||||||
|
: error_not_related_by_convertibility<T1,T2>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns the minimum category type or fails to compile
|
||||||
|
// if T1 and T2 are unrelated.
|
||||||
|
//
|
||||||
|
template <class T1 = mpl::_1, class T2 = mpl::_2>
|
||||||
|
struct minimum_category
|
||||||
|
{
|
||||||
|
typedef boost::iterators::detail::minimum_category_impl<
|
||||||
|
::boost::is_convertible<T1,T2>::value
|
||||||
|
, ::boost::is_convertible<T2,T1>::value
|
||||||
|
> outer;
|
||||||
|
|
||||||
|
typedef typename outer::template apply<T1,T2> inner;
|
||||||
|
typedef typename inner::type type;
|
||||||
|
|
||||||
|
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct minimum_category<mpl::_1,mpl::_2>
|
||||||
|
{
|
||||||
|
template <class T1, class T2>
|
||||||
|
struct apply : minimum_category<T1,T2>
|
||||||
|
{};
|
||||||
|
|
||||||
|
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2))
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
@ -13,21 +13,21 @@
|
|||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost {
|
||||||
{
|
namespace iterators {
|
||||||
|
|
||||||
template< class ElementIterator
|
template< class ElementIterator
|
||||||
, class IndexIterator>
|
, class IndexIterator>
|
||||||
class permutation_iterator
|
class permutation_iterator
|
||||||
: public iterator_adaptor<
|
: public iterator_adaptor<
|
||||||
permutation_iterator<ElementIterator, IndexIterator>
|
permutation_iterator<ElementIterator, IndexIterator>
|
||||||
, IndexIterator, typename detail::iterator_traits<ElementIterator>::value_type
|
, IndexIterator, typename boost::detail::iterator_traits<ElementIterator>::value_type
|
||||||
, use_default, typename detail::iterator_traits<ElementIterator>::reference>
|
, use_default, typename boost::detail::iterator_traits<ElementIterator>::reference>
|
||||||
{
|
{
|
||||||
typedef iterator_adaptor<
|
typedef iterator_adaptor<
|
||||||
permutation_iterator<ElementIterator, IndexIterator>
|
permutation_iterator<ElementIterator, IndexIterator>
|
||||||
, IndexIterator, typename detail::iterator_traits<ElementIterator>::value_type
|
, IndexIterator, typename boost::detail::iterator_traits<ElementIterator>::value_type
|
||||||
, use_default, typename detail::iterator_traits<ElementIterator>::reference> super_t;
|
, use_default, typename boost::detail::iterator_traits<ElementIterator>::reference> super_t;
|
||||||
|
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
|
|
||||||
@ -60,12 +60,16 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
template <class ElementIterator, class IndexIterator>
|
template <class ElementIterator, class IndexIterator>
|
||||||
permutation_iterator<ElementIterator, IndexIterator>
|
inline permutation_iterator<ElementIterator, IndexIterator>
|
||||||
make_permutation_iterator( ElementIterator e, IndexIterator i )
|
make_permutation_iterator( ElementIterator e, IndexIterator i )
|
||||||
{
|
{
|
||||||
return permutation_iterator<ElementIterator, IndexIterator>( e, i );
|
return permutation_iterator<ElementIterator, IndexIterator>( e, i );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::permutation_iterator;
|
||||||
|
using iterators::make_permutation_iterator;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
@ -8,11 +8,10 @@
|
|||||||
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
||||||
|
|
||||||
#include <boost/iterator.hpp>
|
#include <boost/iterator.hpp>
|
||||||
#include <boost/utility.hpp>
|
|
||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost {
|
||||||
{
|
namespace iterators {
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@ -40,14 +39,19 @@ namespace boost
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
private:
|
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 increment() { --this->base_reference(); }
|
||||||
void decrement() { ++this->base_reference(); }
|
void decrement() { ++this->base_reference(); }
|
||||||
|
|
||||||
void advance(typename super_t::difference_type n)
|
void advance(typename super_t::difference_type n)
|
||||||
{
|
{
|
||||||
this->base_reference() += -n;
|
this->base_reference() -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class OtherIterator>
|
template <class OtherIterator>
|
||||||
@ -59,11 +63,16 @@ namespace boost
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class BidirectionalIterator>
|
template <class BidirectionalIterator>
|
||||||
reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x)
|
inline reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x)
|
||||||
{
|
{
|
||||||
return reverse_iterator<BidirectionalIterator>(x);
|
return reverse_iterator<BidirectionalIterator>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::reverse_iterator;
|
||||||
|
using iterators::make_reverse_iterator;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||||
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||||
|
|
||||||
#include <boost/function.hpp>
|
|
||||||
#include <boost/iterator.hpp>
|
#include <boost/iterator.hpp>
|
||||||
#include <boost/iterator/detail/enable_if.hpp>
|
#include <boost/iterator/detail/enable_if.hpp>
|
||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
#include <boost/iterator/iterator_adaptor.hpp>
|
||||||
@ -21,6 +20,8 @@
|
|||||||
#include <boost/type_traits/is_reference.hpp>
|
#include <boost/type_traits/is_reference.hpp>
|
||||||
#include <boost/type_traits/remove_const.hpp>
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
|
#include <boost/utility/result_of.hpp>
|
||||||
|
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
|
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
|
||||||
# include <boost/type_traits/is_base_and_derived.hpp>
|
# include <boost/type_traits/is_base_and_derived.hpp>
|
||||||
@ -29,40 +30,24 @@
|
|||||||
#include <boost/iterator/detail/config_def.hpp>
|
#include <boost/iterator/detail/config_def.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost {
|
||||||
{
|
namespace iterators {
|
||||||
|
|
||||||
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
|
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
|
||||||
class transform_iterator;
|
class transform_iterator;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template <class UnaryFunc>
|
|
||||||
struct function_object_result
|
|
||||||
{
|
|
||||||
typedef typename UnaryFunc::result_type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
||||||
template <class Return, class Argument>
|
|
||||||
struct function_object_result<Return(*)(Argument)>
|
|
||||||
{
|
|
||||||
typedef Return type;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Compute the iterator_adaptor instantiation to be used for transform_iterator
|
// Compute the iterator_adaptor instantiation to be used for transform_iterator
|
||||||
template <class UnaryFunc, class Iterator, class Reference, class Value>
|
template <class UnaryFunc, class Iterator, class Reference, class Value>
|
||||||
struct transform_iterator_base
|
struct transform_iterator_base
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// By default, dereferencing the iterator yields the same as
|
// By default, dereferencing the iterator yields the same as
|
||||||
// the function. Do we need to adjust the way
|
// the function.
|
||||||
// function_object_result is computed for the standard
|
|
||||||
// proposal (e.g. using Doug's result_of)?
|
|
||||||
typedef typename ia_dflt_help<
|
typedef typename ia_dflt_help<
|
||||||
Reference
|
Reference
|
||||||
, function_object_result<UnaryFunc>
|
, result_of<const UnaryFunc(typename std::iterator_traits<Iterator>::reference)>
|
||||||
>::type reference;
|
>::type reference;
|
||||||
|
|
||||||
// To get the default for Value: remove any reference on the
|
// To get the default for Value: remove any reference on the
|
||||||
@ -88,10 +73,10 @@ namespace boost
|
|||||||
|
|
||||||
template <class UnaryFunc, class Iterator, class Reference, class Value>
|
template <class UnaryFunc, class Iterator, class Reference, class Value>
|
||||||
class transform_iterator
|
class transform_iterator
|
||||||
: public boost::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
|
: public boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
|
||||||
{
|
{
|
||||||
typedef typename
|
typedef typename
|
||||||
boost::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
|
boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
|
||||||
super_t;
|
super_t;
|
||||||
|
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
@ -142,7 +127,7 @@ namespace boost
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class UnaryFunc, class Iterator>
|
template <class UnaryFunc, class Iterator>
|
||||||
transform_iterator<UnaryFunc, Iterator>
|
inline transform_iterator<UnaryFunc, Iterator>
|
||||||
make_transform_iterator(Iterator it, UnaryFunc fun)
|
make_transform_iterator(Iterator it, UnaryFunc fun)
|
||||||
{
|
{
|
||||||
return transform_iterator<UnaryFunc, Iterator>(it, fun);
|
return transform_iterator<UnaryFunc, Iterator>(it, fun);
|
||||||
@ -156,16 +141,9 @@ namespace boost
|
|||||||
// function pointer in the iterator be 0, leading to a runtime
|
// function pointer in the iterator be 0, leading to a runtime
|
||||||
// crash.
|
// crash.
|
||||||
template <class UnaryFunc, class Iterator>
|
template <class UnaryFunc, class Iterator>
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
inline typename iterators::enable_if<
|
||||||
typename mpl::if_<
|
|
||||||
#else
|
|
||||||
typename iterators::enable_if<
|
|
||||||
#endif
|
|
||||||
is_class<UnaryFunc> // We should probably find a cheaper test than is_class<>
|
is_class<UnaryFunc> // We should probably find a cheaper test than is_class<>
|
||||||
, transform_iterator<UnaryFunc, Iterator>
|
, transform_iterator<UnaryFunc, Iterator>
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
|
||||||
, int[3]
|
|
||||||
#endif
|
|
||||||
>::type
|
>::type
|
||||||
make_transform_iterator(Iterator it)
|
make_transform_iterator(Iterator it)
|
||||||
{
|
{
|
||||||
@ -174,13 +152,18 @@ namespace boost
|
|||||||
|
|
||||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||||
template <class Return, class Argument, class Iterator>
|
template <class Return, class Argument, class Iterator>
|
||||||
transform_iterator< Return (*)(Argument), Iterator, Return>
|
inline transform_iterator< Return (*)(Argument), Iterator, Return>
|
||||||
make_transform_iterator(Iterator it, Return (*fun)(Argument))
|
make_transform_iterator(Iterator it, Return (*fun)(Argument))
|
||||||
{
|
{
|
||||||
return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
|
return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::transform_iterator;
|
||||||
|
using iterators::make_transform_iterator;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#include <boost/iterator/detail/config_undef.hpp>
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// Copyright David Abrahams and Thomas Becker 2000-2006. Distributed
|
// Copyright David Abrahams and Thomas Becker 2000-2006.
|
||||||
// under the Boost Software License, Version 1.0. (See accompanying
|
// Copyright Kohei Takahashi 2012-2014.
|
||||||
// file LICENSE_1_0.txt or copy at
|
//
|
||||||
|
// 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)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
||||||
@ -12,44 +14,34 @@
|
|||||||
#include <boost/iterator/iterator_facade.hpp>
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
|
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
|
||||||
#include <boost/iterator/iterator_categories.hpp>
|
#include <boost/iterator/iterator_categories.hpp>
|
||||||
#include <boost/detail/iterator.hpp>
|
|
||||||
|
|
||||||
#include <boost/iterator/detail/minimum_category.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/type_traits/remove_reference.hpp>
|
||||||
#include <boost/mpl/and.hpp>
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
#include <boost/mpl/apply.hpp>
|
|
||||||
#include <boost/mpl/eval_if.hpp>
|
#include <boost/mpl/at.hpp>
|
||||||
#include <boost/mpl/lambda.hpp>
|
#include <boost/mpl/fold.hpp>
|
||||||
|
#include <boost/mpl/transform.hpp>
|
||||||
#include <boost/mpl/placeholders.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 boost {
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
// Zip iterator forward declaration for zip_iterator_base
|
// Zip iterator forward declaration for zip_iterator_base
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
class zip_iterator;
|
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
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -72,332 +64,97 @@ namespace boost {
|
|||||||
struct increment_iterator
|
struct increment_iterator
|
||||||
{
|
{
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
void operator()(Iterator& it)
|
void operator()(Iterator& it) const
|
||||||
{ ++it; }
|
{ ++it; }
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
struct decrement_iterator
|
struct decrement_iterator
|
||||||
{
|
{
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
void operator()(Iterator& it)
|
void operator()(Iterator& it) const
|
||||||
{ --it; }
|
{ --it; }
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
struct dereference_iterator
|
struct dereference_iterator
|
||||||
{
|
{
|
||||||
template<typename Iterator>
|
template<typename>
|
||||||
struct apply
|
struct result;
|
||||||
|
|
||||||
|
template<typename This, typename Iterator>
|
||||||
|
struct result<This(Iterator)>
|
||||||
{
|
{
|
||||||
typedef typename
|
typedef typename
|
||||||
iterator_traits<Iterator>::reference
|
remove_cv<typename remove_reference<Iterator>::type>::type
|
||||||
type;
|
iterator;
|
||||||
|
|
||||||
|
typedef typename iterator_reference<iterator>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
typename apply<Iterator>::type operator()(Iterator const& it)
|
typename result<dereference_iterator(Iterator)>::type
|
||||||
|
operator()(Iterator const& it) const
|
||||||
{ return *it; }
|
{ 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<
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
mpl::or_<
|
|
||||||
#endif
|
|
||||||
boost::is_same<Tuple, tuples::null_type>
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
|
||||||
, boost::is_same<Tuple,int>
|
|
||||||
>
|
|
||||||
#endif
|
|
||||||
, 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>
|
|
||||||
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>
|
|
||||||
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>
|
|
||||||
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>
|
|
||||||
Fun BOOST_TUPLE_ALGO(tuple_for_each)(
|
|
||||||
tuples::null_type
|
|
||||||
, Fun f BOOST_TUPLE_ALGO_TERMINATOR
|
|
||||||
)
|
|
||||||
{ return f; }
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Tuple, typename Fun>
|
|
||||||
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>
|
|
||||||
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>
|
|
||||||
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 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
|
// Metafunction to obtain the type of the tuple whose element types
|
||||||
// are the reference types of an iterator tuple.
|
// are the reference types of an iterator tuple.
|
||||||
//
|
//
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
struct tuple_of_references
|
struct tuple_of_references
|
||||||
: tuple_impl_specific::tuple_meta_transform<
|
: mpl::transform<
|
||||||
IteratorTuple,
|
IteratorTuple,
|
||||||
iterator_reference<mpl::_1>
|
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
|
// Metafunction to obtain the minimal traversal tag in a tuple
|
||||||
// of iterators.
|
// of iterators.
|
||||||
//
|
//
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
struct minimum_traversal_category_in_iterator_tuple
|
struct minimum_traversal_category_in_iterator_tuple
|
||||||
{
|
{
|
||||||
typedef typename tuple_impl_specific::tuple_meta_transform<
|
typedef typename mpl::transform<
|
||||||
IteratorTuple
|
IteratorTuple
|
||||||
, iterator_traversal<>
|
, pure_traversal_tag<iterator_traversal<> >
|
||||||
>::type tuple_of_traversal_tags;
|
>::type tuple_of_traversal_tags;
|
||||||
|
|
||||||
typedef typename tuple_impl_specific::tuple_meta_accumulate<
|
typedef typename mpl::fold<
|
||||||
tuple_of_traversal_tags
|
tuple_of_traversal_tags
|
||||||
, minimum_category<>
|
|
||||||
, random_access_traversal_tag
|
, random_access_traversal_tag
|
||||||
|
, minimum_category<>
|
||||||
>::type type;
|
>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
|
template<typename Iterator1, typename Iterator2>
|
||||||
template <>
|
struct minimum_traversal_category_in_iterator_tuple<std::pair<Iterator1, Iterator2> >
|
||||||
struct minimum_traversal_category_in_iterator_tuple<int>
|
|
||||||
{
|
{
|
||||||
typedef int type;
|
typedef typename pure_traversal_tag<
|
||||||
};
|
typename iterator_traversal<Iterator1>::type
|
||||||
#endif
|
>::type iterator1_traversal;
|
||||||
|
typedef typename pure_traversal_tag<
|
||||||
|
typename iterator_traversal<Iterator2>::type
|
||||||
|
>::type iterator2_traversal;
|
||||||
|
|
||||||
// We need to call tuple_meta_accumulate with mpl::and_ as the
|
typedef typename minimum_category<
|
||||||
// accumulating functor. To this end, we need to wrap it into
|
iterator1_traversal
|
||||||
// a struct that has exactly two arguments (that is, template
|
, typename minimum_category<
|
||||||
// parameters) and not five, like mpl::and_ does.
|
iterator2_traversal
|
||||||
//
|
, random_access_traversal_tag
|
||||||
template<typename Arg1, typename Arg2>
|
>::type
|
||||||
struct and_with_two_args
|
>::type type;
|
||||||
: mpl::and_<Arg1, Arg2>
|
|
||||||
{
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Class zip_iterator_base
|
// Class zip_iterator_base
|
||||||
@ -418,9 +175,9 @@ namespace boost {
|
|||||||
typedef reference value_type;
|
typedef reference value_type;
|
||||||
|
|
||||||
// Difference type is the first iterator's difference type
|
// Difference type is the first iterator's difference type
|
||||||
typedef typename iterator_traits<
|
typedef typename iterator_difference<
|
||||||
typename tuples::element<0, IteratorTuple>::type
|
typename mpl::at_c<IteratorTuple, 0>::type
|
||||||
>::difference_type difference_type;
|
>::type difference_type;
|
||||||
|
|
||||||
// Traversal catetgory is the minimum traversal category in the
|
// Traversal catetgory is the minimum traversal category in the
|
||||||
// iterator tuple.
|
// iterator tuple.
|
||||||
@ -446,6 +203,30 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
typedef int type;
|
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));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
@ -501,10 +282,11 @@ namespace boost {
|
|||||||
// iterators in the iterator tuple.
|
// iterators in the iterator tuple.
|
||||||
typename super_t::reference dereference() const
|
typename super_t::reference dereference() const
|
||||||
{
|
{
|
||||||
return detail::tuple_impl_specific::tuple_transform(
|
typedef typename super_t::reference reference;
|
||||||
|
typedef detail::converter<reference> gen;
|
||||||
|
return gen::call(fusion::transform(
|
||||||
get_iterator_tuple(),
|
get_iterator_tuple(),
|
||||||
detail::dereference_iterator()
|
detail::dereference_iterator()));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Two zip iterators are equal if all iterators in the iterator
|
// Two zip iterators are equal if all iterators in the iterator
|
||||||
@ -520,39 +302,35 @@ namespace boost {
|
|||||||
template<typename OtherIteratorTuple>
|
template<typename OtherIteratorTuple>
|
||||||
bool equal(const zip_iterator<OtherIteratorTuple>& other) const
|
bool equal(const zip_iterator<OtherIteratorTuple>& other) const
|
||||||
{
|
{
|
||||||
return detail::tuple_impl_specific::tuple_equal(
|
return fusion::equal_to(
|
||||||
get_iterator_tuple(),
|
get_iterator_tuple(),
|
||||||
other.get_iterator_tuple()
|
other.get_iterator_tuple());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advancing a zip iterator means to advance all iterators in the
|
// Advancing a zip iterator means to advance all iterators in the
|
||||||
// iterator tuple.
|
// iterator tuple.
|
||||||
void advance(typename super_t::difference_type n)
|
void advance(typename super_t::difference_type n)
|
||||||
{
|
{
|
||||||
detail::tuple_impl_specific::tuple_for_each(
|
fusion::for_each(
|
||||||
m_iterator_tuple,
|
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
|
// Incrementing a zip iterator means to increment all iterators in
|
||||||
// the iterator tuple.
|
// the iterator tuple.
|
||||||
void increment()
|
void increment()
|
||||||
{
|
{
|
||||||
detail::tuple_impl_specific::tuple_for_each(
|
fusion::for_each(
|
||||||
m_iterator_tuple,
|
m_iterator_tuple,
|
||||||
detail::increment_iterator()
|
detail::increment_iterator());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrementing a zip iterator means to decrement all iterators in
|
// Decrementing a zip iterator means to decrement all iterators in
|
||||||
// the iterator tuple.
|
// the iterator tuple.
|
||||||
void decrement()
|
void decrement()
|
||||||
{
|
{
|
||||||
detail::tuple_impl_specific::tuple_for_each(
|
fusion::for_each(
|
||||||
m_iterator_tuple,
|
m_iterator_tuple,
|
||||||
detail::decrement_iterator()
|
detail::decrement_iterator());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distance is calculated using the first iterator in the tuple.
|
// Distance is calculated using the first iterator in the tuple.
|
||||||
@ -561,8 +339,8 @@ namespace boost {
|
|||||||
const zip_iterator<OtherIteratorTuple>& other
|
const zip_iterator<OtherIteratorTuple>& other
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return boost::tuples::get<0>(other.get_iterator_tuple()) -
|
return fusion::at_c<0>(other.get_iterator_tuple()) -
|
||||||
boost::tuples::get<0>(this->get_iterator_tuple());
|
fusion::at_c<0>(this->get_iterator_tuple());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data Members
|
// Data Members
|
||||||
@ -576,10 +354,15 @@ namespace boost {
|
|||||||
// Make function for zip iterator
|
// Make function for zip iterator
|
||||||
//
|
//
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
zip_iterator<IteratorTuple>
|
inline zip_iterator<IteratorTuple>
|
||||||
make_zip_iterator(IteratorTuple t)
|
make_zip_iterator(IteratorTuple t)
|
||||||
{ return zip_iterator<IteratorTuple>(t); }
|
{ return zip_iterator<IteratorTuple>(t); }
|
||||||
|
|
||||||
}
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::zip_iterator;
|
||||||
|
using iterators::make_zip_iterator;
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// this should use random_access_iterator_helper but I've had
|
// this should use random_access_iterator_helper but I've had
|
||||||
@ -61,13 +62,19 @@ inline int_iterator<IntT>
|
|||||||
operator+(IntT n, int_iterator<IntT> t) { t += n; return t; }
|
operator+(IntT n, int_iterator<IntT> t) { t += n; return t; }
|
||||||
|
|
||||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
} /* namespace iterators */
|
||||||
|
|
||||||
|
using iterators::int_iterator;
|
||||||
|
|
||||||
} /* namespace boost */
|
} /* namespace boost */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
namespace boost {
|
namespace boost {
|
||||||
using ::int_iterator;
|
using ::int_iterator;
|
||||||
}
|
namespace iterators {
|
||||||
|
using ::int_iterator;
|
||||||
|
}}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
// (C) Copyright David Abrahams and Jeremy Siek 2000-2001.
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Revision History:
|
|
||||||
// 04 Jan 2001 Factored counting_iterator stuff into
|
|
||||||
// boost/counting_iterator.hpp (David Abrahams)
|
|
||||||
|
|
||||||
#ifndef BOOST_INTEGER_RANGE_HPP_
|
|
||||||
#define BOOST_INTEGER_RANGE_HPP_
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/iterator/counting_iterator.hpp>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
// Counting Iterator and Integer Range Class
|
|
||||||
|
|
||||||
template <class IntegerType>
|
|
||||||
struct integer_range {
|
|
||||||
typedef counting_iterator<IntegerType> iterator;
|
|
||||||
|
|
||||||
typedef iterator const_iterator;
|
|
||||||
typedef IntegerType value_type;
|
|
||||||
typedef std::ptrdiff_t difference_type;
|
|
||||||
typedef IntegerType reference;
|
|
||||||
typedef IntegerType const_reference;
|
|
||||||
typedef const IntegerType* pointer;
|
|
||||||
typedef const IntegerType* const_pointer;
|
|
||||||
typedef IntegerType size_type;
|
|
||||||
|
|
||||||
integer_range(IntegerType start, IntegerType finish)
|
|
||||||
: m_start(start), m_finish(finish) { }
|
|
||||||
|
|
||||||
iterator begin() const { return iterator(m_start); }
|
|
||||||
iterator end() const { return iterator(m_finish); }
|
|
||||||
size_type size() const { return m_finish - m_start; }
|
|
||||||
bool empty() const { return m_finish == m_start; }
|
|
||||||
void swap(integer_range& x) {
|
|
||||||
std::swap(m_start, x.m_start);
|
|
||||||
std::swap(m_finish, x.m_finish);
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
IntegerType m_start, m_finish;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class IntegerType>
|
|
||||||
inline integer_range<IntegerType>
|
|
||||||
make_integer_range(IntegerType first, IntegerType last)
|
|
||||||
{
|
|
||||||
return integer_range<IntegerType>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_INTEGER_RANGE_HPP_
|
|
@ -25,7 +25,6 @@
|
|||||||
# include <boost/static_assert.hpp>
|
# include <boost/static_assert.hpp>
|
||||||
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
||||||
# include <boost/implicit_cast.hpp>
|
# include <boost/implicit_cast.hpp>
|
||||||
# include <boost/type_traits/broken_compiler_spec.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
@ -41,9 +40,8 @@ struct dummyT {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
// Tests whether type Iterator satisfies the requirements for a
|
// Tests whether type Iterator satisfies the requirements for a
|
||||||
// TrivialIterator.
|
// TrivialIterator.
|
||||||
@ -263,6 +261,18 @@ void const_nonconst_iterator_test(Iterator i, ConstIterator j)
|
|||||||
assert(i == k);
|
assert(i == k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::undefined;
|
||||||
|
using iterators::trivial_iterator_test;
|
||||||
|
using iterators::mutable_trivial_iterator_test;
|
||||||
|
using iterators::input_iterator_test;
|
||||||
|
using iterators::lvalue_test;
|
||||||
|
using iterators::forward_iterator_test;
|
||||||
|
using iterators::bidirectional_iterator_test;
|
||||||
|
using iterators::random_access_iterator_test;
|
||||||
|
using iterators::const_nonconst_iterator_test;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_TESTS_HPP
|
#endif // BOOST_ITERATOR_TESTS_HPP
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
namespace iterators {
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
class shared_container_iterator : public iterator_adaptor<
|
class shared_container_iterator : public iterator_adaptor<
|
||||||
@ -37,7 +38,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
shared_container_iterator<Container>
|
inline shared_container_iterator<Container>
|
||||||
make_shared_container_iterator(typename Container::iterator iter,
|
make_shared_container_iterator(typename Container::iterator iter,
|
||||||
boost::shared_ptr<Container> const& container) {
|
boost::shared_ptr<Container> const& container) {
|
||||||
typedef shared_container_iterator<Container> iterator;
|
typedef shared_container_iterator<Container> iterator;
|
||||||
@ -47,7 +48,7 @@ make_shared_container_iterator(typename Container::iterator iter,
|
|||||||
|
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
std::pair<
|
inline std::pair<
|
||||||
shared_container_iterator<Container>,
|
shared_container_iterator<Container>,
|
||||||
shared_container_iterator<Container> >
|
shared_container_iterator<Container> >
|
||||||
make_shared_container_range(boost::shared_ptr<Container> const& container) {
|
make_shared_container_range(boost::shared_ptr<Container> const& container) {
|
||||||
@ -57,6 +58,12 @@ make_shared_container_range(boost::shared_ptr<Container> const& container) {
|
|||||||
make_shared_container_iterator(container->end(),container));
|
make_shared_container_iterator(container->end(),container));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
using iterators::shared_container_iterator;
|
||||||
|
using iterators::make_shared_container_iterator;
|
||||||
|
using iterators::make_shared_container_range;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif // SHARED_CONTAINER_ITERATOR_RG08102002_HPP
|
#endif // SHARED_CONTAINER_ITERATOR_RG08102002_HPP
|
||||||
|
18
meta/libraries.json
Normal file
18
meta/libraries.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"key": "iterator",
|
||||||
|
"name": "Iterator",
|
||||||
|
"authors": [
|
||||||
|
"Dave Abrahams",
|
||||||
|
"Jeremy Siek",
|
||||||
|
"Thomas Witt"
|
||||||
|
],
|
||||||
|
"description": "The Boost Iterator Library contains two parts. The first is a system of concepts which extend the C++ standard iterator requirements. The second is a framework of components for building iterators based on these extended concepts and includes several useful iterator adaptors.",
|
||||||
|
"category": [
|
||||||
|
"Iterators"
|
||||||
|
],
|
||||||
|
"maintainers": [
|
||||||
|
"David Abrahams <dave -at- boost-consulting.com>",
|
||||||
|
"Thomas Witt <witt - at - acm.org>",
|
||||||
|
"Jeffrey Lee Hellrung Jr. <jeffrey.hellrung -at- gmail.com>"
|
||||||
|
]
|
||||||
|
}
|
@ -14,11 +14,17 @@ test-suite iterator
|
|||||||
|
|
||||||
[ run zip_iterator_test.cpp
|
[ run zip_iterator_test.cpp
|
||||||
: : :
|
: : :
|
||||||
|
|
||||||
# stlport's debug mode generates long symbols which overwhelm
|
# stlport's debug mode generates long symbols which overwhelm
|
||||||
# vc6
|
# vc6
|
||||||
#<msvc-stlport><*><runtime-build>release
|
#<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.
|
# These tests should work for just about everything.
|
||||||
[ compile is_lvalue_iterator.cpp ]
|
[ compile is_lvalue_iterator.cpp ]
|
||||||
@ -43,5 +49,13 @@ test-suite iterator
|
|||||||
[ run iterator_traits_test.cpp ]
|
[ run iterator_traits_test.cpp ]
|
||||||
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
||||||
]
|
]
|
||||||
|
[ run function_input_iterator_test.cpp ]
|
||||||
|
|
||||||
|
[ run generator_iterator_test.cpp ]
|
||||||
|
|
||||||
|
[ run minimum_category.cpp ]
|
||||||
|
[ compile-fail minimum_category_compile_fail.cpp ]
|
||||||
|
|
||||||
|
[ run advance_test.cpp ]
|
||||||
|
[ run distance_test.cpp ]
|
||||||
;
|
;
|
||||||
|
91
test/advance_test.cpp
Normal file
91
test/advance_test.cpp
Normal 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();
|
||||||
|
}
|
85
test/detail/zip_iterator_test.ipp
Normal file
85
test/detail/zip_iterator_test.ipp
Normal 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();
|
||||||
|
}
|
857
test/detail/zip_iterator_test_original.ipp
Normal file
857
test/detail/zip_iterator_test_original.ipp
Normal 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
84
test/distance_test.cpp
Normal 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();
|
||||||
|
}
|
119
test/function_input_iterator_test.cpp
Normal file
119
test/function_input_iterator_test.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright 2010 (c) Dean Michael Berris
|
||||||
|
// Distributed under the Boost Software License Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/iterator/function_input_iterator.hpp>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct ones {
|
||||||
|
typedef int result_type;
|
||||||
|
result_type operator() () {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int ones_function () {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct counter {
|
||||||
|
typedef int result_type;
|
||||||
|
int n;
|
||||||
|
explicit counter(int n_) : n(n_) { }
|
||||||
|
result_type operator() () {
|
||||||
|
return n++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
// test the iterator with function objects
|
||||||
|
ones ones_generator;
|
||||||
|
vector<int> values(10);
|
||||||
|
generate(values.begin(), values.end(), ones());
|
||||||
|
|
||||||
|
vector<int> generated;
|
||||||
|
copy(
|
||||||
|
boost::make_function_input_iterator(ones_generator, 0),
|
||||||
|
boost::make_function_input_iterator(ones_generator, 10),
|
||||||
|
back_inserter(generated)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(values.size() == generated.size());
|
||||||
|
assert(equal(values.begin(), values.end(), generated.begin()));
|
||||||
|
cout << "function iterator test with function objects successful." << endl;
|
||||||
|
|
||||||
|
// test the iterator with normal functions
|
||||||
|
vector<int>().swap(generated);
|
||||||
|
copy(
|
||||||
|
boost::make_function_input_iterator(&ones_function, 0),
|
||||||
|
boost::make_function_input_iterator(&ones_function, 10),
|
||||||
|
back_inserter(generated)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(values.size() == generated.size());
|
||||||
|
assert(equal(values.begin(), values.end(), generated.begin()));
|
||||||
|
cout << "function iterator test with pointer to function successful." << endl;
|
||||||
|
|
||||||
|
// test the iterator with a reference to a function
|
||||||
|
vector<int>().swap(generated);
|
||||||
|
copy(
|
||||||
|
boost::make_function_input_iterator(ones_function, 0),
|
||||||
|
boost::make_function_input_iterator(ones_function, 10),
|
||||||
|
back_inserter(generated)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(values.size() == generated.size());
|
||||||
|
assert(equal(values.begin(), values.end(), generated.begin()));
|
||||||
|
cout << "function iterator test with reference to function successful." << endl;
|
||||||
|
|
||||||
|
// test the iterator with a stateful function object
|
||||||
|
counter counter_generator(42);
|
||||||
|
vector<int>().swap(generated);
|
||||||
|
copy(
|
||||||
|
boost::make_function_input_iterator(counter_generator, 0),
|
||||||
|
boost::make_function_input_iterator(counter_generator, 10),
|
||||||
|
back_inserter(generated)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(generated.size() == 10);
|
||||||
|
assert(counter_generator.n == 42 + 10);
|
||||||
|
for(std::size_t i = 0; i != 10; ++i)
|
||||||
|
assert(generated[i] == 42 + i);
|
||||||
|
cout << "function iterator test with stateful function object successful." << endl;
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
63
test/generator_iterator_test.cpp
Normal file
63
test/generator_iterator_test.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2014 Peter Dimov
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/generator_iterator.hpp>
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
class X
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
int v;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef int result_type;
|
||||||
|
|
||||||
|
X(): v( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int operator()()
|
||||||
|
{
|
||||||
|
return ++v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class InputIterator, class Size, class OutputIterator> OutputIterator copy_n( InputIterator first, Size n, OutputIterator result )
|
||||||
|
{
|
||||||
|
while( n-- > 0 )
|
||||||
|
{
|
||||||
|
*result++ = *first++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_test()
|
||||||
|
{
|
||||||
|
X x;
|
||||||
|
boost::generator_iterator<X> in( &x );
|
||||||
|
|
||||||
|
int const N = 4;
|
||||||
|
int v[ N ] = { 0 };
|
||||||
|
|
||||||
|
::copy_n( in, 4, v );
|
||||||
|
|
||||||
|
BOOST_TEST_EQ( v[0], 1 );
|
||||||
|
BOOST_TEST_EQ( v[1], 2 );
|
||||||
|
BOOST_TEST_EQ( v[2], 3 );
|
||||||
|
BOOST_TEST_EQ( v[3], 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
copy_test();
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
@ -27,8 +27,6 @@ struct my_ptr {
|
|||||||
// typedef boost::no_traversal_tag iterator_category;
|
// typedef boost::no_traversal_tag iterator_category;
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(my_ptr)
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(zow)
|
|
||||||
|
|
||||||
// Borland 5.6.4 and earlier drop const all over the place, so this
|
// Borland 5.6.4 and earlier drop const all over the place, so this
|
||||||
// test will fail in the lines marked with (**)
|
// test will fail in the lines marked with (**)
|
||||||
|
@ -27,8 +27,6 @@
|
|||||||
|
|
||||||
#include <boost/mpl/has_xxx.hpp>
|
#include <boost/mpl/has_xxx.hpp>
|
||||||
|
|
||||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -53,7 +51,6 @@ template <int I> struct see_val;
|
|||||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||||
|
|
||||||
using boost::dummyT;
|
using boost::dummyT;
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::shared_ptr<dummyT>)
|
|
||||||
|
|
||||||
typedef std::vector<int> storage;
|
typedef std::vector<int> storage;
|
||||||
typedef std::vector<int*> pointer_ra_container;
|
typedef std::vector<int*> pointer_ra_container;
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
|
||||||
#include <boost/iterator/is_lvalue_iterator.hpp>
|
#include <boost/iterator/is_lvalue_iterator.hpp>
|
||||||
#include <boost/iterator.hpp>
|
#include <boost/iterator.hpp>
|
||||||
|
|
||||||
@ -20,7 +19,6 @@ struct v
|
|||||||
~v();
|
~v();
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(v)
|
|
||||||
|
|
||||||
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
|
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
|
||||||
{
|
{
|
||||||
@ -83,8 +81,6 @@ struct constant_lvalue_iterator
|
|||||||
constant_lvalue_iterator operator++(int);
|
constant_lvalue_iterator operator++(int);
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<v>::proxy)
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator<int>::proxy)
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
|
||||||
#include <boost/iterator/is_readable_iterator.hpp>
|
#include <boost/iterator/is_readable_iterator.hpp>
|
||||||
#include <boost/iterator.hpp>
|
#include <boost/iterator.hpp>
|
||||||
|
|
||||||
@ -20,7 +19,6 @@ struct v
|
|||||||
~v();
|
~v();
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(v)
|
|
||||||
|
|
||||||
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
|
struct value_iterator : boost::iterator<std::input_iterator_tag,v>
|
||||||
{
|
{
|
||||||
@ -71,7 +69,6 @@ struct proxy_iterator2 : boost::iterator<std::output_iterator_tag,v>
|
|||||||
proxy operator*() const;
|
proxy operator*() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(proxy_iterator::proxy)
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <boost/pending/iterator_tests.hpp>
|
#include <boost/pending/iterator_tests.hpp>
|
||||||
|
|
||||||
# include <boost/type_traits/broken_compiler_spec.hpp>
|
|
||||||
|
|
||||||
# include <boost/detail/lightweight_test.hpp>
|
# include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -35,37 +33,6 @@
|
|||||||
|
|
||||||
using boost::dummyT;
|
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> storage;
|
||||||
typedef std::deque<int*> pointer_deque;
|
typedef std::deque<int*> pointer_deque;
|
||||||
typedef std::set<storage::iterator> iterator_set;
|
typedef std::set<storage::iterator> iterator_set;
|
||||||
|
@ -7,6 +7,11 @@
|
|||||||
#include <boost/iterator/iterator_facade.hpp>
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
#include <boost/iterator/new_iterator_tests.hpp>
|
#include <boost/iterator/new_iterator_tests.hpp>
|
||||||
|
|
||||||
|
#include <boost/call_traits.hpp>
|
||||||
|
#include <boost/polymorphic_cast.hpp>
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
|
||||||
// This is a really, really limited test so far. All we're doing
|
// This is a really, really limited test so far. All we're doing
|
||||||
// right now is checking that the postfix++ proxy for single-pass
|
// right now is checking that the postfix++ proxy for single-pass
|
||||||
// iterators works properly.
|
// iterators works properly.
|
||||||
@ -87,7 +92,100 @@ struct input_iter
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct wrapper
|
||||||
|
{
|
||||||
|
T m_x;
|
||||||
|
explicit wrapper(typename boost::call_traits<T>::param_type x)
|
||||||
|
: m_x(x)
|
||||||
|
{ }
|
||||||
|
template <class U>
|
||||||
|
wrapper(const wrapper<U>& other,
|
||||||
|
typename boost::enable_if< boost::is_convertible<U,T> >::type* = 0)
|
||||||
|
: m_x(other.m_x)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iterator_with_proxy_reference
|
||||||
|
: boost::iterator_facade<
|
||||||
|
iterator_with_proxy_reference
|
||||||
|
, wrapper<int>
|
||||||
|
, boost::incrementable_traversal_tag
|
||||||
|
, wrapper<int&>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
int& m_x;
|
||||||
|
explicit iterator_with_proxy_reference(int& x)
|
||||||
|
: m_x(x)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{ }
|
||||||
|
wrapper<int&> dereference() const
|
||||||
|
{ return wrapper<int&>(m_x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U>
|
||||||
|
void same_type(U const&)
|
||||||
|
{ BOOST_MPL_ASSERT((boost::is_same<T,U>)); }
|
||||||
|
|
||||||
|
template <class I, class A>
|
||||||
|
struct abstract_iterator
|
||||||
|
: boost::iterator_facade<
|
||||||
|
abstract_iterator<I, A>
|
||||||
|
, A &
|
||||||
|
// In order to be value type as a reference, traversal category has
|
||||||
|
// to satisfy least forward traversal.
|
||||||
|
, boost::forward_traversal_tag
|
||||||
|
, A &
|
||||||
|
>
|
||||||
|
{
|
||||||
|
abstract_iterator(I iter) : iter(iter) {}
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{ ++iter; }
|
||||||
|
|
||||||
|
A & dereference() const
|
||||||
|
{ return *iter; }
|
||||||
|
|
||||||
|
bool equal(abstract_iterator const& y) const
|
||||||
|
{ return iter == y.iter; }
|
||||||
|
|
||||||
|
I iter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct base
|
||||||
|
{
|
||||||
|
virtual void assign(const base &) = 0;
|
||||||
|
virtual bool equal(const base &) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct derived : base
|
||||||
|
{
|
||||||
|
derived(int state) : state(state) { }
|
||||||
|
derived(const derived &d) : state(d.state) { }
|
||||||
|
derived(const base &b) { derived::assign(b); }
|
||||||
|
|
||||||
|
virtual void assign(const base &b)
|
||||||
|
{
|
||||||
|
state = boost::polymorphic_cast<const derived *>(&b)->state;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool equal(const base &b) const
|
||||||
|
{
|
||||||
|
return state == boost::polymorphic_cast<const derived *>(&b)->state;
|
||||||
|
}
|
||||||
|
|
||||||
|
int state;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const base &lhs, const base &rhs)
|
||||||
|
{
|
||||||
|
return lhs.equal(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
int state = 0;
|
int state = 0;
|
||||||
boost::readable_iterator_test(counter_iterator<int const&>(&state), 0);
|
boost::readable_iterator_test(counter_iterator<int const&>(&state), 0);
|
||||||
@ -95,12 +193,35 @@ int main()
|
|||||||
boost::readable_iterator_test(counter_iterator<proxy>(&state), 3);
|
boost::readable_iterator_test(counter_iterator<proxy>(&state), 3);
|
||||||
boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7);
|
boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7);
|
||||||
BOOST_TEST(state == 8);
|
BOOST_TEST(state == 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
// test for a fix to http://tinyurl.com/zuohe
|
// test for a fix to http://tinyurl.com/zuohe
|
||||||
// These two lines should be equivalent (and both compile)
|
// These two lines should be equivalent (and both compile)
|
||||||
input_iter p;
|
input_iter p;
|
||||||
(*p).mutator();
|
(*p).mutator();
|
||||||
p->mutator();
|
p->mutator();
|
||||||
|
|
||||||
|
same_type<input_iter::pointer>(p.operator->());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
iterator_with_proxy_reference i(x);
|
||||||
|
BOOST_TEST(x == 0);
|
||||||
|
BOOST_TEST(i.m_x == 0);
|
||||||
|
++(*i).m_x;
|
||||||
|
BOOST_TEST(x == 1);
|
||||||
|
BOOST_TEST(i.m_x == 1);
|
||||||
|
++i->m_x;
|
||||||
|
BOOST_TEST(x == 2);
|
||||||
|
BOOST_TEST(i.m_x == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
derived d(1);
|
||||||
|
boost::readable_iterator_test(abstract_iterator<derived *, base>(&d), derived(1));
|
||||||
|
}
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
22
test/minimum_category.cpp
Normal file
22
test/minimum_category.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright Andrey Semashev 2014.
|
||||||
|
//
|
||||||
|
// Use, modification and distribution is subject to
|
||||||
|
// the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/iterator/minimum_category.hpp>
|
||||||
|
#include <boost/core/lightweight_test_trait.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
using boost::is_same;
|
||||||
|
using boost::iterators::minimum_category;
|
||||||
|
|
||||||
|
int main(int, char*[])
|
||||||
|
{
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<minimum_category<std::forward_iterator_tag, std::random_access_iterator_tag>::type, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<minimum_category<std::random_access_iterator_tag, std::forward_iterator_tag>::type, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<minimum_category<std::random_access_iterator_tag, std::random_access_iterator_tag>::type, std::random_access_iterator_tag>));
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
19
test/minimum_category_compile_fail.cpp
Normal file
19
test/minimum_category_compile_fail.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright Andrey Semashev 2014.
|
||||||
|
//
|
||||||
|
// Use, modification and distribution is subject to
|
||||||
|
// the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/iterator/minimum_category.hpp>
|
||||||
|
|
||||||
|
using boost::iterators::minimum_category;
|
||||||
|
|
||||||
|
struct A {};
|
||||||
|
struct B {};
|
||||||
|
|
||||||
|
int main(int, char*[])
|
||||||
|
{
|
||||||
|
minimum_category<A, B>::type cat;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -35,7 +35,6 @@ struct X {
|
|||||||
template <class T> operator T&() const;
|
template <class T> operator T&() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(X)
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@ -57,12 +56,24 @@ int main()
|
|||||||
STATIC_ASSERT_SAME(boost::pointee<X*>::type, X);
|
STATIC_ASSERT_SAME(boost::pointee<X*>::type, X);
|
||||||
STATIC_ASSERT_SAME(boost::pointee<X const*>::type, X const);
|
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<int> >::type, int);
|
||||||
STATIC_ASSERT_SAME(boost::pointee<std::auto_ptr<X> >::type, X);
|
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<int const> >::type, int const);
|
||||||
STATIC_ASSERT_SAME(boost::pointee<std::auto_ptr<X const> >::type, X 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<int>::iterator >::type, int);
|
||||||
STATIC_ASSERT_SAME(boost::pointee<std::list<X>::iterator >::type, X);
|
STATIC_ASSERT_SAME(boost::pointee<std::list<X>::iterator >::type, X);
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
// Moved test of transform iterator into its own file. It to
|
// Moved test of transform iterator into its own file. It to
|
||||||
// to be in iterator_adaptor_test.cpp.
|
// to be in iterator_adaptor_test.cpp.
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/iterator/transform_iterator.hpp>
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
@ -102,6 +103,22 @@ int mult_2(int arg)
|
|||||||
return arg*2;
|
return arg*2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct polymorphic_mult_functor
|
||||||
|
{
|
||||||
|
//Implement result_of protocol
|
||||||
|
template <class FArgs> struct result;
|
||||||
|
template <class F, class T> struct result<const F(T )> {typedef T type;};
|
||||||
|
template <class F, class T> struct result<const F(T& )> {typedef T type;};
|
||||||
|
template <class F, class T> struct result<const F(const T&)> {typedef T type;};
|
||||||
|
template <class F, class T> struct result<F(T )> {typedef void type;};
|
||||||
|
template <class F, class T> struct result<F(T& )> {typedef void type;};
|
||||||
|
template <class F, class T> struct result<F(const T&)> {typedef void type;};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T operator()(const T& _arg) const {return _arg*2;}
|
||||||
|
template <class T>
|
||||||
|
void operator()(const T& _arg) { BOOST_ASSERT(0); }
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
@ -244,5 +261,25 @@ main()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test transform_iterator with polymorphic object function
|
||||||
|
{
|
||||||
|
int x[N], y[N];
|
||||||
|
for (int k = 0; k < N; ++k)
|
||||||
|
x[k] = k;
|
||||||
|
std::copy(x, x + N, y);
|
||||||
|
|
||||||
|
for (int k2 = 0; k2 < N; ++k2)
|
||||||
|
x[k2] = x[k2] * 2;
|
||||||
|
|
||||||
|
boost::input_iterator_test(
|
||||||
|
boost::make_transform_iterator(y, polymorphic_mult_functor()), x[0], x[1]);
|
||||||
|
|
||||||
|
boost::input_iterator_test(
|
||||||
|
boost::make_transform_iterator(&y[0], polymorphic_mult_functor()), x[0], x[1]);
|
||||||
|
|
||||||
|
boost::random_access_readable_iterator_test(
|
||||||
|
boost::make_transform_iterator(y, polymorphic_mult_functor()), N, x);
|
||||||
|
}
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,10 @@
|
|||||||
|
|
||||||
#include "static_assert_same.hpp"
|
#include "static_assert_same.hpp"
|
||||||
|
|
||||||
#include <boost/type_traits/broken_compiler_spec.hpp>
|
#include <boost/iterator/minimum_category.hpp>
|
||||||
|
|
||||||
#include <boost/iterator/detail/minimum_category.hpp>
|
|
||||||
|
|
||||||
struct X { int a; };
|
struct X { int a; };
|
||||||
|
|
||||||
BOOST_TT_BROKEN_COMPILER_SPEC(X)
|
|
||||||
|
|
||||||
struct Xiter : boost::iterator_adaptor<Xiter,X*>
|
struct Xiter : boost::iterator_adaptor<Xiter,X*>
|
||||||
{
|
{
|
||||||
@ -32,14 +29,14 @@ void operator_arrow_test()
|
|||||||
template <class T, class U, class Min>
|
template <class T, class U, class Min>
|
||||||
struct static_assert_min_cat
|
struct static_assert_min_cat
|
||||||
: static_assert_same<
|
: static_assert_same<
|
||||||
typename boost::detail::minimum_category<T,U>::type, Min
|
typename boost::iterators::minimum_category<T,U>::type, Min
|
||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
void category_test()
|
void category_test()
|
||||||
{
|
{
|
||||||
using namespace boost;
|
using namespace boost::iterators;
|
||||||
using namespace boost::detail;
|
using namespace boost::iterators::detail;
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((
|
BOOST_STATIC_ASSERT((
|
||||||
!boost::is_convertible<
|
!boost::is_convertible<
|
||||||
|
@ -1,833 +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 <functional>
|
|
||||||
#include <boost/tuple/tuple.hpp>
|
#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>
|
|
||||||
|
|
||||||
template <class It>
|
#define ZI_TUPLE boost::tuples::tuple
|
||||||
struct pure_traversal
|
#define ZI_MAKE_TUPLE boost::make_tuple
|
||||||
: boost::detail::pure_traversal_tag<
|
#define ZI_TUPLE_GET(n) boost::tuples::get<n>
|
||||||
typename boost::iterator_traversal<It>::type
|
#define ZI_USE_BOOST_TUPLE
|
||||||
>
|
|
||||||
{};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Das Main Funktion
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int main( void )
|
|
||||||
{
|
|
||||||
|
|
||||||
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"
|
||||||
|
9
test/zip_iterator_test2_fusion_deque.cpp
Normal file
9
test/zip_iterator_test2_fusion_deque.cpp
Normal 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"
|
11
test/zip_iterator_test2_fusion_list.cpp
Normal file
11
test/zip_iterator_test2_fusion_list.cpp
Normal 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"
|
11
test/zip_iterator_test2_fusion_vector.cpp
Normal file
11
test/zip_iterator_test2_fusion_vector.cpp
Normal 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"
|
21
test/zip_iterator_test2_std_tuple.cpp
Normal file
21
test/zip_iterator_test2_std_tuple.cpp
Normal 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
|
15
test/zip_iterator_test_fusion.cpp
Normal file
15
test/zip_iterator_test_fusion.cpp
Normal 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"
|
16
test/zip_iterator_test_std_pair.cpp
Normal file
16
test/zip_iterator_test_std_pair.cpp
Normal 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"
|
||||||
|
|
29
test/zip_iterator_test_std_tuple.cpp
Normal file
29
test/zip_iterator_test_std_tuple.cpp
Normal 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
|
||||||
|
|
Reference in New Issue
Block a user