Compare commits

..

251 Commits

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

Fixes #8010
2016-01-27 22:22:55 -06:00
c09c8ca2b2 Support lambda expressions in function_input_iterator 2015-12-28 02:45:49 +09:00
22dd100dfd Revert "Remove unused deprecated includes"
This reverts commit b2b9ab1568.
2015-10-15 23:55:35 -04:00
2f72016049 Revert "Fix test compilation"
This reverts commit 443dfb9901.
2015-10-15 23:53:37 -04:00
5b26a8b3fc Merge branch 'develop' 2015-10-14 23:59:55 -04:00
711a0232f8 Merge pull request #19 from MarcelRaad/patch-1
Fix test compilation
2015-09-22 18:03:05 -07:00
443dfb9901 Fix test compilation
boost/iterator.hpp was implicitly dragged in via boost/operators.hpp, from which it was removed in cb6500161b. It's not needed anyway, all it does is map boost::iterator to std::iterator.
2015-09-22 00:33:50 +02:00
c734f3bfa3 Merge pull request #18 from MarcelRaad/remove-deprecated-includes
Remove deprecated includes
2015-09-14 12:06:20 -04:00
b2b9ab1568 Remove unused deprecated includes
A comment in boost/iterator.hpp and boost/detail/iterator.hpp mentions that
the files are obsolete and will be deprecated. All they do is pull some types
from namespace std into namespace boost.
2015-09-14 14:28:38 +02:00
8b23342969 Merge pull request #17 from boostorg/revert-16-remove-deprecated-includes
Revert "Remove unused deprecated includes"
2015-09-14 08:17:35 -04:00
922296f8c8 Revert "Remove unused deprecated includes" 2015-09-14 08:16:43 -04:00
c9a91a1fba Merge pull request #16 from MarcelRaad/remove-deprecated-includes
Remove unused deprecated includes
2015-09-14 08:08:53 -04:00
80e6f4a3bf Remove unused deprecated includes
A comment in boost/iterator.hpp and boost/detail/iterator.hpp mentions that
the files are obsolete and will be deprecated. All they do is pull some types
from namespace std into namespace boost.
2015-09-14 10:57:16 +02:00
398bbe63bb Updated quickbook docs just fix problems exposed by upgrading to quickbook 1.6 2015-08-24 12:49:59 -04:00
87d82527b1 Updated zip iterator abstract adds information about the iterator 'tuple'. 2015-08-24 07:18:03 -04:00
b9448b5fae Updated with an explanation of the new 'tuple' type for a zip_iterator based on Boost fusion sequences. 2015-08-24 00:24:09 -04:00
76519ea4a7 Merge branch 'Flast-pr/zip_iterator/fusionize' into develop 2015-08-23 23:56:13 -04:00
878812c42f More tests with fusion sequence as tuple 2015-08-23 23:46:44 -04:00
2283f084d9 Merge pull request #2 from Flast/pr/zip_iterator/fusionize
Fusion based zip_iterator, close #7526
2015-08-23 23:37:38 -04:00
a0533d97f5 Merge branch 'pr/zip_iterator/fusionize' of https://github.com/Flast/iterator into Flast-pr/zip_iterator/fusionize 2015-08-21 22:09:37 -04:00
ece225bbda Merge branch 'develop' 2015-07-18 22:08:52 -04:00
b62dc6ba9d Remove unneeded header file for undefines. 2015-05-22 00:54:44 -04:00
20dc7b1abe Merge pull request #14 from eldiener/develop
Changed needed for type_traits version2 to remove icexxx.hpp dependencies.
2015-05-21 23:28:00 -04:00
0dbbb61bec Put back MPL auxiliary lambda support. 2015-05-21 23:15:31 -04:00
2de2111db2 Remove dependency on deprecated type_traits headers. 2015-05-21 23:14:42 -04:00
db04fafe21 Merge pull request #12 from Lastique/patch-1
Remove unused pure_traversal_tag import into boost::iterators::detail
2015-05-21 16:52:07 -04:00
4e0fc90b60 Merge pull request #11 from jzmaddock/patch-1
Update is_lvalue_iterator.hpp
2015-05-21 16:35:38 -04:00
53cbba6c09 Remove unused name import
As Boost.Range has been updated, there is no need to import pure_traversal_tag into boost::iterators::detail.
2015-01-26 00:02:36 +03:00
8be623d733 Update is_lvalue_iterator.hpp 2015-01-22 08:48:25 +00:00
d12d60fa12 Update is_lvalue_iterator.hpp
In the current type_traits rewrite, type_traits headers no long implicitly include mpl ones, so mpl/bool.hpp has to be explicitly included now.
2015-01-21 16:54:54 +00:00
ec7d398578 Merge pull request #10 from Flast/pr/ref-to-ref/dr106
Avoid 'reference to reference' error with strict C++03 compiler.

While I can't reproduce the error you describe, the patch looks good and it tested okay with Clang 6.0 on Mac and gcc-4.9.1 on Linux.  Thanks for the patch.
2014-11-02 15:59:02 -07:00
3d3560c12d Avoid 'reference to reference' error in C++03.
Some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
  'reference-to-reference' in the template and typedef which described
  in CWG DR106 [1].

  In such situations, iterator_facade rejects reference type as a value
  type and some special iterators will become ill-formed:
  the test libs/range/test/join.hpp might be descriptive.

  [1] http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106

Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-09-29 14:58:40 +09:00
46f9e1753f Merge pull request #9 from boostorg/develop
Merge develop into master

Tested with gcc-4.2.1 on Darwin.
2014-09-06 11:18:28 -06:00
2511f21d62 Merge upstream branch 'develop' into pr/zip_iterator/fusionize 2014-08-25 00:36:36 +09:00
adee905c51 Merge pull request #8 from Lastique/add_docs
Add docs for iterator category and traversal manipulation tools.

Thanks Andrey.
2014-08-23 16:14:52 -06:00
82779f78ec Added docs for iterator category and traversal manipulation tools. 2014-08-24 01:55:25 +04:00
a569c97969 Merge pull request #6 from Lastique/publish-details
Publish some of the implementation details

Tested with clang-5.1 on darwin.
2014-08-23 14:08:11 -06:00
aad821d28d Merge pull request #7 from danieljames/metadata
Create metadata file.
2014-08-23 13:53:06 -06:00
23934d7c0d Add metadata file. 2014-08-18 15:00:20 +01:00
1073b7f7bc Adjustments for compatibility with commit 48dfb68045. 2014-07-30 23:00:35 +04:00
f158dba6ad Moved minimum_category to the public namespace. Added tests. 2014-07-19 21:39:49 +04:00
8fe632d6b1 Copied minimum_category.hpp to public headers. 2014-07-19 21:03:11 +04:00
810b58cfb0 Moved pure_traversal_tag to public namespace.
Also added an import into the boost::detail namespace for backward compatibility with Boost.Range. Added a pure_iterator_traversal metafunction that automatically converts iterator category as well.
2014-07-19 20:57:42 +04:00
156c13a494 Merge upstream branch 'develop' into pr/zip_iterator/fusionize
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-07-12 15:57:03 +09:00
785680d929 Merge pull request #5 from Lastique/adl-protect
Moved most components of the library to iterators:: namespace.

Thanks Andrey.
2014-07-10 11:33:50 -06:00
269de2691a Added a workaround for boost/token_iteratpr.hpp which uses an implementation detail of this library. 2014-07-07 22:22:28 +04:00
11f7d1bc18 Merge upstream branch 'develop' into pr/zip_iterator/fusionize
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-07-03 21:52:26 +09:00
4a403cd3eb Trim spaces. 2014-07-03 00:36:44 +04:00
dc96d371fa Moved most components of the library to iterators:: namespace.
This change excludes boost:: and boost::detail:: namespaces from ADL for unqualified function calls (e.g. algorithms). This reduces the possibility of name clashes with other libraries and user's code. One of the effects should be fixing test failures on gcc 4.2 and 4.4 due to clashed with Boost.TypeTraits.

Also some of the functions marked with inline keyword.
2014-07-03 00:22:45 +04:00
e000b676cc Merge pull request #4 from Lastique/sfinae-based-operators
Make iterator operators conditionally defined depending on its category.

Looks okay and fixes several known problems, thanks Andrey.
2014-06-30 16:49:53 -06:00
045a05f81f Run generator_iterator_test.cpp
I accidentally removed it in 8e5b8025d8.
2014-06-30 10:59:03 +01:00
25139e1311 Remove operator_brackets_dispatch.hpp
I should have removed it in 8e5b8025d8.
2014-06-30 10:53:35 +01:00
aad767ed3f Merge upstream branch 'develop' into pr/zip_iterator/fusionize 2014-06-30 11:13:38 +09:00
7fa65a4278 Made iterator operators conditionally defined depending on its category.
This makes iterators defined using iterator_facade more friendly to type inspection and fixes its use with next()/prior() since commit 651a869d4f.
The arithmetic, indexing and relational operators are only defined if the iterator category or traversal permits that. Note that the implementation requires partial template specialization support now.
2014-06-30 00:05:38 +04:00
fd94cc7d78 Removed executable flags from docs, tests and examples. 2014-06-29 15:49:05 +04:00
36988fcf98 Removed executable flags from headers. 2014-06-29 15:42:47 +04:00
4283d20261 Merge remote-tracking branch 'origin/develop' 2014-06-26 11:53:43 +01:00
91f782ec52 Merge branch 'feature/remove-old-compiler-support' into develop 2014-06-26 11:46:39 +01:00
9841d87212 Add tests for fusion based zip_iterator
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-14 15:59:31 +09:00
782313db8c Remove unnecessary specialization
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-14 15:59:31 +09:00
c040d4c38b make_zip_iterator should be inlined
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-14 15:59:31 +09:00
1ddaca8297 zip_iterator specialization for std::pair
Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-14 15:59:31 +09:00
acf9b4d4cf Reimplement zip_iterator based on Boost.Fusion
By default, backward compatibility for Boost.Tuple is presented.

Signed-off-by: Kohei Takahashi <flast@flast.jp>
2014-06-12 01:05:36 +09:00
e88b3f475c Remove the the broken compiler notes.
Now that the workarounds have been removed, they no longer apply.
2014-06-06 23:03:04 +01:00
01cffbed98 Rebuild iterator_traits.html using latest docutils. 2014-06-06 23:03:04 +01:00
187bc896f6 BOOST_ITERATOR_CATEGORY shouldn't be removed.
Since it was documented, it should be kept for backwards compatiblity.
2014-06-06 23:03:03 +01:00
6883d083d2 Iterator: Remove obsolete MSVC version checks.
[SVN r86082]

Conflicts:
	include/boost/iterator/iterator_facade.hpp
2014-06-06 23:03:03 +01:00
0345db959b Remove use of BOOST_ITERATOR_CATEGORY
[SVN r86056]
2014-06-06 23:03:03 +01:00
d814423414 Iterator: Remove obsolete GCC version check.
[SVN r86055]
2014-06-06 23:03:03 +01:00
eb288b2908 Iterator: Remove use of eti baseclass workaround.
[SVN r85940]
2014-06-06 23:03:03 +01:00
0e23f15623 Merge branch 'feature/remove-broken-compiler-spec' into develop 2014-06-06 01:06:55 +01:00
6b2a5cccc4 Remove all references to now defunct (and removed) header.
[SVN r86438]
2014-06-06 01:06:48 +01:00
a803b5b42d Remove use of obsolete BOOST_TT_BROKEN_COMPILER_SPEC
[SVN r86250]
2014-06-06 01:06:48 +01:00
d8284fa602 Merge branch 'feature/comment-fixes' into develop 2014-06-06 01:04:04 +01:00
8d96469cb4 Add link to changeset mentioned in comment. 2014-06-06 01:03:30 +01:00
09549a613e refs #6403
[SVN r80903]
2014-06-06 01:03:30 +01:00
daac0f2ab1 refs #6404
[SVN r80902]
2014-06-06 01:03:30 +01:00
8e5b8025d8 Revert changes that were merged to master.
Reverted: 2e099caceb9..21102938e8ccb

I'm going to reapply some of them soon, but it's easier to revert them
all first, as there are conflicts. Also the number of changes that were
inserted since then, mean that there would be a huge gap between related
changes.
2014-06-06 00:56:20 +01:00
c142956936 Remove boost/iterator.hpp, it has been moved to core. 2014-06-05 03:09:11 +03:00
21afa3d8ec Merge branch 'develop' 2014-06-05 02:38:34 +03:00
2d9362fe89 Move generator_iterator doc/test files, update test/Jamfile.v2. 2014-06-05 02:37:48 +03:00
8779e0e715 Merge branch 'develop' 2014-06-05 02:27:45 +03:00
3546643667 Added test for generator_iterator.hpp. 2014-06-05 02:27:26 +03:00
70ac888f75 Use a local copy of the valid HTML 4.01 icon.
[SVN r53048]
2014-06-05 02:27:25 +03:00
854d39f58a Link to people pages on the website, as they've been removed from the download.
[SVN r43209]
2014-06-05 02:27:25 +03:00
7bb83d4646 Fixed license & copyright issues and converted to HTML 4.01
[SVN r36280]
2014-06-05 02:27:24 +03:00
bb27f3ee25 Fix broken links
[SVN r30403]
2014-06-05 02:27:24 +03:00
96d2e9638c c++boost.gif -> boost.png replacement
[SVN r25573]
2014-06-05 02:27:24 +03:00
f2137c58b7 Converted to Boost Software License, Version 1.0
[SVN r24055]
2014-06-05 02:27:23 +03:00
0dfc7bd53c Removed access category tags from iterator library, made corresponding changes elsewhere.
boost/iterator and libs/iterator/test were updated from
branch "simplify"

[SVN r20905]
2014-06-05 02:27:23 +03:00
ae1d0d0dfe Move to new iterator adaptors
[SVN r19074]
2014-06-05 02:27:22 +03:00
9ddc974825 add or update See www.boost.org comments
[SVN r16708]
2014-06-05 02:27:22 +03:00
1cde579a68 Fix from Yitzhak Sapir <yitzhaks@actimize.com>
[SVN r16198]
2014-06-05 02:27:21 +03:00
73ccc2bac0 fix example (thanks to Michael Stevens)
[SVN r11979]
2014-06-05 02:27:21 +03:00
9b13de9bfe add generator iterator adaptor
[SVN r11736]
2014-06-05 02:27:21 +03:00
35cf24d413 add boost::generator_iterator_policies and convenience classes
[SVN r11725]
2014-06-05 02:27:20 +03:00
a83b13f4e6 Added test for generator_iterator.hpp. 2014-06-05 02:26:20 +03:00
c6f70f8394 Use a local copy of the valid HTML 4.01 icon.
[SVN r53048]
2014-06-05 02:26:20 +03:00
0b33da51dd Link to people pages on the website, as they've been removed from the download.
[SVN r43209]
2014-06-05 02:26:19 +03:00
39c44e0da3 Fixed license & copyright issues and converted to HTML 4.01
[SVN r36280]
2014-06-05 02:26:18 +03:00
d1c93d3574 Fix broken links
[SVN r30403]
2014-06-05 02:26:17 +03:00
208400a1d0 c++boost.gif -> boost.png replacement
[SVN r25573]
2014-06-05 02:26:17 +03:00
dae3cf2a9d Converted to Boost Software License, Version 1.0
[SVN r24055]
2014-06-05 02:26:17 +03:00
0c44051189 Removed access category tags from iterator library, made corresponding changes elsewhere.
boost/iterator and libs/iterator/test were updated from
branch "simplify"

[SVN r20905]
2014-06-05 02:26:16 +03:00
4fcb23f8e0 Move to new iterator adaptors
[SVN r19074]
2014-06-05 02:26:16 +03:00
8a004c12f6 add or update See www.boost.org comments
[SVN r16708]
2014-06-05 02:26:15 +03:00
3695e48b68 Fix from Yitzhak Sapir <yitzhaks@actimize.com>
[SVN r16198]
2014-06-05 02:26:15 +03:00
ac3a206eb9 fix example (thanks to Michael Stevens)
[SVN r11979]
2014-06-05 02:26:14 +03:00
f9095485a2 add generator iterator adaptor
[SVN r11736]
2014-06-05 02:26:14 +03:00
1c4527d58e add boost::generator_iterator_policies and convenience classes
[SVN r11725]
2014-06-05 02:26:14 +03:00
455a039c33 Merge branch 'develop' 2014-06-05 01:38:33 +03:00
5d7289ad3e Removed executable attribute. 2014-06-05 01:34:13 +03:00
40fd24e5b5 Link to documentation added.
[SVN r27745]
2014-06-05 01:34:13 +03:00
290cea8289 merge new MPL version from 'mplbook' branch
[SVN r24874]
2014-06-05 01:34:12 +03:00
e6babb8bf9 Kill off outer cv-stripping of Dereferenceable
[SVN r21696]
2014-06-05 01:34:12 +03:00
84cd6e1be4 Updated pointee and indirect_reference so that pointee represents the immutability of the pointed-to type via const qualification. The pointee of a proxy-based iterator will be const qualified unless a mutable reference to the value_type can be bound to the returned proxy.
Added a test for pointee

Fixed iterator_facade so operator[] result type computation didn't
cause a problem with abstract types.

Updated iterator_facade operator[] docs for accuracy.

Allowed Borland to simply fail the indirect_iterator_member_types test
because of its lame const-dropping, instead of trying to work around
it.

[SVN r21579]
2014-06-05 01:34:12 +03:00
2325b6070a Added traits:
is_incrementable.hpp: checks whether ++x is well-formed

   pointee.hpp: value_type of iterators or smart pointers

   indirect_reference.hpp: reference type of iterators or smart pointers

indirect_iterator.hpp
indirect_iterator_member_types.cpp

   Use pointee/indirect_reference to select value/reference type.

iterator_concepts.hpp: Fixed interoperable test.  Hardly tests enough, but it's a start

minimum_category.hpp: Better error messages for vc6

indirect_iterator_test.cpp: Workarounds for compilers without SFINAE

static_assert_same.hpp: Informative error reports; added a macro.

zip_iterator_test.hpp: Added missing #include

Jamfile: made zip_iterator test pass with vc6/stlport

[SVN r21514]
2014-06-05 01:34:11 +03:00
91b2854e4a Removed executable attribute. 2014-06-05 01:33:57 +03:00
27b44876bc Link to documentation added.
[SVN r27745]
2014-06-05 01:33:56 +03:00
123bf514ac merge new MPL version from 'mplbook' branch
[SVN r24874]
2014-06-05 01:33:56 +03:00
ac7b14253f Kill off outer cv-stripping of Dereferenceable
[SVN r21696]
2014-06-05 01:33:55 +03:00
69df402f70 Updated pointee and indirect_reference so that pointee represents the immutability of the pointed-to type via const qualification. The pointee of a proxy-based iterator will be const qualified unless a mutable reference to the value_type can be bound to the returned proxy.
Added a test for pointee

Fixed iterator_facade so operator[] result type computation didn't
cause a problem with abstract types.

Updated iterator_facade operator[] docs for accuracy.

Allowed Borland to simply fail the indirect_iterator_member_types test
because of its lame const-dropping, instead of trying to work around
it.

[SVN r21579]
2014-06-05 01:33:55 +03:00
e600d3f65b Added traits:
is_incrementable.hpp: checks whether ++x is well-formed

   pointee.hpp: value_type of iterators or smart pointers

   indirect_reference.hpp: reference type of iterators or smart pointers

indirect_iterator.hpp
indirect_iterator_member_types.cpp

   Use pointee/indirect_reference to select value/reference type.

iterator_concepts.hpp: Fixed interoperable test.  Hardly tests enough, but it's a start

minimum_category.hpp: Better error messages for vc6

indirect_iterator_test.cpp: Workarounds for compilers without SFINAE

static_assert_same.hpp: Informative error reports; added a macro.

zip_iterator_test.hpp: Added missing #include

Jamfile: made zip_iterator test pass with vc6/stlport

[SVN r21514]
2014-06-05 01:33:54 +03:00
f6e5aa2462 Merge branch 'develop' 2014-06-05 01:16:50 +03:00
21102938e8 Remove all references to now defunct (and removed) header.
[SVN r86438]
2014-06-05 01:16:01 +03:00
a1c0cf8373 Remove use of obsolete BOOST_TT_BROKEN_COMPILER_SPEC
[SVN r86250]
2014-06-05 01:15:17 +03:00
220a11883c Remove remaining occurances of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
These evaded scripting.

[SVN r86249]
2014-06-05 01:14:58 +03:00
913df78ec0 Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
[SVN r86248]
2014-06-05 01:14:37 +03:00
01f9b396d8 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifdef...#else...#endif blocks.

[SVN r86246]
2014-06-05 01:14:14 +03:00
67d418a5c6 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#endif conditions.

[SVN r86244]
2014-06-05 01:13:55 +03:00
d853e444ce Iterator: Remove obsolete MSVC version checks.
[SVN r86082]
2014-06-05 01:13:31 +03:00
e6d5c24b91 Remove use of BOOST_ITERATOR_CATEGORY
[SVN r86056]
2014-06-05 01:13:14 +03:00
98db5b4f9a Iterator: Remove obsolete GCC version check.
[SVN r86055]
2014-06-05 01:13:00 +03:00
739c95411f Iterator: Remove use of eti baseclass workaround.
[SVN r85940]
2014-06-05 01:12:47 +03:00
8ce330a111 refs #6403
[SVN r80903]
2014-06-05 01:12:20 +03:00
3eef8090d6 refs #6404
[SVN r80902]
2014-06-05 01:12:07 +03:00
d291c7b43e - BREAKING CHANGE: iterator_facade::pointer now corresponds to the actual result of iterator_facade::operator-> rather than Value*. This required an adjustment to a test.
- The logic for determining the result of iterator_facade::operator[] has been factored out into a separate detail header in preparation for its potential use in iterator_range to avoid iterator_range::operator[] from returning a reference to a temporary.

[SVN r80901]
2014-06-05 01:11:49 +03:00
1471102bfc Removed development/ that was only in develop and probably a relic. 2014-06-05 01:06:32 +03:00
2e099caceb Create merge base for git. 2014-06-01 19:15:17 +01:00
3fd1c34411 Merge r86524 (Correct broken links to C++ standard papers); fixes #9212
[SVN r86673]
2013-11-13 03:22:55 +00:00
dec42098db Correct broken links to C++ standard papers. Refs #9212.
[SVN r86524]
2013-10-30 12:51:24 +00:00
d4d51389d1 Remove all references to now defunct (and removed) header.
[SVN r86438]
2013-10-26 10:13:38 +00:00
4a82a5646f Remove use of obsolete BOOST_TT_BROKEN_COMPILER_SPEC
[SVN r86250]
2013-10-11 23:23:26 +00:00
fecf28a440 Remove remaining occurances of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
These evaded scripting.

[SVN r86249]
2013-10-11 23:22:36 +00:00
bc34e54f6c Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
[SVN r86248]
2013-10-11 23:20:59 +00:00
f543f1e7b6 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifdef...#else...#endif blocks.

[SVN r86246]
2013-10-11 23:19:17 +00:00
9f661c9112 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#endif conditions.

[SVN r86244]
2013-10-11 23:15:00 +00:00
04bc178fc1 Iterator: Remove obsolete MSVC version checks.
[SVN r86082]
2013-09-30 16:04:19 +00:00
1b2fbfaaca Remove use of BOOST_ITERATOR_CATEGORY
[SVN r86056]
2013-09-30 15:54:32 +00:00
a6a8fd00d7 Iterator: Remove obsolete GCC version check.
[SVN r86055]
2013-09-30 15:54:03 +00:00
30a13b8141 Iterator: Remove use of eti baseclass workaround.
[SVN r85940]
2013-09-26 09:43:37 +00:00
db29a874f1 refs #6403
[SVN r80903]
2012-10-08 03:22:45 +00:00
8345293f94 refs #6404
[SVN r80902]
2012-10-08 02:17:55 +00:00
512298cb5c - BREAKING CHANGE: iterator_facade::pointer now corresponds to the actual result of iterator_facade::operator-> rather than Value*. This required an adjustment to a test.
- The logic for determining the result of iterator_facade::operator[] has been factored out into a separate detail header in preparation for its potential use in iterator_range to avoid iterator_range::operator[] from returning a reference to a temporary.

[SVN r80901]
2012-10-08 02:02:09 +00:00
6d0b2d4f8a Merging trunk to release; fixing typo in comments of iterator_facade.
[SVN r80818]
2012-10-02 13:30:46 +00:00
7dbd0f5a89 Fixing typos in comments of iterator_facade.
[SVN r80817]
2012-10-02 13:27:34 +00:00
c9463e941f Merging boost/iterator from trunk to release (usability improvement after latest fix to function_input_iterator).
[SVN r80813]
2012-10-02 01:14:36 +00:00
1ce1296320 Extending the usability of function_input_iterator after the changes addressing #5825: a dereference before each increment is no longer required.
[SVN r80790]
2012-09-30 18:58:56 +00:00
9025bbfc2a Merging boost/iterator and libs/iterator trunk to release.
[SVN r80568]
2012-09-18 02:50:52 +00:00
c6f3269f4a updating documentation to reflect new and more sensible behavior
[SVN r80468]
2012-09-09 15:51:22 +00:00
31c3971720 fix #5825; fix #7194
[SVN r80467]
2012-09-09 15:33:12 +00:00
2db78eec90 Replace all uses of boost/utility.hpp with more-granular includes. Solves modularization dependency nightmare.
[SVN r78502]
2012-05-18 04:44:04 +00:00
c7fc3470d0 merging from trunk; fix #5127 from M. Morin; fix for refs #5697
[SVN r78184]
2012-04-24 21:28:07 +00:00
ad90dac61d refs #5127 applying Michael Morin's patch for transform_iterator to trunk
[SVN r78121]
2012-04-22 01:27:49 +00:00
964a29979c Applied patches from #5697; refs #5697
[SVN r77723]
2012-04-02 18:19:44 +00:00
fbbdcf8c99 Merged in BGL, enable_if, and related changes from trunk: r67035, r57559, r72837, r73010, r73026, r72960, r73425, r73424, r73009, r73998, r73997, r73006, r73630, r73631, r73999, r73422, r73423, r73996, r71221
[SVN r74023]
2011-08-23 18:26:46 +00:00
5d72ae48da Iterator: Use boost::result_of to determine nested result type of function in transform_iterator. Fixes #1427.
[SVN r70715]
2011-03-29 21:31:29 +00:00
1ca1caddff Iterator: merge several changes from trunk.
- Update iterator_facade test for #1019
  (header change already merged).
- Category of each iterator is reduced to a known category before we try to
  find a minimum. Fixes #1517.
- `function_input_iterator` from Dean Michael Berris. Fixes #2893
- Fix typo in `boost/iterator.hpp`. Fixes #3434.
- Always include `add_reference` header in iterator adaptor header.

Did not merge changes for #1427.


[SVN r70709]
2011-03-29 21:17:11 +00:00
5c477dc695 Always include add_reference in iterator_adaptor.
It's only included for certain configurations but is always used. This
didn't matter in the past because it was transitively included by
is_convertible. But it isn't now on Visual C++ because its itsintrinsic
version is being used, which doesn't require add_reference.

[SVN r69855]
2011-03-11 18:28:31 +00:00
d45b57c33c Revert [68076], refs #1427.
Will try to fix this properly in 1.47.


[SVN r68524]
2011-01-28 08:40:25 +00:00
caa0e5035a Added Michel's patches for #1427
[SVN r68205]
2011-01-17 14:52:49 +00:00
5a88e6f958 Merging fixes to release; Fixes #1427
[SVN r68076]
2011-01-13 01:25:09 +00:00
36565eae63 Merging fixes to release; fixes #2294 fixes #4918 fixes #3645 refs #2823 refs #1427 refs #2893
[SVN r67792]
2011-01-08 18:38:08 +00:00
14b1075d6b Apply patch for #3645; will merge to release after tests cycle
[SVN r67738]
2011-01-06 23:42:00 +00:00
752fc7c185 Removed <boost/pending/integer_range.hpp> and a few more uses of it; fixes #4642
[SVN r67035]
2010-12-05 20:38:44 +00:00
de4ef14f9b Merge documentation fixes.
* Use `doc/src/*.css` instead of `doc/html/*.css`.
* Remove wiki and people directories.
* Some documentation fixes.
* Left out `minimal.css` changes and boostbook changes because of clashes.


[SVN r63347]
2010-06-26 12:30:09 +00:00
15f3bf9352 Update various libraries' documentation build.
Mostly to use the images and css files under doc/src instead of
doc/html, usually be deleting the settings in order to use the defaults.
Also add 'boost.root' to some builds in order to fix links which rely on
it.

[SVN r63146]
2010-06-20 18:00:48 +00:00
d469568de7 function_input_iterator fixes from Dean Michael Berris
[SVN r62710]
2010-06-10 05:59:46 +00:00
251b9f8057 Fixed #3434
[SVN r62626]
2010-06-09 01:13:28 +00:00
2786268510 Applied patches from #1427; fixes #1427
[SVN r62625]
2010-06-09 01:08:45 +00:00
6bb82230b9 Added function_input_iterator from Dean Michael Berris; fixes #2893
[SVN r62615]
2010-06-09 00:09:56 +00:00
f65f03afcc Merged r62593 from trunk
[SVN r62594]
2010-06-08 19:11:44 +00:00
c07f55ff65 Removed unneeded #include; fixes #1533
[SVN r62593]
2010-06-08 19:10:16 +00:00
ac522bc9e1 category of each component iterator is reduced to a known category before we try to find a minimum.
Closes #1517


[SVN r58012]
2009-11-28 18:53:43 +00:00
4c60e26bf8 Made sure that iterator_facade's nested `::pointer` type is always
the same as what's returned from operator->.  For input iterators,
that wasn't always the case (see operator_arrow_proxy).

Fixes #1019.


[SVN r57989]
2009-11-28 05:12:29 +00:00
d11c7a3ec4 rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
cfc04ce11e rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
76fd8e27fb Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
25d4d34ebe Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
ea26e9f109 Merge PDF build changes from Trunk.
[SVN r51417]
2009-02-23 18:39:32 +00:00
f2433c63d5 Add PDF generation options to fix external links to point to the web site.
Added a few more Boostbook based libs that were missed first time around.
Fixed PDF naming issues.

[SVN r51284]
2009-02-17 10:05:58 +00:00
264c186eac merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
55c08b706c Updating dependency information for modularized libraries.
[SVN r49628]
2008-11-07 17:05:27 +00:00
835498603d Updating CMake files to latest trunk. Added dependency information for regression tests and a few new macros for internal use.
[SVN r49627]
2008-11-07 17:02:56 +00:00
b0ec5a759b Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor
[SVN r49510]
2008-11-01 13:15:41 +00:00
2ece3ac5c2 CodeGear patch. Fixes #2344
[SVN r49321]
2008-10-13 19:27:26 +00:00
e06c4b3279 Applied patch from ticket #2344
[SVN r49227]
2008-10-09 21:49:48 +00:00
78effefadb Merging SunPro 5.9 workaround from trunk
[SVN r47467]
2008-07-16 04:52:14 +00:00
37c46f7da5 Merged revisions 43206,43208-43213 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43206 | danieljames | 2008-02-10 09:55:03 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix some broken links.
........
  r43209 | danieljames | 2008-02-10 14:56:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Link to people pages on the website, as they've been removed from the download.
........
  r43210 | danieljames | 2008-02-10 15:02:17 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Point links to the pages that used to be in 'more' to the site.
........
  r43212 | danieljames | 2008-02-10 16:10:16 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix links on the home page as well.
........
  r43213 | danieljames | 2008-02-10 16:21:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Generated documentation which is no longer generated.
........


[SVN r43214]
2008-02-10 16:39:38 +00:00
6d0f901b2e merge trunk version (changeset/42064) to release branch
[SVN r42129]
2007-12-17 18:43:36 +00:00
db0e0b7b91 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
23d53055f9 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
ff73538b5b Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
30685528c7 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
c849f35965 Doc and build fixes by Dave Abrahams.
[SVN r38154]
2007-07-06 19:47:17 +00:00
aa483f4961 Correct testing bugs:
either changing assert(...) or BOOST_ASSERT(...) to BOOST_TEST
    (in my code only)

    or adding "return boost::report_errors();" where it was clearly
    missing (and a pure bug, in anyone's code).

    or changing BOOST_TEST to BOOST_CHECK where the integer library
    was clearly using Boost.Test and not returning report_errors().


[SVN r37063]
2007-02-25 15:28:02 +00:00
93c010eb51 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
0dc017b1a8 Remove unfinished quickbook documentation from release.
[SVN r35678]
2006-10-20 19:05:37 +00:00
92c92bbbf8 Remove internal doc from release.
[SVN r35676]
2006-10-20 18:03:38 +00:00
f51591cb04 Cleans up license/copyright warnings
[SVN r35406]
2006-09-29 01:59:59 +00:00
624131ce46 merged from HEAD
[SVN r35238]
2006-09-21 00:52:02 +00:00
47da2546f9 merged from HEAD
[SVN r35211]
2006-09-19 16:50:44 +00:00
8a53abc1e8 merged from HEAD
[SVN r35152]
2006-09-18 02:38:38 +00:00
b258a435cc Stop relying on new concept check facilities that aren't in 1.34.0
[SVN r35128]
2006-09-15 16:45:19 +00:00
43e4f1a766 merged from HEAD
[SVN r35127]
2006-09-15 16:41:43 +00:00
02d22c12ae fix for http://tinyurl.com/kbwzm
[SVN r35102]
2006-09-13 22:36:10 +00:00
70ef2f0e81 fix for http://tinyurl.com/zuohe
[SVN r35101]
2006-09-13 22:24:14 +00:00
b7283c93c6 merged from trunk
[SVN r35075]
2006-09-12 22:34:33 +00:00
5184d64b80 Add missing license/copyright
[SVN r35070]
2006-09-11 22:27:29 +00:00
f482354ffd merged from trunk
[SVN r33820]
2006-04-25 20:35:01 +00:00
7a2b9d66a9 Borland workaround updated
[SVN r33719]
2006-04-17 14:23:24 +00:00
d79112ee5a merged from trunk
[SVN r33713]
2006-04-16 18:03:52 +00:00
4a5e8f175a This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
98 changed files with 3988 additions and 2393 deletions

40
.travis.yml Normal file
View File

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

View File

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

View File

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

View File

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

View 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&#64;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&amp;</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 &lt;class Function, class State&gt;
class function_input_iterator;
template &lt;class Function, class State&gt;
typename function_input_iterator&lt;Function, State&gt;
make_function_input_iterator(Function &amp; 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&lt;int&gt;(cout, &quot; &quot;)
);
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&lt;int&gt;(count, &quot; &quot;)
);
</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>

View 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
View 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 &lt;class Generator&gt;
class generator_iterator_policies;
template &lt;class Generator&gt;
class generator_iterator_generator;
template &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; 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 &lt;class Generator&gt;
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 &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; 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 &lt;iostream&gt;
#include &lt;boost/generator_iterator.hpp&gt;
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&lt;my_generator&gt;::type it = boost::make_generator_iterator(gen);
for(int i = 0; i &lt; 10; ++i, ++it)
std::cout &lt;&lt; *it &lt;&lt; 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 &copy; 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>

View File

@ -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 &quot;lazy sequence&quot;</li> Implements a &quot;lazy sequence&quot;</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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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">&lt;boost/iterator/iterator_traits.hpp&gt;</span></tt> provides <tr class="field"><th class="field-name">abstract:</th><td class="field-body">Header <tt class="docutils literal">&lt;boost/iterator/iterator_traits.hpp&gt;</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 &quot;multi-valued&quot; traits template can be difficult to use in a such a &quot;multi-valued&quot; traits template can be difficult to use in a
metaprogramming context. <tt class="docutils literal"><span class="pre">&lt;boost/iterator/iterator_traits.hpp&gt;</span></tt> metaprogramming context. <tt class="docutils literal">&lt;boost/iterator/iterator_traits.hpp&gt;</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">&lt;boost/iterator/iterator_traits.hpp&gt;</span></tt>:</p> <p>Header <tt class="docutils literal">&lt;boost/iterator/iterator_traits.hpp&gt;</tt>:</p>
<pre class="literal-block"> <pre class="literal-block">
template &lt;class Iterator&gt; template &lt;class Iterator&gt;
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" />

View File

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

View File

@ -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&amp;</span></tt> (or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">T&amp;</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&amp;</span></tt> (or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">T&amp;</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&lt;bool&gt;::iterator</span></tt> is almost a categorized. For example, <tt class="docutils literal"><span class="pre">vector&lt;bool&gt;::iterator</span></tt> is almost a
random access iterator, but the return type is not <tt class="docutils literal"><span class="pre">bool&amp;</span></tt> (see random access iterator, but the return type is not <tt class="docutils literal"><span class="pre">bool&amp;</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&lt;bool&gt;</span></tt> only meet the N1185). Therefore, the iterators of <tt class="docutils literal"><span class="pre">vector&lt;bool&gt;</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&lt;X&gt;::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&lt;X&gt;::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&lt;X&gt;::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&lt;X&gt;::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

View File

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

View File

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

View File

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

View File

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

View File

@ -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`:
@ -487,7 +489,8 @@ w.m)` for some temporary object `w` of type `value_type`.
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs); iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*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]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -52,21 +52,4 @@ Header `<boost/iterator/iterator_traits.hpp>`:
type; type;
}; };
[h2 Broken Compiler Notes] [endsect]
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]

View File

@ -85,7 +85,7 @@ The source code for this example can be found
If `Reference` is `use_default` then the `reference` member of 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]

View File

@ -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]
@ -221,4 +321,4 @@ Iterator Traversal Concepts
[endsect] [endsect]
[endsect] [endsect]

View File

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

View File

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

View File

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

View File

@ -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&lt;UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>. <tt class="docutils literal"><span class="pre">result_of&lt;const UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::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&lt;remove_reference&lt;reference&gt;</span> <span class="pre">&gt;::type</span></tt>. Otherwise, <tt class="docutils literal"><span class="pre">remove_cv&lt;remove_reference&lt;reference&gt;</span> <span class="pre">&gt;::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&lt;UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.</p> <tt class="docutils literal"><span class="pre">result_of&lt;const UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::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">

View File

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

View File

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

View File

@ -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 {
@ -33,13 +34,13 @@ namespace boost {
struct output_proxy { struct output_proxy {
output_proxy(UnaryFunction& f) : m_f(f) { } output_proxy(UnaryFunction& f) : m_f(f) { }
template <class T> output_proxy& operator=(const T& value) { template <class T> output_proxy& operator=(const T& value) {
m_f(value); m_f(value);
return *this; return *this;
} }
UnaryFunction& m_f; UnaryFunction& m_f;
}; };
output_proxy operator*() { return output_proxy(m_f); } output_proxy operator*() { return output_proxy(m_f); }
self& operator++() { return *this; } self& operator++() { return *this; }
self& operator++(int) { return *this; } self& operator++(int) { return *this; }
private: private:
UnaryFunction m_f; UnaryFunction m_f;
@ -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

View 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

View 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

View File

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

View File

@ -0,0 +1,84 @@
// Copyright (C) 2017 Michel Morin.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ITERATOR_ADVANCE_HPP
#define BOOST_ITERATOR_ADVANCE_HPP
#include <boost/config.hpp>
#include <boost/iterator/iterator_categories.hpp>
namespace boost {
namespace iterators {
namespace detail {
template <typename InputIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
InputIterator& it
, Distance n
, incrementable_traversal_tag
)
{
while (n > 0) {
++it;
--n;
}
}
template <typename BidirectionalIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
BidirectionalIterator& it
, Distance n
, bidirectional_traversal_tag
)
{
if (n >= 0) {
while (n > 0) {
++it;
--n;
}
}
else {
while (n < 0) {
--it;
++n;
}
}
}
template <typename RandomAccessIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
RandomAccessIterator& it
, Distance n
, random_access_traversal_tag
)
{
it += n;
}
}
namespace advance_adl_barrier {
template <typename InputIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance(InputIterator& it, Distance n)
{
detail::advance_impl(
it, n, typename iterator_traversal<InputIterator>::type()
);
}
}
using namespace advance_adl_barrier;
} // namespace iterators
using iterators::advance;
} // namespace boost
#endif

View File

@ -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
@ -30,13 +31,13 @@ namespace detail
{ {
// For a while, this wasn't true, but we rely on it below. This is a regression assert. // For a while, this wasn't true, but we rely on it below. This is a regression assert.
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value); BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS # ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized); BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
# else # else
# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
BOOST_STATIC_CONSTANT( BOOST_STATIC_CONSTANT(
bool, value = ( bool, value = (
@ -46,20 +47,20 @@ namespace detail
# else # else
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value); BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
# endif # endif
# endif # endif
}; };
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)
template <> template <>
struct is_numeric< ::boost::long_long_type> struct is_numeric< ::boost::long_long_type>
: mpl::true_ {}; : mpl::true_ {};
template <> template <>
struct is_numeric< ::boost::ulong_long_type> struct is_numeric< ::boost::ulong_long_type>
: mpl::true_ {}; : mpl::true_ {};
@ -69,7 +70,7 @@ namespace detail
template <> template <>
struct is_numeric<wchar_t> struct is_numeric<wchar_t>
: mpl::true_ {}; : mpl::true_ {};
template <class T> template <class T>
struct numeric_difference struct numeric_difference
{ {
@ -77,7 +78,7 @@ namespace detail
}; };
BOOST_STATIC_ASSERT(is_numeric<int>::value); BOOST_STATIC_ASSERT(is_numeric<int>::value);
template <class Incrementable, class CategoryOrTraversal, class Difference> template <class Incrementable, class CategoryOrTraversal, class Difference>
struct counting_iterator_base struct counting_iterator_base
{ {
@ -89,7 +90,7 @@ namespace detail
, iterator_traversal<Incrementable> , iterator_traversal<Incrementable>
> >
>::type traversal; >::type traversal;
typedef typename detail::ia_dflt_help< typedef typename detail::ia_dflt_help<
Difference Difference
, mpl::eval_if< , mpl::eval_if<
@ -98,7 +99,7 @@ namespace detail
, iterator_difference<Incrementable> , iterator_difference<Incrementable>
> >
>::type difference; >::type difference;
typedef iterator_adaptor< typedef iterator_adaptor<
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
, Incrementable // Base , Incrementable // Base
@ -106,7 +107,7 @@ namespace detail
# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY # ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
const // MSVC won't strip this. Instead we enable Thomas' const // MSVC won't strip this. Instead we enable Thomas'
// criterion (see boost/iterator/detail/facade_iterator_category.hpp) // criterion (see boost/iterator/detail/facade_iterator_category.hpp)
# endif # endif
, traversal , traversal
, Incrementable const& // reference , Incrementable const& // reference
, difference , difference
@ -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);
} }
}; };
} }
@ -154,14 +155,14 @@ class counting_iterator
typedef typename detail::counting_iterator_base< typedef typename detail::counting_iterator_base<
Incrementable, CategoryOrTraversal, Difference Incrementable, CategoryOrTraversal, Difference
>::type super_t; >::type super_t;
friend class iterator_core_access; friend class iterator_core_access;
public: public:
typedef typename super_t::difference_type difference_type; typedef typename super_t::difference_type difference_type;
counting_iterator() { } counting_iterator() { }
counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {} counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
counting_iterator(Incrementable x) counting_iterator(Incrementable x)
@ -177,10 +178,10 @@ class counting_iterator
) )
: super_t(t.base()) : super_t(t.base())
{} {}
# endif # endif
private: private:
typename super_t::reference dereference() const typename super_t::reference dereference() const
{ {
return this->base_reference(); return this->base_reference();
@ -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

View File

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

View File

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

View File

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

View File

@ -35,7 +35,7 @@ namespace boost
typedef T type; typedef T type;
}; };
}; };
// //
// For compilers that don't support "Substitution Failure Is Not An Error" // For compilers that don't support "Substitution Failure Is Not An Error"
// enable_if falls back to always enabled. See comments // enable_if falls back to always enabled. See comments
@ -70,11 +70,8 @@ namespace boost
: enabled<(Cond::value)>::template base<Return> : enabled<(Cond::value)>::template base<Return>
# else # else
: mpl::identity<Return> : mpl::identity<Return>
# endif # endif
{ {
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
typedef Return type;
# endif
}; };
} // namespace iterators } // namespace iterators

View File

@ -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
@ -63,9 +66,9 @@ struct iterator_writability_disabled
, boost::detail::indirect_traits::is_reference_to_const<Reference> , boost::detail::indirect_traits::is_reference_to_const<Reference>
, is_const<ValueParam> , is_const<ValueParam>
> >
# else # else
: is_const<ValueParam> : is_const<ValueParam>
# endif # endif
{}; {};
@ -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<
@ -102,7 +99,7 @@ struct iterator_facade_default_category
, typename mpl::eval_if< , typename mpl::eval_if<
mpl::and_< mpl::and_<
is_convertible<Traversal, single_pass_traversal_tag> is_convertible<Traversal, single_pass_traversal_tag>
// check for readability // check for readability
, is_convertible<Reference, ValueParam> , is_convertible<Reference, ValueParam>
> >
@ -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.
@ -153,8 +149,7 @@ struct iterator_category_with_traversal
BOOST_MPL_ASSERT_NOT((is_iterator_traversal<Category>)); BOOST_MPL_ASSERT_NOT((is_iterator_traversal<Category>));
# 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,14 +157,12 @@ 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
>::type category; >::type category;
typedef typename mpl::if_< typedef typename mpl::if_<
is_same< is_same<
Traversal Traversal
@ -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>

View File

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

View File

@ -0,0 +1,65 @@
// Copyright (C) 2017 Michel Morin.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ITERATOR_DISTANCE_HPP
#define BOOST_ITERATOR_DISTANCE_HPP
#include <boost/config.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_traits.hpp>
namespace boost {
namespace iterators {
namespace detail {
template <typename SinglePassIterator>
inline BOOST_CXX14_CONSTEXPR typename iterator_difference<SinglePassIterator>::type
distance_impl(
SinglePassIterator first
, SinglePassIterator last
, single_pass_traversal_tag
)
{
typename iterator_difference<SinglePassIterator>::type n = 0;
while (first != last) {
++first;
++n;
}
return n;
}
template <typename RandomAccessIterator>
inline BOOST_CXX14_CONSTEXPR typename iterator_difference<RandomAccessIterator>::type
distance_impl(
RandomAccessIterator first
, RandomAccessIterator last
, random_access_traversal_tag
)
{
return last - first;
}
}
namespace distance_adl_barrier {
template <typename SinglePassIterator>
inline BOOST_CXX14_CONSTEXPR typename iterator_difference<SinglePassIterator>::type
distance(SinglePassIterator first, SinglePassIterator last)
{
return detail::distance_impl(
first, last, typename iterator_traversal<SinglePassIterator>::type()
);
}
}
using namespace distance_adl_barrier;
} // namespace iterators
using iterators::distance;
} // namespace boost
#endif

View File

@ -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;
@ -39,7 +40,7 @@ namespace boost
> type; > type;
}; };
} }
template <class Predicate, class Iterator> template <class Predicate, class Iterator>
class filter_iterator class filter_iterator
: public detail::filter_iterator_base<Predicate, Iterator>::type : public detail::filter_iterator_base<Predicate, Iterator>::type
@ -68,7 +69,7 @@ namespace boost
// Don't allow use of this constructor if Predicate is a // Don't allow use of this constructor if Predicate is a
// function pointer type, since it will be 0. // function pointer type, since it will be 0.
BOOST_STATIC_ASSERT(is_class<Predicate>::value); BOOST_STATIC_ASSERT(is_class<Predicate>::value);
#endif #endif
satisfy_predicate(); satisfy_predicate();
} }
@ -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

View 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

View File

@ -30,12 +30,13 @@
# include <boost/scoped_ptr.hpp> # include <boost/scoped_ptr.hpp>
# include <boost/mpl/bool.hpp> # include <boost/mpl/bool.hpp>
# include <memory> # include <memory>
#endif #endif
#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,8 +45,8 @@ 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>
, Iter , Iter
@ -69,7 +70,7 @@ namespace boost
struct indirect_base<int, int, int, int, int> {}; struct indirect_base<int, int, int, int, int> {};
} // namespace detail } // namespace detail
template < template <
class Iterator class Iterator
, class Value = use_default , class Value = use_default
@ -107,14 +108,14 @@ namespace boost
: super_t(y.base()) : super_t(y.base())
{} {}
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();
# endif # endif
} }
}; };
@ -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>

View File

@ -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
@ -27,7 +27,7 @@ namespace boost
// standards requirements on constant/mutable container // standards requirements on constant/mutable container
// iterators (23.1 [lib.container.requirements]). // iterators (23.1 [lib.container.requirements]).
// //
// For compilers that don't support is_convertible // For compilers that don't support is_convertible
// is_interoperable gives false positives. See comments // is_interoperable gives false positives. See comments
// on operator implementation for consequences. // on operator implementation for consequences.
// //
@ -40,9 +40,13 @@ namespace boost
is_convertible< A, B > is_convertible< A, B >
, is_convertible< B, A > > , is_convertible< B, A > >
# endif # endif
{ {
}; };
} // namespace iterators
using iterators::is_interoperable;
} // namespace boost } // namespace boost
# include <boost/iterator/detail/config_undef.hpp> # include <boost/iterator/detail/config_undef.hpp>

View File

@ -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
@ -26,20 +31,20 @@ namespace detail
// to the expression's result if <expression> is an lvalue, or // to the expression's result if <expression> is an lvalue, or
// not_an_lvalue() otherwise. // not_an_lvalue() otherwise.
struct not_an_lvalue {}; struct not_an_lvalue {};
template <class T> template <class T>
T& lvalue_preserver(T&, int); T& lvalue_preserver(T&, int);
template <class U> template <class U>
not_an_lvalue lvalue_preserver(U const&, ...); not_an_lvalue lvalue_preserver(U const&, ...);
# define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0) # define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0)
#else #else
# define BOOST_LVALUE_PRESERVER(expr) expr # define BOOST_LVALUE_PRESERVER(expr) expr
#endif #endif
// Guts of is_lvalue_iterator. Value is the iterator's value_type // Guts of is_lvalue_iterator. Value is the iterator's value_type
// and the result is computed in the nested rebind template. // and the result is computed in the nested rebind template.
@ -50,17 +55,17 @@ 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);
static char (& tester(any_conversion_eater, ...) )[2]; static char (& tester(any_conversion_eater, ...) )[2];
template <class It> template <class It>
struct rebind struct rebind
{ {
static It& x; static It& x;
BOOST_STATIC_CONSTANT( BOOST_STATIC_CONSTANT(
bool bool
, value = ( , value = (
@ -75,7 +80,7 @@ namespace detail
}; };
#undef BOOST_LVALUE_PRESERVER #undef BOOST_LVALUE_PRESERVER
// //
// void specializations to handle std input and output iterators // void specializations to handle std input and output iterators
// //
@ -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( };
is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
template< typename T > struct is_non_const_lvalue_iterator
: 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

View File

@ -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,14 +28,14 @@ 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>
struct rebind struct rebind
{ {
static It& x; static It& x;
BOOST_STATIC_CONSTANT( BOOST_STATIC_CONSTANT(
bool bool
, value = ( , value = (
@ -44,7 +48,7 @@ namespace detail
}; };
#undef BOOST_READABLE_PRESERVER #undef BOOST_READABLE_PRESERVER
// //
// void specializations to handle std input and output iterators // void specializations to handle std input and output iterators
// //
@ -94,11 +98,17 @@ 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
#endif #endif

View File

@ -24,36 +24,40 @@
#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 #endif
# include <boost/type_traits/add_reference.hpp>
#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
// the incompleteness of use_default causes massive problems for
// is_convertible (naturally). This workaround is fortunately not using iterators::use_default;
// needed for vc6/vc7.
template<class To> // the incompleteness of use_default causes massive problems for
struct is_convertible<use_default,To> // is_convertible (naturally). This workaround is fortunately not
: mpl::false_ {}; // needed for vc6/vc7.
# endif template<class To>
struct is_convertible<use_default,To>
: mpl::false_ {};
namespace iterators {
namespace detail namespace detail
{ {
// //
// Result type used in enable_if_convertible meta function. // Result type used in enable_if_convertible meta function.
// This can be an incomplete type, as only pointers to // This can be an incomplete type, as only pointers to
// enable_if_convertible< ... >::type are used. // enable_if_convertible< ... >::type are used.
// We could have used void for this, but conversion to // We could have used void for this, but conversion to
// void* is just to easy. // void* is just to easy.
@ -74,7 +78,7 @@ namespace boost
// public iterator_adaptor< adapted_iterator<Iterator>, Iterator > // public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
// { // {
// public: // public:
// //
// ... // ...
// //
// template <class OtherIterator> // template <class OtherIterator>
@ -93,38 +97,23 @@ namespace boost
// and not at the actual instantiation. // and not at the actual instantiation.
// //
// enable_if_interoperable can be safely used in user code. It falls back to // enable_if_interoperable can be safely used in user code. It falls back to
// always enabled for compilers that don't support enable_if or is_convertible. // always enabled for compilers that don't support enable_if or is_convertible.
// There is no need for compiler specific workarounds in user code. // There is no need for compiler specific workarounds in user code.
// //
// The operators implementation relies on boost::is_convertible not returning // The operators implementation relies on boost::is_convertible not returning
// 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.
template<typename From, typename To> template<typename From, typename To>
@ -134,22 +123,22 @@ 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
> >
{}; {};
# else # else
template<typename From, typename To> template<typename From, typename To>
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
> >
{}; {};
# endif # endif
// //
// Default template argument handling for iterator_adaptor // Default template argument handling for iterator_adaptor
// //
@ -181,9 +170,9 @@ namespace boost
{ {
typedef iterator_facade< typedef iterator_facade<
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,13 +200,13 @@ 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
> >
type; type;
}; };
// workaround for aC++ CR JAGaf33512 // workaround for aC++ CR JAGaf33512
template <class Tr1, class Tr2> template <class Tr1, class Tr2>
inline void iterator_adaptor_assert_traversal () inline void iterator_adaptor_assert_traversal ()
@ -225,7 +214,7 @@ namespace boost
BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value)); BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
} }
} }
// //
// Iterator Adaptor // Iterator Adaptor
// //
@ -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:
@ -286,7 +275,7 @@ namespace boost
protected: protected:
// for convenience in derived classes // for convenience in derived classes
typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_; typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
// //
// lvalue access to the Base object for Derived // lvalue access to the Base object for Derived
// //
@ -302,13 +291,13 @@ namespace boost
// to prevent temptation for Derived classes to use it, which // to prevent temptation for Derived classes to use it, which
// will often result in an error. Derived classes should use // will often result in an error. Derived classes should use
// base_reference(), above, to get direct access to m_iterator. // base_reference(), above, to get direct access to m_iterator.
// //
typename super_t::reference dereference() const typename super_t::reference dereference() const
{ return *m_iterator; } { return *m_iterator; }
template < template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D class OtherDerived, class OtherIterator, class V, class C, class R, class D
> >
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
{ {
// Maybe readd with same_distance // Maybe readd with same_distance
@ -323,17 +312,17 @@ 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)
{ {
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag) BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
m_iterator += n; m_iterator += n;
} }
void increment() { ++m_iterator; } void increment() { ++m_iterator; }
void decrement() void decrement()
{ {
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag) BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
--m_iterator; --m_iterator;
@ -341,7 +330,7 @@ namespace boost
template < template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D class OtherDerived, class OtherIterator, class V, class C, class R, class D
> >
typename super_t::difference_type distance_to( typename super_t::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
{ {
@ -354,11 +343,16 @@ namespace boost
} }
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL # undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
private: // data members private: // data members
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>

View File

@ -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
@ -51,19 +51,19 @@ namespace iterator_archetypes
// Not quite tags, since dispatching wouldn't work. // Not quite tags, since dispatching wouldn't work.
typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t; typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t; typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
typedef mpl::int_< typedef mpl::int_<
(readable_iterator_bit|writable_iterator_bit) (readable_iterator_bit|writable_iterator_bit)
>::type readable_writable_iterator_t; >::type readable_writable_iterator_t;
typedef mpl::int_< typedef mpl::int_<
(readable_iterator_bit|lvalue_iterator_bit) (readable_iterator_bit|lvalue_iterator_bit)
>::type readable_lvalue_iterator_t; >::type readable_lvalue_iterator_t;
typedef mpl::int_< typedef mpl::int_<
(lvalue_iterator_bit|writable_iterator_bit) (lvalue_iterator_bit|writable_iterator_bit)
>::type writable_lvalue_iterator_t; >::type writable_lvalue_iterator_t;
typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t; typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t; typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
@ -119,29 +119,27 @@ 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< archetypes::has_access<
iterator_archetypes::has_access< AccessCategory
AccessCategory , archetypes::writable_iterator_t
, iterator_archetypes::writable_iterator_t
>
, mpl::identity<writable_operator_brackets<Value> >
, mpl::if_<
iterator_archetypes::has_access<
AccessCategory
, iterator_archetypes::readable_iterator_t
>
, readable_operator_brackets<Value>
, no_operator_brackets
>
> >
, mpl::identity<no_operator_brackets> , mpl::identity<writable_operator_brackets<Value> >
>::type , mpl::if_<
archetypes::has_access<
AccessCategory
, archetypes::readable_iterator_t
>
, readable_operator_brackets<Value>
, no_operator_brackets
>
>
, mpl::identity<no_operator_brackets>
>::type >::type
{}; {};
template <class TraversalCategory> template <class TraversalCategory>
struct traversal_archetype_impl struct traversal_archetype_impl
{ {
@ -154,18 +152,16 @@ 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>
base; base;
traversal_archetype_() {} traversal_archetype_() {}
traversal_archetype_(ctor_arg arg) traversal_archetype_(ctor_arg arg)
: base(arg) : base(arg)
{} {}
}; };
@ -196,7 +192,7 @@ namespace detail
explicit archetype(ctor_arg arg) explicit archetype(ctor_arg arg)
: traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg) : traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
{} {}
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
}; };
}; };
@ -204,13 +200,7 @@ namespace detail
template <class Derived, class Value> template <class Derived, class Value>
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>
{ {
@ -218,7 +208,7 @@ namespace detail
struct archetype struct archetype
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag> : public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
{ {
archetype() archetype()
: traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg()) : traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
{} {}
}; };
@ -241,7 +231,7 @@ namespace detail
{ {
template<class Derived, class Value> template<class Derived, class Value>
struct archetype struct archetype
: public traversal_archetype_<Derived, Value, bidirectional_traversal_tag> : public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
{ {
Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); } Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); } Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
@ -300,7 +290,7 @@ namespace detail
template <class> struct undefined; template <class> struct undefined;
template <class AccessCategory> template <class AccessCategory>
struct iterator_access_archetype_impl struct iterator_access_archetype_impl
{ {
@ -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;
@ -386,28 +372,26 @@ struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_itera
Value* operator->() const { return 0; } Value* operator->() const { return 0; }
}; };
}; };
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
}; };
}; };
template <class Value, class AccessCategory, class TraversalCategory> template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype; struct iterator_archetype;
template <class Value, class AccessCategory, class TraversalCategory> template <class Value, class AccessCategory, class TraversalCategory>
struct traversal_archetype_base struct traversal_archetype_base
: detail::operator_brackets< : detail::operator_brackets<
typename remove_cv<Value>::type typename remove_cv<Value>::type
, AccessCategory , AccessCategory
@ -429,12 +413,12 @@ namespace detail
, traversal_archetype_base<Value, AccessCategory, TraversalCategory> , traversal_archetype_base<Value, AccessCategory, TraversalCategory>
{ {
typedef iterator_access_archetype<Value, AccessCategory> access; typedef iterator_access_archetype<Value, AccessCategory> access;
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>
@ -467,18 +451,18 @@ struct iterator_archetype
, public detail::iterator_archetype_base< , public detail::iterator_archetype_base<
Value, AccessCategory, TraversalCategory Value, AccessCategory, TraversalCategory
>::workaround_iterator_base >::workaround_iterator_base
# endif # endif
{ {
// Derivation from std::iterator above caused references to nested // Derivation from std::iterator above caused references to nested
// types to be ambiguous, so now we have to redeclare them all // types to be ambiguous, so now we have to redeclare them all
// here. // here.
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \ # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101)) || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
typedef detail::iterator_archetype_base< typedef detail::iterator_archetype_base<
Value,AccessCategory,TraversalCategory Value,AccessCategory,TraversalCategory
> base; > base;
typedef typename base::value_type value_type; typedef typename base::value_type value_type;
typedef typename base::reference reference; typedef typename base::reference reference;
typedef typename base::pointer pointer; typedef typename base::pointer pointer;
@ -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

View File

@ -22,6 +22,7 @@
# include <boost/static_assert.hpp> # include <boost/static_assert.hpp>
namespace boost { namespace boost {
namespace iterators {
// //
// Traversal Categories // Traversal Categories
@ -29,34 +30,34 @@ namespace boost {
struct no_traversal_tag {}; struct no_traversal_tag {};
struct incrementable_traversal_tag struct incrementable_traversal_tag
: no_traversal_tag : no_traversal_tag
{ {
// incrementable_traversal_tag() {} // incrementable_traversal_tag() {}
// incrementable_traversal_tag(std::output_iterator_tag const&) {}; // incrementable_traversal_tag(std::output_iterator_tag const&) {};
}; };
struct single_pass_traversal_tag struct single_pass_traversal_tag
: incrementable_traversal_tag : incrementable_traversal_tag
{ {
// single_pass_traversal_tag() {} // single_pass_traversal_tag() {}
// single_pass_traversal_tag(std::input_iterator_tag const&) {}; // single_pass_traversal_tag(std::input_iterator_tag const&) {};
}; };
struct forward_traversal_tag struct forward_traversal_tag
: single_pass_traversal_tag : single_pass_traversal_tag
{ {
// forward_traversal_tag() {} // forward_traversal_tag() {}
// forward_traversal_tag(std::forward_iterator_tag const&) {}; // forward_traversal_tag(std::forward_iterator_tag const&) {};
}; };
struct bidirectional_traversal_tag struct bidirectional_traversal_tag
: forward_traversal_tag : forward_traversal_tag
{ {
// bidirectional_traversal_tag() {}; // bidirectional_traversal_tag() {};
// bidirectional_traversal_tag(std::bidirectional_iterator_tag const&) {}; // bidirectional_traversal_tag(std::bidirectional_iterator_tag const&) {};
}; };
struct random_access_traversal_tag struct random_access_traversal_tag
: bidirectional_traversal_tag : bidirectional_traversal_tag
{ {
@ -65,7 +66,7 @@ struct random_access_traversal_tag
}; };
namespace detail namespace detail
{ {
// //
// Convert a "strictly old-style" iterator category to a traversal // Convert a "strictly old-style" iterator category to a traversal
// tag. This is broken out into a separate metafunction to reduce // tag. This is broken out into a separate metafunction to reduce
@ -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>

View File

@ -56,7 +56,7 @@ namespace boost_concepts
private: private:
Iterator i; Iterator i;
}; };
template < template <
typename Iterator typename Iterator
, typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type , typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
@ -78,7 +78,7 @@ namespace boost_concepts
, typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type , typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
> >
struct WritableIteratorConcept : WritableIterator<Iterator,ValueType> {}; struct WritableIteratorConcept : WritableIterator<Iterator,ValueType> {};
BOOST_concept(SwappableIterator,(Iterator)) BOOST_concept(SwappableIterator,(Iterator))
{ {
BOOST_CONCEPT_USAGE(SwappableIterator) BOOST_CONCEPT_USAGE(SwappableIterator)
@ -93,7 +93,7 @@ namespace boost_concepts
BOOST_concept(LvalueIterator,(Iterator)) BOOST_concept(LvalueIterator,(Iterator))
{ {
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type; typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
BOOST_CONCEPT_USAGE(LvalueIterator) BOOST_CONCEPT_USAGE(LvalueIterator)
{ {
value_type& r = const_cast<value_type&>(*i); value_type& r = const_cast<value_type&>(*i);
@ -103,7 +103,7 @@ namespace boost_concepts
Iterator i; Iterator i;
}; };
//=========================================================================== //===========================================================================
// Iterator Traversal Concepts // Iterator Traversal Concepts
@ -145,7 +145,7 @@ namespace boost_concepts
, boost::DefaultConstructible<Iterator> , boost::DefaultConstructible<Iterator>
{ {
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type; typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
BOOST_MPL_ASSERT((boost::is_integral<difference_type>)); BOOST_MPL_ASSERT((boost::is_integral<difference_type>));
BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true); BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
@ -155,7 +155,7 @@ namespace boost_concepts
, boost::forward_traversal_tag , boost::forward_traversal_tag
> )); > ));
}; };
BOOST_concept(BidirectionalTraversal,(Iterator)) BOOST_concept(BidirectionalTraversal,(Iterator))
: ForwardTraversal<Iterator> : ForwardTraversal<Iterator>
{ {
@ -192,14 +192,14 @@ namespace boost_concepts
i = i - n; i = i - n;
n = i - j; n = i - j;
} }
private: private:
typename BidirectionalTraversal<Iterator>::difference_type n; typename BidirectionalTraversal<Iterator>::difference_type n;
Iterator i, j; Iterator i, j;
}; };
//=========================================================================== //===========================================================================
// Iterator Interoperability // Iterator Interoperability
namespace detail namespace detail
{ {
@ -248,19 +248,10 @@ 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< public:
typename boost::iterator_traversal<
ConstIterator
>::type
>::type const_traversal_category;
public:
BOOST_CONCEPT_ASSERT((SinglePassIterator<Iterator>)); BOOST_CONCEPT_ASSERT((SinglePassIterator<Iterator>));
BOOST_CONCEPT_ASSERT((SinglePassIterator<ConstIterator>)); BOOST_CONCEPT_ASSERT((SinglePassIterator<ConstIterator>));
@ -271,7 +262,7 @@ namespace boost_concepts
ci = i; ci = i;
} }
private: private:
Iterator i; Iterator i;
ConstIterator ci; ConstIterator ci;

View File

@ -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_< , Return
mpl::or_< >
is_convertible<Facade1, Facade2> {};
, is_convertible<Facade2, Facade1>
> //
// enable if for use in implementation of operators specific for random access traversal.
//
template <
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
, int[3]
>::type type;
};
#else
: ::boost::iterators::enable_if<
mpl::or_<
is_convertible<Facade1, Facade2>
, is_convertible<Facade2, Facade1>
>
, Return
> >
{}; {};
#endif
// //
// Generates associated types for an iterator_facade with the // Generates associated types for an iterator_facade with the
@ -94,7 +107,7 @@ namespace boost
template < template <
class ValueParam class ValueParam
, class CategoryOrTraversal , class CategoryOrTraversal
, class Reference , class Reference
, class Difference , class Difference
> >
struct iterator_facade_types struct iterator_facade_types
@ -102,15 +115,16 @@ namespace boost
typedef typename facade_iterator_category< typedef typename facade_iterator_category<
CategoryOrTraversal, ValueParam, Reference CategoryOrTraversal, ValueParam, Reference
>::type iterator_category; >::type iterator_category;
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;
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \ && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \ || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
@ -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
@ -156,7 +170,7 @@ namespace boost
private: private:
mutable value_type stored_value; mutable value_type stored_value;
}; };
// //
// In general, we can't determine that such an iterator isn't // In general, we can't determine that such an iterator isn't
// writable -- we also need to store a copy of the old iterator so // writable -- we also need to store a copy of the old iterator so
@ -208,7 +222,7 @@ namespace boost
{ {
return stored_iterator; return stored_iterator;
} }
private: private:
mutable value_type stored_value; mutable value_type stored_value;
Iterator stored_iterator; Iterator stored_iterator;
@ -220,7 +234,7 @@ namespace boost
struct is_non_proxy_reference_impl struct is_non_proxy_reference_impl
{ {
static Reference r; static Reference r;
template <class R> template <class R>
static typename mpl::if_< static typename mpl::if_<
is_convertible< is_convertible<
@ -230,17 +244,17 @@ namespace boost
, char[1] , char[1]
, char[2] , char[2]
>::type& helper(R const&); >::type& helper(R const&);
BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1); BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
}; };
template <class Reference, class Value> template <class Reference, class Value>
struct is_non_proxy_reference struct is_non_proxy_reference
: mpl::bool_< : mpl::bool_<
is_non_proxy_reference_impl<Reference, Value>::value is_non_proxy_reference_impl<Reference, Value>::value
> >
{}; {};
# else # else
template <class Reference, class Value> template <class Reference, class Value>
struct is_non_proxy_reference struct is_non_proxy_reference
: is_convertible< : is_convertible<
@ -249,8 +263,8 @@ namespace boost
, Value const volatile* , Value const volatile*
> >
{}; {};
# endif # endif
// A metafunction to choose the result type of postfix ++ // A metafunction to choose the result type of postfix ++
// //
// Because the C++98 input iterator requirements say that *r++ has // Because the C++98 input iterator requirements say that *r++ has
@ -271,8 +285,16 @@ 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
, mpl::not_< , mpl::not_<
@ -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->
// again automatically per 13.3.1.2 para 8
operator T*() const { return &m_value; }
mutable T m_value;
};
// A metafunction that gets the result type for operator->. Also
// 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
// 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); explicit proxy(Reference const & x) : m_ref(x) {}
Reference* operator->() { return boost::addressof(m_ref); }
// This function is needed for MWCW and BCC, which won't call
// operator-> again automatically per 13.3.1.2 para 8
operator Reference*() { return boost::addressof(m_ref); }
Reference m_ref;
};
typedef proxy result_type;
static result_type apply(Reference const & x)
{
return result_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.
@ -380,7 +390,7 @@ namespace boost
> >
> >
{}; {};
template <class Iterator, class Value, class Reference> template <class Iterator, class Value, class Reference>
struct operator_brackets_result struct operator_brackets_result
{ {
@ -410,28 +420,34 @@ 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) # else
mpl::if_<
is_convertible<I2,I1>
, typename I1::difference_type
, typename I2::difference_type
>
# else
mpl::eval_if< mpl::eval_if<
is_convertible<I2,I1> is_convertible<I2,I1>
, iterator_difference<I1> , iterator_difference<I1>
, iterator_difference<I2> , iterator_difference<I2>
> >
# endif # endif
{}; {};
}; };
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 \
@ -440,24 +456,33 @@ namespace boost
operator op( \ operator op( \
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 \
operator op( \ operator op( \
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)
# 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,42 +495,49 @@ 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(
friend inline friend inline
, (iterator_facade<Derived, V, TC, R, D> const& , (iterator_facade<Derived, V, TC, R, D> const&
, typename Derived::difference_type) , typename Derived::difference_type)
) )
; ;
BOOST_ITERATOR_FACADE_PLUS_HEAD( BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend inline friend inline
, (typename Derived::difference_type , (typename Derived::difference_type
, iterator_facade<Derived, V, TC, R, D> const&) , iterator_facade<Derived, V, TC, R, D> const&)
) )
; ;
@ -576,11 +608,156 @@ 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 {
// Implementation for forward traversal iterators
template <
class Derived
, class Value
, class CategoryOrTraversal
, class Reference
, class Difference
>
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
: public boost::iterators::detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
>::base
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
# endif
{
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.
//
Derived& derived()
{
return *static_cast<Derived*>(this);
}
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
};
// Implementation for bidirectional traversal iterators
template <
class Derived
, class Value
, class CategoryOrTraversal
, class Reference
, 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:
Derived& operator--()
{
iterator_core_access::decrement(this->derived());
return this->derived();
}
Derived operator--(int)
{
Derived tmp(this->derived());
--*this;
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)
{
iterator_core_access::advance(this->derived(), n);
return this->derived();
}
Derived& operator-=(difference_type n)
{
iterator_core_access::advance(this->derived(), -n);
return this->derived();
}
Derived operator-(difference_type x) const
{
Derived result(this->derived());
return result -= x;
}
};
} // namespace detail
// //
// iterator_facade - use as a public base class for defining new // iterator_facade - use as a public base class for defining new
// standard-conforming iterators. // standard-conforming iterators.
@ -592,153 +769,38 @@ namespace boost
, class Reference = Value& , class Reference = Value&
, class Difference = std::ptrdiff_t , class Difference = std::ptrdiff_t
> >
class iterator_facade class iterator_facade :
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE public detail::iterator_facade_base<
: public boost::detail::iterator_facade_types< Derived,
Value, CategoryOrTraversal, Reference, Difference Value,
>::base CategoryOrTraversal,
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE Reference,
# endif Difference,
detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
>
{ {
private: protected:
//
// Curiously Recurring Template interface.
//
Derived& derived()
{
return *static_cast<Derived*>(this);
}
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
typedef boost::detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
> associated_types;
protected:
// For use by derived classes // For use by derived classes
typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_; typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
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--()
{
iterator_core_access::decrement(this->derived());
return this->derived();
}
Derived operator--(int)
{
Derived tmp(this->derived());
--*this;
return tmp;
}
Derived& operator+=(difference_type n)
{
iterator_core_access::advance(this->derived(), n);
return this->derived();
}
Derived& operator-=(difference_type n)
{
iterator_core_access::advance(this->derived(), -n);
return this->derived();
}
Derived operator-(difference_type x) const
{
Derived result(this->derived());
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)
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
// //
// Comparison operator implementation. The library supplied operators // Comparison operator implementation. The library supplied operators
// enables the user to provide fully interoperable constant/mutable // enables the user to provide fully interoperable constant/mutable
@ -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) \
@ -860,18 +951,28 @@ namespace boost
return tmp += n; \ return tmp += n; \
} }
BOOST_ITERATOR_FACADE_PLUS(( BOOST_ITERATOR_FACADE_PLUS((
iterator_facade<Derived, V, TC, R, D> const& i iterator_facade<Derived, V, TC, R, D> const& i
, typename Derived::difference_type n , typename Derived::difference_type n
)) ))
BOOST_ITERATOR_FACADE_PLUS(( 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>

View File

@ -8,20 +8,12 @@
# include <boost/detail/iterator.hpp> # include <boost/detail/iterator.hpp>
# 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 #define BOOST_ITERATOR_CATEGORY iterator_category
// "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
# endif
template <class Iterator> template <class Iterator>
@ -29,20 +21,20 @@ struct iterator_value
{ {
typedef typename boost::detail::iterator_traits<Iterator>::value_type type; typedef typename boost::detail::iterator_traits<Iterator>::value_type type;
}; };
template <class Iterator> template <class Iterator>
struct iterator_reference struct iterator_reference
{ {
typedef typename boost::detail::iterator_traits<Iterator>::reference type; typedef typename boost::detail::iterator_traits<Iterator>::reference type;
}; };
template <class Iterator> template <class Iterator>
struct iterator_pointer struct iterator_pointer
{ {
typedef typename boost::detail::iterator_traits<Iterator>::pointer type; typedef typename boost::detail::iterator_traits<Iterator>::pointer type;
}; };
template <class Iterator> template <class Iterator>
struct iterator_difference struct iterator_difference
{ {
@ -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 <>
struct iterator_reference<int>
{
typedef void type;
};
template <> using iterators::iterator_value;
struct iterator_pointer<int> using iterators::iterator_reference;
{ using iterators::iterator_pointer;
typedef void type; using iterators::iterator_difference;
}; using iterators::iterator_category;
template <>
struct iterator_difference<int>
{
typedef void type;
};
template <>
struct BOOST_ITERATOR_CATEGORY<int>
{
typedef void type;
};
# endif
} // namespace boost::iterator } // namespace boost
#endif // ITERATOR_TRAITS_DWA200347_HPP #endif // ITERATOR_TRAITS_DWA200347_HPP

View 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_

View File

@ -13,28 +13,28 @@
#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;
public: public:
permutation_iterator() : m_elt_iter() {} permutation_iterator() : m_elt_iter() {}
explicit permutation_iterator(ElementIterator x, IndexIterator y) explicit permutation_iterator(ElementIterator x, IndexIterator y)
: super_t(y), m_elt_iter(x) {} : super_t(y), m_elt_iter(x) {}
template<class OtherElementIterator, class OtherIndexIterator> template<class OtherElementIterator, class OtherIndexIterator>
@ -54,18 +54,22 @@ private:
template <class,class> friend class permutation_iterator; template <class,class> friend class permutation_iterator;
#else #else
public: public:
#endif #endif
ElementIterator m_elt_iter; ElementIterator m_elt_iter;
}; };
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

View File

@ -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 {
// //
// //
@ -28,7 +27,7 @@ namespace boost
public: public:
reverse_iterator() {} reverse_iterator() {}
explicit reverse_iterator(Iterator x) explicit reverse_iterator(Iterator x)
: super_t(x) {} : super_t(x) {}
template<class OtherIterator> template<class OtherIterator>
@ -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

View File

@ -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,48 +20,34 @@
#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>
#endif #endif
#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;
@ -111,10 +96,10 @@ namespace boost
// don't provide this constructor if UnaryFunc is a // don't provide this constructor if UnaryFunc is a
// function pointer type, since it will be 0. Too dangerous. // function pointer type, since it will be 0. Too dangerous.
BOOST_STATIC_ASSERT(is_class<UnaryFunc>::value); BOOST_STATIC_ASSERT(is_class<UnaryFunc>::value);
#endif #endif
} }
template< template <
class OtherUnaryFunction class OtherUnaryFunction
, class OtherIterator , class OtherIterator
, class OtherReference , class OtherReference
@ -124,7 +109,7 @@ namespace boost
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310) #if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
, typename enable_if_convertible<OtherUnaryFunction, UnaryFunc>::type* = 0 , typename enable_if_convertible<OtherUnaryFunction, UnaryFunc>::type* = 0
#endif #endif
) )
: super_t(t.base()), m_f(t.functor()) : super_t(t.base()), m_f(t.functor())
{} {}
@ -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>

View File

@ -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
{ {
@ -60,7 +52,7 @@ namespace boost {
{ {
public: public:
advance_iterator(DiffType step) : m_step(step) {} advance_iterator(DiffType step) : m_step(step) {}
template<typename Iterator> template<typename Iterator>
void operator()(Iterator& it) const void operator()(Iterator& it) const
{ it += m_step; } { it += m_step; }
@ -72,337 +64,102 @@ 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 typename pure_traversal_tag<
typedef int type; typename iterator_traversal<Iterator1>::type
}; >::type iterator1_traversal;
#endif typedef typename pure_traversal_tag<
typename iterator_traversal<Iterator2>::type
// We need to call tuple_meta_accumulate with mpl::and_ as the >::type iterator2_traversal;
// accumulating functor. To this end, we need to wrap it into
// a struct that has exactly two arguments (that is, template typedef typename minimum_category<
// parameters) and not five, like mpl::and_ does. iterator1_traversal
// , typename minimum_category<
template<typename Arg1, typename Arg2> iterator2_traversal
struct and_with_two_args , random_access_traversal_tag
: mpl::and_<Arg1, Arg2> >::type
{ >::type type;
}; };
# 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
// //
// Builds and exposes the iterator facade type from which the zip // Builds and exposes the iterator facade type from which the zip
// iterator will be derived. // iterator will be derived.
// //
template<typename IteratorTuple> template<typename IteratorTuple>
@ -411,30 +168,30 @@ namespace boost {
private: private:
// Reference type is the type of the tuple obtained from the // Reference type is the type of the tuple obtained from the
// iterators' reference types. // iterators' reference types.
typedef typename typedef typename
detail::tuple_of_references<IteratorTuple>::type reference; detail::tuple_of_references<IteratorTuple>::type reference;
// Value type is the same as reference type. // Value type is the same as reference type.
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.
typedef typename typedef typename
detail::minimum_traversal_category_in_iterator_tuple< detail::minimum_traversal_category_in_iterator_tuple<
IteratorTuple IteratorTuple
>::type traversal_category; >::type traversal_category;
public: public:
// The iterator facade type from which the zip iterator will // The iterator facade type from which the zip iterator will
// be derived. // be derived.
typedef iterator_facade< typedef iterator_facade<
zip_iterator<IteratorTuple>, zip_iterator<IteratorTuple>,
value_type, value_type,
traversal_category, traversal_category,
reference, reference,
difference_type difference_type
@ -446,35 +203,59 @@ 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));
}
};
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// //
// zip_iterator class definition // zip_iterator class definition
// //
template<typename IteratorTuple> template<typename IteratorTuple>
class zip_iterator : class zip_iterator :
public detail::zip_iterator_base<IteratorTuple>::type public detail::zip_iterator_base<IteratorTuple>::type
{ {
// Typedef super_t as our base class. // Typedef super_t as our base class.
typedef typename typedef typename
detail::zip_iterator_base<IteratorTuple>::type super_t; detail::zip_iterator_base<IteratorTuple>::type super_t;
// iterator_core_access is the iterator's best friend. // iterator_core_access is the iterator's best friend.
friend class iterator_core_access; friend class iterator_core_access;
public: public:
// Construction // Construction
// ============ // ============
// Default constructor // Default constructor
zip_iterator() { } zip_iterator() { }
// Constructor from iterator tuple // Constructor from iterator tuple
zip_iterator(IteratorTuple iterator_tuple) zip_iterator(IteratorTuple iterator_tuple)
: m_iterator_tuple(iterator_tuple) : m_iterator_tuple(iterator_tuple)
{ } { }
// Copy constructor // Copy constructor
@ -493,18 +274,19 @@ namespace boost {
{ return m_iterator_tuple; } { return m_iterator_tuple; }
private: private:
// Implementation of Iterator Operations // Implementation of Iterator Operations
// ===================================== // =====================================
// Dereferencing returns a tuple built from the dereferenced // Dereferencing returns a tuple built from the dereferenced
// 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;
get_iterator_tuple(), typedef detail::converter<reference> gen;
detail::dereference_iterator() return gen::call(fusion::transform(
); get_iterator_tuple(),
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
@ -517,69 +299,70 @@ namespace boost {
// under several compilers. No point in bringing in a bunch // under several compilers. No point in bringing in a bunch
// of #ifdefs here. // of #ifdefs here.
// //
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.
template<typename OtherIteratorTuple> template<typename OtherIteratorTuple>
typename super_t::difference_type distance_to( typename super_t::difference_type distance_to(
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
// ============ // ============
// The iterator tuple. // The iterator tuple.
IteratorTuple m_iterator_tuple; IteratorTuple m_iterator_tuple;
}; };
// 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

View File

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

View File

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

View File

@ -25,28 +25,26 @@
# 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 {
// use this for the value type // use this for the value type
struct dummyT { struct dummyT {
dummyT() { } dummyT() { }
dummyT(detail::dummy_constructor) { } dummyT(detail::dummy_constructor) { }
dummyT(int x) : m_x(x) { } dummyT(int x) : m_x(x) { }
int foo() const { return m_x; } int foo() const { return m_x; }
bool operator==(const dummyT& d) const { return m_x == d.m_x; } bool operator==(const dummyT& d) const { return m_x == d.m_x; }
int m_x; int m_x;
}; };
} }
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.
// Preconditions: i != j, *i == val // Preconditions: i != j, *i == val
template <class Iterator, class T> template <class Iterator, class T>
void trivial_iterator_test(const Iterator i, const Iterator j, T val) void trivial_iterator_test(const Iterator i, const Iterator j, T val)
@ -87,7 +85,7 @@ void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
// Preconditions: *i == v1, *++i == v2 // Preconditions: *i == v1, *++i == v2
template <class Iterator, class T> template <class Iterator, class T>
void input_iterator_test(Iterator i, T v1, T v2) void input_iterator_test(Iterator i, T v1, T v2)
{ {
Iterator i1(i); Iterator i1(i);
@ -153,7 +151,7 @@ template <> struct lvalue_test<true> {
#endif #endif
template <class Iterator, class T> template <class Iterator, class T>
void forward_iterator_test(Iterator i, T v1, T v2) void forward_iterator_test(Iterator i, T v1, T v2)
{ {
input_iterator_test(i, v1, v2); input_iterator_test(i, v1, v2);
@ -218,7 +216,7 @@ void random_access_iterator_test(Iterator i, int N, TrueVals vals)
int c; int c;
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type; typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
for (c = 0; c < N-1; ++c) { for (c = 0; c < N-1; ++c) {
assert(i == j + c); assert(i == j + c);
assert(*i == vals[c]); assert(*i == vals[c]);
@ -237,7 +235,7 @@ void random_access_iterator_test(Iterator i, int N, TrueVals vals)
assert(i == k - c); assert(i == k - c);
assert(*i == vals[N - 1 - c]); assert(*i == vals[N - 1 - c]);
assert(*i == boost::implicit_cast<value_type>(j[N - 1 - c])); assert(*i == boost::implicit_cast<value_type>(j[N - 1 - c]));
Iterator q = k - c; Iterator q = k - c;
assert(*i == *q); assert(*i == *q);
assert(i > j); assert(i > j);
assert(i >= j); assert(i >= j);
@ -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

View File

@ -20,7 +20,7 @@
# include <boost/mpl/if.hpp> # include <boost/mpl/if.hpp>
# include <boost/mpl/eval_if.hpp> # include <boost/mpl/eval_if.hpp>
namespace boost { namespace boost {
namespace detail namespace detail
{ {
@ -34,25 +34,25 @@ namespace detail
struct iterator_pointee struct iterator_pointee
{ {
typedef typename iterator_traits<Iterator>::value_type value_type; typedef typename iterator_traits<Iterator>::value_type value_type;
struct impl struct impl
{ {
template <class T> template <class T>
static char test(T const&); static char test(T const&);
static char (& test(value_type&) )[2]; static char (& test(value_type&) )[2];
static Iterator& x; static Iterator& x;
}; };
BOOST_STATIC_CONSTANT(bool, is_constant = sizeof(impl::test(*impl::x)) == 1); BOOST_STATIC_CONSTANT(bool, is_constant = sizeof(impl::test(*impl::x)) == 1);
typedef typename mpl::if_c< typedef typename mpl::if_c<
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
::boost::detail::iterator_pointee<Iterator>::is_constant ::boost::detail::iterator_pointee<Iterator>::is_constant
# else # else
is_constant is_constant
# endif # endif
, typename add_const<value_type>::type , typename add_const<value_type>::type
, value_type , value_type
>::type type; >::type type;
@ -68,7 +68,7 @@ struct pointee
> >
{ {
}; };
} // namespace boost } // namespace boost
#endif // POINTEE_DWA200415_HPP #endif // POINTEE_DWA200415_HPP

View File

@ -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
View 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>"
]
}

View File

@ -3,28 +3,34 @@
# 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)
test-suite iterator test-suite iterator
: :
# These first two tests will run last, and are expected to fail # These first two tests will run last, and are expected to fail
# for many less-capable compilers. # for many less-capable compilers.
[ compile-fail interoperable_fail.cpp ] [ compile-fail interoperable_fail.cpp ]
# test uses expected success, so that we catch unrelated # test uses expected success, so that we catch unrelated
# compilation problems. # compilation problems.
[ run is_convertible_fail.cpp ] [ run is_convertible_fail.cpp ]
[ 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 ]
[ compile is_readable_iterator.cpp ] [ compile is_readable_iterator.cpp ]
[ compile pointee.cpp ] [ compile pointee.cpp ]
[ run unit_tests.cpp ] [ run unit_tests.cpp ]
[ run concept_tests.cpp ] [ run concept_tests.cpp ]
[ run iterator_adaptor_cc.cpp ] [ run iterator_adaptor_cc.cpp ]
@ -41,7 +47,15 @@ test-suite iterator
[ run counting_iterator_test.cpp ] [ run counting_iterator_test.cpp ]
[ run interoperable.cpp ] [ run interoperable.cpp ]
[ 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
View File

@ -0,0 +1,91 @@
// Copyright (C) 2017 Michel Morin.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <vector>
#include <list>
#include <boost/container/slist.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/iterator/advance.hpp>
#include <boost/iterator/transform_iterator.hpp>
int twice(int x) { return x + x; }
template <typename Iterator>
void test_advance(Iterator it_from, Iterator it_to, int n)
{
boost::advance(it_from, n);
BOOST_TEST(it_from == it_to);
}
int main()
{
int array[3] = {1, 2, 3};
int* ptr1 = array;
int* ptr2 = array + 3;
{
test_advance(ptr1, ptr2, 3);
test_advance(ptr2, ptr1, -3);
test_advance(
boost::make_transform_iterator(ptr1, twice)
, boost::make_transform_iterator(ptr2, twice)
, 3
);
test_advance(
boost::make_transform_iterator(ptr2, twice)
, boost::make_transform_iterator(ptr1, twice)
, -3
);
}
{
std::vector<int> ints(ptr1, ptr2);
test_advance(ints.begin(), ints.end(), 3);
test_advance(ints.end(), ints.begin(), -3);
test_advance(
boost::make_transform_iterator(ints.begin(), twice)
, boost::make_transform_iterator(ints.end(), twice)
, 3
);
test_advance(
boost::make_transform_iterator(ints.end(), twice)
, boost::make_transform_iterator(ints.begin(), twice)
, -3
);
}
{
std::list<int> ints(ptr1, ptr2);
test_advance(ints.begin(), ints.end(), 3);
test_advance(ints.end(), ints.begin(), -3);
test_advance(
boost::make_transform_iterator(ints.begin(), twice)
, boost::make_transform_iterator(ints.end(), twice)
, 3
);
test_advance(
boost::make_transform_iterator(ints.end(), twice)
, boost::make_transform_iterator(ints.begin(), twice)
, -3
);
}
{
boost::container::slist<int> ints(ptr1, ptr2);
test_advance(ints.begin(), ints.end(), 3);
test_advance(
boost::make_transform_iterator(ints.begin(), twice)
, boost::make_transform_iterator(ints.end(), twice)
, 3
);
}
return boost::report_errors();
}

View File

@ -0,0 +1,85 @@
// Copyright (c) 2014 Kohei Takahashi.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for most recent version including documentation.
#include <boost/detail/lightweight_test.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/iterator/zip_iterator.hpp>
#include <vector>
#include <string>
int main()
{
typedef TUPLE<
std::vector<int>::iterator,
std::vector<std::string>::iterator
> iterator_tuple;
std::vector<int> vi = boost::assign::list_of(42)(72);
std::vector<std::string> vs = boost::assign::list_of("kokoro")("pyonpyon");
{
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
boost::zip_iterator<iterator_tuple> i2 = i1;
BOOST_TEST( i1 == i2);
BOOST_TEST( i1++ == i2);
BOOST_TEST( i1 == (i2 + 1));
BOOST_TEST((i1 - 1) == i2);
BOOST_TEST( i1-- == ++i2);
BOOST_TEST( i1 == --i2);
}
{
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
boost::zip_iterator<iterator_tuple> i2 = i1 + 1;
BOOST_TEST( i1 != i2);
BOOST_TEST( i1++ != i2);
BOOST_TEST( i1 != (i2 + 1));
BOOST_TEST((i1 - 1) != i2);
BOOST_TEST( i1-- != ++i2);
BOOST_TEST( i1 != --i2);
}
{
boost::zip_iterator<iterator_tuple> i(MAKE_TUPLE(vi.begin(), vs.begin()));
BOOST_TEST(boost::fusion::at_c<0>(* i ) == 42);
BOOST_TEST(boost::fusion::at_c<1>(* i ) == "kokoro");
BOOST_TEST(boost::fusion::at_c<0>(*(i + 1)) == 72);
BOOST_TEST(boost::fusion::at_c<1>(*(i + 1)) == "pyonpyon");
}
{
// Trac #12895
boost::zip_iterator<
TUPLE<int*, std::string*>
> i(MAKE_TUPLE(vi.data(), vs.data()));
BOOST_TEST(boost::fusion::at_c<0>(* i ) == 42);
BOOST_TEST(boost::fusion::at_c<1>(* i ) == "kokoro");
BOOST_TEST(boost::fusion::at_c<0>(*(i + 1)) == 72);
BOOST_TEST(boost::fusion::at_c<1>(*(i + 1)) == "pyonpyon");
}
{
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
boost::zip_iterator<iterator_tuple> i2(MAKE_TUPLE(vi.end(), vs.end()));
BOOST_TEST((i2 - i1) == 2);
++i1;
BOOST_TEST((i2 - i1) == 1);
--i2;
BOOST_TEST((i2 - i1) == 0);
}
return boost::report_errors();
}

View File

@ -0,0 +1,857 @@
// (C) Copyright Dave Abrahams and Thomas Becker 2003. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// File:
// =====
// zip_iterator_test_main.cpp
// Author:
// =======
// Thomas Becker
// Created:
// ========
// Jul 15, 2003
// Purpose:
// ========
// Test driver for zip_iterator.hpp
// Compilers Tested:
// =================
// Metrowerks Codewarrior Pro 7.2, 8.3
// gcc 2.95.3
// gcc 3.2
// Microsoft VC 6sp5 (test fails due to some compiler bug)
// Microsoft VC 7 (works)
// Microsoft VC 7.1
// Intel 5
// Intel 6
// Intel 7.1
// Intel 8
// Borland 5.5.1 (broken due to lack of support from Boost.Tuples)
/////////////////////////////////////////////////////////////////////////////
//
// Includes
//
/////////////////////////////////////////////////////////////////////////////
#include <boost/iterator/zip_iterator.hpp>
#include <boost/iterator/zip_iterator.hpp> // 2nd #include tests #include guard.
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <string>
#include <functional>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/is_readable_iterator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/detail/workaround.hpp>
#include <stddef.h>
/// Tests for https://svn.boost.org/trac/boost/ticket/1517
int to_value(int const &v)
{
return v;
}
void category_test()
{
std::list<int> rng1;
std::string rng2;
boost::make_zip_iterator(
ZI_MAKE_TUPLE(
boost::make_transform_iterator(rng1.begin(), &to_value), // BidirectionalInput
rng2.begin() // RandomAccess
)
);
}
///
/////////////////////////////////////////////////////////////////////////////
//
// Das Main Funktion
//
/////////////////////////////////////////////////////////////////////////////
int main( void )
{
category_test();
std::cout << "\n"
<< "***********************************************\n"
<< "* *\n"
<< "* Test driver for boost::zip_iterator *\n"
<< "* Copyright Thomas Becker 2003 *\n"
<< "* *\n"
<< "***********************************************\n\n"
<< std::flush;
size_t num_successful_tests = 0;
size_t num_failed_tests = 0;
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator construction and dereferencing
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator construction and dereferencing: "
<< std::flush;
std::vector<double> vect1(3);
vect1[0] = 42.;
vect1[1] = 43.;
vect1[2] = 44.;
std::set<int> intset;
intset.insert(52);
intset.insert(53);
intset.insert(54);
//
typedef
boost::zip_iterator<
ZI_TUPLE<
std::set<int>::iterator
, std::vector<double>::iterator
>
> zit_mixed;
zit_mixed zip_it_mixed = zit_mixed(
ZI_MAKE_TUPLE(
intset.begin()
, vect1.begin()
)
);
ZI_TUPLE<int, double> val_tuple(
*zip_it_mixed);
ZI_TUPLE<const int&, double&> ref_tuple(
*zip_it_mixed);
double dblOldVal = ZI_TUPLE_GET(1)(ref_tuple);
ZI_TUPLE_GET(1)(ref_tuple) -= 41.;
if( 52 == ZI_TUPLE_GET(0)(val_tuple) &&
42. == ZI_TUPLE_GET(1)(val_tuple) &&
52 == ZI_TUPLE_GET(0)(ref_tuple) &&
1. == ZI_TUPLE_GET(1)(ref_tuple) &&
1. == *vect1.begin()
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
// Undo change to vect1
ZI_TUPLE_GET(1)(ref_tuple) = dblOldVal;
#if defined(ZI_USE_BOOST_TUPLE)
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator with 12 components
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterators with 12 components: "
<< std::flush;
// Declare 12 containers
//
std::list<int> li1;
li1.push_back(1);
std::set<int> se1;
se1.insert(2);
std::vector<int> ve1;
ve1.push_back(3);
//
std::list<int> li2;
li2.push_back(4);
std::set<int> se2;
se2.insert(5);
std::vector<int> ve2;
ve2.push_back(6);
//
std::list<int> li3;
li3.push_back(7);
std::set<int> se3;
se3.insert(8);
std::vector<int> ve3;
ve3.push_back(9);
//
std::list<int> li4;
li4.push_back(10);
std::set<int> se4;
se4.insert(11);
std::vector<int> ve4;
ve4.push_back(12);
// typedefs for cons lists of iterators.
typedef boost::tuples::cons<
std::set<int>::iterator,
ZI_TUPLE<
std::vector<int>::iterator,
std::list<int>::iterator,
std::set<int>::iterator,
std::vector<int>::iterator,
std::list<int>::iterator,
std::set<int>::iterator,
std::vector<int>::iterator,
std::list<int>::iterator,
std::set<int>::iterator,
std::vector<int>::const_iterator
>::inherited
> cons_11_its_type;
//
typedef boost::tuples::cons<
std::list<int>::const_iterator,
cons_11_its_type
> cons_12_its_type;
// typedefs for cons lists for dereferencing the zip iterator
// made from the cons list above.
typedef boost::tuples::cons<
const int&,
ZI_TUPLE<
int&,
int&,
const int&,
int&,
int&,
const int&,
int&,
int&,
const int&,
const int&
>::inherited
> cons_11_refs_type;
//
typedef boost::tuples::cons<
const int&,
cons_11_refs_type
> cons_12_refs_type;
// typedef for zip iterator with 12 elements
typedef boost::zip_iterator<cons_12_its_type> zip_it_12_type;
// Declare a 12-element zip iterator.
zip_it_12_type zip_it_12(
cons_12_its_type(
li1.begin(),
cons_11_its_type(
se1.begin(),
ZI_MAKE_TUPLE(
ve1.begin(),
li2.begin(),
se2.begin(),
ve2.begin(),
li3.begin(),
se3.begin(),
ve3.begin(),
li4.begin(),
se4.begin(),
ve4.begin()
)
)
)
);
// Dereference, mess with the result a little.
cons_12_refs_type zip_it_12_dereferenced(*zip_it_12);
ZI_TUPLE_GET(9)(zip_it_12_dereferenced) = 42;
// Make a copy and move it a little to force some instantiations.
zip_it_12_type zip_it_12_copy(zip_it_12);
++zip_it_12_copy;
if( ZI_TUPLE_GET(11)(zip_it_12.get_iterator_tuple()) == ve4.begin() &&
ZI_TUPLE_GET(11)(zip_it_12_copy.get_iterator_tuple()) == ve4.end() &&
1 == ZI_TUPLE_GET(0)(zip_it_12_dereferenced) &&
12 == ZI_TUPLE_GET(11)(zip_it_12_dereferenced) &&
42 == *(li4.begin())
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator incrementing and dereferencing
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator ++ and *: "
<< std::flush;
std::vector<double> vect2(3);
vect2[0] = 2.2;
vect2[1] = 3.3;
vect2[2] = 4.4;
boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_begin(
ZI_MAKE_TUPLE(
vect1.begin(),
vect2.begin()
)
);
boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_run(
ZI_MAKE_TUPLE(
vect1.begin(),
vect2.begin()
)
);
boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_end(
ZI_MAKE_TUPLE(
vect1.end(),
vect2.end()
)
);
if( zip_it_run == zip_it_begin &&
42. == ZI_TUPLE_GET(0)(*zip_it_run) &&
2.2 == ZI_TUPLE_GET(1)(*zip_it_run) &&
43. == ZI_TUPLE_GET(0)(*(++zip_it_run)) &&
3.3 == ZI_TUPLE_GET(1)(*zip_it_run) &&
44. == ZI_TUPLE_GET(0)(*(++zip_it_run)) &&
4.4 == ZI_TUPLE_GET(1)(*zip_it_run) &&
zip_it_end == ++zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator decrementing and dereferencing
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator -- and *: "
<< std::flush;
if( zip_it_run == zip_it_end &&
zip_it_end == zip_it_run-- &&
44. == ZI_TUPLE_GET(0)(*zip_it_run) &&
4.4 == ZI_TUPLE_GET(1)(*zip_it_run) &&
43. == ZI_TUPLE_GET(0)(*(--zip_it_run)) &&
3.3 == ZI_TUPLE_GET(1)(*zip_it_run) &&
42. == ZI_TUPLE_GET(0)(*(--zip_it_run)) &&
2.2 == ZI_TUPLE_GET(1)(*zip_it_run) &&
zip_it_begin == zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator copy construction and equality
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator copy construction and equality: "
<< std::flush;
boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
> zip_it_run_copy(zip_it_run);
if(zip_it_run == zip_it_run && zip_it_run == zip_it_run_copy)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator inequality
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator inequality: "
<< std::flush;
if(!(zip_it_run != zip_it_run_copy) && zip_it_run != ++zip_it_run_copy)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator less than
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator less than: "
<< std::flush;
// Note: zip_it_run_copy == zip_it_run + 1
//
if( zip_it_run < zip_it_run_copy &&
!( zip_it_run < --zip_it_run_copy) &&
zip_it_run == zip_it_run_copy
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator less than or equal
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "zip iterator less than or equal: "
<< std::flush;
// Note: zip_it_run_copy == zip_it_run
//
++zip_it_run;
zip_it_run_copy += 2;
if( zip_it_run <= zip_it_run_copy &&
zip_it_run <= --zip_it_run_copy &&
!( zip_it_run <= --zip_it_run_copy) &&
zip_it_run <= zip_it_run
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator greater than
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator greater than: "
<< std::flush;
// Note: zip_it_run_copy == zip_it_run - 1
//
if( zip_it_run > zip_it_run_copy &&
!( zip_it_run > ++zip_it_run_copy) &&
zip_it_run == zip_it_run_copy
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator greater than or equal
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator greater than or equal: "
<< std::flush;
++zip_it_run;
// Note: zip_it_run == zip_it_run_copy + 1
//
if( zip_it_run >= zip_it_run_copy &&
--zip_it_run >= zip_it_run_copy &&
! (zip_it_run >= ++zip_it_run_copy)
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator + int
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator + int: "
<< std::flush;
// Note: zip_it_run == zip_it_run_copy - 1
//
zip_it_run = zip_it_run + 2;
++zip_it_run_copy;
if( zip_it_run == zip_it_run_copy && zip_it_run == zip_it_begin + 3 )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator - int
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator - int: "
<< std::flush;
// Note: zip_it_run == zip_it_run_copy, and both are at end position
//
zip_it_run = zip_it_run - 2;
--zip_it_run_copy;
--zip_it_run_copy;
if( zip_it_run == zip_it_run_copy && (zip_it_run - 1) == zip_it_begin )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator +=
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator +=: "
<< std::flush;
// Note: zip_it_run == zip_it_run_copy, and both are at begin + 1
//
zip_it_run += 2;
if( zip_it_run == zip_it_begin + 3 )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator -=
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator -=: "
<< std::flush;
// Note: zip_it_run is at end position, zip_it_run_copy is at
// begin plus one.
//
zip_it_run -= 2;
if( zip_it_run == zip_it_run_copy )
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator getting member iterators
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator member iterators: "
<< std::flush;
// Note: zip_it_run and zip_it_run_copy are both at
// begin plus one.
//
if( ZI_TUPLE_GET(0)(zip_it_run.get_iterator_tuple()) == vect1.begin() + 1 &&
ZI_TUPLE_GET(1)(zip_it_run.get_iterator_tuple()) == vect2.begin() + 1
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Making zip iterators
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Making zip iterators: "
<< std::flush;
std::vector<ZI_TUPLE<double, double> >
vect_of_tuples(3);
std::copy(
boost::make_zip_iterator(
ZI_MAKE_TUPLE(
vect1.begin(),
vect2.begin()
)
),
boost::make_zip_iterator(
ZI_MAKE_TUPLE(
vect1.end(),
vect2.end()
)
),
vect_of_tuples.begin()
);
if( 42. == ZI_TUPLE_GET(0)(*vect_of_tuples.begin()) &&
2.2 == ZI_TUPLE_GET(1)(*vect_of_tuples.begin()) &&
43. == ZI_TUPLE_GET(0)(*(vect_of_tuples.begin() + 1)) &&
3.3 == ZI_TUPLE_GET(1)(*(vect_of_tuples.begin() + 1)) &&
44. == ZI_TUPLE_GET(0)(*(vect_of_tuples.begin() + 2)) &&
4.4 == ZI_TUPLE_GET(1)(*(vect_of_tuples.begin() + 2))
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator non-const --> const conversion
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator non-const to const conversion: "
<< std::flush;
boost::zip_iterator<
ZI_TUPLE<
std::set<int>::const_iterator,
std::vector<double>::const_iterator
>
>
zip_it_const(
ZI_MAKE_TUPLE(
intset.begin(),
vect2.begin()
)
);
//
boost::zip_iterator<
ZI_TUPLE<
std::set<int>::iterator,
std::vector<double>::const_iterator
>
>
zip_it_half_const(
ZI_MAKE_TUPLE(
intset.begin(),
vect2.begin()
)
);
//
boost::zip_iterator<
ZI_TUPLE<
std::set<int>::iterator,
std::vector<double>::iterator
>
>
zip_it_non_const(
ZI_MAKE_TUPLE(
intset.begin(),
vect2.begin()
)
);
zip_it_half_const = ++zip_it_non_const;
zip_it_const = zip_it_half_const;
++zip_it_const;
// zip_it_non_const = ++zip_it_const; // Error: can't convert from const to non-const
if( 54 == ZI_TUPLE_GET(0)(*zip_it_const) &&
4.4 == ZI_TUPLE_GET(1)(*zip_it_const) &&
53 == ZI_TUPLE_GET(0)(*zip_it_half_const) &&
3.3 == ZI_TUPLE_GET(1)(*zip_it_half_const)
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
#if defined(ZI_USE_BOOST_TUPLE)
/////////////////////////////////////////////////////////////////////////////
//
// Zip iterator categories
//
/////////////////////////////////////////////////////////////////////////////
std::cout << "Zip iterator categories: "
<< std::flush;
// The big iterator of the previous test has vector, list, and set iterators.
// Therefore, it must be bidirectional, but not random access.
bool bBigItIsBidirectionalIterator = boost::is_convertible<
boost::iterator_traversal<zip_it_12_type>::type
, boost::bidirectional_traversal_tag
>::value;
bool bBigItIsRandomAccessIterator = boost::is_convertible<
boost::iterator_traversal<zip_it_12_type>::type
, boost::random_access_traversal_tag
>::value;
// A combining iterator with all vector iterators must have random access
// traversal.
//
typedef boost::zip_iterator<
ZI_TUPLE<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
>
> all_vects_type;
bool bAllVectsIsRandomAccessIterator = boost::is_convertible<
boost::iterator_traversal<all_vects_type>::type
, boost::random_access_traversal_tag
>::value;
// The big test.
if( bBigItIsBidirectionalIterator &&
! bBigItIsRandomAccessIterator &&
bAllVectsIsRandomAccessIterator
)
{
++num_successful_tests;
std::cout << "OK" << std::endl;
}
else
{
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
#endif
// Done
//
std::cout << "\nTest Result:"
<< "\n============"
<< "\nNumber of successful tests: " << static_cast<unsigned int>(num_successful_tests)
<< "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests)
<< std::endl;
return num_failed_tests;
}

84
test/distance_test.cpp Normal file
View File

@ -0,0 +1,84 @@
// Copyright (C) 2017 Michel Morin.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <vector>
#include <list>
#include <boost/container/slist.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/iterator/distance.hpp>
#include <boost/iterator/transform_iterator.hpp>
int twice(int x) { return x + x; }
template <typename Iterator>
void test_distance(Iterator it_from, Iterator it_to, int n)
{
BOOST_TEST(boost::distance(it_from, it_to) == n);
}
int main()
{
int array[3] = {1, 2, 3};
int* ptr1 = array;
int* ptr2 = array + 3;
{
test_distance(ptr1, ptr2, 3);
test_distance(ptr2, ptr1, -3);
test_distance(
boost::make_transform_iterator(ptr1, twice)
, boost::make_transform_iterator(ptr2, twice)
, 3
);
test_distance(
boost::make_transform_iterator(ptr2, twice)
, boost::make_transform_iterator(ptr1, twice)
, -3
);
}
{
std::vector<int> ints(ptr1, ptr2);
test_distance(ints.begin(), ints.end(), 3);
test_distance(ints.end(), ints.begin(), -3);
test_distance(
boost::make_transform_iterator(ints.begin(), twice)
, boost::make_transform_iterator(ints.end(), twice)
, 3
);
test_distance(
boost::make_transform_iterator(ints.end(), twice)
, boost::make_transform_iterator(ints.begin(), twice)
, -3
);
}
{
std::list<int> ints(ptr1, ptr2);
test_distance(ints.begin(), ints.end(), 3);
test_distance(
boost::make_transform_iterator(ints.begin(), twice)
, boost::make_transform_iterator(ints.end(), twice)
, 3
);
}
{
boost::container::slist<int> ints(ptr1, ptr2);
test_distance(ints.begin(), ints.end(), 3);
test_distance(
boost::make_transform_iterator(ints.begin(), twice)
, boost::make_transform_iterator(ints.end(), twice)
, 3
);
}
return boost::report_errors();
}

View File

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

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

View File

@ -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 (**)

View File

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

View File

@ -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()
{ {

View File

@ -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()
{ {

View File

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

View File

@ -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.
@ -45,14 +50,14 @@ class counter_iterator
struct proxy struct proxy
{ {
proxy(int& x) : state(x) {} proxy(int& x) : state(x) {}
operator int const&() const operator int const&() const
{ {
return state; return state;
} }
int& operator=(int x) { state = x; return state; } int& operator=(int x) { state = x; return state; }
int& state; int& state;
}; };
@ -87,20 +92,136 @@ 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; {
boost::readable_iterator_test(counter_iterator<int const&>(&state), 0); int state = 0;
state = 3; boost::readable_iterator_test(counter_iterator<int const&>(&state), 0);
boost::readable_iterator_test(counter_iterator<proxy>(&state), 3); state = 3;
boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7); boost::readable_iterator_test(counter_iterator<proxy>(&state), 3);
BOOST_TEST(state == 8); boost::writable_iterator_test(counter_iterator<proxy>(&state), 9, 7);
BOOST_TEST(state == 8);
}
{
// test for a fix to http://tinyurl.com/zuohe
// These two lines should be equivalent (and both compile)
input_iter p;
(*p).mutator();
p->mutator();
same_type<input_iter::pointer>(p.operator->());
}
{
int x = 0;
iterator_with_proxy_reference i(x);
BOOST_TEST(x == 0);
BOOST_TEST(i.m_x == 0);
++(*i).m_x;
BOOST_TEST(x == 1);
BOOST_TEST(i.m_x == 1);
++i->m_x;
BOOST_TEST(x == 2);
BOOST_TEST(i.m_x == 2);
}
{
derived d(1);
boost::readable_iterator_test(abstract_iterator<derived *, base>(&d), derived(1));
}
// test for a fix to http://tinyurl.com/zuohe
// These two lines should be equivalent (and both compile)
input_iter p;
(*p).mutator();
p->mutator();
return boost::report_errors(); return boost::report_errors();
} }

22
test/minimum_category.cpp Normal file
View File

@ -0,0 +1,22 @@
// Copyright Andrey Semashev 2014.
//
// Use, modification and distribution is subject to
// the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/minimum_category.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/type_traits/is_same.hpp>
#include <iterator>
using boost::is_same;
using boost::iterators::minimum_category;
int main(int, char*[])
{
BOOST_TEST_TRAIT_TRUE((is_same<minimum_category<std::forward_iterator_tag, std::random_access_iterator_tag>::type, std::forward_iterator_tag>));
BOOST_TEST_TRAIT_TRUE((is_same<minimum_category<std::random_access_iterator_tag, std::forward_iterator_tag>::type, std::forward_iterator_tag>));
BOOST_TEST_TRAIT_TRUE((is_same<minimum_category<std::random_access_iterator_tag, std::random_access_iterator_tag>::type, std::random_access_iterator_tag>));
return boost::report_errors();
}

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

View File

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

View File

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

View File

@ -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,30 +29,30 @@ 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<
std::input_iterator_tag std::input_iterator_tag
, input_output_iterator_tag>::value)); , input_output_iterator_tag>::value));
BOOST_STATIC_ASSERT(( BOOST_STATIC_ASSERT((
!boost::is_convertible< !boost::is_convertible<
std::output_iterator_tag std::output_iterator_tag
, input_output_iterator_tag>::value)); , input_output_iterator_tag>::value));
BOOST_STATIC_ASSERT(( BOOST_STATIC_ASSERT((
boost::is_convertible< boost::is_convertible<
input_output_iterator_tag input_output_iterator_tag
, std::input_iterator_tag>::value)); , std::input_iterator_tag>::value));
BOOST_STATIC_ASSERT(( BOOST_STATIC_ASSERT((
boost::is_convertible< boost::is_convertible<
input_output_iterator_tag input_output_iterator_tag
@ -67,7 +64,7 @@ void category_test()
boost::is_convertible< boost::is_convertible<
std::forward_iterator_tag std::forward_iterator_tag
, input_output_iterator_tag>::value)); , input_output_iterator_tag>::value));
#endif #endif
int test = static_assert_min_cat< int test = static_assert_min_cat<
std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag std::input_iterator_tag,input_output_iterator_tag, std::input_iterator_tag
@ -81,7 +78,7 @@ void category_test()
test = static_assert_min_cat< test = static_assert_min_cat<
input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag input_output_iterator_tag,std::forward_iterator_tag, input_output_iterator_tag
>::value; >::value;
#endif #endif
test = static_assert_min_cat< test = static_assert_min_cat<
std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag std::input_iterator_tag,std::forward_iterator_tag, std::input_iterator_tag
@ -96,8 +93,8 @@ void category_test()
test = static_assert_min_cat< test = static_assert_min_cat<
std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag std::output_iterator_tag,std::random_access_iterator_tag, std::output_iterator_tag
>::value; >::value;
#endif #endif
(void)test; (void)test;
} }

View File

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

View File

@ -0,0 +1,9 @@
#include <boost/fusion/include/deque.hpp>
#include <boost/fusion/include/make_deque.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#define ZI_TUPLE boost::fusion::deque
#define ZI_MAKE_TUPLE boost::fusion::make_deque
#define ZI_TUPLE_GET(n) boost::fusion::at_c<n>
#include "detail/zip_iterator_test_original.ipp"

View File

@ -0,0 +1,11 @@
#include <boost/config.hpp>
#include <boost/fusion/include/list.hpp>
#include <boost/fusion/include/make_list.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#define ZI_TUPLE boost::fusion::list
#define ZI_MAKE_TUPLE boost::fusion::make_list
#define ZI_TUPLE_GET(n) boost::fusion::at_c<n>
#include "detail/zip_iterator_test_original.ipp"

View File

@ -0,0 +1,11 @@
#include <boost/config.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#define ZI_TUPLE boost::fusion::vector
#define ZI_MAKE_TUPLE boost::fusion::make_vector
#define ZI_TUPLE_GET(n) boost::fusion::at_c<n>
#include "detail/zip_iterator_test_original.ipp"

View File

@ -0,0 +1,21 @@
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <tuple>
#include <boost/fusion/adapted/std_tuple.hpp>
#define ZI_TUPLE std::tuple
#define ZI_MAKE_TUPLE std::make_tuple
#define ZI_TUPLE_GET(n) std::get<n>
#include "detail/zip_iterator_test_original.ipp"
#else
int main()
{
return 0;
}
#endif

View File

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

View File

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

View File

@ -0,0 +1,29 @@
// Copyright (c) 2014 Kohei Takahashi.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for most recent version including documentation.
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <tuple>
#include <boost/fusion/adapted/std_tuple.hpp>
#define TUPLE std::tuple
#define MAKE_TUPLE std::make_tuple
#include "detail/zip_iterator_test.ipp"
#else
int main()
{
return 0;
}
#endif