Compare commits

...

349 Commits

Author SHA1 Message Date
0013c5c4f0 Skip zip_iterator_test_std_pair on g++ in C++03 mode 2017-12-24 04:56:47 +02:00
386dbf1054 Skip zip_iterator_test_std_pair on msvc-9.0 and below 2017-12-24 04:38:07 +02:00
486721bbfe Update .travis.yml, appveyor.yml 2017-12-24 01:47:23 +02:00
5ad48c4d14 Fix links to examples 2017-12-23 23:54:33 +02:00
adecfd94f3 Use lightweight_test in shared_iterator_test.cpp 2017-12-23 23:45:59 +02:00
affe7e6d84 Add shared_iterator_test to test/Jamfile 2017-12-23 23:45:33 +02:00
91b392a478 Move test files to test/ 2017-12-23 22:05:35 +02:00
84227ea6ba Move shared_iterator_example* to example/ 2017-12-23 22:04:25 +02:00
67ac957273 shared_container_iterator library: - updated Copyright and License notices - Added shared_iterator_test to the iterator test suite.
[SVN r22140]
2017-12-23 22:02:20 +02:00
f86cd29f52 Fix tabs in file.
[SVN r21399]
2017-12-23 22:02:20 +02:00
fff85e7db9 Updated shared_container_iterator to use the new iterator adaptors library. Updated the documentation and examples as well to reflect the changes.
[SVN r19535]
2017-12-23 22:02:20 +02:00
d6c6f0ce16 Added Shared Container Iterator adaptor to iterator adaptor library.
[SVN r15169]
2017-12-23 22:02:20 +02:00
81faa161cf Add #include <boost/next_prior.hpp>; no longer in utility.hpp 2017-12-02 04:04:32 +02:00
7e5a32b3ea Merge pull request #38 from pavelkryukov/patch-1
Remove std::unary_function from zip_iterator_eg.rst
2017-11-25 13:58:41 -05:00
1b388c2496 Remove std::unary_function from zip_iterator_eg.rst 2017-11-25 12:15:52 +03:00
30b93d7428 Removed the use of std::unary_function. 2017-11-20 16:28:28 +03:00
28b8cc8c9c Removed --depth 1 2017-10-29 21:43:30 -04:00
992a314211 Better appveyor file setup. 2017-10-09 12:07:41 -04:00
422ad12716 Merge branch 'develop' of https://github.com/boostorg/iterator into develop 2017-10-09 08:17:24 -04:00
b2585dda6a Added Appveyor file. 2017-10-09 08:16:23 -04:00
8b5e92a0c4 Converted asserts in tests to tests using lightweight_test.hpp. 2017-10-02 01:26:39 +03:00
a36ed0f35d Replaced type_traits.hpp with more fine-grained includes. Replaced assert with BOOST_ASSERT. 2017-10-02 01:18:17 +03:00
0a08203107 Replaced type_traits.hpp with more fine grained includes.
This should work around compilation failures on gcc 4.6, which apparently
cannot handle all headers in Boost.TypeTraits.
2017-09-30 15:56:53 +03:00
38ef552209 Add the new path to the header to the comment. 2017-09-18 01:50:55 +03:00
a85dfaa7f2 Added a forwarding header for function_output_iterator.hpp 2017-09-18 01:43:24 +03:00
2af60e066d Move function_output_iterator.hpp into the iterator directory. 2017-09-18 01:39:00 +03:00
7442334ce1 Merge pull request #35 from morinmorin/fix_result_of_in_transform_iterator
Fix usage of decltype-based result_of in transform_iterator.
2017-09-18 01:23:43 +03:00
8577675c85 Renamed scripts to have a meaningful extension. 2017-09-18 01:09:42 +03:00
685b3fe855 Re-added executable permissions for scripts.
The executable bit was removed previously because the files have no extension
and were not considered as scripts by the search command.
2017-09-18 00:30:45 +03:00
a653a39cf4 Removed executable tags. 2017-09-16 07:19:04 -04:00
c338572735 Fix usage of decltype-based result_of in transform_iterator.
Regardless of value categories of a transform_iterator object, its
dereference operator calls m_f as an lvalue. Thus, correct usage of
decltype-based result_of is result_of<const UnaryFunc&(...)>.
2017-09-16 18:01:03 +09:00
07afd26ca2 Merge pull request #34 from morinmorin/fix_result_of_usage
Fix result_of usage
2017-09-11 23:44:36 +03:00
d058933767 Correct the result_of usage. 2017-09-12 02:54:50 +09:00
e2f81e9b48 Silenced signed/unsigned mismatch warning. 2017-09-08 18:12:58 +03:00
379200dfd1 Force result_of use decltype whenever possible to maximize testing of function input iterator with lambdas. 2017-09-08 18:12:02 +03:00
a26314dfb9 Added a check for BOOST_RESULT_OF_USE_DECLTYPE in case if tests are run with forced use of decltype in result_of. 2017-09-07 18:51:36 +03:00
e61592c553 Merge pull request #32 from morinmorin/clean_up_function_input_iterator
Clean up function_input_iterator
2017-09-07 18:46:07 +03:00
a3751006db Merge pull request #33 from morinmorin/fix_lambda_test
Fix lambda test
2017-09-07 18:36:10 +03:00
40da532a4d Suppress signed-unsigned comparison warning. 2017-09-07 20:17:35 +09:00
7ce9f87954 Add more feature checks; lambda test needs decltype-based result_of. 2017-09-07 20:14:39 +09:00
553b9713ac Remove dead class template (i.e. function_reference_input_iterator).
Both make_function_input_iterator(function) and make...(&function)
do not depend on function_reference_input_iterator. Actually, passing a
function reference as a template argument to function_input_iterator is
not supported. Doing so results in compiler errors.
2017-09-06 23:12:18 +09:00
ba32745e80 Replace ugly BOOST_DEDUCED_TYPENAME with typename. 2017-09-06 19:50:15 +09:00
282b28e51f Use boost::addressof instead of &. 2017-09-06 19:47:55 +09:00
479898d9d5 Remove unnecessary headers in test. 2017-09-06 19:41:24 +09:00
c1a375284d Merge pull request #31 from morinmorin/clean_up_test
Clean up function_input_iterator_test.cpp
2017-09-04 12:02:15 -04:00
24d2f58f98 Use lightweight_test.hpp instead of <cassert> 2017-09-05 00:32:15 +09:00
25a91d5981 Silenced gcc warnings about unused parameters. 2017-09-01 20:51:07 +03:00
9b78dc1006 Replaced vector::data() with &v[0] for compatibility with older compilers that don't provide this function. 2017-08-30 17:09:19 +03:00
89ca2fd1ae Shortened internal ids of qbk sections regarding iterator concepts. 2017-08-28 21:48:24 +03:00
79277b78d2 Added references to generator_iterator docs to rst and qbk docs. 2017-08-28 21:45:03 +03:00
eb90ad7a99 Merge pull request #30 from morinmorin/port_rst_to_quickbook
Port rst docs changeset to quickbook
2017-08-28 15:56:05 +03:00
de07014e9a Port rst docs changeset to quickbook (230d47e).
Move difference_type from the Forward Traversal Iterator concept to
the Single Pass Traversal concept.
2017-08-28 20:47:09 +09:00
25dc5c6c9c Port rst docs changeset to quickbook (6368d38).
Fix base class for const_node_iterator.
2017-08-28 20:42:43 +09:00
048c3dfa72 Port rst docs changeset to quickbook (daac0f2).
The argument order is flipped in the documentation.
2017-08-28 20:40:47 +09:00
f7dfc36a9c Port rst docs changeset to quickbook (ad90dac).
UnaryFunction is treated as a const object, but the documentation was missing
the const qualification.
2017-08-28 20:39:10 +09:00
c529399fb1 Reworked the test to avoid bogus warnings from gcc. 2017-08-27 17:48:47 +03:00
6faa3a942b Merge branch 'develop' of github.com:boostorg/iterator into develop 2017-08-27 17:31:54 +03:00
0c6b09ef6a Workaround MSVC 14.1 problem with template specialization partial ordering that caused compilation failure when next/prior is used with pointers. Added a test. 2017-08-27 17:31:34 +03:00
83220e7aea Merge branch 'develop' 2017-08-27 14:02:11 +03:00
991ea534ee Silenced warnings about signed/unsigned mismatch in comparisons. 2017-08-27 13:59:52 +03:00
210633c08c Silenced warnings about signed/unsigned mismatch in comparisons. 2017-08-27 13:59:09 +03:00
3275ee3c82 Updated examples to use unique_ptr when available rather than auto_ptr, which is being deprecated. 2017-08-26 15:04:47 -04:00
a72deda3ac Merge branch 'develop' 2017-08-26 20:39:41 +03:00
2b6b6bf8ad Silence warnings in tests about unused variables and local typedefs. 2017-08-26 20:39:26 +03:00
0107df44ab 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.
2017-08-26 20:23:14 +03:00
011288c2c8 Merge branch 'develop' 2017-08-26 20:07:54 +03:00
eaf1a48583 Added documentation for advance and distance. Various cleanup and fixes.
- Fixed multiple broken links to the documentation. Converted some of the
  links to internal references to the QuickBook documentation. Not all
  links converted because some of the QuickBook pages are not completely
  converted.
- Renamed utilities.qbk to type_traits.qbk and removed the part duplicated
  by concept_checking.qbk.
- Renamed traits.qbk to iterator_traits.qbk to better disambiguate with
  other type traits documented in type_traits.qbk.
- Converted some of the headings in iterator concepts to sections to be
  able to give those sections ids. This allows to reference those sections
  from other places in the documentation.
- In order to preserve the more compact pagination of the new sections
  (i.e. to have multiple sections on one page, like it was with headings)
  set chunk.section.depth=2 in the docs Jamfile.
2017-08-26 19:56:23 +03:00
52fbe950ec Minor next/prior docs corrections to better fit the rest of the docs. 2017-08-26 17:48:38 +03:00
6a672cecbd Replaced non-functional list syntax with direct wording. 2017-08-26 17:36:28 +03:00
577203bee8 Merge branch 'develop' 2017-08-26 17:25:35 +03:00
5f6ac9c020 Added next/prior documentation. 2017-08-26 16:27:55 +03:00
a48de6a8b8 Added tests for next/prior to the Jamfile. Ported tests to lightweight_test.hpp. 2017-08-26 15:31:38 +03:00
5f6fd2dec6 Use std::iterator_traits to detect iterators, when possible.
This allows next/prior to detect user's iterators that do not
define iterator_category nested type but specialize
std::iterator_traits instead.
2017-08-26 15:23:36 +03:00
e3577e7687 Use Boost.Iterator to advance iterators.
By using Boost.Iterator we rely on the separate traversal category instead of
the standard iterator category to advance iterators efficiently. For instance,
this allows to advance transform iterators over a random access sequence
in constant time, despite that they are formally input iterators.

Also, std::reverse_iterator formally requires at least bidirectional iterator
as the underlying iterator type. Transform iterators from the example above
don't qualify, so potentially std::reverse_iterator could fail to compile.
2017-08-26 15:23:36 +03:00
5ba36b063e Changed iterator_category nested type detection to work with MSVC and different versions of gcc. 2017-08-26 15:23:36 +03:00
bab02bb82e Add test cases for std::reverse_iterator 2017-08-26 15:23:36 +03:00
d251a6f515 Reworked iterator handling in next/prior helpers.
The new implementation tries to detect if the incremented/decremented type
is an iterator first and if not falls back to operator probing. This way
iterators that are not SFINAE-friendly (i.e. unconditionally define
arithmetic operators regardless of the iterator category) are still treated
as iterators through std::advance and do not fail the compilation.

The iterator detection is based on probing for the nested iterator_category
type that is expected to be present in class-type iterators. This heuristic
is not flawless since iterators are not required to defined this type.
User-defined iterators may not have it and instead specialize
std::iterator_traits. This use case is not covered by the current implementation
and will likely fail to compile. With C++17 SFINAE-friendly std::iterator_traits
this can be fixed, but currently Boost.Config lacks the macro to detect
availability of this feature. Support for it can be added by a later commit.

Also simplified boost::prior for iterators, removing the possibility of
integer overflow caused by negation of the distance value.
2017-08-26 15:23:36 +03:00
9d054b25ce Reworked next() and prior() taking the distance arguments.
The new version should provide the expected behavior in the case (prior(v.end(), v.size()) == v.begin()). It should also work with integers now, as was originally intended by David Abrahams. Added tests to verify these new use cases.
2017-08-26 15:23:36 +03:00
d1b22ac8e8 Remove executable bit from the file. 2017-08-26 15:23:36 +03:00
abe77db3e0 Added Daryle Walker's copyrights as requested.
[SVN r24481]
2017-08-26 15:23:36 +03:00
398819237e Removed Boost.org copyrights and replaced with originating authors copyright instead.
[SVN r24372]
2017-08-26 15:23:36 +03:00
a4bacb5077 Extended next/prior using patch from Daniel Walker (Daniel.Walker-at-bowneglobal.com)
[SVN r21382]
2017-08-26 15:23:36 +03:00
5ba5f2c2d4 split utility.hpp header
[SVN r17472]
2017-08-26 15:23:36 +03:00
6c1b356be1 Merge pull request #29 from morinmorin/add_doc_for_advance_and_distance
Add doc for advance and distance
2017-07-23 12:38:00 -04:00
bfcf52ace6 Add links to advance and distance 2017-07-23 23:49:30 +09:00
e2c927628c Add documentation for advance and distance 2017-07-23 23:46:26 +09:00
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
bf7d904bf8 Point links to the pages that used to be in 'more' to the site.
[SVN r43210]
2008-02-10 15:02:17 +00:00
6d0f901b2e merge trunk version (changeset/42064) to release branch
[SVN r42129]
2007-12-17 18:43:36 +00:00
efecbd0d27 don't use identifires R1 and R2: some HP-UX headers define them as macros
[SVN r42064]
2007-12-15 03:42:49 +00:00
65e229fb0d SunPro 5.9 can't detect lvalue returns
[SVN r41956]
2007-12-10 15:19:21 +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
bd5731efa9 // Add or correct comment identifying Boost library this header is associated with.
[SVN r41173]
2007-11-17 20:13:16 +00:00
a2d9e63f94 Get rid of .cvsignore files
[SVN r41107]
2007-11-15 15:20:27 +00:00
f34109aa26 Merging some of the more obvious changes from RC_1_34_0
[SVN r40714]
2007-11-03 03:25:13 +00:00
ff73538b5b Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
0f88de3d88 Update
[SVN r38519]
2007-08-08 19:09:45 +00:00
107595b76c Fix missing include
[SVN r38518]
2007-08-08 19:09:25 +00:00
1f0a885def Remove V1 Jamfiles
[SVN r38516]
2007-08-08 19:02:26 +00:00
5bf5110cdb Resolved symbol ambiguities.
[SVN r38098]
2007-06-26 19:12:52 +00:00
0b095e687f 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).


[SVN r37057]
2007-02-24 22:40:59 +00:00
c0d6dacf62 Pull all non-runtime stuff out of the USAGE clause
[SVN r37056]
2007-02-24 22:01:22 +00:00
c080ee4dcf Remove detritus
[SVN r35427]
2006-09-29 22:22:28 +00:00
9d241238f8 Fix inspection issues
[SVN r35239]
2006-09-21 02:40:19 +00:00
45f64ea8f7 Remove flotsam
[SVN r35210]
2006-09-19 16:47:36 +00:00
71abf15b60 Take advantage of BOOST_CONCEPT_USAGE for defining usage requirements:
Using this macro is better than simply defining a destructor because
usage patterns will be tested whenever associated types are accessed.


[SVN r35199]
2006-09-19 13:41:30 +00:00
7243852b0a GCC-3.3.x workarounds
[SVN r35151]
2006-09-18 02:34:18 +00:00
e7843bdea3 The previous test ran afoul of a few compilers. Let's try again.
[SVN r35126]
2006-09-15 16:40:07 +00:00
bca372da18 fix for http://tinyurl.com/kbwzm
[SVN r35102]
2006-09-13 22:36:10 +00:00
0237e49a17 fix for http://tinyurl.com/zuohe
[SVN r35101]
2006-09-13 22:24:14 +00:00
b5492bd866 Fix license text, with Thomas B's permission
[SVN r35074]
2006-09-12 22:33:29 +00:00
1fad13e34f add missing license/copyright info
[SVN r35068]
2006-09-11 22:08:18 +00:00
3355660636 Added missing 'struct'
[SVN r33960]
2006-05-07 21:00:35 +00:00
eaf9bf62d1 Strip off "Concept" suffix.
[SVN r33899]
2006-05-01 21:42:56 +00:00
9f20320f59 Change UnaryFunction -> UnaryFunc to get out of the way of the concept checking class for VC6.
[SVN r33898]
2006-05-01 20:07:13 +00:00
2cb253ed35 Throw out bogus commented-out conversion operators.
[SVN r33871]
2006-04-30 03:38:28 +00:00
230d47e93a Move difference_type from the Forward Traversal Iterator concept to
the Single Pass Traversal concept, so that input iterators are still
input iterators.  It does make sense to measure the distance between
Single Pass iterators, provided you're willing to throw away the data.


[SVN r33870]
2006-04-30 03:35:16 +00:00
e2957cfb0c use idiomatic convertibility assertions.
[SVN r33869]
2006-04-30 03:33:33 +00:00
f5b644e765 Fixes for concept checking; use destructors for checking classes, misc cleanup.
[SVN r33862]
2006-04-29 20:27:14 +00:00
28dd458088 Add missing "inline". Fixes boost-Bugs-1476219.
[SVN r33819]
2006-04-25 20:34:32 +00:00
0dbe767eec Borland workaround updated
[SVN r33719]
2006-04-17 14:23:24 +00:00
c0fc8532e7 Warning suppression for GCC (warning: declaration of 'end' shadows a member of 'this').
[SVN r33712]
2006-04-16 18:02:23 +00:00
182 changed files with 9754 additions and 2754 deletions

87
.travis.yml Normal file
View File

@ -0,0 +1,87 @@
# Copyright 2016, 2017 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"
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++
env: TOOLSET=gcc CXXSTD=03,11
- os: linux
compiler: g++-5
env: TOOLSET=gcc-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
env: TOOLSET=gcc-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: TOOLSET=gcc-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang CXXSTD=03,11,14,1z
- os: osx
compiler: clang++
env: TOOLSET=clang CXXSTD=03,11,14,1z
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
- cd ..
- git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- cp -r $TRAVIS_BUILD_DIR/* libs/iterator
- python tools/boostdep/depinst/depinst.py iterator
- ./bootstrap.sh
- ./b2 headers
script:
- ./b2 -j3 libs/iterator/test toolset=$TOOLSET cxxstd=$CXXSTD
notifications:
email:
on_success: always

43
appveyor.yml Normal file
View File

@ -0,0 +1,43 @@
# Copyright 2017 Edward Diener
# 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)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
- /feature\/.*/
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
install:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\iterator
- python tools/boostdep/depinst/depinst.py iterator
- cmd /c bootstrap
- b2 -d0 headers
build: off
test_script:
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- b2 -j3 libs/iterator/test toolset=%TOOLSET% %CXXSTD%

View File

@ -1 +0,0 @@
GNUmakefile

0
doc/BidirectionalTraversal.rst Executable file → Normal file
View File

0
doc/ForwardTraversal.rst Executable file → Normal file
View File

0
doc/GNUmakefile Executable file → Normal file
View File

0
doc/IncrementableIterator.rst Executable file → Normal file
View File

View File

@ -13,8 +13,15 @@ boostbook standalone
:
iterator
:
<xsl:param>boost.root=../../../..
<xsl:param>toc.max.depth=3
<xsl:param>toc.section.depth=3
<xsl:param>chunk.section.depth=4
<xsl:param>chunk.section.depth=2
<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 ;

0
doc/LvalueIterator.rst Executable file → Normal file
View File

0
doc/ReadableIterator.rst Executable file → Normal file
View File

0
doc/SinglePassIterator.rst Executable file → Normal file
View File

0
doc/SwappableIterator.rst Executable file → Normal file
View File

0
doc/WritableIterator.rst Executable file → Normal file
View File

75
doc/advance.rst Normal file
View File

@ -0,0 +1,75 @@
.. 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)
=======
advance
=======
``boost::iterators::advance`` is an adapted version of ``std::advance`` for
the Boost iterator traversal concepts.
Header
------
``<boost/iterator/advance.hpp>``
Synopsis
--------
::
template <typename Iterator, typename Distance>
constexpr void advance(Iterator& it, Distance n);
Description
-----------
Moves ``it`` forward by ``n`` increments
(or backward by ``|n|`` decrements if ``n`` is negative).
Requirements
------------
``Iterator`` should model Incrementable Iterator.
Preconditions
-------------
Let ``it``\ :sub:`i` be the iterator obtained by incrementing
(or decrementing if ``n`` is negative) ``it`` by *i*. All the iterators
``it``\ :sub:`i` for *i* = 0, 1, 2, ..., ``|n|`` should be valid.
If ``Iterator`` does not model Bidirectional Traversal Iterator,
``n`` should be non-negative.
Complexity
----------
If ``Iterator`` models Random Access Traversal Iterator, it takes constant time;
otherwise it takes linear time.
Notes
-----
- This function is not a customization point and is protected against
being found by argument-dependent lookup (ADL).
- This function is ``constexpr`` only in C++14 or later.
--------------------------------------------------------------------------------
| Author: Michel Morin
| Copyright |C| 2017 Michel Morin
| Distributed under the `Boost Software License, Version 1.0
<http://www.boost.org/LICENSE_1_0.txt>`_.
.. |C| unicode:: U+00A9 .. COPYRIGHT SIGN

0
doc/counting_iterator.pdf Executable file → Normal file
View File

72
doc/distance.rst Normal file
View File

@ -0,0 +1,72 @@
.. 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)
========
distance
========
``boost::iterators::distance`` is an adapted version of ``std::distance`` for
the Boost iterator traversal concepts.
Header
------
``<boost/iterator/distance.hpp>``
Synopsis
--------
::
template <typename Iterator>
constexpr typename iterator_difference<Iterator>::type
distance(Iterator first, Iterator last);
Description
-----------
Computes the (signed) distance from ``first`` to ``last``.
Requirements
------------
``Iterator`` should model Single Pass Iterator.
Preconditions
-------------
If ``Iterator`` models Random Access Traversal Iterator,
``[first, last)`` or ``[last, first)`` should be valid;
otherwise ``[first, last)`` should be valid.
Complexity
----------
If ``Iterator`` models Random Access Traversal Iterator, it takes constant time;
otherwise it takes linear time.
Notes
-----
- This function is not a customization point and is protected against
being found by argument-dependent lookup (ADL).
- This function is ``constexpr`` only in C++14 or later.
--------------------------------------------------------------------------------
| Author: Michel Morin
| Copyright |C| 2017 Michel Morin
| Distributed under the `Boost Software License, Version 1.0
<http://www.boost.org/LICENSE_1_0.txt>`_.
.. |C| unicode:: U+00A9 .. COPYRIGHT SIGN

0
doc/docutils.sty Executable file → Normal file
View File

18
doc/facade-and-adaptor.html Executable file → Normal file
View File

@ -26,7 +26,7 @@
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>
<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
committee's library working group.</td>
</tr>
@ -239,29 +239,29 @@ Iterator Concepts.</p>
<div class="section" id="iterator-concepts">
<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>
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
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
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 class="section" id="interoperability">
<h2><a class="toc-backref" href="#id19">Interoperability</a></h2>
<p>The question of iterator interoperability is poorly addressed in the
current standard. There are currently two defect reports that are
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
iterator types, but objects of these types are not required to
interoperate in comparison or subtraction expressions. This situation
is tedious in practice and out of line with the way built in types
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
conversion to an iterator type B, the iterator types are interoperable
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
fixes the issues raised in 280. It provides the desired
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
<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
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
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
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://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
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

0
doc/facade-and-adaptor.pdf Executable file → Normal file
View File

View File

@ -19,7 +19,7 @@
.. Version 1.9 of this ReStructuredText document corresponds to
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.
@ -140,7 +140,7 @@ as proposed in n1550_, since user-defined and especially adapted
iterators suffer from the well known categorization problems that are
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
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
interoperability without introducing unwanted overloads.
.. _179: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179
.. _280: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280
.. _179: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179
.. _280: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#280
Iterator Facade

0
doc/facade_iterator_category.rst Executable file → Normal file
View File

0
doc/filter_iterator.pdf Executable file → Normal file
View File

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.

0
doc/function_output_iterator.pdf Executable file → Normal file
View File

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>

48
doc/index.html Executable file → Normal file
View File

@ -3,7 +3,7 @@
<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.5: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>The Boost.Iterator Library Boost</title>
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
@ -37,7 +37,7 @@ Lab</a>, <a class="reference external" href="http://www.styleadvisor.com">Zephyr
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Abstract:</th><td class="field-body">The Boost Iterator Library contains two parts. The first
is a system of <a class="reference external" href="../../../more/generic_programming.html#concept">concepts</a> which extend the C++ standard
is a system of <a class="reference external" href="http://www.boost.org/more/generic_programming.html#concept">concepts</a> 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
@ -57,21 +57,21 @@ older Boost Iterator Adaptor Library.</td>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first"><strong>Table of Contents</strong></p>
<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="#iterator-facade-and-adaptor" id="id23">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="#iterator-utilities" id="id25">Iterator Utilities</a><ul>
<li><a class="reference internal" href="#traits" id="id26">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="#new-style-iterators" id="id23">New-Style Iterators</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="id25">Specialized Adaptors</a></li>
<li><a class="reference internal" href="#iterator-utilities" id="id26">Iterator Utilities</a><ul>
<li><a class="reference internal" href="#traits" id="id27">Traits</a></li>
<li><a class="reference internal" href="#testing-and-concept-checking" id="id28">Testing and Concept Checking</a></li>
</ul>
</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="#history" id="id29">History</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="id30">History</a></li>
</ul>
</div>
<hr class="docutils" />
<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
because they bind together two orthogonal concepts: traversal and
element access. For example, because a random access iterator is
@ -90,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>
</div>
<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
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,
@ -117,7 +117,7 @@ and accepted into the first C++ technical report; see our</p>
<p>for more details.</p>
</div>
<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
iterator templates based on the Boost <a class="reference internal" href="#iterator-facade-and-adaptor">iterator facade and adaptor</a>.</p>
<ul class="simple">
@ -125,9 +125,15 @@ iterator templates based on the Boost <a class="reference internal" href="#itera
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
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
object; each time an element is written into the dereferenced
iterator, it is passed as a parameter to the function object.</li>
<li><a class="reference external" href="generator_iterator.htm"><tt class="docutils literal"><span class="pre">generator_iterator</span></tt></a>: an input iterator wrapping a reference to a generator (nullary function object);
each time the iterator is dereferenced, the function object
is called to get the value to return. This is a more outdated analogue of <tt class="docutils literal"><span class="pre">function_input_iterator</span></tt>.</li>
<li><a class="reference external" href="indirect_iterator.html"><tt class="docutils literal"><span class="pre">indirect_iterator</span></tt></a> (<a class="reference external" href="indirect_iterator.pdf">PDF</a>): an iterator over the objects <em>pointed-to</em> by the
elements of some sequence.</li>
<li><a class="reference external" href="permutation_iterator.html"><tt class="docutils literal"><span class="pre">permutation_iterator</span></tt></a> (<a class="reference external" href="permutation_iterator.pdf">PDF</a>): an iterator over the elements of some random-access
@ -146,9 +152,9 @@ positions of heterogeneous underlying iterators.</li>
</ul>
</div>
<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">
<h2><a class="toc-backref" href="#id26">Traits</a></h2>
<h2><a class="toc-backref" href="#id27">Traits</a></h2>
<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
of pointers, smart pointers and iterators in generic code. Used
@ -162,7 +168,7 @@ testing iterator interoperability -->
<!-- comment! __ interoperable.pdf -->
</div>
<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">
<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>
@ -170,17 +176,17 @@ testing iterator interoperability -->
</div>
</div>
<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
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
design, you'll move those same core operations into the body of the
iterator class itself. If you were writing a family of iterators,
you probably wrote a <a class="reference external" href="../../../more/generic_programming.html#type_generator">type generator</a> to build the
you probably wrote a <a class="reference external" href="http://www.boost.org/more/generic_programming.html#type_generator">type generator</a> to build the
<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
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
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
@ -195,7 +201,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>
</div>
<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
pointers, which would access the pointed-to elements when
dereferenced. Naturally, being a library writer, he decided to
@ -223,7 +229,7 @@ library you see today.</p>
<table class="docutils citation" frame="void" id="cop95" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<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>
</tbody>
</table>

46
doc/index.rst Executable file → Normal file
View File

@ -43,7 +43,7 @@ __ ../../../index.htm
The components of the Boost Iterator Library replace the
older Boost Iterator Adaptor Library.
.. _concepts: ../../../more/generic_programming.html#concept
.. _concepts: http://www.boost.org/more/generic_programming.html#concept
.. contents:: **Table of Contents**
@ -115,8 +115,8 @@ __ iterator_facade.pdf
__ iterator_adaptor.pdf
Both |facade| and |adaptor| as well as many of the `specialized
adaptors`_ mentioned below have been proposed for standardization,
and accepted into the first C++ technical report; see our
adaptors`_ mentioned below have been proposed for standardization;
see our
`Standard Proposal For Iterator Facade and Adaptor`__ (PDF__)
@ -138,10 +138,18 @@ iterator templates based on the Boost `iterator facade and adaptor`_.
* |filter|_ (PDF__): an iterator over the subset of elements of some
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
iterator, it is passed as a parameter to the function object.
* |generator|_: 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. This is an outdated analogue of |function_input|_.
* |indirect|_ (PDF__): an iterator over the objects *pointed-to* by the
elements of some sequence.
@ -171,10 +179,17 @@ __ counting_iterator.pdf
.. _filter: filter_iterator.html
__ filter_iterator.pdf
.. |function| replace:: ``function_output_iterator``
.. _function: function_output_iterator.html
.. |function_input| replace:: ``function_input_iterator``
.. _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
.. |generator| replace:: ``generator_iterator``
.. _generator: generator_iterator.htm
.. |indirect| replace:: ``indirect_iterator``
.. _indirect: indirect_iterator.html
__ indirect_iterator.pdf
@ -205,6 +220,23 @@ __ zip_iterator.pdf
Iterator Utilities
====================
Operations
----------
The standard library does not handle new-style iterators properly,
because it knows nothing about the iterator traversal concepts.
The Boost.Iterator library provides implementations that fully understand
the new concepts for the two basic operations:
- |advance|_
- |distance|_
.. |advance| replace:: ``advance``
.. _advance: advance.html
.. |distance| replace:: ``distance``
.. _distance: distance.html
Traits
------
@ -271,7 +303,7 @@ over how your iterator works: you can add additional constructors,
or even override the iterator functionality provided by the
library.
.. _`type generator`: ../../../more/generic_programming.html#type_generator
.. _`type generator`: http://www.boost.org/more/generic_programming.html#type_generator
If you're looking for the old ``projection_iterator`` component,
its functionality has been merged into ``transform_iterator``: as

0
doc/indirect_iterator.pdf Executable file → Normal file
View File

0
doc/indirect_reference_ref.rst Executable file → Normal file
View File

0
doc/interoperability-revisited.rst Executable file → Normal file
View File

2
doc/issues.rst Executable file → Normal file
View File

@ -3,7 +3,7 @@
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. _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
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu

0
doc/iterator_adaptor.pdf Executable file → Normal file
View File

0
doc/iterator_adaptor_tutorial.rst Executable file → Normal file
View File

0
doc/iterator_archetypes.html Executable file → Normal file
View File

0
doc/iterator_archetypes.pdf Executable file → Normal file
View File

0
doc/iterator_archetypes.rst Executable file → Normal file
View File

0
doc/iterator_concepts.pdf Executable file → Normal file
View File

0
doc/iterator_concepts.rst Executable file → Normal file
View File

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
<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
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
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
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://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
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
@ -866,7 +866,7 @@ operator -(iterator_facade&lt;Dr1,V1,TC1,R1,D1&gt; const&amp; lhs,
<p>In this section we'll walk through the implementation of a few
iterators using <tt class="docutils literal"><span class="pre">iterator_facade</span></tt>, based around the simple
example of a linked list of polymorphic objects. This example was
inspired by a <a class="reference external" href="http://thread.gmane.org/gmane.comp.lib.boost.user/5100">posting</a> by Keith Macdonald on the <a class="reference external" href="../../../more/mailing_lists.htm#users">Boost-Users</a>
inspired by a <a class="reference external" href="http://thread.gmane.org/gmane.comp.lib.boost.user/5100">posting</a> by Keith Macdonald on the <a class="reference external" href="http://www.boost.org/more/mailing_lists.htm#users">Boost-Users</a>
mailing list.</p>
<div class="section" id="the-problem">
<h2><a class="toc-backref" href="#id32">The Problem</a></h2>

0
doc/iterator_facade.pdf Executable file → Normal file
View File

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

View File

@ -106,7 +106,7 @@ The ``iterator_category`` member of ``iterator_facade`` is
.. parsed-literal::
*iterator-category*\ (CategoryOrTraversal, value_type, reference)
*iterator-category*\ (CategoryOrTraversal, reference, value_type)
where *iterator-category* is defined as follows:

2
doc/iterator_facade_tutorial.rst Executable file → Normal file
View File

@ -8,7 +8,7 @@ example of a linked list of polymorphic objects. This example was
inspired by a `posting`__ by Keith Macdonald on the `Boost-Users`_
mailing list.
.. _`Boost-Users`: ../../../more/mailing_lists.htm#users
.. _`Boost-Users`: http://www.boost.org/more/mailing_lists.htm#users
__ http://thread.gmane.org/gmane.comp.lib.boost.user/5100

31
doc/iterator_traits.html Executable file → Normal file
View File

@ -3,11 +3,11 @@
<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.5: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
<title>Iterator Traits</title>
<meta name="author" content="David Abrahams" />
<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." />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
@ -25,7 +25,7 @@
<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>
<tr><th class="docinfo-name">Date:</th>
<td>2006-09-11</td></tr>
<td>$Date$</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams 2004.</td></tr>
</tbody>
@ -37,7 +37,7 @@
<col class="field-name" />
<col class="field-body" />
<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
MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</td>
</tr>
@ -46,15 +46,15 @@ MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#meta
<div class="section" id="overview">
<h1>Overview</h1>
<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>,
<tt class="docutils literal"><span class="pre">iterator_category</span></tt>, and <tt class="docutils literal"><span class="pre">difference_type</span></tt>. Unfortunately,
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">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
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>
</div>
<div class="section" id="summary">
<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">
template &lt;class Iterator&gt;
struct iterator_value
@ -98,21 +98,6 @@ struct iterator_category
};
</pre>
</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 class="footer">
<hr class="footer" />

0
doc/iterator_traits.pdf Executable file → Normal file
View File

21
doc/iterator_traits.rst Executable file → Normal file
View File

@ -75,24 +75,3 @@ Header ``<boost/iterator/iterator_traits.hpp>``::
detail::iterator_traits<Iterator>::iterator_category
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

0
doc/make_counting_iterator.rst Executable file → Normal file
View File

0
doc/make_filter_iterator.rst Executable file → Normal file
View File

0
doc/make_transform_iterator.rst Executable file → Normal file
View File

0
doc/make_zip_iterator.rst Executable file → Normal file
View File

34
doc/new-iter-concepts.html Executable file → Normal file
View File

@ -27,10 +27,10 @@
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>
<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
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><th class="docinfo-name">Copyright:</th>
<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>
</tr>
<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>
</tr>
<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>
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>
</tr>
</tbody>
@ -141,7 +141,7 @@ is resolved)</td>
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
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
requirements of input iterator and output iterator. This is so
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
Iterator requirements would not necessarily be a model of Readable or
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>
(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>
@ -561,10 +561,10 @@ concept if the following expressions are valid and respect the stated
semantics.</p>
<table border="1" class="docutils">
<colgroup>
<col width="32%" />
<col width="29%" />
<col width="13%" />
<col width="37%" />
<col width="27%" />
<col width="12%" />
<col width="25%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head" colspan="4">Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality
@ -598,6 +598,13 @@ relation over its domain</td>
<td><tt class="docutils literal"><span class="pre">!(a</span> <span class="pre">==</span> <span class="pre">b)</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">iterator_traits&lt;X&gt;::difference_type</span></tt></td>
<td>A signed integral type
representing the distance
between iterators</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">iterator_traversal&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="docutils literal"><span class="pre">single_pass_traversal_tag</span></tt></td>
@ -641,11 +648,6 @@ singular value.</td>
dereferenceable implies
<tt class="docutils literal"><span class="pre">++r</span> <span class="pre">==</span> <span class="pre">++s.</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">iterator_traits&lt;X&gt;::difference_type</span></tt></td>
<td>A signed integral type representing
the distance between iterators</td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">iterator_traversal&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="docutils literal"><span class="pre">forward_traversal_tag</span></tt></td>
@ -974,7 +976,7 @@ struct random_access_traversal_tag : bidirectional_traversal_tag { };
<div class="section" id="addition-to-lib-iterator-traits">
<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
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>
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>
@ -1005,7 +1007,7 @@ otherwise.</p>
</div>
<div class="section" id="footnotes">
<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
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

0
doc/new-iter-concepts.pdf Executable file → Normal file
View File

View File

@ -38,10 +38,10 @@
.. contents:: Table of Contents
.. _n1297: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html
.. _n1477: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1477.html
.. _n1531: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1531.html
.. _n1550: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1550.html
.. _n1297: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1297.html
.. _n1477: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1477.html
.. _n1531: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1531.html
.. _n1550: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1550.htm
============
Motivation
@ -76,8 +76,8 @@ requirements in the iterator categories.
| |is resolved) |
+------------------------+-----------------------------------------------------+
.. _issue 200: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200
.. _issue 299: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299
.. _issue 200: http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#200
.. _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
@ -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
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
adaptor which applies a unary function object to the dereferenced
@ -496,26 +496,30 @@ concept if the following expressions are valid and respect the stated
semantics.
+--------------------------------------------------------------------------------------------------------+
|Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality |
|Comparable) |
+--------------------------------+-----------------------------+-------------+---------------------------+
|Expression |Return Type | Operational |Assertion/ |
| | | Semantics |Pre-/Post-condition |
+================================+=============================+=============+===========================+
|``++r`` |``X&`` | |pre: ``r`` is |
| | | |dereferenceable; post: |
| | | |``r`` is dereferenceable or|
| | | |``r`` is past-the-end |
+--------------------------------+-----------------------------+-------------+---------------------------+
|``a == b`` |convertible to ``bool`` | |``==`` is an equivalence |
| | | |relation over its domain |
+--------------------------------+-----------------------------+-------------+---------------------------+
|``a != b`` |convertible to ``bool`` |``!(a == b)``| |
+--------------------------------+-----------------------------+-------------+---------------------------+
|``iterator_traversal<X>::type`` |Convertible to | | |
| |``single_pass_traversal_tag``| | |
+--------------------------------+-----------------------------+-------------+---------------------------+
+----------------------------------------------------------------------------------------------------------------+
|Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality Comparable) |
| |
+----------------------------------------+-----------------------------+-------------+---------------------------+
|Expression |Return Type | Operational |Assertion/ |
| | | Semantics |Pre-/Post-condition |
+========================================+=============================+=============+===========================+
|``++r`` |``X&`` | |pre: ``r`` is |
| | | |dereferenceable; post: |
| | | |``r`` is dereferenceable or|
| | | |``r`` is past-the-end |
+----------------------------------------+-----------------------------+-------------+---------------------------+
|``a == b`` |convertible to ``bool`` | |``==`` is an equivalence |
| | | |relation over its domain |
+----------------------------------------+-----------------------------+-------------+---------------------------+
|``a != b`` |convertible to ``bool`` |``!(a == b)``| |
+----------------------------------------+-----------------------------+-------------+---------------------------+
|``iterator_traits<X>::difference_type`` |A signed integral type | | |
| |representing the distance | | |
| |between iterators | | |
+----------------------------------------+-----------------------------+-------------+---------------------------+
|``iterator_traversal<X>::type`` |Convertible to | | |
| |``single_pass_traversal_tag``| | |
+----------------------------------------+-----------------------------+-------------+---------------------------+
.. TR1: single_pass_iterator_tag changed to
single_pass_traversal_tag for consistency
@ -541,10 +545,6 @@ valid and respect the stated semantics.
| | |dereferenceable implies |
| | |``++r == ++s.`` |
+---------------------------------------+-----------------------------------+----------------------------+
|``iterator_traits<X>::difference_type``|A signed integral type representing| |
| |the distance between iterators | |
| | | |
+---------------------------------------+-----------------------------------+----------------------------+
|``iterator_traversal<X>::type`` |Convertible to | |
| |``forward_traversal_tag`` | |
+---------------------------------------+-----------------------------------+----------------------------+
@ -791,7 +791,7 @@ The UnaryTypeTrait concept is defined in n1519_; the LWG is
considering adding the requirement that specializations are derived
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

0
doc/permutation_iterator.pdf Executable file → Normal file
View File

0
doc/pointee.html Executable file → Normal file
View File

0
doc/pointee.pdf Executable file → Normal file
View File

0
doc/pointee.rst Executable file → Normal file
View File

0
doc/pointee_ref.rst Executable file → Normal file
View File

333
doc/quickbook/adaptor.qbk Normal file
View File

@ -0,0 +1,333 @@
[section:adaptor Iterator Adaptor]
The `iterator_adaptor` class template adapts some `Base` [#base]_
type to create a new iterator. Instantiations of `iterator_adaptor`
are derived from a corresponding instantiation of `iterator_facade`
and implement the core behaviors in terms of the `Base` type. In
essence, `iterator_adaptor` merely forwards all operations to an
instance of the `Base` type, which it stores as a member.
.. [#base] The term "Base" here does not refer to a base class and is
not meant to imply the use of derivation. We have followed the lead
of the standard library, which provides a base() function to access
the underlying iterator object of a `reverse_iterator` adaptor.
The user of `iterator_adaptor` creates a class derived from an
instantiation of `iterator_adaptor` and then selectively
redefines some of the core member functions described in the
`iterator_facade` core requirements table. The `Base` type need
not meet the full requirements for an iterator; it need only
support the operations used by the core interface functions of
`iterator_adaptor` that have not been redefined in the user's
derived class.
Several of the template parameters of `iterator_adaptor` default
to `use_default`. This allows the
user to make use of a default parameter even when she wants to
specify a parameter later in the parameter list. Also, the
defaults for the corresponding associated types are somewhat
complicated, so metaprogramming is required to compute them, and
`use_default` can help to simplify the implementation. Finally,
the identity of the `use_default` type is not left unspecified
because specification helps to highlight that the `Reference`
template parameter may not always be identical to the iterator's
`reference` type, and will keep users from making mistakes based on
that assumption.
[section:adaptor_reference Reference]
[h2 Synopsis]
template <
class Derived
, class Base
, class Value = use_default
, class CategoryOrTraversal = use_default
, class Reference = use_default
, class Difference = use_default
>
class iterator_adaptor
: public iterator_facade<Derived, *V'*, *C'*, *R'*, *D'*> // see details
{
friend class iterator_core_access;
public:
iterator_adaptor();
explicit iterator_adaptor(Base const& iter);
typedef Base base_type;
Base const& base() const;
protected:
typedef iterator_adaptor iterator_adaptor\_;
Base const& base_reference() const;
Base& base_reference();
private: // Core iterator interface for iterator_facade.
typename iterator_adaptor::reference dereference() const;
template <
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;
void advance(typename iterator_adaptor::difference_type n);
void increment();
void decrement();
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
private:
Base m_iterator; // exposition only
};
__ base_parameters_
.. _requirements:
[h2 Requirements]
`static_cast<Derived*>(iterator_adaptor*)` shall be well-formed.
The `Base` argument shall be Assignable and Copy Constructible.
.. _base_parameters:
[h2 Base Class Parameters]
The *V'*, *C'*, *R'*, and *D'* parameters of the `iterator_facade`
used as a base class in the summary of `iterator_adaptor`
above are defined as follows:
[pre
*V'* = if (Value is use_default)
return iterator_traits<Base>::value_type
else
return Value
*C'* = if (CategoryOrTraversal is use_default)
return iterator_traversal<Base>::type
else
return CategoryOrTraversal
*R'* = if (Reference is use_default)
if (Value is use_default)
return iterator_traits<Base>::reference
else
return Value&
else
return Reference
*D'* = if (Difference is use_default)
return iterator_traits<Base>::difference_type
else
return Difference
]
[h2 Operations]
[h3 Public]
iterator_adaptor();
[*Requires:] The `Base` type must be Default Constructible.[br]
[*Returns:] An instance of `iterator_adaptor` with
`m_iterator` default constructed.
explicit iterator_adaptor(Base const& iter);
[*Returns:] An instance of `iterator_adaptor` with
`m_iterator` copy constructed from `iter`.
Base const& base() const;
[*Returns:] `m_iterator`
[h3 Protected]
Base const& base_reference() const;
[*Returns:] A const reference to `m_iterator`.
Base& base_reference();
[*Returns:] A non-const reference to `m_iterator`.
[h3 Private]
typename iterator_adaptor::reference dereference() const;
[*Returns:] `*m_iterator`
template <
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;
[*Returns:] `m_iterator == x.base()`
void advance(typename iterator_adaptor::difference_type n);
[*Effects:] `m_iterator += n;`
void increment();
[*Effects:] `++m_iterator;`
void decrement();
[*Effects:] `--m_iterator;`
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
[*Returns:] `y.base() - m_iterator`
[endsect]
[section:adaptor_tutorial Tutorial]
In this section we'll further refine the `node_iter` class
template we developed in the |fac_tut|_. If you haven't already
read that material, you should go back now and check it out because
we're going to pick up right where it left off.
.. |fac_tut| replace:: `iterator_facade` tutorial
.. _fac_tut: iterator_facade.html#tutorial-example
[blurb [*`node_base*` really *is* an iterator][br][br]
It's not really a very interesting iterator, since `node_base`
is an abstract class: a pointer to a `node_base` just points
at some base subobject of an instance of some other class, and
incrementing a `node_base*` moves it past this base subobject
to who-knows-where? The most we can do with that incremented
position is to compare another `node_base*` to it. In other
words, the original iterator traverses a one-element array.
]
You probably didn't think of it this way, but the `node_base*`
object that underlies `node_iterator` is itself an iterator,
just like all other pointers. If we examine that pointer closely
from an iterator perspective, we can see that it has much in common
with the `node_iterator` we're building. First, they share most
of the same associated types (`value_type`, `reference`,
`pointer`, and `difference_type`). Second, even some of the
core functionality is the same: `operator*` and `operator==` on
the `node_iterator` return the result of invoking the same
operations on the underlying pointer, via the `node_iterator`\ 's
|dereference_and_equal|_). The only real behavioral difference
between `node_base*` and `node_iterator` can be observed when
they are incremented: `node_iterator` follows the
`m_next` pointer, while `node_base*` just applies an address offset.
.. |dereference_and_equal| replace:: `dereference` and `equal` member functions
.. _dereference_and_equal: iterator_facade.html#implementing-the-core-operations
It turns out that the pattern of building an iterator on another
iterator-like type (the `Base` [#base]_ type) while modifying
just a few aspects of the underlying type's behavior is an
extremely common one, and it's the pattern addressed by
`iterator_adaptor`. Using `iterator_adaptor` is very much like
using `iterator_facade`, but because iterator_adaptor tries to
mimic as much of the `Base` type's behavior as possible, we
neither have to supply a `Value` argument, nor implement any core
behaviors other than `increment`. The implementation of
`node_iter` is thus reduced to:
template <class Value>
class node_iter
: public boost::iterator_adaptor<
node_iter<Value> // Derived
, Value* // Base
, boost::use_default // Value
, boost::forward_traversal_tag // CategoryOrTraversal
>
{
private:
struct enabler {}; // a private type avoids misuse
public:
node_iter()
: node_iter::iterator_adaptor_(0) {}
explicit node_iter(Value* p)
: node_iter::iterator_adaptor_(p) {}
template <class OtherValue>
node_iter(
node_iter<OtherValue> const& other
, typename boost::enable_if<
boost::is_convertible<OtherValue*,Value*>
, enabler
>::type = enabler()
)
: node_iter::iterator_adaptor_(other.base()) {}
private:
friend class boost::iterator_core_access;
void increment() { this->base_reference() = this->base()->next(); }
};
Note the use of `node_iter::iterator_adaptor_` here: because
`iterator_adaptor` defines a nested `iterator_adaptor_` type
that refers to itself, that gives us a convenient way to refer to
the complicated base class type of `node_iter<Value>`. [Note:
this technique is known not to work with Borland C++ 5.6.4 and
Metrowerks CodeWarrior versions prior to 9.0]
You can see an example program that exercises this version of the
node iterators
[@../example/node_iterator3.cpp `here`].
In the case of `node_iter`, it's not very compelling to pass
`boost::use_default` as `iterator_adaptor` 's `Value`
argument; we could have just passed `node_iter` 's `Value`
along to `iterator_adaptor`, and that'd even be shorter! Most
iterator class templates built with `iterator_adaptor` are
parameterized on another iterator type, rather than on its
`value_type`. For example, `boost::reverse_iterator` takes an
iterator type argument and reverses its direction of traversal,
since the original iterator and the reversed one have all the same
associated types, `iterator_adaptor` 's delegation of default
types to its `Base` saves the implementor of
`boost::reverse_iterator` from writing:
std::iterator_traits<Iterator>::*some-associated-type*
at least four times.
We urge you to review the documentation and implementations of
|reverse_iterator|_ and the other Boost `specialized iterator
adaptors`__ to get an idea of the sorts of things you can do with
`iterator_adaptor`. In particular, have a look at
|transform_iterator|_, which is perhaps the most straightforward
adaptor, and also |counting_iterator|_, which demonstrates that
`iterator_adaptor`\ 's `Base` type needn't be an iterator.
.. |reverse_iterator| replace:: `reverse_iterator`
.. _reverse_iterator: reverse_iterator.html
.. |counting_iterator| replace:: `counting_iterator`
.. _counting_iterator: counting_iterator.html
.. |transform_iterator| replace:: `transform_iterator`
.. _transform_iterator: transform_iterator.html
__ index.html#specialized-adaptors
[endsect]
[endsect]

View File

@ -0,0 +1,149 @@
[section:algorithms Algorithms]
[section:advance Function template `advance()`]
The `boost::iterators::advance` function template is an adapted version of `std::advance` for the Boost iterator [link iterator.concepts.traversal traversal concepts].
[heading Header]
<boost/iterator/advance.hpp>
[heading Synopsis]
template <typename Iterator, typename Distance>
constexpr void advance(Iterator& it, Distance n);
[heading Description]
Moves `it` forward by `n` increments (or backward by `|n|` decrements if `n` is negative).
[heading Requirements]
`Iterator` should model Incrementable Iterator.
[heading Preconditions]
Let `it`[sub `i`] be the iterator obtained by incrementing (or decrementing if `n` is negative) `it` by `i`. All the iterators `it`[sub `i`] for `i` = 0, 1, 2, ..., `|n|` should be valid.
If `Iterator` does not model [link iterator.concepts.traversal.bidirectional Bidirectional Traversal Iterator], `n` should be non-negative.
[heading Complexity]
If `Iterator` models [link iterator.concepts.traversal.random_access Random Access Traversal Iterator], it takes constant time; otherwise it takes linear time.
[heading Notes]
* This function is not a customization point and is protected against being found by argument-dependent lookup (ADL).
* This function is `constexpr` only in C++14 or later.
[heading Acknowledgements]
Contributed by Michel Morin.
[endsect]
[section:distance Function template `distance()`]
The `boost::iterators::distance` function template is an adapted version of `std::distance` for the Boost iterator [link iterator.concepts.traversal traversal concepts].
[heading Header]
<boost/iterator/distance.hpp>
[heading Synopsis]
template <typename Iterator>
constexpr typename iterator_difference<Iterator>::type
distance(Iterator first, Iterator last);
[heading Description]
Computes the (signed) distance from `first` to `last`.
[heading Requirements]
`Iterator` should model [link iterator.concepts.traversal.single_pass Single Pass Iterator].
[heading Preconditions]
If `Iterator` models [link iterator.concepts.traversal.random_access Random Access Traversal Iterator], `[first, last)` or `[last, first)` should be valid; otherwise `[first, last)` should be valid.
[heading Complexity]
If `Iterator` models [link iterator.concepts.traversal.random_access Random Access Traversal Iterator], it takes constant time; otherwise it takes linear time.
[heading Notes]
* This function is not a customization point and is protected against being found by argument-dependent lookup (ADL).
* This function is `constexpr` only in C++14 or later.
[heading Acknowledgements]
Contributed by Michel Morin.
[endsect]
[section:next_prior Function templates `next()` and `prior()`]
Certain data types, such as the C++ Standard Library's forward and bidirectional iterators, do not provide addition and subtraction via `operator+()` or `operator-()`. This means that non-modifying computation of the next or prior value requires a temporary, even though `operator++()` or `operator--()` is provided. It also means that writing code like `itr+1` inside a template restricts the iterator category to random access iterators.
The `next()` and `prior()` functions defined in `boost/next_prior.hpp` provide a simple way around these problems.
[heading Synopsis]
template <class T>
T next(T x)
{
return ++x;
}
template <class T, class Distance>
T next(T x, Distance n)
{
std::advance(x, n);
return x;
}
template <class T>
T prior(T x)
{
return --x;
}
template <class T, class Distance>
T prior(T x, Distance n)
{
std::advance(x, -n);
return x;
}
[note Function implementations above are given for exposition only. The actual implementation has the same effect for iterators, but has different properties, as documented later.]
[heading Usage]
Usage is simple:
const std::list<T>::iterator p = get_some_iterator();
const std::list<T>::iterator prev = boost::prior(p);
const std::list<T>::iterator next = boost::next(prev, 2);
The distance from the given iterator should be supplied as an absolute value. For example, the iterator four iterators prior to the given iterator `p` may be obtained by `prior(p, 4)`.
With C++11, the Standard Library provides `std::next()` and `std::prev()` function templates, which serve the same purpose. However, there are advantages to `boost::next()` and `boost::prior()`.
First, `boost::next()` and `boost::prior()` are compatible not only with iterators but with any type that provides arithmetic operators `operator++()`, `operator--()`, `operator+()`, `operator-()`, `operator+=()` or `operator-=()`. For example, this is possible:
int x = 10;
int y = boost::next(x, 5);
assert(y == 15);
Second, `boost::next()` and `boost::prior()` use [link iterator.concepts.traversal traversal categories] to select the most efficient implementation. For some kinds of iterators, such as [link iterator.specialized.transform transform iterators], the standard iterator category does not reflect the traversal category correctly and therefore `std::next()` and `std::prev()` will fall back to linear complexity.
[heading Acknowledgements]
Contributed by [@http://www.boost.org/people/dave_abrahams.htm Dave Abrahams]. Two-argument versions by Daniel Walker.
[endsect]
[endsect]

View File

@ -0,0 +1,160 @@
[section:archetypes Iterator Archetypes]
The `iterator_archetype` class constructs a minimal implementation of
one of the iterator access concepts and one of the iterator traversal concepts.
This is used for doing a compile-time check to see if a the type requirements
of a template are really enough to cover the implementation of the template.
For further information see the documentation for the |concepts|_ library.
[h2 Synopsis]
namespace iterator_archetypes
{
// Access categories
typedef /*implementation defined*/ readable_iterator_t;
typedef /*implementation defined*/ writable_iterator_t;
typedef /*implementation defined*/ readable_writable_iterator_t;
typedef /*implementation defined*/ readable_lvalue_iterator_t;
typedef /*implementation defined*/ writable_lvalue_iterator_t;
}
template <
class Value
, class AccessCategory
, class TraversalCategory
>
class iterator_archetype
{
typedef /* see below */ value_type;
typedef /* see below */ reference;
typedef /* see below */ pointer;
typedef /* see below */ difference_type;
typedef /* see below */ iterator_category;
};
[h3 Access Category Tags]
The access category types provided correspond to the following
standard iterator access concept combinations:
readable_iterator_t :=
Readable Iterator
writable_iterator_t :=
Writeable Iterator
readable_writable_iterator_t :=
Readable Iterator & Writeable Iterator & Swappable Iterator
readable_lvalue_iterator_t :=
Readable Iterator & Lvalue Iterator
writeable_lvalue_iterator_t :=
Readable Iterator & Writeable Iterator & Swappable Iterator & Lvalue Iterator
[h3 Traits]
The nested trait types are defined as follows:
if (AccessCategory == readable_iterator_t)
value_type = Value
reference = Value
pointer = Value*
else if (AccessCategory == writable_iterator_t)
value_type = void
reference = void
pointer = void
else if (AccessCategory == readable_writable_iterator_t)
value_type = Value
reference :=
A type X that is convertible to Value for which the following
expression is valid. Given an object x of type X and v of type
Value.
x = v
pointer = Value*
else if (AccessCategory == readable_lvalue_iterator_t)
value_type = Value
reference = Value const&
pointer = Value const*
else if (AccessCategory == writable_lvalue_iterator_t)
value_type = Value
reference = Value&
pointer = Value*
if ( TraversalCategory is convertible to forward_traversal_tag )
difference_type := ptrdiff_t
else
difference_type := unspecified type
iterator_category :=
A type X satisfying the following two constraints:
1. X is convertible to X1, and not to any more-derived
type, where X1 is defined by:
if (reference is a reference type
&& TraversalCategory is convertible to forward_traversal_tag)
{
if (TraversalCategory is convertible to random_access_traversal_tag)
X1 = random_access_iterator_tag
else if (TraversalCategory is convertible to bidirectional_traversal_tag)
X1 = bidirectional_iterator_tag
else
X1 = forward_iterator_tag
}
else
{
if (TraversalCategory is convertible to single_pass_traversal_tag
&& reference != void)
X1 = input_iterator_tag
else
X1 = output_iterator_tag
}
2. X is convertible to TraversalCategory
[h2 Requirements]
The `AccessCategory` argument must be one of the predefined access
category tags. The `TraversalCategory` must be one of the standard
traversal tags. The `Value` type must satisfy the requirements of
the iterator concept specified by `AccessCategory` and
`TraversalCategory` as implied by the nested traits types.
[h2 Concepts]
`iterator_archetype` models the iterator concepts specified by the
`AccessCategory` and `TraversalCategory`
arguments. `iterator_archetype` does not model any other access
concepts or any more derived traversal concepts.
[endsect]

View File

@ -0,0 +1,54 @@
[section:concept_checking Concept Checking]
The iterator concept checking classes provide a mechanism for a
template to report better error messages when a user instantiates the
template with a type that does not meet the requirements of the
template. For an introduction to using concept checking classes, see
the documentation for the _concept_check_ library.
[h2 `iterator_concepts.hpp` Synopsis]
namespace boost_concepts {
// Iterator Access Concepts
template <typename Iterator>
class ReadableIteratorConcept;
template <
typename Iterator
, typename ValueType = std::iterator_traits<Iterator>::value_type
>
class WritableIteratorConcept;
template <typename Iterator>
class SwappableIteratorConcept;
template <typename Iterator>
class LvalueIteratorConcept;
// Iterator Traversal Concepts
template <typename Iterator>
class IncrementableIteratorConcept;
template <typename Iterator>
class SinglePassIteratorConcept;
template <typename Iterator>
class ForwardTraversalConcept;
template <typename Iterator>
class BidirectionalTraversalConcept;
template <typename Iterator>
class RandomAccessTraversalConcept;
// Interoperability
template <typename Iterator, typename ConstIterator>
class InteroperableIteratorConcept;
}
[endsect]

376
doc/quickbook/concepts.qbk Normal file
View File

@ -0,0 +1,376 @@
[section:concepts Iterator Concepts]
[section:access Access]
[section:readable Readable Iterator Concept]
A class or built-in type `X` models the *Readable Iterator* concept
for value type `T` if, in addition to `X` being Assignable and
Copy Constructible, the following expressions are valid and respect
the stated semantics. `U` is the type of any specified member of
type `T`.
[table Readable Iterator Requirements (in addition to Assignable and Copy Constructible)
[
[Expression]
[Return Type]
[Note/Precondition]
]
[
[`iterator_traits<X>::value_type`]
[`T`]
[Any non-reference, non cv-qualified type]
]
[
[`*a`]
[ Convertible to `T`]
[pre: `a` is dereferenceable. If `a == b` then `*a` is equivalent to `*b`.]
]
[
[`a->m`]
[`U&`]
[pre: `(*a).m` is well-defined. Equivalent to `(*a).m`.]
]
]
[endsect]
[section:writable Writable Iterator Concept]
A class or built-in type `X` models the *Writable Iterator* concept
if, in addition to `X` being Copy Constructible, the following
expressions are valid and respect the stated semantics. Writable
Iterators have an associated *set of value types*.
[table Writable Iterator Requirements (in addition to Copy Constructible)
[
[Expression]
[Return Type]
[Precondition]
]
[
[`*a = o` ]
[]
[pre: The type of `o` is in the set of value types of `X`]
]
]
[endsect]
[section:swappable Swappable Iterator Concept]
A class or built-in type `X` models the *Swappable Iterator* concept
if, in addition to `X` being Copy Constructible, the following
expressions are valid and respect the stated semantics.
[table Swappable Iterator Requirements (in addition to Copy Constructible)
[
[Expression]
[Return Type]
[Postcondition]
]
[
[`iter_swap(a, b)`]
[`void`]
[the pointed to values are exchanged]
]
]
[blurb *Note:* An iterator that is a model of the *Readable* and *Writable Iterator* concepts
is also a model of *Swappable Iterator*. *--end note*]
[endsect]
[section:lvalue Lvalue Iterator Concept]
The *Lvalue Iterator* concept adds the requirement that the return
type of `operator*` type be a reference to the value type of the
iterator.
[table Lvalue Iterator Requirements
[
[Expression]
[Return Type]
[Note/Assertion]
]
[
[`*a` ]
[`T&` ]
[
`T` is *cv* `iterator_traits<X>::value_type` where *cv* is an optional cv-qualification.
pre: `a` is dereferenceable. If `a == b` then `*a` is equivalent to `*b`.
]
]
]
[endsect]
[endsect]
[section:traversal Traversal]
[section:incrementable Incrementable Iterator Concept]
A class or built-in type `X` models the *Incrementable Iterator*
concept if, in addition to `X` being Assignable and Copy
Constructible, the following expressions are valid and respect the
stated semantics.
[table Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible)
[
[Expression ]
[Return Type]
[Assertion/Semantics ]
]
[
[`++r` ]
[`X&` ]
[`&r == &++r`]
]
[
[`r++` ]
[`X` ]
[``
{
X tmp = r;
++r;
return tmp;
}
``]
]
[
[`iterator_traversal<X>::type`]
[Convertible to `incrementable_traversal_tag`]
[]
]
]
[endsect]
[section:single_pass Single Pass Iterator Concept]
A class or built-in type `X` models the *Single Pass Iterator*
concept if the following expressions are valid and respect the stated
semantics.
[table Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality Comparable)
[
[Expression]
[Return Type]
[Assertion/Semantics / Pre-/Post-condition]
]
[
[`++r`]
[`X&`]
[pre:[br]`r` is dereferenceable;[br]post:[br]`r` is dereferenceable or[br]`r` is past-the-end]
]
[
[`a == b`]
[convertible to `bool`]
[`==` is an equivalence relation over its domain]
]
[
[`a != b`]
[convertible to `bool`]
[`!(a == b)`]
]
[
[`iterator_traits<X>::difference_type`]
[A signed integral type representing the distance between iterators]
[]
]
[
[`iterator_traversal<X>::type`]
[Convertible to`single_pass_traversal_tag`]
[]
]
]
[endsect]
[section:forward Forward Traversal Concept]
A class or built-in type `X` models the *Forward Traversal*
concept if, in addition to `X` meeting the requirements of Default
Constructible and Single Pass Iterator, the following expressions are
valid and respect the stated semantics.
[table Forward Traversal Iterator Requirements (in addition to Default Constructible and Single Pass Iterator)
[
[Expression]
[Return Type]
[Assertion/Note]
]
[
[`X u;`]
[`X&`]
[note: `u` may have a singular value.]
]
[
[`++r`]
[`X&`]
[`r == s` and `r` is dereferenceable implies `++r == ++s.`]
]
[
[`iterator_traversal<X>::type`]
[Convertible to `forward_traversal_tag`]
[]
]
]
[endsect]
[section:bidirectional Bidirectional Traversal Concept]
A class or built-in type `X` models the *Bidirectional Traversal*
concept if, in addition to `X` meeting the requirements of Forward
Traversal Iterator, the following expressions are valid and respect
the stated semantics.
[table Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator)
[
[Expression]
[Return Type]
[Assertion/Semantics/Pre-/Post-condition]
]
[
[`--r`]
[`X&`]
[pre: there exists `s` such that `r == ++s`.[br] post: `s` is dereferenceable. `--(++r) == r`. `--r == --s` implies `r == s`. `&r == &--r`.]
]
[
[`r--`]
[convertible to `const X&`]
[``
{
X tmp = r;
--r;
return tmp;
}
``]
]
[
[`iterator_traversal<X>::type`]
[Convertible to `bidirectional_traversal_tag`]
[]
]
]
[endsect]
[section:random_access Random Access Traversal Concept]
A class or built-in type `X` models the *Random Access Traversal*
concept if the following expressions are valid and respect the stated
semantics. In the table below, `Distance` is
`iterator_traits<X>::difference_type` and `n` represents a
constant object of type `Distance`.
[table Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal)
[
[Expression]
[Return Type]
[Operational Semantics]
[Assertion/Precondition]
]
[
[`r += n`]
[ `X&`]
[``
{
Distance m = n;
if (m >= 0)
while (m--)
++r;
else
while (m++)
--r;
return r;
}
``]
[ ]
]
[
[`a + n`, `n + a`]
[`X`]
[``
{
X tmp = a;
return tmp+= n;
}
``]
[]
]
[
[`r -= n`]
[`X&`]
[`return r += -n`]
[]
]
[
[`a - n`]
[`X`]
[``
{
X tmp = a;
return tmp-= n;
}
``]
[]
]
[
[`b - a`]
[`Distance`]
[`a < b ? distance(a,b) : -distance(b,a)`]
[pre: there exists a value `n` of `Distance` such that `a + n == b`. `b == a + (b - a)`.]
]
[
[`a\[n\]`]
[convertible to T]
[`*(a + n)`]
[pre: a is a *Readable Iterator*]
]
[
[`a\[n\] = v`]
[convertible to T]
[`*(a + n) = v`]
[pre: a is a *Writable iterator*]
]
[
[`a < b`]
[convertible to `bool`]
[`b - a > 0`]
[`<` is a total ordering relation]
]
[
[`a > b`]
[convertible to `bool`]
[`b < a`]
[`>` is a total ordering relation]
]
[
[`a >= b`]
[convertible to `bool`]
[`!(a < b)`]
[]
]
[
[`a <= b`]
[convertible to `bool`]
[`!(a > b)`]
[]
]
[
[`iterator_traversal<X>::type`]
[convertible to `random_access_traversal_tag`]
[]
[]
]
]
[endsect]
[endsect]
[endsect]

View File

@ -0,0 +1,192 @@
[section:counting Counting Iterator]
A `counting_iterator` adapts an object by adding an `operator*` that
returns the current value of the object. All other iterator operations
are forwarded to the adapted object.
[h2 Example]
This example fills an array with numbers and a second array with
pointers into the first array, using `counting_iterator` for both
tasks. Finally `indirect_iterator` is used to print out the numbers
into the first array via indirection through the second array.
int N = 7;
std::vector<int> numbers;
typedef std::vector<int>::iterator n_iter;
std::copy(boost::counting_iterator<int>(0),
boost::counting_iterator<int>(N),
std::back_inserter(numbers));
std::vector<std::vector<int>::iterator> pointers;
std::copy(boost::make_counting_iterator(numbers.begin()),
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
std::cout << "indirectly printing out the numbers from 0 to "
<< N << std::endl;
std::copy(boost::make_indirect_iterator(pointers.begin()),
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
The output is:
indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6
The source code for this example can be found [@../example/counting_iterator_example.cpp here].
[h2 Reference]
[h3 Synopsis]
template <
class Incrementable
, class CategoryOrTraversal = use_default
, class Difference = use_default
>
class counting_iterator
{
public:
typedef Incrementable value_type;
typedef const Incrementable& reference;
typedef const Incrementable* pointer;
typedef /* see below */ difference_type;
typedef /* see below */ iterator_category;
counting_iterator();
counting_iterator(counting_iterator const& rhs);
explicit counting_iterator(Incrementable x);
Incrementable const& base() const;
reference operator*() const;
counting_iterator& operator++();
counting_iterator& operator--();
private:
Incrementable m_inc; // exposition
};
If the `Difference` argument is `use_default` then
`difference_type` is an unspecified signed integral
type. Otherwise `difference_type` is `Difference`.
`iterator_category` is determined according to the following
algorithm:
if (CategoryOrTraversal is not use_default)
return CategoryOrTraversal
else if (numeric_limits<Incrementable>::is_specialized)
return |iterator-category|_\ (
random_access_traversal_tag, Incrementable, const Incrementable&)
else
return |iterator-category|_\ (
iterator_traversal<Incrementable>::type,
Incrementable, const Incrementable&)
[blurb *Note:* implementers are encouraged to provide an implementation of
`operator-` and a `difference_type` that avoids overflows in
the cases where `std::numeric_limits<Incrementable>::is_specialized`
is true.]
[h3 Requirements]
The `Incrementable` argument shall be Copy Constructible and Assignable.
If `iterator_category` is convertible to `forward_iterator_tag`
or `forward_traversal_tag`, the following must be well-formed:
Incrementable i, j;
++i; // pre-increment
i == j; // operator equal
If `iterator_category` is convertible to
`bidirectional_iterator_tag` or `bidirectional_traversal_tag`,
the following expression must also be well-formed:
--i
If `iterator_category` is convertible to
`random_access_iterator_tag` or `random_access_traversal_tag`,
the following must must also be valid:
counting_iterator::difference_type n;
i += n;
n = i - j;
i < j;
[h3 Concepts]
Specializations of `counting_iterator` model Readable Lvalue
Iterator. In addition, they model the concepts corresponding to the
iterator tags to which their `iterator_category` is convertible.
Also, if `CategoryOrTraversal` is not `use_default` then
`counting_iterator` models the concept corresponding to the iterator
tag `CategoryOrTraversal`. Otherwise, if
`numeric_limits<Incrementable>::is_specialized`, then
`counting_iterator` models Random Access Traversal Iterator.
Otherwise, `counting_iterator` models the same iterator traversal
concepts modeled by `Incrementable`.
`counting_iterator<X,C1,D1>` is interoperable with
`counting_iterator<Y,C2,D2>` if and only if `X` is
interoperable with `Y`.
[h3 Operations]
In addition to the operations required by the concepts modeled by
`counting_iterator`, `counting_iterator` provides the following
operations.
counting_iterator();
[*Requires: ] `Incrementable` is Default Constructible.[br]
[*Effects: ] Default construct the member `m_inc`.
counting_iterator(counting_iterator const& rhs);
[*Effects: ] Construct member `m_inc` from `rhs.m_inc`.
explicit counting_iterator(Incrementable x);
[*Effects: ] Construct member `m_inc` from `x`.
reference operator*() const;
[*Returns: ] `m_inc`
counting_iterator& operator++();
[*Effects: ] `++m_inc`[br]
[*Returns: ] `*this`
counting_iterator& operator--();
[*Effects: ] `--m_inc`[br]
[*Returns: ] `*this`
Incrementable const& base() const;
[*Returns: ] `m_inc`
[endsect]

637
doc/quickbook/facade.qbk Normal file
View File

@ -0,0 +1,637 @@
[section:facade Iterator Facade]
While the iterator interface is rich, there is a core subset of the
interface that is necessary for all the functionality. We have
identified the following core behaviors for iterators:
* dereferencing
* incrementing
* decrementing
* equality comparison
* random-access motion
* distance measurement
In addition to the behaviors listed above, the core interface elements
include the associated types exposed through iterator traits:
`value_type`, `reference`, `difference_type`, and
`iterator_category`.
Iterator facade uses the Curiously Recurring Template
Pattern (CRTP) [Cop95]_ so that the user can specify the behavior
of `iterator_facade` in a derived class. Former designs used
policy objects to specify the behavior, but that approach was
discarded for several reasons:
1. the creation and eventual copying of the policy object may create
overhead that can be avoided with the current approach.
2. The policy object approach does not allow for custom constructors
on the created iterator types, an essential feature if
`iterator_facade` should be used in other library
implementations.
3. Without the use of CRTP, the standard requirement that an
iterator's `operator++` returns the iterator type itself
would mean that all iterators built with the library would
have to be specializations of `iterator_facade<...>`, rather
than something more descriptive like
`indirect_iterator<T*>`. Cumbersome type generator
metafunctions would be needed to build new parameterized
iterators, and a separate `iterator_adaptor` layer would be
impossible.
[h2 Usage]
The user of `iterator_facade` derives his iterator class from a
specialization of `iterator_facade` and passes the derived
iterator class as `iterator_facade`\ 's first template parameter.
The order of the other template parameters have been carefully
chosen to take advantage of useful defaults. For example, when
defining a constant lvalue iterator, the user can pass a
const-qualified version of the iterator's `value_type` as
`iterator_facade`\ 's `Value` parameter and omit the
`Reference` parameter which follows.
The derived iterator class must define member functions implementing
the iterator's core behaviors. The following table describes
expressions which are required to be valid depending on the category
of the derived iterator type. These member functions are described
briefly below and in more detail in the iterator facade
requirements.
[table Core Interface
[
[Expression]
[Effects]
]
[
[`i.dereference()`]
[Access the value referred to]
]
[
[`i.equal(j)`]
[Compare for equality with `j`]
]
[
[`i.increment()`]
[Advance by one position]
]
[
[`i.decrement()`]
[Retreat by one position]
]
[
[`i.advance(n)`]
[Advance by `n` positions]
]
[
[`i.distance_to(j)`]
[Measure the distance to `j`]
]
]
[/ .. Should we add a comment that a zero overhead implementation of iterator_facade is possible with proper inlining?]
In addition to implementing the core interface functions, an iterator
derived from `iterator_facade` typically defines several
constructors. To model any of the standard iterator concepts, the
iterator must at least have a copy constructor. Also, if the iterator
type `X` is meant to be automatically interoperate with another
iterator type `Y` (as with constant and mutable iterators) then
there must be an implicit conversion from `X` to `Y` or from `Y`
to `X` (but not both), typically implemented as a conversion
constructor. Finally, if the iterator is to model Forward Traversal
Iterator or a more-refined iterator concept, a default constructor is
required.
[h2 Iterator Core Access]
`iterator_facade` and the operator implementations need to be able
to access the core member functions in the derived class. Making the
core member functions public would expose an implementation detail to
the user. The design used here ensures that implementation details do
not appear in the public interface of the derived iterator type.
Preventing direct access to the core member functions has two
advantages. First, there is no possibility for the user to accidently
use a member function of the iterator when a member of the value_type
was intended. This has been an issue with smart pointer
implementations in the past. The second and main advantage is that
library implementers can freely exchange a hand-rolled iterator
implementation for one based on `iterator_facade` without fear of
breaking code that was accessing the public core member functions
directly.
In a naive implementation, keeping the derived class' core member
functions private would require it to grant friendship to
`iterator_facade` and each of the seven operators. In order to
reduce the burden of limiting access, `iterator_core_access` is
provided, a class that acts as a gateway to the core member functions
in the derived iterator class. The author of the derived class only
needs to grant friendship to `iterator_core_access` to make his core
member functions available to the library.
`iterator_core_access` will be typically implemented as an empty
class containing only private static member functions which invoke the
iterator core member functions. There is, however, no need to
standardize the gateway protocol. Note that even if
`iterator_core_access` used public member functions it would not
open a safety loophole, as every core member function preserves the
invariants of the iterator.
[h2 `operator[]`]
The indexing operator for a generalized iterator presents special
challenges. A random access iterator's `operator[]` is only
required to return something convertible to its `value_type`.
Requiring that it return an lvalue would rule out currently-legal
random-access iterators which hold the referenced value in a data
member (e.g. |counting|_), because `*(p+n)` is a reference
into the temporary iterator `p+n`, which is destroyed when
`operator[]` returns.
.. |counting| replace:: `counting_iterator`
Writable iterators built with `iterator_facade` implement the
semantics required by the preferred resolution to `issue 299`_ and
adopted by proposal n1550_: the result of `p[n]` is an object
convertible to the iterator's `value_type`, and `p[n] = x` is
equivalent to `*(p + n) = x` (Note: This result object may be
implemented as a proxy containing a copy of `p+n`). This approach
will work properly for any random-access iterator regardless of the
other details of its implementation. A user who knows more about
the implementation of her iterator is free to implement an
`operator[]` that returns an lvalue in the derived iterator
class; it will hide the one supplied by `iterator_facade` from
clients of her iterator.
.. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
.. _`issue 299`: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299
.. _`operator arrow`:
[h2 `operator->`]
The `reference` type of a readable iterator (and today's input
iterator) need not in fact be a reference, so long as it is
convertible to the iterator's `value_type`. When the `value_type`
is a class, however, it must still be possible to access members
through `operator->`. Therefore, an iterator whose `reference`
type is not in fact a reference must return a proxy containing a copy
of the referenced value from its `operator->`.
The return types for `iterator_facade`\ 's `operator->` and
`operator[]` are not explicitly specified. Instead, those types
are described in terms of a set of requirements, which must be
satisfied by the `iterator_facade` implementation.
.. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template
Patterns, C++ Report, February 1995, pp. 24-27.
[section:facade_reference Reference]
template <
class Derived
, class Value
, class CategoryOrTraversal
, class Reference = Value&
, class Difference = ptrdiff_t
>
class iterator_facade {
public:
typedef remove_const<Value>::type value_type;
typedef Reference reference;
typedef Value\* pointer;
typedef Difference difference_type;
typedef /* see below__ \*/ iterator_category;
reference operator\*() const;
/* see below__ \*/ operator->() const;
/* see below__ \*/ operator[](difference_type n) const;
Derived& operator++();
Derived operator++(int);
Derived& operator--();
Derived operator--(int);
Derived& operator+=(difference_type n);
Derived& operator-=(difference_type n);
Derived operator-(difference_type n) const;
protected:
typedef iterator_facade iterator_facade\_;
};
// Comparison operators
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type // exposition
operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
// Iterator difference
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
/* see below__ \*/
operator-(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
// Iterator addition
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
typename Derived::difference_type n);
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (typename Derived::difference_type n,
iterator_facade<Dr,V,TC,R,D> const&);
__ `iterator category`_
__ `operator arrow`_
__ brackets_
__ minus_
.. _`iterator category`:
The `iterator_category` member of `iterator_facade` is
.. parsed-literal::
*iterator-category*\ (CategoryOrTraversal, reference, value_type)
where *iterator-category* is defined as follows:
.. include:: facade_iterator_category.rst
The `enable_if_interoperable` template used above is for exposition
purposes. The member operators should only be in an overload set
provided the derived types `Dr1` and `Dr2` are interoperable,
meaning that at least one of the types is convertible to the other. The
`enable_if_interoperable` approach uses SFINAE to take the operators
out of the overload set when the types are not interoperable.
The operators should behave *as-if* `enable_if_interoperable`
were defined to be:
template <bool, typename> enable_if_interoperable_impl
{};
template <typename T> enable_if_interoperable_impl<true,T>
{ typedef T type; };
template<typename Dr1, typename Dr2, typename T>
struct enable_if_interoperable
: enable_if_interoperable_impl<
is_convertible<Dr1,Dr2>::value || is_convertible<Dr2,Dr1>::value
, T
>
{};
[h2 Requirements]
The following table describes the typical valid expressions on
`iterator_facade`\ 's `Derived` parameter, depending on the
iterator concept(s) it will model. The operations in the first
column must be made accessible to member functions of class
`iterator_core_access`. In addition,
`static_cast<Derived*>(iterator_facade*)` shall be well-formed.
In the table below, `F` is `iterator_facade<X,V,C,R,D>`, `a` is an
object of type `X`, `b` and `c` are objects of type `const X`,
`n` is an object of `F::difference_type`, `y` is a constant
object of a single pass iterator type interoperable with `X`, and `z`
is a constant object of a random access traversal iterator type
interoperable with `X`.
.. _`core operations`:
.. topic:: `iterator_facade` Core Operations
[table Core Operations
[
[Expression]
[Return Type]
[Assertion/Note]
[Used to implement Iterator Concept(s)]
]
[
[`c.dereference()`]
[`F::reference`]
[]
[Readable Iterator, Writable Iterator]
]
[
[`c.equal(y)`]
[convertible to bool]
[true iff `c` and `y` refer to the same position]
[Single Pass Iterator]
]
[
[`a.increment()`]
[unused]
[]
[Incrementable Iterator]
]
[
[`a.decrement()`]
[unused]
[]
[Bidirectional Traversal Iterator]
]
[
[`a.advance(n)`]
[unused]
[]
[Random Access Traversal Iterator]
]
[
[`c.distance_to(z)`]
[convertible to `F::difference_type`]
[equivalent to `distance(c, X(z))`.]
[Random Access Traversal Iterator]
]
]
[h2 Operations]
The operations in this section are described in terms of operations on
the core interface of `Derived` which may be inaccessible
(i.e. private). The implementation should access these operations
through member functions of class `iterator_core_access`.
reference operator*() const;
[*Returns:] `static_cast<Derived const*>(this)->dereference()`
operator->() const; (see below__)
__ `operator arrow`_
[*Returns:] If `reference` is a reference type, an object of type `pointer` equal to: `&static_cast<Derived const*>(this)->dereference()`
Otherwise returns an object of unspecified type such that,
`(*static_cast<Derived const*>(this))->m` is equivalent to `(w = **static_cast<Derived const*>(this),
w.m)` for some temporary object `w` of type `value_type`.
.. _brackets:
*unspecified* operator[](difference_type n) const;
[*Returns:] an object convertible to `value_type`. For constant
objects `v` of type `value_type`, and `n` of type
`difference_type`, `(*this)[n] = v` is equivalent to
`*(*this + n) = v`, and `static_cast<value_type
const&>((*this)[n])` is equivalent to
`static_cast<value_type const&>(*(*this + n))`
Derived& operator++();
[*Effects:]
static_cast<Derived*>(this)->increment();
return *static_cast<Derived*>(this);
Derived operator++(int);
[*Effects:]
Derived tmp(static_cast<Derived const*>(this));
++*this;
return tmp;
Derived& operator--();
[*Effects:]
static_cast<Derived*>(this)->decrement();
return *static_cast<Derived*>(this);
Derived operator--(int);
[*Effects:]
Derived tmp(static_cast<Derived const*>(this));
--*this;
return tmp;
Derived& operator+=(difference_type n);
[*Effects:]
static_cast<Derived*>(this)->advance(n);
return *static_cast<Derived*>(this);
Derived& operator-=(difference_type n);
[*Effects:]
static_cast<Derived*>(this)->advance(-n);
return *static_cast<Derived*>(this);
Derived operator-(difference_type n) const;
[*Effects:]
Derived tmp(static_cast<Derived const*>(this));
return tmp -= n;
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
typename Derived::difference_type n);
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (typename Derived::difference_type n,
iterator_facade<Dr,V,TC,R,D> const&);
[*Effects:]
Derived tmp(static_cast<Derived const*>(this));
return tmp += n;
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
`((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
Otherwise,
`((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
`!((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
Otherwise,
`!((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) < 0`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) <= 0`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) > 0`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) >= 0`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0`.
]
.. _minus:
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,difference>::type
operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Return Type:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
`difference` shall be
`iterator_traits<Dr1>::difference_type`.
Otherwise
`difference` shall be `iterator_traits<Dr2>::difference_type`
]
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
`-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs)`.
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)`.
]
[endsect]
[include facade_tutorial.qbk]
[endsect]

View File

@ -0,0 +1,507 @@
[section:facade_tutorial Tutorial]
In this section we'll walk through the implementation of a few
iterators using `iterator_facade`, based around the simple
example of a linked list of polymorphic objects. This example was
inspired by a
[@http://thread.gmane.org/gmane.comp.lib.boost.user/5100 `posting`]
by Keith Macdonald on the
[@http://www.boost.org/more/mailing_lists.htm#users `Boost-Users`]
mailing list.
[h2 The Problem]
Say we've written a polymorphic linked list node base class:
# include <iostream>
struct node_base
{
node_base() : m_next(0) {}
// Each node manages all of its tail nodes
virtual ~node_base() { delete m_next; }
// Access the rest of the list
node_base* next() const { return m_next; }
// print to the stream
virtual void print(std::ostream& s) const = 0;
// double the value
virtual void double_me() = 0;
void append(node_base* p)
{
if (m_next)
m_next->append(p);
else
m_next = p;
}
private:
node_base* m_next;
};
Lists can hold objects of different types by linking together
specializations of the following template:
template <class T>
struct node : node_base
{
node(T x)
: m_value(x)
{}
void print(std::ostream& s) const { s << this->m_value; }
void double_me() { m_value += m_value; }
private:
T m_value;
};
And we can print any node using the following streaming operator:
inline std::ostream& operator<<(std::ostream& s, node_base const& n)
{
n.print(s);
return s;
}
Our first challenge is to build an appropriate iterator over these
lists.
[h2 A Basic Iterator Using `iterator_facade`]
We will construct a `node_iterator` class using inheritance from
`iterator_facade` to implement most of the iterator's operations.
# include "node.hpp"
# include <boost/iterator/iterator_facade.hpp>
class node_iterator
: public boost::iterator_facade<...>
{
...
};
[h2 Template Arguments for `iterator_facade`]
`iterator_facade` has several template parameters, so we must decide
what types to use for the arguments. The parameters are `Derived`,
`Value`, `CategoryOrTraversal`, `Reference`, and `Difference`.
[h3 `Derived`]
Because `iterator_facade` is meant to be used with the CRTP
[Cop95]_ the first parameter is the iterator class name itself,
`node_iterator`.
[h3 `Value`]
The `Value` parameter determines the `node_iterator`\ 's
`value_type`. In this case, we are iterating over `node_base`
objects, so `Value` will be `node_base`.
[h3 `CategoryOrTraversal`]
Now we have to determine which `iterator traversal concept`_ our
`node_iterator` is going to model. Singly-linked lists only have
forward links, so our iterator can't can't be a `bidirectional
traversal iterator`_. Our iterator should be able to make multiple
passes over the same linked list (unlike, say, an
`istream_iterator` which consumes the stream it traverses), so it
must be a `forward traversal iterator`_. Therefore, we'll pass
`boost::forward_traversal_tag` in this position [#category]_.
.. [#category] `iterator_facade` also supports old-style category
tags, so we could have passed `std::forward_iterator_tag` here;
either way, the resulting iterator's `iterator_category` will
end up being `std::forward_iterator_tag`.
[h3 `Reference`]
The `Reference` argument becomes the type returned by
`node_iterator`\ 's dereference operation, and will also be the
same as `std::iterator_traits<node_iterator>::reference`. The
library's default for this parameter is `Value&`; since
`node_base&` is a good choice for the iterator's `reference`
type, we can omit this argument, or pass `use_default`.
[h3 `Difference`]
The `Difference` argument determines how the distance between
two `node_iterator`\ s will be measured and will also be the
same as `std::iterator_traits<node_iterator>::difference_type`.
The library's default for `Difference` is `std::ptrdiff_t`, an
appropriate type for measuring the distance between any two
addresses in memory, and one that works for almost any iterator,
so we can omit this argument, too.
The declaration of `node_iterator` will therefore look something
like:
# include "node.hpp"
# include <boost/iterator/iterator_facade.hpp>
class node_iterator
: public boost::iterator_facade<
node_iterator
, node_base
, boost::forward_traversal_tag
>
{
...
};
[h2 Constructors and Data Members]
Next we need to decide how to represent the iterator's position.
This representation will take the form of data members, so we'll
also need to write constructors to initialize them. The
`node_iterator`\ 's position is quite naturally represented using
a pointer to a `node_base`. We'll need a constructor to build an
iterator from a `node_base*`, and a default constructor to
satisfy the `forward traversal iterator`_ requirements [#default]_.
Our `node_iterator` then becomes:
# include "node.hpp"
# include <boost/iterator/iterator_facade.hpp>
class node_iterator
: public boost::iterator_facade<
node_iterator
, node_base
, boost::forward_traversal_tag
>
{
public:
node_iterator()
: m_node(0)
{}
explicit node_iterator(node_base* p)
: m_node(p)
{}
private:
...
node_base* m_node;
};
.. [#default] Technically, the C++ standard places almost no
requirements on a default-constructed iterator, so if we were
really concerned with efficiency, we could've written the
default constructor to leave `m_node` uninitialized.
[h2 Implementing the Core Operations]
The last step is to implement the `core operations`_ required by
the concepts we want our iterator to model. Referring to the
table__, we can see that the first three rows are applicable
because `node_iterator` needs to satisfy the requirements for
`readable iterator`_, `single pass iterator`_, and `incrementable
iterator`_.
__ `core operations`_
We therefore need to supply `dereference`,
`equal`, and `increment` members. We don't want these members
to become part of `node_iterator`\ 's public interface, so we can
make them private and grant friendship to
`boost::iterator_core_access`, a "back-door" that
`iterator_facade` uses to get access to the core operations:
# include "node.hpp"
# include <boost/iterator/iterator_facade.hpp>
class node_iterator
: public boost::iterator_facade<
node_iterator
, node_base
, boost::forward_traversal_tag
>
{
public:
node_iterator()
: m_node(0) {}
explicit node_iterator(node_base* p)
: m_node(p) {}
private:
friend class boost::iterator_core_access;
void increment() { m_node = m_node->next(); }
bool equal(node_iterator const& other) const
{
return this->m_node == other.m_node;
}
node_base& dereference() const { return *m_node; }
node_base* m_node;
};
Voila; a complete and conforming readable, forward-traversal
iterator! For a working example of its use, see
[@../example/node_iterator1.cpp `this program`].
__ ../example/node_iterator1.cpp
[h2 A constant `node_iterator`]
[blurb *Constant and Mutable iterators*[br][br]
The term **mutable iterator** means an iterator through which
the object it references (its "referent") can be modified. A
**constant iterator** is one which doesn't allow modification of
its referent.[br][br]
The words *constant* and *mutable* don't refer to the ability to
modify the iterator itself. For example, an `int const*` is a
non-\ `const` *constant iterator*, which can be incremented
but doesn't allow modification of its referent, and `int*
const` is a `const` *mutable iterator*, which cannot be
modified but which allows modification of its referent.[br][br]
Confusing? We agree, but those are the standard terms. It
probably doesn't help much that a container's constant iterator
is called `const_iterator`.
]
Now, our `node_iterator` gives clients access to both `node`\
's `print(std::ostream&) const` member function, but also its
mutating `double_me()` member. If we wanted to build a
*constant* `node_iterator`, we'd only have to make three
changes:
class const_node_iterator
: public boost::iterator_facade<
const_node_iterator
, node_base **const**
, boost::forward_traversal_tag
>
{
public:
const_node_iterator()
: m_node(0) {}
explicit const_node_iterator(node_base* p)
: m_node(p) {}
private:
friend class boost::iterator_core_access;
void increment() { m_node = m_node->next(); }
bool equal(const_node_iterator const& other) const
{
return this->m_node == other.m_node;
}
node_base **const**\ & dereference() const { return \*m_node; }
node_base **const**\ * m_node;
};
[blurb `const` and an iterator's `value_type`[br][br]
The C++ standard requires an iterator's `value_type` *not* be
`const`\ -qualified, so `iterator_facade` strips the
`const` from its `Value` parameter in order to produce the
iterator's `value_type`. Making the `Value` argument
`const` provides a useful hint to `iterator_facade` that the
iterator is a *constant iterator*, and the default `Reference`
argument will be correct for all lvalue iterators.
]
As a matter of fact, `node_iterator` and `const_node_iterator`
are so similar that it makes sense to factor the common code out
into a template as follows:
template <class Value>
class node_iter
: public boost::iterator_facade<
node_iter<Value>
, Value
, boost::forward_traversal_tag
>
{
public:
node_iter()
: m_node(0) {}
explicit node_iter(Value* p)
: m_node(p) {}
private:
friend class boost::iterator_core_access;
bool equal(node_iter<Value> const& other) const
{
return this->m_node == other.m_node;
}
void increment()
{ m_node = m_node->next(); }
Value& dereference() const
{ return *m_node; }
Value* m_node;
};
typedef node_iter<node_base> node_iterator;
typedef node_iter<node_base const> node_const_iterator;
[h2 Interoperability]
Our `const_node_iterator` works perfectly well on its own, but
taken together with `node_iterator` it doesn't quite meet
expectations. For example, we'd like to be able to pass a
`node_iterator` where a `node_const_iterator` was expected,
just as you can with `std::list<int>`\ 's `iterator` and
`const_iterator`. Furthermore, given a `node_iterator` and a
`node_const_iterator` into the same list, we should be able to
compare them for equality.
This expected ability to use two different iterator types together
is known as |interoperability|_. Achieving interoperability in
our case is as simple as templatizing the `equal` function and
adding a templatized converting constructor [#broken]_ [#random]_:
template <class Value>
class node_iter
: public boost::iterator_facade<
node_iter<Value>
, Value
, boost::forward_traversal_tag
>
{
public:
node_iter()
: m_node(0) {}
explicit node_iter(Value* p)
: m_node(p) {}
template <class OtherValue>
node_iter(node_iter<OtherValue> const& other)
: m_node(other.m_node) {}
private:
friend class boost::iterator_core_access;
template <class> friend class node_iter;
template <class OtherValue>
bool equal(node_iter<OtherValue> const& other) const
{
return this->m_node == other.m_node;
}
void increment()
{ m_node = m_node->next(); }
Value& dereference() const
{ return *m_node; }
Value* m_node;
};
typedef impl::node_iterator<node_base> node_iterator;
typedef impl::node_iterator<node_base const> node_const_iterator;
.. |interoperability| replace:: **interoperability**
.. _interoperability: new-iter-concepts.html#interoperable-iterators-lib-interoperable-iterators
.. [#broken] If you're using an older compiler and it can't handle
this example, see the `example code`__ for workarounds.
.. [#random] If `node_iterator` had been a `random access
traversal iterator`_, we'd have had to templatize its
`distance_to` function as well.
__ ../example/node_iterator2.hpp
You can see an example program which exercises our interoperable
iterators
[@../example/node_iterator2.cpp `here`].
[h2 Telling the Truth]
Now `node_iterator` and `node_const_iterator` behave exactly as
you'd expect... almost. We can compare them and we can convert in
one direction: from `node_iterator` to `node_const_iterator`.
If we try to convert from `node_const_iterator` to
`node_iterator`, we'll get an error when the converting
constructor tries to initialize `node_iterator`\ 's `m_node`, a
`node*` with a `node const*`. So what's the problem?
The problem is that
`boost::`\ |is_convertible|_\ `<node_const_iterator,node_iterator>::value`
will be `true`, but it should be `false`. |is_convertible|_
lies because it can only see as far as the *declaration* of
`node_iter`\ 's converting constructor, but can't look inside at
the *definition* to make sure it will compile. A perfect solution
would make `node_iter`\ 's converting constructor disappear when
the `m_node` conversion would fail.
.. |is_convertible| replace:: `is_convertible`
.. _is_convertible: ../../type_traits/index.html#relationships
In fact, that sort of magic is possible using
|enable_if|__. By rewriting the converting constructor as
follows, we can remove it from the overload set when it's not
appropriate:
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
...
private:
struct enabler {};
public:
template <class OtherValue>
node_iter(
node_iter<OtherValue> const& other
, typename boost::enable_if<
boost::is_convertible<OtherValue*,Value*>
, enabler
>::type = enabler()
)
: m_node(other.m_node) {}
.. |enable_if| replace:: `boost::enable_if`
__ ../../utility/enable_if.html
[h2 Wrap Up]
This concludes our `iterator_facade` tutorial, but before you
stop reading we urge you to take a look at |iterator_adaptor|__.
There's another way to approach writing these iterators which might
even be superior.
.. |iterator_adaptor| replace:: `iterator_adaptor`
__ iterator_adaptor.html
.. _`iterator traversal concept`: new-iter-concepts.html#iterator-traversal-concepts-lib-iterator-traversal
.. _`readable iterator`: new-iter-concepts.html#readable-iterators-lib-readable-iterators
.. _`lvalue iterator`: new-iter-concepts.html#lvalue-iterators-lib-lvalue-iterators
.. _`single pass iterator`: new-iter-concepts.html#single-pass-iterators-lib-single-pass-iterators
.. _`incrementable iterator`: new-iter-concepts.html#incrementable-iterators-lib-incrementable-iterators
.. _`forward traversal iterator`: new-iter-concepts.html#forward-traversal-iterators-lib-forward-traversal-iterators
.. _`bidirectional traversal iterator`: new-iter-concepts.html#bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators
.. _`random access traversal iterator`: new-iter-concepts.html#random-access-traversal-iterators-lib-random-access-traversal-iterators
[endsect]

View File

@ -0,0 +1,242 @@
[section:filter Filter Iterator]
The filter iterator adaptor creates a view of an iterator range in
which some elements of the range are skipped. A predicate function
object controls which elements are skipped. When the predicate is
applied to an element, if it returns `true` then the element is
retained and if it returns `false` then the element is skipped
over. When skipping over elements, it is necessary for the filter
adaptor to know when to stop so as to avoid going past the end of the
underlying range. A filter iterator is therefore constructed with pair
of iterators indicating the range of elements in the unfiltered
sequence to be traversed.
[h2 Example]
This example uses `filter_iterator` and then
`make_filter_iterator` to output only the positive integers from an
array of integers. Then `make_filter_iterator` is is used to output
the integers greater than `-2`.
struct is_positive_number {
bool operator()(int x) { return 0 < x; }
};
int main()
{
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
const int N = sizeof(numbers_)/sizeof(int);
typedef int* base_iterator;
base_iterator numbers(numbers_);
// Example using filter_iterator
typedef boost::filter_iterator<is_positive_number, base_iterator>
FilterIter;
is_positive_number predicate;
FilterIter filter_iter_first(predicate, numbers, numbers + N);
FilterIter filter_iter_last(predicate, numbers + N, numbers + N);
std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// Example using make_filter_iterator()
std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// Another example using make_filter_iterator()
std::copy(
boost::make_filter_iterator(
std::bind2nd(std::greater<int>(), -2)
, numbers, numbers + N)
, boost::make_filter_iterator(
std::bind2nd(std::greater<int>(), -2)
, numbers + N, numbers + N)
, std::ostream_iterator<int>(std::cout, " ")
);
std::cout << std::endl;
return boost::exit_success;
}
The output is:
4 5 8
4 5 8
0 -1 4 5 8
The source code for this example can be found [@../example/filter_iterator_example.cpp here].
[h2 Reference]
[h3 Synopsis]
template <class Predicate, class Iterator>
class filter_iterator
{
public:
typedef iterator_traits<Iterator>::value_type value_type;
typedef iterator_traits<Iterator>::reference reference;
typedef iterator_traits<Iterator>::pointer pointer;
typedef iterator_traits<Iterator>::difference_type difference_type;
typedef /* see below */ iterator_category;
filter_iterator();
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
filter_iterator(Iterator x, Iterator end = Iterator());
template<class OtherIterator>
filter_iterator(
filter_iterator<Predicate, OtherIterator> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
Predicate predicate() const;
Iterator end() const;
Iterator const& base() const;
reference operator*() const;
filter_iterator& operator++();
private:
Predicate m_pred; // exposition only
Iterator m_iter; // exposition only
Iterator m_end; // exposition only
};
If `Iterator` models Readable Lvalue Iterator and Bidirectional Traversal
Iterator then `iterator_category` is convertible to
`std::bidirectional_iterator_tag`.
Otherwise, if `Iterator` models Readable Lvalue Iterator and Forward Traversal
Iterator then `iterator_category` is convertible to
`std::forward_iterator_tag`.
Otherwise `iterator_category` is
convertible to `std::input_iterator_tag`.
[h3 Requirements]
The `Iterator` argument shall meet the requirements of Readable
Iterator and Single Pass Iterator or it shall meet the requirements of
Input Iterator.
The `Predicate` argument must be Assignable, Copy Constructible, and
the expression `p(x)` must be valid where `p` is an object of type
`Predicate`, `x` is an object of type
`iterator_traits<Iterator>::value_type`, and where the type of
`p(x)` must be convertible to `bool`.
[h3 Concepts]
The concepts that `filter_iterator` models are dependent on which
concepts the `Iterator` argument models, as specified in the
following tables.
[table Traversal
[[If `Iterator` models ][then `filter_iterator` models ]]
[[Single Pass Iterator ][Single Pass Iterator ]]
[[Forward Traversal Iterator ][Forward Traversal Iterator ]]
[[Bidirectional Traversal Iterator ][Bidirectional Traversal Iterator]]
]
[table Access
[[If `Iterator` models ][then `filter_iterator` models ]]
[[Readable Iterator][Readable Iterator]]
[[Writable Iterator][Writable Iterator]]
[[Lvalue Iterator ][Lvalue Iterator ]]
]
[table C++03
[[If `Iterator` models ][then `filter_iterator` models ]]
[[Readable Iterator, Single Pass Iterator ][Input Iterator ]]
[[Readable Lvalue Iterator, Forward Traversal Iterator][Forward Iterator ]]
[[Writable Lvalue Iterator, Forward Traversal Iterator][Mutable Forward Iterator ]]
[[Writable Lvalue Iterator, Bidirectional Iterator ][Mutable Bidirectional Iterator]]
]
`filter_iterator<P1, X>` is interoperable with `filter_iterator<P2, Y>`
if and only if `X` is interoperable with `Y`.
[h3 Operations]
In addition to those operations required by the concepts that
`filter_iterator` models, `filter_iterator` provides the following
operations.
filter_iterator();
[*Requires: ]`Predicate` and `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs a `filter_iterator` whose`m_pred`, `m_iter`, and `m_end`
members are a default constructed.
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
the first position in the range `[x,end)` such that `f(*m_iter) == true`
or else`m_iter == end`. The member `m_pred` is constructed from
`f` and `m_end` from `end`.
filter_iterator(Iterator x, Iterator end = Iterator());
[*Requires: ] `Predicate` must be Default Constructible and
`Predicate` is a class type (not a function pointer).[br]
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
the first position in the range `[x,end)` such that `m_pred(*m_iter) == true`
or else`m_iter == end`. The member `m_pred` is default constructed.
template <class OtherIterator>
filter_iterator(
filter_iterator<Predicate, OtherIterator> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs a filter iterator whose members are copied from `t`.
Predicate predicate() const;
[*Returns: ] `m_pred`
Ierator end() const;
[*Returns: ] `m_end`
Iterator const& base() const;
[*Returns: ] `m_iterator`
reference operator*() const;
[*Returns: ] `*m_iter`
filter_iterator& operator++();
[*Effects: ] Increments `m_iter` and then continues to
increment `m_iter` until either `m_iter == m_end`
or `m_pred(*m_iter) == true`.[br]
[*Returns: ] `*this`
[endsect]

View File

@ -0,0 +1,100 @@
[section:function_output Function Output Iterator]
The function output iterator adaptor makes it easier to create custom
output iterators. The adaptor takes a unary function and creates a
model of Output Iterator. Each item assigned to the output iterator is
passed as an argument to the unary function. The motivation for this
iterator is that creating a conforming output iterator is non-trivial,
particularly because the proper implementation usually requires a
proxy object.
[h2 Example]
struct string_appender
{
string_appender(std::string& s)
: m_str(&s)
{}
void operator()(const std::string& x) const
{
*m_str += x;
}
std::string* m_str;
};
int main(int, char*[])
{
std::vector<std::string> x;
x.push_back("hello");
x.push_back(" ");
x.push_back("world");
x.push_back("!");
std::string s = "";
std::copy(x.begin(), x.end(),
boost::make_function_output_iterator(string_appender(s)));
std::cout << s << std::endl;
return 0;
}
[h2 Reference]
[h3 Synopsis]
template <class UnaryFunction>
class function_output_iterator {
public:
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit function_output_iterator();
explicit function_output_iterator(const UnaryFunction& f);
/* see below */ operator*();
function_output_iterator& operator++();
function_output_iterator& operator++(int);
private:
UnaryFunction m_f; // exposition only
};
[h3 Requirements]
`UnaryFunction` must be Assignable and Copy Constructible.
[h3 Concepts]
`function_output_iterator` is a model of the Writable and
Incrementable Iterator concepts.
[h3 Operations]
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
[*Effects: ] Constructs an instance of `function_output_iterator`
with `m_f` constructed from `f`.
unspecified_type operator*();
[*Returns: ] An object `r` of unspecified type such that `r = t`
is equivalent to `m_f(t)` for all `t`.
function_output_iterator& operator++();
[*Returns: ] `*this`.
function_output_iterator& operator++(int);
[*Returns: ] `*this`.
[endsect]

View File

@ -0,0 +1,254 @@
[section:indirect Indirect Iterator]
`indirect_iterator` adapts an iterator by applying an
*extra* dereference inside of `operator*()`. For example, this
iterator adaptor makes it possible to view a container of pointers
(e.g. `list<foo*>`) as if it were a container of the pointed-to type
(e.g. `list<foo>`). `indirect_iterator` depends on two
auxiliary traits, `pointee` and `indirect_reference`, to
provide support for underlying iterators whose `value_type` is
not an iterator.
[h2 Example]
This example prints an array of characters, using
`indirect_iterator` to access the array of characters through an
array of pointers. Next `indirect_iterator` is used with the
`transform` algorithm to copy the characters (incremented by one) to
another array. A constant indirect iterator is used for the source and
a mutable indirect iterator is used for the destination. The last part
of the example prints the original array of characters, but this time
using the `make_indirect_iterator` helper function.
char characters[] = "abcdefg";
const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
char* pointers_to_chars[N]; // at the end.
for (int i = 0; i < N; ++i)
pointers_to_chars[i] = &characters[i];
// Example of using indirect_iterator
boost::indirect_iterator<char**, char>
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
// Example of making mutable and constant indirect iterators
char mutable_characters[N];
char* pointers_to_mutable_chars[N];
for (int j = 0; j < N; ++j)
pointers_to_mutable_chars[j] = &mutable_characters[j];
boost::indirect_iterator<char* const*> mutable_indirect_first(pointers_to_mutable_chars),
mutable_indirect_last(pointers_to_mutable_chars + N);
boost::indirect_iterator<char* const*, char const> const_indirect_first(pointers_to_chars),
const_indirect_last(pointers_to_chars + N);
std::transform(const_indirect_first, const_indirect_last,
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
std::copy(mutable_indirect_first, mutable_indirect_last,
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
// Example of using make_indirect_iterator()
std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
The output is:
a,b,c,d,e,f,g,
b,c,d,e,f,g,h,
a,b,c,d,e,f,g,
The source code for this example can be found
[@../example/indirect_iterator_example.cpp here].
[h2 Reference]
[h3 Synopsis]
template <
class Iterator
, class Value = use_default
, class CategoryOrTraversal = use_default
, class Reference = use_default
, class Difference = use_default
>
class indirect_iterator
{
public:
typedef /* see below */ value_type;
typedef /* see below */ reference;
typedef /* see below */ pointer;
typedef /* see below */ difference_type;
typedef /* see below */ iterator_category;
indirect_iterator();
indirect_iterator(Iterator x);
template <
class Iterator2, class Value2, class Category2
, class Reference2, class Difference2
>
indirect_iterator(
indirect_iterator<
Iterator2, Value2, Category2, Reference2, Difference2
> const& y
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);
Iterator const& base() const;
reference operator*() const;
indirect_iterator& operator++();
indirect_iterator& operator--();
private:
Iterator m_iterator; // exposition
};
The member types of `indirect_iterator` are defined according to
the following pseudo-code, where `V` is
`iterator_traits<Iterator>::value_type`
[pre
if (Value is use_default) then
typedef remove_const<pointee<V>::type>::type value_type;
else
typedef remove_const<Value>::type value_type;
if (Reference is use_default) then
if (Value is use_default) then
typedef indirect_reference<V>::type reference;
else
typedef Value& reference;
else
typedef Reference reference;
if (Value is use_default) then
typedef pointee<V>::type\* pointer;
else
typedef Value\* pointer;
if (Difference is use_default)
typedef iterator_traits<Iterator>::difference_type difference_type;
else
typedef Difference difference_type;
if (CategoryOrTraversal is use_default)
typedef *iterator-category* (
iterator_traversal<Iterator>::type,`reference`,`value_type`
) iterator_category;
else
typedef *iterator-category* (
CategoryOrTraversal,`reference`,`value_type`
) iterator_category;
]
[h3 Requirements]
The expression `*v`, where `v` is an object of
`iterator_traits<Iterator>::value_type`, shall be valid
expression and convertible to `reference`. `Iterator` shall
model the traversal concept indicated by `iterator_category`.
`Value`, `Reference`, and `Difference` shall be chosen so
that `value_type`, `reference`, and `difference_type` meet
the requirements indicated by `iterator_category`.
[blurb Note: there are further requirements on the
`iterator_traits<Iterator>::value_type` if the `Value`
parameter is not `use_default`, as implied by the algorithm for
deducing the default for the `value_type` member.]
[h3 Concepts]
In addition to the concepts indicated by `iterator_category`
and by `iterator_traversal<indirect_iterator>::type`, a
specialization of `indirect_iterator` models the following
concepts, Where `v` is an object of
`iterator_traits<Iterator>::value_type`:
Readable Iterator if `reference(*v)` is convertible to
`value_type`.
Writable Iterator if `reference(*v) = t` is a valid
expression (where `t` is an object of type
`indirect_iterator::value_type`)
Lvalue Iterator if `reference` is a reference type.
`indirect_iterator<X,V1,C1,R1,D1>` is interoperable with
`indirect_iterator<Y,V2,C2,R2,D2>` if and only if `X` is
interoperable with `Y`.
[h3 Operations]
In addition to the operations required by the concepts described
above, specializations of `indirect_iterator` provide the
following operations:
indirect_iterator();
[*Requires: ] `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs an instance of `indirect_iterator` with
a default-constructed `m_iterator`.
indirect_iterator(Iterator x);
[*Effects: ] Constructs an instance of `indirect_iterator` with
`m_iterator` copy constructed from `x`.
template <
class Iterator2, class Value2, unsigned Access, class Traversal
, class Reference2, class Difference2
>
indirect_iterator(
indirect_iterator<
Iterator2, Value2, Access, Traversal, Reference2, Difference2
> const& y
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);
[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs an instance of `indirect_iterator` whose
`m_iterator` subobject is constructed from `y.base()`.
Iterator const& base() const;
[*Returns: ] `m_iterator`
reference operator*() const;
[*Returns: ] `**m_iterator`
indirect_iterator& operator++();
[*Effects: ] `++m_iterator`[br]
[*Returns: ] `*this`
indirect_iterator& operator--();
[*Effects: ] `--m_iterator`[br]
[*Returns: ] `*this`
[endsect]

308
doc/quickbook/iterator.qbk Normal file
View File

@ -0,0 +1,308 @@
[library Boost.Iterator
[/ version 1.0.1]
[quickbook 1.6]
[authors [Abrahams, David], [Siek, Jeremy], [Witt, Thomas]]
[copyright 2003 2005 David Abrahams Jeremy Siek Thomas Witt]
[category iterator]
[id iterator]
[dirname iterator]
[purpose
]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
<ulink url="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt
</ulink>)
]
]
[/ QuickBook Document version 1.0 ]
[/ Images ]
[def _note_ [$images/note.png]]
[def _alert_ [$images/caution.png]]
[def _detail_ [$images/note.png]]
[def _tip_ [$images/tip.png]]
[/ Links ]
[def _iterator_ [@../../../iterator/doc/index.html Boost.Iterator]]
[def _concept_check_ [@../../../concept_check/index.html Boost.ConceptCheck]]
[template sub[x]'''<subscript>'''[x]'''</subscript>''']
[section:intro Introduction]
[def _concepts_ [@http://www.boost.org/more/generic_programming.html#concept concepts]]
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. The extended iterator concepts have been
carefully designed so that old-style iterators
can fit in the new concepts and so that new-style
iterators will be compatible with old-style algorithms,
though algorithms may need to be updated if they want to
take full advantage of the new-style iterator
capabilities. Several components of this library have
been accepted into the C++ standard technical report.
The components of the Boost Iterator Library replace the
older Boost Iterator Adaptor Library.
[h2 New-Style Iterators]
[def _N1185_ [@http://www.gotw.ca/publications/N1185.pdf N1185]]
[def _N1211_ [@http://www.gotw.ca/publications/N1211.pdf N1211]]
[def _GOTW_50_ [@http://www.gotw.ca/gotw/050.htm Guru of the Week]]
The iterator categories defined in C++98 are extremely limiting
because they bind together two orthogonal concepts: traversal and
element access. For example, because a random access iterator is
required to return a reference (and not a proxy) when dereferenced,
it is impossible to capture the capabilities of
`vector<bool>::iterator` using the C++98 categories. This is the
infamous "`vector<bool>` is not a container, and its iterators
aren't random access iterators", debacle about which Herb Sutter
wrote two papers for the standards comittee (_N1185_ and _N1211_),
and a _GOTW_50_. New-style iterators go well beyond
patching up `vector<bool>`, though: there are lots of other
iterators already in use which can't be adequately represented by
the existing concepts. For details about the new iterator
concepts, see our [@../new-iter-concepts.html Standard Proposal for New-Style Iterators].
[h2 Iterator Facade and Adaptor]
[/
[def _facade_ [link iterator.generic.facade facade]]
[def _adaptor_ [link iterator.generic.adaptor adaptor]]
]
[def _facade_ [@../iterator_facade.html facade]]
[def _adaptor_ [@../iterator_adaptor.html adaptor]]
Writing standard-conforming iterators is tricky, but the need comes
up often. In order to ease the implementation of new iterators,
the Boost.Iterator library provides the _facade_ class template,
which implements many useful defaults and compile-time checks
designed to help the iterator author ensure that his iterator is
correct.
It is also common to define a new iterator that is similar to some
underlying iterator or iterator-like type, but that modifies some
aspect of the underlying type's behavior. For that purpose, the
library supplies the _adaptor_ class template, which is specially
designed to take advantage of as much of the underlying type's
behavior as possible.
Both _facade_ and _adaptor_ as well as many of the [link iterator.specialized specialized
adaptors] mentioned below have been proposed for standardization
([@../facade-and-adaptor.html Standard Proposal For Iterator Facade and Adaptor]).
[h2 Specialized Adaptors]
The iterator library supplies a useful suite of standard-conforming
iterator templates based on the Boost [link
iterator.intro.iterator_facade_and_adaptor iterator facade and adaptor]
templates.
[def _counting_ [link iterator.specialized.counting `counting_iterator`]]
[def _filter_ [link iterator.specialized.filter `filter_iterator`]]
[def _function_input_ [@../function_input_iterator.html `function_input_iterator`]]
[def _function_output_ [link iterator.specialized.function_output `function_output_iterator`]]
[def _generator_ [@../generator_iterator.htm `generator_iterator`]]
[def _indirect_ [link iterator.specialized.indirect `indirect_iterator`]]
[def _permutation_ [link iterator.specialized.permutation `permutation_iterator`]]
[def _reverse_ [link iterator.specialized.reverse `reverse_iterator`]]
[def _shared_ [link iterator.specialized.shared_container `shared_container_iterator`]]
[def _transform_ [link iterator.specialized.transform `transform_iterator`]]
[def _zip_ [link iterator.specialized.zip `zip_iterator`]]
[def _shared_ptr_ [@../../smart_ptr/shared_ptr.htm `shared_ptr`]]
* _counting_: an iterator over a sequence of consecutive values.
Implements a "lazy sequence"
* _filter_: an iterator over the subset of elements of some
sequence which satisfy a given predicate
* _function_input_: 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_: an output iterator wrapping a unary function
object; each time an element is written into the dereferenced
iterator, it is passed as a parameter to the function object.
* _generator_: 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. An outdated analogue of _function_input_.
* _indirect_: an iterator over the objects *pointed-to* by the
elements of some sequence.
* _permutation_: an iterator over the elements of some random-access
sequence, rearranged according to some sequence of integer indices.
* _reverse_: an iterator which traverses the elements of some
bidirectional sequence in reverse. Corrects many of the
shortcomings of C++98's `std::reverse_iterator`.
* _shared_: an iterator over elements of a container whose
lifetime is maintained by a _shared_ptr_ stored in the iterator.
* _transform_: an iterator over elements which are the result of
applying some functional transformation to the elements of an
underlying sequence. This component also replaces the old
`projection_iterator_adaptor`.
* _zip_: an iterator over tuples of the elements at corresponding
positions of heterogeneous underlying iterators.
[h2 Iterator Utilities]
[h3 Traits]
[def _pointee_ [link iterator.utilities.traits `pointee.hpp`]]
[def _iterator_traits_ [link iterator.utilities.iterator_traits `iterator_traits.hpp`]]
[def _interoperable_ [@../interoperable.html `interoperable.hpp`]]
[def _MPL_ [@../../mpl/doc/index.html [*MPL]]]
* _pointee_: Provides the capability to deduce the referent types
of pointers, smart pointers and iterators in generic code. Used
in _indirect_.
* _iterator_traits_: Provides _MPL_ compatible metafunctions which
retrieve an iterator's traits. Also corrects for the deficiencies
of broken implementations of `std::iterator_traits`.
[/
* _interoperable_: Provides an _MPL_ compatible metafunction for
testing iterator interoperability
]
[h3 Testing and Concept Checking]
[def _iterator_concepts_ [link iterator.concepts `iterator_concepts.hpp`]]
[def _iterator_archetypes_ [link iterator.utilities.archetypes `iterator_archetypes.hpp`]]
* _iterator_concepts_: Concept checking classes for the new iterator concepts.
* _iterator_archetypes_: Concept archetype classes for the new iterators concepts.
[h2 Iterator Algorithms]
The library provides a number of generic algorithms for use with iterators. These
algorithms take advantage of the new concepts defined by the library to provide
better performance and functionality.
[def _advance_ [link iterator.algorithms.advance `advance.hpp`]]
[def _distance_ [link iterator.algorithms.distance `distance.hpp`]]
[def _next_prior_ [link iterator.algorithms.next_prior `next_prior.hpp`]]
* _advance_: Provides `advance()` function for advancing an iterator a given number
of positions forward or backward.
* _distance_: Provides `distance()` function for computing distance between two
iterators.
* _next_prior_: Provides `next()` and `prior()` functions for obtaining
next and prior iterators to a given iterator. The functions are also compatible
with non-iterator types.
[endsect]
[include concepts.qbk]
[section:generic Generic Iterators]
[include facade.qbk]
[include adaptor.qbk]
[endsect]
[include specialized_adaptors.qbk]
[section:utilities Utilities]
[include archetypes.qbk]
[include concept_checking.qbk]
[include iterator_traits.qbk]
[include type_traits.qbk]
[endsect]
[include algorithms.qbk]
[section:upgrading Upgrading from the old Boost Iterator Adaptor Library]
[def _type_generator_ [@http://www.boost.org/more/generic_programming.html#type_generator type generator]]
If you have been using the old Boost Iterator Adaptor library to
implement iterators, you probably wrote a `Policies` class which
captures the core operations of your iterator. In the new library
design, you'll move those same core operations into the body of the
iterator class itself. If you were writing a family of iterators,
you probably wrote a _type_generator_ to build the
`iterator_adaptor` specialization you needed; in the new library
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
use of the Curiously Recurring Template Pattern (CRTP) [Cop95]_,
you can now define the iterator class yourself and acquire
functionality through inheritance from `iterator_facade` or
`iterator_adaptor`. As a result, you also get much finer control
over how your iterator works: you can add additional constructors,
or even override the iterator functionality provided by the
library.
If you're looking for the old `projection_iterator` component,
its functionality has been merged into _transform_iterator_: as
long as the function object's `result_type` (or the `Reference`
template argument, if explicitly specified) is a true reference
type, _transform_iterator_ will behave like
`projection_iterator` used to.
[endsect]
[section:history History]
In 2000 Dave Abrahams was writing an iterator for a container of
pointers, which would access the pointed-to elements when
dereferenced. Naturally, being a library writer, he decided to
generalize the idea and the Boost Iterator Adaptor library was born.
Dave was inspired by some writings of Andrei Alexandrescu and chose a
policy based design (though he probably didn't capture Andrei's idea
very well - there was only one policy class for all the iterator's
orthogonal properties). Soon Jeremy Siek realized he would need the
library and they worked together to produce a "Boostified" version,
which was reviewed and accepted into the library. They wrote a paper
and made several important revisions of the code.
Eventually, several shortcomings of the older library began to make
the need for a rewrite apparent. Dave and Jeremy started working
at the Santa Cruz C++ committee meeting in 2002, and had quickly
generated a working prototype. At the urging of Mat Marcus, they
decided to use the GenVoca/CRTP pattern approach, and moved the
policies into the iterator class itself. Thomas Witt expressed
interest and became the voice of strict compile-time checking for
the project, adding uses of the SFINAE technique to eliminate false
converting constructors and operators from the overload set. He
also recognized the need for a separate `iterator_facade`, and
factored it out of `iterator_adaptor`. Finally, after a
near-complete rewrite of the prototype, they came up with the
library you see today.
[:\[Coplien, 1995\] Coplien, J., Curiously Recurring Template
Patterns, C++ Report, February 1995, pp. 24-27.]
[endsect]

View File

@ -0,0 +1,55 @@
[section:iterator_traits Iterator Traits]
`std::iterator_traits` provides access to five associated types
of any iterator: its `value_type`, `reference`, `pointer`,
`iterator_category`, and `difference_type`. Unfortunately,
such a "multi-valued" traits template can be difficult to use in a
metaprogramming context. `<boost/iterator/iterator_traits.hpp>`
provides access to these types using a standard metafunctions_.
[h2 Synopsis]
Header `<boost/iterator/iterator_traits.hpp>`:
template <class Iterator>
struct iterator_value
{
typedef typename
std::iterator_traits<Iterator>::value_type
type;
};
template <class Iterator>
struct iterator_reference
{
typedef typename
std::iterator_traits<Iterator>::reference
type;
};
template <class Iterator>
struct iterator_pointer
{
typedef typename
std::iterator_traits<Iterator>::pointer
type;
};
template <class Iterator>
struct iterator_difference
{
typedef typename
detail::iterator_traits<Iterator>::difference_type
type;
};
template <class Iterator>
struct iterator_category
{
typedef typename
detail::iterator_traits<Iterator>::iterator_category
type;
};
[endsect]

View File

@ -0,0 +1,207 @@
[section:permutation Permutation Iterator]
The permutation iterator adaptor provides a permuted view of a given
range. That is, the view includes every element of the given range but
in a potentially different order. The adaptor takes two arguments:
* an iterator to the range V on which the permutation
will be applied
* the reindexing scheme that defines how the
elements of V will be permuted.
Note that the permutation iterator is not limited to strict
permutations of the given range V. The distance between begin and end
of the reindexing iterators is allowed to be smaller compared to the
size of the range V, in which case the permutation iterator only
provides a permutation of a subrange of V. The indexes neither need
to be unique. In this same context, it must be noted that the past the
end permutation iterator is completely defined by means of the
past-the-end iterator to the indices.
[h2 Example]
using namespace boost;
int i = 0;
typedef std::vector< int > element_range_type;
typedef std::list< int > index_type;
static const int element_range_size = 10;
static const int index_size = 4;
element_range_type elements( element_range_size );
for(element_range_type::iterator el_it = elements.begin() ; el_it != elements.end() ; ++el_it)
*el_it = std::distance(elements.begin(), el_it);
index_type indices( index_size );
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
*i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
std::reverse( indices.begin(), indices.end() );
typedef permutation_iterator< element_range_type::iterator, index_type::iterator > permutation_type;
permutation_type begin = make_permutation_iterator( elements.begin(), indices.begin() );
permutation_type it = begin;
permutation_type end = make_permutation_iterator( elements.begin(), indices.end() );
std::cout << "The original range is : ";
std::copy( elements.begin(), elements.end(), std::ostream_iterator< int >( std::cout, " " ) );
std::cout << "\n";
std::cout << "The reindexing scheme is : ";
std::copy( indices.begin(), indices.end(), std::ostream_iterator< int >( std::cout, " " ) );
std::cout << "\n";
std::cout << "The permutated range is : ";
std::copy( begin, end, std::ostream_iterator< int >( std::cout, " " ) );
std::cout << "\n";
std::cout << "Elements at even indices in the permutation : ";
it = begin;
for(i = 0; i < index_size / 2 ; ++i, it+=2 ) std::cout << *it << " ";
std::cout << "\n";
std::cout << "Permutation backwards : ";
it = begin + (index_size);
assert( it != begin );
for( ; it-- != begin ; ) std::cout << *it << " ";
std::cout << "\n";
std::cout << "Iterate backward with stride 2 : ";
it = begin + (index_size - 1);
for(i = 0 ; i < index_size / 2 ; ++i, it-=2 ) std::cout << *it << " ";
std::cout << "\n";
The output is:
The original range is : 0 1 2 3 4 5 6 7 8 9
The reindexing scheme is : 9 8 7 6
The permutated range is : 9 8 7 6
Elements at even indices in the permutation : 9 7
Permutation backwards : 6 7 8 9
Iterate backward with stride 2 : 6 8
The source code for this example can be found
[@../example/permutation_iter_example.cpp here].
[h2 Reference]
[h3 Synopsis]
template< class ElementIterator
, class IndexIterator
, class ValueT = use_default
, class CategoryT = use_default
, class ReferenceT = use_default
, class DifferenceT = use_default >
class permutation_iterator
{
public:
permutation_iterator();
explicit permutation_iterator(ElementIterator x, IndexIterator y);
template< class OEIter, class OIIter, class V, class C, class R, class D >
permutation_iterator(
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
);
reference operator*() const;
permutation_iterator& operator++();
ElementIterator const& base() const;
private:
ElementIterator m_elt; // exposition only
IndexIterator m_order; // exposition only
};
template <class ElementIterator, class IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator( ElementIterator e, IndexIterator i);
[h3 Requirements]
`ElementIterator` shall model Random Access Traversal Iterator.
`IndexIterator` shall model Readable Iterator. The value type of
the `IndexIterator` must be convertible to the difference type of
`ElementIterator`.
[h3 Concepts]
`permutation_iterator` models the same iterator traversal concepts
as `IndexIterator` and the same iterator access concepts as
`ElementIterator`.
If `IndexIterator` models Single Pass Iterator and
`ElementIterator` models Readable Iterator then
`permutation_iterator` models Input Iterator.
If `IndexIterator` models Forward Traversal Iterator and
`ElementIterator` models Readable Lvalue Iterator then
`permutation_iterator` models Forward Iterator.
If `IndexIterator` models Bidirectional Traversal Iterator and
`ElementIterator` models Readable Lvalue Iterator then
`permutation_iterator` models Bidirectional Iterator.
If `IndexIterator` models Random Access Traversal Iterator and
`ElementIterator` models Readable Lvalue Iterator then
`permutation_iterator` models Random Access Iterator.
`permutation_iterator<E1, X, V1, C2, R1, D1>` is interoperable
with `permutation_iterator<E2, Y, V2, C2, R2, D2>` if and only if
`X` is interoperable with `Y` and `E1` is convertible
to `E2`.
[h3 Operations]
In addition to those operations required by the concepts that
`permutation_iterator` models, `permutation_iterator` provides the
following operations.
permutation_iterator();
[*Effects: ] Default constructs `m_elt` and `m_order`.
explicit permutation_iterator(ElementIterator x, IndexIterator y);
[*Effects: ] Constructs `m_elt` from `x` and `m_order` from `y`.
template< class OEIter, class OIIter, class V, class C, class R, class D >
permutation_iterator(
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
);
[*Effects: ] Constructs `m_elt` from `r.m_elt` and
`m_order` from `y.m_order`.
reference operator*() const;
[*Returns: ] `*(m_elt + *m_order)`
permutation_iterator& operator++();
[*Effects: ] `++m_order`[br]
[*Returns: ] `*this`
ElementIterator const& base() const;
[*Returns: ] `m_order`
template <class ElementIterator, class IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator(ElementIterator e, IndexIterator i);
[*Returns: ] `permutation_iterator<ElementIterator, IndexIterator>(e, i)`
[endsect]

View File

@ -0,0 +1,160 @@
[section:reverse Reverse Iterator]
The reverse iterator adaptor iterates through the adapted iterator
range in the opposite direction.
[h2 Example]
The following example prints an array of characters in reverse order
using `reverse_iterator`.
char letters_[] = "hello world!";
const int N = sizeof(letters_)/sizeof(char) - 1;
typedef char* base_iterator;
base_iterator letters(letters_);
std::cout << "original sequence of letters:\t\t\t" << letters_ << std::endl;
boost::reverse_iterator<base_iterator>
reverse_letters_first(letters + N),
reverse_letters_last(letters);
std::cout << "sequence in reverse order:\t\t\t";
std::copy(reverse_letters_first, reverse_letters_last,
std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
std::cout << "sequence in double-reversed (normal) order:\t";
std::copy(boost::make_reverse_iterator(reverse_letters_last),
boost::make_reverse_iterator(reverse_letters_first),
std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
The output is:
original sequence of letters: hello world!
sequence in reverse order: !dlrow olleh
sequence in double-reversed (normal) order: hello world!
The source code for this example can be found
[@../example/reverse_iterator_example.cpp here].
[h2 Reference]
[h3 Synopsis]
template <class Iterator>
class reverse_iterator
{
public:
typedef iterator_traits<Iterator>::value_type value_type;
typedef iterator_traits<Iterator>::reference reference;
typedef iterator_traits<Iterator>::pointer pointer;
typedef iterator_traits<Iterator>::difference_type difference_type;
typedef /* see below */ iterator_category;
reverse_iterator() {}
explicit reverse_iterator(Iterator x) ;
template<class OtherIterator>
reverse_iterator(
reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
Iterator const& base() const;
reference operator*() const;
reverse_iterator& operator++();
reverse_iterator& operator--();
private:
Iterator m_iterator; // exposition
};
If `Iterator` models Random Access Traversal Iterator and Readable
Lvalue Iterator, then `iterator_category` is convertible to
`random_access_iterator_tag`. Otherwise, if
`Iterator` models Bidirectional Traversal Iterator and Readable
Lvalue Iterator, then `iterator_category` is convertible to
`bidirectional_iterator_tag`. Otherwise, `iterator_category` is
convertible to `input_iterator_tag`.
[h3 Requirements]
`Iterator` must be a model of Bidirectional Traversal Iterator. The
type `iterator_traits<Iterator>::reference` must be the type of
`*i`, where `i` is an object of type `Iterator`.
[h3 Concepts]
A specialization of `reverse_iterator` models the same iterator
traversal and iterator access concepts modeled by its `Iterator`
argument. In addition, it may model old iterator concepts
specified in the following table:
[table Categories
[[If `I` models ][then `reverse_iterator<I>` models]]
[[Readable Lvalue Iterator, Bidirectional Traversal Iterator][Bidirectional Iterator]]
[[Writable Lvalue Iterator, Bidirectional Traversal Iterator][Mutable Bidirectional Iterator]]
[[Readable Lvalue Iterator, Random Access Traversal Iterator][Random Access Iterator]]
[[Writable Lvalue Iterator, Random Access Traversal Iterator][Mutable Random Access Iterator]]
]
`reverse_iterator<X>` is interoperable with
`reverse_iterator<Y>` if and only if `X` is interoperable with
`Y`.
[h3 Operations]
In addition to the operations required by the concepts modeled by
`reverse_iterator`, `reverse_iterator` provides the following
operations.
reverse_iterator();
[*Requires: ] `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator`
default constructed.
explicit reverse_iterator(Iterator x);
[*Effects: ] Constructs an instance of `reverse_iterator` with
`m_iterator` copy constructed from `x`.
template<class OtherIterator>
reverse_iterator(
reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs instance of `reverse_iterator` whose
`m_iterator` subobject is constructed from `y.base()`.
Iterator const& base() const;
[*Returns: ] `m_iterator`
reference operator*() const;
[*Effects: ] Iterator tmp = m_iterator; return *--tmp;
reverse_iterator& operator++();
[*Effects: ] `--m_iterator`[br]
[*Returns: ] `*this`
reverse_iterator& operator--();
[*Effects: ] `++m_iterator`[br]
[*Returns: ] `*this`
[endsect]

View File

@ -0,0 +1,248 @@
[section:shared_container Shared Container Iterator]
Defined in header [@../../../boost/shared_container_iterator.hpp `boost/shared_container_iterator.hpp`].
The purpose of the shared container iterator is to attach the lifetime
of a container to the lifetime of its iterators. In other words, the
container will not be deleted until after all its iterators are
destroyed. The shared container iterator is typically used to
implement functions that return iterators over a range of objects that
only need to exist for the lifetime of the iterators. By returning a
pair of shared iterators from a function, the callee can return a
heap-allocated range of objects whose lifetime is automatically
managed.
The shared container iterator augments an iterator over a shared
container. It maintains a reference count on the shared container. If
only shared container iterators hold references to the container, the
container's lifetime will end when the last shared container iterator
over it is destroyed. In any case, the shared container is guaranteed
to persist beyond the lifetime of all the iterators. In all other
ways, the shared container iterator behaves the same as its base
iterator.
[h2 Synopsis]
namespace boost {
template <typename Container>
class shared_container_iterator;
template <typename Container>
shared_container_iterator<Container>
make_shared_container_iterator(typename Container::iterator base,
boost::shared_ptr<Container> const& container);
std::pair<
typename shared_container_iterator<Container>,
typename shared_container_iterator<Container>
>
make_shared_container_range(boost::shared_ptr<Container> const& container);
}
[section:shared_container_type The Shared Container Iterator Type]
template <typename Container> class shared_container_iterator;
The class template `shared_container_iterator` is the shared container
iterator type. The `Container` template type argument must model the
[@http://www.sgi.com/tech/stl/Container.html Container] concept.
[h2 Example]
The following example illustrates how to create an iterator that
regulates the lifetime of a reference counted `std::vector`. Though the
original shared pointer `ints` ceases to exist after `set_range()`
returns, the `shared_counter_iterator` objects maintain references to
the underlying vector and thereby extend the container's lifetime.
[@../../example/shared_iterator_example1.cpp `shared_iterator_example1.cpp`]:
#include "shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <algorithm>
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
void set_range(iterator& i, iterator& end) {
boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
i = iterator(ints->begin(),ints);
end = iterator(ints->end(),ints);
}
int main() {
iterator i,end;
set_range(i,end);
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}
The output from this part is:
0,1,2,3,4,5,
[table Template Parameters
[[Parameter][Description]]
[[Container][The type of the container that we wish to iterate over. It must be a model of the Container concept.]]
]
[h2 Concepts]
The `shared_container_iterator` type models the same iterator concept
as the base iterator (`Container::iterator`).
[h2 Operations]
The `shared_container_iterator` type implements the member functions
and operators required of the
[@http://www.sgi.com/tech/stl/RandomAccessIterator.html Random Access
Iterator] concept, though only operations defined for the base
iterator will be valid. In addition it has the following constructor:
shared_container_iterator(Container::iterator const& it,
boost::shared_ptr<Container> const& container)
[endsect]
[section:shared_container_object_generator The Shared Container Iterator Object Generator]
template <typename Container>
shared_container_iterator<Container>
make_shared_container_iterator(Container::iterator base,
boost::shared_ptr<Container> const& container)
This function provides an alternative to directly constructing a
`shared_container_iterator`. Using the object generator, a
`shared_container_iterator` can be created and passed to a function without
explicitly specifying its type.
[h2 Example]
This example, similar to the previous,
uses `make_shared_container_iterator()` to create the iterators.
[@../../example/shared_iterator_example2.cpp `shared_iterator_example2.cpp`]:
#include "shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
template <typename Iterator>
void print_range_nl (Iterator begin, Iterator end) {
typedef typename std::iterator_traits<Iterator>::value_type val;
std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
std::cout.put('\n');
}
int main() {
typedef boost::shared_ptr< std::vector<int> > ints_t;
{
ints_t ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
boost::make_shared_container_iterator(ints->end(),ints));
}
return 0;
}
Observe that the `shared_container_iterator` type is never explicitly
named. The output from this example is the same as the previous.
[endsect]
[section:shared_container_generator The Shared Container Iterator Range Generator]
template <typename Container>
std::pair<
shared_container_iterator<Container>,
shared_container_iterator<Container>
>
make_shared_container_range(boost::shared_ptr<Container> const& container);
Class shared_container_iterator is meant primarily to return, using iterators, a range of values that we can guarantee will be alive as long as the iterators are. This is a convenience function to do just that. It is equivalent to
std::make_pair(make_shared_container_iterator(container->begin(),container),
make_shared_container_iterator(container->end(),container));
[h2 Example]
In the following example, a range of values is returned as a pair of shared_container_iterator objects.
[@../../example/shared_iterator_example3.cpp `shared_iterator_example3.cpp`]:
#include "shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/tuple/tuple.hpp" // for boost::tie
#include <algorithm> // for std::copy
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
std::pair<iterator,iterator>
return_range() {
boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
range->push_back(0);
range->push_back(1);
range->push_back(2);
range->push_back(3);
range->push_back(4);
range->push_back(5);
return boost::make_shared_container_range(range);
}
int main() {
iterator i,end;
boost::tie(i,end) = return_range();
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}
Though the range object only lives for the duration of the
`return_range` call, the reference counted `std::vector` will live
until `i` and `end` are both destroyed. The output from this example is
the same as the previous two.
[endsect]
[endsect]

View File

@ -0,0 +1,22 @@
[section:specialized Specialized Adaptors]
[include ./counting_iterator.qbk]
[include ./filter_iterator.qbk]
[include ./function_output_iterator.qbk]
[include ./indirect_iterator.qbk]
[include ./permutation_iterator.qbk]
[include ./reverse_iterator.qbk]
[include ./shared_container_iterator.qbk]
[include ./transform_iterator.qbk]
[include ./zip_iterator.qbk]
[endsect]

View File

@ -0,0 +1,216 @@
[section:transform Transform Iterator]
The transform iterator adapts an iterator by modifying the
`operator*` to apply a function object to the result of
dereferencing the iterator and returning the result.
[h2 Example]
This is a simple example of using the transform_iterators class to
generate iterators that multiply (or add to) the value returned by
dereferencing the iterator. It would be cooler to use lambda library
in this example.
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
const int N = sizeof(x)/sizeof(int);
typedef boost::binder1st< std::multiplies<int> > Function;
typedef boost::transform_iterator<Function, int*> doubling_iterator;
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
std::cout << "multiplying the array by 2:" << std::endl;
while (i != i_end)
std::cout << *i++ << " ";
std::cout << std::endl;
std::cout << "adding 4 to each element in the array:" << std::endl;
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
The output is:
multiplying the array by 2:
2 4 6 8 10 12 14 16
adding 4 to each element in the array:
5 6 7 8 9 10 11 12
The source code for this example can be found
[@../example/transform_iterator_example.cpp here].
[h2 Reference]
[h3 Synopsis]
template <class UnaryFunction,
class Iterator,
class Reference = use_default,
class Value = use_default>
class transform_iterator
{
public:
typedef /* see below */ value_type;
typedef /* see below */ reference;
typedef /* see below */ pointer;
typedef iterator_traits<Iterator>::difference_type difference_type;
typedef /* see below */ iterator_category;
transform_iterator();
transform_iterator(Iterator const& x, UnaryFunction f);
template<class F2, class I2, class R2, class V2>
transform_iterator(
transform_iterator<F2, I2, R2, V2> const& t
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
, typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
);
UnaryFunction functor() const;
Iterator const& base() const;
reference operator*() const;
transform_iterator& operator++();
transform_iterator& operator--();
private:
Iterator m_iterator; // exposition only
UnaryFunction m_f; // exposition only
};
If `Reference` is `use_default` then the `reference` member of
`transform_iterator` is[br]
`result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
Otherwise, `reference` is `Reference`.
If `Value` is `use_default` then the `value_type` member is
`remove_cv<remove_reference<reference> >::type`. Otherwise,
`value_type` is `Value`.
If `Iterator` models Readable Lvalue Iterator and if `Iterator`
models Random Access Traversal Iterator, then `iterator_category` is
convertible to `random_access_iterator_tag`. Otherwise, if
`Iterator` models Bidirectional Traversal Iterator, then
`iterator_category` is convertible to
`bidirectional_iterator_tag`. Otherwise `iterator_category` is
convertible to `forward_iterator_tag`. If `Iterator` does not
model Readable Lvalue Iterator then `iterator_category` is
convertible to `input_iterator_tag`.
[h3 Requirements]
The type `UnaryFunction` must be Assignable, Copy Constructible, and
the expression `f(*i)` must be valid where `f` is a const object of
type `UnaryFunction`, `i` is an object of type `Iterator`, and
where the type of `f(*i)` must be
`result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
The argument `Iterator` shall model Readable Iterator.
[h3 Concepts]
The resulting `transform_iterator` models the most refined of the
following that is also modeled by `Iterator`.
* Writable Lvalue Iterator if `transform_iterator::reference` is a non-const reference.
* Readable Lvalue Iterator if `transform_iterator::reference` is a const reference.
* Readable Iterator otherwise.
The `transform_iterator` models the most refined standard traversal
concept that is modeled by the `Iterator` argument.
If `transform_iterator` is a model of Readable Lvalue Iterator then
it models the following original iterator concepts depending on what
the `Iterator` argument models.
[table Category
[[If `Iterator` models][then `transform_iterator` models]]
[[Single Pass Iterator][Input Iterator]]
[[Forward Traversal Iterator][Forward Iterator]]
[[Bidirectional Traversal Iterator][Bidirectional Iterator]]
[[Random Access Traversal Iterator][Random Access Iterator]]
]
If `transform_iterator` models Writable Lvalue Iterator then it is a
mutable iterator (as defined in the old iterator requirements).
`transform_iterator<F1, X, R1, V1>` is interoperable with
`transform_iterator<F2, Y, R2, V2>` if and only if `X` is
interoperable with `Y`.
[h3 Operations]
In addition to the operations required by the [link iterator.specialized.transform.concepts concepts] modeled by
`transform_iterator`, `transform_iterator` provides the following
operations:
transform_iterator();
[*Returns: ] An instance of `transform_iterator` with `m_f`
and `m_iterator` default constructed.
transform_iterator(Iterator const& x, UnaryFunction f);
[*Returns: ] An instance of `transform_iterator` with `m_f`
initialized to `f` and `m_iterator` initialized to `x`.
template<class F2, class I2, class R2, class V2>
transform_iterator(
transform_iterator<F2, I2, R2, V2> const& t
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
, typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
);
[*Returns: ] An instance of `transform_iterator` with `m_f`
initialized to `t.functor()` and `m_iterator` initialized to
`t.base()`.[br]
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.
UnaryFunction functor() const;
[*Returns: ] `m_f`
Iterator const& base() const;
[*Returns: ] `m_iterator`
reference operator*() const;
[*Returns: ] `m_f(*m_iterator)`
transform_iterator& operator++();
[*Effects: ] `++m_iterator`[br]
[*Returns: ] `*this`
transform_iterator& operator--();
[*Effects: ] `--m_iterator`[br]
[*Returns: ] `*this`
[endsect]

View File

@ -0,0 +1,211 @@
[section:traits Type Traits]
[h2 Overview]
Have you ever wanted to write a generic function that can operate
on any kind of dereferenceable object? If you have, you've
probably run into the problem of how to determine the type that the
object "points at":
template <class Dereferenceable>
void f(Dereferenceable p)
{
*what-goes-here?* value = \*p;
...
}
[h2 `pointee`]
It turns out to be impossible to come up with a fully-general
algorithm to do determine *what-goes-here* directly, but it is
possible to require that `pointee<Dereferenceable>::type` is
correct. Naturally, `pointee` has the same difficulty: it can't
determine the appropriate `::type` reliably for all
`Dereferenceable`\ s, but it makes very good guesses (it works
for all pointers, standard and boost smart pointers, and
iterators), and when it guesses wrongly, it can be specialized as
necessary:
namespace boost
{
template <class T>
struct pointee<third_party_lib::smart_pointer<T> >
{
typedef T type;
};
}
[h2 `indirect_reference`]
`indirect_reference<T>::type` is rather more specialized than
`pointee`, and is meant to be used to forward the result of
dereferencing an object of its argument type. Most dereferenceable
types just return a reference to their pointee, but some return
proxy references or return the pointee by value. When that
information is needed, call on `indirect_reference`.
Both of these templates are essential to the correct functioning of
[link 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]
[h3 `pointee`]
template <class Dereferenceable>
struct pointee
{
typedef /* see below */ type;
};
[*Requires:] For an object `x` of type `Dereferenceable`, `*x`
is well-formed. If `++x` is ill-formed it shall neither be
ambiguous nor shall it violate access control, and
`Dereferenceable::element_type` shall be an accessible type.
Otherwise `iterator_traits<Dereferenceable>::value_type` shall
be well formed. \[Note: These requirements need not apply to
explicit or partial specializations of `pointee`\]
`type` is determined according to the following algorithm, where
`x` is an object of type `Dereferenceable`:
if ( ++x is ill-formed )
{
return Dereferenceable::element_type
}
else if (*x is a mutable reference to
std::iterator_traits<Dereferenceable>::value_type)
{
return iterator_traits<Dereferenceable>::value_type
}
else
{
return iterator_traits<Dereferenceable>::value_type const
}
[h3 `indirect_reference`]
template <class Dereferenceable>
struct indirect_reference
{
typedef /* see below */ type;
};
[*Requires:] For an object `x` of type `Dereferenceable`, `*x`
is well-formed. If `++x` is ill-formed it shall neither be
ambiguous nor shall it violate access control, and
`pointee<Dereferenceable>::type&` shall be well-formed.
Otherwise `iterator_traits<Dereferenceable>::reference` shall
be well formed. \[Note: These requirements need not apply to
explicit or partial specializations of `indirect_reference`\]
`type` is determined according to the following algorithm, where
`x` is an object of type `Dereferenceable`:
if ( ++x is ill-formed )
return pointee<Dereferenceable>::type&
else
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]

View File

@ -0,0 +1,266 @@
[section:zip Zip Iterator]
The zip iterator provides the ability to parallel-iterate
over several controlled sequences simultaneously. A zip
iterator is constructed from a tuple of iterators. Moving
the zip iterator moves all the iterators in parallel.
Dereferencing the zip iterator returns a tuple that contains
the results of dereferencing the individual iterators.
The tuple of iterators is now implemented in terms of a Boost fusion sequence.
Because of this the 'tuple' may be any Boost fusion sequence and, for backwards
compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
Boost fusion adapter exists. This includes, among others, a std::tuple and a std::pair.
Just remember to include the appropriate Boost fusion adapter header files for these
other Boost fusion adapters. The zip_iterator header file already includes the
Boost fusion adapter header file for Boost tuple, so you need not include it yourself
to use a Boost tuple as your 'tuple'.
[section:zip_example Example]
There are two main types of applications of the `zip_iterator`. The first
one concerns runtime efficiency: If one has several controlled sequences
of the same length that must be somehow processed, e.g., with the
`for_each` algorithm, then it is more efficient to perform just
one parallel-iteration rather than several individual iterations. For an
example, assume that `vect_of_doubles` and `vect_of_ints`
are two vectors of equal length containing doubles and ints, respectively,
and consider the following two iterations:
std::vector<double>::const_iterator beg1 = vect_of_doubles.begin();
std::vector<double>::const_iterator end1 = vect_of_doubles.end();
std::vector<int>::const_iterator beg2 = vect_of_ints.begin();
std::vector<int>::const_iterator end2 = vect_of_ints.end();
std::for_each(beg1, end1, func_0());
std::for_each(beg2, end2, func_1());
These two iterations can now be replaced with a single one as follows:
std::for_each(
boost::make_zip_iterator(
boost::make_tuple(beg1, beg2)
),
boost::make_zip_iterator(
boost::make_tuple(end1, end2)
),
zip_func()
);
A non-generic implementation of `zip_func` could look as follows:
struct zip_func :
public std::unary_function<const boost::tuple<const double&, const int&>&, void>
{
void operator()(const boost::tuple<const double&, const int&>& t) const
{
m_f0(t.get<0>());
m_f1(t.get<1>());
}
private:
func_0 m_f0;
func_1 m_f1;
};
The second important application of the `zip_iterator` is as a building block
to make combining iterators. A combining iterator is an iterator
that parallel-iterates over several controlled sequences and, upon
dereferencing, returns the result of applying a functor to the values of the
sequences at the respective positions. This can now be achieved by using the
`zip_iterator` in conjunction with the `transform_iterator`.
Suppose, for example, that you have two vectors of doubles, say
`vect_1` and `vect_2`, and you need to expose to a client
a controlled sequence containing the products of the elements of
`vect_1` and `vect_2`. Rather than placing these products
in a third vector, you can use a combining iterator that calculates the
products on the fly. Let us assume that `tuple_multiplies` is a
functor that works like `std::multiplies`, except that it takes
its two arguments packaged in a tuple. Then the two iterators
`it_begin` and `it_end` defined below delimit a controlled
sequence containing the products of the elements of `vect_1` and
`vect_2`:
typedef boost::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
> the_iterator_tuple;
typedef boost::zip_iterator<
the_iterator_tuple
> the_zip_iterator;
typedef boost::transform_iterator<
tuple_multiplies<double>,
the_zip_iterator
> the_transform_iterator;
the_transform_iterator it_begin(
the_zip_iterator(
the_iterator_tuple(
vect_1.begin(),
vect_2.begin()
)
),
tuple_multiplies<double>()
);
the_transform_iterator it_end(
the_zip_iterator(
the_iterator_tuple(
vect_1.end(),
vect_2.end()
)
),
tuple_multiplies<double>()
);
[endsect]
[section:zip_reference Reference]
[h2 Synopsis]
template<typename IteratorTuple>
class zip_iterator
{
public:
typedef /* see below */ reference;
typedef reference value_type;
typedef value_type* pointer;
typedef /* see below */ difference_type;
typedef /* see below */ iterator_category;
zip_iterator();
zip_iterator(IteratorTuple iterator_tuple);
template<typename OtherIteratorTuple>
zip_iterator(
const zip_iterator<OtherIteratorTuple>& other
, typename enable_if_convertible<
OtherIteratorTuple
, IteratorTuple>::type* = 0 // exposition only
);
const IteratorTuple& get_iterator_tuple() const;
private:
IteratorTuple m_iterator_tuple; // exposition only
};
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
make_zip_iterator(IteratorTuple t);
The `reference` member of `zip_iterator` is the type of the tuple
made of the reference types of the iterator types in the `IteratorTuple`
argument.
The `difference_type` member of `zip_iterator` is the `difference_type`
of the first of the iterator types in the `IteratorTuple` argument.
The `iterator_category` member of `zip_iterator` is convertible to the
minimum of the traversal categories of the iterator types in the `IteratorTuple`
argument. For example, if the `zip_iterator` holds only vector
iterators, then `iterator_category` is convertible to
`boost::random_access_traversal_tag`. If you add a list iterator, then
`iterator_category` will be convertible to `boost::bidirectional_traversal_tag`,
but no longer to `boost::random_access_traversal_tag`.
[h2 Requirements]
All iterator types in the argument `IteratorTuple` shall model Readable Iterator.
[h2 Concepts]
The resulting `zip_iterator` models Readable Iterator.
The fact that the `zip_iterator` models only Readable Iterator does not
prevent you from modifying the values that the individual iterators point
to. The tuple returned by the `zip_iterator`'s `operator*` is a tuple
constructed from the reference types of the individual iterators, not
their value types. For example, if `zip_it` is a `zip_iterator` whose
first member iterator is an `std::vector<double>::iterator`, then the
following line will modify the value which the first member iterator of
`zip_it` currently points to:
zip_it->get<0>() = 42.0;
Consider the set of standard traversal concepts obtained by taking
the most refined standard traversal concept modeled by each individual
iterator type in the `IteratorTuple` argument.The `zip_iterator`
models the least refined standard traversal concept in this set.
`zip_iterator<IteratorTuple1>` is interoperable with
`zip_iterator<IteratorTuple2>` if and only if `IteratorTuple1`
is interoperable with `IteratorTuple2`.
[h2 Operations]
In addition to the operations required by the concepts modeled by
`zip_iterator`, `zip_iterator` provides the following
operations.
zip_iterator();
[*Returns:] An instance of `zip_iterator` with `m_iterator_tuple`
default constructed.
zip_iterator(IteratorTuple iterator_tuple);
[*Returns:] An instance of `zip_iterator` with `m_iterator_tuple`
initialized to `iterator_tuple`.
template<typename OtherIteratorTuple>
zip_iterator(
const zip_iterator<OtherIteratorTuple>& other
, typename enable_if_convertible<
OtherIteratorTuple
, IteratorTuple>::type* = 0 // exposition only
);
[*Returns:] An instance of `zip_iterator` that is a copy of `other`.[br]
[*Requires:] `OtherIteratorTuple` is implicitly convertible to `IteratorTuple`.
const IteratorTuple& get_iterator_tuple() const;
[*Returns:] `m_iterator_tuple`
reference operator*() const;
[*Returns:] A tuple consisting of the results of dereferencing all iterators in
`m_iterator_tuple`.
zip_iterator& operator++();
[*Effects:] Increments each iterator in `m_iterator_tuple`.[br]
[*Returns:] `*this`
zip_iterator& operator--();
[*Effects:] Decrements each iterator in `m_iterator_tuple`.[br]
[*Returns:] `*this`
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
make_zip_iterator(IteratorTuple t);
[*Returns:] An instance of `zip_iterator<IteratorTuple>` with `m_iterator_tuple`
initialized to `t`.
[endsect]
[endsect]

View File

@ -3,7 +3,7 @@
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. _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
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu

0
doc/reverse_iterator.pdf Executable file → Normal file
View File

View File

@ -6,6 +6,7 @@ sources = [
'counting_iterator.rst',
'facade-and-adaptor.rst',
'filter_iterator.rst',
'function_input_iterator.rst',
'function_output_iterator.rst',
'index.rst',
'indirect_iterator.rst',

View File

@ -99,7 +99,7 @@ private:
</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
<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>
<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,
@ -117,10 +117,10 @@ convertible to <tt class="docutils literal"><span class="pre">input_iterator_tag
<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>
<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
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>
</div>
<div class="section" id="transform-iterator-models">

0
doc/transform_iterator.pdf Executable file → Normal file
View File

0
doc/transform_iterator_eg.rst Executable file → Normal file
View File

View File

@ -41,7 +41,7 @@
If ``Reference`` is ``use_default`` then the ``reference`` member of
``transform_iterator`` is
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
``result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
Otherwise, ``reference`` is ``Reference``.
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 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
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.

0
doc/zip_iterator.html Executable file → Normal file
View File

0
doc/zip_iterator.pdf Executable file → Normal file
View File

0
doc/zip_iterator.rst Executable file → Normal file
View File

10
doc/zip_iterator_abstract.rst Executable file → Normal file
View File

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

3
doc/zip_iterator_eg.rst Executable file → Normal file
View File

@ -45,8 +45,7 @@ A non-generic implementation of ``zip_func`` could look as follows:
::
struct zip_func :
public std::unary_function<const boost::tuple<const double&, const int&>&, void>
struct zip_func
{
void operator()(const boost::tuple<const double&, const int&>& t) const
{

0
doc/zip_iterator_ref.rst Executable file → Normal file
View File

0
example/node.hpp Executable file → Normal file
View File

10
example/node_iterator1.cpp Executable file → Normal file
View File

@ -11,7 +11,17 @@
int main()
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<node<int> > nodes(new node<int>(42));
#else
std::unique_ptr<node<int> > nodes(new node<int>(42));
#endif
nodes->append(new node<std::string>(" is greater than "));
nodes->append(new node<int>(13));

0
example/node_iterator1.hpp Executable file → Normal file
View File

10
example/node_iterator2.cpp Executable file → Normal file
View File

@ -12,7 +12,17 @@
int main()
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<node<int> > nodes(new node<int>(42));
#else
std::unique_ptr<node<int> > nodes(new node<int>(42));
#endif
nodes->append(new node<std::string>(" is greater than "));
nodes->append(new node<int>(13));

0
example/node_iterator2.hpp Executable file → Normal file
View File

10
example/node_iterator3.cpp Executable file → Normal file
View File

@ -12,7 +12,17 @@
int main()
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<node<int> > nodes(new node<int>(42));
#else
std::unique_ptr<node<int> > nodes(new node<int>(42));
#endif
nodes->append(new node<std::string>(" is greater than "));
nodes->append(new node<int>(13));

Some files were not shown because too many files have changed in this diff Show More