Compare commits

...

99 Commits

Author SHA1 Message Date
2a0b753691 Use Azure mirrors of Ubuntu .deb repositories in containers.
This reduces the likelihood of spurious CI failures caused by DDoS filters
being triggered by massive numbers of concurrent CI jobs.
2025-06-13 03:48:03 +03:00
0087a426d9 Added new gcc and clang jobs to GitHub Actions. 2025-06-13 03:47:38 +03:00
c409288ff5 Removed windows-2019 GitHub Actions jobs.
The windows-2019 image is deprecated and is about to be removed.
2025-06-13 03:45:12 +03:00
01ac4e1a47 Disable operator_brackets_proxy assignment if reference is not assignable.
Use SFINAE to disable operator_brackets_proxy assignment operator is reference
is not assignable from the assignment argument. Also fix the iterator type
in std::declval in noexcept specification.
2025-06-09 12:01:39 +03:00
e968c3312b Forward dereferencing operators in operator_brackets_proxy.
This allows for expressions like it[n]->foo() and (*it[n]).foo() to compile.
2025-06-09 04:58:45 +03:00
da00617e56 Use perfect forwarding in assignment to operator_brackets_proxy.
Also apply noexcept markup to all of the proxy operators.
2025-06-09 04:58:27 +03:00
7c77e52509 Always use operator_brackets_proxy in iterator_facade.
This avoids returning a copy of the value from operator[], which can
be unexpected by users wanting to obtain an address of the value
referenced by the iterator.

We still want to return a proxy instead of the iterator's reference
since the iterator may be holding the value internally, and the iterator
gets destroyed after returning from operator[], so the returned
reference would be dangling.

Closes https://github.com/boostorg/iterator/issues/61.
2025-06-09 03:22:08 +03:00
256004a446 Remove gcc 4.8 and 4.9 GitHub Actions jobs.
These compilers don't provide std::is_trivially_copyable type trait,
which is now required.
2025-06-09 02:53:18 +03:00
7e3e9a584e Replace is_copy_constructible+is_trivial with is_trivially_copyable.
For the purpose of selecting operator[] result type, we don't care
whether the value type is trivially default-constructible. So, in order
to avoid using the deprecated in C++26 is_trivial, use is_trivially_copyable
instead of is_copy_constructible+is_trivial.

Closes https://github.com/boostorg/iterator/issues/93.
2025-06-09 02:36:26 +03:00
3767696513 Removed legacy MinGW32 AppVeyor CI job.
Boost.Regex develop no longer builds on legacy MinGW32 due to missing
definitions of std::mutex etc.
2025-05-25 03:57:17 +03:00
1372e9afb6 Fix filter_iterator copy/converting constructor.
The constructed iterator would have an invalid end iterator because of
a typo in storage initialization.

Fixes https://github.com/boostorg/iterator/issues/92.
2025-05-24 23:19:45 +03:00
6428e552e4 Nonessential. 2025-04-23 02:55:50 +03:00
766c881f9a Removed usage of obsolete ubuntu-20.04 GHA image. 2025-04-19 18:36:04 +03:00
c2b846c57d Added a test for filter_iterator converting constructor. 2025-04-02 00:13:07 +03:00
1a7996ebd0 Fixed compilation of filter_iterator conversion constructor.
The constructor would attempt to access a private member of the source
iterator, which could have a different type and therefore have that
member inaccessible. Also, the storage forwarding constructor had incorrect
types used in the forwarding expressions, which caused further compilation
errors.

Fixes https://github.com/boostorg/iterator/issues/90.
2025-04-02 00:09:36 +03:00
eee670608e Revert "Added a workaround for the missing MPL includes in Range."
This reverts commit dfb1fd9bed.

The missing includes were added to Boost.Range, the workaround is
no longer needed.
2025-02-07 14:10:12 +03:00
c89e2b325a Removed use of std::unary_function from docs example. 2025-02-07 13:46:19 +03:00
a7150173ed Moved shared_container_iterator.hpp in iterator directory, modernized code.
shared_container_iterator now uses std::shared_ptr to store the reference
to the container. boost::shared_ptr is still supported and is wrapped
into std::shared_ptr on construction, so there is overhead due to allocation
of std::shared_ptr state. Going forward, std::shared_ptr is expected
to be the primary use case. As a bonus, this eliminates the dependency
on Boost.SmartPtr.

Moved shared_container_iterator.hpp into the iterator directory and left
a forwarding header for backward compatibility.
2025-02-07 13:36:40 +03:00
e446c6e05c Added indirect_reference_t alias. 2025-02-07 13:36:40 +03:00
8998179e9d Added pointee_t alias. 2025-02-07 13:36:40 +03:00
d35869cd25 Moved generator_iterator.hpp in iterator directory and modernized.
generator_iterator now uses decltype approach to deduce value and reference
types instead of the legacy result_type typedef, which was required to be
defined by the generator function.

The default constructor of generator_iterator now value initializes its
data members to avoid using uninitialized data.
2025-02-07 13:36:33 +03:00
6e6def930f Modernized transform_iterator.hpp, use EBO to store the transform function. 2025-02-07 01:17:55 +03:00
1a58ca89d1 Reformatted reverse_iterator.hpp. 2025-02-07 01:17:55 +03:00
34f703cfb6 Removed workarounds for older compilers from permutation_iterator.hpp. 2025-02-07 01:17:55 +03:00
a91fc06bb4 Prohibit default construction of function_output_iterator on function pointers.
Default-constructed function_output_iterator with function pointers is unusable
and previously would have contained an uninitialized function pointer.
Disable the default constructor using SFINAE to prevent misuse.

Also reformat code.
2025-02-07 01:17:55 +03:00
fd1445140f Removed usage of FunctionTypes in function_input_iterator.hpp.
This effectively removes usage of MPL in function_input_iterator.hpp and
also simplifies implementation.
2025-02-07 01:17:50 +03:00
8c2fdf6053 Use variadic template expansion in min category deduction in zip_iterator.
This results in marginally faster compile times in modern code bases
where tuples are variadic.
2025-02-06 01:47:49 +03:00
aadd90df45 Removed direct usage of MPL from zip_iterator.hpp.
MPL is still used through Boost.Fusion, but that is a matter of
optimizing Boost.Fusion now.
2025-02-06 01:47:49 +03:00
dc57bcf319 Modernized filter_iterator.hpp.
Use EBO to minimize wasted storage space if the predicate is an empty class.

Disable default constructing non-class predicates using SFINAE instead
of a static_assert. This will help type traits like is_constructible,
when applied to the iterator type.
2025-02-06 01:47:49 +03:00
baf6d06cc2 Modernized iterator_traits.hpp.
Added *_t type traits and removed an oudated macro that was used with
ancient compilers.
2025-02-06 01:47:49 +03:00
6e60ea7a88 Extracted and unified default template parameter handling helpers.
The new eval_if_default helper replaces both ia_dflt_help and
ia_eval_if_default helpers. Additionally, added a new if_default
helper, which expands to the type or the default parameter directly.

The new helpers are placed in separate headers which can be used
without the iterator_adaptor template.
2025-02-06 01:47:43 +03:00
cb81a1dfc3 Extracted enable_if_convertible trait to a separate header.
Keep including the new header in iterator_adaptor.hpp for backward
compatibility, until downstream users are updated to include the new
header.
2025-02-06 01:38:24 +03:00
c22af90b60 Reformat advance.hpp and distance.hpp. 2025-02-06 01:38:24 +03:00
b6a41e325c Added a missing include in interoperable.hpp. 2025-02-06 01:38:24 +03:00
0c2eda4bb8 Removed MPL usage from indirect_iterator.hpp. 2025-02-06 01:38:16 +03:00
dfb1fd9bed Added a workaround for the missing MPL includes in Range.
This is a temporary workaround until Boost.Range is fixed by:

https://github.com/boostorg/range/pull/154
2025-02-05 18:51:44 +03:00
b12874b6ca Removed MPL usage from iterator_facade.hpp. 2025-02-05 18:51:44 +03:00
1875d95019 Removed MPL usage from iterator_adaptor.hpp. 2025-02-05 18:51:44 +03:00
4f5f61e37b Slightly optimized iterator_facade_default_category compilation speed. 2025-02-05 18:51:44 +03:00
5aa1c9fef3 Removed workarounds for older compilers from is_readable_iterator.hpp. 2025-02-05 18:51:44 +03:00
d6a68dc6eb Removed workarounds for older compilers from counting_iterator.hpp. 2025-02-05 18:51:44 +03:00
e5ee9a6168 Removed unneeded include. 2025-02-05 18:51:44 +03:00
82703b7c14 Moved input_output_iterator_tag to unit tests.
The class was not used anywhere else and was an implementation detail.
2025-02-05 18:51:44 +03:00
d8ce9ddfc7 Removed MPL usage from facade_iterator_category.hpp. 2025-02-05 18:51:44 +03:00
5f713e9b14 Use std::type_identity when possible in counting_iterator.hpp. 2025-02-05 18:51:44 +03:00
12ee53d441 Added type_identity forwarding header. 2025-02-05 18:51:44 +03:00
ef40faf620 Replaced leftover boost::true/false_type with std in counting_iterator.hpp.
Also made (unsigned) long long support mandatory.
2025-02-05 18:51:44 +03:00
fc99b7a15d Added missing includes for use_default. 2025-02-05 18:51:44 +03:00
241c28018e Converted leftover boost::true/false_type to std in iterator_facade.hpp. 2025-02-05 18:51:44 +03:00
83905b219e Reduced dependency on MPL in iterator_categories.hpp.
Also simplified implementation of type traits using Boost.MP11.
2025-02-05 18:51:44 +03:00
6fab3bbfa4 Removed dependency on MPL from is_lvalue_iterator.hpp.
Also removed workarounds for older compilers and simplified implementation.
2025-02-05 18:51:44 +03:00
dec7d0f24c Extracted min_category as a variadic metafunction.
The new min_category is similar to minimum_category but accepts variable
number of iterator categories on input instead of just two, and also does
not depend on Boost.MPL for lambda placeholders. The existing minimum_category
trait has been reimplemented in terms of min_category and deprecated.

We don't yet emit deprecation warnings as there is still code that uses
the old trait which we first need to update. Eventually, minimum_category
will emit warnings and will be removed.
2025-02-05 18:51:37 +03:00
b30cbf634c Reduced dependency on MPL in minimum_category.hpp. 2025-01-26 20:00:53 +03:00
7ddbf15868 Removed MPL usage from iterator_archetypes.hpp. 2025-01-26 19:08:40 +03:00
4fc0165034 Removed support for ancient complilers for MPL lambdas in is_readable_iterator. 2025-01-26 17:58:48 +03:00
bcf94f9e5d Removed MPL usage from pointee and indirect_reference. 2025-01-26 17:57:47 +03:00
d6297a553b Removed the BOOST_ITERATOR_CONVERTIBLE helper macro. 2025-01-26 15:55:52 +03:00
32d19a72e1 Trim trailing spaces. 2025-01-26 15:45:03 +03:00
cf43da4286 Removed useless #if 1. 2025-01-26 15:42:30 +03:00
10e89b3e4c Restored brace formatting in new_iterator_tests.hpp. 2025-01-26 15:25:28 +03:00
5ed3144969 Restored the original static assert check. 2025-01-26 15:22:53 +03:00
f9effffb6d Mostly remove pre-CXX11 workarounds.
С++03 support was deprecated in 1.85 and now can be removed. This PR clears
many of workarounds, which are no longer needed now.

* Remove unused workaround macros (many of).
* Remove BOOST_STATIC_ASSERT usages.
* Minimize Boost::type_traits dependency (in favour of STL's type_traits).

Closes https://github.com/boostorg/iterator/pull/82.

Squashed commit of the following:

commit 741a627b73
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Jan 25 12:13:05 2025 +0300

    Replace testers with standard metafunctions.

commit bf4cce6114
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Jan 25 11:51:32 2025 +0300

    Refactor is_lvalue_iterator.hpp.

commit 8d080c6c58
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Jan 25 10:27:32 2025 +0300

    Remove more workarounds.

commit 5a4ba24d36
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sun Jan 19 16:38:30 2025 +0300

    Fixes.

commit fdfafce2b9
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Oct 26 15:06:43 2024 +0300

    Remove BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
    Correct static_assert messages.
    Fix messages & replace is_standard_layout with is_copy_constructible.

commit c69ac1408a
Author: Georgy Guminov <gogagum@gmail.com>
Date:   Sat Oct 26 14:48:51 2024 +0300

    Correct static_assert messages.

commit b5df827151
Author: Georqy Guminov <gogagum@gmail.com>
Date:   Sun Jun 23 16:12:29 2024 +0300

    Fixes. Remove some Boost.MPL usages. Remove unused includes.

commit 01fd35e9f8
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 17:14:21 2024 +0300

    abstract conjunction.

commit c02def8acf
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 16:35:43 2024 +0300

    return addressof & conjunction.

commit 3b3d162575
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 16:30:44 2024 +0300

    Make macro more readable.

commit 4ab19e045f
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 15:56:49 2024 +0300

    Add static_assert messages.

commit 82b5c44cd3
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Wed Jun 12 14:12:10 2024 +0300

    Return is iterator CXX17 test.

commit 2d58d65462
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Tue Jun 11 14:04:17 2024 +0300

    Omitted.

commit a0d04d9491
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Tue Jun 11 14:00:35 2024 +0300

    Replace move with static_cast

commit 4a49b8a1a2
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Mon Jun 10 21:38:53 2024 +0300

    Return BOOST_NOEXCEPT

commit 054c013bba
Author: Georgiy Guminov <gogagum@gmail.com>
Date:   Sun Jun 9 15:20:41 2024 +0300

    CXX11
2025-01-26 15:21:16 +03:00
53101ffab9 GitHub Actions CI update.
Removed MacOS 12 and added MacOS 15 job as the former image is removed
from GHA.

Added newer gcc and clang jobs on Linux. Updated Linux images to reduce
reliance on external package repositories.
2025-01-26 15:05:14 +03:00
4b40364d6d Work around compilation errors on clang-10 through 12. 2024-10-11 01:04:21 +03:00
7c55a6cef8 Marked output_proxy assignment as const.
This is also required for compliance with std::output_iterator concept.
2024-10-11 00:34:28 +03:00
1ea8087623 Check for compliance with output_iterator in function_output_iterator_test. 2024-10-11 00:29:20 +03:00
e4eaeeac44 Make function_output_iterator compliant with std::output_iterator concept.
Fixes https://github.com/boostorg/iterator/issues/85.
Closes https://github.com/boostorg/iterator/pull/87.
2024-10-11 00:26:30 +03:00
46ffe06b3d Removed MSVC-12 job from AppVeyor CI.
This compiler is no longer supported by Boost.SmartPtr that is
used in tests.
2024-10-11 00:21:46 +03:00
8b83324682 Removed gcc 4.6 and 4.7 from GitHub Actions CI.
These compilers are not supported by Boost.SmartPtr and Boost.Optional,
which are used in tests.
2024-10-11 00:13:00 +03:00
ce030ab2c3 Add support for modular build structure. (#84)
* Make the library modular usable.

* Switch to library requirements instead of source. As source puts extra source in install targets.

* Remove not-needed reference to Conversion dependency.

* Add missing b2 testing module import.

* Add requires-b2 check to top-level build file.

* Bump B2 require to 5.2

* Change all <source> references to <library>.

* Update copyright dates.

* Move inter-lib dependencies to a project variable and into the build targets.

* Update build deps.
2024-08-19 01:22:08 +03:00
4914e1f40a Updated deprecated include in docs.
Closes https://github.com/boostorg/iterator/pull/83.
2024-07-03 15:12:28 +03:00
0abef890ee Replaced macos-11 GHA image with 12, 13 and 14 since 11 is being removed. 2024-05-21 01:17:20 +03:00
4f7219965a Added gcc-13 CI job. 2024-02-06 00:35:15 +03:00
988594fb9d Added clang-17 CI jobs. 2024-02-06 00:26:38 +03:00
3fa2242082 Added Windows jobs to GHA CI. 2024-02-06 00:24:05 +03:00
43dde9b9c3 Reduced CI job timeouts. 2024-02-06 00:22:10 +03:00
7968dd3ea8 Replaced actions/checkout usage with manual download commands.
This fixes the deprecation warnings for actions/checkout@v3. actions/checkout@v4
is not functional because of the upstream bug:

https://github.com/actions/checkout/issues/1590
2024-02-06 00:17:16 +03:00
dfe11e7144 Removed one more $ tag. 2024-01-03 01:43:52 +03:00
9cc1a4fdd1 Removed $Date$ tags from docs.
The tags were not being updated for a long time now and were
visible in the final docs.

Reported in https://github.com/boostorg/website/issues/762.
2024-01-03 01:31:05 +03:00
ae5d7d8c0c Added a CMake test. 2023-11-17 17:47:20 +03:00
d72d57fa39 Removed dependency on Boost.Conversion in CMakeLists.txt.
Fixes https://github.com/boostorg/iterator/issues/81.
2023-11-17 17:24:02 +03:00
c98f965388 Use gcc-11 libstdc++ for clang-12 through 15. 2023-11-17 11:06:21 +03:00
d09f78ae9b Removed C++03 CI jobs. 2023-11-17 04:46:21 +03:00
a9dabd3c65 Removed dependency on Boost.Conversion in tests.
This reduces the minimum supported compilers versions.
2023-11-17 04:25:29 +03:00
80bb1ac9e4 Avoid including <utility>, added a missing include. 2023-06-22 21:14:03 +03:00
d11499c08c Performance improvement: (#79)
Performance improvement: Add move semantics to by-value parameters (iterator and predicate), to eliminate the cost of copy-construction. Both the Predicate (Normally a std::function, or lambda), and custom iterators can have state, which can be expensive to copy. Profiler identified this as a bottleneck while using boost::adaptors::filtered.
2023-06-22 21:06:19 +03:00
6d02c36718 Add clang-16 CI jobs, switch to clang-15 from stock Ubuntu repos. 2023-06-05 03:17:56 +03:00
85b542e1b6 Extracted is_iterator trait to a separate header.
Also, reworked is_iterator to be more robust against various corner cases
and added dedicated tests for the type trait.
2023-05-21 15:18:54 +03:00
e8fbd92a61 Use BOOST_STATIC_ASSERT instead of BOOST_MPL_ASSERT (#78)
The MPL version is slower to compile and `BOOST_STATIC_ASSERT` is
already used in some places. So unify that.

This also fixes `Wzero-as-null-pointer-constant` warnings, see https://github.com/boostorg/mpl/pull/75
2023-05-07 15:23:16 +03:00
7c9b4296a1 Fixed accessing members of the dereferenced value after iterator post-increment.
The recent commit 5777e9944b broke code such as
(*it++).foo(), where the result of dereferencing would be convertible to
the value type but did not provide the members of the value type. To mitigate
this, return a reference to the value instead of a proxy object. This will only
work for non-writable iterators (and it didn't work for writable iterators
before either) because in that case a proxy is needed to be able to intercept
operator=.

Also fix a similar issue with (it++)->foo() by adding operator-> overloads
to the post-increment result proxies.

Added tests for the fixes.
2022-11-18 00:46:21 +03:00
0a95636faf Added test for converting func_input_iter increment results to the iterator type. 2022-11-09 21:19:00 +03:00
5777e9944b Added conversion from postfix increment proxy to iterator type.
This allows expressions such as `Iterator it2(it1++)` to compile.

Additionally separated operations that are allowed on the result of
dereferencing the proxy to a separate set of proxies to make the allowed
set of expressions more strict and unambiguous. In particular, it means
`it++` cannot be converted to value type and `*it++` cannot be converted
to the iterator type anymore. Also, make sure `*it1++ = *it2++` works
as expexted by explicitly converting the proxy to the value type on
assignment.

Fixes https://github.com/boostorg/iterator/issues/75.
2022-11-09 21:16:20 +03:00
853ba3d3c7 Use the proper derived type of the function_input_iterator in iterator_facade.
This fixes incorrect final iterator type being used in iterator_facade, which
results in an internal base class being returned from various facade methods.

Reported in https://github.com/boostorg/iterator/issues/75.
2022-11-09 21:15:44 +03:00
f82627f2cc Updated to GHA checkout@v3 to avoid deprecation warnings. 2022-10-18 17:57:57 +03:00
ed1d96f251 GitHub Actions config update.
- Added gcc-12 and clang-13 through 15 jobs.
- Added C++23 testing for gcc and clang on Linux.
- Updated clang version for UBSAN job.
- Updated Ubuntu version for clang jobs to avoid having to use external APT
  repository.
- Updated python package installation for compatibility with Ubuntu 22.04.
2022-09-10 01:29:45 +03:00
ce52aee3ce Switched gcc-9 to ubuntu-20.04 GHA CI image. 2022-08-14 17:53:43 +03:00
17355c5ad0 Updated copyright years. 2022-08-14 14:01:45 +03:00
9504b3bced Replaced ubuntu-18.04 GHA CI images with containers.
Also use ubuntu-latest image for jobs that are running in a container.
2022-08-14 14:00:17 +03:00
2cc45f1694 Switch to macos-11 GHA image as macos-10.15 is deprecated. 2022-08-12 15:59:54 +03:00
113 changed files with 4725 additions and 4358 deletions

View File

@ -1,4 +1,4 @@
# Copyright 2021 Andrey Semashev
# Copyright 2021-2025 Andrey Semashev
#
# 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)
@ -33,209 +33,281 @@ jobs:
matrix:
include:
# Linux, gcc
- toolset: gcc-4.4
cxxstd: "98,0x"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.4
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.6
cxxstd: "03,0x"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.6
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.7
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.7
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-18.04
install:
- g++-4.8
- toolset: gcc-4.9
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.9
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-20.04
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-7
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:20.04
install:
- g++-9
- toolset: gcc-10
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
cxxstd: "11,14,17,20"
os: ubuntu-latest
container: ubuntu:20.04
install:
- g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
cxxstd: "11,14,17,20,23"
os: ubuntu-22.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-12
cxxstd: "11,14,17,20,23"
os: ubuntu-22.04
install:
- g++-12
- toolset: gcc-13
cxxstd: "11,14,17,20,23"
os: ubuntu-24.04
install:
- g++-13
- toolset: gcc-14
cxxstd: "11,14,17,20,23,26"
os: ubuntu-24.04
install:
- g++-14
- toolset: gcc-15
cxxstd: "11,14,17,20,23,26"
os: ubuntu-latest
container: ubuntu:25.04
install:
- g++-15
- name: UBSAN
toolset: gcc-11
cxxstd: "03,11,14,17,20"
toolset: gcc-13
cxxstd: "11,14,17,20,23"
ubsan: 1
build_variant: debug
os: ubuntu-20.04
os: ubuntu-24.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
- g++-13
# Linux, clang
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11"
os: ubuntu-20.04
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-20.04
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
os: ubuntu-20.04
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "03,11,14"
os: ubuntu-20.04
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.8
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-18.04
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-18.04
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-7
# Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-8
- g++-7
gcc_toolchain: 7
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:20.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
cxxstd: "11,14,17,20"
os: ubuntu-latest
container: ubuntu:20.04
install:
- clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
cxxstd: "11,14,17,20"
os: ubuntu-22.04
install:
- clang-11
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-12
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
- clang-13
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-14
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-14
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-15
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
os: ubuntu-24.04
install:
- clang-16
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-17
cxxstd: "11,14,17,20,23,26"
os: ubuntu-24.04
install:
- clang-17
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-18
cxxstd: "11,14,17,20,23,26"
os: ubuntu-24.04
install:
- clang-18
- g++-13
- toolset: clang
compiler: clang++-19
cxxstd: "11,14,17,20,23,26"
os: ubuntu-24.04
install:
- clang-19
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,26"
os: ubuntu-latest
container: ubuntu:25.04
install:
- clang-20
- toolset: clang
compiler: clang++-20
cxxstd: "11,14,17,20,23,26"
os: ubuntu-latest
container: ubuntu:25.04
install:
- clang-20
- libc++-20-dev
- libc++abi-20-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- name: UBSAN
toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
compiler: clang++-18
cxxstd: "11,14,17,20,23,26"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
linkflags: "-stdlib=libc++ -lubsan"
ubsan: 1
build_variant: debug
os: ubuntu-20.04
os: ubuntu-24.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
- clang-18
- libc++-18-dev
- libc++abi-18-dev
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
cxxstd: "11,14,17,20,2b"
os: macos-13
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-14
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-15
timeout-minutes: 60
- name: CMake tests
cmake_tests: 1
os: ubuntu-24.04
timeout-minutes: 20
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
@ -252,14 +324,34 @@ jobs:
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
if [ -f "/etc/debian_version" ]
then
# Use Azure APT mirrors in containers to avoid HTTP errors due to DDoS filters triggered by lots of CI jobs launching concurrently.
# Note that not all Ubuntu versions support "mirror+file:..." URIs in APT sources, so just use Azure mirrors exclusively.
# Note also that on recent Ubuntu versions DEB822 format is used for source files.
APT_SOURCES=()
if [ -d "/etc/apt/sources.list.d" ]
then
readarray -t APT_SOURCES < <(find "/etc/apt/sources.list.d" -type f -name '*.sources' -print)
fi
if [ -f "/etc/apt/sources.list" ]
then
APT_SOURCES+=("/etc/apt/sources.list")
fi
if [ "${#APT_SOURCES[@]}" -gt 0 ]
then
sed -i -E -e 's!([^ ]+) (http|https)://(archive|security)\.ubuntu\.com/ubuntu[^ ]*(.*)!\1 http://azure.archive.ubuntu.com/ubuntu/\4!' "${APT_SOURCES[@]}"
fi
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ python python3 perl git cmake
if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ]
then
PYTHON_PACKAGE="python-is-python3"
else
PYTHON_PACKAGE="python"
fi
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake
fi
fi
git config --global pack.threads 0
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: |
@ -374,11 +466,25 @@ jobs:
then
DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS")
fi
mkdir -p snapshot
cd snapshot
echo "Downloading library snapshot: https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
curl -L --retry "$NET_RETRY_COUNT" -o "${LIBRARY}-${GITHUB_SHA}.tar.gz" "https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
tar -xf "${LIBRARY}-${GITHUB_SHA}.tar.gz"
if [ ! -d "${LIBRARY}-${GITHUB_SHA}" ]
then
echo "Library snapshot does not contain the library directory ${LIBRARY}-${GITHUB_SHA}:"
ls -la
exit 1
fi
rm -f "${LIBRARY}-${GITHUB_SHA}.tar.gz"
cd ..
git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root"
cd boost-root
mkdir -p libs/$LIBRARY
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
mkdir -p libs
rm -rf "libs/$LIBRARY"
mv -f "../snapshot/${LIBRARY}-${GITHUB_SHA}" "libs/$LIBRARY"
rm -rf "../snapshot"
git submodule update --init tools/boostdep
DEPINST_ARGS+=("$LIBRARY")
python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}"
@ -400,7 +506,7 @@ jobs:
- name: Run tests
if: matrix.cmake_tests == ''
run: |
cd ../boost-root
cd boost-root
B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}")
if [ -n "${{matrix.build_variant}}" ]
then
@ -427,3 +533,88 @@ jobs:
fi
B2_ARGS+=("libs/$LIBRARY/test")
./b2 "${B2_ARGS[@]}"
- name: Run CMake tests
if: matrix.cmake_tests
run: |
if [ -n "${{matrix.macosx_version_min}}" ]
then
export MACOSX_DEPLOYMENT_TARGET="${{matrix.macosx_version_min}}"
fi
cd boost-root
mkdir __build_static__ && cd __build_static__
cmake ../libs/$LIBRARY/test/test_cmake
cmake --build . --target boost_${LIBRARY}_cmake_self_test -j $BUILD_JOBS
cd ..
mkdir __build_shared__ && cd __build_shared__
cmake -DBUILD_SHARED_LIBS=On ../libs/$LIBRARY/test/test_cmake
cmake --build . --target boost_${LIBRARY}_cmake_self_test -j $BUILD_JOBS
windows:
defaults:
run:
shell: cmd
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "11,14,17,20,23"
addrmd: 64
os: windows-2022
timeout-minutes: 20
runs-on: ${{matrix.os}}
steps:
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
mkdir snapshot
cd snapshot
echo Downloading library snapshot: https://github.com/%GITHUB_REPOSITORY%/archive/%GITHUB_SHA%.zip
curl -L --retry %NET_RETRY_COUNT% -o "%LIBRARY%-%GITHUB_SHA%.zip" "https://github.com/%GITHUB_REPOSITORY%/archive/%GITHUB_SHA%.zip"
tar -xf "%LIBRARY%-%GITHUB_SHA%.zip"
if not exist "%LIBRARY%-%GITHUB_SHA%\" (
echo Library snapshot does not contain the library directory %LIBRARY%-%GITHUB_SHA%:
dir
exit /b 1
)
del /f "%LIBRARY%-%GITHUB_SHA%.zip"
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
if not exist "libs\" mkdir libs
if exist "libs\%LIBRARY%\" rmdir /s /q "libs\%LIBRARY%"
move /Y "..\snapshot\%LIBRARY%-%GITHUB_SHA%" "libs\%LIBRARY%"
rmdir /s /q "..\snapshot"
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
run: |
cd boost-root
if not "${{matrix.cxxstd}}" == "" set CXXSTD=cxxstd=${{matrix.cxxstd}}
if not "${{matrix.addrmd}}" == "" set ADDRMD=address-model=${{matrix.addrmd}}
if not "${{matrix.build_variant}}" == "" (set BUILD_VARIANT=variant=${{matrix.build_variant}}) else (set BUILD_VARIANT=variant=%DEFAULT_BUILD_VARIANT%)
b2 -j %NUMBER_OF_PROCESSORS% libs/%LIBRARY%/test toolset=${{matrix.toolset}} %CXXSTD% %ADDRMD% %BUILD_VARIANT% embed-manifest-via=linker

View File

@ -17,15 +17,11 @@ target_link_libraries(boost_iterator
Boost::assert
Boost::concept_check
Boost::config
Boost::conversion
Boost::core
Boost::detail
Boost::function_types
Boost::fusion
Boost::mpl
Boost::optional
Boost::smart_ptr
Boost::static_assert
Boost::type_traits
Boost::utility
)

View File

@ -15,12 +15,6 @@ branches:
environment:
matrix:
- TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
ADDRMD: 32
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-12.0
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-14.0
CXXSTD: 14,latest
ADDRMD: 32,64
@ -42,25 +36,23 @@ environment:
CXXSTD: 14,17,latest
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
CXXSTD: 11,14,1z
ADDPATH: C:\cygwin\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
CXXSTD: 11,14,1z
ADDPATH: C:\cygwin64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\mingw\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
CXXSTD: 11,14,1z
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
CXXSTD: 11,14,1z
ADDPATH: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TEST_CMAKE: 1
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
install:
- set GIT_FETCH_JOBS=8
@ -87,3 +79,17 @@ test_script:
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j %NUMBER_OF_PROCESSORS% libs/iterator/test toolset=%TOOLSET% %CXXSTD% %ADDRMD%
for:
- matrix:
only: [TEST_CMAKE: 1]
test_script:
- mkdir __build_static__
- cd __build_static__
- cmake ../libs/iterator/test/test_cmake
- cmake --build . --target boost_iterator_cmake_self_test -j %NUMBER_OF_PROCESSORS%
- cd ..
- mkdir __build_shared__
- cd __build_shared__
- cmake -DBUILD_SHARED_LIBS=On ../libs/iterator/test/test_cmake
- cmake --build . --target boost_iterator_cmake_self_test -j %NUMBER_OF_PROCESSORS%

32
build.jam Normal file
View File

@ -0,0 +1,32 @@
# Copyright René Ferdinand Rivera Morell 2023-2024
# 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)
require-b2 5.2 ;
constant boost_dependencies :
/boost/assert//boost_assert
/boost/concept_check//boost_concept_check
/boost/config//boost_config
/boost/core//boost_core
/boost/detail//boost_detail
/boost/fusion//boost_fusion
/boost/mpl//boost_mpl
/boost/optional//boost_optional
/boost/type_traits//boost_type_traits
/boost/utility//boost_utility ;
project /boost/iterator
: common-requirements
<include>include
;
explicit
[ alias boost_iterator : : : : <library>$(boost_dependencies) ]
[ alias all : boost_iterator test ]
;
call-if : boost-library iterator
;

View File

@ -11,7 +11,6 @@
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -1,8 +1,6 @@
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
boostinspect:nolicense

View File

@ -4,7 +4,6 @@
%%
%% o author: Alexander Schmolck (a.schmolck@gmx.net)
%% o created: 2002-07-07 10:50:31+00:40
%% o last modified: $Date: 2004/01/29 05:55:26 $
%% o keywords:
%% o license:
%XXX titlesec

View File

@ -2622,7 +2622,7 @@ proxy object.</p>
<div class="section" id="header">
<h4><a class="toc-backref" href="#id70">Header</a></h4>
<pre class="literal-block">
#include &lt;boost/function_output_iterator.hpp&gt;
#include &lt;boost/iterator/function_output_iterator.hpp&gt;
</pre>
<pre class="literal-block">
template &lt;class UnaryFunction&gt;

View File

@ -10,7 +10,6 @@
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, `Zephyr Associates, Inc.`_
:date: $Date$
:Number: This is a revised version of N1530_\ =03-0113, which was
accepted for Technical Report 1 by the C++ standard

View File

@ -11,7 +11,6 @@
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -7,7 +7,7 @@ Header
::
#include <boost/function_output_iterator.hpp>
#include <boost/iterator/function_output_iterator.hpp>
::

View File

@ -68,7 +68,7 @@ proxy object.</td>
<div class="section" id="header">
<h1><a class="toc-backref" href="#id1">Header</a></h1>
<pre class="literal-block">
#include &lt;boost/function_output_iterator.hpp&gt;
#include &lt;boost/iterator/function_output_iterator.hpp&gt;
</pre>
<pre class="literal-block">
template &lt;class UnaryFunction&gt;

View File

@ -11,7 +11,6 @@
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -15,7 +15,7 @@
<h1>Generator Iterator Adaptor</h1>
<p>Defined in header <a href=
"../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a></p>
"../../boost/iterator/generator_iterator.hpp">boost/iterator/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
@ -33,9 +33,7 @@
<blockquote>
<pre>
namespace boost {
template &lt;class Generator&gt;
class generator_iterator_policies;
namespace iterators {
template &lt;class Generator&gt;
class generator_iterator_generator;
@ -43,6 +41,7 @@ namespace boost {
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; gen);
}
}
</pre>
</blockquote>
<hr>
@ -60,8 +59,8 @@ template &lt;class Generator&gt;
class generator_iterator_generator
{
public:
typedef <i>unspecified</i> type; // the resulting generator iterator type
}
using type = <i>unspecified</i>; // the resulting generator iterator type
};
</pre>
<h3>Template Parameters</h3>
@ -78,8 +77,8 @@ public:
"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
return type of the function is deduced automatically from its
<tt>operator()</tt>. The function object must be a model of
<a href=
"http://www.sgi.com/tech/stl/Generator.html">Generator</a>.</td>
</tr>
@ -122,14 +121,14 @@ make_generator_iterator(Generator &amp; gen);
<blockquote>
<pre>
#include &lt;iostream&gt;
#include &lt;boost/generator_iterator.hpp&gt;
#include &lt;boost/iterators/generator_iterator.hpp&gt;
class my_generator
{
public:
typedef int result_type;
using result_type = int;
my_generator() : state(0) { }
int operator()() { return ++state; }
result_type operator()() { return ++state; }
private:
int state;
};
@ -137,7 +136,7 @@ private:
int main()
{
my_generator gen;
boost::generator_iterator_generator&lt;my_generator&gt;::type it = boost::make_generator_iterator(gen);
auto it = boost::iterators::make_generator_iterator(gen);
for(int i = 0; i &lt; 10; ++i, ++it)
std::cout &lt;&lt; *it &lt;&lt; std::endl;
}

View File

@ -26,8 +26,6 @@
<tr class="field"><th class="field-name">organizations:</th><td class="field-body"><a class="reference external" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference external" href="http://www.osl.iu.edu">Open Systems
Lab</a>, <a class="reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td>
</tr>
<tr class="field"><th class="field-name">date:</th><td class="field-body">$Date$</td>
</tr>
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003.</td>
</tr>
</tbody>
@ -142,7 +140,7 @@ sequence, rearranged according to some sequence of integer indices.</li>
bidirectional sequence in reverse. Corrects many of the
shortcomings of C++98's <tt class="docutils literal"><span class="pre">std::reverse_iterator</span></tt>.</li>
<li><a class="reference external" href="../../utility/shared_container_iterator.html"><tt class="docutils literal"><span class="pre">shared_container_iterator</span></tt></a>: an iterator over elements of a container whose
lifetime is maintained by a <a class="reference external" href="../../smart_ptr/shared_ptr.htm"><tt class="docutils literal"><span class="pre">shared_ptr</span></tt></a> stored in the iterator.</li>
lifetime is maintained by a <tt class="docutils literal"><span class="pre">shared_ptr</span></tt> stored in the iterator.</li>
<li><a class="reference external" href="transform_iterator.html"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt></a> (<a class="reference external" href="transform_iterator.pdf">PDF</a>): 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

View File

@ -19,7 +19,6 @@ __ ../../../index.htm
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
:organizations: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, `Zephyr Associates, Inc.`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003.

View File

@ -11,7 +11,6 @@
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -2,7 +2,6 @@
Interoperability Revisited
++++++++++++++++++++++++++++
:date: $Date$
:copyright: Copyright Thomas Witt 2004.
.. Distributed under the Boost

View File

@ -8,7 +8,6 @@
:Author: David Abrahams and Jeremy Siek
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
:Organization: `Boost Consulting`_, Indiana University Bloomington
:date: $Date$
:Copyright: Copyright David Abrahams, Jeremy Siek 2003. Use, modification and
distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy

View File

@ -11,7 +11,6 @@
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -10,7 +10,6 @@
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, `Zephyr Associates, Inc.`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2004.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -10,7 +10,6 @@
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, `Zephyr Associates, Inc.`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2004.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -11,7 +11,6 @@
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -7,7 +7,6 @@
<title>Iterator Traits</title>
<meta name="author" content="David Abrahams" />
<meta name="organization" content="Boost Consulting" />
<meta name="date" content="$Date$" />
<meta name="copyright" content="Copyright David Abrahams 2004." />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
@ -24,8 +23,6 @@
<td><a class="first last reference external" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a></td></tr>
<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>$Date$</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams 2004.</td></tr>
</tbody>

View File

@ -9,7 +9,6 @@
:Author: David Abrahams
:Contact: dave@boost-consulting.com
:organization: `Boost Consulting`_
:date: $Date$
:copyright: Copyright David Abrahams 2004.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -13,7 +13,6 @@
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, `Zephyr Associates, Inc.`_
:date: $Date$
:Number: This is a revised version of n1550_\ =03-0133, which was
accepted for Technical Report 1 by the C++ standard

View File

@ -10,7 +10,6 @@
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_
:date: $Date$
:copyright: Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -9,7 +9,6 @@
:Author: David Abrahams
:Contact: dave@boost-consulting.com
:organization: `Boost Consulting`_
:date: $Date$
:copyright: Copyright David Abrahams 2004.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -1,6 +1,6 @@
[section:shared_container Shared Container Iterator]
Defined in header [@../../../boost/shared_container_iterator.hpp `boost/shared_container_iterator.hpp`].
Defined in header [@../../../boost/iterator/shared_container_iterator.hpp `boost/iterator/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
@ -24,9 +24,22 @@ iterator.
[h2 Synopsis]
namespace boost {
namespace iterators {
template <typename Container>
class shared_container_iterator;
template <typename Container>
shared_container_iterator<Container>
make_shared_container_iterator(typename Container::iterator base,
std::shared_ptr<Container> const& container);
std::pair<
typename shared_container_iterator<Container>,
typename shared_container_iterator<Container>
>
make_shared_container_range(std::shared_ptr<Container> const& container);
// Backward compatibility with boost::shared_ptr
template <typename Container>
shared_container_iterator<Container>
make_shared_container_iterator(typename Container::iterator base,
@ -38,6 +51,15 @@ iterator.
>
make_shared_container_range(boost::shared_ptr<Container> const& container);
}
}
[note `shared_container_iterator` and its factory functions support both
`std::shared_ptr` and `boost::shared_ptr` for a smart pointer that holds
a shared reference to the container. However, the support for `boost::shared_ptr`
comes at a cost of wrapping it in a `std::shared_ptr` internally. This means
that when constructing the iterator from a `boost::shared_ptr`, the construction
will have to allocate memory for `std::shared_ptr` shared state, which may
potentially fail. It is recommended to use `std::shared_ptr` directly.]
[section:shared_container_type The Shared Container Iterator Type]
@ -57,18 +79,17 @@ the underlying vector and thereby extend the container's lifetime.
[example_link shared_iterator_example1.cpp..`shared_iterator_example1.cpp`]:
#include "shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <boost/iterator/shared_container_iterator.hpp>
#include <algorithm>
#include <iostream>
#include <vector>
#include <memory>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
using iterator = boost::iterators::shared_container_iterator< std::vector<int> >;
void set_range(iterator& i, iterator& end) {
boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
void set_range(iterator& i, iterator& end) {
std::shared_ptr< std::vector<int> > ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
@ -77,18 +98,17 @@ the underlying vector and thereby extend the container's lifetime.
ints->push_back(4);
ints->push_back(5);
i = iterator(ints->begin(),ints);
end = iterator(ints->end(),ints);
i = iterator(ints->begin(), ints);
end = iterator(ints->end(), ints);
}
int main() {
iterator i, end;
iterator i,end;
set_range(i, end);
set_range(i,end);
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::copy(i, end, std::ostream_iterator<int>(std::cout, ","));
std::cout.put('\n');
return 0;
@ -116,8 +136,12 @@ 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:
iterator will be valid. In addition it has the following constructors:
shared_container_iterator(Container::iterator const& it,
std::shared_ptr<Container> const& container)
// Backward compatibility with boost::shared_ptr
shared_container_iterator(Container::iterator const& it,
boost::shared_ptr<Container> const& container)
@ -125,6 +149,12 @@ iterator will be valid. In addition it has the following constructor:
[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,
std::shared_ptr<Container> const& container)
// Backward compatibility with boost::shared_ptr
template <typename Container>
shared_container_iterator<Container>
make_shared_container_iterator(Container::iterator base,
@ -142,25 +172,23 @@ uses `make_shared_container_iterator()` to create the iterators.
[example_link shared_iterator_example2.cpp..`shared_iterator_example2.cpp`]:
#include "shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <boost/iterator/shared_container_iterator.hpp>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
#include <memory>
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,","));
void print_range_nl(Iterator begin, Iterator end) {
using val = typename std::iterator_traits<Iterator>::value_type;
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;
using ints_t = std::shared_ptr< std::vector<int> >;
{
ints_t ints(new std::vector<int>());
@ -171,12 +199,10 @@ uses `make_shared_container_iterator()` to create the iterators.
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));
print_range_nl(boost::iterators::make_shared_container_iterator(ints->begin(), ints),
boost::iterators::make_shared_container_iterator(ints->end(), ints));
}
return 0;
}
@ -187,53 +213,61 @@ named. The output from this example is the same as the previous.
[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(std::shared_ptr<Container> const& container);
// Backward compatibility with boost::shared_ptr
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));
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 functionally equivalent to this:
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.
In the following example, a range of values is returned as a pair of `shared_container_iterator` objects.
[example_link 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 <boost/iterator/shared_container_iterator.hpp>
#include <algorithm> // for std::copy
#include <iostream>
#include <vector>
#include <memory>
#include <tuple> // for std::tie
typedef boost::shared_container_iterator< std::vector<int> > iterator;
using iterator = boost::iterators::shared_container_iterator< std::vector<int> >;
std::pair<iterator,iterator>
std::pair<iterator, iterator>
return_range() {
boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
std::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);
return boost::iterators::make_shared_container_range(range);
}
int main() {
iterator i,end;
std::tie(i, end) = return_range();
boost::tie(i,end) = return_range();
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::copy(i, end, std::ostream_iterator<int>(std::cout, ","));
std::cout.put('\n');
return 0;

View File

@ -48,14 +48,14 @@ 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`]
[h2 `min_category`]
`minimum_category` takes two iterator categories or two iterator traversal tags
`min_category` takes one or more iterator categories or iterator traversal tags
and returns the one that is the weakest (i.e. least advanced). For example:
static_assert(
is_same<
minimum_category<
min_category<
std::forward_iterator_tag,
std::random_access_iterator_tag
>::type,

View File

@ -52,9 +52,10 @@ These two iterations can now be replaced with a single one as follows:
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
{
using result_type = void;
void operator()(const boost::tuple<const double&, const int&>& t) const
{
m_f0(t.get<0>());

View File

@ -8,7 +8,6 @@
:Author: David Abrahams and Jeremy Siek
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
:Organization: `Boost Consulting`_, Indiana University Bloomington
:date: $Date$
:Copyright: Copyright David Abrahams, Jeremy Siek 2003. Use, modification and
distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy

View File

@ -11,7 +11,6 @@
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -11,7 +11,6 @@
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -9,7 +9,6 @@
:Author: David Abrahams, Thomas Becker
:Contact: dave@boost-consulting.com, thomas@styleadvisor.com
:organization: `Boost Consulting`_, `Zephyr Associates, Inc.`_
:date: $Date$
:copyright: Copyright David Abrahams and Thomas Becker 2003.
.. _`Boost Consulting`: http://www.boost-consulting.com

View File

@ -6,11 +6,7 @@
# include "node.hpp"
# include <boost/iterator/iterator_facade.hpp>
# ifndef BOOST_NO_SFINAE
# include <boost/type_traits/is_convertible.hpp>
# include <boost/utility/enable_if.hpp>
# endif
# include <type_traits>
template <class Value>
class node_iter
@ -33,21 +29,13 @@ class node_iter
template <class OtherValue>
node_iter(
node_iter<OtherValue> const& other
# ifndef BOOST_NO_SFINAE
, typename boost::enable_if<
boost::is_convertible<OtherValue*,Value*>
, typename std::enable_if<
std::is_convertible<OtherValue*,Value*>::value
, enabler
>::type = enabler()
# endif
)
: m_node(other.m_node) {}
# if !BOOST_WORKAROUND(__GNUC__, == 2)
private: // GCC2 can't grant friendship to template member functions
friend class boost::iterator_core_access;
# endif
template <class OtherValue>
bool equal(node_iter<OtherValue> const& other) const
{

View File

@ -6,11 +6,7 @@
# include "node.hpp"
# include <boost/iterator/iterator_adaptor.hpp>
# ifndef BOOST_NO_SFINAE
# include <boost/type_traits/is_convertible.hpp>
# include <boost/utility/enable_if.hpp>
# endif
# include <type_traits>
template <class Value>
class node_iter
@ -38,12 +34,10 @@ class node_iter
template <class OtherValue>
node_iter(
node_iter<OtherValue> const& other
# ifndef BOOST_NO_SFINAE
, typename boost::enable_if<
boost::is_convertible<OtherValue*,Value*>
, typename std::enable_if<
std::is_convertible<OtherValue*,Value*>::value
, enabler
>::type = enabler()
# endif
)
: super_t(other.base()) {}

View File

@ -1,85 +1,14 @@
// (C) Copyright Jens Maurer 2001.
// (C) Copyright Andrey Semashev 2025.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Revision History:
// 15 Nov 2001 Jens Maurer
// created.
// See http://www.boost.org/libs/utility/iterator_adaptors.htm for documentation.
#ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
#define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
#include <boost/iterator/iterator_facade.hpp>
#include <boost/ref.hpp>
// This is a deprecated header left for backward compatibility.
// Please use <boost/iterator/generator_iterator.hpp> instead.
namespace boost {
namespace iterators {
template<class Generator>
class generator_iterator
: public iterator_facade<
generator_iterator<Generator>
, typename Generator::result_type
, single_pass_traversal_tag
, typename Generator::result_type const&
>
{
typedef iterator_facade<
generator_iterator<Generator>
, typename Generator::result_type
, single_pass_traversal_tag
, typename Generator::result_type const&
> super_t;
public:
generator_iterator() {}
generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {}
void increment()
{
m_value = (*m_g)();
}
const typename Generator::result_type&
dereference() const
{
return m_value;
}
bool equal(generator_iterator const& y) const
{
return this->m_g == y.m_g && this->m_value == y.m_value;
}
private:
Generator* m_g;
typename Generator::result_type m_value;
};
template<class Generator>
struct generator_iterator_generator
{
typedef generator_iterator<Generator> type;
};
template <class Generator>
inline generator_iterator<Generator>
make_generator_iterator(Generator & gen)
{
typedef generator_iterator<Generator> result_t;
return result_t(&gen);
}
} // namespace iterators
using iterators::generator_iterator;
using iterators::generator_iterator_generator;
using iterators::make_generator_iterator;
} // namespace boost
#include <boost/iterator/generator_iterator.hpp>
#endif // BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP

View File

@ -1,5 +1,5 @@
#ifndef INDIRECT_REFERENCE_DWA200415_HPP
# define INDIRECT_REFERENCE_DWA200415_HPP
#ifndef BOOST_INDIRECT_REFERENCE_DWA200415_HPP
#define BOOST_INDIRECT_REFERENCE_DWA200415_HPP
//
// Copyright David Abrahams 2004. Use, modification and distribution is
@ -11,33 +11,36 @@
// http://www.boost.org/libs/iterator/doc/pointee.html
//
# include <boost/detail/is_incrementable.hpp>
# include <boost/iterator/iterator_traits.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/pointee.hpp>
#include <type_traits>
#include <boost/detail/is_incrementable.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/pointee.hpp>
namespace boost {
namespace detail {
namespace detail
template< typename P >
struct smart_ptr_reference
{
template <class P>
struct smart_ptr_reference
{
typedef typename boost::pointee<P>::type& type;
};
}
using type = boost::pointee_t< P >&;
};
template <class P>
struct indirect_reference
: mpl::eval_if<
detail::is_incrementable<P>
, iterator_reference<P>
, detail::smart_ptr_reference<P>
>
} // namespace detail
template< typename P >
struct indirect_reference :
std::conditional<
detail::is_incrementable< P >::value,
iterator_reference< P >,
detail::smart_ptr_reference< P >
>::type
{
};
template< typename P >
using indirect_reference_t = typename indirect_reference< P >::type;
} // namespace boost
#endif // INDIRECT_REFERENCE_DWA200415_HPP
#endif // BOOST_INDIRECT_REFERENCE_DWA200415_HPP

View File

@ -8,83 +8,62 @@
#define BOOST_ITERATOR_ADVANCE_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/iterator/iterator_categories.hpp>
namespace boost {
namespace iterators {
namespace detail {
namespace detail {
template <typename InputIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
InputIterator& it
, Distance n
, incrementable_traversal_tag
)
template< typename InputIterator, typename Distance >
inline BOOST_CXX14_CONSTEXPR void advance_impl(InputIterator& it, Distance n, incrementable_traversal_tag)
{
while (n > 0)
{
++it;
--n;
}
}
template< typename BidirectionalIterator, typename Distance >
inline BOOST_CXX14_CONSTEXPR void advance_impl(BidirectionalIterator& it, Distance n, bidirectional_traversal_tag)
{
if (n >= 0)
{
while (n > 0)
{
while (n > 0) {
++it;
--n;
}
}
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, >= 40600)
// type-limits warning issued below when n is an unsigned integral
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
#endif
template <typename BidirectionalIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
BidirectionalIterator& it
, Distance n
, bidirectional_traversal_tag
)
{
if (n >= 0) {
while (n > 0) {
++it;
--n;
}
}
else {
while (n < 0) {
--it;
++n;
}
}
}
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, >= 40600)
#pragma GCC diagnostic pop
#endif
template <typename RandomAccessIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
RandomAccessIterator& it
, Distance n
, random_access_traversal_tag
)
{
it += n;
++it;
--n;
}
}
namespace advance_adl_barrier {
template <typename InputIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance(InputIterator& it, Distance n)
else
{
while (n < 0)
{
detail::advance_impl(
it, n, typename iterator_traversal<InputIterator>::type()
);
--it;
++n;
}
}
}
using namespace advance_adl_barrier;
template< typename RandomAccessIterator, typename Distance >
inline BOOST_CXX14_CONSTEXPR void advance_impl(RandomAccessIterator& it, Distance n, random_access_traversal_tag)
{
it += n;
}
} // namespace detail
namespace advance_adl_barrier {
template< typename InputIterator, typename Distance >
inline BOOST_CXX14_CONSTEXPR void advance(InputIterator& it, Distance n)
{
detail::advance_impl(it, n, typename iterator_traversal< InputIterator >::type());
}
} // namespace advance_adl_barrier
using namespace advance_adl_barrier;
} // namespace iterators

View File

@ -2,246 +2,212 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef COUNTING_ITERATOR_DWA200348_HPP
# define COUNTING_ITERATOR_DWA200348_HPP
#ifndef BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
#define BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
# include <boost/config.hpp>
# include <boost/static_assert.hpp>
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
# include <limits>
# elif !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
# include <boost/type_traits/is_convertible.hpp>
# else
# include <boost/type_traits/is_arithmetic.hpp>
# endif
# include <boost/type_traits/is_integral.hpp>
# include <boost/type_traits/type_identity.hpp>
# include <boost/type_traits/conditional.hpp>
# include <boost/type_traits/integral_constant.hpp>
# include <boost/detail/numeric_traits.hpp>
# include <boost/iterator/iterator_adaptor.hpp>
#include <limits>
#include <type_traits>
#include <boost/config.hpp>
#include <boost/core/use_default.hpp>
#include <boost/detail/numeric_traits.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/detail/if_default.hpp>
#include <boost/iterator/detail/eval_if_default.hpp>
#include <boost/iterator/detail/type_traits/type_identity.hpp>
namespace boost {
namespace iterators {
template <
class Incrementable
, class CategoryOrTraversal
, class Difference
template<
typename Incrementable,
typename CategoryOrTraversal,
typename Difference
>
class counting_iterator;
namespace detail
namespace detail {
// Try to detect numeric types at compile time in ways compatible
// with the limitations of the compiler and library.
template< typename T >
struct is_numeric :
public std::integral_constant< bool, std::numeric_limits< T >::is_specialized >
{};
template<>
struct is_numeric< long long > :
public std::true_type
{};
template<>
struct is_numeric< unsigned long long > :
public std::true_type
{};
#if defined(BOOST_HAS_INT128)
template<>
struct is_numeric< boost::int128_type > :
public std::true_type
{};
template<>
struct is_numeric< boost::uint128_type > :
public std::true_type
{};
#endif
// Some compilers fail to have a numeric_limits specialization
template<>
struct is_numeric< wchar_t > :
public std::true_type
{};
template< typename T >
struct numeric_difference
{
// Try to detect numeric types at compile time in ways compatible
// with the limitations of the compiler and library.
template <class T>
struct is_numeric_impl
{
// For a while, this wasn't true, but we rely on it below. This is a regression assert.
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
using type = typename boost::detail::numeric_traits< T >::difference_type;
};
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
#if defined(BOOST_HAS_INT128)
// std::numeric_limits, which is used by numeric_traits, is not specialized for __int128 in some standard libraries
template<>
struct numeric_difference< boost::int128_type >
{
using type = boost::int128_type;
};
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
template<>
struct numeric_difference< boost::uint128_type >
{
using type = boost::int128_type;
};
#endif
# else
template< typename Incrementable, typename CategoryOrTraversal, typename Difference, bool IsNumeric = is_numeric< Incrementable >::value >
struct counting_iterator_types
{
using traversal = detail::eval_if_default_t<
CategoryOrTraversal,
iterator_traversal< Incrementable >
>;
# if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
BOOST_STATIC_CONSTANT(
bool, value = (
boost::is_convertible<int,T>::value
&& boost::is_convertible<T,int>::value
));
# else
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
# endif
using difference = detail::eval_if_default_t<
Difference,
iterator_difference< Incrementable >
>;
};
# endif
};
template< typename Incrementable, typename CategoryOrTraversal, typename Difference >
struct counting_iterator_types< Incrementable, CategoryOrTraversal, Difference, true >
{
using traversal = detail::if_default_t<
CategoryOrTraversal,
random_access_traversal_tag
>;
template <class T>
struct is_numeric
: boost::integral_constant<bool, ::boost::iterators::detail::is_numeric_impl<T>::value>
{};
using difference = detail::eval_if_default_t<
Difference,
numeric_difference< Incrementable >
>;
};
# if defined(BOOST_HAS_LONG_LONG)
template <>
struct is_numeric<boost::long_long_type>
: boost::true_type {};
template< typename Incrementable, typename CategoryOrTraversal, typename Difference >
struct counting_iterator_base
{
using iterator_types = counting_iterator_types< Incrementable, CategoryOrTraversal, Difference >;
template <>
struct is_numeric<boost::ulong_long_type>
: boost::true_type {};
# endif
using type = iterator_adaptor<
counting_iterator< Incrementable, CategoryOrTraversal, Difference >, // self
Incrementable, // Base
#ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
const // MSVC won't strip this. Instead we enable Thomas'
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
#endif
Incrementable, // Value
typename iterator_types::traversal,
Incrementable const&, // reference
typename iterator_types::difference
>;
};
# if defined(BOOST_HAS_INT128)
template <>
struct is_numeric<boost::int128_type>
: boost::true_type {};
// A distance calculation policy for wrapped iterators
template< typename Difference, typename Incrementable1, typename Incrementable2 >
struct iterator_distance
{
static Difference distance(Incrementable1 x, Incrementable2 y)
{
return y - x;
}
};
template <>
struct is_numeric<boost::uint128_type>
: boost::true_type {};
# endif
// A distance calculation policy for wrapped numbers
template< typename Difference, typename Incrementable1, typename Incrementable2 >
struct number_distance
{
static Difference distance(Incrementable1 x, Incrementable2 y)
{
return boost::detail::numeric_distance(x, y);
}
};
// Some compilers fail to have a numeric_limits specialization
template <>
struct is_numeric<wchar_t>
: true_type {};
} // namespace detail
template <class T>
struct numeric_difference
{
typedef typename boost::detail::numeric_traits<T>::difference_type type;
};
# if defined(BOOST_HAS_INT128)
// std::numeric_limits, which is used by numeric_traits, is not specialized for __int128 in some standard libraries
template <>
struct numeric_difference<boost::int128_type>
{
typedef boost::int128_type type;
};
template <>
struct numeric_difference<boost::uint128_type>
{
typedef boost::int128_type type;
};
# endif
template <class Incrementable, class CategoryOrTraversal, class Difference>
struct counting_iterator_base
{
typedef typename detail::ia_dflt_help<
CategoryOrTraversal
, typename boost::conditional<
is_numeric<Incrementable>::value
, boost::type_identity<random_access_traversal_tag>
, iterator_traversal<Incrementable>
>::type
>::type traversal;
typedef typename detail::ia_dflt_help<
Difference
, typename boost::conditional<
is_numeric<Incrementable>::value
, numeric_difference<Incrementable>
, iterator_difference<Incrementable>
>::type
>::type difference;
typedef iterator_adaptor<
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
, Incrementable // Base
, Incrementable // Value
# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
const // MSVC won't strip this. Instead we enable Thomas'
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
# endif
, traversal
, Incrementable const& // reference
, difference
> type;
};
// Template class distance_policy_select -- choose a policy for computing the
// distance between counting_iterators at compile-time based on whether or not
// the iterator wraps an integer or an iterator, using "poor man's partial
// specialization".
template <bool is_integer> struct distance_policy_select;
// A policy for wrapped iterators
template <class Difference, class Incrementable1, class Incrementable2>
struct iterator_distance
{
static Difference distance(Incrementable1 x, Incrementable2 y)
{
return y - x;
}
};
// A policy for wrapped numbers
template <class Difference, class Incrementable1, class Incrementable2>
struct number_distance
{
static Difference distance(Incrementable1 x, Incrementable2 y)
{
return boost::detail::numeric_distance(x, y);
}
};
}
template <
class Incrementable
, class CategoryOrTraversal = use_default
, class Difference = use_default
template<
typename Incrementable,
typename CategoryOrTraversal = use_default,
typename Difference = use_default
>
class counting_iterator
: public detail::counting_iterator_base<
Incrementable, CategoryOrTraversal, Difference
>::type
class counting_iterator :
public detail::counting_iterator_base< Incrementable, CategoryOrTraversal, Difference >::type
{
typedef typename detail::counting_iterator_base<
Incrementable, CategoryOrTraversal, Difference
>::type super_t;
friend class iterator_core_access;
public:
typedef typename super_t::difference_type difference_type;
private:
using super_t = typename detail::counting_iterator_base<
Incrementable, CategoryOrTraversal, Difference
>::type;
BOOST_DEFAULTED_FUNCTION(counting_iterator(), {})
public:
using reference = typename super_t::reference;
using difference_type = typename super_t::difference_type;
BOOST_DEFAULTED_FUNCTION(counting_iterator(counting_iterator const& rhs), : super_t(rhs.base()) {})
counting_iterator() = default;
counting_iterator(Incrementable x)
: super_t(x)
counting_iterator(counting_iterator const&) = default;
counting_iterator& operator=(counting_iterator const&) = default;
counting_iterator(Incrementable x) :
super_t(x)
{
}
# if 0
template<class OtherIncrementable>
counting_iterator(
counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& t
, typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
)
: super_t(t.base())
{}
# endif
BOOST_DEFAULTED_FUNCTION(counting_iterator& operator=(counting_iterator const& rhs), { *static_cast< super_t* >(this) = static_cast< super_t const& >(rhs); return *this; })
private:
typename super_t::reference dereference() const
private:
reference dereference() const
{
return this->base_reference();
}
template <class OtherIncrementable>
template< typename OtherIncrementable >
difference_type
distance_to(counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& y) const
distance_to(counting_iterator< OtherIncrementable, CategoryOrTraversal, Difference > const& y) const
{
typedef typename boost::conditional<
detail::is_numeric<Incrementable>::value
, detail::number_distance<difference_type, Incrementable, OtherIncrementable>
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
>::type d;
using distance_traits = typename std::conditional<
detail::is_numeric< Incrementable >::value,
detail::number_distance< difference_type, Incrementable, OtherIncrementable >,
detail::iterator_distance< difference_type, Incrementable, OtherIncrementable >
>::type;
return d::distance(this->base(), y.base());
return distance_traits::distance(this->base(), y.base());
}
};
// Manufacture a counting iterator for an arbitrary incrementable type
template <class Incrementable>
inline counting_iterator<Incrementable>
make_counting_iterator(Incrementable x)
template< typename Incrementable >
inline counting_iterator< Incrementable > make_counting_iterator(Incrementable x)
{
typedef counting_iterator<Incrementable> result_t;
return result_t(x);
return counting_iterator< Incrementable >(x);
}
} // namespace iterators
@ -251,4 +217,4 @@ using iterators::make_counting_iterator;
} // namespace boost
#endif // COUNTING_ITERATOR_DWA200348_HPP
#endif // BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP

View File

@ -1,21 +0,0 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP
# define ANY_CONVERSION_EATER_DWA20031117_HPP
namespace boost {
namespace iterators {
namespace detail {
// This type can be used in traits to "eat" up the one user-defined
// implicit conversion allowed.
struct any_conversion_eater
{
template <class T>
any_conversion_eater(T const&);
};
}}} // namespace boost::iterators::detail
#endif // ANY_CONVERSION_EATER_DWA20031117_HPP

View File

@ -26,8 +26,6 @@
// libs/iterator/test/constant_iterator_arrow.cpp fails to compile
// because the operator-> return is improperly deduced as a non-const
// pointer.
#if 1 || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x531))
// Recall that in general, compilers without partial specialization
// can't strip constness. Consider counting_iterator, which normally
@ -44,85 +42,4 @@
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
#endif
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x5A0)) \
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \
|| BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) \
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
# define BOOST_NO_LVALUE_RETURN_DETECTION
# if 0 // test code
struct v {};
typedef char (&no)[3];
template <class T>
no foo(T const&, ...);
template <class T>
char foo(T&, int);
struct value_iterator
{
v operator*() const;
};
template <class T>
struct lvalue_deref_helper
{
static T& x;
enum { value = (sizeof(foo(*x,0)) == 1) };
};
int z2[(lvalue_deref_helper<v*>::value == 1) ? 1 : -1];
int z[(lvalue_deref_helper<value_iterator>::value) == 1 ? -1 : 1 ];
# endif
#endif
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types"
#endif
#if BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \
|| BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
# define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile:
# if 0 // test code
#include <boost/type_traits/is_convertible.hpp>
template <class T>
struct foo
{
foo(T);
template <class U>
foo(foo<U> const& other) : p(other.p) { }
T p;
};
bool x = boost::is_convertible<foo<int const*>, foo<int*> >::value;
# endif
#endif
#if !defined(BOOST_MSVC) && (defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_IS_CONVERTIBLE_TEMPLATE))
# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
#endif
# if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
// GCC-2.95 (obsolete) eagerly instantiates templated constructors and conversion
// operators in convertibility checks, causing premature errors.
//
// Borland's problems are harder to diagnose due to lack of an
// instantiation stack backtrace. They may be due in part to the fact
// that it drops cv-qualification willy-nilly in templates.
# define BOOST_NO_ONE_WAY_ITERATOR_INTEROP
# endif
// no include guard; multiple inclusion intended

View File

@ -11,11 +11,7 @@
// 23/02/03 thw
//
#undef BOOST_NO_IS_CONVERTIBLE
#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
#undef BOOST_NO_LVALUE_RETURN_DETECTION
#undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
#undef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
#ifdef BOOST_ITERATOR_CONFIG_DEF
# undef BOOST_ITERATOR_CONFIG_DEF

View File

@ -1,83 +0,0 @@
// (C) Copyright David Abrahams 2002.
// (C) Copyright Jeremy Siek 2002.
// (C) Copyright Thomas Witt 2002.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ENABLE_IF_23022003THW_HPP
#define BOOST_ENABLE_IF_23022003THW_HPP
#include <boost/config.hpp>
#include <boost/iterator/detail/config_def.hpp>
#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE)
#include <boost/type_traits/type_identity.hpp>
#endif
//
// Boost iterators uses its own enable_if cause we need
// special semantics for deficient compilers.
// 23/02/03 thw
//
namespace boost
{
namespace iterators
{
//
// Base machinery for all kinds of enable if
//
template<bool>
struct enabled
{
template<typename T>
struct base
{
typedef T type;
};
};
//
// For compilers that don't support "Substitution Failure Is Not An Error"
// enable_if falls back to always enabled. See comments
// on operator implementation for consequences.
//
template<>
struct enabled<false>
{
template<typename T>
struct base
{
#ifdef BOOST_NO_SFINAE
typedef T type;
// This way to do it would give a nice error message containing
// invalid overload, but has the big disadvantage that
// there is no reference to user code in the error message.
//
// struct invalid_overload;
// typedef invalid_overload type;
//
#endif
};
};
template <class Cond,
class Return>
struct enable_if
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
: enabled<(Cond::value)>::template base<Return>
# else
: boost::type_identity<Return>
# endif
{
};
} // namespace iterators
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_ENABLE_IF_23022003THW_HPP

View File

@ -0,0 +1,44 @@
/*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Copyright (c) 2025 Andrey Semashev
*/
#ifndef BOOST_ITERATOR_DETAIL_EVAL_IF_DEFAULT_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_EVAL_IF_DEFAULT_HPP_INCLUDED_
#include <boost/core/use_default.hpp>
#include <boost/iterator/detail/type_traits/type_identity.hpp>
namespace boost {
namespace iterators {
namespace detail {
// If T is use_default, return the result of invoking
// DefaultNullaryFn, otherwise - of NondefaultNullaryFn.
// By default, NondefaultNullaryFn returns T, which means
// the metafunction can be called with just two parameters
// and in that case will return either T or the result of
// invoking DefaultNullaryFn.
template< typename T, typename DefaultNullaryFn, typename NondefaultNullaryFn = detail::type_identity< T > >
struct eval_if_default
{
using type = typename NondefaultNullaryFn::type;
};
template< typename DefaultNullaryFn, typename NondefaultNullaryFn >
struct eval_if_default< use_default, DefaultNullaryFn, NondefaultNullaryFn >
{
using type = typename DefaultNullaryFn::type;
};
template< typename T, typename DefaultNullaryFn, typename NondefaultNullaryFn = detail::type_identity< T > >
using eval_if_default_t = typename eval_if_default< T, DefaultNullaryFn, NondefaultNullaryFn >::type;
} // namespace detail
} // namespace iterators
} // namespace boost
#endif // BOOST_ITERATOR_DETAIL_EVAL_IF_DEFAULT_HPP_INCLUDED_

View File

@ -2,31 +2,17 @@
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
#define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
# include <boost/core/use_default.hpp>
#include <iterator>
#include <type_traits>
# include <boost/iterator/iterator_categories.hpp>
#include <boost/mp11/utility.hpp>
# include <boost/mpl/or.hpp> // used in iterator_tag inheritance logic
# include <boost/mpl/and.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/assert.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_const.hpp>
# include <boost/type_traits/is_reference.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/iterator/detail/config_def.hpp> // try to keep this last
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
# include <boost/detail/indirect_traits.hpp>
# endif
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/detail/type_traits/conjunction.hpp>
#include <boost/iterator/detail/type_traits/disjunction.hpp>
#include <boost/iterator/detail/config_def.hpp> // try to keep this last
//
// iterator_category deduction for iterator_facade
@ -34,45 +20,49 @@
namespace boost {
namespace iterators {
using boost::use_default;
namespace detail {
struct input_output_iterator_tag
: std::input_iterator_tag
{
// Using inheritance for only input_iterator_tag helps to avoid
// ambiguities when a stdlib implementation dispatches on a
// function which is overloaded on both input_iterator_tag and
// output_iterator_tag, as STLPort does, in its __valid_range
// function. I claim it's better to avoid the ambiguity in these
// cases.
operator std::output_iterator_tag() const
{
return std::output_iterator_tag();
}
};
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
template< typename T >
struct is_const_lvalue_reference :
public std::false_type
{};
template< typename T >
struct is_const_lvalue_reference< T const& > :
public std::true_type
{};
#endif // BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
//
// True iff the user has explicitly disabled writability of this
// iterator. Pass the iterator_facade's Value parameter and its
// nested ::reference type.
//
template <class ValueParam, class Reference>
struct iterator_writability_disabled
template< typename ValueParam, typename Reference >
struct iterator_writability_disabled :
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
: mpl::or_<
is_const<Reference>
, boost::detail::indirect_traits::is_reference_to_const<Reference>
, is_const<ValueParam>
public detail::disjunction<
detail::is_const_lvalue_reference< Reference >,
std::is_const< Reference >,
std::is_const< ValueParam >
>
# else
: is_const<ValueParam>
public std::is_const< ValueParam >
# endif
{};
template< typename Traversal, typename ValueParam, typename Reference >
using is_traversal_of_input_iterator = detail::conjunction<
std::is_convertible< Traversal, single_pass_traversal_tag >,
// check for readability
std::is_convertible< Reference, ValueParam >
>;
//
// Convert an iterator_facade's traversal category, Value parameter,
// and ::reference type to an appropriate old-style category.
@ -81,114 +71,109 @@ struct iterator_writability_disabled
// to output_iterator_tag.
//
// Change at: https://svn.boost.org/trac/boost/changeset/21683
template <class Traversal, class ValueParam, class Reference>
template< typename Traversal, typename ValueParam, typename Reference >
struct iterator_facade_default_category
: mpl::eval_if<
mpl::and_<
is_reference<Reference>
, is_convertible<Traversal,forward_traversal_tag>
>
, mpl::eval_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<std::random_access_iterator_tag>
, mpl::if_<
is_convertible<Traversal,bidirectional_traversal_tag>
, std::bidirectional_iterator_tag
, std::forward_iterator_tag
>
>
, typename mpl::eval_if<
mpl::and_<
is_convertible<Traversal, single_pass_traversal_tag>
// check for readability
, is_convertible<Reference, ValueParam>
>
, mpl::identity<std::input_iterator_tag>
, mpl::identity<Traversal>
>
>
{
using type = typename std::conditional<
detail::is_traversal_of_input_iterator< Traversal, ValueParam, Reference >::value,
std::input_iterator_tag,
Traversal
>::type;
};
// Specialization for the (typical) case when the reference type is an actual reference
template< typename Traversal, typename ValueParam, typename Referenced >
struct iterator_facade_default_category< Traversal, ValueParam, Referenced& >
{
using type = mp11::mp_cond<
std::is_convertible< Traversal, random_access_traversal_tag >, std::random_access_iterator_tag,
std::is_convertible< Traversal, bidirectional_traversal_tag >, std::bidirectional_iterator_tag,
std::is_convertible< Traversal, forward_traversal_tag >, std::forward_iterator_tag,
detail::is_traversal_of_input_iterator< Traversal, ValueParam, Referenced& >, std::input_iterator_tag,
std::true_type, Traversal
>;
};
template< typename Traversal, typename ValueParam, typename Reference >
using iterator_facade_default_category_t = typename iterator_facade_default_category< Traversal, ValueParam, Reference >::type;
// True iff T is convertible to an old-style iterator category.
template <class T>
struct is_iterator_category
: mpl::or_<
is_convertible<T,std::input_iterator_tag>
, is_convertible<T,std::output_iterator_tag>
template< typename T >
struct is_iterator_category :
public detail::disjunction<
std::is_convertible< T, std::input_iterator_tag >,
std::is_convertible< T, std::output_iterator_tag >
>
{
};
template <class T>
struct is_iterator_traversal
: is_convertible<T,incrementable_traversal_tag>
{};
template< typename T >
struct is_iterator_traversal :
public std::is_convertible< T, incrementable_traversal_tag >
{};
//
// A composite iterator_category tag convertible to Category (a pure
// old-style category) and Traversal (a pure traversal tag).
// Traversal must be a strict increase of the traversal power given by
// Category.
//
template <class Category, class Traversal>
struct iterator_category_with_traversal
: Category, Traversal
template< typename Category, typename Traversal >
struct iterator_category_with_traversal :
public Category,
public Traversal
{
// Make sure this isn't used to build any categories where
// convertibility to Traversal is redundant. Should just use the
// Category element in that case.
BOOST_MPL_ASSERT_NOT((
is_convertible<
typename iterator_category_to_traversal<Category>::type
, Traversal
>));
static_assert(
!std::is_convertible< iterator_category_to_traversal_t< Category >, Traversal >::value,
"Category transformed to corresponding traversal must be convertible to Traversal."
);
BOOST_MPL_ASSERT((is_iterator_category<Category>));
BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
BOOST_MPL_ASSERT_NOT((is_iterator_traversal<Category>));
# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
BOOST_MPL_ASSERT((is_iterator_traversal<Traversal>));
# endif
static_assert(is_iterator_category< Category >::value, "Category must be an STL iterator category.");
static_assert(!is_iterator_category< Traversal >::value, "Traversal must not be an STL iterator category.");
static_assert(!is_iterator_traversal< Category >::value, "Category must not be a traversal tag.");
static_assert(is_iterator_traversal< Traversal >::value, "Traversal must be a traversal tag.");
};
// Computes an iterator_category tag whose traversal is Traversal and
// which is appropriate for an iterator
template <class Traversal, class ValueParam, class Reference>
template< typename Traversal, typename ValueParam, typename Reference >
struct facade_iterator_category_impl
{
BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
static_assert(!is_iterator_category< Traversal >::value, "Traversal must not be an STL iterator category.");
typedef typename iterator_facade_default_category<
Traversal,ValueParam,Reference
>::type category;
using category = iterator_facade_default_category_t< Traversal, ValueParam, Reference >;
typedef typename mpl::if_<
is_same<
Traversal
, typename iterator_category_to_traversal<category>::type
>
, category
, iterator_category_with_traversal<category,Traversal>
>::type type;
using type = typename std::conditional<
std::is_same<
Traversal,
typename iterator_category_to_traversal< category >::type
>::value,
category,
iterator_category_with_traversal< category, Traversal >
>::type;
};
template< typename Traversal, typename ValueParam, typename Reference >
using facade_iterator_category_impl_t = typename facade_iterator_category_impl< Traversal, ValueParam, Reference >::type;
//
// Compute an iterator_category for iterator_facade
//
template <class CategoryOrTraversal, class ValueParam, class Reference>
template< typename CategoryOrTraversal, typename ValueParam, typename Reference >
struct facade_iterator_category
: mpl::eval_if<
is_iterator_category<CategoryOrTraversal>
, mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
, facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
>
{
using type = mp11::mp_eval_if<
is_iterator_category< CategoryOrTraversal >,
CategoryOrTraversal, // old-style categories are fine as-is
facade_iterator_category_impl_t, CategoryOrTraversal, ValueParam, Reference
>;
};
}}} // namespace boost::iterators::detail
# include <boost/iterator/detail/config_undef.hpp>
#include <boost/iterator/detail/config_undef.hpp>
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP

View File

@ -0,0 +1,41 @@
/*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Copyright (c) 2025 Andrey Semashev
*/
#ifndef BOOST_ITERATOR_DETAIL_IF_DEFAULT_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_IF_DEFAULT_HPP_INCLUDED_
#include <boost/core/use_default.hpp>
namespace boost {
namespace iterators {
namespace detail {
// If T is use_default, return Default, otherwise - Nondefault.
// By default, Nondefault is T, which means
// the metafunction can be called with just two parameters
// and in that case will return either T or Default.
template< typename T, typename Default, typename Nondefault = T >
struct if_default
{
using type = Nondefault;
};
template< typename Default, typename Nondefault >
struct if_default< use_default, Default, Nondefault >
{
using type = Default;
};
template< typename T, typename Default, typename Nondefault = T >
using if_default_t = typename if_default< T, Default, Nondefault >::type;
} // namespace detail
} // namespace iterators
} // namespace boost
#endif // BOOST_ITERATOR_DETAIL_IF_DEFAULT_HPP_INCLUDED_

View File

@ -1,19 +0,0 @@
// Copyright David Abrahams 2003. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP
# define MINIMUM_CATEGORY_DWA20031119_HPP
# include <boost/iterator/minimum_category.hpp>
namespace boost {
// This import below (as well as the whole header) is for backward compatibility
// with boost/token_iterator.hpp. It should be removed as soon as that header is fixed.
namespace detail {
using iterators::minimum_category;
} // namespace detail
} // namespace boost
#endif // MINIMUM_CATEGORY_DWA20031119_HPP

View File

@ -0,0 +1,53 @@
/*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Copyright (c) 2024 Georgiy Guminov
*/
/*!
* \file iterator/detail/type_traits/conjunction.hpp
*
* This header contains definition of \c conjunction type trait.
*/
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
#include <type_traits>
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
namespace boost {
namespace iterators {
namespace detail {
using std::conjunction;
} // namespace detail
} // namespace iterator
} // namespace boost
#else
#include <boost/type_traits/conjunction.hpp>
namespace boost {
namespace iterators {
namespace detail {
using boost::conjunction;
} // namespace detail
} // namespace iterator
} // namespace boost
#endif
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_

View File

@ -0,0 +1,53 @@
/*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Copyright (c) 2024 Georgiy Guminov
*/
/*!
* \file iterator/detail/type_traits/disjunction.hpp
*
* This header contains definition of \c disjunction type trait.
*/
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
#include <type_traits>
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
namespace boost {
namespace iterators {
namespace detail {
using std::disjunction;
} // namespace detail
} // namespace iterator
} // namespace boost
#else
#include <boost/type_traits/disjunction.hpp>
namespace boost {
namespace iterators {
namespace detail {
using boost::disjunction;
} // namespace detail
} // namespace iterator
} // namespace boost
#endif
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_

View File

@ -0,0 +1,53 @@
/*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Copyright (c) 2024 Georgiy Guminov
*/
/*!
* \file iterator/detail/type_traits/negation.hpp
*
* This header contains definition of \c negation type trait.
*/
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
#include <type_traits>
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
namespace boost {
namespace iterators {
namespace detail {
using std::negation;
} // namespace detail
} // namespace iterator
} // namespace boost
#else
#include <boost/type_traits/negation.hpp>
namespace boost {
namespace iterators {
namespace detail {
using boost::negation;
} // namespace detail
} // namespace iterator
} // namespace boost
#endif
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_

View File

@ -0,0 +1,54 @@
/*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Copyright (c) 2025 Andrey Semashev
*/
/*!
* \file iterator/detail/type_traits/type_identity.hpp
*
* This header contains definition of \c negation type trait.
*/
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED_
#include <type_traits>
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if (defined(__cpp_lib_type_identity) && (__cpp_lib_type_identity >= 201806l)) || \
/* Note: MSVC 19.21 does not define _MSVC_LANG to 202002 in c++latest (C++20) mode but to a value larger than 201703 */ \
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 142) && (_MSC_VER >= 1921) && (BOOST_CXX_VERSION > 201703l))
namespace boost {
namespace iterators {
namespace detail {
using std::type_identity;
} // namespace detail
} // namespace iterator
} // namespace boost
#else
#include <boost/type_traits/type_identity.hpp>
namespace boost {
namespace iterators {
namespace detail {
using boost::type_identity;
} // namespace detail
} // namespace iterator
} // namespace boost
#endif
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED_

View File

@ -13,48 +13,42 @@
namespace boost {
namespace iterators {
namespace detail {
namespace detail {
template <typename SinglePassIterator>
inline BOOST_CXX14_CONSTEXPR typename iterator_difference<SinglePassIterator>::type
distance_impl(
SinglePassIterator first
, SinglePassIterator last
, single_pass_traversal_tag
)
{
typename iterator_difference<SinglePassIterator>::type n = 0;
while (first != last) {
++first;
++n;
}
return n;
}
template <typename RandomAccessIterator>
inline BOOST_CXX14_CONSTEXPR typename iterator_difference<RandomAccessIterator>::type
distance_impl(
RandomAccessIterator first
, RandomAccessIterator last
, random_access_traversal_tag
)
{
return last - first;
}
template< typename SinglePassIterator >
inline BOOST_CXX14_CONSTEXPR typename iterator_difference< SinglePassIterator >::type
distance_impl(SinglePassIterator first, SinglePassIterator last, single_pass_traversal_tag)
{
typename iterator_difference< SinglePassIterator >::type n = 0;
while (first != last)
{
++first;
++n;
}
return n;
}
namespace distance_adl_barrier {
template <typename SinglePassIterator>
inline BOOST_CXX14_CONSTEXPR typename iterator_difference<SinglePassIterator>::type
distance(SinglePassIterator first, SinglePassIterator last)
{
return detail::distance_impl(
first, last, typename iterator_traversal<SinglePassIterator>::type()
);
}
}
template< typename RandomAccessIterator >
inline BOOST_CXX14_CONSTEXPR typename iterator_difference< RandomAccessIterator >::type
distance_impl(RandomAccessIterator first, RandomAccessIterator last, random_access_traversal_tag)
{
return last - first;
}
using namespace distance_adl_barrier;
} // namespace detail
namespace distance_adl_barrier {
template< typename SinglePassIterator >
inline BOOST_CXX14_CONSTEXPR typename iterator_difference< SinglePassIterator >::type
distance(SinglePassIterator first, SinglePassIterator last)
{
return detail::distance_impl(first, last, typename iterator_traversal< SinglePassIterator >::type());
}
} // namespace distance_adl_barrier
using namespace distance_adl_barrier;
} // namespace iterators

View File

@ -0,0 +1,84 @@
/*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Copyright (c) 2025 Andrey Semashev
*/
#ifndef BOOST_ITERATOR_ENABLE_IF_CONVERTIBLE_HPP_INCLUDED_
#define BOOST_ITERATOR_ENABLE_IF_CONVERTIBLE_HPP_INCLUDED_
#include <type_traits>
namespace boost {
namespace iterators {
namespace detail {
//
// Result type used in enable_if_convertible meta function.
// This can be an incomplete type, as only pointers to
// enable_if_convertible< ... >::type are used.
// We could have used void for this, but conversion to
// void* is just too easy.
//
struct enable_type;
} // namespace detail
//
// enable_if for use in adapted iterators constructors.
//
// In order to provide interoperability between adapted constant and
// mutable iterators, adapted iterators will usually provide templated
// conversion constructors of the following form
//
// template <class BaseIterator>
// class adapted_iterator :
// public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
// {
// public:
//
// ...
//
// template <class OtherIterator>
// adapted_iterator(
// OtherIterator const& it
// , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
//
// ...
// };
//
// enable_if_convertible is used to remove those overloads from the overload
// set that cannot be instantiated. For all practical purposes only overloads
// for constant/mutable interaction will remain. This has the advantage that
// meta functions like boost::is_convertible do not return false positives,
// as they can only look at the signature of the conversion constructor
// and not at the actual instantiation.
//
// enable_if_interoperable can be safely used in user code. It falls back to
// always enabled for compilers that don't support enable_if or is_convertible.
// There is no need for compiler specific workarounds in user code.
//
// The operators implementation relies on boost::is_convertible not returning
// false positives for user/library defined iterator types. See comments
// on operator implementation for consequences.
//
template< typename From, typename To >
struct enable_if_convertible :
public std::enable_if<
std::is_convertible< From, To >::value,
boost::iterators::detail::enable_type
>
{};
template< typename From, typename To >
using enable_if_convertible_t = typename enable_if_convertible< From, To >::type;
} // namespace iterators
using iterators::enable_if_convertible;
} // namespace boost
#endif // BOOST_ITERATOR_ENABLE_IF_CONVERTIBLE_HPP_INCLUDED_

View File

@ -7,124 +7,145 @@
#ifndef BOOST_FILTER_ITERATOR_23022003THW_HPP
#define BOOST_FILTER_ITERATOR_23022003THW_HPP
#include <type_traits>
#include <boost/core/use_default.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/static_assert.hpp>
#include <boost/iterator/enable_if_convertible.hpp>
namespace boost {
namespace iterators {
template <class Predicate, class Iterator>
class filter_iterator;
template< typename Predicate, typename Iterator >
class filter_iterator;
namespace detail
{
template <class Predicate, class Iterator>
struct filter_iterator_base
namespace detail {
template< typename Predicate, typename Iterator >
using filter_iterator_base_t = iterator_adaptor<
filter_iterator< Predicate, Iterator >,
Iterator,
use_default,
typename std::conditional<
std::is_convertible<
iterator_traversal_t< Iterator >,
random_access_traversal_tag
>::value,
bidirectional_traversal_tag,
use_default
>::type
>;
} // namespace detail
template< typename Predicate, typename Iterator >
class filter_iterator :
public detail::filter_iterator_base_t< Predicate, Iterator >
{
friend class iterator_core_access;
template< typename, typename >
friend class filter_iterator;
private:
using super_t = detail::filter_iterator_base_t< Predicate, Iterator >;
// Storage class to leverage EBO, when possible
struct storage :
private boost::empty_value< Predicate >
{
typedef iterator_adaptor<
filter_iterator<Predicate, Iterator>
, Iterator
, use_default
, typename mpl::if_<
is_convertible<
typename iterator_traversal<Iterator>::type
, random_access_traversal_tag
>
, bidirectional_traversal_tag
, use_default
>::type
> type;
using predicate_base = boost::empty_value< Predicate >;
Iterator m_end;
storage() = default;
template<
typename Iter,
typename = typename std::enable_if<
!std::is_same<
typename std::remove_cv< typename std::remove_reference< Iter >::type >::type,
storage
>::value
>
>
explicit storage(Iter&& end) :
predicate_base(boost::empty_init_t{}), m_end(static_cast< Iterator&& >(end))
{
}
template< typename Pred, typename Iter >
storage(Pred&& pred, Iter&& end) :
predicate_base(boost::empty_init_t{}, static_cast< Pred&& >(pred)), m_end(static_cast< Iter&& >(end))
{
}
Predicate& predicate() noexcept { return predicate_base::get(); }
Predicate const& predicate() const noexcept { return predicate_base::get(); }
};
}
template <class Predicate, class Iterator>
class filter_iterator
: public detail::filter_iterator_base<Predicate, Iterator>::type
{
typedef typename detail::filter_iterator_base<
Predicate, Iterator
>::type super_t;
public:
filter_iterator() = default;
friend class iterator_core_access;
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator()) :
super_t(static_cast< Iterator&& >(x)), m_storage(static_cast< Predicate&& >(f), static_cast< Iterator&& >(end))
{
satisfy_predicate();
}
public:
filter_iterator() { }
template< bool Requires = std::is_class< Predicate >::value, typename = typename std::enable_if< Requires >::type >
filter_iterator(Iterator x, Iterator end = Iterator()) :
super_t(static_cast< Iterator&& >(x)), m_storage(static_cast< Iterator&& >(end))
{
satisfy_predicate();
}
filter_iterator(Predicate f, Iterator x, Iterator end_ = Iterator())
: super_t(x), m_predicate(f), m_end(end_)
{
satisfy_predicate();
}
template< typename OtherIterator, typename = enable_if_convertible_t< OtherIterator, Iterator > >
filter_iterator(filter_iterator< Predicate, OtherIterator > const& t) :
super_t(t.base()), m_storage(t.m_storage.predicate(), t.m_storage.m_end)
{}
filter_iterator(Iterator x, Iterator end_ = Iterator())
: super_t(x), m_predicate(), m_end(end_)
{
// Pro8 is a little too aggressive about instantiating the
// body of this function.
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
// Don't allow use of this constructor if Predicate is a
// function pointer type, since it will be 0.
BOOST_STATIC_ASSERT(is_class<Predicate>::value);
#endif
satisfy_predicate();
}
Predicate predicate() const { return m_storage.predicate(); }
Iterator end() const { return m_storage.m_end; }
template<class OtherIterator>
filter_iterator(
filter_iterator<Predicate, OtherIterator> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
)
: super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {}
private:
void increment()
{
++(this->base_reference());
satisfy_predicate();
}
Predicate predicate() const { return m_predicate; }
void decrement()
{
while (!m_storage.predicate()(*--(this->base_reference()))) {}
}
Iterator end() const { return m_end; }
void satisfy_predicate()
{
while (this->base() != m_storage.m_end && !m_storage.predicate()(*this->base()))
++(this->base_reference());
}
private:
void increment()
{
++(this->base_reference());
satisfy_predicate();
}
private:
storage m_storage;
};
void decrement()
{
while(!this->m_predicate(*--(this->base_reference()))){};
}
template< typename Predicate, typename Iterator >
inline filter_iterator< Predicate, Iterator > make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
{
return filter_iterator< Predicate, Iterator >(static_cast< Predicate&& >(f), static_cast< Iterator&& >(x), static_cast< Iterator&& >(end));
}
void satisfy_predicate()
{
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
++(this->base_reference());
}
// Probably should be the initial base class so it can be
// optimized away via EBO if it is an empty class.
Predicate m_predicate;
Iterator m_end;
};
template <class Predicate, class Iterator>
inline filter_iterator<Predicate,Iterator>
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
{
return filter_iterator<Predicate,Iterator>(f,x,end);
}
template <class Predicate, class Iterator>
inline filter_iterator<Predicate,Iterator>
make_filter_iterator(
typename iterators::enable_if<
is_class<Predicate>
, Iterator
>::type x
, Iterator end = Iterator())
{
return filter_iterator<Predicate,Iterator>(x,end);
}
template< typename Predicate, typename Iterator >
inline typename std::enable_if<
std::is_class< Predicate >::value,
filter_iterator< Predicate, Iterator >
>::type make_filter_iterator(Iterator x, Iterator end = Iterator())
{
return filter_iterator< Predicate, Iterator >(static_cast< Iterator&& >(x), static_cast< Iterator&& >(end));
}
} // namespace iterators

View File

@ -6,160 +6,150 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_FUNCTION_INPUT_ITERATOR
#define BOOST_FUNCTION_INPUT_ITERATOR
#ifndef BOOST_ITERATOR_FUNCTION_INPUT_ITERATOR_HPP_INCLUDED_
#define BOOST_ITERATOR_FUNCTION_INPUT_ITERATOR_HPP_INCLUDED_
#include <memory>
#include <type_traits>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/core/addressof.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/function_types/is_function_pointer.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/none.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/detail/type_traits/conjunction.hpp>
#include <boost/optional/optional.hpp>
#include <boost/utility/result_of.hpp>
#ifdef BOOST_RESULT_OF_USE_TR1
#include <boost/type_traits/is_function.hpp>
#endif
namespace boost {
namespace iterators {
namespace impl {
template< typename Function, typename Input >
class function_input_iterator;
// Computes the return type of an lvalue-call with an empty argument,
// i.e. decltype(declval<F&>()()). F should be a nullary lvalue-callable
// or function.
template <class F>
struct result_of_nullary_lvalue_call
{
typedef typename result_of<
#ifdef BOOST_RESULT_OF_USE_TR1
typename boost::conditional<is_function<F>::value, F&, F>::type()
#else
F&()
#endif
>::type type;
};
namespace detail {
template <class Function, class Input>
class function_input_iterator :
public iterator_facade<
function_input_iterator<Function, Input>,
typename result_of_nullary_lvalue_call<Function>::type,
single_pass_traversal_tag,
typename result_of_nullary_lvalue_call<Function>::type const &
>
{
public:
function_input_iterator() {}
function_input_iterator(Function & f_, Input state_ = Input())
: f(boost::addressof(f_)), state(state_) {}
template< typename Function, typename Input >
using function_input_iterator_facade_base_t = iterator_facade<
iterators::function_input_iterator< Function, Input >,
decltype(std::declval< Function& >()()),
single_pass_traversal_tag,
decltype(std::declval< Function& >()()) const&
>;
void increment() {
if(value)
value = none;
else
(*f)();
++state;
}
template< typename Function, typename Input >
class function_object_input_iterator :
public function_input_iterator_facade_base_t< Function, Input >
{
private:
using base_type = function_input_iterator_facade_base_t< Function, Input >;
typename result_of_nullary_lvalue_call<Function>::type const &
dereference() const {
return (value ? value : value = (*f)()).get();
}
protected:
using function_arg_type = Function&;
bool equal(function_input_iterator const & other) const {
return f == other.f && state == other.state;
}
public:
using value_type = typename base_type::value_type;
private:
Function * f;
Input state;
mutable optional<typename result_of_nullary_lvalue_call<Function>::type> value;
};
public:
function_object_input_iterator(function_arg_type f, Input state) :
m_f(std::addressof(f)), m_state(state)
{}
template <class Function, class Input>
class function_pointer_input_iterator :
public iterator_facade<
function_pointer_input_iterator<Function, Input>,
typename function_types::result_type<Function>::type,
single_pass_traversal_tag,
typename function_types::result_type<Function>::type const &
>
{
public:
function_pointer_input_iterator() {}
function_pointer_input_iterator(Function &f_, Input state_ = Input())
: f(f_), state(state_) {}
protected:
typename std::add_pointer< Function >::type m_f;
Input m_state;
mutable optional< value_type > m_value;
};
void increment() {
if(value)
value = none;
else
(*f)();
++state;
}
template< typename Function, typename Input >
class function_pointer_input_iterator :
public function_input_iterator_facade_base_t< Function, Input >
{
private:
using base_type = function_input_iterator_facade_base_t< Function, Input >;
typename function_types::result_type<Function>::type const &
dereference() const {
return (value ? value : value = (*f)()).get();
}
protected:
using function_arg_type = Function;
bool equal(function_pointer_input_iterator const & other) const {
return f == other.f && state == other.state;
}
public:
using value_type = typename base_type::value_type;
private:
Function f;
Input state;
mutable optional<typename function_types::result_type<Function>::type> value;
};
public:
function_pointer_input_iterator(function_arg_type f, Input state) :
m_f(f), m_state(state)
{}
} // namespace impl
protected:
Function m_f;
Input m_state;
mutable optional< value_type > m_value;
};
template <class Function, class Input>
class function_input_iterator :
public boost::conditional<
function_types::is_function_pointer<Function>::value,
impl::function_pointer_input_iterator<Function,Input>,
impl::function_input_iterator<Function,Input>
>::type
template< typename Function, typename Input >
using function_input_iterator_base_t = typename std::conditional<
detail::conjunction<
std::is_pointer< Function >,
std::is_function< typename std::remove_pointer< Function >::type >
>::value,
detail::function_pointer_input_iterator< Function, Input >,
detail::function_object_input_iterator< Function, Input >
>::type;
} // namespace detail
template< typename Function, typename Input >
class function_input_iterator :
public detail::function_input_iterator_base_t< Function, Input >
{
private:
using base_type = detail::function_input_iterator_base_t< Function, Input >;
using function_arg_type = typename base_type::function_arg_type;
public:
using reference = typename base_type::reference;
public:
function_input_iterator(function_arg_type f, Input i) :
base_type(f, i)
{}
void increment()
{
typedef typename boost::conditional<
function_types::is_function_pointer<Function>::value,
impl::function_pointer_input_iterator<Function,Input>,
impl::function_input_iterator<Function,Input>
>::type base_type;
public:
function_input_iterator(Function & f, Input i)
: base_type(f, i) {}
};
template <class Function, class Input>
inline function_input_iterator<Function, Input>
make_function_input_iterator(Function & f, Input state) {
typedef function_input_iterator<Function, Input> result_t;
return result_t(f, state);
if (this->m_value)
this->m_value.reset();
else
(*this->m_f)();
++this->m_state;
}
template <class Function, class Input>
inline function_input_iterator<Function*, Input>
make_function_input_iterator(Function * f, Input state) {
typedef function_input_iterator<Function*, Input> result_t;
return result_t(f, state);
reference dereference() const
{
if (!this->m_value)
this->m_value = (*this->m_f)();
return this->m_value.get();
}
struct infinite
bool equal(function_input_iterator const& other) const
{
infinite & operator++() { return *this; }
infinite & operator++(int) { return *this; }
bool operator==(infinite &) const { return false; };
bool operator==(infinite const &) const { return false; };
};
return this->m_f == other.m_f && this->m_state == other.m_state;
}
};
template< typename Function, typename Input >
inline function_input_iterator< Function, Input > make_function_input_iterator(Function& f, Input state)
{
return function_input_iterator< Function, Input >(f, state);
}
template< typename Function, typename Input >
inline function_input_iterator< Function*, Input > make_function_input_iterator(Function* f, Input state)
{
return function_input_iterator< Function*, Input >(f, state);
}
struct infinite
{
infinite& operator++() { return *this; }
infinite& operator++(int) { return *this; }
bool operator==(infinite&) const { return false; };
bool operator==(infinite const&) const { return false; };
};
} // namespace iterators
@ -169,5 +159,4 @@ using iterators::infinite;
} // namespace boost
#endif
#endif // BOOST_ITERATOR_FUNCTION_INPUT_ITERATOR_HPP_INCLUDED_

View File

@ -8,82 +8,76 @@
// 27 Feb 2001 Jeremy Siek
// Initial checkin.
#ifndef BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
#define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
#ifndef BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_
#define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_
#include <cstddef>
#include <iterator>
#include <boost/config.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#include <boost/type_traits/remove_reference.hpp>
#endif
#include <type_traits>
namespace boost {
namespace iterators {
template <class UnaryFunction>
class function_output_iterator {
private:
typedef function_output_iterator self;
class output_proxy {
template< typename UnaryFunction >
class function_output_iterator
{
private:
class output_proxy
{
public:
explicit output_proxy(UnaryFunction& f) BOOST_NOEXCEPT : m_f(f) { }
explicit output_proxy(UnaryFunction& f) noexcept :
m_f(f)
{}
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class T>
typename boost::disable_if_c<
boost::is_same< typename boost::remove_cv< T >::type, output_proxy >::value,
output_proxy&
>::type operator=(const T& value) {
m_f(value);
return *this;
}
#else
template <class T>
typename boost::disable_if_c<
boost::is_same< typename boost::remove_cv< typename boost::remove_reference< T >::type >::type, output_proxy >::value,
output_proxy&
>::type operator=(T&& value) {
m_f(static_cast< T&& >(value));
return *this;
}
#endif
template< typename T >
typename std::enable_if<
!std::is_same< typename std::remove_cv< typename std::remove_reference< T >::type >::type, output_proxy >::value,
output_proxy const&
>::type operator=(T&& value) const
{
m_f(static_cast< T&& >(value));
return *this;
}
BOOST_DEFAULTED_FUNCTION(output_proxy(output_proxy const& that), BOOST_NOEXCEPT : m_f(that.m_f) {})
BOOST_DELETED_FUNCTION(output_proxy& operator=(output_proxy const&))
output_proxy(output_proxy const& that) = default;
output_proxy& operator=(output_proxy const&) = delete;
private:
UnaryFunction& m_f;
UnaryFunction& m_f;
};
public:
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
public:
using iterator_category = std::output_iterator_tag;
using value_type = void;
using difference_type = std::ptrdiff_t;
using pointer = void;
using reference = void;
explicit function_output_iterator() {}
template<
bool Requires = std::is_class< UnaryFunction >::value,
typename = typename std::enable_if< Requires >::type
>
function_output_iterator() :
m_f()
{}
explicit function_output_iterator(const UnaryFunction& f)
: m_f(f) {}
explicit function_output_iterator(UnaryFunction const& f) :
m_f(f)
{}
output_proxy operator*() { return output_proxy(m_f); }
self& operator++() { return *this; }
self& operator++(int) { return *this; }
function_output_iterator& operator++() { return *this; }
function_output_iterator& operator++(int) { return *this; }
private:
private:
UnaryFunction m_f;
};
};
template <class UnaryFunction>
inline function_output_iterator<UnaryFunction>
make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) {
return function_output_iterator<UnaryFunction>(f);
}
template< typename UnaryFunction >
inline function_output_iterator< UnaryFunction > make_function_output_iterator(UnaryFunction const& f = UnaryFunction())
{
return function_output_iterator< UnaryFunction >(f);
}
} // namespace iterators
@ -92,4 +86,4 @@ using iterators::make_function_output_iterator;
} // namespace boost
#endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
#endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP_INCLUDED_

View File

@ -0,0 +1,96 @@
// (C) Copyright Jens Maurer 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Revision History:
// 15 Nov 2001 Jens Maurer
// created.
// See http://www.boost.org/libs/utility/iterator_adaptors.htm for documentation.
#ifndef BOOST_ITERATOR_GENERATOR_ITERATOR_HPP_INCLUDED_
#define BOOST_ITERATOR_GENERATOR_ITERATOR_HPP_INCLUDED_
#include <memory>
#include <type_traits>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
namespace boost {
namespace iterators {
template< typename Generator >
class generator_iterator :
public iterator_facade<
generator_iterator< Generator >,
decltype(std::declval< Generator& >()()),
single_pass_traversal_tag,
decltype(std::declval< Generator& >()()) const&
>
{
friend class iterator_core_access;
private:
using super_t = iterator_facade<
generator_iterator< Generator >,
decltype(std::declval< Generator& >()()),
single_pass_traversal_tag,
decltype(std::declval< Generator& >()()) const&
>;
public:
generator_iterator() :
m_g(nullptr),
m_value()
{}
generator_iterator(Generator* g) :
m_g(g),
m_value((*m_g)())
{}
private:
void increment()
{
m_value = (*m_g)();
}
typename super_t::reference dereference() const
{
return m_value;
}
bool equal(generator_iterator const& y) const
{
return m_g == y.m_g && m_value == y.m_value;
}
private:
Generator* m_g;
typename Generator::result_type m_value;
};
template< typename Generator >
struct generator_iterator_generator
{
using type = generator_iterator< Generator >;
};
template< typename Generator >
inline generator_iterator< Generator > make_generator_iterator(Generator& gen)
{
return generator_iterator< Generator >(std::addressof(gen));
}
} // namespace iterators
using iterators::generator_iterator;
using iterators::generator_iterator_generator;
using iterators::make_generator_iterator;
} // namespace boost
#endif // BOOST_ITERATOR_GENERATOR_ITERATOR_HPP_INCLUDED_

View File

@ -7,131 +7,109 @@
#ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP
#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP
#include <iterator>
#include <type_traits>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/enable_if_convertible.hpp>
#include <boost/iterator/detail/eval_if_default.hpp>
#include <boost/pointee.hpp>
#include <boost/indirect_reference.hpp>
#include <boost/detail/indirect_traits.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <iterator>
#ifdef BOOST_MPL_CFG_NO_HAS_XXX
# include <boost/shared_ptr.hpp>
# include <boost/scoped_ptr.hpp>
# include <boost/mpl/bool.hpp>
# include <memory>
#endif
#include <boost/iterator/detail/config_def.hpp> // must be last #include
#include <boost/core/use_default.hpp>
namespace boost {
namespace iterators {
template <class Iter, class Value, class Category, class Reference, class Difference>
class indirect_iterator;
template< typename Iter, typename Value, typename Category, typename Reference, typename Difference >
class indirect_iterator;
namespace detail
{
template <class Iter, class Value, class Category, class Reference, class Difference>
struct indirect_base
{
typedef typename std::iterator_traits<Iter>::value_type dereferenceable;
namespace detail {
typedef iterator_adaptor<
indirect_iterator<Iter, Value, Category, Reference, Difference>
, Iter
, typename ia_dflt_help<
Value, pointee<dereferenceable>
>::type
, Category
, typename ia_dflt_help<
Reference
, mpl::eval_if<
is_same<Value,use_default>
, indirect_reference<dereferenceable>
, add_reference<Value>
>
>::type
, Difference
> type;
};
template< typename Iter, typename Value, typename Category, typename Reference, typename Difference >
struct indirect_base
{
using dereferenceable = typename std::iterator_traits< Iter >::value_type;
template <>
struct indirect_base<int, int, int, int, int> {};
} // namespace detail
using type = iterator_adaptor<
indirect_iterator< Iter, Value, Category, Reference, Difference >,
Iter,
detail::eval_if_default_t<
Value,
pointee< dereferenceable >
>,
Category,
detail::eval_if_default_t<
Reference,
detail::eval_if_default<
Value,
indirect_reference< dereferenceable >,
std::add_lvalue_reference< Value >
>
>,
Difference
>;
};
} // namespace detail
template <
class Iterator
, class Value = use_default
, class Category = use_default
, class Reference = use_default
, class Difference = use_default
>
class indirect_iterator
: public detail::indirect_base<
template<
typename Iterator,
typename Value = use_default,
typename Category = use_default,
typename Reference = use_default,
typename Difference = use_default
>
class indirect_iterator :
public detail::indirect_base<
Iterator, Value, Category, Reference, Difference
>::type
{
typedef typename detail::indirect_base<
Iterator, Value, Category, Reference, Difference
>::type super_t;
>::type
{
using super_t = typename detail::indirect_base<
Iterator, Value, Category, Reference, Difference
>::type;
friend class iterator_core_access;
friend class iterator_core_access;
public:
indirect_iterator() {}
public:
indirect_iterator() = default;
indirect_iterator(Iterator iter)
: super_t(iter) {}
indirect_iterator(Iterator iter) :
super_t(iter)
{}
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
)
: super_t(y.base())
{}
template<
typename Iterator2,
typename Value2,
typename Category2,
typename Reference2,
typename Difference2,
typename = enable_if_convertible_t< Iterator2, Iterator >
>
indirect_iterator(indirect_iterator< Iterator2, Value2, Category2, Reference2, Difference2 > const& y) :
super_t(y.base())
{}
private:
typename super_t::reference dereference() const
{
# if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x5A0 )
return const_cast<super_t::reference>(**this->base());
# else
return **this->base();
# endif
}
};
private:
typename super_t::reference dereference() const
{
return **this->base();
}
};
template <class Iter>
inline
indirect_iterator<Iter> make_indirect_iterator(Iter x)
{
return indirect_iterator<Iter>(x);
}
template< typename Iter >
inline indirect_iterator< Iter > make_indirect_iterator(Iter x)
{
return indirect_iterator< Iter >(x);
}
template <class Traits, class Iter>
inline
indirect_iterator<Iter,Traits> make_indirect_iterator(Iter x, Traits* = 0)
{
return indirect_iterator<Iter, Traits>(x);
}
template< typename Value, typename Iter >
inline indirect_iterator< Iter, Value > make_indirect_iterator(Iter x)
{
return indirect_iterator< Iter, Value >(x);
}
} // namespace iterators
@ -140,6 +118,4 @@ using iterators::make_indirect_iterator;
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP

View File

@ -5,43 +5,33 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_INTEROPERABLE_23022003THW_HPP
# define BOOST_INTEROPERABLE_23022003THW_HPP
#define BOOST_INTEROPERABLE_23022003THW_HPP
# include <boost/mpl/bool.hpp>
# include <boost/mpl/or.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/iterator/detail/config_def.hpp> // must appear last
#include <type_traits>
#include <boost/iterator/detail/type_traits/disjunction.hpp>
namespace boost {
namespace iterators {
//
// Meta function that determines whether two
// iterator types are considered interoperable.
//
// Two iterator types A,B are considered interoperable if either
// A is convertible to B or vice versa.
// This interoperability definition is in sync with the
// standards requirements on constant/mutable container
// iterators (23.1 [lib.container.requirements]).
//
// For compilers that don't support is_convertible
// is_interoperable gives false positives. See comments
// on operator implementation for consequences.
//
template <typename A, typename B>
struct is_interoperable
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
: mpl::true_
# else
: mpl::or_<
is_convertible< A, B >
, is_convertible< B, A > >
# endif
{
};
//
// Meta function that determines whether two
// iterator types are considered interoperable.
//
// Two iterator types A,B are considered interoperable if either
// A is convertible to B or vice versa.
// This interoperability definition is in sync with the
// standards requirements on constant/mutable container
// iterators (23.1 [lib.container.requirements]).
//
// For compilers that don't support is_convertible
// is_interoperable gives false positives. See comments
// on operator implementation for consequences.
//
template< typename A, typename B >
struct is_interoperable :
public detail::disjunction< std::is_convertible< A, B >, std::is_convertible< B, A > >
{
};
} // namespace iterators
@ -49,6 +39,4 @@ using iterators::is_interoperable;
} // namespace boost
# include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_INTEROPERABLE_23022003THW_HPP

View File

@ -0,0 +1,148 @@
/*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Copyright (c) 2023 Andrey Semashev
*/
/*!
* \file iterator/is_iterator.hpp
*
* This header contains definition of the \c is_iterator type trait.
*/
#ifndef BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
#define BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
#include <cstddef>
#include <boost/config.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/iterator/detail/type_traits/conjunction.hpp>
#include <boost/iterator/detail/type_traits/negation.hpp>
#if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS)
#include <iterator>
#endif
#include <type_traits>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace iterators {
namespace detail {
// The trait attempts to detect if the T type is an iterator class. Class-type iterators are assumed
// to have the nested type iterator_category. Strictly speaking, this is not required to be the
// case (e.g. a user can specialize iterator_traits for T without defining T::iterator_category).
// Still, this is a good heuristic in practice, and we can't do anything better anyway.
// Since C++17 we can test for iterator_traits<T>::iterator_category presence instead as it is
// required to be only present for iterators.
namespace has_iterator_category_detail {
typedef char yes_type;
struct no_type { char padding[2]; };
template< typename T >
yes_type check(
#if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS)
typename std::iterator_traits< T >::iterator_category*
#else
typename T::iterator_category*
#endif
);
template< typename >
no_type check(...);
} // namespace has_iterator_category_detail
template< typename T >
struct is_iterator_impl :
public std::integral_constant<
bool,
sizeof(has_iterator_category_detail::check<T>(0)) == sizeof(has_iterator_category_detail::yes_type)
>
{
};
template< typename T >
struct is_iterator_impl< T* > :
public conjunction<
boost::is_complete<T>,
negation< std::is_function< T > >
>::type
{
};
template< typename T, typename U >
struct is_iterator_impl< T U::* > :
public std::false_type
{
};
template< typename T >
struct is_iterator_impl<T&> :
public std::false_type
{
};
template< typename T, std::size_t N >
struct is_iterator_impl< T[N] > :
public std::false_type
{
};
#if !defined(BOOST_TT_HAS_WORKING_IS_COMPLETE)
template< typename T >
struct is_iterator_impl< T[] > :
public std::false_type
{
};
template< >
struct is_iterator_impl< void > :
public std::false_type
{
};
template< >
struct is_iterator_impl< void* > :
public std::false_type
{
};
#endif // !defined(BOOST_TT_HAS_WORKING_IS_COMPLETE)
} // namespace detail
/*!
* \brief The type trait detects whether the type \c T is an iterator type.
*
* The type trait yields \c true if its argument type \c T, after stripping top level
* cv qualifiers, is one of the following:
*
* - A pointer type, other than a pointer to function, a pointer to a class member,
* or a pointer to an incomplete type, including `void`.
* - A class type for which an iterator category is obtainable. Prior to C++17,
* the iterator category must be defined as a public `T::iterator_category` type.
* Since C++17, the expression `std::iterator_traits< T >::iterator_category` must
* be valid and produce the iterator category type.
*
* Otherwise, the type trait yields \c false.
*/
template< typename T >
struct is_iterator : public detail::is_iterator_impl< T >::type {};
template< typename T >
struct is_iterator< const T > : public detail::is_iterator_impl< T >::type {};
template< typename T >
struct is_iterator< volatile T > : public detail::is_iterator_impl< T >::type {};
template< typename T >
struct is_iterator< const volatile T > : public detail::is_iterator_impl< T >::type {};
} // namespace iterators
using iterators::is_iterator;
} // namespace boost
#endif // BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_

View File

@ -2,152 +2,73 @@
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
# define IS_LVALUE_ITERATOR_DWA2003112_HPP
#define IS_LVALUE_ITERATOR_DWA2003112_HPP
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/iterator/detail/any_conversion_eater.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
#include <boost/iterator/detail/type_traits/conjunction.hpp>
#include <iterator>
// should be the last #includes
#include <boost/type_traits/integral_constant.hpp>
#include <boost/iterator/detail/config_def.hpp>
#ifndef BOOST_NO_IS_CONVERTIBLE
#include <type_traits>
namespace boost {
namespace iterators {
namespace detail {
namespace detail
// Guts of is_lvalue_iterator. It is the iterator type and
// Value is the iterator's value_type.
template< typename It, typename Value >
struct is_lvalue_iterator_impl :
public detail::conjunction<
std::is_convertible< decltype(*std::declval< It& >()), typename std::add_lvalue_reference< Value >::type >,
std::is_lvalue_reference< decltype(*std::declval< It& >()) >
>::type
{
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
// Calling lvalue_preserver( <expression>, 0 ) returns a reference
// to the expression's result if <expression> is an lvalue, or
// not_an_lvalue() otherwise.
struct not_an_lvalue {};
template <class T>
T& lvalue_preserver(T&, int);
template <class U>
not_an_lvalue lvalue_preserver(U const&, ...);
# define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0)
#else
# define BOOST_LVALUE_PRESERVER(expr) expr
#endif
// Guts of is_lvalue_iterator. Value is the iterator's value_type
// and the result is computed in the nested rebind template.
template <class Value>
struct is_lvalue_iterator_impl
{
// Eat implicit conversions so we don't report true for things
// convertible to Value const&
struct conversion_eater
{
conversion_eater(typename add_lvalue_reference<Value>::type);
};
static char tester(conversion_eater, int);
static char (& tester(any_conversion_eater, ...) )[2];
template <class It>
struct rebind
{
static It& x;
BOOST_STATIC_CONSTANT(
bool
, value = (
sizeof(
is_lvalue_iterator_impl<Value>::tester(
BOOST_LVALUE_PRESERVER(*x), 0
)
) == 1
)
);
};
};
#undef BOOST_LVALUE_PRESERVER
//
// void specializations to handle std input and output iterators
//
template <>
struct is_lvalue_iterator_impl<void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
template <>
struct is_lvalue_iterator_impl<const void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
template <>
struct is_lvalue_iterator_impl<volatile void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
template <>
struct is_lvalue_iterator_impl<const volatile void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
#endif
//
// This level of dispatching is required for Borland. We might save
// an instantiation by removing it for others.
//
template <class It>
struct is_readable_lvalue_iterator_impl
: is_lvalue_iterator_impl<
BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type const
>::template rebind<It>
{};
template <class It>
struct is_non_const_lvalue_iterator_impl
: is_lvalue_iterator_impl<
BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type
>::template rebind<It>
{};
} // namespace detail
template< typename T > struct is_lvalue_iterator
: public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_lvalue_iterator_impl<T>::value>
{
public:
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_lvalue_iterator,(T))
};
template< typename T > struct is_non_const_lvalue_iterator
: public ::boost::integral_constant<bool,::boost::iterators::detail::is_non_const_lvalue_iterator_impl<T>::value>
//
// void specializations to handle std input and output iterators
//
template< typename It >
struct is_lvalue_iterator_impl< It, void > :
public std::false_type
{
};
template< typename It >
struct is_lvalue_iterator_impl< It, const void > :
public std::false_type
{
};
template< typename It >
struct is_lvalue_iterator_impl< It, volatile void > :
public std::false_type
{
};
template< typename It >
struct is_lvalue_iterator_impl< It, const volatile void > :
public std::false_type
{
};
} // namespace detail
template< typename T >
struct is_lvalue_iterator :
public iterators::detail::is_lvalue_iterator_impl<
T,
typename std::iterator_traits< T >::value_type const
>::type
{
};
template< typename T >
struct is_non_const_lvalue_iterator :
public iterators::detail::is_lvalue_iterator_impl<
T,
typename std::iterator_traits< T >::value_type
>::type
{
public:
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_non_const_lvalue_iterator,(T))
};
} // namespace iterators
@ -157,8 +78,4 @@ using iterators::is_non_const_lvalue_iterator;
} // namespace boost
#endif
#include <boost/iterator/detail/config_undef.hpp>
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP

View File

@ -2,108 +2,62 @@
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef IS_READABLE_ITERATOR_DWA2003112_HPP
# define IS_READABLE_ITERATOR_DWA2003112_HPP
#include <boost/mpl/bool.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/iterator/detail/any_conversion_eater.hpp>
#define IS_READABLE_ITERATOR_DWA2003112_HPP
#include <iterator>
// should be the last #include
#include <boost/type_traits/integral_constant.hpp>
#include <boost/iterator/detail/config_def.hpp>
#ifndef BOOST_NO_IS_CONVERTIBLE
#include <type_traits>
namespace boost {
namespace iterators {
namespace detail {
namespace detail
// Guts of is_readable_iterator. It is the iterator type and
// Value is the iterator's value_type.
template< typename It, typename Value >
struct is_readable_iterator_impl :
public std::is_convertible<
decltype(*std::declval< It& >()),
typename std::add_lvalue_reference< Value >::type
>
{
// Guts of is_readable_iterator. Value is the iterator's value_type
// and the result is computed in the nested rebind template.
template <class Value>
struct is_readable_iterator_impl
{
static char tester(typename add_lvalue_reference<Value>::type, int);
static char (& tester(any_conversion_eater, ...) )[2];
};
template <class It>
struct rebind
{
static It& x;
//
// void specializations to handle std input and output iterators
//
template< typename It >
struct is_readable_iterator_impl< It, void > :
public std::false_type
{
};
BOOST_STATIC_CONSTANT(
bool
, value = (
sizeof(
is_readable_iterator_impl<Value>::tester(*x, 1)
) == 1
)
);
};
};
template< typename It >
struct is_readable_iterator_impl< It, const void > :
public std::false_type
{
};
#undef BOOST_READABLE_PRESERVER
template< typename It >
struct is_readable_iterator_impl< It, volatile void > :
public std::false_type
{
};
//
// void specializations to handle std input and output iterators
//
template <>
struct is_readable_iterator_impl<void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
template< typename It >
struct is_readable_iterator_impl< It, const volatile void > :
public std::false_type
{
};
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
template <>
struct is_readable_iterator_impl<const void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
template <>
struct is_readable_iterator_impl<volatile void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
template <>
struct is_readable_iterator_impl<const volatile void>
{
template <class It>
struct rebind : boost::mpl::false_
{};
};
#endif
//
// This level of dispatching is required for Borland. We might save
// an instantiation by removing it for others.
//
template <class It>
struct is_readable_iterator_impl2
: is_readable_iterator_impl<
BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type const
>::template rebind<It>
{};
} // namespace detail
template< typename T > struct is_readable_iterator
: public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_iterator_impl2<T>::value>
template< typename T >
struct is_readable_iterator :
public iterators::detail::is_readable_iterator_impl<
T,
typename std::iterator_traits< T >::value_type const
>::type
{
public:
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_readable_iterator,(T))
};
} // namespace iterators
@ -112,8 +66,4 @@ using iterators::is_readable_iterator;
} // namespace boost
#endif
#include <boost/iterator/detail/config_undef.hpp>
#endif // IS_READABLE_ITERATOR_DWA2003112_HPP

View File

@ -7,349 +7,202 @@
#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
#include <boost/static_assert.hpp>
#include <type_traits>
#include <boost/core/use_default.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp>
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
# include <boost/type_traits/remove_reference.hpp>
#endif
#include <boost/type_traits/add_reference.hpp>
#include <boost/iterator/detail/config_def.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/enable_if_convertible.hpp> // for backward compatibility; remove once downstream users are updated
#include <boost/iterator/detail/eval_if_default.hpp>
#include <boost/iterator/detail/config_def.hpp>
namespace boost {
namespace iterators {
// Used as a default template argument internally, merely to
// indicate "use the default", this can also be passed by users
// explicitly in order to specify that the default should be used.
using boost::use_default;
// Used as a default template argument internally, merely to
// indicate "use the default", this can also be passed by users
// explicitly in order to specify that the default should be used.
using boost::use_default;
} // namespace iterators
namespace detail {
// the incompleteness of use_default causes massive problems for
// is_convertible (naturally). This workaround is fortunately not
// needed for vc6/vc7.
template<class To>
struct is_convertible<use_default,To>
: mpl::false_ {};
// A metafunction which computes an iterator_adaptor's base class,
// a specialization of iterator_facade.
template<
typename Derived,
typename Base,
typename Value,
typename Traversal,
typename Reference,
typename Difference
>
using iterator_adaptor_base_t = iterator_facade<
Derived,
namespace iterators {
namespace detail
{
//
// Result type used in enable_if_convertible meta function.
// This can be an incomplete type, as only pointers to
// enable_if_convertible< ... >::type are used.
// We could have used void for this, but conversion to
// void* is just to easy.
//
struct enable_type;
}
//
// enable_if for use in adapted iterators constructors.
//
// In order to provide interoperability between adapted constant and
// mutable iterators, adapted iterators will usually provide templated
// conversion constructors of the following form
//
// template <class BaseIterator>
// class adapted_iterator :
// public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
// {
// public:
//
// ...
//
// template <class OtherIterator>
// adapted_iterator(
// OtherIterator const& it
// , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
//
// ...
// };
//
// enable_if_convertible is used to remove those overloads from the overload
// set that cannot be instantiated. For all practical purposes only overloads
// for constant/mutable interaction will remain. This has the advantage that
// meta functions like boost::is_convertible do not return false positives,
// as they can only look at the signature of the conversion constructor
// and not at the actual instantiation.
//
// enable_if_interoperable can be safely used in user code. It falls back to
// always enabled for compilers that don't support enable_if or is_convertible.
// There is no need for compiler specific workarounds in user code.
//
// The operators implementation relies on boost::is_convertible not returning
// false positives for user/library defined iterator types. See comments
// on operator implementation for consequences.
//
# if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
template <class From, class To>
struct enable_if_convertible
{
typedef boost::iterators::detail::enable_type type;
};
# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292))
// For some reason vc7.1 needs us to "cut off" instantiation
// of is_convertible in a few cases.
template<typename From, typename To>
struct enable_if_convertible
: iterators::enable_if<
mpl::or_<
is_same<From,To>
, is_convertible<From, To>
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
detail::eval_if_default_t<
Value,
detail::eval_if_default<
Reference,
iterator_value< Base >,
std::remove_reference< Reference >
>
, boost::iterators::detail::enable_type
>,
#else
detail::eval_if_default_t<
Value,
iterator_value< Base >
>,
#endif
detail::eval_if_default_t<
Traversal,
iterator_traversal< Base >
>,
detail::eval_if_default_t<
Reference,
detail::eval_if_default<
Value,
iterator_reference< Base >,
std::add_lvalue_reference< Value >
>
>,
detail::eval_if_default_t<
Difference,
iterator_difference< Base >
>
{};
>;
# else
} // namespace detail
template<typename From, typename To>
struct enable_if_convertible
: iterators::enable_if<
is_convertible<From, To>
, boost::iterators::detail::enable_type
>
{};
# endif
//
// Default template argument handling for iterator_adaptor
//
namespace detail
{
// If T is use_default, return the result of invoking
// DefaultNullaryFn, otherwise return T.
template <class T, class DefaultNullaryFn>
struct ia_dflt_help
: mpl::eval_if<
is_same<T, use_default>
, DefaultNullaryFn
, mpl::identity<T>
>
{
};
// A metafunction which computes an iterator_adaptor's base class,
// a specialization of iterator_facade.
template <
class Derived
, class Base
, class Value
, class Traversal
, class Reference
, class Difference
>
struct iterator_adaptor_base
{
typedef iterator_facade<
Derived
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
, typename boost::iterators::detail::ia_dflt_help<
Value
, mpl::eval_if<
is_same<Reference,use_default>
, iterator_value<Base>
, remove_reference<Reference>
>
>::type
# else
, typename boost::iterators::detail::ia_dflt_help<
Value, iterator_value<Base>
>::type
# endif
, typename boost::iterators::detail::ia_dflt_help<
Traversal
, iterator_traversal<Base>
>::type
, typename boost::iterators::detail::ia_dflt_help<
Reference
, mpl::eval_if<
is_same<Value,use_default>
, iterator_reference<Base>
, add_reference<Value>
>
>::type
, typename boost::iterators::detail::ia_dflt_help<
Difference, iterator_difference<Base>
>::type
>
type;
};
// workaround for aC++ CR JAGaf33512
template <class Tr1, class Tr2>
inline void iterator_adaptor_assert_traversal ()
{
BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
}
}
//
// Iterator Adaptor
//
// The parameter ordering changed slightly with respect to former
// versions of iterator_adaptor The idea is that when the user needs
// to fiddle with the reference type it is highly likely that the
// iterator category has to be adjusted as well. Any of the
// following four template arguments may be ommitted or explicitly
// replaced by use_default.
//
// Value - if supplied, the value_type of the resulting iterator, unless
// const. If const, a conforming compiler strips constness for the
// value_type. If not supplied, iterator_traits<Base>::value_type is used
//
// Category - the traversal category of the resulting iterator. If not
// supplied, iterator_traversal<Base>::type is used.
//
// Reference - the reference type of the resulting iterator, and in
// particular, the result type of operator*(). If not supplied but
// Value is supplied, Value& is used. Otherwise
// iterator_traits<Base>::reference is used.
//
// Difference - the difference_type of the resulting iterator. If not
// supplied, iterator_traits<Base>::difference_type is used.
//
template <
class Derived
, class Base
, class Value = use_default
, class Traversal = use_default
, class Reference = use_default
, class Difference = use_default
>
class iterator_adaptor
: public boost::iterators::detail::iterator_adaptor_base<
//
// Iterator Adaptor
//
// The parameter ordering changed slightly with respect to former
// versions of iterator_adaptor The idea is that when the user needs
// to fiddle with the reference type it is highly likely that the
// iterator category has to be adjusted as well. Any of the
// following four template arguments may be omitted or explicitly
// replaced by use_default.
//
// Value - if supplied, the value_type of the resulting iterator, unless
// const. If const, a conforming compiler strips constness for the
// value_type. If not supplied, iterator_traits<Base>::value_type is used
//
// Category - the traversal category of the resulting iterator. If not
// supplied, iterator_traversal<Base>::type is used.
//
// Reference - the reference type of the resulting iterator, and in
// particular, the result type of operator*(). If not supplied but
// Value is supplied, Value& is used. Otherwise
// iterator_traits<Base>::reference is used.
//
// Difference - the difference_type of the resulting iterator. If not
// supplied, iterator_traits<Base>::difference_type is used.
//
template<
typename Derived,
typename Base,
typename Value = use_default,
typename Traversal = use_default,
typename Reference = use_default,
typename Difference = use_default
>
class iterator_adaptor :
public detail::iterator_adaptor_base_t<
Derived, Base, Value, Traversal, Reference, Difference
>::type
{
friend class iterator_core_access;
>
{
friend class iterator_core_access;
protected:
typedef typename boost::iterators::detail::iterator_adaptor_base<
Derived, Base, Value, Traversal, Reference, Difference
>::type super_t;
public:
iterator_adaptor() {}
protected:
using super_t = detail::iterator_adaptor_base_t<
Derived, Base, Value, Traversal, Reference, Difference
>;
explicit iterator_adaptor(Base const &iter)
: m_iterator(iter)
{
}
public:
using base_type = Base;
typedef Base base_type;
iterator_adaptor() = default;
Base const& base() const
{ return m_iterator; }
explicit iterator_adaptor(Base const& iter) :
m_iterator(iter)
{
}
protected:
// for convenience in derived classes
typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
base_type const& base() const { return m_iterator; }
//
// lvalue access to the Base object for Derived
//
Base const& base_reference() const
{ return m_iterator; }
protected:
// for convenience in derived classes
using iterator_adaptor_ = iterator_adaptor< Derived, Base, Value, Traversal, Reference, Difference >;
Base& base_reference()
{ return m_iterator; }
//
// lvalue access to the Base object for Derived
//
Base& base_reference() { return m_iterator; }
Base const& base_reference() const { return m_iterator; }
private:
//
// Core iterator interface for iterator_facade. This is private
// to prevent temptation for Derived classes to use it, which
// will often result in an error. Derived classes should use
// base_reference(), above, to get direct access to m_iterator.
//
typename super_t::reference dereference() const
{ return *m_iterator; }
private:
//
// Core iterator interface for iterator_facade. This is private
// to prevent temptation for Derived classes to use it, which
// will often result in an error. Derived classes should use
// base_reference(), above, to get direct access to m_iterator.
//
typename super_t::reference dereference() const { return *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
{
template< typename OtherDerived, typename OtherIterator, typename V, typename C, typename R, typename D >
bool equal(iterator_adaptor< OtherDerived, OtherIterator, V, C, R, D > const& x) const
{
// Maybe readd with same_distance
// BOOST_STATIC_ASSERT(
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
// );
return m_iterator == x.base();
}
return m_iterator == x.base();
}
typedef typename iterator_category_to_traversal<
typename super_t::iterator_category
>::type my_traversal;
using my_traversal = typename iterator_category_to_traversal< typename super_t::iterator_category >::type;
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
boost::iterators::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
void advance(typename super_t::difference_type n)
{
static_assert(detail::is_traversal_at_least< my_traversal, random_access_traversal_tag >::value,
"Iterator must support random access traversal.");
m_iterator += n;
}
void advance(typename super_t::difference_type n)
{
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
m_iterator += n;
}
void increment() { ++m_iterator; }
void increment() { ++m_iterator; }
void decrement()
{
static_assert(detail::is_traversal_at_least< my_traversal, bidirectional_traversal_tag >::value,
"Iterator must support bidirectional traversal.");
--m_iterator;
}
void decrement()
{
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
--m_iterator;
}
template< typename OtherDerived, typename OtherIterator, typename V, typename C, typename R, typename D >
typename super_t::difference_type distance_to(iterator_adaptor< OtherDerived, OtherIterator, V, C, R, D > const& y) const
{
static_assert(detail::is_traversal_at_least< my_traversal, random_access_traversal_tag >::value,
"Super iterator must support random access traversal.");
// Maybe readd with same_distance
// BOOST_STATIC_ASSERT(
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
// );
return y.base() - m_iterator;
}
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
typename super_t::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
{
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
// Maybe readd with same_distance
// BOOST_STATIC_ASSERT(
// (detail::same_category_and_difference<Derived,OtherDerived>::value)
// );
return y.base() - m_iterator;
}
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
private: // data members
Base m_iterator;
};
private: // data members
Base m_iterator;
};
} // namespace iterators
using iterators::iterator_adaptor;
using iterators::enable_if_convertible;
} // namespace boost

View File

@ -7,27 +7,14 @@
#define BOOST_ITERATOR_ARCHETYPES_HPP
#include <boost/iterator/iterator_categories.hpp>
#include <boost/operators.hpp>
#include <boost/static_assert.hpp>
#include <boost/iterator/detail/facade_iterator_category.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/operators.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/mpl/bitand.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mp11/utility.hpp>
#include <cstddef>
#include <type_traits>
namespace boost {
namespace iterators {
@ -38,252 +25,253 @@ struct access_archetype;
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
struct traversal_archetype;
namespace archetypes
namespace archetypes {
enum
{
enum {
readable_iterator_bit = 1
, writable_iterator_bit = 2
, swappable_iterator_bit = 4
, lvalue_iterator_bit = 8
};
readable_iterator_bit = 1,
writable_iterator_bit = 2,
swappable_iterator_bit = 4,
lvalue_iterator_bit = 8
};
// Not quite tags, since dispatching wouldn't work.
typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
// Not quite tags, since dispatching wouldn't work.
using readable_iterator_t = std::integral_constant<unsigned int, readable_iterator_bit>;
using writable_iterator_t = std::integral_constant<unsigned int, writable_iterator_bit>;
typedef mpl::int_<
(readable_iterator_bit|writable_iterator_bit)
>::type readable_writable_iterator_t;
using readable_writable_iterator_t = std::integral_constant<
unsigned int,
(readable_iterator_bit | writable_iterator_bit)
>;
typedef mpl::int_<
(readable_iterator_bit|lvalue_iterator_bit)
>::type readable_lvalue_iterator_t;
using readable_lvalue_iterator_t = std::integral_constant<
unsigned int,
(readable_iterator_bit | lvalue_iterator_bit)
>;
typedef mpl::int_<
(lvalue_iterator_bit|writable_iterator_bit)
>::type writable_lvalue_iterator_t;
using writable_lvalue_iterator_t = std::integral_constant<
unsigned int,
(lvalue_iterator_bit | writable_iterator_bit)
>;
typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
using swappable_iterator_t = std::integral_constant<unsigned int, swappable_iterator_bit>;
using lvalue_iterator_t = std::integral_constant<unsigned int, lvalue_iterator_bit>;
template <class Derived, class Base>
struct has_access
: mpl::equal_to<
mpl::bitand_<Derived,Base>
, Base
>
{};
}
template <class Derived, class Base>
struct has_access :
public std::integral_constant<bool, (Derived::value & Base::value) == Base::value>
{};
namespace detail
} // namespace archetypes
namespace detail {
template <class T>
struct assign_proxy
{
template <class T>
struct assign_proxy
{
assign_proxy& operator=(T) { return *this; }
};
assign_proxy& operator=(T) { return *this; }
};
template <class T>
struct read_proxy
{
operator T() { return static_object<T>::get(); }
};
template <class T>
struct read_proxy
{
operator T() { return static_object<T>::get(); }
};
template <class T>
struct read_write_proxy
: read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS
{
read_write_proxy& operator=(T) { return *this; }
};
template <class T>
struct read_write_proxy :
public read_proxy<T> // Used to inherit from assign_proxy, but that doesn't work. -JGS
{
read_write_proxy& operator=(T) { return *this; }
};
template <class T>
struct arrow_proxy
{
T const* operator->() const { return 0; }
};
template <class T>
struct arrow_proxy
{
T const* operator->() const { return 0; }
};
struct no_operator_brackets {};
struct no_operator_brackets {};
template <class ValueType>
struct readable_operator_brackets
{
read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
};
template <class ValueType>
struct readable_operator_brackets
{
read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
};
template <class ValueType>
struct writable_operator_brackets
{
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
};
template <class ValueType>
struct writable_operator_brackets
{
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
};
template <class Value, class AccessCategory, class TraversalCategory>
struct operator_brackets
: mpl::eval_if<
is_convertible<TraversalCategory, random_access_traversal_tag>
, mpl::eval_if<
archetypes::has_access<
AccessCategory
, archetypes::writable_iterator_t
>
, mpl::identity<writable_operator_brackets<Value> >
, mpl::if_<
archetypes::has_access<
AccessCategory
, archetypes::readable_iterator_t
>
, readable_operator_brackets<Value>
, no_operator_brackets
>
>
, mpl::identity<no_operator_brackets>
>::type
{};
template <class Value, class AccessCategory, class TraversalCategory>
struct operator_brackets :
public mp11::mp_eval_if_c<
!std::is_convertible<TraversalCategory, random_access_traversal_tag>::value,
no_operator_brackets,
mp11::mp_cond,
archetypes::has_access<AccessCategory, archetypes::writable_iterator_t>, writable_operator_brackets<Value>,
archetypes::has_access<AccessCategory, archetypes::readable_iterator_t>, readable_operator_brackets<Value>,
std::true_type, no_operator_brackets
>
{};
template <class TraversalCategory>
struct traversal_archetype_impl
{
template <class Derived,class Value> struct archetype;
};
template <class TraversalCategory>
struct traversal_archetype_impl
{
template <class Derived,class Value> struct archetype;
};
// Constructor argument for those iterators that
// are not default constructible
struct ctor_arg {};
// Constructor argument for those iterators that
// are not default constructible
struct ctor_arg {};
template <class Derived, class Value, class TraversalCategory>
struct traversal_archetype_
: traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
{
typedef typename
traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
base;
template <class Derived, class Value, class TraversalCategory>
struct traversal_archetype_ :
public traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
{
using base = typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>;
traversal_archetype_() {}
traversal_archetype_() {}
traversal_archetype_(ctor_arg arg)
: base(arg)
{}
};
traversal_archetype_(ctor_arg arg) : base(arg)
{}
};
template <>
struct traversal_archetype_impl<incrementable_traversal_tag>
{
template<class Derived, class Value>
struct archetype
{
explicit archetype(ctor_arg) {}
template <>
struct traversal_archetype_impl<incrementable_traversal_tag>
{
template<class Derived, class Value>
struct archetype
{
explicit archetype(ctor_arg) {}
struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS
typedef bogus difference_type;
struct bogus { }; // This used to be void, but that causes trouble for iterator_facade. Need more research. -JGS
using difference_type = bogus;
Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
};
};
Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
};
};
template <>
struct traversal_archetype_impl<single_pass_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
{
explicit archetype(ctor_arg arg)
: traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
{}
template <>
struct traversal_archetype_impl<single_pass_traversal_tag>
{
template<class Derived, class Value>
struct archetype :
public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
{
explicit archetype(ctor_arg arg) :
traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
{}
typedef std::ptrdiff_t difference_type;
};
};
using difference_type = std::ptrdiff_t;
};
};
template <class Derived, class Value>
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
template <class Derived, class Value>
bool operator==(
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
template <>
struct traversal_archetype_impl<forward_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
{
archetype()
: traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
{}
};
};
template <>
struct traversal_archetype_impl<forward_traversal_tag>
{
template<class Derived, class Value>
struct archetype :
public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
{
archetype() :
traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
{}
};
};
template <>
struct traversal_archetype_impl<bidirectional_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
{
Derived& operator--() { return static_object<Derived>::get(); }
Derived operator--(int) const { return static_object<Derived>::get(); }
};
};
template <>
struct traversal_archetype_impl<bidirectional_traversal_tag>
{
template<class Derived, class Value>
struct archetype :
public traversal_archetype_<Derived, Value, forward_traversal_tag>
{
Derived& operator--() { return static_object<Derived>::get(); }
Derived operator--(int) const { return static_object<Derived>::get(); }
};
};
template <>
struct traversal_archetype_impl<random_access_traversal_tag>
{
template<class Derived, class Value>
struct archetype
: public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
{
Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
};
};
template <>
struct traversal_archetype_impl<random_access_traversal_tag>
{
template<class Derived, class Value>
struct archetype :
public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
{
Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
};
};
template <class Derived, class Value>
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t) { return static_object<Derived>::get(); }
template <class Derived, class Value>
Derived& operator+(
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t) { return static_object<Derived>::get(); }
template <class Derived, class Value>
Derived& operator+(std::ptrdiff_t,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return static_object<Derived>::get(); }
template <class Derived, class Value>
Derived& operator+(
std::ptrdiff_t,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return static_object<Derived>::get(); }
template <class Derived, class Value>
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t)
{ return static_object<Derived>::get(); }
template <class Derived, class Value>
Derived& operator-(
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
std::ptrdiff_t) { return static_object<Derived>::get(); }
template <class Derived, class Value>
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return 0; }
template <class Derived, class Value>
std::ptrdiff_t operator-(
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return 0; }
template <class Derived, class Value>
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator<(
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator>(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator>(
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator<=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator<=(
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator>=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
template <class Derived, class Value>
bool operator>=(
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
{ return true; }
struct bogus_type;
struct bogus_type;
template <class Value>
struct convertible_type
: mpl::if_< is_const<Value>,
typename remove_const<Value>::type,
bogus_type >
{};
template <class Value>
struct convertible_type
{
using type = bogus_type;
};
template <class Value>
struct convertible_type<const Value>
{
using type = Value;
};
} // namespace detail
@ -297,24 +285,20 @@ struct iterator_access_archetype_impl
};
template <class Value, class AccessCategory>
struct iterator_access_archetype
: iterator_access_archetype_impl<
AccessCategory
>::template archetype<Value>
struct iterator_access_archetype :
public iterator_access_archetype_impl<AccessCategory>::template archetype<Value>
{
};
template <>
struct iterator_access_archetype_impl<
archetypes::readable_iterator_t
>
struct iterator_access_archetype_impl<archetypes::readable_iterator_t>
{
template <class Value>
struct archetype
{
typedef typename remove_cv<Value>::type value_type;
typedef Value reference;
typedef Value* pointer;
using value_type = typename std::remove_cv<Value>::type;
using reference = Value;
using pointer = Value*;
value_type operator*() const { return static_object<value_type>::get(); }
@ -323,34 +307,28 @@ struct iterator_access_archetype_impl<
};
template <>
struct iterator_access_archetype_impl<
archetypes::writable_iterator_t
>
struct iterator_access_archetype_impl<archetypes::writable_iterator_t>
{
template <class Value>
struct archetype
{
BOOST_STATIC_ASSERT(!is_const<Value>::value);
typedef void value_type;
typedef void reference;
typedef void pointer;
static_assert(!std::is_const<Value>::value, "Value type must not be const.");
using value_type = void;
using reference = void;
using pointer = void;
detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
};
};
template <>
struct iterator_access_archetype_impl<
archetypes::readable_writable_iterator_t
>
struct iterator_access_archetype_impl<archetypes::readable_writable_iterator_t>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, archetypes::readable_iterator_t
>
struct archetype :
public virtual iterator_access_archetype<Value, archetypes::readable_iterator_t>
{
typedef detail::read_write_proxy<Value> reference;
using reference = detail::read_write_proxy<Value>;
detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
};
@ -360,12 +338,10 @@ template <>
struct iterator_access_archetype_impl<archetypes::readable_lvalue_iterator_t>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, archetypes::readable_iterator_t
>
struct archetype :
public virtual iterator_access_archetype<Value, archetypes::readable_iterator_t>
{
typedef Value& reference;
using reference = Value&;
Value& operator*() const { return static_object<Value>::get(); }
Value* operator->() const { return 0; }
@ -376,12 +352,10 @@ template <>
struct iterator_access_archetype_impl<archetypes::writable_lvalue_iterator_t>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, archetypes::readable_lvalue_iterator_t
>
struct archetype :
public virtual iterator_access_archetype<Value, archetypes::readable_lvalue_iterator_t>
{
BOOST_STATIC_ASSERT((!is_const<Value>::value));
static_assert(!std::is_const<Value>::value, "Value type must not be const.");
};
};
@ -390,58 +364,59 @@ template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype;
template <class Value, class AccessCategory, class TraversalCategory>
struct traversal_archetype_base
: detail::operator_brackets<
typename remove_cv<Value>::type
, AccessCategory
, TraversalCategory
>
, detail::traversal_archetype_<
iterator_archetype<Value, AccessCategory, TraversalCategory>
, Value
, TraversalCategory
struct traversal_archetype_base :
public detail::operator_brackets<
typename std::remove_cv<Value>::type,
AccessCategory,
TraversalCategory
>,
public detail::traversal_archetype_<
iterator_archetype<Value, AccessCategory, TraversalCategory>,
Value,
TraversalCategory
>
{
};
namespace detail
{
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype_base
: iterator_access_archetype<Value, AccessCategory>
, traversal_archetype_base<Value, AccessCategory, TraversalCategory>
{
typedef iterator_access_archetype<Value, AccessCategory> access;
typedef typename detail::facade_iterator_category<
TraversalCategory
, typename mpl::eval_if<
archetypes::has_access<
AccessCategory, archetypes::writable_iterator_t
>
, remove_const<Value>
, add_const<Value>
>::type
, typename access::reference
>::type iterator_category;
// Needed for some broken libraries (see below)
struct workaround_iterator_base
{
typedef typename iterator_archetype_base::iterator_category iterator_category;
typedef Value value_type;
typedef typename traversal_archetype_base<
Value, AccessCategory, TraversalCategory
>::difference_type difference_type;
typedef typename access::pointer pointer;
typedef typename access::reference reference;
};
};
}
namespace detail {
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype
: public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
struct iterator_archetype_base :
public iterator_access_archetype<Value, AccessCategory>,
public traversal_archetype_base<Value, AccessCategory, TraversalCategory>
{
using access = iterator_access_archetype<Value, AccessCategory>;
using iterator_category = typename detail::facade_iterator_category<
TraversalCategory,
typename std::conditional<
archetypes::has_access<
AccessCategory, archetypes::writable_iterator_t
>::value,
std::remove_const<Value>,
std::add_const<Value>
>::type::type,
typename access::reference
>::type;
// Needed for some broken libraries (see below)
struct workaround_iterator_base
{
using iterator_category = typename iterator_archetype_base::iterator_category;
using value_type = Value;
using difference_type = typename traversal_archetype_base<
Value, AccessCategory, TraversalCategory
>::difference_type;
using pointer = typename access::pointer;
using reference = typename access::reference;
};
};
} // namespace detail
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype :
public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
// These broken libraries require derivation from std::iterator
// (or related magic) in order to handle iter_swap and other
@ -459,28 +434,23 @@ struct iterator_archetype
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
typedef detail::iterator_archetype_base<
Value,AccessCategory,TraversalCategory
> base;
using base = detail::iterator_archetype_base<
Value, AccessCategory, TraversalCategory
>;
typedef typename base::value_type value_type;
typedef typename base::reference reference;
typedef typename base::pointer pointer;
typedef typename base::difference_type difference_type;
typedef typename base::iterator_category iterator_category;
using value_type = typename base::value_type;
using reference = typename base::reference;
using pointer = typename base::pointer;
using difference_type = typename base::difference_type;
using iterator_category = typename base::iterator_category;
# endif
iterator_archetype() { }
iterator_archetype(iterator_archetype const& x)
: detail::iterator_archetype_base<
Value
, AccessCategory
, TraversalCategory
>(x)
iterator_archetype(iterator_archetype const& x) :
detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>(x)
{}
iterator_archetype& operator=(iterator_archetype const&)
{ return *this; }
iterator_archetype& operator=(iterator_archetype const&) { return *this; }
# if 0
// Optional conversion from mutable

View File

@ -4,23 +4,13 @@
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ITERATOR_CATEGORIES_HPP
# define BOOST_ITERATOR_CATEGORIES_HPP
# include <boost/config.hpp>
# include <boost/iterator/detail/config_def.hpp>
# include <boost/detail/workaround.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/placeholders.hpp>
# include <boost/mpl/aux_/lambda_support.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/static_assert.hpp>
#define BOOST_ITERATOR_CATEGORIES_HPP
#include <iterator>
#include <type_traits>
#include <boost/mpl/arg_fwd.hpp>
#include <boost/mp11/utility.hpp>
namespace boost {
namespace iterators {
@ -28,168 +18,78 @@ namespace iterators {
//
// Traversal Categories
//
struct no_traversal_tag {};
struct incrementable_traversal_tag
: no_traversal_tag
{
// incrementable_traversal_tag() {}
// incrementable_traversal_tag(std::output_iterator_tag const&) {};
};
struct single_pass_traversal_tag
: incrementable_traversal_tag
{
// single_pass_traversal_tag() {}
// single_pass_traversal_tag(std::input_iterator_tag const&) {};
};
struct forward_traversal_tag
: single_pass_traversal_tag
{
// forward_traversal_tag() {}
// forward_traversal_tag(std::forward_iterator_tag const&) {};
};
struct bidirectional_traversal_tag
: forward_traversal_tag
{
// bidirectional_traversal_tag() {};
// bidirectional_traversal_tag(std::bidirectional_iterator_tag const&) {};
};
struct random_access_traversal_tag
: bidirectional_traversal_tag
{
// random_access_traversal_tag() {};
// random_access_traversal_tag(std::random_access_iterator_tag const&) {};
};
namespace detail
{
//
// Convert a "strictly old-style" iterator category to a traversal
// tag. This is broken out into a separate metafunction to reduce
// the cost of instantiating iterator_category_to_traversal, below,
// for new-style types.
//
template <class Cat>
struct old_category_to_traversal
: mpl::eval_if<
is_convertible<Cat,std::random_access_iterator_tag>
, mpl::identity<random_access_traversal_tag>
, mpl::eval_if<
is_convertible<Cat,std::bidirectional_iterator_tag>
, mpl::identity<bidirectional_traversal_tag>
, mpl::eval_if<
is_convertible<Cat,std::forward_iterator_tag>
, mpl::identity<forward_traversal_tag>
, mpl::eval_if<
is_convertible<Cat,std::input_iterator_tag>
, mpl::identity<single_pass_traversal_tag>
, mpl::eval_if<
is_convertible<Cat,std::output_iterator_tag>
, mpl::identity<incrementable_traversal_tag>
, void
>
>
>
>
>
{};
} // namespace detail
struct incrementable_traversal_tag : public no_traversal_tag {};
struct single_pass_traversal_tag : public incrementable_traversal_tag {};
struct forward_traversal_tag : public single_pass_traversal_tag {};
struct bidirectional_traversal_tag : public forward_traversal_tag {};
struct random_access_traversal_tag : public bidirectional_traversal_tag {};
//
// Convert an iterator category into a traversal tag
//
template <class Cat>
template< typename Cat >
using iterator_category_to_traversal_t = mp11::mp_cond<
// if already convertible to a traversal tag, we're done.
std::is_convertible< Cat, incrementable_traversal_tag >, Cat,
std::is_convertible< Cat, std::random_access_iterator_tag >, random_access_traversal_tag,
std::is_convertible< Cat, std::bidirectional_iterator_tag >, bidirectional_traversal_tag,
std::is_convertible< Cat, std::forward_iterator_tag >, forward_traversal_tag,
std::is_convertible< Cat, std::input_iterator_tag >, single_pass_traversal_tag,
std::is_convertible< Cat, std::output_iterator_tag >, incrementable_traversal_tag,
std::true_type, void
>;
template< typename Cat >
struct iterator_category_to_traversal
: mpl::eval_if< // if already convertible to a traversal tag, we're done.
is_convertible<Cat,incrementable_traversal_tag>
, mpl::identity<Cat>
, boost::iterators::detail::old_category_to_traversal<Cat>
>
{};
{
using type = iterator_category_to_traversal_t< Cat >;
};
// Trait to get an iterator's traversal category
template <class Iterator = mpl::_1>
struct iterator_traversal
: iterator_category_to_traversal<
typename std::iterator_traits<Iterator>::iterator_category
>
{};
template< typename Iterator >
using iterator_traversal_t = iterator_category_to_traversal_t<
typename std::iterator_traits< Iterator >::iterator_category
>;
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. Instantiating the nested apply template also
// requires instantiating iterator_traits on the
// placeholder. Instead we just specialize it as a metafunction
// class.
template <>
struct iterator_traversal<mpl::_1>
template< typename Iterator = mpl::arg< 1 > >
struct iterator_traversal
{
template <class T>
struct apply : iterator_traversal<T>
{};
using type = iterator_traversal_t< Iterator >;
};
template <>
struct iterator_traversal<mpl::_>
: iterator_traversal<mpl::_1>
{};
# endif
//
// Convert an iterator traversal to one of the traversal tags.
//
template <class Traversal>
template< typename Traversal >
using pure_traversal_tag_t = mp11::mp_cond<
std::is_convertible< Traversal, random_access_traversal_tag >, random_access_traversal_tag,
std::is_convertible< Traversal, bidirectional_traversal_tag >, bidirectional_traversal_tag,
std::is_convertible< Traversal, forward_traversal_tag >, forward_traversal_tag,
std::is_convertible< Traversal, single_pass_traversal_tag >, single_pass_traversal_tag,
std::is_convertible< Traversal, incrementable_traversal_tag >, incrementable_traversal_tag,
std::true_type, void
>;
template< typename Traversal >
struct pure_traversal_tag
: mpl::eval_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<random_access_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,bidirectional_traversal_tag>
, mpl::identity<bidirectional_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,forward_traversal_tag>
, mpl::identity<forward_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,single_pass_traversal_tag>
, mpl::identity<single_pass_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,incrementable_traversal_tag>
, mpl::identity<incrementable_traversal_tag>
, void
>
>
>
>
>
{
using type = pure_traversal_tag_t< Traversal >;
};
//
// Trait to retrieve one of the iterator traversal tags from the iterator category or traversal.
//
template <class Iterator = mpl::_1>
struct pure_iterator_traversal
: pure_traversal_tag<typename iterator_traversal<Iterator>::type>
{};
template< typename Iterator >
using pure_iterator_traversal_t = pure_traversal_tag_t<
iterator_traversal_t< Iterator >
>;
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
template <>
struct pure_iterator_traversal<mpl::_1>
template< typename Iterator = mpl::arg< 1 > >
struct pure_iterator_traversal
{
template <class T>
struct apply : pure_iterator_traversal<T>
{};
using type = pure_iterator_traversal_t< Iterator >;
};
template <>
struct pure_iterator_traversal<mpl::_>
: pure_iterator_traversal<mpl::_1>
{};
# endif
} // namespace iterators
@ -202,15 +102,6 @@ using iterators::random_access_traversal_tag;
using iterators::iterator_category_to_traversal;
using iterators::iterator_traversal;
// This import is needed for backward compatibility with Boost.Range:
// boost/range/detail/demote_iterator_traversal_tag.hpp
// It should be removed when that header is fixed.
namespace detail {
using iterators::pure_traversal_tag;
} // namespace detail
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_ITERATOR_CATEGORIES_HPP

View File

@ -9,15 +9,7 @@
#include <boost/concept_check.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/static_assert.hpp>
#include <type_traits>
// Use boost/limits to work around missing limits headers on some compilers
#include <boost/limits.hpp>
@ -144,8 +136,8 @@ namespace boost_concepts
{
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
BOOST_MPL_ASSERT((boost::is_integral<difference_type>));
BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
static_assert(std::is_integral<difference_type>::value, "difference_type must be integral.");
static_assert(std::numeric_limits<difference_type>::is_signed, "difference_type must be signed.");
BOOST_CONCEPT_ASSERT((
boost::Convertible<

File diff suppressed because it is too large Load Diff

View File

@ -3,49 +3,56 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ITERATOR_TRAITS_DWA200347_HPP
# define ITERATOR_TRAITS_DWA200347_HPP
# include <boost/detail/workaround.hpp>
#define ITERATOR_TRAITS_DWA200347_HPP
#include <iterator>
namespace boost {
namespace iterators {
// Macro for supporting old compilers, no longer needed but kept
// for backwards compatibility (it was documented).
#define BOOST_ITERATOR_CATEGORY iterator_category
template< typename Iterator >
using iterator_value_t = typename std::iterator_traits< Iterator >::value_type;
template <class Iterator>
template< typename Iterator >
struct iterator_value
{
typedef typename std::iterator_traits<Iterator>::value_type type;
using type = iterator_value_t< Iterator >;
};
template <class Iterator>
template< typename Iterator >
using iterator_reference_t = typename std::iterator_traits< Iterator >::reference;
template< typename Iterator >
struct iterator_reference
{
typedef typename std::iterator_traits<Iterator>::reference type;
using type = iterator_reference_t< Iterator >;
};
template< typename Iterator >
using iterator_pointer_t = typename std::iterator_traits< Iterator >::pointer;
template <class Iterator>
template< typename Iterator >
struct iterator_pointer
{
typedef typename std::iterator_traits<Iterator>::pointer type;
using type = iterator_pointer_t< Iterator >;
};
template <class Iterator>
template< typename Iterator >
using iterator_difference_t = typename std::iterator_traits< Iterator >::difference_type;
template< typename Iterator >
struct iterator_difference
{
typedef typename std::iterator_traits<Iterator>::difference_type type;
using type = iterator_difference_t< Iterator >;
};
template <class Iterator>
template< typename Iterator >
using iterator_category_t = typename std::iterator_traits< Iterator >::iterator_category;
template< typename Iterator >
struct iterator_category
{
typedef typename std::iterator_traits<Iterator>::iterator_category type;
using type = iterator_category_t< Iterator >;
};
} // namespace iterators

View File

@ -0,0 +1,83 @@
// Copyright Andrey Semashev 2025.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ITERATOR_MIN_CATEGORY_HPP_INCLUDED_
#define BOOST_ITERATOR_MIN_CATEGORY_HPP_INCLUDED_
#include <type_traits>
namespace boost {
namespace iterators {
namespace detail {
template<
typename T1,
typename T2,
bool GreaterEqual = std::is_convertible< T1, T2 >::value,
bool LessEqual = std::is_convertible< T2, T1 >::value
>
struct min_category_impl
{
static_assert(GreaterEqual || LessEqual, "Iterator category types must be related through convertibility.");
};
template< typename T1, typename T2 >
struct min_category_impl< T1, T2, true, false >
{
using type = T2;
};
template< typename T1, typename T2 >
struct min_category_impl< T1, T2, false, true >
{
using type = T1;
};
template< typename T1, typename T2 >
struct min_category_impl< T1, T2, true, true >
{
static_assert(std::is_same< T1, T2 >::value, "Iterator category types must be the same when they are equivalent.");
using type = T1;
};
} // namespace detail
//
// Returns the minimum iterator category type in the list
// or fails to compile if any of the categories are unrelated.
//
template< typename... Categories >
struct min_category;
template< typename T >
struct min_category< T >
{
using type = T;
};
template< typename T1, typename T2, typename... Tail >
struct min_category< T1, T2, Tail... >
{
using type = typename min_category<
typename iterators::detail::min_category_impl< T1, T2 >::type,
Tail...
>::type;
};
// Shortcut to slightly optimize compilation speed
template< typename T1, typename T2 >
struct min_category< T1, T2 >
{
using type = typename iterators::detail::min_category_impl< T1, T2 >::type;
};
template< typename... Categories >
using min_category_t = typename min_category< Categories... >::type;
} // namespace iterators
} // namespace boost
#endif // BOOST_ITERATOR_MIN_CATEGORY_HPP_INCLUDED_

View File

@ -2,94 +2,32 @@
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
# define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
#define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
# include <boost/static_assert.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/mpl/placeholders.hpp>
# include <boost/mpl/aux_/lambda_support.hpp>
#include <boost/mpl/arg_fwd.hpp>
#include <boost/iterator/min_category.hpp>
namespace boost {
namespace iterators {
namespace detail {
template <bool GreaterEqual, bool LessEqual>
struct minimum_category_impl;
template <class T1, class T2>
struct error_not_related_by_convertibility;
template <>
struct minimum_category_impl<true,false>
// Deprecated metafunction for selecting minimum iterator category,
// use min_category instead.
template< class T1 = mpl::arg<1>, class T2 = mpl::arg<2> >
struct minimum_category :
public min_category<T1, T2>
{
template <class T1, class T2> struct apply
{
typedef T2 type;
};
};
template <>
struct minimum_category_impl<false,true>
{
template <class T1, class T2> struct apply
{
typedef T1 type;
};
};
template <>
struct minimum_category_impl<true,true>
{
template <class T1, class T2> struct apply
{
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
typedef T1 type;
};
};
template <>
struct minimum_category_impl<false,false>
{
template <class T1, class T2> struct apply
: error_not_related_by_convertibility<T1,T2>
{
};
};
} // namespace detail
//
// Returns the minimum category type or fails to compile
// if T1 and T2 are unrelated.
//
template <class T1 = mpl::_1, class T2 = mpl::_2>
struct minimum_category
{
typedef boost::iterators::detail::minimum_category_impl<
::boost::is_convertible<T1,T2>::value
, ::boost::is_convertible<T2,T1>::value
> outer;
typedef typename outer::template apply<T1,T2> inner;
typedef typename inner::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
};
template <>
struct minimum_category<mpl::_1,mpl::_2>
struct minimum_category< mpl::arg<1>, mpl::arg<2> >
{
template <class T1, class T2>
struct apply : minimum_category<T1,T2>
struct apply :
public min_category<T1, T2>
{};
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2))
};
} // namespace iterators
} // namespace boost
#endif // BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_

View File

@ -1,5 +1,5 @@
#ifndef BOOST_NEW_ITERATOR_TESTS_HPP
# define BOOST_NEW_ITERATOR_TESTS_HPP
#define BOOST_NEW_ITERATOR_TESTS_HPP
//
// Copyright (c) David Abrahams 2001.
@ -28,50 +28,45 @@
// 04 Feb 2001 Added lvalue test, corrected preconditions
// (David Abrahams)
# include <iterator>
# include <boost/static_assert.hpp>
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
# include <boost/pending/iterator_tests.hpp>
# include <boost/iterator/is_readable_iterator.hpp>
# include <boost/iterator/is_lvalue_iterator.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/mpl/and.hpp>
#include <boost/concept_archetype.hpp> // for detail::dummy_constructor
#include <boost/iterator/is_lvalue_iterator.hpp>
#include <boost/iterator/is_readable_iterator.hpp>
#include <boost/pending/iterator_tests.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/is_incrementable.hpp>
#include <boost/iterator/detail/type_traits/conjunction.hpp>
# include <boost/iterator/detail/config_def.hpp>
# include <boost/detail/is_incrementable.hpp>
# include <boost/core/lightweight_test.hpp>
#include <iterator>
#include <type_traits>
namespace boost {
// Do separate tests for *i++ so we can treat, e.g., smart pointers,
// as readable and/or writable iterators.
template <class Iterator, class T>
void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
void readable_iterator_traversal_test(Iterator i1, T v, std::true_type)
{
T v2(*i1++);
BOOST_TEST(v == v2);
}
template <class Iterator, class T>
void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
void readable_iterator_traversal_test(const Iterator i1, T v, std::false_type)
{}
template <class Iterator, class T>
void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
void writable_iterator_traversal_test(Iterator i1, T v, std::true_type)
{
++i1; // we just wrote into that position
++i1; // we just wrote into that position
*i1++ = v;
Iterator x(i1++);
(void)x;
}
template <class Iterator, class T>
void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
void writable_iterator_traversal_test(const Iterator i1, T v, std::false_type)
{}
// Preconditions: *i == v
template <class Iterator, class T>
void readable_iterator_test(const Iterator i1, T v)
@ -85,13 +80,15 @@ void readable_iterator_test(const Iterator i1, T v)
BOOST_TEST(v1 == v);
BOOST_TEST(v2 == v);
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
readable_iterator_traversal_test(
i1, v,
std::integral_constant<
bool, detail::is_postfix_incrementable<Iterator>::value>{});
// I think we don't really need this as it checks the same things as
// the above code.
BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
# endif
static_assert(is_readable_iterator<Iterator>::value,
"Iterator must be readable.");
}
template <class Iterator, class T>
@ -100,13 +97,12 @@ void writable_iterator_test(Iterator i, T v, T v2)
Iterator i2(i); // Copy Constructible
*i2 = v;
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
writable_iterator_traversal_test(
i, v2, mpl::and_<
detail::is_incrementable<Iterator>
, detail::is_postfix_incrementable<Iterator>
i, v2,
iterators::detail::conjunction<
std::integral_constant<bool, detail::is_incrementable<Iterator>::value>,
std::integral_constant<bool, detail::is_postfix_incrementable<Iterator>::value>
>());
# endif
}
template <class Iterator>
@ -125,13 +121,16 @@ void constant_lvalue_iterator_test(Iterator i, T v1)
Iterator i2(i);
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::reference reference;
BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
static_assert(std::is_same<const value_type&, reference>::value,
"reference type must be the same as const value_type& for "
"constant lvalue iterator.");
const T& v2 = *i2;
BOOST_TEST(v1 == v2);
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
# endif
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
static_assert(is_lvalue_iterator<Iterator>::value
&& !is_non_const_lvalue_iterator<Iterator>::value,
"Iterator must be a const lvalue iterator.");
#endif
}
template <class Iterator, class T>
@ -140,20 +139,22 @@ void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
Iterator i2(i);
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::reference reference;
BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
static_assert(std::is_same<value_type&, reference>::value,
"reference type must be the same as value_type& for "
"non-constant lvalue iterator.");
T& v3 = *i2;
BOOST_TEST(v1 == v3);
// A non-const lvalue iterator is not neccessarily writable, but we
// A non-const lvalue iterator is not necessarily writable, but we
// are assuming the value_type is assignable here
*i = v2;
T& v4 = *i2;
BOOST_TEST(v2 == v4);
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
# endif
static_assert(is_lvalue_iterator<Iterator>::value,
"Iterator must be an lvalue iterator.");
static_assert(is_non_const_lvalue_iterator<Iterator>::value,
"Iterator must be non-const.");
}
template <class Iterator, class T>
@ -226,7 +227,7 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
const Iterator j = i;
int c;
for (c = 0; c < N-1; ++c)
for (c = 0; c < N - 1; ++c)
{
BOOST_TEST(i == j + c);
BOOST_TEST(*i == vals[c]);
@ -242,7 +243,7 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
}
Iterator k = j + N - 1;
for (c = 0; c < N-1; ++c)
for (c = 0; c < N - 1; ++c)
{
BOOST_TEST(i == k - c);
BOOST_TEST(*i == vals[N - 1 - c]);
@ -260,6 +261,4 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
} // namespace boost
# include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_NEW_ITERATOR_TESTS_HPP

View File

@ -5,65 +5,74 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PERMUTATION_ITERATOR_HPP
#define BOOST_PERMUTATION_ITERATOR_HPP
#ifndef BOOST_ITERATOR_PERMUTATION_ITERATOR_HPP_INCLUDED_
#define BOOST_ITERATOR_PERMUTATION_ITERATOR_HPP_INCLUDED_
#include <iterator>
#include <boost/core/use_default.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/enable_if_convertible.hpp>
namespace boost {
namespace iterators {
template< class ElementIterator
, class IndexIterator>
class permutation_iterator
: public iterator_adaptor<
permutation_iterator<ElementIterator, IndexIterator>
, IndexIterator, typename std::iterator_traits<ElementIterator>::value_type
, use_default, typename std::iterator_traits<ElementIterator>::reference>
template< typename ElementIterator, typename IndexIterator >
class permutation_iterator :
public iterator_adaptor<
permutation_iterator< ElementIterator, IndexIterator >,
IndexIterator,
typename std::iterator_traits< ElementIterator >::value_type,
use_default,
typename std::iterator_traits< ElementIterator >::reference
>
{
typedef iterator_adaptor<
permutation_iterator<ElementIterator, IndexIterator>
, IndexIterator, typename std::iterator_traits<ElementIterator>::value_type
, use_default, typename std::iterator_traits<ElementIterator>::reference> super_t;
friend class iterator_core_access;
public:
permutation_iterator() : m_elt_iter() {}
explicit permutation_iterator(ElementIterator x, IndexIterator y)
: super_t(y), m_elt_iter(x) {}
template<class OtherElementIterator, class OtherIndexIterator>
permutation_iterator(
permutation_iterator<OtherElementIterator, OtherIndexIterator> const& r
, typename enable_if_convertible<OtherElementIterator, ElementIterator>::type* = 0
, typename enable_if_convertible<OtherIndexIterator, IndexIterator>::type* = 0
)
: super_t(r.base()), m_elt_iter(r.m_elt_iter)
{}
friend class iterator_core_access;
template< typename, typename >
friend class permutation_iterator;
private:
typename super_t::reference dereference() const
{ return *(m_elt_iter + *this->base()); }
using super_t = iterator_adaptor<
permutation_iterator< ElementIterator, IndexIterator >,
IndexIterator,
typename std::iterator_traits< ElementIterator >::value_type,
use_default,
typename std::iterator_traits< ElementIterator >::reference
>;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template <class,class> friend class permutation_iterator;
#else
public:
#endif
public:
permutation_iterator() :
m_elt_iter()
{}
explicit permutation_iterator(ElementIterator x, IndexIterator y) :
super_t(y),
m_elt_iter(x)
{}
template<
typename OtherElementIterator,
typename OtherIndexIterator,
typename = enable_if_convertible_t< OtherElementIterator, ElementIterator >,
typename = enable_if_convertible_t< OtherIndexIterator, IndexIterator >
>
permutation_iterator(permutation_iterator< OtherElementIterator, OtherIndexIterator > const& r) :
super_t(r.base()),
m_elt_iter(r.m_elt_iter)
{}
private:
typename super_t::reference dereference() const { return *(m_elt_iter + *this->base()); }
private:
ElementIterator m_elt_iter;
};
template <class ElementIterator, class IndexIterator>
inline permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator( ElementIterator e, IndexIterator i )
template< typename ElementIterator, typename IndexIterator >
inline permutation_iterator< ElementIterator, IndexIterator > make_permutation_iterator(ElementIterator e, IndexIterator i)
{
return permutation_iterator<ElementIterator, IndexIterator>( e, i );
return permutation_iterator< ElementIterator, IndexIterator >(e, i);
}
} // namespace iterators
@ -73,4 +82,4 @@ using iterators::make_permutation_iterator;
} // namespace boost
#endif
#endif // BOOST_ITERATOR_PERMUTATION_ITERATOR_HPP_INCLUDED_

View File

@ -4,68 +4,67 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
#ifndef BOOST_ITERATOR_REVERSE_ITERATOR_23022003THW_HPP
#define BOOST_ITERATOR_REVERSE_ITERATOR_23022003THW_HPP
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/enable_if_convertible.hpp>
namespace boost {
namespace iterators {
//
//
//
template <class Iterator>
class reverse_iterator
: public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
{
typedef iterator_adaptor< reverse_iterator<Iterator>, Iterator > super_t;
template< typename Iterator >
class reverse_iterator :
public iterator_adaptor< reverse_iterator< Iterator >, Iterator >
{
friend class iterator_core_access;
friend class iterator_core_access;
private:
using super_t = iterator_adaptor< reverse_iterator< Iterator >, Iterator >;
public:
reverse_iterator() {}
public:
reverse_iterator() = default;
explicit reverse_iterator(Iterator x)
: super_t(x) {}
explicit reverse_iterator(Iterator x) :
super_t(x)
{}
template<class OtherIterator>
reverse_iterator(
reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
)
: super_t(r.base())
{}
template<
typename OtherIterator,
typename = enable_if_convertible_t< OtherIterator, Iterator >
>
reverse_iterator(reverse_iterator< OtherIterator > const& r) :
super_t(r.base())
{}
private:
typename super_t::reference dereference() const
{
Iterator it = this->base_reference();
--it;
return *it;
}
private:
typename super_t::reference dereference() const
{
Iterator it = this->base_reference();
--it;
return *it;
}
void increment() { --this->base_reference(); }
void decrement() { ++this->base_reference(); }
void increment() { --this->base_reference(); }
void decrement() { ++this->base_reference(); }
void advance(typename super_t::difference_type n)
{
this->base_reference() -= n;
}
void advance(typename super_t::difference_type n)
{
this->base_reference() -= n;
}
template <class OtherIterator>
typename super_t::difference_type
distance_to(reverse_iterator<OtherIterator> const& y) const
{
return this->base_reference() - y.base();
}
};
template< typename OtherIterator >
typename super_t::difference_type distance_to(reverse_iterator< OtherIterator > const& y) const
{
return this->base_reference() - y.base();
}
};
template <class BidirectionalIterator>
inline reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x)
{
return reverse_iterator<BidirectionalIterator>(x);
}
template< typename Iterator >
inline reverse_iterator< Iterator > make_reverse_iterator(Iterator x)
{
return reverse_iterator< Iterator >(x);
}
} // namespace iterators
@ -74,4 +73,4 @@ using iterators::make_reverse_iterator;
} // namespace boost
#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP
#endif // BOOST_ITERATOR_REVERSE_ITERATOR_23022003THW_HPP

View File

@ -0,0 +1,117 @@
// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation.
#ifndef BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
#define BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_
#include <memory>
#include <utility>
#include <boost/iterator/iterator_adaptor.hpp>
namespace boost {
// For backward compatibility with boost::shared_ptr
template< class T >
class shared_ptr;
namespace iterators {
namespace detail {
// Fake deleter that holds an instance of boost::shared_ptr and through it keeps the pointed object from deletion
template< typename T >
class shared_container_iterator_bsptr_holder
{
private:
boost::shared_ptr< T > m_ptr;
public:
explicit shared_container_iterator_bsptr_holder(boost::shared_ptr< T > const& ptr) :
m_ptr(ptr)
{}
void operator()(T*) const noexcept {}
};
} // namespace detail
template< typename Container >
class shared_container_iterator :
public iterator_adaptor<
shared_container_iterator< Container >,
typename Container::iterator
>
{
private:
using super_t = iterator_adaptor<
shared_container_iterator< Container >,
typename Container::iterator
>;
using iterator_t = typename Container::iterator;
using container_ref_t = std::shared_ptr< Container >;
public:
shared_container_iterator() = default;
shared_container_iterator(iterator_t const& x, container_ref_t const& c) :
super_t(x),
m_container_ref(c)
{}
// Constructor for backward compatibility with boost::shared_ptr
shared_container_iterator(iterator_t const& x, boost::shared_ptr< Container > const& c) :
super_t(x),
m_container_ref(c.get(), detail::shared_container_iterator_bsptr_holder< Container >(c))
{}
private:
container_ref_t m_container_ref;
};
template< typename Container >
inline shared_container_iterator< Container >
make_shared_container_iterator(typename Container::iterator iter, std::shared_ptr< Container > const& container)
{
return shared_container_iterator< Container >(iter, container);
}
template< typename Container >
inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > >
make_shared_container_range(std::shared_ptr< Container > const& container)
{
return std::make_pair
(
iterators::make_shared_container_iterator(container->begin(), container),
iterators::make_shared_container_iterator(container->end(), container)
);
}
// Factory functions for backward compatibility with boost::shared_ptr
template< typename Container >
inline shared_container_iterator< Container >
make_shared_container_iterator(typename Container::iterator iter, boost::shared_ptr< Container > const& container)
{
return shared_container_iterator< Container >(iter, container);
}
template< typename Container >
inline std::pair< shared_container_iterator< Container >, shared_container_iterator< Container > >
make_shared_container_range(boost::shared_ptr< Container > const& container)
{
std::shared_ptr< Container > c(container.get(), detail::shared_container_iterator_bsptr_holder< Container >(container));
return iterators::make_shared_container_range(std::move(c));
}
} // namespace iterators
using iterators::shared_container_iterator;
using iterators::make_shared_container_iterator;
using iterators::make_shared_container_range;
} // namespace boost
#endif // BOOST_ITERATOR_SHARED_CONTAINER_ITERATOR_HPP_INCLUDED_

View File

@ -4,168 +4,137 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/result_of.hpp>
#ifndef BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
#define BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP
#include <iterator>
#include <type_traits>
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
#include <boost/type_traits/is_base_and_derived.hpp>
#endif
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
#include <boost/static_assert.hpp>
#endif
#include <boost/iterator/detail/config_def.hpp>
#include <boost/core/use_default.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/enable_if_convertible.hpp>
#include <boost/iterator/detail/eval_if_default.hpp>
namespace boost {
namespace iterators {
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
class transform_iterator;
template<
typename UnaryFunction,
typename Iterator,
typename Reference = use_default,
typename Value = use_default
>
class transform_iterator;
namespace detail
{
// Compute the iterator_adaptor instantiation to be used for transform_iterator
template <class UnaryFunc, class Iterator, class Reference, class Value>
struct transform_iterator_base
{
private:
// By default, dereferencing the iterator yields the same as
// the function.
typedef typename ia_dflt_help<
Reference
#ifdef BOOST_RESULT_OF_USE_TR1
, result_of<const UnaryFunc(typename std::iterator_traits<Iterator>::reference)>
#else
, result_of<const UnaryFunc&(typename std::iterator_traits<Iterator>::reference)>
#endif
>::type reference;
namespace detail {
// To get the default for Value: remove any reference on the
// result type, but retain any constness to signal
// non-writability. Note that if we adopt Thomas' suggestion
// to key non-writability *only* on the Reference argument,
// we'd need to strip constness here as well.
typedef typename ia_dflt_help<
Value
, remove_reference<reference>
>::type cv_value_type;
template< typename UnaryFunc, typename Iterator >
struct transform_iterator_default_reference
{
using type = decltype(std::declval< UnaryFunc const& >()(std::declval< typename std::iterator_traits< Iterator >::reference >()));
};
public:
typedef iterator_adaptor<
transform_iterator<UnaryFunc, Iterator, Reference, Value>
, Iterator
, cv_value_type
, use_default // Leave the traversal category alone
, reference
> type;
};
}
// Compute the iterator_adaptor instantiation to be used for transform_iterator
template< typename UnaryFunc, typename Iterator, typename Reference, typename Value >
struct transform_iterator_base
{
private:
// By default, dereferencing the iterator yields the same as
// the function.
using reference = detail::eval_if_default_t<
Reference,
transform_iterator_default_reference< UnaryFunc, Iterator >
>;
template <class UnaryFunc, class Iterator, class Reference, class Value>
class transform_iterator
: public boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
{
typedef typename
boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
super_t;
// To get the default for Value: remove any reference on the
// result type, but retain any constness to signal
// non-writability. Note that if we adopt Thomas' suggestion
// to key non-writability *only* on the Reference argument,
// we'd need to strip constness here as well.
using cv_value_type = detail::eval_if_default_t<
Value,
std::remove_reference< reference >
>;
public:
using type = iterator_adaptor<
transform_iterator< UnaryFunc, Iterator, Reference, Value >,
Iterator,
cv_value_type,
use_default, // Leave the traversal category alone
reference
>;
};
} // namespace detail
template< typename UnaryFunc, typename Iterator, typename Reference, typename Value >
class transform_iterator :
public detail::transform_iterator_base< UnaryFunc, Iterator, Reference, Value >::type,
private boost::empty_value< UnaryFunc >
{
friend class iterator_core_access;
public:
transform_iterator() { }
private:
using super_t = typename detail::transform_iterator_base< UnaryFunc, Iterator, Reference, Value >::type;
using functor_base = boost::empty_value< UnaryFunc >;
transform_iterator(Iterator const& x, UnaryFunc f)
: super_t(x), m_f(f) { }
public:
transform_iterator() = default;
explicit transform_iterator(Iterator const& x)
: super_t(x)
{
// Pro8 is a little too aggressive about instantiating the
// body of this function.
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
// don't provide this constructor if UnaryFunc is a
// function pointer type, since it will be 0. Too dangerous.
BOOST_STATIC_ASSERT(is_class<UnaryFunc>::value);
#endif
}
transform_iterator(Iterator const& x, UnaryFunc f) :
super_t(x),
functor_base(boost::empty_init_t{}, f)
{}
template <
class OtherUnaryFunction
, class OtherIterator
, class OtherReference
, class OtherValue>
transform_iterator(
transform_iterator<OtherUnaryFunction, OtherIterator, OtherReference, OtherValue> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
, typename enable_if_convertible<OtherUnaryFunction, UnaryFunc>::type* = 0
#endif
)
: super_t(t.base()), m_f(t.functor())
{}
// don't provide this constructor if UnaryFunc is a
// function pointer type, since it will be 0. Too dangerous.
template< bool Requires = std::is_class< UnaryFunc >::value, typename = typename std::enable_if< Requires >::type >
explicit transform_iterator(Iterator const& x) :
super_t(x)
{}
UnaryFunc functor() const
{ return m_f; }
template<
typename OtherUnaryFunction,
typename OtherIterator,
typename OtherReference,
typename OtherValue,
typename = enable_if_convertible_t< OtherIterator, Iterator >,
typename = enable_if_convertible_t< OtherUnaryFunction, UnaryFunc >
>
transform_iterator(transform_iterator< OtherUnaryFunction, OtherIterator, OtherReference, OtherValue > const& t) :
super_t(t.base()),
functor_base(boost::empty_init_t{}, t.functor())
{}
private:
typename super_t::reference dereference() const
{ return m_f(*this->base()); }
UnaryFunc functor() const { return functor_base::get(); }
// Probably should be the initial base class so it can be
// optimized away via EBO if it is an empty class.
UnaryFunc m_f;
};
private:
typename super_t::reference dereference() const { return functor_base::get()(*this->base()); }
};
template <class UnaryFunc, class Iterator>
inline transform_iterator<UnaryFunc, Iterator>
make_transform_iterator(Iterator it, UnaryFunc fun)
{
return transform_iterator<UnaryFunc, Iterator>(it, fun);
}
template< typename UnaryFunc, typename Iterator >
inline transform_iterator< UnaryFunc, Iterator > make_transform_iterator(Iterator it, UnaryFunc fun)
{
return transform_iterator< UnaryFunc, Iterator >(it, fun);
}
// Version which allows explicit specification of the UnaryFunc
// type.
//
// This generator is not provided if UnaryFunc is a function
// pointer type, because it's too dangerous: the default-constructed
// function pointer in the iterator be 0, leading to a runtime
// crash.
template <class UnaryFunc, class Iterator>
inline typename iterators::enable_if<
is_class<UnaryFunc> // We should probably find a cheaper test than is_class<>
, transform_iterator<UnaryFunc, Iterator>
>::type
make_transform_iterator(Iterator it)
{
return transform_iterator<UnaryFunc, Iterator>(it, UnaryFunc());
}
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template <class Return, class Argument, class Iterator>
inline transform_iterator< Return (*)(Argument), Iterator, Return>
make_transform_iterator(Iterator it, Return (*fun)(Argument))
{
return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
}
#endif
// Version which allows explicit specification of the UnaryFunc
// type.
//
// This generator is not provided if UnaryFunc is a function
// pointer type, because it's too dangerous: the default-constructed
// function pointer in the iterator be 0, leading to a runtime
// crash.
template< typename UnaryFunc, typename Iterator >
inline typename std::enable_if<
std::is_class< UnaryFunc >::value, // We should probably find a cheaper test than is_class<>
transform_iterator< UnaryFunc, Iterator >
>::type make_transform_iterator(Iterator it)
{
return transform_iterator< UnaryFunc, Iterator >(it);
}
} // namespace iterators
@ -174,6 +143,4 @@ using iterators::make_transform_iterator;
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#endif // BOOST_ITERATOR_TRANSFORM_ITERATOR_23022003THW_HPP

View File

@ -6,27 +6,19 @@
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
# define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
#include <stddef.h>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/minimum_category.hpp>
#define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
#include <utility> // for std::pair
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/enable_if_convertible.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/min_category.hpp>
#include <boost/mp11/list.hpp>
#include <boost/mp11/utility.hpp>
#include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/algorithm/transformation/transform.hpp>
#include <boost/fusion/sequence/convert.hpp>
@ -35,245 +27,265 @@
#include <boost/fusion/support/tag_of_fwd.hpp>
namespace boost {
// Forward declarations for Boost.Tuple support
namespace tuples {
struct null_type;
template< class, class >
struct cons;
} // namespace tuples
// Forward declarations for Boost.Fusion support
namespace fusion {
struct void_;
} // namespace fusion
namespace iterators {
// Zip iterator forward declaration for zip_iterator_base
template<typename IteratorTuple>
class zip_iterator;
// Zip iterator forward declaration for zip_iterator_base
template< typename IteratorTuple >
class zip_iterator;
namespace detail
{
namespace detail {
// Functors to be used with tuple algorithms
//
template<typename DiffType>
class advance_iterator
// Functors to be used with tuple algorithms
//
template< typename DiffType >
class advance_iterator
{
public:
advance_iterator(DiffType step) :
m_step(step)
{}
template< typename Iterator >
void operator()(Iterator& it) const { it += m_step; }
private:
DiffType m_step;
};
struct increment_iterator
{
template< typename Iterator >
void operator()(Iterator& it) const { ++it; }
};
struct decrement_iterator
{
template< typename Iterator >
void operator()(Iterator& it) const { --it; }
};
struct dereference_iterator
{
template< typename >
struct result;
template< typename This, typename Iterator >
struct result< This(Iterator) >
{
public:
advance_iterator(DiffType step) : m_step(step) {}
template<typename Iterator>
void operator()(Iterator& it) const
{ it += m_step; }
private:
DiffType m_step;
};
//
struct increment_iterator
{
template<typename Iterator>
void operator()(Iterator& it) const
{ ++it; }
};
//
struct decrement_iterator
{
template<typename Iterator>
void operator()(Iterator& it) const
{ --it; }
};
//
struct dereference_iterator
{
template<typename>
struct result;
template<typename This, typename Iterator>
struct result<This(Iterator)>
{
typedef typename
remove_cv<typename remove_reference<Iterator>::type>::type
iterator;
typedef typename iterator_reference<iterator>::type type;
};
template<typename Iterator>
typename result<dereference_iterator(Iterator)>::type
operator()(Iterator const& it) const
{ return *it; }
using type = iterator_reference_t<
typename std::remove_cv< typename std::remove_reference< Iterator >::type >::type
>;
};
// Metafunction to obtain the type of the tuple whose element types
// are the reference types of an iterator tuple.
//
template<typename IteratorTuple>
struct tuple_of_references
: mpl::transform<
IteratorTuple,
iterator_reference<mpl::_1>
>
template< typename Iterator >
typename result< dereference_iterator(Iterator) >::type operator()(Iterator const& it) const
{
};
return *it;
}
};
// Specialization for std::pair
template<typename Iterator1, typename Iterator2>
struct tuple_of_references<std::pair<Iterator1, Iterator2> >
// The trait checks if the type is a trailing "null" type used to indicate unused template parameters in non-variadic types
template< typename T >
struct is_trailing_null_type : std::false_type {};
template< typename T >
struct is_trailing_null_type< const T > : is_trailing_null_type< T > {};
template< >
struct is_trailing_null_type< tuples::null_type > : std::true_type {};
template< >
struct is_trailing_null_type< fusion::void_ > : std::true_type {};
// Metafunction to obtain the type of the tuple whose element types
// are the reference types of an iterator tuple.
template< typename IteratorTuple >
struct tuple_of_references;
template< typename IteratorTuple >
using tuple_of_references_t = typename tuple_of_references< IteratorTuple >::type;
template< template< typename... > class Tuple, typename... Iterators >
struct tuple_of_references< Tuple< Iterators... > >
{
// Note: non-variadic Boost.Tuple and Boost.Fusion need special handling
// to avoid instantiating iterator traits on the trailing "null" types.
// If not that, we could simply do
// mp11::mp_transform< iterator_reference_t, IteratorTuple >.
using type = Tuple<
mp11::mp_eval_if<
detail::is_trailing_null_type< Iterators >,
Iterators,
iterator_reference_t, Iterators
>...
>;
};
template< typename Front, typename Tail >
struct tuple_of_references< tuples::cons< Front, Tail > >
{
using type = tuples::cons<
iterator_reference_t< Front >,
mp11::mp_eval_if<
detail::is_trailing_null_type< Tail >,
Tail,
detail::tuple_of_references_t, Tail
>
>;
};
// Metafunction to obtain the minimal traversal tag in a list
// of iterators.
template< typename IteratorList >
struct minimum_traversal_category_in_iterator_list;
template< typename IteratorList >
using minimum_traversal_category_in_iterator_list_t = typename minimum_traversal_category_in_iterator_list< IteratorList >::type;
template< template< typename... > class List, typename... Iterators >
struct minimum_traversal_category_in_iterator_list< List< Iterators... > >
{
// Note: non-variadic Boost.Tuple and Boost.Fusion need special handling
// to avoid instantiating iterator traits on the trailing "null" types.
// For such types just use random_access_traversal_tag, which will not
// affect the result of min_category.
using type = min_category_t<
mp11::mp_eval_if<
detail::is_trailing_null_type< Iterators >,
random_access_traversal_tag,
pure_iterator_traversal_t, Iterators
>...
>;
};
template< typename FrontTraversal, typename Tail >
using minimum_traversal_category_in_tail_t = min_category_t<
FrontTraversal,
minimum_traversal_category_in_iterator_list_t< Tail >
>;
template< typename Front, typename Tail >
struct minimum_traversal_category_in_iterator_list< tuples::cons< Front, Tail > >
{
using front_traversal = pure_iterator_traversal_t< Front >;
using type = mp11::mp_eval_if<
detail::is_trailing_null_type< Tail >,
front_traversal,
minimum_traversal_category_in_tail_t,
front_traversal,
Tail
>;
};
///////////////////////////////////////////////////////////////////
//
// Class zip_iterator_base
//
// Builds and exposes the iterator facade type from which the zip
// iterator will be derived.
//
template< typename IteratorTuple >
struct zip_iterator_base
{
private:
// Reference type is the type of the tuple obtained from the
// iterators' reference types.
using reference = detail::tuple_of_references_t< IteratorTuple >;
// Value type is the same as reference type.
using value_type = reference;
// Difference type is the first iterator's difference type
using difference_type = iterator_difference_t< mp11::mp_front< IteratorTuple > >;
// Traversal catetgory is the minimum traversal category in the
// iterator tuple.
using traversal_category = detail::minimum_traversal_category_in_iterator_list_t< IteratorTuple >;
public:
// The iterator facade type from which the zip iterator will
// be derived.
using type = iterator_facade<
zip_iterator< IteratorTuple >,
value_type,
traversal_category,
reference,
difference_type
>;
};
template< typename Reference >
struct converter
{
template< typename Seq >
static Reference call(Seq seq)
{
typedef std::pair<
typename iterator_reference<Iterator1>::type
, typename iterator_reference<Iterator2>::type
> type;
};
using tag = typename fusion::traits::tag_of< Reference >::type;
return fusion::convert< tag >(seq);
}
};
// Metafunction to obtain the minimal traversal tag in a tuple
// of iterators.
//
template<typename IteratorTuple>
struct minimum_traversal_category_in_iterator_tuple
template< typename Reference1, typename Reference2 >
struct converter< std::pair< Reference1, Reference2 > >
{
using reference = std::pair< Reference1, Reference2 >;
template< typename Seq >
static reference call(Seq seq)
{
typedef typename mpl::transform<
IteratorTuple
, pure_traversal_tag<iterator_traversal<> >
>::type tuple_of_traversal_tags;
return reference(fusion::at_c< 0 >(seq), fusion::at_c< 1 >(seq));
}
};
typedef typename mpl::fold<
tuple_of_traversal_tags
, random_access_traversal_tag
, minimum_category<>
>::type type;
};
} // namespace detail
template<typename Iterator1, typename Iterator2>
struct minimum_traversal_category_in_iterator_tuple<std::pair<Iterator1, Iterator2> >
{
typedef typename pure_traversal_tag<
typename iterator_traversal<Iterator1>::type
>::type iterator1_traversal;
typedef typename pure_traversal_tag<
typename iterator_traversal<Iterator2>::type
>::type iterator2_traversal;
/////////////////////////////////////////////////////////////////////
//
// zip_iterator class definition
//
template< typename IteratorTuple >
class zip_iterator :
public detail::zip_iterator_base< IteratorTuple >::type
{
// Typedef super_t as our base class.
using super_t = typename detail::zip_iterator_base< IteratorTuple >::type;
typedef typename minimum_category<
iterator1_traversal
, typename minimum_category<
iterator2_traversal
, random_access_traversal_tag
>::type
>::type type;
};
///////////////////////////////////////////////////////////////////
//
// Class zip_iterator_base
//
// Builds and exposes the iterator facade type from which the zip
// iterator will be derived.
//
template<typename IteratorTuple>
struct zip_iterator_base
{
private:
// Reference type is the type of the tuple obtained from the
// iterators' reference types.
typedef typename
detail::tuple_of_references<IteratorTuple>::type reference;
// Value type is the same as reference type.
typedef reference value_type;
// Difference type is the first iterator's difference type
typedef typename iterator_difference<
typename mpl::at_c<IteratorTuple, 0>::type
>::type difference_type;
// Traversal catetgory is the minimum traversal category in the
// iterator tuple.
typedef typename
detail::minimum_traversal_category_in_iterator_tuple<
IteratorTuple
>::type traversal_category;
public:
// The iterator facade type from which the zip iterator will
// be derived.
typedef iterator_facade<
zip_iterator<IteratorTuple>,
value_type,
traversal_category,
reference,
difference_type
> type;
};
template <>
struct zip_iterator_base<int>
{
typedef int type;
};
template <typename reference>
struct converter
{
template <typename Seq>
static reference call(Seq seq)
{
typedef typename fusion::traits::tag_of<reference>::type tag;
return fusion::convert<tag>(seq);
}
};
template <typename Reference1, typename Reference2>
struct converter<std::pair<Reference1, Reference2> >
{
typedef std::pair<Reference1, Reference2> reference;
template <typename Seq>
static reference call(Seq seq)
{
return reference(
fusion::at_c<0>(seq)
, fusion::at_c<1>(seq));
}
};
}
/////////////////////////////////////////////////////////////////////
//
// zip_iterator class definition
//
template<typename IteratorTuple>
class zip_iterator :
public detail::zip_iterator_base<IteratorTuple>::type
{
// Typedef super_t as our base class.
typedef typename
detail::zip_iterator_base<IteratorTuple>::type super_t;
// iterator_core_access is the iterator's best friend.
friend class iterator_core_access;
public:
// iterator_core_access is the iterator's best friend.
friend class iterator_core_access;
public:
// Construction
// ============
// Default constructor
zip_iterator() { }
zip_iterator() = default;
// Constructor from iterator tuple
zip_iterator(IteratorTuple iterator_tuple)
: m_iterator_tuple(iterator_tuple)
{ }
zip_iterator(IteratorTuple iterator_tuple) :
m_iterator_tuple(iterator_tuple)
{}
// Copy constructor
template<typename OtherIteratorTuple>
zip_iterator(
const zip_iterator<OtherIteratorTuple>& other,
typename enable_if_convertible<
OtherIteratorTuple,
IteratorTuple
>::type* = 0
) : m_iterator_tuple(other.get_iterator_tuple())
template< typename OtherIteratorTuple, typename = enable_if_convertible_t< OtherIteratorTuple, IteratorTuple > >
zip_iterator(zip_iterator< OtherIteratorTuple > const& other) :
m_iterator_tuple(other.get_iterator_tuple())
{}
// Get method for the iterator tuple.
const IteratorTuple& get_iterator_tuple() const
{ return m_iterator_tuple; }
private:
IteratorTuple const& get_iterator_tuple() const { return m_iterator_tuple; }
private:
// Implementation of Iterator Operations
// =====================================
@ -281,11 +293,9 @@ namespace iterators {
// iterators in the iterator tuple.
typename super_t::reference dereference() const
{
typedef typename super_t::reference reference;
typedef detail::converter<reference> gen;
return gen::call(fusion::transform(
get_iterator_tuple(),
detail::dereference_iterator()));
using reference = typename super_t::reference;
using gen = detail::converter< reference >;
return gen::call(fusion::transform(get_iterator_tuple(), detail::dereference_iterator()));
}
// Two zip iterators are equal if all iterators in the iterator
@ -298,64 +308,55 @@ namespace iterators {
// under several compilers. No point in bringing in a bunch
// of #ifdefs here.
//
template<typename OtherIteratorTuple>
bool equal(const zip_iterator<OtherIteratorTuple>& other) const
template< typename OtherIteratorTuple >
bool equal(zip_iterator< OtherIteratorTuple > const& other) const
{
return fusion::equal_to(
get_iterator_tuple(),
other.get_iterator_tuple());
return fusion::equal_to(get_iterator_tuple(), other.get_iterator_tuple());
}
// Advancing a zip iterator means to advance all iterators in the
// iterator tuple.
void advance(typename super_t::difference_type n)
{
fusion::for_each(
m_iterator_tuple,
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n));
fusion::for_each(m_iterator_tuple, detail::advance_iterator< typename super_t::difference_type >(n));
}
// Incrementing a zip iterator means to increment all iterators in
// the iterator tuple.
void increment()
{
fusion::for_each(
m_iterator_tuple,
detail::increment_iterator());
fusion::for_each(m_iterator_tuple, detail::increment_iterator());
}
// Decrementing a zip iterator means to decrement all iterators in
// the iterator tuple.
void decrement()
{
fusion::for_each(
m_iterator_tuple,
detail::decrement_iterator());
fusion::for_each(m_iterator_tuple, detail::decrement_iterator());
}
// Distance is calculated using the first iterator in the tuple.
template<typename OtherIteratorTuple>
typename super_t::difference_type distance_to(
const zip_iterator<OtherIteratorTuple>& other
) const
template< typename OtherIteratorTuple >
typename super_t::difference_type distance_to(zip_iterator< OtherIteratorTuple > const& other) const
{
return fusion::at_c<0>(other.get_iterator_tuple()) -
fusion::at_c<0>(this->get_iterator_tuple());
return fusion::at_c< 0 >(other.get_iterator_tuple()) - fusion::at_c< 0 >(this->get_iterator_tuple());
}
private:
// Data Members
// ============
// The iterator tuple.
IteratorTuple m_iterator_tuple;
};
};
// Make function for zip iterator
//
template<typename IteratorTuple>
inline zip_iterator<IteratorTuple>
make_zip_iterator(IteratorTuple t)
{ return zip_iterator<IteratorTuple>(t); }
// Make function for zip iterator
//
template< typename IteratorTuple >
inline zip_iterator< IteratorTuple > make_zip_iterator(IteratorTuple t)
{
return zip_iterator< IteratorTuple >(t);
}
} // namespace iterators

View File

@ -15,13 +15,12 @@
#ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED
#define BOOST_NEXT_PRIOR_HPP_INCLUDED
#include <iterator>
#include <boost/config.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/has_plus.hpp>
#include <boost/type_traits/has_plus_assign.hpp>
#include <boost/type_traits/has_minus.hpp>
#include <boost/type_traits/has_minus_assign.hpp>
#include <boost/iterator/is_iterator.hpp>
#include <boost/iterator/advance.hpp>
#include <boost/iterator/reverse_iterator.hpp>
@ -39,46 +38,6 @@ namespace boost {
namespace next_prior_detail {
// The trait attempts to detect if the T type is an iterator. Class-type iterators are assumed
// to have the nested type iterator_category. Strictly speaking, this is not required to be the
// case (e.g. a user can specialize iterator_traits for T without defining T::iterator_category).
// Still, this is a good heuristic in practice, and we can't do anything better anyway.
// Since C++17 we can test for iterator_traits<T>::iterator_category presence instead as it is
// required to be only present for iterators.
template< typename T, typename Void = void >
struct is_iterator_class
{
static BOOST_CONSTEXPR_OR_CONST bool value = false;
};
template< typename T >
struct is_iterator_class<
T,
typename enable_if_has_type<
#if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS)
typename std::iterator_traits< T >::iterator_category
#else
typename T::iterator_category
#endif
>::type
>
{
static BOOST_CONSTEXPR_OR_CONST bool value = true;
};
template< typename T >
struct is_iterator :
public is_iterator_class< T >
{
};
template< typename T >
struct is_iterator< T* >
{
static BOOST_CONSTEXPR_OR_CONST bool value = true;
};
template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value >
struct next_plus_impl;
@ -107,7 +66,7 @@ struct next_plus_assign_impl< T, Distance, true >
}
};
template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value >
template< typename T, typename Distance, bool IsIterator = boost::iterators::is_iterator< T >::value >
struct next_advance_impl :
public next_plus_assign_impl< T, Distance >
{
@ -152,7 +111,7 @@ struct prior_minus_assign_impl< T, Distance, true >
}
};
template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value >
template< typename T, typename Distance, bool IsIterator = boost::iterators::is_iterator< T >::value >
struct prior_advance_impl :
public prior_minus_assign_impl< T, Distance >
{

View File

@ -20,14 +20,10 @@
// (David Abrahams)
# include <iterator>
# include <boost/static_assert.hpp>
# include <type_traits>
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
# include <boost/implicit_cast.hpp>
# include <boost/core/ignore_unused.hpp>
# include <boost/core/lightweight_test.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/type_traits/is_pointer.hpp>
# include <boost/type_traits/is_reference.hpp>
namespace boost {
@ -144,10 +140,11 @@ template <bool is_pointer> struct lvalue_test
typedef typename Iterator::reference reference;
typedef typename Iterator::value_type value_type;
# endif
BOOST_STATIC_ASSERT(boost::is_reference<reference>::value);
BOOST_STATIC_ASSERT((boost::is_same<reference,value_type&>::value
|| boost::is_same<reference,const value_type&>::value
));
static_assert(std::is_reference<reference>::value, "reference must be a reference type.");
static_assert(
std::is_same<reference, value_type&>::value || std::is_same<reference, const value_type&>::value,
"reference must either be a reference to value_type or constant reference to value_type."
);
}
};
@ -181,7 +178,7 @@ void forward_iterator_test(Iterator i, T v1, T v2)
// borland doesn't allow non-type template parameters
# if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
lvalue_test<std::is_pointer<Iterator>::value>::check(i);
#endif
}
@ -223,12 +220,15 @@ void random_access_iterator_test(Iterator i, int N, TrueVals vals)
int c;
typedef typename std::iterator_traits<Iterator>::value_type value_type;
boost::ignore_unused<value_type>();
struct local
{
static value_type to_value_type(value_type v) { return v; }
};
for (c = 0; c < N-1; ++c) {
BOOST_TEST(i == j + c);
BOOST_TEST(*i == vals[c]);
BOOST_TEST(*i == boost::implicit_cast<value_type>(j[c]));
BOOST_TEST(*i == local::to_value_type(j[c]));
BOOST_TEST(*i == *(j + c));
BOOST_TEST(*i == *(c + j));
++i;
@ -242,7 +242,7 @@ void random_access_iterator_test(Iterator i, int N, TrueVals vals)
for (c = 0; c < N-1; ++c) {
BOOST_TEST(i == k - c);
BOOST_TEST(*i == vals[N - 1 - c]);
BOOST_TEST(*i == boost::implicit_cast<value_type>(j[N - 1 - c]));
BOOST_TEST(*i == local::to_value_type(j[N - 1 - c]));
Iterator q = k - c;
boost::ignore_unused(q);
BOOST_TEST(*i == *q);

View File

@ -1,5 +1,5 @@
#ifndef POINTEE_DWA200415_HPP
# define POINTEE_DWA200415_HPP
#ifndef BOOST_POINTEE_DWA200415_HPP
#define BOOST_POINTEE_DWA200415_HPP
//
// Copyright David Abrahams 2004. Use, modification and distribution is
@ -13,64 +13,50 @@
// http://www.boost.org/libs/iterator/doc/pointee.html
//
# include <boost/detail/is_incrementable.hpp>
# include <boost/iterator/iterator_traits.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/eval_if.hpp>
#include <iterator>
#include <type_traits>
#include <boost/detail/is_incrementable.hpp>
namespace boost {
namespace detail {
namespace detail
template< typename P >
struct smart_ptr_pointee
{
template <class P>
struct smart_ptr_pointee
{
typedef typename P::element_type type;
};
using type = typename P::element_type;
};
template <class Iterator>
struct iterator_pointee
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
template<
typename Iterator,
typename = typename std::remove_reference< decltype(*std::declval< Iterator& >()) >::type
>
struct iterator_pointee
{
using type = typename std::iterator_traits< Iterator >::value_type;
};
struct impl
{
template <class T>
static char test(T const&);
template< typename Iterator, typename Reference >
struct iterator_pointee< Iterator, const Reference >
{
using type = typename std::add_const< typename std::iterator_traits< Iterator >::value_type >::type;
};
static char (& test(value_type&) )[2];
} // namespace detail
static Iterator& x;
};
BOOST_STATIC_CONSTANT(bool, is_constant = sizeof(impl::test(*impl::x)) == 1);
typedef typename mpl::if_c<
# if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
::boost::detail::iterator_pointee<Iterator>::is_constant
# else
is_constant
# endif
, typename add_const<value_type>::type
, value_type
>::type type;
};
}
template <class P>
struct pointee
: mpl::eval_if<
detail::is_incrementable<P>
, detail::iterator_pointee<P>
, detail::smart_ptr_pointee<P>
>
template< typename P >
struct pointee :
public std::conditional<
detail::is_incrementable< P >::value,
detail::iterator_pointee< P >,
detail::smart_ptr_pointee< P >
>::type
{
};
template< typename P >
using pointee_t = typename pointee< P >::type;
} // namespace boost
#endif // POINTEE_DWA200415_HPP
#endif // BOOST_POINTEE_DWA200415_HPP

View File

@ -1,69 +1,14 @@
// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org/libs/utility/shared_container_iterator.html for documentation.
// (C) Copyright Andrey Semashev 2025.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_SHARED_CONTAINER_ITERATOR_HPP
#define BOOST_SHARED_CONTAINER_ITERATOR_HPP
#include "boost/iterator_adaptors.hpp"
#include "boost/shared_ptr.hpp"
#include <utility>
// This is a deprecated header left for backward compatibility.
// Please use <boost/iterator/shared_container_iterator.hpp> instead.
namespace boost {
namespace iterators {
#include <boost/iterator/shared_container_iterator.hpp>
template <typename Container>
class shared_container_iterator : public iterator_adaptor<
shared_container_iterator<Container>,
typename Container::iterator> {
typedef iterator_adaptor<
shared_container_iterator<Container>,
typename Container::iterator> super_t;
typedef typename Container::iterator iterator_t;
typedef boost::shared_ptr<Container> container_ref_t;
container_ref_t container_ref;
public:
shared_container_iterator() { }
shared_container_iterator(iterator_t const& x,container_ref_t const& c) :
super_t(x), container_ref(c) { }
};
template <typename Container>
inline shared_container_iterator<Container>
make_shared_container_iterator(typename Container::iterator iter,
boost::shared_ptr<Container> const& container) {
typedef shared_container_iterator<Container> iterator;
return iterator(iter,container);
}
template <typename Container>
inline std::pair<
shared_container_iterator<Container>,
shared_container_iterator<Container> >
make_shared_container_range(boost::shared_ptr<Container> const& container) {
return
std::make_pair(
make_shared_container_iterator(container->begin(),container),
make_shared_container_iterator(container->end(),container));
}
} // namespace iterators
using iterators::shared_container_iterator;
using iterators::make_shared_container_iterator;
using iterators::make_shared_container_range;
} // namespace boost
#endif
#endif // BOOST_SHARED_CONTAINER_ITERATOR_HPP

View File

@ -2,6 +2,10 @@
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import testing ;
project : requirements <library>/boost/iterator//boost_iterator ;
test-suite iterator
:
# These first two tests will run last, and are expected to fail
@ -22,9 +26,11 @@ test-suite iterator
[ run zip_iterator_test2_fusion_vector.cpp ]
[ run zip_iterator_test2_fusion_list.cpp ]
# [ run zip_iterator_test2_fusion_deque.cpp ] // See bug report for fusion https://svn.boost.org/trac/boost/ticket/11572
[ run zip_iterator_test_fusion.cpp ]
[ run zip_iterator_test_std_tuple.cpp ]
[ run zip_iterator_test_std_pair.cpp ]
[ run zip_iterator_test_fusion.cpp : : : <library>/boost/assign//boost_assign ]
[ run zip_iterator_test_std_tuple.cpp : : : <library>/boost/assign//boost_assign ]
[ run zip_iterator_test_std_pair.cpp : : : <library>/boost/assign//boost_assign ]
[ run is_iterator.cpp ]
# These tests should work for just about everything.
[ compile is_lvalue_iterator.cpp ]
@ -52,17 +58,21 @@ test-suite iterator
[ run function_input_iterator_test.cpp ]
[ run function_output_iterator_test.cpp ]
[ compile-fail function_output_iterator_cf.cpp ]
[ compile-fail function_output_iterator_def_ctor_cf.cpp ]
[ run generator_iterator_test.cpp ]
[ run min_category.cpp ]
[ compile-fail min_category_compile_fail1.cpp ]
[ compile-fail min_category_compile_fail2.cpp ]
[ run minimum_category.cpp ]
[ compile-fail minimum_category_compile_fail.cpp ]
[ run next_prior_test.cpp ]
[ run advance_test.cpp ]
[ run distance_test.cpp ]
[ compile adl_test.cpp ]
[ compile range_distance_compat_test.cpp ]
[ run advance_test.cpp : : : <library>/boost/container//boost_container ]
[ run distance_test.cpp : : : <library>/boost/container//boost_container ]
[ compile adl_test.cpp : <library>/boost/array//boost_array ]
[ compile range_distance_compat_test.cpp : <library>/boost/range//boost_range ]
[ run shared_iterator_test.cpp ]
[ run shared_iterator_test.cpp : : : <library>/boost/smart_ptr//boost_smart_ptr ]
;

View File

@ -30,13 +30,12 @@
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/next_prior.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/limits.hpp>
#include <algorithm>
#include <climits>
#include <iterator>
#include <type_traits>
#include <stdlib.h>
#ifndef BOOST_BORLANDC
# include <boost/tuple/tuple.hpp>
@ -68,7 +67,7 @@ struct unsigned_assert_nonnegative
template <class T>
struct assert_nonnegative
: boost::conditional<
: std::conditional<
std::numeric_limits<T>::is_signed
, signed_assert_nonnegative<T>
, unsigned_assert_nonnegative<T>

View File

@ -160,7 +160,7 @@ int main( void )
// Undo change to vect1
ZI_TUPLE_GET(1)(ref_tuple) = dblOldVal;
#if defined(ZI_USE_BOOST_TUPLE)
/////////////////////////////////////////////////////////////////////////////
@ -295,7 +295,7 @@ int main( void )
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
#endif
/////////////////////////////////////////////////////////////////////////////
@ -841,7 +841,7 @@ int main( void )
++num_failed_tests;
std::cout << "not OK" << std::endl;
}
#endif
// Done

View File

@ -7,15 +7,14 @@
#include <boost/iterator/filter_iterator.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/concept_check.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/iterator_archetypes.hpp>
#include <boost/cstdlib.hpp>
#include <type_traits>
#include <deque>
#include <iostream>
using boost::dummyT;
@ -37,13 +36,13 @@ int main()
// Concept checks
// Adapting old-style iterators
{
typedef boost::filter_iterator<one_or_four, boost::input_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::input_iterator_archetype<dummyT> >;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::input_output_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::input_output_iterator_archetype<dummyT> >;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
@ -51,39 +50,39 @@ int main()
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::forward_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::forward_iterator_archetype<dummyT> >;
boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::mutable_forward_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::mutable_forward_iterator_archetype<dummyT> >;
boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::bidirectional_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::bidirectional_iterator_archetype<dummyT> >;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::mutable_bidirectional_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::mutable_bidirectional_iterator_archetype<dummyT> >;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::random_access_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::random_access_iterator_archetype<dummyT> >;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::filter_iterator<one_or_four, boost::mutable_random_access_iterator_archetype<dummyT> > Iter;
using Iter = boost::filter_iterator<one_or_four, boost::mutable_random_access_iterator_archetype<dummyT> >;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
@ -91,24 +90,24 @@ int main()
}
// Adapting new-style iterators
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::single_pass_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::SinglePassIteratorConcept<Iter> >();
}
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::single_pass_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost::OutputIteratorConcept<Iter, dummyT> >();
@ -118,12 +117,12 @@ int main()
}
#endif
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
@ -131,35 +130,35 @@ int main()
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_lvalue_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ForwardTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::forward_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::Mutable_ForwardIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
@ -168,12 +167,12 @@ int main()
#endif
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::InputIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
@ -181,35 +180,35 @@ int main()
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // Causes Internal Error in linker.
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::readable_writable_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
const dummyT
, boost::iterator_archetypes::readable_lvalue_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::ReadableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::BidirectionalTraversalConcept<Iter> >();
}
{
typedef boost::iterator_archetype<
using BaseIter = boost::iterator_archetype<
dummyT
, boost::iterator_archetypes::writable_lvalue_iterator_t
, boost::random_access_traversal_tag
> BaseIter;
typedef boost::filter_iterator<one_or_four, BaseIter> Iter;
>;
using Iter = boost::filter_iterator<one_or_four, BaseIter>;
boost::function_requires< boost::Mutable_BidirectionalIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::WritableIteratorConcept<Iter> >();
boost::function_requires< boost_concepts::LvalueIteratorConcept<Iter> >();
@ -223,20 +222,26 @@ int main()
dummyT(3), dummyT(4), dummyT(5) };
const int N = sizeof(array)/sizeof(dummyT);
typedef boost::filter_iterator<one_or_four, dummyT*> filter_iter;
using filter_iter = boost::filter_iterator<one_or_four, dummyT*>;
boost::bidirectional_readable_iterator_test(
filter_iter(one_or_four(), array, array+N)
, dummyT(1), dummyT(4));
BOOST_STATIC_ASSERT(
(!boost::is_convertible<
static_assert(
!std::is_convertible<
boost::iterator_traversal<filter_iter>::type
, boost::random_access_traversal_tag
>::value
));
>::value,
"Filter interator must have a random_access_traversal_tag.");
//# endif
// Check that the iterator can be constructed from a different but compatible iterator
{
using const_filter_iter = boost::filter_iterator<one_or_four, const dummyT*>;
filter_iter mutable_it(one_or_four(), array+0, array+N);
const_filter_iter const_it(mutable_it);
(void)const_it;
}
// On compilers not supporting partial specialization, we can do more type
// deduction with deque iterators than with pointers... unless the library

View File

@ -11,14 +11,12 @@
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_DECLTYPE)
// Force boost::result_of use decltype, even on compilers that don't support N3276.
// This enables this test to also verify if the iterator works with lambdas
// on such compilers with this config macro. Note that without the macro result_of
// (and consequently the iterator) is guaranteed to _not_ work, so this case is not
// worth testing anyway.
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/iterator/function_input_iterator.hpp>
@ -99,8 +97,15 @@ int main()
for(std::size_t i = 0; i != 10; ++i)
BOOST_TEST_EQ(generated[i], static_cast<int>(42 + i));
#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) \
&& defined(BOOST_RESULT_OF_USE_DECLTYPE)
// Test that incrementing the iterator returns a reference to the iterator type
{
typedef boost::iterators::function_input_iterator<counter, int> function_counter_iterator_t;
function_counter_iterator_t it1(counter_generator, 0);
function_counter_iterator_t it2(++it1);
function_counter_iterator_t it3(it2++);
BOOST_TEST_EQ(*it3, 54);
}
// test the iterator with lambda expressions
int num = 42;
auto lambda_generator = [&num] { return num++; };
@ -114,7 +119,6 @@ int main()
BOOST_TEST_EQ(generated.size(), 10u);
for(std::size_t i = 0; i != 10; ++i)
BOOST_TEST_EQ(generated[i], static_cast<int>(42 + i));
#endif // BOOST_NO_CXX11_LAMBDAS
return boost::report_errors();
}

View File

@ -0,0 +1,14 @@
// Copyright 2025 (c) Andrey Semashev
// Distributed under the Boost Software License Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/function_output_iterator.hpp>
int main()
{
boost::iterators::function_output_iterator< void (*)(int) > it;
(void)it;
return 0;
}

View File

@ -8,6 +8,8 @@
#include <boost/core/lightweight_test.hpp>
#include <boost/iterator/function_output_iterator.hpp>
#include <iterator>
namespace {
struct sum_func
@ -42,7 +44,6 @@ int main()
BOOST_TEST_EQ(n, 6);
}
#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
{
int n = 0;
auto it = boost::iterators::make_function_output_iterator([&n](int x) { n -= x; });
@ -55,6 +56,12 @@ int main()
BOOST_TEST_EQ(n, -6);
}
#if defined(__cpp_lib_concepts) && ( __cpp_lib_concepts >= 202002L )
{
auto func = [](int) {};
static_assert(std::output_iterator< boost::iterators::function_output_iterator< decltype(func) >, int >);
}
#endif
return boost::report_errors();

View File

@ -6,7 +6,7 @@
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/generator_iterator.hpp>
#include <boost/iterator/generator_iterator.hpp>
#include <boost/core/lightweight_test.hpp>
#include <algorithm>

View File

@ -9,12 +9,10 @@
#include <boost/config.hpp>
#include <iostream>
#include <boost/iterator/indirect_iterator.hpp>
#include <boost/static_assert.hpp>
#include "static_assert_same.hpp"
#include <boost/type_traits/same_traits.hpp>
#include <type_traits>
struct zow { };
@ -40,10 +38,12 @@ int main()
STATIC_ASSERT_SAME(Iter::pointer, int*);
STATIC_ASSERT_SAME(Iter::difference_type, std::ptrdiff_t);
BOOST_STATIC_ASSERT((boost::is_convertible<Iter::iterator_category,
std::random_access_iterator_tag>::value));
BOOST_STATIC_ASSERT((boost::is_convertible<boost::iterator_traversal<Iter>::type,
boost::random_access_traversal_tag>::value));
static_assert(std::is_convertible<Iter::iterator_category,
std::random_access_iterator_tag>::value,
"Iter must have a random access category.");
static_assert(std::is_convertible<boost::iterator_traversal<Iter>::type,
boost::random_access_traversal_tag>::value,
"Iter must have a random_access_traversal_tag.");
}
{
typedef boost::indirect_iterator<int const**> Iter;
@ -71,10 +71,12 @@ int main()
STATIC_ASSERT_SAME(Iter::difference_type, std::ptrdiff_t);
BOOST_STATIC_ASSERT((boost::is_convertible<Iter::iterator_category,
std::random_access_iterator_tag>::value));
BOOST_STATIC_ASSERT((boost::is_convertible<boost::iterator_traversal<Iter>::type,
boost::random_access_traversal_tag>::value));
static_assert(std::is_convertible<Iter::iterator_category,
std::random_access_iterator_tag>::value,
"Iter must have a random access category.");
static_assert(std::is_convertible<boost::iterator_traversal<Iter>::type,
boost::random_access_traversal_tag>::value,
"Iter must have a random_access_traversal_tag.");
}
{
typedef boost::indirect_iterator<char**, int, std::random_access_iterator_tag, long&, short> Iter;

View File

@ -37,8 +37,7 @@
#if !defined(__SGI_STL_PORT) \
&& (defined(BOOST_MSVC_STD_ITERATOR) \
|| BOOST_WORKAROUND(_CPPLIB_VER, <= 310) \
|| BOOST_WORKAROUND(__GNUC__, <= 2))
|| BOOST_WORKAROUND(_CPPLIB_VER, <= 310))
// std container random-access iterators don't support mutable/const
// interoperability (but may support const/mutable interop).

View File

@ -8,12 +8,13 @@
//
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/cstdlib.hpp>
#include <type_traits>
int main()
{
typedef boost::reverse_iterator<int*> rev_iter1;
typedef boost::reverse_iterator<char*> rev_iter2;
return boost::is_convertible<rev_iter1, rev_iter2>::value
return std::is_convertible<rev_iter1, rev_iter2>::value
? boost::exit_failure : boost::exit_success;
}

164
test/is_iterator.cpp Normal file
View File

@ -0,0 +1,164 @@
/*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*
* Copyright (c) 2023 Andrey Semashev
*/
/*!
* \file is_iterator.cpp
*
* This header contains tests for the \c is_iterator type trait.
*/
#include <boost/iterator/is_iterator.hpp>
#include <cstddef>
#include <list>
#include <vector>
#include <string>
#include <iterator>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/core/lightweight_test.hpp>
template< typename T >
struct value_iterator
{
typedef std::input_iterator_tag iterator_category;
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
value_type operator*() const;
};
template< typename T >
struct proxy_iterator
{
typedef T value_type;
typedef std::output_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
struct proxy
{
operator value_type&() const;
proxy& operator=(value_type) const;
};
proxy operator*() const;
};
template< typename T >
struct lvalue_iterator
{
typedef T value_type;
typedef T& reference;
typedef T difference_type;
typedef std::input_iterator_tag iterator_category;
typedef T* pointer;
T& operator*() const;
lvalue_iterator& operator++();
lvalue_iterator operator++(int);
};
template< typename T >
struct constant_lvalue_iterator
{
typedef T value_type;
typedef T const& reference;
typedef T difference_type;
typedef std::input_iterator_tag iterator_category;
typedef T const* pointer;
T const& operator*() const;
constant_lvalue_iterator& operator++();
constant_lvalue_iterator operator++(int);
};
template< typename Iterator >
class adapted_iterator :
public boost::iterators::iterator_adaptor< adapted_iterator< Iterator >, Iterator >
{
friend class iterator_core_access;
private:
typedef boost::iterators::iterator_adaptor< adapted_iterator< Iterator >, Iterator > base_type;
private:
typename base_type::reference dereference() const;
void increment();
void decrement();
void advance(typename base_type::difference_type n);
template< typename OtherIterator >
typename base_type::difference_type distance_to(adapted_iterator< OtherIterator > const& y) const;
};
struct complete {};
struct incomplete;
int main()
{
BOOST_TEST(boost::iterators::is_iterator< int* >::value);
BOOST_TEST(boost::iterators::is_iterator< const int* >::value);
BOOST_TEST(boost::iterators::is_iterator< complete* >::value);
BOOST_TEST(boost::iterators::is_iterator< std::reverse_iterator< int* > >::value);
BOOST_TEST(boost::iterators::is_iterator< std::reverse_iterator< complete* > >::value);
BOOST_TEST(boost::iterators::is_iterator< adapted_iterator< int* > >::value);
BOOST_TEST(boost::iterators::is_iterator< std::string::iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::string::const_iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::string::reverse_iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::string::const_reverse_iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::list< int >::iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::list< int >::const_iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::list< int >::reverse_iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::list< int >::const_reverse_iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::vector< int >::iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::vector< int >::const_iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::vector< int >::reverse_iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::vector< int >::const_reverse_iterator >::value);
BOOST_TEST(boost::iterators::is_iterator< std::insert_iterator< std::vector< int > > >::value);
BOOST_TEST(boost::iterators::is_iterator< std::back_insert_iterator< std::vector< int > > >::value);
BOOST_TEST(boost::iterators::is_iterator< std::front_insert_iterator< std::vector< int > > >::value);
BOOST_TEST(boost::iterators::is_iterator< std::istream_iterator< int > >::value);
BOOST_TEST(boost::iterators::is_iterator< std::ostream_iterator< int > >::value);
BOOST_TEST(boost::iterators::is_iterator< std::istreambuf_iterator< char > >::value);
BOOST_TEST(boost::iterators::is_iterator< std::ostreambuf_iterator< char > >::value);
BOOST_TEST(!boost::iterators::is_iterator< int >::value);
BOOST_TEST(!boost::iterators::is_iterator< complete >::value);
BOOST_TEST(!boost::iterators::is_iterator< void >::value);
BOOST_TEST(!boost::iterators::is_iterator< const void >::value);
BOOST_TEST(!boost::iterators::is_iterator< void* >::value);
#if defined(BOOST_TT_HAS_WORKING_IS_COMPLETE)
BOOST_TEST(!boost::iterators::is_iterator< incomplete >::value);
BOOST_TEST(!boost::iterators::is_iterator< incomplete* >::value);
#endif
BOOST_TEST(!boost::iterators::is_iterator< int (int) >::value);
BOOST_TEST(!boost::iterators::is_iterator< int (*)(int) >::value);
BOOST_TEST(!boost::iterators::is_iterator< int complete::* >::value);
BOOST_TEST(!boost::iterators::is_iterator< int (complete::*)(int) >::value);
BOOST_TEST(!boost::iterators::is_iterator< int (complete::*)(int) const >::value);
#if defined(__cpp_noexcept_function_type) && (__cpp_noexcept_function_type >= 201510L)
BOOST_TEST(!boost::iterators::is_iterator< int (*)(int) noexcept >::value);
BOOST_TEST(!boost::iterators::is_iterator< int (complete::*)(int) noexcept >::value);
BOOST_TEST(!boost::iterators::is_iterator< int (complete::*)(int) const noexcept >::value);
#endif
BOOST_TEST(!boost::iterators::is_iterator< int[] >::value);
BOOST_TEST(!boost::iterators::is_iterator< int[10] >::value);
BOOST_TEST(!boost::iterators::is_iterator< int*[] >::value);
BOOST_TEST(!boost::iterators::is_iterator< int*[10] >::value);
BOOST_TEST(!boost::iterators::is_iterator< int& >::value);
BOOST_TEST(!boost::iterators::is_iterator< int*& >::value);
BOOST_TEST(!boost::iterators::is_iterator< int (&)(int) >::value);
BOOST_TEST(!boost::iterators::is_iterator< int (&)[10] >::value);
return boost::report_errors();
}

View File

@ -4,15 +4,10 @@
#include <deque>
#include <iterator>
#include <iostream>
#include <cstddef> // std::ptrdiff_t
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/iterator/is_lvalue_iterator.hpp>
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
#include <boost/iterator/detail/config_def.hpp>
struct v
{
v();
@ -88,61 +83,90 @@ struct constant_lvalue_iterator
constant_lvalue_iterator operator++(int);
};
int main()
{
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v*>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<proxy_iterator<int> >::value);
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(!boost::is_lvalue_iterator<value_iterator>::value);
#endif
static_assert(boost::is_lvalue_iterator<v*>::value,
"boost::is_lvalue_iterator<v*>::value is expected to be true.");
static_assert(boost::is_lvalue_iterator<v const*>::value,
"boost::is_lvalue_iterator<v const*>::value is expected to be true.");
static_assert(boost::is_lvalue_iterator<std::deque<v>::iterator>::value,
"boost::is_lvalue_iterator<std::deque<v>::iterator>::value.");
static_assert(boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value,
"boost::is_lvalue_iterator<std::deque<v>::const_iterator>::value is expected to be true.");
static_assert(!boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v>>>::value,
"boost::is_lvalue_iterator<std::back_insert_iterator<std::deque<v>>>::value is expected to be false.");
static_assert(!boost::is_lvalue_iterator<std::ostream_iterator<v>>::value,
"boost::is_lvalue_iterator<std::ostream_iterator<v>>::value is expected to be false.");
static_assert(!boost::is_lvalue_iterator<proxy_iterator<v>>::value,
"boost::is_lvalue_iterator<proxy_iterator<v>>::value is expected to be false.");
static_assert(!boost::is_lvalue_iterator<proxy_iterator<int>>::value,
"boost::is_lvalue_iterator<proxy_iterator<int>>::value is expected to be false.");
static_assert(!boost::is_lvalue_iterator<value_iterator>::value,
"boost::is_lvalue_iterator<value_iterator>::value is expected to be false.");
// Make sure inaccessible copy constructor doesn't prevent
// reference binding
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<noncopyable_iterator>::value);
static_assert(boost::is_lvalue_iterator<noncopyable_iterator>::value,
"boost::is_lvalue_iterator<noncopyable_iterator>::value is expected to be true.");
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<lvalue_iterator<float> >::value);
static_assert(boost::is_lvalue_iterator<lvalue_iterator<v>>::value,
"boost::is_lvalue_iterator<lvalue_iterator<v>>::value is expected to be true.");
static_assert(boost::is_lvalue_iterator<lvalue_iterator<int>>::value,
"boost::is_lvalue_iterator<lvalue_iterator<int>>::value is expected to be true.");
static_assert(boost::is_lvalue_iterator<lvalue_iterator<char*>>::value,
"boost::is_lvalue_iterator<lvalue_iterator<char*>>::value is expected to be true.");
static_assert(boost::is_lvalue_iterator<lvalue_iterator<float>>::value,
"boost::is_lvalue_iterator<lvalue_iterator<float>>::value is expected to be true.");
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<constant_lvalue_iterator<float> >::value);
static_assert(boost::is_lvalue_iterator<constant_lvalue_iterator<v>>::value,
"boost::is_lvalue_iterator<constant_lvalue_iterator<v>>::value is expected to be true.");
static_assert(boost::is_lvalue_iterator<constant_lvalue_iterator<int>>::value,
"boost::is_lvalue_iterator<constant_lvalue_iterator<int>>::value is expected to be true.");
static_assert(boost::is_lvalue_iterator<constant_lvalue_iterator<char*>>::value,
"boost::is_lvalue_iterator<constant_lvalue_iterator<char*>>::value is expected to be true.");
static_assert(boost::is_lvalue_iterator<constant_lvalue_iterator<float>>::value,
"boost::is_lvalue_iterator<constant_lvalue_iterator<float>>::value is expected to be true.");
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<v*>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<proxy_iterator<int> >::value);
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<value_iterator>::value);
#endif
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value);
static_assert(boost::is_non_const_lvalue_iterator<v*>::value,
"boost::is_non_const_lvalue_iterator<v*>::value is expected to be true.");
static_assert(!boost::is_non_const_lvalue_iterator<v const*>::value,
"boost::is_non_const_lvalue_iterator<v const*>::value is expected to be false.");
static_assert(boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value,
"boost::is_non_const_lvalue_iterator<std::deque<v>::iterator>::value is expected to be true.");
static_assert(!boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value,
"boost::is_non_const_lvalue_iterator<std::deque<v>::const_iterator>::value is expected to be false.");
static_assert(!boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v>>>::value,
"boost::is_non_const_lvalue_iterator<std::back_insert_iterator<std::deque<v>>>::value is expected to be false.");
static_assert(!boost::is_non_const_lvalue_iterator<std::ostream_iterator<v>>::value,
"boost::is_non_const_lvalue_iterator<std::ostream_iterator<v>>::value is expected to be false.");
static_assert(!boost::is_non_const_lvalue_iterator<proxy_iterator<v>>::value,
"boost::is_non_const_lvalue_iterator<proxy_iterator<v>>::value is expected to be false.");
static_assert(!boost::is_non_const_lvalue_iterator<proxy_iterator<int>>::value,
"boost::is_non_const_lvalue_iterator<proxy_iterator<int>>::value is expected to be false.");
static_assert(!boost::is_non_const_lvalue_iterator<value_iterator>::value,
"boost::is_non_const_lvalue_iterator<value_iterator>::value is expected to be false.");
static_assert(!boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value,
"boost::is_non_const_lvalue_iterator<noncopyable_iterator>::value is expected to be false.");
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<v> >::value);
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<int> >::value);
#endif
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<lvalue_iterator<float> >::value);
static_assert(boost::is_non_const_lvalue_iterator<lvalue_iterator<v>>::value,
"boost::is_non_const_lvalue_iterator<lvalue_iterator<v>>::value is expected to be true.");
static_assert(boost::is_non_const_lvalue_iterator<lvalue_iterator<int>>::value,
"boost::is_non_const_lvalue_iterator<lvalue_iterator<int>>::value is expected to be true.");
static_assert(boost::is_non_const_lvalue_iterator<lvalue_iterator<char*>>::value,
"boost::is_non_const_lvalue_iterator<lvalue_iterator<char*>>::value is expected to be true.");
static_assert(boost::is_non_const_lvalue_iterator<lvalue_iterator<float>>::value,
"boost::is_non_const_lvalue_iterator<lvalue_iterator<float>>::value is expected to be true.");
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*> >::value);
BOOST_STATIC_ASSERT(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float> >::value);
static_assert(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v>>::value,
"boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<v>>::value is expected to be false.");
static_assert(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int>>::value,
"boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<int>>::value is expected to be false.");
static_assert(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*>>::value,
"boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<char*>>::value is expected to be false.");
static_assert(!boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float>>::value,
"boost::is_non_const_lvalue_iterator<constant_lvalue_iterator<float>>::value is expected to be false.");
return 0;
}

View File

@ -4,15 +4,10 @@
#include <deque>
#include <iterator>
#include <iostream>
#include <cstddef> // std::ptrdiff_t
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/iterator/is_readable_iterator.hpp>
// Last, for BOOST_NO_LVALUE_RETURN_DETECTION
#include <boost/iterator/detail/config_def.hpp>
struct v
{
v();
@ -78,19 +73,29 @@ struct proxy_iterator2
int main()
{
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v*>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<v const*>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::iterator>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<std::deque<v>::const_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::back_insert_iterator<std::deque<v> > >::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<std::ostream_iterator<v> >::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<proxy_iterator>::value);
BOOST_STATIC_ASSERT(!boost::is_readable_iterator<proxy_iterator2>::value);
BOOST_STATIC_ASSERT(boost::is_readable_iterator<value_iterator>::value);
static_assert(boost::is_readable_iterator<v*>::value,
"boost::is_readable_iterator<v*>::value is expected to be true.");
static_assert(boost::is_readable_iterator<v const*>::value,
"boost::is_readable_iterator<v const*>::value is expected to be true.");
static_assert(boost::is_readable_iterator<std::deque<v>::iterator>::value,
"boost::is_readable_iterator<std::deque<v>::iterator>::value is expected to be true.");
static_assert(boost::is_readable_iterator<std::deque<v>::const_iterator>::value,
"boost::is_readable_iterator<std::deque<v>::const_iterator>::value is expected to be true.");
static_assert(!boost::is_readable_iterator<std::back_insert_iterator<std::deque<v>>>::value,
"boost::is_readable_iterator<std::back_insert_iterator<std::deque<v>>>::value is expected to be false.");
static_assert(!boost::is_readable_iterator<std::ostream_iterator<v>>::value,
"boost::is_readable_iterator<std::ostream_iterator<v>>::value is expected to be false.");
static_assert(boost::is_readable_iterator<proxy_iterator>::value,
"boost::is_readable_iterator<proxy_iterator>::value is expected to be true.");
static_assert(!boost::is_readable_iterator<proxy_iterator2>::value,
"boost::is_readable_iterator<proxy_iterator2>::value is expected to be false.");
static_assert(boost::is_readable_iterator<value_iterator>::value,
"boost::is_readable_iterator<value_iterator>::value is expected to be true.");
// Make sure inaccessible copy constructor doesn't prevent
// readability
BOOST_STATIC_ASSERT(boost::is_readable_iterator<noncopyable_iterator>::value);
static_assert(boost::is_readable_iterator<noncopyable_iterator>::value,
"boost::is_readable_iterator<noncopyable_iterator>::value is expected to be true.");
return 0;
}

View File

@ -27,7 +27,7 @@ int main()
#if defined(__SGI_STL_PORT) \
|| !BOOST_WORKAROUND(__GNUC__, <= 2) \
&& !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, <= 1)) \
&& !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) \
&& !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) \
&& !BOOST_WORKAROUND(__LIBCOMO_VERSION__, BOOST_TESTED_AT(29)) \
&& !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 1)
{

View File

@ -13,10 +13,9 @@
#include <numeric>
#include <boost/iterator/iterator_adaptor.hpp>
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
# include <boost/iterator/is_readable_iterator.hpp>
# include <boost/iterator/is_lvalue_iterator.hpp>
#endif
#include <boost/iterator/is_readable_iterator.hpp>
#include <boost/iterator/is_lvalue_iterator.hpp>
#include <boost/iterator/enable_if_convertible.hpp>
#include <boost/pending/iterator_tests.hpp>
# include <boost/core/lightweight_test.hpp>
@ -29,8 +28,6 @@
#include "static_assert_same.hpp"
#include <boost/iterator/detail/config_def.hpp>
using boost::dummyT;
typedef std::deque<int> storage;
@ -56,9 +53,6 @@ struct ptr_iterator
, V*
, V
, boost::random_access_traversal_tag
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
, V&
#endif
>
{
private:
@ -67,9 +61,6 @@ private:
, V*
, V
, boost::random_access_traversal_tag
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
, V&
#endif
> super_t;
public:
@ -198,6 +189,16 @@ main()
boost::const_nonconst_iterator_test(i, ++j);
}
// Test that operator_brackets_proxy forwards operator-> and operator*
{
dummyT* ptr_array[] = { array + 0, array + 1, array + 2,
array + 3, array + 4, array + 5 };
ptr_iterator<dummyT*> i(ptr_array);
BOOST_TEST_EQ(i[2]->foo(), 2);
BOOST_TEST_EQ((*i[2]).foo(), 2);
}
int test;
// Test the iterator_traits
{
@ -208,9 +209,10 @@ main()
test = static_assert_same<Iter1::reference, int&>::value;
test = static_assert_same<Iter1::pointer, int*>::value;
test = static_assert_same<Iter1::difference_type, std::ptrdiff_t>::value;
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value));
#endif
static_assert(
std::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value,
"Iterator must have a random access category."
);
}
{
@ -219,16 +221,10 @@ main()
test = static_assert_same<Iter1::value_type, int>::value;
test = static_assert_same<Iter1::reference, const int&>::value;
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
# endif
#endif
static_assert(boost::is_readable_iterator<Iter1>::value, "Iter1 is expected to be readable.");
static_assert(boost::is_lvalue_iterator<Iter1>::value, "Iter1 is expected to be lvalue iterator.");
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) // borland drops constness
test = static_assert_same<Iter1::pointer, int const*>::value;
#endif
}
{
@ -238,14 +234,16 @@ main()
test = static_assert_same<Iter::value_type, int>::value;
test = static_assert_same<Iter::reference, int const&>::value;
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) // borland drops constness
test = static_assert_same<Iter::pointer, int const*>::value;
#endif
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
#endif
static_assert(
boost::is_non_const_lvalue_iterator<BaseIter>::value,
"boost::is_non_const_lvalue_iterator<BaseIter>::value is expected to be true."
);
static_assert(
boost::is_lvalue_iterator<Iter>::value,
"boost::is_lvalue_iterator<Iter>::value is expected to be true."
);
typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;

View File

@ -8,9 +8,9 @@
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/call_traits.hpp>
#include <boost/polymorphic_cast.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
#include <type_traits>
#include "static_assert_same.hpp"
// This is a really, really limited test so far. All we're doing
// right now is checking that the postfix++ proxy for single-pass
@ -63,7 +63,23 @@ struct proxy
struct value
{
void mutator() {} // non-const member function
int increment_count;
int private_mutator_count;
int& shared_mutator_count;
explicit value(int& shared_mutator_count) :
increment_count(0),
private_mutator_count(0),
shared_mutator_count(shared_mutator_count)
{
}
// non-const member function
void mutator()
{
++private_mutator_count;
++shared_mutator_count;
}
};
struct input_iter
@ -75,21 +91,25 @@ struct input_iter
>
{
public:
input_iter() {}
explicit input_iter(value& val) : state(&val) {}
void increment()
{
++(state->increment_count);
}
value
dereference() const
{
return value();
return *state;
}
bool equal(input_iter const&) const
{
return false;
}
private:
value* state;
};
template <class T>
@ -101,7 +121,7 @@ struct wrapper
{ }
template <class U>
wrapper(const wrapper<U>& other,
typename boost::enable_if< boost::is_convertible<U,T> >::type* = 0)
typename std::enable_if< std::is_convertible<U,T>::value >::type* = 0)
: m_x(other.m_x)
{ }
};
@ -125,19 +145,15 @@ struct iterator_with_proxy_reference
{ return wrapper<int&>(m_x); }
};
template <class T, class U>
void same_type(U const&)
{ BOOST_MPL_ASSERT((boost::is_same<T,U>)); }
template <class I, class A>
struct abstract_iterator
: boost::iterator_facade<
abstract_iterator<I, A>
, A &
, A&
// In order to be value type as a reference, traversal category has
// to satisfy least forward traversal.
, boost::forward_traversal_tag
, A &
, A&
>
{
abstract_iterator(I iter) : iter(iter) {}
@ -145,7 +161,7 @@ struct abstract_iterator
void increment()
{ ++iter; }
A & dereference() const
A& dereference() const
{ return *iter; }
bool equal(abstract_iterator const& y) const
@ -156,30 +172,30 @@ struct abstract_iterator
struct base
{
virtual void assign(const base &) = 0;
virtual bool equal(const base &) const = 0;
virtual void assign(const base&) = 0;
virtual bool equal(const base&) const = 0;
};
struct derived : base
{
derived(int state) : state(state) { }
derived(const derived &d) : state(d.state) { }
derived(const base &b) { derived::assign(b); }
derived(const derived& d) : state(d.state) { }
derived(const base& b) { derived::assign(b); }
virtual void assign(const base &b)
virtual void assign(const base& b)
{
state = boost::polymorphic_cast<const derived *>(&b)->state;
state = dynamic_cast<const derived& >(b).state;
}
virtual bool equal(const base &b) const
virtual bool equal(const base& b) const
{
return state == boost::polymorphic_cast<const derived *>(&b)->state;
return state == dynamic_cast<const derived&>(b).state;
}
int state;
};
inline bool operator==(const base &lhs, const base &rhs)
inline bool operator==(const base& lhs, const base& rhs)
{
return lhs.equal(rhs);
}
@ -198,11 +214,28 @@ int main()
{
// test for a fix to http://tinyurl.com/zuohe
// These two lines should be equivalent (and both compile)
input_iter p;
int shared_mutator_count = 0;
value val(shared_mutator_count);
input_iter p(val);
(*p).mutator();
p->mutator();
BOOST_TEST_EQ(val.increment_count, 0);
BOOST_TEST_EQ(val.private_mutator_count, 0); // mutator() should be invoked on an object returned by value
BOOST_TEST_EQ(shared_mutator_count, 2);
same_type<input_iter::pointer>(p.operator->());
STATIC_ASSERT_SAME(input_iter::pointer, std::remove_cv<std::remove_reference<decltype(p.operator->())>::type>::type);
}
{
// Test that accessing dereferenced value of a post-incremented iterator works
int shared_mutator_count = 0;
value val(shared_mutator_count);
input_iter p(val);
(*p++).mutator();
(p++)->mutator();
BOOST_TEST_EQ(val.increment_count, 2);
BOOST_TEST_EQ(val.private_mutator_count, 0); // mutator() should be invoked on an object returned by value
BOOST_TEST_EQ(shared_mutator_count, 2);
}
{

View File

@ -20,15 +20,13 @@
// reference type from operator* (David Abrahams)
// 19 Jan 2001 Initial version with iterator operators (David Abrahams)
#include <boost/type_traits/is_same.hpp>
#include <boost/operators.hpp>
#include <boost/static_assert.hpp>
#include <boost/config.hpp>
#include <iterator>
#include <vector>
#include <list>
#include <boost/core/lightweight_test.hpp>
#include <iostream>
#include <type_traits>
// A UDT for which we can specialize std::iterator_traits<element*> on
// compilers which don't support partial specialization. There's no
@ -98,7 +96,7 @@ template <> struct assertion<true>
template <class T, class U>
struct assert_same
: assertion<(::boost::is_same<T,U>::value)>
: assertion<(std::is_same<T,U>::value)>
{
};

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