Compare commits

..

1 Commits

Author SHA1 Message Date
a9b594c925 v2, v3, integration branch
[SVN r62649]
2010-06-09 11:34:33 +00:00
147 changed files with 3549 additions and 6398 deletions

View File

@ -1,429 +0,0 @@
# Copyright 2021 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)
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
concurrency:
group: ${{format('{0}:{1}', github.repository, github.ref)}}
cancel-in-progress: true
env:
GIT_FETCH_JOBS: 8
NET_RETRY_COUNT: 5
DEFAULT_BUILD_VARIANT: debug,release
jobs:
posix:
defaults:
run:
shell: bash
strategy:
fail-fast: false
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
container: ubuntu:16.04
install:
- g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install:
- g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install:
- g++-7
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install:
- g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install:
- g++-9
- toolset: gcc-10
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
- name: UBSAN
toolset: gcc-11
cxxstd: "03,11,14,17,20"
ubsan: 1
build_variant: debug
os: ubuntu-20.04
install:
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
# Linux, clang
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "03,11,14"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.8
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-18.04
install:
- clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-18.04
install:
- clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install:
- clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install:
- clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: 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
install:
- clang-8
- g++-7
gcc_toolchain: 7
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-12
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- name: UBSAN
toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
ubsan: 1
build_variant: debug
os: ubuntu-20.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
timeout-minutes: 60
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
steps:
- name: Setup environment
run: |
if [ -f "/etc/debian_version" ]
then
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
export DEBIAN_FRONTEND=noninteractive
fi
if [ -n "${{matrix.container}}" ]
then
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
if [ -f "/etc/debian_version" ]
then
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
fi
fi
git config --global pack.threads 0
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: |
declare -a SOURCE_KEYS SOURCES
if [ -n "${{join(matrix.source_keys, ' ')}}" ]
then
SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}")
fi
if [ -n "${{join(matrix.sources, ' ')}}" ]
then
SOURCES=("${{join(matrix.sources, '" "')}}")
fi
for key in "${SOURCE_KEYS[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
echo "Adding key: $key"
wget -O - "$key" | sudo apt-key add - && break || sleep 2
done
done
if [ ${#SOURCES[@]} -gt 0 ]
then
APT_ADD_REPO_COMMON_ARGS=("-y")
APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')"
if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ]
then
APT_ADD_REPO_COMMON_ARGS+=("-n")
fi
APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)"
for source in "${SOURCES[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}")
if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ]
then
case "$source" in
"ppa:"*)
APT_ADD_REPO_ARGS+=("-P")
;;
"deb "*)
APT_ADD_REPO_ARGS+=("-S")
;;
*)
APT_ADD_REPO_ARGS+=("-U")
;;
esac
fi
APT_ADD_REPO_ARGS+=("$source")
echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}"
sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
done
done
fi
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}}
- name: Setup GCC Toolchain
if: matrix.gcc_toolchain
run: |
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
mkdir -p "$GCC_TOOLCHAIN_ROOT"
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null)
echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV
echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV
DEPINST_ARGS=()
GIT_VERSION="$(git --version | sed -e 's/git version //')"
GIT_HAS_JOBS=1
if [ -f "/etc/debian_version" ]
then
if $(dpkg --compare-versions "$GIT_VERSION" lt 2.8.0)
then
GIT_HAS_JOBS=0
fi
else
declare -a GIT_VER=(${GIT_VERSION//./ })
declare -a GIT_MIN_VER=(2 8 0)
for ((i=0; i<${#GIT_VER[@]}; i++))
do
if [ -z "${GIT_MIN_VER[i]}" ]
then
GIT_MIN_VER[i]=0
fi
if [ "${GIT_VER[i]}" -lt "${GIT_MIN_VER[i]}" ]
then
GIT_HAS_JOBS=0
break
fi
done
fi
if [ "$GIT_HAS_JOBS" -ne 0 ]
then
DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS")
fi
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
git submodule update --init tools/boostdep
DEPINST_ARGS+=("$LIBRARY")
python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}"
if [ -z "${{matrix.cmake_tests}}" ]
then
./bootstrap.sh
./b2 headers
if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ]
then
echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam
if [ -n "$GCC_TOOLCHAIN_ROOT" ]
then
echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam
fi
echo " ;" >> ~/user-config.jam
fi
fi
- name: Run tests
if: matrix.cmake_tests == ''
run: |
cd ../boost-root
B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}")
if [ -n "${{matrix.build_variant}}" ]
then
B2_ARGS+=("variant=${{matrix.build_variant}}")
else
B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT")
fi
if [ -n "${{matrix.threading}}" ]
then
B2_ARGS+=("threading=${{matrix.threading}}")
fi
if [ -n "${{matrix.ubsan}}" ]
then
export UBSAN_OPTIONS="print_stacktrace=1"
B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global")
fi
if [ -n "${{matrix.cxxflags}}" ]
then
B2_ARGS+=("cxxflags=${{matrix.cxxflags}}")
fi
if [ -n "${{matrix.linkflags}}" ]
then
B2_ARGS+=("linkflags=${{matrix.linkflags}}")
fi
B2_ARGS+=("libs/$LIBRARY/test")
./b2 "${B2_ARGS[@]}"

View File

@ -1,31 +0,0 @@
# Copyright 2018 Peter Dimov
# Copyright 2018 Andrey Semashev
# 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
cmake_minimum_required(VERSION 3.5...3.20)
project(boost_iterator VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_iterator INTERFACE)
add_library(Boost::iterator ALIAS boost_iterator)
target_include_directories(boost_iterator INTERFACE include)
target_link_libraries(boost_iterator
INTERFACE
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

@ -1,27 +0,0 @@
# Boost.Iterator
Boost.Iterator, part of collection of the [Boost C++ Libraries](https://github.com/boostorg), provides tools for building and working with iterators in C++. The library also provides a number of iterator classes that can be used out of the box.
### Directories
* **doc** - Documentation sources
* **include** - Interface headers of Boost.Iterator
* **test** - Boost.Iterator unit tests
* **example** - Boost.Iterator usage examples
### More information
* [Documentation](https://boost.org/libs/iterator)
* [Report bugs](https://github.com/boostorg/iterator/issues/new). Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
* Submit your patches as [pull requests](https://github.com/boostorg/iterator/compare) against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
### Build status
Branch | GitHub Actions | AppVeyor | Test Matrix | Dependencies |
:-------------: | -------------- | -------- | ----------- | ------------ |
[`master`](https://github.com/boostorg/iterator/tree/master) | [![GitHub Actions](https://github.com/boostorg/iterator/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/iterator/actions?query=branch%3Amaster) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/ud8ug5aai8vd30hg/branch/master?svg=true)](https://ci.appveyor.com/project/Lastique/iterator/branch/master) | [![Tests](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/iterator.html) | [![Dependencies](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/iterator.html)
[`develop`](https://github.com/boostorg/iterator/tree/develop) | [![GitHub Actions](https://github.com/boostorg/iterator/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/iterator/actions?query=branch%3Adevelop) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/ud8ug5aai8vd30hg/branch/develop?svg=true)](https://ci.appveyor.com/project/Lastique/iterator/branch/develop) | [![Tests](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/iterator.html) | [![Dependencies](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/iterator.html)
### License
Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).

View File

@ -1,89 +0,0 @@
# Copyright 2017 Edward Diener
# Copyright 2019 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)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
- /feature\/.*/
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
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-14.1
CXXSTD: 14,17,latest
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: msvc-14.2
ADDRMD: 32,64
CXXSTD: 14,17,20,latest
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- TOOLSET: msvc-14.3
ADDRMD: 32,64
CXXSTD: 14,17,20,latest
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
- TOOLSET: clang-win
ADDRMD: 32,64
CXXSTD: 14,17,latest
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\cygwin\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,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
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
ADDPATH: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
install:
- set GIT_FETCH_JOBS=8
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init tools/build
- git submodule init tools/boostdep
- git submodule init tools/boost_install
- git submodule init libs/headers
- git submodule init libs/config
- git submodule update --jobs %GIT_FETCH_JOBS%
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\iterator
- python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" iterator
- cmd /c bootstrap
- b2 -d0 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- 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%

View File

@ -4,24 +4,19 @@
using quickbook ;
xml iterator
:
quickbook/iterator.qbk
xml iterator
:
quickbook/iterator.qbk
;
boostbook standalone
:
iterator
:
<xsl:param>"boost.root=../../../.."
<xsl:param>toc.max.depth=3
<xsl:param>toc.section.depth=3
<xsl:param>chunk.section.depth=2
<format>pdf:<xsl:param>"boost.url.prefix=http://www.boost.org/doc/libs/release/libs/iterator/doc/html"
<xsl:param>chunk.section.depth=4
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/iterator/doc
;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : standalone ;
explicit boostrelease ;

View File

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

View File

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

View File

@ -26,7 +26,7 @@
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2006-09-11</td></tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html">N1530</a>=03-0113, which was
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html">N1530</a>=03-0113, which was
accepted for Technical Report 1 by the C++ standard
committee's library working group.</td>
</tr>
@ -239,29 +239,29 @@ Iterator Concepts.</p>
<div class="section" id="iterator-concepts">
<h2><a class="toc-backref" href="#id18">Iterator Concepts</a></h2>
<p>This proposal is formulated in terms of the new <tt class="docutils literal"><span class="pre">iterator</span> <span class="pre">concepts</span></tt>
as proposed in <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a>, since user-defined and especially adapted
as proposed in <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a>, since user-defined and especially adapted
iterators suffer from the well known categorization problems that are
inherent to the current iterator categories.</p>
<p>This proposal does not strictly depend on proposal <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a>, as there
<p>This proposal does not strictly depend on proposal <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a>, as there
is a direct mapping between new and old categories. This proposal
could be reformulated using this mapping if <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a> was not accepted.</p>
could be reformulated using this mapping if <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a> was not accepted.</p>
</div>
<div class="section" id="interoperability">
<h2><a class="toc-backref" href="#id19">Interoperability</a></h2>
<p>The question of iterator interoperability is poorly addressed in the
current standard. There are currently two defect reports that are
concerned with interoperability issues.</p>
<p>Issue <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a> concerns the fact that mutable container iterator types
<p>Issue <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a> concerns the fact that mutable container iterator types
are only required to be convertible to the corresponding constant
iterator types, but objects of these types are not required to
interoperate in comparison or subtraction expressions. This situation
is tedious in practice and out of line with the way built in types
work. This proposal implements the proposed resolution to issue
<a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a>, as most standard library implementations do nowadays. In other
<a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a>, as most standard library implementations do nowadays. In other
words, if an iterator type A has an implicit or user defined
conversion to an iterator type B, the iterator types are interoperable
and the usual set of operators are available.</p>
<p>Issue <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#280">280</a> concerns the current lack of interoperability between
<p>Issue <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280">280</a> concerns the current lack of interoperability between
reverse iterator types. The proposed new reverse_iterator template
fixes the issues raised in 280. It provides the desired
interoperability without introducing unwanted overloads.</p>
@ -422,8 +422,8 @@ member (e.g. <a class="reference internal" href="#counting"><tt class="docutils
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
semantics required by the preferred resolution to <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
adopted by proposal <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a>: the result of <tt class="docutils literal"><span class="pre">p[n]</span></tt> is an object
semantics required by the preferred resolution to <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
adopted by proposal <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a>: the result of <tt class="docutils literal"><span class="pre">p[n]</span></tt> is an object
convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach

View File

@ -19,7 +19,7 @@
.. Version 1.9 of this ReStructuredText document corresponds to
n1530_, the paper accepted by the LWG.
.. _n1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html
.. _n1530: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
@ -140,7 +140,7 @@ as proposed in n1550_, since user-defined and especially adapted
iterators suffer from the well known categorization problems that are
inherent to the current iterator categories.
.. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
.. _n1550: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html
This proposal does not strictly depend on proposal n1550_, as there
is a direct mapping between new and old categories. This proposal
@ -169,8 +169,8 @@ reverse iterator types. The proposed new reverse_iterator template
fixes the issues raised in 280. It provides the desired
interoperability without introducing unwanted overloads.
.. _179: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179
.. _280: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#280
.. _179: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179
.. _280: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280
Iterator Facade

View File

@ -1,13 +1,10 @@
:Author:
`Dean Michael Berris <mailto:me@deanberris.com>`_
`Dean Michael Berris <mailto:mikhailberis@gmail.com>`_
:License:
Distributed under the Boost Software License, Version 1.0
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
:Copyright:
Copyright 2012 Google, Inc.
Function Input Iterator
=======================
@ -18,14 +15,11 @@ the iterator has been incremented. A Function Input Iterator models the
.. _InputIterator: http://www.sgi.com/tech/stl/InputIterator.html
The Function Input Iterator takes a function that models the Generator_ concept
(which is basically a nullary or 0-arity function object). The first dereference
of the iterator at a given position invokes the generator function and stores
and returns the result; subsequent dereferences at the same position simply
return the same stored result. Incrementing the iterator places it at a new
position, hence a subsequent dereference will generate a new value via another
invokation of the generator function. This ensures the generator function is
invoked precisely when the iterator is requested to return a (new) value.
Like the Generator Iterator, the Function Input Iterator takes a function
that models the Generator_ concept (which is basically a nullary or 0-arity
function object). Each increment of the function Function Input Iterator
invokes the generator function and stores the value in the iterator. When
the iterator is dereferenced the stored value is returned.
.. _Generator: http://www.sgi.com/tech/stl/Generator.html
@ -64,7 +58,7 @@ Synopsis
template <class Function, class State>
typename function_input_iterator<Function, State>
make_function_input_iterator(Function & f, State s);
make_function_input_iterator(Function & f);
struct infinite;
}
@ -118,7 +112,7 @@ it with the ``boost::infinite`` helper class.
copy(
make_function_input_iterator(f,infinite()),
make_function_input_iterator(f,infinite()),
ostream_iterator<int>(cout, " ")
ostream_iterator<int>(count, " ")
);
Above, instead of creating a huge vector we rely on the STL copy algorithm

View File

@ -1,163 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<title>Generator Iterator Adaptor Documentation</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle"
width="277" height="86">
<h1>Generator Iterator Adaptor</h1>
<p>Defined in header <a href=
"../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a></p>
<p>The generator iterator adaptor makes it easier to create custom input
iterators from 0-ary functions and function objects. The adaptor takes a
<a href="http://www.sgi.com/tech/stl/Generator.html">Generator</a> and
creates a model of <a href=
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>. Each
increment retrieves an item from the generator and makes it available to be
retrieved by dereferencing. The motivation for this iterator is that some
concepts can be more naturally expressed as a generator, while most STL
algorithms expect an iterator. An example is the <a href=
"../random/index.html">Random Number</a> library.</p>
<h2>Synopsis</h2>
<blockquote>
<pre>
namespace boost {
template &lt;class Generator&gt;
class generator_iterator_policies;
template &lt;class Generator&gt;
class generator_iterator_generator;
template &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; gen);
}
</pre>
</blockquote>
<hr>
<h2>The Generator Iterator Generator Class</h2>
<p>The class generator_iterator_generator is a helper class whose purpose
is to construct a generator iterator type. The template parameter for this
class is the Generator function object type that is being wrapped. The
generator iterator adaptor only holds a reference (or pointer) to the
function object, therefore the function object must outlive the generator
iterator adaptor constructed from it.</p>
<pre>
template &lt;class Generator&gt;
class generator_iterator_generator
{
public:
typedef <i>unspecified</i> type; // the resulting generator iterator type
}
</pre>
<h3>Template Parameters</h3>
<table border summary="">
<tr>
<th>Parameter</th>
<th>Description</th>
</tr>
<tr>
<td><tt><a href=
"http://www.sgi.com/tech/stl/Generator.html">Generator</a></tt></td>
<td>The generator (0-ary function object) type being wrapped. The
return type of the function must be defined as
<tt>Generator::result_type</tt>. The function object must be a model of
<a href=
"http://www.sgi.com/tech/stl/Generator.html">Generator</a>.</td>
</tr>
</table>
<h3>Concept Model</h3>
<p>The generator iterator class is a model of <a href=
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.</p>
<h3>Members</h3>
<p>The generator iterator implements the member functions and operators
required of the <a href=
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>
concept.<br></p>
<hr>
<h2><a name="make_generator_iterator" id="make_generator_iterator">The
Generator Iterator Object Generator</a></h2>
<p>The <tt>make_generator_iterator()</tt> function provides a convenient
way to create generator iterator objects. The function saves the user the
trouble of explicitly writing out the iterator types.</p>
<blockquote>
<pre>
template &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; gen);
</pre>
</blockquote>
<hr>
<h3>Example</h3>
<p>The following program shows how <code>generator_iterator</code>
transforms a generator into an input iterator.</p>
<blockquote>
<pre>
#include &lt;iostream&gt;
#include &lt;boost/generator_iterator.hpp&gt;
class my_generator
{
public:
typedef int result_type;
my_generator() : state(0) { }
int operator()() { return ++state; }
private:
int state;
};
int main()
{
my_generator gen;
boost::generator_iterator_generator&lt;my_generator&gt;::type it = boost::make_generator_iterator(gen);
for(int i = 0; i &lt; 10; ++i, ++it)
std::cout &lt;&lt; *it &lt;&lt; std::endl;
}
</pre>
</blockquote>
<hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
height="31" width="88"></a></p>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
<p><i>Copyright &copy; 2001 <a href=
"http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a></i></p>
<p><i>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href=
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
</body>
</html>

View File

@ -131,9 +131,6 @@ is called to get the value to return.</li>
<li><a class="reference external" href="function_output_iterator.html"><tt class="docutils literal"><span class="pre">function_output_iterator</span></tt></a> (<a class="reference external" href="function_output_iterator.pdf">PDF</a>): an output iterator wrapping a unary function
object; each time an element is written into the dereferenced
iterator, it is passed as a parameter to the function object.</li>
<li><a class="reference external" href="generator_iterator.htm"><tt class="docutils literal"><span class="pre">generator_iterator</span></tt></a>: an input iterator wrapping a reference to a generator (nullary function object);
each time the iterator is dereferenced, the function object
is called to get the value to return. This is a more outdated analogue of <tt class="docutils literal"><span class="pre">function_input_iterator</span></tt>.</li>
<li><a class="reference external" href="indirect_iterator.html"><tt class="docutils literal"><span class="pre">indirect_iterator</span></tt></a> (<a class="reference external" href="indirect_iterator.pdf">PDF</a>): an iterator over the objects <em>pointed-to</em> by the
elements of some sequence.</li>
<li><a class="reference external" href="permutation_iterator.html"><tt class="docutils literal"><span class="pre">permutation_iterator</span></tt></a> (<a class="reference external" href="permutation_iterator.pdf">PDF</a>): an iterator over the elements of some random-access

View File

@ -115,8 +115,8 @@ __ iterator_facade.pdf
__ iterator_adaptor.pdf
Both |facade| and |adaptor| as well as many of the `specialized
adaptors`_ mentioned below have been proposed for standardization;
see our
adaptors`_ mentioned below have been proposed for standardization,
and accepted into the first C++ technical report; see our
`Standard Proposal For Iterator Facade and Adaptor`__ (PDF__)
@ -146,10 +146,6 @@ iterator templates based on the Boost `iterator facade and adaptor`_.
object; each time an element is written into the dereferenced
iterator, it is passed as a parameter to the function object.
* |generator|_: an input iterator wrapping a generator (nullary
function object); each time the iterator is dereferenced, the function object
is called to get the value to return. This is an outdated analogue of |function_input|_.
* |indirect|_ (PDF__): an iterator over the objects *pointed-to* by the
elements of some sequence.
@ -187,9 +183,6 @@ __ function_input_iterator.pdf
.. _function_output: function_output_iterator.html
__ function_output_iterator.pdf
.. |generator| replace:: ``generator_iterator``
.. _generator: generator_iterator.htm
.. |indirect| replace:: ``indirect_iterator``
.. _indirect: indirect_iterator.html
__ indirect_iterator.pdf
@ -220,23 +213,6 @@ __ zip_iterator.pdf
Iterator Utilities
====================
Operations
----------
The standard library does not handle new-style iterators properly,
because it knows nothing about the iterator traversal concepts.
The Boost.Iterator library provides implementations that fully understand
the new concepts for the two basic operations:
- |advance|_
- |distance|_
.. |advance| replace:: ``advance``
.. _advance: advance.html
.. |distance| replace:: ``distance``
.. _distance: distance.html
Traits
------

View File

@ -3,7 +3,7 @@
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. _N1550: http://www.boost-consulting.com/writing/n1550.html
.. _N1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html
.. _N1530: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html
:Author: David Abrahams and Jeremy Siek
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu

View File

@ -242,8 +242,8 @@ member (e.g. <a class="reference external" href="counting_iterator.html"><tt cla
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
semantics required by the preferred resolution to <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
adopted by proposal <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm">n1550</a>: the result of <tt class="docutils literal"><span class="pre">p[n]</span></tt> is an object
semantics required by the preferred resolution to <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
adopted by proposal <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html">n1550</a>: the result of <tt class="docutils literal"><span class="pre">p[n]</span></tt> is an object
convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach

View File

@ -167,9 +167,9 @@ the implementation of her iterator is free to implement an
class; it will hide the one supplied by ``iterator_facade`` from
clients of her iterator.
.. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
.. _n1550: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html
.. _`issue 299`: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299
.. _`issue 299`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
.. _`operator arrow`:

View File

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

View File

@ -3,11 +3,11 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
<title>Iterator Traits</title>
<meta name="author" content="David Abrahams" />
<meta name="organization" content="Boost Consulting" />
<meta name="date" content="$Date$" />
<meta name="date" content="2006-09-11" />
<meta name="copyright" content="Copyright David Abrahams 2004." />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
@ -25,7 +25,7 @@
<tr><th class="docinfo-name">Organization:</th>
<td><a class="first last reference external" href="http://www.boost-consulting.com">Boost Consulting</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>$Date$</td></tr>
<td>2006-09-11</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams 2004.</td></tr>
</tbody>
@ -37,7 +37,7 @@
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">Header <tt class="docutils literal">&lt;boost/iterator/iterator_traits.hpp&gt;</tt> provides
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">Header <tt class="docutils literal"><span class="pre">&lt;boost/iterator/iterator_traits.hpp&gt;</span></tt> provides
the ability to access an iterator's associated types using
MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</td>
</tr>
@ -46,15 +46,15 @@ MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#meta
<div class="section" id="overview">
<h1>Overview</h1>
<p><tt class="docutils literal"><span class="pre">std::iterator_traits</span></tt> provides access to five associated types
of any iterator: its <tt class="docutils literal">value_type</tt>, <tt class="docutils literal">reference</tt>, <tt class="docutils literal">pointer</tt>,
<tt class="docutils literal">iterator_category</tt>, and <tt class="docutils literal">difference_type</tt>. Unfortunately,
of any iterator: its <tt class="docutils literal"><span class="pre">value_type</span></tt>, <tt class="docutils literal"><span class="pre">reference</span></tt>, <tt class="docutils literal"><span class="pre">pointer</span></tt>,
<tt class="docutils literal"><span class="pre">iterator_category</span></tt>, and <tt class="docutils literal"><span class="pre">difference_type</span></tt>. Unfortunately,
such a &quot;multi-valued&quot; traits template can be difficult to use in a
metaprogramming context. <tt class="docutils literal">&lt;boost/iterator/iterator_traits.hpp&gt;</tt>
metaprogramming context. <tt class="docutils literal"><span class="pre">&lt;boost/iterator/iterator_traits.hpp&gt;</span></tt>
provides access to these types using a standard <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</p>
</div>
<div class="section" id="summary">
<h1>Summary</h1>
<p>Header <tt class="docutils literal">&lt;boost/iterator/iterator_traits.hpp&gt;</tt>:</p>
<p>Header <tt class="docutils literal"><span class="pre">&lt;boost/iterator/iterator_traits.hpp&gt;</span></tt>:</p>
<pre class="literal-block">
template &lt;class Iterator&gt;
struct iterator_value
@ -98,6 +98,21 @@ struct iterator_category
};
</pre>
</div>
<div class="section" id="broken-compiler-notes">
<h1>Broken Compiler Notes</h1>
<p>Because of workarounds in Boost, you may find that these
<a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a> actually work better than the facilities provided by
your compiler's standard library.</p>
<p>On compilers that don't support partial specialization, such as
Microsoft Visual C++ 6.0 or 7.0, you may need to manually invoke
<a class="reference external" href="../../type_traits/index.html#transformations">BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION</a> on the
<tt class="docutils literal"><span class="pre">value_type</span></tt> of pointers that are passed to these metafunctions.</p>
<p>Because of bugs in the implementation of GCC-2.9x, the name of
<tt class="docutils literal"><span class="pre">iterator_category</span></tt> is changed to <tt class="docutils literal"><span class="pre">iterator_category_</span></tt> on that
compiler. A macro, <tt class="docutils literal"><span class="pre">BOOST_ITERATOR_CATEGORY</span></tt>, that expands to
either <tt class="docutils literal"><span class="pre">iterator_category</span></tt> or <tt class="docutils literal"><span class="pre">iterator_category_</span></tt>, as
appropriate to the platform, is provided for portability.</p>
</div>
</div>
<div class="footer">
<hr class="footer" />

View File

@ -75,3 +75,24 @@ Header ``<boost/iterator/iterator_traits.hpp>``::
detail::iterator_traits<Iterator>::iterator_category
type;
};
Broken Compiler Notes
=====================
Because of workarounds in Boost, you may find that these
metafunctions_ actually work better than the facilities provided by
your compiler's standard library.
On compilers that don't support partial specialization, such as
Microsoft Visual C++ 6.0 or 7.0, you may need to manually invoke
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION_ on the
``value_type`` of pointers that are passed to these metafunctions.
Because of bugs in the implementation of GCC-2.9x, the name of
``iterator_category`` is changed to ``iterator_category_`` on that
compiler. A macro, ``BOOST_ITERATOR_CATEGORY``, that expands to
either ``iterator_category`` or ``iterator_category_``, as
appropriate to the platform, is provided for portability.
.. _BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION: ../../type_traits/index.html#transformations

View File

@ -27,10 +27,10 @@
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2006-09-11</td></tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1550.htm">n1550</a>=03-0133, which was
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1550.html">n1550</a>=03-0133, which was
accepted for Technical Report 1 by the C++ standard
committee's library working group. This proposal is a
revision of paper <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1297.html">n1297</a>, <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1477.html">n1477</a>, and <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1531.html">n1531</a>.</td>
revision of paper <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html">n1297</a>, <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1477.html">n1477</a>, and <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1531.html">n1531</a>.</td>
</tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt
@ -127,12 +127,12 @@ requirements in the iterator categories.</p>
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt></td>
</tr>
<tr><td>Forward Iterator</td>
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is <tt class="docutils literal"><span class="pre">T&amp;</span></tt> (or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">T&amp;</span></tt> once <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#200">issue 200</a>
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is <tt class="docutils literal"><span class="pre">T&amp;</span></tt> (or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">T&amp;</span></tt> once <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200">issue 200</a>
is resolved)</td>
</tr>
<tr><td>Random Access Iterator</td>
<td><tt class="docutils literal"><span class="pre">i[n]</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt> (also <tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt>
is required for mutable iterators once <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>
is required for mutable iterators once <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>
is resolved)</td>
</tr>
</tbody>
@ -141,7 +141,7 @@ is resolved)</td>
single hierarchy, many useful iterators can not be appropriately
categorized. For example, <tt class="docutils literal"><span class="pre">vector&lt;bool&gt;::iterator</span></tt> is almost a
random access iterator, but the return type is not <tt class="docutils literal"><span class="pre">bool&amp;</span></tt> (see
<a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#96">issue 96</a> and Herb Sutter's paper J16/99-0008 = WG21
<a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96">issue 96</a> and Herb Sutter's paper J16/99-0008 = WG21
N1185). Therefore, the iterators of <tt class="docutils literal"><span class="pre">vector&lt;bool&gt;</span></tt> only meet the
requirements of input iterator and output iterator. This is so
nonintuitive that the C++ standard contradicts itself on this point.
@ -344,7 +344,7 @@ approach for specifying <tt class="docutils literal"><span class="pre">operator[
direction would mean that an iterator satisfying the old Random Access
Iterator requirements would not necessarily be a model of Readable or
Writable Lvalue Iterator. Instead we have chosen a design that
matches the preferred resolution of <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>: <tt class="docutils literal"><span class="pre">operator[]</span></tt> is
matches the preferred resolution of <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>: <tt class="docutils literal"><span class="pre">operator[]</span></tt> is
only required to return something convertible to the <tt class="docutils literal"><span class="pre">value_type</span></tt>
(for a Readable Iterator), and is required to support assignment
<tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt> (for a Writable Iterator).</p>
@ -976,7 +976,7 @@ struct random_access_traversal_tag : bidirectional_traversal_tag { };
<div class="section" id="addition-to-lib-iterator-traits">
<h2><a class="toc-backref" href="#id23">Addition to [lib.iterator.traits]</a></h2>
<p>The <tt class="docutils literal"><span class="pre">is_readable_iterator</span></tt> class
template satisfies the <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">UnaryTypeTrait</a> requirements.</p>
template satisfies the <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">UnaryTypeTrait</a> requirements.</p>
<p>Given an iterator type <tt class="docutils literal"><span class="pre">X</span></tt>, <tt class="docutils literal"><span class="pre">is_readable_iterator&lt;X&gt;::value</span></tt>
yields <tt class="docutils literal"><span class="pre">true</span></tt> if, for an object <tt class="docutils literal"><span class="pre">a</span></tt> of type <tt class="docutils literal"><span class="pre">X</span></tt>, <tt class="docutils literal"><span class="pre">*a</span></tt> is
convertible to <tt class="docutils literal"><span class="pre">iterator_traits&lt;X&gt;::value_type</span></tt>, and <tt class="docutils literal"><span class="pre">false</span></tt>
@ -1007,7 +1007,7 @@ otherwise.</p>
</div>
<div class="section" id="footnotes">
<h1><a class="toc-backref" href="#id24">Footnotes</a></h1>
<p>The UnaryTypeTrait concept is defined in <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">n1519</a>; the LWG is
<p>The UnaryTypeTrait concept is defined in <a class="reference external" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">n1519</a>; the LWG is
considering adding the requirement that specializations are derived
from their nested <tt class="docutils literal"><span class="pre">::type</span></tt>.</p>
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue

View File

@ -38,10 +38,10 @@
.. contents:: Table of Contents
.. _n1297: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1297.html
.. _n1477: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1477.html
.. _n1531: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1531.html
.. _n1550: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1550.htm
.. _n1297: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html
.. _n1477: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1477.html
.. _n1531: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1531.html
.. _n1550: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1550.html
============
Motivation
@ -76,8 +76,8 @@ requirements in the iterator categories.
| |is resolved) |
+------------------------+-----------------------------------------------------+
.. _issue 200: http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#200
.. _issue 299: http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#299
.. _issue 200: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200
.. _issue 299: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299
Because iterator traversal and value access are mixed together in a
@ -91,7 +91,7 @@ nonintuitive that the C++ standard contradicts itself on this point.
In paragraph 23.2.4/1 it says that a ``vector`` is a sequence that
supports random access iterators.
.. _issue 96: http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#96
.. _issue 96: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96
Another difficult-to-categorize iterator is the transform iterator, an
adaptor which applies a unary function object to the dereferenced
@ -791,7 +791,7 @@ The UnaryTypeTrait concept is defined in n1519_; the LWG is
considering adding the requirement that specializations are derived
from their nested ``::type``.
.. _n1519: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1519.htm
.. _n1519: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm
..
LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue

View File

@ -1,3 +1,4 @@
[section:adaptor Iterator Adaptor]
The `iterator_adaptor` class template adapts some `Base` [#base]_
@ -46,7 +47,7 @@ that assumption.
, class Reference = use_default
, class Difference = use_default
>
class iterator_adaptor
class iterator_adaptor
: public iterator_facade<Derived, *V'*, *C'*, *R'*, *D'*> // see details
{
friend class iterator_core_access;
@ -59,21 +60,21 @@ that assumption.
typedef iterator_adaptor iterator_adaptor\_;
Base const& base_reference() const;
Base& base_reference();
private: // Core iterator interface for iterator_facade.
private: // Core iterator interface for iterator_facade.
typename iterator_adaptor::reference dereference() const;
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
void advance(typename iterator_adaptor::difference_type n);
void increment();
void decrement();
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
>
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
@ -131,8 +132,8 @@ above are defined as follows:
iterator_adaptor();
[*Requires:] The `Base` type must be Default Constructible.[br]
[*Returns:] An instance of `iterator_adaptor` with
[*Requires:] The `Base` type must be Default Constructible.\n
[*Returns:] An instance of `iterator_adaptor` with
`m_iterator` default constructed.
@ -166,7 +167,7 @@ above are defined as follows:
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
>
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
[*Returns:] `m_iterator == x.base()`
@ -187,7 +188,7 @@ above are defined as follows:
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
>
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
@ -205,7 +206,7 @@ we're going to pick up right where it left off.
.. |fac_tut| replace:: `iterator_facade` tutorial
.. _fac_tut: iterator_facade.html#tutorial-example
[blurb [*`node_base*` really *is* an iterator][br][br]
[blurb [*`node_base*` really *is* an iterator]\n\n
It's not really a very interesting iterator, since `node_base`
is an abstract class: a pointer to a `node_base` just points
at some base subobject of an instance of some other class, and
@ -228,7 +229,7 @@ operations on the underlying pointer, via the `node_iterator`\ 's
|dereference_and_equal|_). The only real behavioral difference
between `node_base*` and `node_iterator` can be observed when
they are incremented: `node_iterator` follows the
`m_next` pointer, while `node_base*` just applies an address offset.
`m_next` pointer, while `node_base*` just applies an address offset.
.. |dereference_and_equal| replace:: `dereference` and `equal` member functions
.. _dereference_and_equal: iterator_facade.html#implementing-the-core-operations
@ -286,8 +287,8 @@ this technique is known not to work with Borland C++ 5.6.4 and
Metrowerks CodeWarrior versions prior to 9.0]
You can see an example program that exercises this version of the
node iterators
[example_link node_iterator3.cpp..here].
node iterators
[@../example/node_iterator3.cpp `here`].
In the case of `node_iter`, it's not very compelling to pass
@ -305,7 +306,7 @@ types to its `Base` saves the implementor of
std::iterator_traits<Iterator>::*some-associated-type*
at least four times.
at least four times.
We urge you to review the documentation and implementations of
|reverse_iterator|_ and the other Boost `specialized iterator
@ -329,4 +330,4 @@ __ index.html#specialized-adaptors
[endsect]
[endsect]
[endsect]

View File

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

View File

@ -1,3 +1,4 @@
[section:archetypes Iterator Archetypes]
The `iterator_archetype` class constructs a minimal implementation of
@ -40,23 +41,23 @@ The access category types provided correspond to the following
standard iterator access concept combinations:
readable_iterator_t :=
Readable Iterator
writable_iterator_t :=
Writeable Iterator
readable_writable_iterator_t :=
Readable Iterator & Writeable Iterator & Swappable Iterator
readable_lvalue_iterator_t :=
Readable Iterator & Lvalue Iterator
writeable_lvalue_iterator_t :=
Readable Iterator & Writeable Iterator & Swappable Iterator & Lvalue Iterator
[h3 Traits]
@ -65,25 +66,25 @@ The nested trait types are defined as follows:
if (AccessCategory == readable_iterator_t)
value_type = Value
reference = Value
pointer = Value*
else if (AccessCategory == writable_iterator_t)
value_type = void
reference = void
pointer = void
else if (AccessCategory == readable_writable_iterator_t)
value_type = Value
reference :=
A type X that is convertible to Value for which the following
expression is valid. Given an object x of type X and v of type
expression is valid. Given an object x of type X and v of type
Value.
x = v
@ -91,13 +92,13 @@ The nested trait types are defined as follows:
pointer = Value*
else if (AccessCategory == readable_lvalue_iterator_t)
value_type = Value
reference = Value const&
pointer = Value const*
else if (AccessCategory == writable_lvalue_iterator_t)
value_type = Value
reference = Value&
pointer = Value*
@ -107,11 +108,11 @@ The nested trait types are defined as follows:
difference_type := ptrdiff_t
else
difference_type := unspecified type
iterator_category :=
iterator_category :=
A type X satisfying the following two constraints:
@ -155,4 +156,5 @@ the iterator concept specified by `AccessCategory` and
arguments. `iterator_archetype` does not model any other access
concepts or any more derived traversal concepts.
[endsect]
[endsect]

View File

@ -4,7 +4,7 @@ The iterator concept checking classes provide a mechanism for a
template to report better error messages when a user instantiates the
template with a type that does not meet the requirements of the
template. For an introduction to using concept checking classes, see
the documentation for the _concept_check_ library.
the documentation for the boost::concept_check library.
[h2 `iterator_concepts.hpp` Synopsis]
@ -51,4 +51,4 @@ the documentation for the _concept_check_ library.
}
[endsect]
[endsect]

View File

@ -1,8 +1,9 @@
[section:concepts Iterator Concepts]
[section:access Access]
[section:concepts_access Access]
[section:readable Readable Iterator Concept]
[h2 Readable Iterator Concept]
A class or built-in type `X` models the *Readable Iterator* concept
for value type `T` if, in addition to `X` being Assignable and
@ -31,18 +32,17 @@ type `T`.
[`U&`]
[pre: `(*a).m` is well-defined. Equivalent to `(*a).m`.]
]
]
[endsect]
[section:writable Writable Iterator Concept]
]
[h2 Writable Iterator Concept ]
A class or built-in type `X` models the *Writable Iterator* concept
if, in addition to `X` being Copy Constructible, the following
expressions are valid and respect the stated semantics. Writable
Iterators have an associated *set of value types*.
[table Writable Iterator Requirements (in addition to Copy Constructible)
[table Writable Iterator Requirements (in addition to Copy Constructible)
[
[Expression]
[Return Type]
@ -55,15 +55,13 @@ Iterators have an associated *set of value types*.
]
]
[endsect]
[section:swappable Swappable Iterator Concept]
[h2 Swappable Iterator Concept]
A class or built-in type `X` models the *Swappable Iterator* concept
if, in addition to `X` being Copy Constructible, the following
expressions are valid and respect the stated semantics.
[table Swappable Iterator Requirements (in addition to Copy Constructible)
[table Swappable Iterator Requirements (in addition to Copy Constructible)
[
[Expression]
[Return Type]
@ -79,9 +77,7 @@ expressions are valid and respect the stated semantics.
[blurb *Note:* An iterator that is a model of the *Readable* and *Writable Iterator* concepts
is also a model of *Swappable Iterator*. *--end note*]
[endsect]
[section:lvalue Lvalue Iterator Concept]
[h2 Lvalue Iterator Concept]
The *Lvalue Iterator* concept adds the requirement that the return
type of `operator*` type be a reference to the value type of the
@ -105,17 +101,17 @@ iterator.
[endsect]
[endsect]
[section:concepts_traversal Traversal]
[section:traversal Traversal]
[h2 Incrementable Iterator Concept]
[section:incrementable Incrementable Iterator Concept]
A class or built-in type `X` models the *Incrementable Iterator*
concept if, in addition to `X` being Assignable and Copy
Constructible, the following expressions are valid and respect the
stated semantics.
[table Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible)
[
[Expression ]
@ -133,7 +129,7 @@ stated semantics.
[``
{
X tmp = r;
++r;
++r;
return tmp;
}
``]
@ -145,9 +141,7 @@ stated semantics.
]
]
[endsect]
[section:single_pass Single Pass Iterator Concept]
[h2 Single Pass Iterator Concept]
A class or built-in type `X` models the *Single Pass Iterator*
concept if the following expressions are valid and respect the stated
@ -162,7 +156,7 @@ semantics.
[
[`++r`]
[`X&`]
[pre:[br]`r` is dereferenceable;[br]post:[br]`r` is dereferenceable or[br]`r` is past-the-end]
[pre:\n`r` is dereferenceable;\npost:\n`r` is dereferenceable or\n`r` is past-the-end]
]
[
[`a == b`]
@ -174,11 +168,6 @@ semantics.
[convertible to `bool`]
[`!(a == b)`]
]
[
[`iterator_traits<X>::difference_type`]
[A signed integral type representing the distance between iterators]
[]
]
[
[`iterator_traversal<X>::type`]
[Convertible to`single_pass_traversal_tag`]
@ -186,9 +175,8 @@ semantics.
]
]
[endsect]
[section:forward Forward Traversal Concept]
[h2 Forward Traversal Concept]
A class or built-in type `X` models the *Forward Traversal*
concept if, in addition to `X` meeting the requirements of Default
@ -211,6 +199,11 @@ valid and respect the stated semantics.
[`X&`]
[`r == s` and `r` is dereferenceable implies `++r == ++s.`]
]
[
[`iterator_traits<X>::difference_type`]
[A signed integral type representing the distance between iterators]
[]
]
[
[`iterator_traversal<X>::type`]
[Convertible to `forward_traversal_tag`]
@ -218,9 +211,7 @@ valid and respect the stated semantics.
]
]
[endsect]
[section:bidirectional Bidirectional Traversal Concept]
[h2 Bidirectional Traversal Concept]
A class or built-in type `X` models the *Bidirectional Traversal*
concept if, in addition to `X` meeting the requirements of Forward
@ -232,11 +223,11 @@ the stated semantics.
[Expression]
[Return Type]
[Assertion/Semantics/Pre-/Post-condition]
]
]
[
[`--r`]
[`X&`]
[pre: there exists `s` such that `r == ++s`.[br] post: `s` is dereferenceable. `--(++r) == r`. `--r == --s` implies `r == s`. `&r == &--r`.]
[pre: there exists `s` such that `r == ++s`.\n post: `s` is dereferenceable. `--(++r) == r`. `--r == --s` implies `r == s`. `&r == &--r`.]
]
[
[`r--`]
@ -256,9 +247,7 @@ the stated semantics.
]
]
[endsect]
[section:random_access Random Access Traversal Concept]
[h2 Random Access Traversal Concept]
A class or built-in type `X` models the *Random Access Traversal*
concept if the following expressions are valid and respect the stated
@ -266,8 +255,8 @@ semantics. In the table below, `Distance` is
`iterator_traits<X>::difference_type` and `n` represents a
constant object of type `Distance`.
[table Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal)
[
[table Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal)
[
[Expression]
[Return Type]
[Operational Semantics]
@ -277,10 +266,10 @@ constant object of type `Distance`.
[`r += n`]
[ `X&`]
[``
{
{
Distance m = n;
if (m >= 0)
while (m--)
while (m--)
++r;
else
while (m++)
@ -290,18 +279,18 @@ constant object of type `Distance`.
``]
[ ]
]
[
[
[`a + n`, `n + a`]
[`X`]
[``
{
{
X tmp = a;
return tmp+= n;
}
``]
[]
]
[
[
[`r -= n`]
[`X&`]
[`return r += -n`]
@ -311,9 +300,9 @@ constant object of type `Distance`.
[`a - n`]
[`X`]
[``
{
{
X tmp = a;
return tmp-= n;
return tmp-= n;
}
``]
[]
@ -325,13 +314,13 @@ constant object of type `Distance`.
[pre: there exists a value `n` of `Distance` such that `a + n == b`. `b == a + (b - a)`.]
]
[
[`a[n]`]
[`a\[n\]`]
[convertible to T]
[`*(a + n)`]
[pre: a is a *Readable Iterator*]
]
[
[`a[n] = v`]
[`a\[n\] = v`]
[convertible to T]
[`*(a + n) = v`]
[pre: a is a *Writable iterator*]
@ -370,6 +359,4 @@ constant object of type `Distance`.
[endsect]
[endsect]
[endsect]
[endsect]

View File

@ -1,3 +1,4 @@
[section:counting Counting Iterator]
A `counting_iterator` adapts an object by adding an `operator*` that
@ -17,30 +18,28 @@ into the first array via indirection through the second array.
std::vector<int> numbers;
typedef std::vector<int>::iterator n_iter;
std::copy(boost::counting_iterator<int>(0),
boost::counting_iterator<int>(N),
std::back_inserter(numbers));
boost::counting_iterator<int>(N),
std::back_inserter(numbers));
std::vector<std::vector<int>::iterator> pointers;
std::copy(boost::make_counting_iterator(numbers.begin()),
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
std::cout << "indirectly printing out the numbers from 0 to "
<< N << std::endl;
std::cout << "indirectly printing out the numbers from 0 to "
<< N << std::endl;
std::copy(boost::make_indirect_iterator(pointers.begin()),
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator<int>(std::cout, " "));
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
The output is:
[pre
indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6
]
indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6
The source code for this example can be found [example_link counting_iterator_example.cpp..here].
The source code for this example can be found [@../example/counting_iterator_example.cpp here].
[h2 Reference]
@ -87,9 +86,9 @@ algorithm:
random_access_traversal_tag, Incrementable, const Incrementable&)
else
return |iterator-category|_\ (
iterator_traversal<Incrementable>::type,
iterator_traversal<Incrementable>::type,
Incrementable, const Incrementable&)
[blurb *Note:* implementers are encouraged to provide an implementation of
`operator-` and a `difference_type` that avoids overflows in
the cases where `std::numeric_limits<Incrementable>::is_specialized`
@ -153,7 +152,7 @@ operations.
counting_iterator();
[*Requires: ] `Incrementable` is Default Constructible.[br]
[*Requires: ] `Incrementable` is Default Constructible.\n
[*Effects: ] Default construct the member `m_inc`.
@ -175,14 +174,14 @@ operations.
counting_iterator& operator++();
[*Effects: ] `++m_inc`[br]
[*Effects: ] `++m_inc`\n
[*Returns: ] `*this`
counting_iterator& operator--();
[*Effects: ] `--m_inc`[br]
[*Returns: ] `*this`
[*Effects: ] `--m_inc`\n
[*Returns: ] `*this`
Incrementable const& base() const;
@ -190,4 +189,4 @@ operations.
[*Returns: ] `m_inc`
[endsect]
[endsect]

View File

@ -1,3 +1,4 @@
[section:facade Iterator Facade]
While the iterator interface is rich, there is a core subset of the
@ -67,7 +68,6 @@ requirements.
[
[`i.dereference()`]
[Access the value referred to]
]
[
[`i.equal(j)`]
[Compare for equality with `j`]
@ -83,7 +83,6 @@ requirements.
[
[`i.advance(n)`]
[Advance by `n` positions]
]
[
[`i.distance_to(j)`]
[Measure the distance to `j`]
@ -140,7 +139,7 @@ standardize the gateway protocol. Note that even if
open a safety loophole, as every core member function preserves the
invariants of the iterator.
[h2 `operator[]`]
[h2 `operator\[\]`]
The indexing operator for a generalized iterator presents special
challenges. A random access iterator's `operator[]` is only
@ -166,9 +165,9 @@ the implementation of her iterator is free to implement an
class; it will hide the one supplied by `iterator_facade` from
clients of her iterator.
.. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
.. _n1550: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/papers/2003/n1550.html
.. _`issue 299`: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299
.. _`issue 299`: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#299
.. _`operator arrow`:
@ -288,7 +287,7 @@ The `iterator_category` member of `iterator_facade` is
.. parsed-literal::
*iterator-category*\ (CategoryOrTraversal, reference, value_type)
*iterator-category*\ (CategoryOrTraversal, value_type, reference)
where *iterator-category* is defined as follows:
@ -296,10 +295,10 @@ where *iterator-category* is defined as follows:
The `enable_if_interoperable` template used above is for exposition
purposes. The member operators should only be in an overload set
provided the derived types `Dr1` and `Dr2` are interoperable,
provided the derived types `Dr1` and `Dr2` are interoperable,
meaning that at least one of the types is convertible to the other. The
`enable_if_interoperable` approach uses SFINAE to take the operators
out of the overload set when the types are not interoperable.
out of the overload set when the types are not interoperable.
The operators should behave *as-if* `enable_if_interoperable`
were defined to be:
@ -399,7 +398,7 @@ through member functions of class `iterator_core_access`.
__ `operator arrow`_
[*Returns:] If `reference` is a reference type, an object of type `pointer` equal to: `&static_cast<Derived const*>(this)->dereference()`
Otherwise returns an object of unspecified type such that,
Otherwise returns an object of unspecified type such that,
`(*static_cast<Derived const*>(this))->m` is equivalent to `(w = **static_cast<Derived const*>(this),
w.m)` for some temporary object `w` of type `value_type`.
@ -416,7 +415,7 @@ w.m)` for some temporary object `w` of type `value_type`.
Derived& operator++();
[*Effects:]
[*Effects:]
static_cast<Derived*>(this)->increment();
return *static_cast<Derived*>(this);
@ -456,7 +455,7 @@ w.m)` for some temporary object `w` of type `value_type`.
Derived& operator-=(difference_type n);
[*Effects:]
static_cast<Derived*>(this)->advance(-n);
return *static_cast<Derived*>(this);
@ -488,16 +487,14 @@ w.m)` for some temporary object `w` of type `value_type`.
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
then
`((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
Otherwise,
Otherwise,
`((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@ -507,16 +504,14 @@ w.m)` for some temporary object `w` of type `value_type`.
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
then
`!((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
Otherwise,
Otherwise,
`!((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@ -526,16 +521,14 @@ w.m)` for some temporary object `w` of type `value_type`.
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
then
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) < 0`.
Otherwise,
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@ -545,16 +538,14 @@ w.m)` for some temporary object `w` of type `value_type`.
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
then
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) <= 0`.
Otherwise,
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@ -564,16 +555,14 @@ w.m)` for some temporary object `w` of type `value_type`.
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
then
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) > 0`.
Otherwise,
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0`.
]
template <class Dr1, class V1, class TC1, class R1, class D1,
@ -583,16 +572,14 @@ w.m)` for some temporary object `w` of type `value_type`.
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
then
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) >= 0`.
Otherwise,
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0`.
]
.. _minus:
@ -604,33 +591,29 @@ w.m)` for some temporary object `w` of type `value_type`.
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
[*Return Type:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
then
`difference` shall be
`iterator_traits<Dr1>::difference_type`.
Otherwise
Otherwise
`difference` shall be `iterator_traits<Dr2>::difference_type`
]
[*Returns:]
[pre
if `is_convertible<Dr2,Dr1>::value`
then
then
`-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs)`.
Otherwise,
Otherwise,
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)`.
]
[endsect]
[include facade_tutorial.qbk]
[endsect]
[endsect]

View File

@ -1,11 +1,12 @@
[section:facade_tutorial Tutorial]
In this section we'll walk through the implementation of a few
iterators using `iterator_facade`, based around the simple
example of a linked list of polymorphic objects. This example was
inspired by a
inspired by a
[@http://thread.gmane.org/gmane.comp.lib.boost.user/5100 `posting`]
by Keith Macdonald on the
by Keith Macdonald on the
[@http://www.boost.org/more/mailing_lists.htm#users `Boost-Users`]
mailing list.
@ -29,16 +30,16 @@ Say we've written a polymorphic linked list node base class:
// print to the stream
virtual void print(std::ostream& s) const = 0;
// double the value
virtual void double_me() = 0;
void append(node_base* p)
{
if (m_next)
m_next->append(p);
if (m_next)
m_next->append(p);
else
m_next = p;
m_next = p;
}
private:
@ -209,7 +210,7 @@ the concepts we want our iterator to model. Referring to the
table__, we can see that the first three rows are applicable
because `node_iterator` needs to satisfy the requirements for
`readable iterator`_, `single pass iterator`_, and `incrementable
iterator`_.
iterator`_.
__ `core operations`_
@ -253,24 +254,24 @@ make them private and grant friendship to
};
Voila; a complete and conforming readable, forward-traversal
iterator! For a working example of its use, see
[example_link node_iterator1.cpp..this program].
iterator! For a working example of its use, see
[@../example/node_iterator1.cpp `this program`].
__ ../../example/node_iterator1.cpp
__ ../example/node_iterator1.cpp
[h2 A constant `node_iterator`]
[blurb *Constant and Mutable iterators*[br][br]
[blurb *Constant and Mutable iterators*\n\n
The term **mutable iterator** means an iterator through which
the object it references (its "referent") can be modified. A
**constant iterator** is one which doesn't allow modification of
its referent.[br][br]
its referent.\n\n
The words *constant* and *mutable* don't refer to the ability to
modify the iterator itself. For example, an `int const*` is a
non-\ `const` *constant iterator*, which can be incremented
but doesn't allow modification of its referent, and `int*
const` is a `const` *mutable iterator*, which cannot be
modified but which allows modification of its referent.[br][br]
modified but which allows modification of its referent.\n\n
Confusing? We agree, but those are the standard terms. It
probably doesn't help much that a container's constant iterator
is called `const_iterator`.
@ -284,7 +285,7 @@ changes:
class const_node_iterator
: public boost::iterator_facade<
const_node_iterator
node_iterator
, node_base **const**
, boost::forward_traversal_tag
>
@ -311,7 +312,7 @@ changes:
node_base **const**\ * m_node;
};
[blurb `const` and an iterator's `value_type`[br][br]
[blurb `const` and an iterator's `value_type`\n\n
The C++ standard requires an iterator's `value_type` *not* be
`const`\ -qualified, so `iterator_facade` strips the
`const` from its `Value` parameter in order to produce the
@ -401,7 +402,7 @@ adding a templatized converting constructor [#broken]_ [#random]_:
template <class OtherValue>
bool equal(node_iter<OtherValue> const& other) const
{
{
return this->m_node == other.m_node;
}
@ -427,11 +428,11 @@ adding a templatized converting constructor [#broken]_ [#random]_:
`distance_to` function as well.
__ ../../example/node_iterator2.hpp
__ ../example/node_iterator2.hpp
You can see an example program which exercises our interoperable
iterators
[example_link node_iterator2.cpp..here].
iterators
[@../example/node_iterator2.cpp `here`].
[h2 Telling the Truth]
@ -466,7 +467,7 @@ appropriate:
...
private:
private:
struct enabler {};
public:

View File

@ -1,3 +1,4 @@
[section:filter Filter Iterator]
The filter iterator adaptor creates a view of an iterator range in
@ -18,6 +19,7 @@ This example uses `filter_iterator` and then
array of integers. Then `make_filter_iterator` is is used to output
the integers greater than `-2`.
struct is_positive_number {
bool operator()(int x) { return 0 < x; }
};
@ -31,7 +33,7 @@ the integers greater than `-2`.
base_iterator numbers(numbers_);
// Example using filter_iterator
typedef boost::filter_iterator<is_positive_number, base_iterator>
typedef boost::filter_iterator<is_positive_number, base_iterator>
FilterIter;
is_positive_number predicate;
@ -50,11 +52,11 @@ the integers greater than `-2`.
// Another example using make_filter_iterator()
std::copy(
boost::make_filter_iterator(
std::bind(std::greater<int>(), std::placeholders::_1, -2)
std::bind2nd(std::greater<int>(), -2)
, numbers, numbers + N)
, boost::make_filter_iterator(
std::bind(std::greater<int>(), std::placeholders::_1, -2)
std::bind2nd(std::greater<int>(), -2)
, numbers + N, numbers + N)
, std::ostream_iterator<int>(std::cout, " ")
@ -68,13 +70,12 @@ the integers greater than `-2`.
The output is:
[pre
4 5 8
4 5 8
0 -1 4 5 8
]
4 5 8
4 5 8
0 -1 4 5 8
The source code for this example can be found [example_link filter_iterator_example.cpp..here].
The source code for this example can be found [@../example/filter_iterator_example.cpp here].
[h2 Reference]
@ -113,10 +114,10 @@ The source code for this example can be found [example_link filter_iterator_exam
If `Iterator` models Readable Lvalue Iterator and Bidirectional Traversal
Iterator then `iterator_category` is convertible to
`std::bidirectional_iterator_tag`.
`std::bidirectional_iterator_tag`.
Otherwise, if `Iterator` models Readable Lvalue Iterator and Forward Traversal
Iterator then `iterator_category` is convertible to
`std::forward_iterator_tag`.
`std::forward_iterator_tag`.
Otherwise `iterator_category` is
convertible to `std::input_iterator_tag`.
@ -163,7 +164,7 @@ following tables.
[[Writable Lvalue Iterator, Bidirectional Iterator ][Mutable Bidirectional Iterator]]
]
`filter_iterator<P1, X>` is interoperable with `filter_iterator<P2, Y>`
`filter_iterator<P1, X>` is interoperable with `filter_iterator<P2, Y>`
if and only if `X` is interoperable with `Y`.
@ -177,15 +178,15 @@ operations.
filter_iterator();
[*Requires: ]`Predicate` and `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs a `filter_iterator` whose`m_pred`, `m_iter`, and `m_end`
[*Requires: ]`Predicate` and `Iterator` must be Default Constructible.\n
[*Effects: ] Constructs a `filter_iterator` whose`m_pred`, `m_iter`, and `m_end`
members are a default constructed.
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
the first position in the range `[x,end)` such that `f(*m_iter) == true`
the first position in the range `[x,end)` such that `f(*m_iter) == true`
or else`m_iter == end`. The member `m_pred` is constructed from
`f` and `m_end` from `end`.
@ -194,9 +195,9 @@ operations.
filter_iterator(Iterator x, Iterator end = Iterator());
[*Requires: ] `Predicate` must be Default Constructible and
`Predicate` is a class type (not a function pointer).[br]
`Predicate` is a class type (not a function pointer).\n
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
the first position in the range `[x,end)` such that `m_pred(*m_iter) == true`
the first position in the range `[x,end)` such that `m_pred(*m_iter) == true`
or else`m_iter == end`. The member `m_pred` is default constructed.
@ -204,9 +205,9 @@ operations.
filter_iterator(
filter_iterator<Predicate, OtherIterator> const& t
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
);`
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.\n
[*Effects: ] Constructs a filter iterator whose members are copied from `t`.
@ -234,7 +235,8 @@ operations.
[*Effects: ] Increments `m_iter` and then continues to
increment `m_iter` until either `m_iter == m_end`
or `m_pred(*m_iter) == true`.[br]
[*Returns: ] `*this`
or `m_pred(*m_iter) == true`.\n
[*Returns: ] `*this`
[endsect]
[endsect]

View File

@ -1,3 +1,4 @@
[section:function_output Function Output Iterator]
The function output iterator adaptor makes it easier to create custom
@ -33,8 +34,8 @@ proxy object.
x.push_back("!");
std::string s = "";
std::copy(x.begin(), x.end(),
boost::make_function_output_iterator(string_appender(s)));
std::copy(x.begin(), x.end(),
boost::make_function_output_iterator(string_appender(s)));
std::cout << s << std::endl;
@ -67,7 +68,7 @@ proxy object.
[h3 Requirements]
`UnaryFunction` must be Assignable and Copy Constructible.
`UnaryFunction` must be Assignable and Copy Constructible.
[h3 Concepts]
@ -78,14 +79,14 @@ Incrementable Iterator concepts.
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
[*Effects: ] Constructs an instance of `function_output_iterator`
[*Effects: ] Constructs an instance of `function_output_iterator`
with `m_f` constructed from `f`.
unspecified_type operator*();
[*Returns: ] An object `r` of unspecified type such that `r = t`
is equivalent to `m_f(t)` for all `t`.
function_output_iterator& operator++();
@ -96,4 +97,4 @@ Incrementable Iterator concepts.
[*Returns: ] `*this`.
[endsect]
[endsect]

View File

@ -1,3 +1,4 @@
[section:indirect Indirect Iterator]
`indirect_iterator` adapts an iterator by applying an
@ -49,31 +50,30 @@ using the `make_indirect_iterator` helper function.
const_indirect_last(pointers_to_chars + N);
std::transform(const_indirect_first, const_indirect_last,
mutable_indirect_first, std::bind(std::plus<char>(), 1, std::placeholders::_1));
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
std::copy(mutable_indirect_first, mutable_indirect_last,
std::ostream_iterator<char>(std::cout, ","));
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
// Example of using make_indirect_iterator()
std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ","));
std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
The output is:
[pre
a,b,c,d,e,f,g,
b,c,d,e,f,g,h,
a,b,c,d,e,f,g,
]
a,b,c,d,e,f,g,
b,c,d,e,f,g,h,
a,b,c,d,e,f,g,
The source code for this example can be found
[example_link indirect_iterator_example.cpp..here].
The source code for this example can be found
[@../example/indirect_iterator_example.cpp here].
[h2 Reference]
@ -137,9 +137,9 @@ the following pseudo-code, where `V` is
else
typedef Reference reference;
if (Value is use_default) then
if (Value is use_default) then
typedef pointee<V>::type\* pointer;
else
else
typedef Value\* pointer;
if (Difference is use_default)
@ -203,8 +203,8 @@ following operations:
indirect_iterator();
[*Requires: ] `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs an instance of `indirect_iterator` with
[*Requires: ] `Iterator` must be Default Constructible.\n
[*Effects: ] Constructs an instance of `indirect_iterator` with
a default-constructed `m_iterator`.
@ -225,8 +225,8 @@ following operations:
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);
[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs an instance of `indirect_iterator` whose
[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.\n
[*Effects: ] Constructs an instance of `indirect_iterator` whose
`m_iterator` subobject is constructed from `y.base()`.
@ -242,13 +242,13 @@ following operations:
indirect_iterator& operator++();
[*Effects: ] `++m_iterator`[br]
[*Effects: ] `++m_iterator`\n
[*Returns: ] `*this`
indirect_iterator& operator--();
[*Effects: ] `--m_iterator`[br]
[*Effects: ] `--m_iterator`\n
[*Returns: ] `*this`
[endsect]
[endsect]

View File

@ -1,6 +1,6 @@
[library Boost.Iterator
[/ version 1.0.1]
[quickbook 1.6]
[authors [Abrahams, David], [Siek, Jeremy], [Witt, Thomas]]
[copyright 2003 2005 David Abrahams Jeremy Siek Thomas Witt]
[category iterator]
@ -28,11 +28,7 @@
[/ Links ]
[def _iterator_ [@../../../iterator/doc/index.html Boost.Iterator]]
[def _concept_check_ [@../../../concept_check/index.html Boost.ConceptCheck]]
[template example_link[name descr]'''<ulink url="../../example/'''[name]'''">'''[descr]'''</ulink>''']
[template sub[x]'''<subscript>'''[x]'''</subscript>''']
[def _iterator_ [@../../libs/iterator/doc/index.html Boost.Iterator]]
[section:intro Introduction]
@ -74,23 +70,19 @@ and a _GOTW_50_. New-style iterators go well beyond
patching up `vector<bool>`, though: there are lots of other
iterators already in use which can't be adequately represented by
the existing concepts. For details about the new iterator
concepts, see our [@../new-iter-concepts.html Standard Proposal for New-Style Iterators].
concepts, see our [@./new-iter-concepts.html Standard Proposal for New-Style Iterators].
[h2 Iterator Facade and Adaptor]
[/
[def _facade_ [link iterator.generic.facade facade]]
[def _adaptor_ [link iterator.generic.adaptor adaptor]]
]
[def _facade_ [@../iterator_facade.html facade]]
[def _adaptor_ [@../iterator_adaptor.html adaptor]]
[def _facade_ [@./iterator_facade.html facade]]
[def _adaptor_ [@./iterator_adaptor.html adaptor]]
Writing standard-conforming iterators is tricky, but the need comes
up often. In order to ease the implementation of new iterators,
the Boost.Iterator library provides the _facade_ class template,
which implements many useful defaults and compile-time checks
designed to help the iterator author ensure that his iterator is
correct.
correct.
It is also common to define a new iterator that is similar to some
underlying iterator or iterator-like type, but that modifies some
@ -99,28 +91,26 @@ library supplies the _adaptor_ class template, which is specially
designed to take advantage of as much of the underlying type's
behavior as possible.
Both _facade_ and _adaptor_ as well as many of the [link iterator.specialized specialized
adaptors] mentioned below have been proposed for standardization
([@../facade-and-adaptor.html Standard Proposal For Iterator Facade and Adaptor]).
Both _facade_ and _adaptor_ as well as many of the `specialized
adaptors`_ mentioned below have been proposed for standardization
([@./facade-and-adaptor.html Standard Proposal For Iterator Facade and Adaptor]).
[h2 Specialized Adaptors]
The iterator library supplies a useful suite of standard-conforming
iterator templates based on the Boost [link
iterator.intro.iterator_facade_and_adaptor iterator facade and adaptor]
intro.iterator_facade_and_adaptor iterator facade and adaptor]
templates.
[def _counting_ [link iterator.specialized.counting `counting_iterator`]]
[def _filter_ [link iterator.specialized.filter `filter_iterator`]]
[def _function_input_ [@../function_input_iterator.html `function_input_iterator`]]
[def _function_output_ [link iterator.specialized.function_output `function_output_iterator`]]
[def _generator_ [@../generator_iterator.htm `generator_iterator`]]
[def _indirect_ [link iterator.specialized.indirect `indirect_iterator`]]
[def _permutation_ [link iterator.specialized.permutation `permutation_iterator`]]
[def _reverse_ [link iterator.specialized.reverse `reverse_iterator`]]
[def _shared_ [link iterator.specialized.shared_container `shared_container_iterator`]]
[def _transform_ [link iterator.specialized.transform `transform_iterator`]]
[def _zip_ [link iterator.specialized.zip `zip_iterator`]]
[def _counting_ [@./counting_iterator.html `counting_iterator`]]
[def _filter_ [@./filter_iterator.html `filter_iterator`]]
[def _function_ [@./function_output_iterator.html `function_output_iterator`]]
[def _indirect_ [@./indirect_iterator.html `indirect_iterator`]]
[def _permutation_ [@./permutation_iterator.html `permutation_iterator`]]
[def _reverse_ [@./reverse_iterator.html `reverse_iterator`]]
[def _shared_ [@./shared_container_iterator.html `shared_container_iterator`]]
[def _transform_ [@./transform_iterator.html `transform_iterator`]]
[def _zip_ [@./zip_iterator.html `zip_iterator`]]
[def _shared_ptr_ [@../../smart_ptr/shared_ptr.htm `shared_ptr`]]
@ -130,18 +120,10 @@ templates.
* _filter_: an iterator over the subset of elements of some
sequence which satisfy a given predicate
* _function_input_: an input iterator wrapping a generator (nullary
function object); each time the iterator is dereferenced, the function object
is called to get the value to return.
* _function_output_: an output iterator wrapping a unary function
* _function_: an output iterator wrapping a unary function
object; each time an element is written into the dereferenced
iterator, it is passed as a parameter to the function object.
* _generator_: an input iterator wrapping a generator (nullary
function object); each time the iterator is dereferenced, the function object
is called to get the value to return. An outdated analogue of _function_input_.
* _indirect_: an iterator over the objects *pointed-to* by the
elements of some sequence.
@ -150,7 +132,7 @@ templates.
* _reverse_: an iterator which traverses the elements of some
bidirectional sequence in reverse. Corrects many of the
shortcomings of C++98's `std::reverse_iterator`.
shortcomings of C++98's ``std::reverse_iterator``.
* _shared_: an iterator over elements of a container whose
lifetime is maintained by a _shared_ptr_ stored in the iterator.
@ -158,7 +140,7 @@ templates.
* _transform_: an iterator over elements which are the result of
applying some functional transformation to the elements of an
underlying sequence. This component also replaces the old
`projection_iterator_adaptor`.
``projection_iterator_adaptor``.
* _zip_: an iterator over tuples of the elements at corresponding
positions of heterogeneous underlying iterators.
@ -167,9 +149,9 @@ templates.
[h3 Traits]
[def _pointee_ [link iterator.utilities.traits `pointee.hpp`]]
[def _iterator_traits_ [link iterator.utilities.iterator_traits `iterator_traits.hpp`]]
[def _interoperable_ [@../interoperable.html `interoperable.hpp`]]
[def _pointee_ [@./pointee.html `pointee.hpp`]]
[def _iterator_traits_ [@./iterator_traits.html `iterator_traits.hpp`]]
[def _interoperable_ [@./interoperable.html `interoperable.hpp`]]
[def _MPL_ [@../../mpl/doc/index.html [*MPL]]]
* _pointee_: Provides the capability to deduce the referent types
@ -180,40 +162,19 @@ templates.
retrieve an iterator's traits. Also corrects for the deficiencies
of broken implementations of `std::iterator_traits`.
[/
* _interoperable_: Provides an _MPL_ compatible metafunction for
testing iterator interoperability
[\ * |interoperable|_ (PDF__): Provides an _MPL_ compatible metafunction for
testing iterator interoperability
]
[h3 Testing and Concept Checking]
[def _iterator_concepts_ [link iterator.concepts `iterator_concepts.hpp`]]
[def _iterator_archetypes_ [link iterator.utilities.archetypes `iterator_archetypes.hpp`]]
[def _iterator_concepts_ [@./iterator_concepts.html `iterator_concepts.hpp`]]
[def _iterator_archetypes_ [@./iterator_archetypes.html `iterator_archetypes.hpp`]]
* _iterator_concepts_: Concept checking classes for the new iterator concepts.
* _iterator_archetypes_: Concept archetype classes for the new iterators concepts.
[h2 Iterator Algorithms]
The library provides a number of generic algorithms for use with iterators. These
algorithms take advantage of the new concepts defined by the library to provide
better performance and functionality.
[def _advance_ [link iterator.algorithms.advance `advance.hpp`]]
[def _distance_ [link iterator.algorithms.distance `distance.hpp`]]
[def _next_prior_ [link iterator.algorithms.next_prior `next_prior.hpp`]]
* _advance_: Provides `advance()` function for advancing an iterator a given number
of positions forward or backward.
* _distance_: Provides `distance()` function for computing distance between two
iterators.
* _next_prior_: Provides `next()` and `prior()` functions for obtaining
next and prior iterators to a given iterator. The functions are also compatible
with non-iterator types.
[endsect]
[include concepts.qbk]
@ -234,14 +195,12 @@ better performance and functionality.
[include concept_checking.qbk]
[include iterator_traits.qbk]
[include traits.qbk]
[include type_traits.qbk]
[include utilities.qbk]
[endsect]
[include algorithms.qbk]
[section:upgrading Upgrading from the old Boost Iterator Adaptor Library]
[def _type_generator_ [@http://www.boost.org/more/generic_programming.html#type_generator type generator]]
@ -305,3 +264,5 @@ library you see today.
Patterns, C++ Report, February 1995, pp. 24-27.]
[endsect]

View File

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

View File

@ -1,3 +1,4 @@
[section:permutation Permutation Iterator]
The permutation iterator adaptor provides a permuted view of a given
@ -34,7 +35,7 @@ past-the-end iterator to the indices.
*el_it = std::distance(elements.begin(), el_it);
index_type indices( index_size );
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
*i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
std::reverse( indices.begin(), indices.end() );
@ -74,28 +75,27 @@ past-the-end iterator to the indices.
The output is:
[pre
The original range is : 0 1 2 3 4 5 6 7 8 9
The reindexing scheme is : 9 8 7 6
The permutated range is : 9 8 7 6
Elements at even indices in the permutation : 9 7
Permutation backwards : 6 7 8 9
Iterate backward with stride 2 : 6 8
]
The original range is : 0 1 2 3 4 5 6 7 8 9
The reindexing scheme is : 9 8 7 6
The permutated range is : 9 8 7 6
Elements at even indices in the permutation : 9 7
Permutation backwards : 6 7 8 9
Iterate backward with stride 2 : 6 8
The source code for this example can be found
[example_link permutation_iter_example.cpp..here].
[@../example/permutation_iter_example.cpp here].
[h2 Reference]
[h3 Synopsis]
template< class ElementIterator
, class IndexIterator
, class ValueT = use_default
, class CategoryT = use_default
, class ReferenceT = use_default
, class DifferenceT = use_default >
, class IndexIterator
, class ValueT = use_default
, class CategoryT = use_default
, class ReferenceT = use_default
, class DifferenceT = use_default >
class permutation_iterator
{
public:
@ -104,10 +104,10 @@ The source code for this example can be found
template< class OEIter, class OIIter, class V, class C, class R, class D >
permutation_iterator(
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
);
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
);
reference operator*() const;
permutation_iterator& operator++();
ElementIterator const& base() const;
@ -117,7 +117,7 @@ The source code for this example can be found
};
template <class ElementIterator, class IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator( ElementIterator e, IndexIterator i);
@ -134,15 +134,15 @@ the `IndexIterator` must be convertible to the difference type of
as `IndexIterator` and the same iterator access concepts as
`ElementIterator`.
If `IndexIterator` models Single Pass Iterator and
If `IndexIterator` models Single Pass Iterator and
`ElementIterator` models Readable Iterator then
`permutation_iterator` models Input Iterator.
If `IndexIterator` models Forward Traversal Iterator and
If `IndexIterator` models Forward Traversal Iterator and
`ElementIterator` models Readable Lvalue Iterator then
`permutation_iterator` models Forward Iterator.
If `IndexIterator` models Bidirectional Traversal Iterator and
If `IndexIterator` models Bidirectional Traversal Iterator and
`ElementIterator` models Readable Lvalue Iterator then
`permutation_iterator` models Bidirectional Iterator.
@ -173,10 +173,10 @@ following operations.
template< class OEIter, class OIIter, class V, class C, class R, class D >
permutation_iterator(
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
);
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
);
[*Effects: ] Constructs `m_elt` from `r.m_elt` and
`m_order` from `y.m_order`.
@ -189,7 +189,7 @@ following operations.
permutation_iterator& operator++();
[*Effects: ] `++m_order`[br]
[*Effects: ] `++m_order`\n
[*Returns: ] `*this`
@ -199,9 +199,9 @@ following operations.
template <class ElementIterator, class IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator(ElementIterator e, IndexIterator i);
[*Returns: ] `permutation_iterator<ElementIterator, IndexIterator>(e, i)`
[endsect]
[endsect]

View File

@ -1,3 +1,4 @@
[section:reverse Reverse Iterator]
The reverse iterator adaptor iterates through the adapted iterator
@ -8,6 +9,7 @@ range in the opposite direction.
The following example prints an array of characters in reverse order
using `reverse_iterator`.
char letters_[] = "hello world!";
const int N = sizeof(letters_)/sizeof(char) - 1;
typedef char* base_iterator;
@ -33,14 +35,13 @@ using `reverse_iterator`.
The output is:
[pre
original sequence of letters: hello world!
sequence in reverse order: !dlrow olleh
sequence in double-reversed (normal) order: hello world!
]
original sequence of letters: hello world!
sequence in reverse order: !dlrow olleh
sequence in double-reversed (normal) order: hello world!
The source code for this example can be found
[example_link reverse_iterator_example.cpp..here].
[@../example/reverse_iterator_example.cpp here].
[h2 Reference]
@ -114,8 +115,8 @@ operations.
reverse_iterator();
[*Requires: ] `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator`
[*Requires: ] `Iterator` must be Default Constructible.\n
[*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator`
default constructed.
explicit reverse_iterator(Iterator x);
@ -130,8 +131,8 @@ operations.
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs instance of `reverse_iterator` whose
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.\n
[*Effects: ] Constructs instance of `reverse_iterator` whose
`m_iterator` subobject is constructed from `y.base()`.
@ -148,12 +149,12 @@ operations.
reverse_iterator& operator++();
[*Effects: ] `--m_iterator`[br]
[*Effects: ] `--m_iterator`\n
[*Returns: ] `*this`
reverse_iterator& operator--();
[*Effects: ] `++m_iterator`[br]
[*Effects: ] `++m_iterator`\n
[*Returns: ] `*this`
[endsect]
[endsect]

View File

@ -1,3 +1,4 @@
[section:shared_container Shared Container Iterator]
Defined in header [@../../../boost/shared_container_iterator.hpp `boost/shared_container_iterator.hpp`].
@ -26,12 +27,12 @@ iterator.
namespace boost {
template <typename Container>
class shared_container_iterator;
template <typename Container>
shared_container_iterator<Container>
make_shared_container_iterator(typename Container::iterator base,
make_shared_container_iterator(typename Container::iterator base,
boost::shared_ptr<Container> const& container);
std::pair<
typename shared_container_iterator<Container>,
typename shared_container_iterator<Container>
@ -45,7 +46,7 @@ iterator.
The class template `shared_container_iterator` is the shared container
iterator type. The `Container` template type argument must model the
[@http://www.sgi.com/tech/stl/Container.html Container] concept.
[@http://www.sgi.com/tech/stl/Container.html Container] concept.
[h2 Example]
@ -55,50 +56,48 @@ original shared pointer `ints` ceases to exist after `set_range()`
returns, the `shared_counter_iterator` objects maintain references to
the underlying vector and thereby extend the container's lifetime.
[example_link shared_iterator_example1.cpp..`shared_iterator_example1.cpp`]:
[@../../../libs/utility/shared_iterator_example1.cpp `shared_iterator_example1.cpp`]:
#include "shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <algorithm>
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
void set_range(iterator& i, iterator& end) {
boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
i = iterator(ints->begin(),ints);
end = iterator(ints->end(),ints);
}
int main() {
iterator i,end;
set_range(i,end);
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}
The output from this part is:
[pre
0,1,2,3,4,5,
]
0,1,2,3,4,5,
[table Template Parameters
[[Parameter][Description]]
@ -131,16 +130,16 @@ iterator will be valid. In addition it has the following constructor:
boost::shared_ptr<Container> const& container)
This function provides an alternative to directly constructing a
`shared_container_iterator`. Using the object generator, a
`shared_container_iterator`. Using the object generator, a
`shared_container_iterator` can be created and passed to a function without
explicitly specifying its type.
[h2 Example]
This example, similar to the previous,
This example, similar to the previous,
uses `make_shared_container_iterator()` to create the iterators.
[example_link shared_iterator_example2.cpp..`shared_iterator_example2.cpp`]:
[@../../../libs/utility/shared_iterator_example2.cpp `shared_iterator_example2.cpp`]:
#include "shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
@ -148,35 +147,35 @@ uses `make_shared_container_iterator()` to create the iterators.
#include <iterator>
#include <iostream>
#include <vector>
template <typename Iterator>
void print_range_nl (Iterator begin, Iterator end) {
typedef typename std::iterator_traits<Iterator>::value_type val;
std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
std::cout.put('\n');
}
int main() {
typedef boost::shared_ptr< std::vector<int> > ints_t;
{
ints_t ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
boost::make_shared_container_iterator(ints->end(),ints));
}
return 0;
}
@ -201,18 +200,18 @@ named. The output from this example is the same as the previous.
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`]:
[@../../../libs/utility/shared_iterator_example3.cpp `shared_iterator_example3.cpp`]:
#include "shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/tuple/tuple.hpp" // for boost::tie
#include <algorithm> // for std::copy
#include <iostream>
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
typedef boost::shared_container_iterator< std::vector<int> > iterator;
std::pair<iterator,iterator>
return_range() {
boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
@ -224,18 +223,18 @@ In the following example, a range of values is returned as a pair of shared_cont
range->push_back(5);
return boost::make_shared_container_range(range);
}
int main() {
iterator i,end;
boost::tie(i,end) = return_range();
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}
@ -246,4 +245,4 @@ the same as the previous two.
[endsect]
[endsect]
[endsect]

View File

@ -1,3 +1,4 @@
[section:specialized Specialized Adaptors]
[include ./counting_iterator.qbk]
@ -18,4 +19,4 @@
[include ./zip_iterator.qbk]
[endsect]
[endsect]

72
doc/quickbook/traits.qbk Normal file
View File

@ -0,0 +1,72 @@
[section:traits Iterator Traits]
`std::iterator_traits` provides access to five associated types
of any iterator: its `value_type`, `reference`, `pointer`,
`iterator_category`, and `difference_type`. Unfortunately,
such a "multi-valued" traits template can be difficult to use in a
metaprogramming context. `<boost/iterator/iterator_traits.hpp>`
provides access to these types using a standard metafunctions_.
[h2 Synopsis]
Header `<boost/iterator/iterator_traits.hpp>`:
template <class Iterator>
struct iterator_value
{
typedef typename
std::iterator_traits<Iterator>::value_type
type;
};
template <class Iterator>
struct iterator_reference
{
typedef typename
std::iterator_traits<Iterator>::reference
type;
};
template <class Iterator>
struct iterator_pointer
{
typedef typename
std::iterator_traits<Iterator>::pointer
type;
};
template <class Iterator>
struct iterator_difference
{
typedef typename
detail::iterator_traits<Iterator>::difference_type
type;
};
template <class Iterator>
struct iterator_category
{
typedef typename
detail::iterator_traits<Iterator>::iterator_category
type;
};
[h2 Broken Compiler Notes]
Because of workarounds in Boost, you may find that these
[@../../mpl/doc/index.html#metafunctions metafunctions] actually work better than the facilities provided by
your compiler's standard library.
On compilers that don't support partial specialization, such as
Microsoft Visual C++ 6.0 or 7.0, you may need to manually invoke
[@../../type_traits/index.html#transformations BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION] on the
`value_type` of pointers that are passed to these metafunctions.
Because of bugs in the implementation of GCC-2.9x, the name of
`iterator_category` is changed to `iterator_category_` on that
compiler. A macro, `BOOST_ITERATOR_CATEGORY`, that expands to
either `iterator_category` or `iterator_category_`, as
appropriate to the platform, is provided for portability.
[endsect]

View File

@ -1,3 +1,4 @@
[section:transform Transform Iterator]
The transform iterator adapts an iterator by modifying the
@ -13,38 +14,37 @@ generate iterators that multiply (or add to) the value returned by
dereferencing the iterator. It would be cooler to use lambda library
in this example.
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
const int N = sizeof(x)/sizeof(int);
typedef boost::binder1st< std::multiplies<int> > Function;
typedef boost::transform_iterator<Function, int*> doubling_iterator;
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
std::cout << "multiplying the array by 2:" << std::endl;
while (i != i_end)
std::cout << *i++ << " ";
std::cout << std::endl;
std::cout << "adding 4 to each element in the array:" << std::endl;
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
const int N = sizeof(x)/sizeof(int);
typedef boost::binder1st< std::multiplies<int> > Function;
typedef boost::transform_iterator<Function, int*> doubling_iterator;
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
std::cout << "multiplying the array by 2:" << std::endl;
while (i != i_end)
std::cout << *i++ << " ";
std::cout << std::endl;
std::cout << "adding 4 to each element in the array:" << std::endl;
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
The output is:
[pre
multiplying the array by 2:
2 4 6 8 10 12 14 16
adding 4 to each element in the array:
5 6 7 8 9 10 11 12
]
multiplying the array by 2:
2 4 6 8 10 12 14 16
adding 4 to each element in the array:
5 6 7 8 9 10 11 12
The source code for this example can be found
[example_link transform_iterator_example.cpp..here].
The source code for this example can be found
[@../example/transform_iterator_example.cpp here].
[h2 Reference]
@ -52,8 +52,8 @@ The source code for this example can be found
[h3 Synopsis]
template <class UnaryFunction,
class Iterator,
class Reference = use_default,
class Iterator,
class Reference = use_default,
class Value = use_default>
class transform_iterator
{
@ -85,8 +85,8 @@ The source code for this example can be found
If `Reference` is `use_default` then the `reference` member of
`transform_iterator` is[br]
`result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
`transform_iterator` is\n
`result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
Otherwise, `reference` is `Reference`.
@ -110,13 +110,13 @@ convertible to `input_iterator_tag`.
The type `UnaryFunction` must be Assignable, Copy Constructible, and
the expression `f(*i)` must be valid where `f` is a const object of
the expression `f(*i)` must be valid where `f` is an object of
type `UnaryFunction`, `i` is an object of type `Iterator`, and
where the type of `f(*i)` must be
`result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
`result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
The argument `Iterator` shall model Readable Iterator.
The argument `Iterator` shall model Readable Iterator.
[h3 Concepts]
@ -126,11 +126,11 @@ The resulting `transform_iterator` models the most refined of the
following that is also modeled by `Iterator`.
* Writable Lvalue Iterator if `transform_iterator::reference` is a non-const reference.
* Writable Lvalue Iterator if `transform_iterator::reference` is a non-const reference.
* Readable Lvalue Iterator if `transform_iterator::reference` is a const reference.
* Readable Iterator otherwise.
* Readable Iterator otherwise.
The `transform_iterator` models the most refined standard traversal
@ -143,11 +143,11 @@ the `Iterator` argument models.
[table Category
[[If `Iterator` models][then `transform_iterator` models]]
[[Single Pass Iterator][Input Iterator]]
[[Forward Traversal Iterator][Forward Iterator]]
[[Bidirectional Traversal Iterator][Bidirectional Iterator]]
[[Random Access Traversal Iterator][Random Access Iterator]]
[[If `Iterator` models][then `transform_iterator` models]]
[[Single Pass Iterator][Input Iterator]]
[[Forward Traversal Iterator][Forward Iterator]]
[[Bidirectional Traversal Iterator][Bidirectional Iterator]]
[[Random Access Traversal Iterator][Random Access Iterator]]
]
If `transform_iterator` models Writable Lvalue Iterator then it is a
@ -160,7 +160,7 @@ interoperable with `Y`.
[h3 Operations]
In addition to the operations required by the [link iterator.specialized.transform.concepts concepts] modeled by
In addition to the operations required by the [link transform.concepts concepts] modeled by
`transform_iterator`, `transform_iterator` provides the following
operations:
@ -177,13 +177,13 @@ operations:
template<class F2, class I2, class R2, class V2>
transform_iterator(
transform_iterator<F2, I2, R2, V2> const& t
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
, typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
);
[*Returns: ] An instance of `transform_iterator` with `m_f`
initialized to `t.functor()` and `m_iterator` initialized to
`t.base()`.[br]
`t.base()`.\n
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.
@ -204,13 +204,13 @@ operations:
transform_iterator& operator++();
[*Effects: ] `++m_iterator`[br]
[*Effects: ] `++m_iterator`\n
[*Returns: ] `*this`
transform_iterator& operator--();
[*Effects: ] `--m_iterator`[br]
[*Effects: ] `--m_iterator`\n
[*Returns: ] `*this`
[endsect]

View File

@ -1,211 +0,0 @@
[section:traits Type Traits]
[h2 Overview]
Have you ever wanted to write a generic function that can operate
on any kind of dereferenceable object? If you have, you've
probably run into the problem of how to determine the type that the
object "points at":
template <class Dereferenceable>
void f(Dereferenceable p)
{
*what-goes-here?* value = \*p;
...
}
[h2 `pointee`]
It turns out to be impossible to come up with a fully-general
algorithm to do determine *what-goes-here* directly, but it is
possible to require that `pointee<Dereferenceable>::type` is
correct. Naturally, `pointee` has the same difficulty: it can't
determine the appropriate `::type` reliably for all
`Dereferenceable`\ s, but it makes very good guesses (it works
for all pointers, standard and boost smart pointers, and
iterators), and when it guesses wrongly, it can be specialized as
necessary:
namespace boost
{
template <class T>
struct pointee<third_party_lib::smart_pointer<T> >
{
typedef T type;
};
}
[h2 `indirect_reference`]
`indirect_reference<T>::type` is rather more specialized than
`pointee`, and is meant to be used to forward the result of
dereferencing an object of its argument type. Most dereferenceable
types just return a reference to their pointee, but some return
proxy references or return the pointee by value. When that
information is needed, call on `indirect_reference`.
Both of these templates are essential to the correct functioning of
[link iterator.specialized.indirect `indirect_iterator`].
[h2 `minimum_category`]
`minimum_category` takes two iterator categories or two iterator traversal tags
and returns the one that is the weakest (i.e. least advanced). For example:
static_assert(
is_same<
minimum_category<
std::forward_iterator_tag,
std::random_access_iterator_tag
>::type,
std::forward_iterator_tag
>::value,
"Unexpected minimum_category result"
);
[h2 Iterator category and traversal tags manipulation]
The library provides several utilities to simplify conversions between iterator categories
and traversal tags:
* `iterator_category_to_traversal<C>::type` - the metafunction takes an iterator category `C` and returns
the corresponding traversal tag.
* `iterator_traversal<T>::type` - a shorthand for `iterator_category_to_traversal<iterator_category<T>::type>::type`.
* `pure_traversal_tag<T>::type` - the metafunction takes a tag `T` which derives from one of the iterator traversal tags
and returns that traversal tag. `T` may also derive from other tags describing the iterator (e.g. whether this is a `const`-iterator
or not), these additional tags are not considered.
* `pure_iterator_traversal<T>::type` - a shorthand for `pure_traversal_tag<iterator_traversal<T>::type>::type`.
[h2 Reference]
[h3 `pointee`]
template <class Dereferenceable>
struct pointee
{
typedef /* see below */ type;
};
[*Requires:] For an object `x` of type `Dereferenceable`, `*x`
is well-formed. If `++x` is ill-formed it shall neither be
ambiguous nor shall it violate access control, and
`Dereferenceable::element_type` shall be an accessible type.
Otherwise `iterator_traits<Dereferenceable>::value_type` shall
be well formed. \[Note: These requirements need not apply to
explicit or partial specializations of `pointee`\]
`type` is determined according to the following algorithm, where
`x` is an object of type `Dereferenceable`:
if ( ++x is ill-formed )
{
return Dereferenceable::element_type
}
else if (*x is a mutable reference to
std::iterator_traits<Dereferenceable>::value_type)
{
return iterator_traits<Dereferenceable>::value_type
}
else
{
return iterator_traits<Dereferenceable>::value_type const
}
[h3 `indirect_reference`]
template <class Dereferenceable>
struct indirect_reference
{
typedef /* see below */ type;
};
[*Requires:] For an object `x` of type `Dereferenceable`, `*x`
is well-formed. If `++x` is ill-formed it shall neither be
ambiguous nor shall it violate access control, and
`pointee<Dereferenceable>::type&` shall be well-formed.
Otherwise `iterator_traits<Dereferenceable>::reference` shall
be well formed. \[Note: These requirements need not apply to
explicit or partial specializations of `indirect_reference`\]
`type` is determined according to the following algorithm, where
`x` is an object of type `Dereferenceable`:
if ( ++x is ill-formed )
return pointee<Dereferenceable>::type&
else
std::iterator_traits<Dereferenceable>::reference
[h3 `minimum_category`]
template <typename C1, typename C2>
struct minimum_category
{
typedef /* see below */ type;
};
[*Requires:] Both `C1` and `C2` shall be standard iterator categories or
iterator traversal tags.
`type` is determined according to the following algorithm, where `c1` is an
object of type `C1` and `c2` is an object of type `C2`:
if (c1 is convertible to c2)
return C2;
else
return C1;
[note The above definition relies on the fact that the more restricting categories
and traversal tags are convertible to the less restricting ones.]
[h3 `iterator_category_to_traversal`]
template <typename C>
struct iterator_category_to_traversal
{
typedef /* see below */ type;
};
[*Requires:] `C` shall be a standard iterator category or an
iterator traversal tag.
If `C` is an iterator traversal tag or convertible to one, `type` equivalent to `C`.
Otherwise, `type` is defined to the closest iterator traversal tag matching `C`.
[h3 `iterator_traversal`]
template <typename Iterator>
struct iterator_traversal
{
typedef typename iterator_category_to_traversal<
typename iterator_category<Iterator>::type
>::type type;
};
[*Requires:] `Iterator` shall be an iterator.
[h3 `pure_traversal_tag`]
template <typename T>
struct pure_traversal_tag
{
typedef /* see below */ type;
};
[*Requires:] `T` shall be convertible to an iterator traversal tag.
`type` is defined to be the most advanced traversal tag `Tag` so that `T` is convertible to `Tag`.
[h3 `pure_iterator_traversal`]
template <typename Iterator>
struct pure_iterator_traversal
{
typedef typename pure_traversal_tag<
typename iterator_traversal<Iterator>::type
>::type type;
};
[*Requires:] `Iterator` shall be an iterator.
[endsect]

224
doc/quickbook/utilities.qbk Normal file
View File

@ -0,0 +1,224 @@
[section:utilities Iterator Utilities]
[section:utilities_traits Traits]
[h2 Overview]
Have you ever wanted to write a generic function that can operate
on any kind of dereferenceable object? If you have, you've
probably run into the problem of how to determine the type that the
object "points at":
template <class Dereferenceable>
void f(Dereferenceable p)
{
*what-goes-here?* value = \*p;
...
}
[h2 `pointee`]
It turns out to be impossible to come up with a fully-general
algorithm to do determine *what-goes-here* directly, but it is
possible to require that `pointee<Dereferenceable>::type` is
correct. Naturally, `pointee` has the same difficulty: it can't
determine the appropriate `::type` reliably for all
`Dereferenceable`\ s, but it makes very good guesses (it works
for all pointers, standard and boost smart pointers, and
iterators), and when it guesses wrongly, it can be specialized as
necessary:
namespace boost
{
template <class T>
struct pointee<third_party_lib::smart_pointer<T> >
{
typedef T type;
};
}
[h2 `indirect_reference`]
`indirect_reference<T>::type` is rather more specialized than
`pointee`, and is meant to be used to forward the result of
dereferencing an object of its argument type. Most dereferenceable
types just return a reference to their pointee, but some return
proxy references or return the pointee by value. When that
information is needed, call on `indirect_reference`.
Both of these templates are essential to the correct functioning of
[link indirecct `indirect_iterator`].
[h2 Reference]
[h3 `pointeee`]
template <class Dereferenceable>
struct pointee
{
typedef /* see below */ type;
};
[*Requires:] For an object `x` of type `Dereferenceable`, `*x`
is well-formed. If `++x` is ill-formed it shall neither be
ambiguous nor shall it violate access control, and
`Dereferenceable::element_type` shall be an accessible type.
Otherwise `iterator_traits<Dereferenceable>::value_type` shall
be well formed. \[Note: These requirements need not apply to
explicit or partial specializations of `pointee`\]
`type` is determined according to the following algorithm, where
`x` is an object of type `Dereferenceable`:
if ( ++x is ill-formed )
{
return `Dereferenceable::element_type`
}
else if (`*x` is a mutable reference to
std::iterator_traits<Dereferenceable>::value_type)
{
return iterator_traits<Dereferenceable>::value_type
}
else
{
return iterator_traits<Dereferenceable>::value_type const
}
[h3 `indirect_reference`]
template <class Dereferenceable>
struct indirect_reference
{
typedef /* see below */ type;
};
[*Requires:] For an object `x` of type `Dereferenceable`, `*x`
is well-formed. If `++x` is ill-formed it shall neither be
ambiguous nor shall it violate access control, and
`pointee<Dereferenceable>::type&` shall be well-formed.
Otherwise `iterator_traits<Dereferenceable>::reference` shall
be well formed. \[Note: These requirements need not apply to
explicit or partial specializations of `indirect_reference`\]
`type` is determined according to the following algorithm, where
`x` is an object of type `Dereferenceable`:
if ( ++x is ill-formed )
return `pointee<Dereferenceable>::type&`
else
std::iterator_traits<Dereferenceable>::reference
[endsect]
[section:utilities_testing Testing and Concept Checking]
The iterator concept checking classes provide a mechanism for a
template to report better error messages when a user instantiates
the template with a type that does not meet the requirements of the
template.
For an introduction to using concept checking classes, see
the documentation for the
[@../../concept_check/index.html `boost::concept_check`] library.
[h2 Reference]
[h3 Iterator Access Concepts]
* |Readable|_
* |Writable|_
* |Swappable|_
* |Lvalue|_
[/ .. |Readable| replace:: *Readable Iterator* ]
[/ .. _Readable: ReadableIterator.html ]
[/ ]
[/ .. |Writable| replace:: *Writable Iterator* ]
[/ .. _Writable: WritableIterator.html ]
[/ ]
[/ .. |Swappable| replace:: *Swappable Iterator* ]
[/ .. _Swappable: SwappableIterator.html ]
[/ ]
[/ .. |Lvalue| replace:: *Lvalue Iterator* ]
[/ .. _Lvalue: LvalueIterator.html ]
Iterator Traversal Concepts
...........................
* |Incrementable|_
* |SinglePass|_
* |Forward|_
* |Bidir|_
* |Random|_
[/ .. |Incrementable| replace:: *Incrementable Iterator* ]
[/ .. _Incrementable: IncrementableIterator.html ]
[/ ]
[/ .. |SinglePass| replace:: *Single Pass Iterator* ]
[/ .. _SinglePass: SinglePassIterator.html ]
[/ ]
[/ .. |Forward| replace:: *Forward Traversal* ]
[/ .. _Forward: ForwardTraversal.html ]
[/ ]
[/ .. |Bidir| replace:: *Bidirectional Traversal* ]
[/ .. _Bidir: BidirectionalTraversal.html ]
[/ ]
[/ .. |Random| replace:: *Random Access Traversal* ]
[/ .. _Random: RandomAccessTraversal.html ]
[h3 `iterator_concepts.hpp` Synopsis]
namespace boost_concepts {
// Iterator Access Concepts
template <typename Iterator>
class ReadableIteratorConcept;
template <
typename Iterator
, typename ValueType = std::iterator_traits<Iterator>::value_type
>
class WritableIteratorConcept;
template <typename Iterator>
class SwappableIteratorConcept;
template <typename Iterator>
class LvalueIteratorConcept;
// Iterator Traversal Concepts
template <typename Iterator>
class IncrementableIteratorConcept;
template <typename Iterator>
class SinglePassIteratorConcept;
template <typename Iterator>
class ForwardTraversalConcept;
template <typename Iterator>
class BidirectionalTraversalConcept;
template <typename Iterator>
class RandomAccessTraversalConcept;
// Interoperability
template <typename Iterator, typename ConstIterator>
class InteroperableIteratorConcept;
}
[endsect]
[endsect]

View File

@ -1,29 +1,20 @@
[section:zip Zip Iterator]
The zip iterator provides the ability to parallel-iterate
over several controlled sequences simultaneously. A zip
over several controlled sequences simultaneously. A zip
iterator is constructed from a tuple of iterators. Moving
the zip iterator moves all the iterators in parallel.
Dereferencing the zip iterator returns a tuple that contains
the results of dereferencing the individual iterators.
The tuple of iterators is now implemented in terms of a Boost fusion sequence.
Because of this the 'tuple' may be any Boost fusion sequence and, for backwards
compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
Boost fusion adapter exists. This includes, among others, a std::tuple and a std::pair.
Just remember to include the appropriate Boost fusion adapter header files for these
other Boost fusion adapters. The zip_iterator header file already includes the
Boost fusion adapter header file for Boost tuple, so you need not include it yourself
to use a Boost tuple as your 'tuple'.
the results of dereferencing the individual iterators.
[section:zip_example Example]
There are two main types of applications of the `zip_iterator`. The first
one concerns runtime efficiency: If one has several controlled sequences
of the same length that must be somehow processed, e.g., with the
of the same length that must be somehow processed, e.g., with the
`for_each` algorithm, then it is more efficient to perform just
one parallel-iteration rather than several individual iterations. For an
one parallel-iteration rather than several individual iterations. For an
example, assume that `vect_of_doubles` and `vect_of_ints`
are two vectors of equal length containing doubles and ints, respectively,
and consider the following two iterations:
@ -52,7 +43,7 @@ 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 :
struct zip_func :
public std::unary_function<const boost::tuple<const double&, const int&>&, void>
{
void operator()(const boost::tuple<const double&, const int&>& t) const
@ -71,16 +62,16 @@ to make combining iterators. A combining iterator is an iterator
that parallel-iterates over several controlled sequences and, upon
dereferencing, returns the result of applying a functor to the values of the
sequences at the respective positions. This can now be achieved by using the
`zip_iterator` in conjunction with the `transform_iterator`.
`zip_iterator` in conjunction with the `transform_iterator`.
Suppose, for example, that you have two vectors of doubles, say
Suppose, for example, that you have two vectors of doubles, say
`vect_1` and `vect_2`, and you need to expose to a client
a controlled sequence containing the products of the elements of
a controlled sequence containing the products of the elements of
`vect_1` and `vect_2`. Rather than placing these products
in a third vector, you can use a combining iterator that calculates the
products on the fly. Let us assume that `tuple_multiplies` is a
functor that works like `std::multiplies`, except that it takes
its two arguments packaged in a tuple. Then the two iterators
its two arguments packaged in a tuple. Then the two iterators
`it_begin` and `it_end` defined below delimit a controlled
sequence containing the products of the elements of `vect_1` and
`vect_2`:
@ -127,7 +118,7 @@ sequence containing the products of the elements of `vect_1` and
template<typename IteratorTuple>
class zip_iterator
{
{
public:
typedef /* see below */ reference;
@ -153,8 +144,8 @@ sequence containing the products of the elements of `vect_1` and
IteratorTuple m_iterator_tuple; // exposition only
};
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
make_zip_iterator(IteratorTuple t);
The `reference` member of `zip_iterator` is the type of the tuple
@ -167,23 +158,23 @@ of the first of the iterator types in the `IteratorTuple` argument.
The `iterator_category` member of `zip_iterator` is convertible to the
minimum of the traversal categories of the iterator types in the `IteratorTuple`
argument. For example, if the `zip_iterator` holds only vector
iterators, then `iterator_category` is convertible to
iterators, then `iterator_category` is convertible to
`boost::random_access_traversal_tag`. If you add a list iterator, then
`iterator_category` will be convertible to `boost::bidirectional_traversal_tag`,
but no longer to `boost::random_access_traversal_tag`.
[h2 Requirements]
All iterator types in the argument `IteratorTuple` shall model Readable Iterator.
All iterator types in the argument `IteratorTuple` shall model Readable Iterator.
[h2 Concepts]
The resulting `zip_iterator` models Readable Iterator.
The fact that the `zip_iterator` models only Readable Iterator does not
The fact that the `zip_iterator` models only Readable Iterator does not
prevent you from modifying the values that the individual iterators point
to. The tuple returned by the `zip_iterator`'s `operator*` is a tuple
constructed from the reference types of the individual iterators, not
to. The tuple returned by the `zip_iterator`'s `operator*` is a tuple
constructed from the reference types of the individual iterators, not
their value types. For example, if `zip_it` is a `zip_iterator` whose
first member iterator is an `std::vector<double>::iterator`, then the
following line will modify the value which the first member iterator of
@ -194,7 +185,7 @@ following line will modify the value which the first member iterator of
Consider the set of standard traversal concepts obtained by taking
the most refined standard traversal concept modeled by each individual
iterator type in the `IteratorTuple` argument.The `zip_iterator`
iterator type in the `IteratorTuple` argument.The `zip_iterator`
models the least refined standard traversal concept in this set.
`zip_iterator<IteratorTuple1>` is interoperable with
@ -227,7 +218,7 @@ operations.
, IteratorTuple>::type* = 0 // exposition only
);
[*Returns:] An instance of `zip_iterator` that is a copy of `other`.[br]
[*Returns:] An instance of `zip_iterator` that is a copy of `other`.\n
[*Requires:] `OtherIteratorTuple` is implicitly convertible to `IteratorTuple`.
@ -244,17 +235,17 @@ operations.
zip_iterator& operator++();
[*Effects:] Increments each iterator in `m_iterator_tuple`.[br]
[*Effects:] Increments each iterator in `m_iterator_tuple`.\n
[*Returns:] `*this`
zip_iterator& operator--();
[*Effects:] Decrements each iterator in `m_iterator_tuple`.[br]
[*Effects:] Decrements each iterator in `m_iterator_tuple`.\n
[*Returns:] `*this`
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
make_zip_iterator(IteratorTuple t);
[*Returns:] An instance of `zip_iterator<IteratorTuple>` with `m_iterator_tuple`
@ -262,4 +253,4 @@ operations.
[endsect]
[endsect]
[endsect]

View File

@ -3,7 +3,7 @@
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. _N1550: http://www.boost-consulting.com/writing/n1550.html
.. _N1530: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1530.html
.. _N1530: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1530.html
:Author: David Abrahams and Jeremy Siek
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu

View File

@ -99,7 +99,7 @@ private:
</pre>
<p>If <tt class="docutils literal"><span class="pre">Reference</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">reference</span></tt> member of
<tt class="docutils literal"><span class="pre">transform_iterator</span></tt> is
<tt class="docutils literal"><span class="pre">result_of&lt;const UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.
<tt class="docutils literal"><span class="pre">result_of&lt;UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.
Otherwise, <tt class="docutils literal"><span class="pre">reference</span></tt> is <tt class="docutils literal"><span class="pre">Reference</span></tt>.</p>
<p>If <tt class="docutils literal"><span class="pre">Value</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">value_type</span></tt> member is
<tt class="docutils literal"><span class="pre">remove_cv&lt;remove_reference&lt;reference&gt;</span> <span class="pre">&gt;::type</span></tt>. Otherwise,
@ -117,10 +117,10 @@ convertible to <tt class="docutils literal"><span class="pre">input_iterator_tag
<div class="section" id="transform-iterator-requirements">
<h1><a class="toc-backref" href="#id3"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
<p>The type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and
the expression <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be valid where <tt class="docutils literal"><span class="pre">f</span></tt> is a const object of
the expression <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be valid where <tt class="docutils literal"><span class="pre">f</span></tt> is an object of
type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt>, <tt class="docutils literal"><span class="pre">i</span></tt> is an object of type <tt class="docutils literal"><span class="pre">Iterator</span></tt>, and
where the type of <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be
<tt class="docutils literal"><span class="pre">result_of&lt;const UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.</p>
<tt class="docutils literal"><span class="pre">result_of&lt;UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.</p>
<p>The argument <tt class="docutils literal"><span class="pre">Iterator</span></tt> shall model Readable Iterator.</p>
</div>
<div class="section" id="transform-iterator-models">

View File

@ -41,7 +41,7 @@
If ``Reference`` is ``use_default`` then the ``reference`` member of
``transform_iterator`` is
``result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
Otherwise, ``reference`` is ``Reference``.
If ``Value`` is ``use_default`` then the ``value_type`` member is
@ -64,10 +64,10 @@ convertible to ``input_iterator_tag``.
...................................
The type ``UnaryFunction`` must be Assignable, Copy Constructible, and
the expression ``f(*i)`` must be valid where ``f`` is a const object of
the expression ``f(*i)`` must be valid where ``f`` is an object of
type ``UnaryFunction``, ``i`` is an object of type ``Iterator``, and
where the type of ``f(*i)`` must be
``result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
The argument ``Iterator`` shall model Readable Iterator.

View File

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

View File

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

View File

@ -41,12 +41,12 @@ int main(int, char*[])
// Use indirect iterator to print out numbers by accessing
// them through the array of pointers.
std::cout << "indirectly printing out the numbers from 0 to "
std::cout << "indirectly printing out the numbers from 0 to "
<< N << std::endl;
std::copy(boost::make_indirect_iterator(pointers.begin()),
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return boost::exit_success;
}

View File

@ -8,7 +8,6 @@
#include <functional>
#include <iostream>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/bind/bind.hpp>
#include <boost/cstdlib.hpp> // for exit_success
struct is_positive_number {
@ -19,10 +18,10 @@ int main()
{
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
const int N = sizeof(numbers_)/sizeof(int);
typedef int* base_iterator;
base_iterator numbers(numbers_);
// Example using make_filter_iterator()
std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
@ -32,7 +31,7 @@ int main()
// Example using filter_iterator
typedef boost::filter_iterator<is_positive_number, base_iterator>
FilterIter;
is_positive_number predicate;
FilterIter filter_iter_first(predicate, numbers, numbers + N);
FilterIter filter_iter_last(predicate, numbers + N, numbers + N);
@ -43,17 +42,17 @@ int main()
// Another example using make_filter_iterator()
std::copy(
boost::make_filter_iterator(
boost::bind(std::greater<int>(), boost::placeholders::_1, -2)
std::bind2nd(std::greater<int>(), -2)
, numbers, numbers + N)
, boost::make_filter_iterator(
boost::bind(std::greater<int>(), boost::placeholders::_1, -2)
std::bind2nd(std::greater<int>(), -2)
, numbers + N, numbers + N)
, std::ostream_iterator<int>(std::cout, " ")
);
std::cout << std::endl;
return boost::exit_success;
}

View File

@ -12,14 +12,14 @@
#include <string>
#include <vector>
#include <boost/iterator/function_output_iterator.hpp>
#include <boost/function_output_iterator.hpp>
struct string_appender
{
string_appender(std::string& s)
: m_str(&s)
{}
void operator()(const std::string& x) const
{
*m_str += x;
@ -37,9 +37,9 @@ int main(int, char*[])
x.push_back("!");
std::string s = "";
std::copy(x.begin(), x.end(),
std::copy(x.begin(), x.end(),
boost::make_function_output_iterator(string_appender(s)));
std::cout << s << std::endl;
return 0;

View File

@ -9,7 +9,6 @@
#include <iterator>
#include <functional>
#include <algorithm>
#include <boost/bind/bind.hpp>
#include <boost/iterator/indirect_iterator.hpp>
int main(int, char*[])
@ -21,13 +20,13 @@ int main(int, char*[])
pointers_to_chars[i] = &characters[i];
// Example of using indirect_iterator
boost::indirect_iterator<char**, char>
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
// Example of making mutable and constant indirect iterators
@ -42,19 +41,19 @@ int main(int, char*[])
const_indirect_last(pointers_to_chars + N);
std::transform(const_indirect_first, const_indirect_last,
mutable_indirect_first, boost::bind(std::plus<char>(), 1, boost::placeholders::_1));
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
std::copy(mutable_indirect_first, mutable_indirect_last,
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
// Example of using make_indirect_iterator()
std::copy(boost::make_indirect_iterator(pointers_to_chars),
std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
return 0;
}

View File

@ -24,7 +24,7 @@ struct node_base
virtual void print(std::ostream& s) const = 0;
virtual void double_me() = 0;
void append(node_base* p)
{
if (m_next)
@ -32,7 +32,7 @@ struct node_base
else
m_next = p;
}
private:
node_base* m_next;
};
@ -52,9 +52,9 @@ struct node : node_base
void print(std::ostream& s) const { s << this->m_value; }
void double_me() { m_value += m_value; }
private:
T m_value;
};
#endif // NODE_DWA2004110_HPP

View File

@ -11,17 +11,7 @@
int main()
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<node<int> > nodes(new node<int>(42));
#else
std::unique_ptr<node<int> > nodes(new node<int>(42));
#endif
nodes->append(new node<std::string>(" is greater than "));
nodes->append(new node<int>(13));
@ -30,7 +20,7 @@ int main()
, std::ostream_iterator<node_base>(std::cout, " ")
);
std::cout << std::endl;
std::for_each(
node_iterator(nodes.get()), node_iterator()
, std::mem_fun_ref(&node_base::double_me)

View File

@ -28,10 +28,10 @@ class node_iterator
void increment()
{ m_node = m_node->next(); }
bool equal(node_iterator const& other) const
{ return this->m_node == other.m_node; }
node_base& dereference() const
{ return *m_node; }

View File

@ -12,33 +12,23 @@
int main()
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<node<int> > nodes(new node<int>(42));
#else
std::unique_ptr<node<int> > nodes(new node<int>(42));
#endif
nodes->append(new node<std::string>(" is greater than "));
nodes->append(new node<int>(13));
// Check interoperability
assert(node_iterator(nodes.get()) == node_const_iterator(nodes.get()));
assert(node_const_iterator(nodes.get()) == node_iterator(nodes.get()));
assert(node_iterator(nodes.get()) != node_const_iterator());
assert(node_const_iterator(nodes.get()) != node_iterator());
std::copy(
node_iterator(nodes.get()), node_iterator()
, std::ostream_iterator<node_base>(std::cout, " ")
);
std::cout << std::endl;
std::for_each(
node_iterator(nodes.get()), node_iterator()
, boost::mem_fn(&node_base::double_me)

View File

@ -38,15 +38,15 @@ class node_iter
boost::is_convertible<OtherValue*,Value*>
, enabler
>::type = enabler()
# endif
# endif
)
: m_node(other.m_node) {}
# if !BOOST_WORKAROUND(__GNUC__, == 2)
private: // GCC2 can't grant friendship to template member functions
private: // GCC2 can't grant friendship to template member functions
friend class boost::iterator_core_access;
# endif
# endif
template <class OtherValue>
bool equal(node_iter<OtherValue> const& other) const
@ -63,7 +63,7 @@ class node_iter
# else
private:
template <class> friend class node_iter;
# endif
# endif
Value* m_node;
};

View File

@ -12,33 +12,23 @@
int main()
{
#if defined(BOOST_NO_CXX11_SMART_PTR)
std::auto_ptr<node<int> > nodes(new node<int>(42));
#else
std::unique_ptr<node<int> > nodes(new node<int>(42));
#endif
nodes->append(new node<std::string>(" is greater than "));
nodes->append(new node<int>(13));
// Check interoperability
assert(node_iterator(nodes.get()) == node_const_iterator(nodes.get()));
assert(node_const_iterator(nodes.get()) == node_iterator(nodes.get()));
assert(node_iterator(nodes.get()) != node_const_iterator());
assert(node_const_iterator(nodes.get()) != node_iterator());
std::copy(
node_iterator(nodes.get()), node_iterator()
, std::ostream_iterator<node_base>(std::cout, " ")
);
std::cout << std::endl;
std::for_each(
node_iterator(nodes.get()), node_iterator()
, boost::mem_fn(&node_base::double_me)

View File

@ -27,7 +27,7 @@ class node_iter
typedef boost::iterator_adaptor<
node_iter<Value>, Value*, boost::use_default, boost::forward_traversal_tag
> super_t;
public:
node_iter()
: super_t(0) {}
@ -43,14 +43,14 @@ class node_iter
boost::is_convertible<OtherValue*,Value*>
, enabler
>::type = enabler()
# endif
# endif
)
: super_t(other.base()) {}
# if !BOOST_WORKAROUND(__GNUC__, == 2)
private: // GCC2 can't grant friendship to template member functions
private: // GCC2 can't grant friendship to template member functions
friend class boost::iterator_core_access;
# endif
# endif
void increment() { this->base_reference() = this->base()->next(); }
};

View File

@ -27,7 +27,7 @@ int main() {
*el_it = std::distance(elements.begin(), el_it);
index_type indices( index_size );
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
*i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
std::reverse( indices.begin(), indices.end() );

View File

@ -15,13 +15,13 @@ int main(int, char*[])
const int N = sizeof(letters_)/sizeof(char) - 1;
typedef char* base_iterator;
base_iterator letters(letters_);
std::cout << "original sequence of letters:\t\t\t"
<< letters_ << std::endl;
// Use reverse_iterator to print a sequence of letters in reverse
// order.
boost::reverse_iterator<base_iterator>
reverse_letters_first(letters + N),
reverse_letters_last(letters);

View File

@ -1,42 +0,0 @@
// Copyright 2003 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <algorithm>
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
void set_range(iterator& i, iterator& end) {
boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
i = iterator(ints->begin(),ints);
end = iterator(ints->end(),ints);
}
int main() {
iterator i,end;
set_range(i,end);
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}

View File

@ -1,43 +0,0 @@
// Copyright 2003 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
template <typename Iterator>
void print_range_nl (Iterator begin, Iterator end) {
typedef typename std::iterator_traits<Iterator>::value_type val;
std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
std::cout.put('\n');
}
int main() {
typedef boost::shared_ptr< std::vector<int> > ints_t;
{
ints_t ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
boost::make_shared_container_iterator(ints->end(),ints));
}
return 0;
}

View File

@ -1,41 +0,0 @@
// Copyright 2003 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/tuple/tuple.hpp" // for boost::tie
#include <algorithm> // for std::copy
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
std::pair<iterator,iterator>
return_range() {
boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
range->push_back(0);
range->push_back(1);
range->push_back(2);
range->push_back(3);
range->push_back(4);
range->push_back(5);
return boost::make_shared_container_range(range);
}
int main() {
iterator i,end;
boost::tie(i,end) = return_range();
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}

View File

@ -1,4 +1,4 @@
// (C) Copyright Jeremy Siek 2000-2004.
// (C) Copyright Jeremy Siek 2000-2004.
// 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)
@ -15,11 +15,10 @@
namespace boost {
template <class Operation>
class binder1st {
public:
typedef typename Operation::result_type result_type;
typedef typename Operation::second_argument_type argument_type;
template <class Operation>
class binder1st
: public std::unary_function<typename Operation::second_argument_type,
typename Operation::result_type> {
protected:
Operation op;
typename Operation::first_argument_type value;
@ -30,7 +29,7 @@ namespace boost {
: op(x), value(y) {}
typename Operation::result_type
operator()(const typename Operation::second_argument_type& x) const {
return op(value, x);
return op(value, x);
}
};
@ -70,6 +69,8 @@ main(int, char*[])
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}

View File

@ -1,18 +1,56 @@
// (C) Copyright Andrey Semashev 2017.
// (C) Copyright Jeremy Siek 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:
// 27 Feb 2001 Jeremy Siek
// Initial checkin.
#ifndef BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
#define BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
// This is a deprecated header left for backward compatibility.
// Use boost/iterator/function_output_iterator.hpp instead.
#include <iterator>
#include <boost/config/header_deprecated.hpp>
namespace boost {
BOOST_HEADER_DEPRECATED("<boost/iterator/function_output_iterator.hpp>")
template <class UnaryFunction>
class function_output_iterator {
typedef function_output_iterator self;
public:
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
#include <boost/iterator/function_output_iterator.hpp>
explicit function_output_iterator() {}
explicit function_output_iterator(const UnaryFunction& f)
: m_f(f) {}
struct output_proxy {
output_proxy(UnaryFunction& f) : m_f(f) { }
template <class T> output_proxy& operator=(const T& value) {
m_f(value);
return *this;
}
UnaryFunction& m_f;
};
output_proxy operator*() { return output_proxy(m_f); }
self& operator++() { return *this; }
self& operator++(int) { return *this; }
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);
}
} // namespace boost
#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP

View File

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

View File

@ -1,43 +0,0 @@
#ifndef INDIRECT_REFERENCE_DWA200415_HPP
# define INDIRECT_REFERENCE_DWA200415_HPP
//
// Copyright David Abrahams 2004. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// typename indirect_reference<P>::type provides the type of *p.
//
// http://www.boost.org/libs/iterator/doc/pointee.html
//
# include <boost/detail/is_incrementable.hpp>
# include <boost/iterator/iterator_traits.hpp>
# include <boost/type_traits/remove_cv.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/pointee.hpp>
namespace boost {
namespace detail
{
template <class P>
struct smart_ptr_reference
{
typedef typename boost::pointee<P>::type& type;
};
}
template <class P>
struct indirect_reference
: mpl::eval_if<
detail::is_incrementable<P>
, iterator_reference<P>
, detail::smart_ptr_reference<P>
>
{
};
} // namespace boost
#endif // INDIRECT_REFERENCE_DWA200415_HPP

View File

@ -0,0 +1,59 @@
// iterator.hpp workarounds for non-conforming standard libraries ---------//
// (C) Copyright Beman Dawes 2000. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/utility for documentation.
// Revision History
// 12 Jan 01 added <cstddef> for std::ptrdiff_t (Jens Maurer)
// 28 Jun 00 Workarounds to deal with known MSVC bugs (David Abrahams)
// 26 Jun 00 Initial version (Jeremy Siek)
#ifndef BOOST_ITERATOR_HPP
#define BOOST_ITERATOR_HPP
#include <iterator>
#include <cstddef> // std::ptrdiff_t
#include <boost/config.hpp>
namespace boost
{
# if defined(BOOST_NO_STD_ITERATOR) && !defined(BOOST_MSVC_STD_ITERATOR)
template <class Category, class T,
class Distance = std::ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator
{
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef Category iterator_category;
};
# else
// declare iterator_base in namespace detail to work around MSVC bugs which
// prevent derivation from an identically-named class in a different namespace.
namespace detail {
template <class Category, class T, class Distance, class Pointer, class Reference>
# if !defined(BOOST_MSVC_STD_ITERATOR)
struct iterator_base : std::iterator<Category, T, Distance, Pointer, Reference> {};
# else
struct iterator_base : std::iterator<Category, T, Distance>
{
typedef Reference reference;
typedef Pointer pointer;
typedef Distance difference_type;
};
# endif
}
template <class Category, class T, class Distance = std::ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator : boost::detail::iterator_base<Category, T, Distance, Pointer, Reference> {};
# endif
} // namespace boost
#endif // BOOST_ITERATOR_HPP

View File

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

View File

@ -5,24 +5,14 @@
#ifndef COUNTING_ITERATOR_DWA200348_HPP
# define 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 <boost/detail/numeric_traits.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/eval_if.hpp>
namespace boost {
namespace iterators {
template <
class Incrementable
@ -40,98 +30,75 @@ namespace detail
{
// 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);
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
# else
# if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
# if !BOOST_WORKAROUND(__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);
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
# endif
# endif
};
template <class T>
struct is_numeric
: boost::integral_constant<bool, ::boost::iterators::detail::is_numeric_impl<T>::value>
: mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
{};
# if defined(BOOST_HAS_LONG_LONG)
template <>
struct is_numeric<boost::long_long_type>
: boost::true_type {};
struct is_numeric< ::boost::long_long_type>
: mpl::true_ {};
template <>
struct is_numeric<boost::ulong_long_type>
: boost::true_type {};
# endif
# if defined(BOOST_HAS_INT128)
template <>
struct is_numeric<boost::int128_type>
: boost::true_type {};
template <>
struct is_numeric<boost::uint128_type>
: boost::true_type {};
struct is_numeric< ::boost::ulong_long_type>
: mpl::true_ {};
# endif
// Some compilers fail to have a numeric_limits specialization
template <>
struct is_numeric<wchar_t>
: true_type {};
: mpl::true_ {};
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
BOOST_STATIC_ASSERT(is_numeric<int>::value);
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>
, mpl::eval_if<
is_numeric<Incrementable>
, mpl::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
, mpl::eval_if<
is_numeric<Incrementable>
, numeric_difference<Incrementable>
, iterator_difference<Incrementable>
>::type
>
>::type difference;
typedef iterator_adaptor<
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
, Incrementable // Base
@ -139,7 +106,7 @@ namespace detail
# 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
# endif
, traversal
, Incrementable const& // reference
, difference
@ -169,7 +136,7 @@ namespace detail
{
static Difference distance(Incrementable1 x, Incrementable2 y)
{
return boost::detail::numeric_distance(x, y);
return numeric_distance(x, y);
}
};
}
@ -187,15 +154,15 @@ class counting_iterator
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;
BOOST_DEFAULTED_FUNCTION(counting_iterator(), {})
BOOST_DEFAULTED_FUNCTION(counting_iterator(counting_iterator const& rhs), : super_t(rhs.base()) {})
counting_iterator() { }
counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
counting_iterator(Incrementable x)
: super_t(x)
@ -210,12 +177,10 @@ class counting_iterator
)
: 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; })
# endif
private:
typename super_t::reference dereference() const
{
return this->base_reference();
@ -225,13 +190,13 @@ class counting_iterator
difference_type
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;
typedef typename mpl::if_<
detail::is_numeric<Incrementable>
, detail::number_distance<difference_type, Incrementable, OtherIncrementable>
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
>::type d;
return d::distance(this->base(), y.base());
return d::distance(this->base(), y.base());
}
};
@ -240,15 +205,11 @@ template <class Incrementable>
inline counting_iterator<Incrementable>
make_counting_iterator(Incrementable x)
{
typedef counting_iterator<Incrementable> result_t;
return result_t(x);
typedef counting_iterator<Incrementable> result_t;
return result_t(x);
}
} // namespace iterators
using iterators::counting_iterator;
using iterators::make_counting_iterator;
} // namespace boost
} // namespace boost::iterator
#endif // COUNTING_ITERATOR_DWA200348_HPP

View File

@ -4,9 +4,7 @@
#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP
# define ANY_CONVERSION_EATER_DWA20031117_HPP
namespace boost {
namespace iterators {
namespace detail {
namespace boost { namespace detail {
// This type can be used in traits to "eat" up the one user-defined
// implicit conversion allowed.
@ -16,6 +14,6 @@ struct any_conversion_eater
any_conversion_eater(T const&);
};
}}} // namespace boost::iterators::detail
}} // namespace boost::detail
#endif // ANY_CONVERSION_EATER_DWA20031117_HPP

View File

@ -18,16 +18,16 @@
#ifdef BOOST_ITERATOR_CONFIG_DEF
# error you have nested config_def #inclusion.
#else
#else
# define BOOST_ITERATOR_CONFIG_DEF
#endif
#endif
// We enable this always now. Otherwise, the simple case in
// 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))
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
// Recall that in general, compilers without partial specialization
// can't strip constness. Consider counting_iterator, which normally
@ -46,11 +46,12 @@
#endif
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x5A0)) \
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|| BOOST_WORKAROUND(__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
@ -79,7 +80,7 @@
int z2[(lvalue_deref_helper<v*>::value == 1) ? 1 : -1];
int z[(lvalue_deref_helper<value_iterator>::value) == 1 ? -1 : 1 ];
# endif
# endif
#endif
@ -87,8 +88,9 @@
# 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))
#if BOOST_WORKAROUND(__GNUC__, == 2) \
|| BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
# define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile:
# if 0 // test code
@ -112,17 +114,24 @@
#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
#endif
# if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
# define BOOST_ARG_DEPENDENT_TYPENAME typename
# else
# define BOOST_ARG_DEPENDENT_TYPENAME
# endif
// GCC-2.95 (obsolete) eagerly instantiates templated constructors and conversion
# if BOOST_WORKAROUND(__GNUC__, == 2) && BOOST_WORKAROUND(__GNUC_MINOR__, BOOST_TESTED_AT(95)) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// GCC-2.95 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
# endif
// no include guard; multiple inclusion intended

View File

@ -14,6 +14,7 @@
#undef BOOST_NO_IS_CONVERTIBLE
#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
#undef BOOST_ARG_DEPENDENT_TYPENAME
#undef BOOST_NO_LVALUE_RETURN_DETECTION
#undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
@ -21,4 +22,4 @@
# undef BOOST_ITERATOR_CONFIG_DEF
#else
# error missing or nested #include config_def
#endif
#endif

View File

@ -7,11 +7,10 @@
#ifndef BOOST_ENABLE_IF_23022003THW_HPP
#define BOOST_ENABLE_IF_23022003THW_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/identity.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
@ -36,7 +35,7 @@ namespace boost
typedef T type;
};
};
//
// For compilers that don't support "Substitution Failure Is Not An Error"
// enable_if falls back to always enabled. See comments
@ -49,6 +48,7 @@ namespace boost
struct base
{
#ifdef BOOST_NO_SFINAE
typedef T type;
// This way to do it would give a nice error message containing
@ -69,9 +69,12 @@ namespace boost
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
: enabled<(Cond::value)>::template base<Return>
# else
: boost::type_identity<Return>
# endif
: mpl::identity<Return>
# endif
{
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
typedef Return type;
# endif
};
} // namespace iterators

View File

@ -4,8 +4,6 @@
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
# include <boost/core/use_default.hpp>
# include <boost/iterator/iterator_categories.hpp>
# include <boost/mpl/or.hpp> // used in iterator_tag inheritance logic
@ -32,12 +30,10 @@
// iterator_category deduction for iterator_facade
//
namespace boost {
namespace iterators {
// forward declaration
namespace boost { struct use_default; }
using boost::use_default;
namespace detail {
namespace boost { namespace detail {
struct input_output_iterator_tag
: std::input_iterator_tag
@ -67,9 +63,9 @@ struct iterator_writability_disabled
, boost::detail::indirect_traits::is_reference_to_const<Reference>
, is_const<ValueParam>
>
# else
# else
: is_const<ValueParam>
# endif
# endif
{};
@ -77,10 +73,16 @@ struct iterator_writability_disabled
// Convert an iterator_facade's traversal category, Value parameter,
// and ::reference type to an appropriate old-style category.
//
// Due to changeset 21683, this now never results in a category convertible
// to output_iterator_tag.
// If writability has been disabled per the above metafunction, the
// result will not be convertible to output_iterator_tag.
//
// Otherwise, if Traversal == single_pass_traversal_tag, the following
// conditions will result in a tag that is convertible both to
// input_iterator_tag and output_iterator_tag:
//
// 1. Reference is a reference to non-const
// 2. Reference is not a reference and is convertible to Value
//
// Change at: https://svn.boost.org/trac/boost/changeset/21683
template <class Traversal, class ValueParam, class Reference>
struct iterator_facade_default_category
: mpl::eval_if<
@ -100,7 +102,7 @@ struct iterator_facade_default_category
, typename mpl::eval_if<
mpl::and_<
is_convertible<Traversal, single_pass_traversal_tag>
// check for readability
, is_convertible<Reference, ValueParam>
>
@ -136,6 +138,7 @@ template <class Category, class Traversal>
struct iterator_category_with_traversal
: Category, Traversal
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// 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.
@ -150,7 +153,8 @@ struct iterator_category_with_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
# endif
# endif
};
// Computes an iterator_category tag whose traversal is Traversal and
@ -158,12 +162,14 @@ struct iterator_category_with_traversal
template <class Traversal, class ValueParam, class Reference>
struct facade_iterator_category_impl
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
# endif
typedef typename iterator_facade_default_category<
Traversal,ValueParam,Reference
>::type category;
typedef typename mpl::if_<
is_same<
Traversal
@ -187,7 +193,7 @@ struct facade_iterator_category
{
};
}}} // namespace boost::iterators::detail
}} // namespace boost::detail
# include <boost/iterator/detail/config_undef.hpp>

View File

@ -4,16 +4,113 @@
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP
# define MINIMUM_CATEGORY_DWA20031119_HPP
# include <boost/iterator/minimum_category.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_same.hpp>
namespace boost {
# include <boost/mpl/aux_/lambda_support.hpp>
// 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 { namespace detail {
//
// Returns the minimum category type or error_type
// if T1 and T2 are unrelated.
//
// For compilers not supporting is_convertible this only
// works with the new boost return and traversal category
// types. The exact boost _types_ are required. No derived types
// will work.
//
//
template <bool GreaterEqual, bool LessEqual>
struct minimum_category_impl
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
{
template <class T1, class T2> struct apply
{
typedef T2 type;
};
typedef void type;
}
# endif
;
} // namespace boost
template <class T1, class T2>
struct error_not_related_by_convertibility;
template <>
struct minimum_category_impl<true,false>
{
template <class T1, class T2> struct apply
{
typedef T2 type;
};
};
template <>
struct minimum_category_impl<false,true>
{
template <class T1, class T2> struct apply
{
typedef T1 type;
};
};
template <>
struct minimum_category_impl<true,true>
{
template <class T1, class T2> struct apply
{
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
typedef T1 type;
};
};
template <>
struct minimum_category_impl<false,false>
{
template <class T1, class T2> struct apply
: error_not_related_by_convertibility<T1,T2>
{
};
};
template <class T1 = mpl::_1, class T2 = mpl::_2>
struct minimum_category
{
typedef minimum_category_impl<
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
is_same<T2,int>::value ||
# endif
::boost::is_convertible<T1,T2>::value
, ::boost::is_convertible<T2,T1>::value
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
|| is_same<T1,int>::value
# endif
> outer;
typedef typename outer::template apply<T1,T2> inner;
typedef typename inner::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
};
template <>
struct minimum_category<mpl::_1,mpl::_2>
{
template <class T1, class T2>
struct apply : minimum_category<T1,T2>
{};
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2))
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
template <>
struct minimum_category<int,int>
{
typedef int type;
};
# endif
}} // namespace boost::detail
#endif // MINIMUM_CATEGORY_DWA20031119_HPP

View File

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

View File

@ -7,15 +7,15 @@
#ifndef BOOST_FILTER_ITERATOR_23022003THW_HPP
#define BOOST_FILTER_ITERATOR_23022003THW_HPP
#include <boost/iterator.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>
namespace boost {
namespace iterators {
namespace boost
{
template <class Predicate, class Iterator>
class filter_iterator;
@ -39,7 +39,7 @@ namespace iterators {
> type;
};
}
template <class Predicate, class Iterator>
class filter_iterator
: public detail::filter_iterator_base<Predicate, Iterator>::type
@ -68,7 +68,7 @@ namespace iterators {
// 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
#endif
satisfy_predicate();
}
@ -108,29 +108,28 @@ namespace iterators {
};
template <class Predicate, class Iterator>
inline filter_iterator<Predicate,Iterator>
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>
filter_iterator<Predicate,Iterator>
make_filter_iterator(
typename iterators::enable_if<
is_class<Predicate>
, Iterator
>::type x
, Iterator end = Iterator())
, Iterator end = Iterator()
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
, Predicate* = 0
#endif
)
{
return filter_iterator<Predicate,Iterator>(x,end);
}
} // namespace iterators
using iterators::filter_iterator;
using iterators::make_filter_iterator;
} // namespace boost
#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP

View File

@ -1,6 +1,4 @@
// Copyright 2009 (C) Dean Michael Berris <me@deanberris.com>
// Copyright 2012 (C) Google, Inc.
// Copyright 2012 (C) Jeffrey Lee Hellrung, Jr.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@ -9,67 +7,32 @@
#ifndef BOOST_FUNCTION_INPUT_ITERATOR
#define BOOST_FUNCTION_INPUT_ITERATOR
#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/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 {
// 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;
};
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 &
template <class Function, class Input>
class function_input_iterator
: public iterator_facade<
function_input_iterator<Function, Input>,
typename Function::result_type,
single_pass_traversal_tag,
typename Function::result_type const &
>
{
{
public:
function_input_iterator() {}
function_input_iterator(Function & f_, Input state_ = Input())
: f(boost::addressof(f_)), state(state_) {}
function_input_iterator(Function * f_, Input state_ = Input())
: f(f_), state(state_), value((*f)()) {}
void increment() {
if(value)
value = none;
else
(*f)();
value = (*f)();
++state;
}
typename result_of_nullary_lvalue_call<Function>::type const &
dereference() const {
return (value ? value : value = (*f)()).get();
typename Function::result_type const &
dereference() const {
return value;
}
bool equal(function_input_iterator const & other) const {
@ -79,95 +42,23 @@ namespace iterators {
private:
Function * f;
Input state;
mutable optional<typename result_of_nullary_lvalue_call<Function>::type> value;
};
template <class Function, class Input>
class function_pointer_input_iterator :
public iterator_facade<
function_pointer_input_iterator<Function, Input>,
typename function_types::result_type<Function>::type,
single_pass_traversal_tag,
typename function_types::result_type<Function>::type const &
>
{
public:
function_pointer_input_iterator() {}
function_pointer_input_iterator(Function &f_, Input state_ = Input())
: f(f_), state(state_) {}
void increment() {
if(value)
value = none;
else
(*f)();
++state;
}
typename function_types::result_type<Function>::type const &
dereference() const {
return (value ? value : value = (*f)()).get();
}
bool equal(function_pointer_input_iterator const & other) const {
return f == other.f && state == other.state;
}
private:
Function f;
Input state;
mutable optional<typename function_types::result_type<Function>::type> value;
};
} // namespace impl
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
{
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) {}
typename Function::result_type value;
};
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);
make_function_input_iterator(Function & f, Input state) {
typedef function_input_iterator<Function, Input> result_t;
return result_t(&f, state);
}
template <class Function, class Input>
inline function_input_iterator<Function*, Input>
make_function_input_iterator(Function * f, Input state) {
typedef function_input_iterator<Function*, Input> result_t;
return result_t(f, state);
}
struct infinite
{
struct infinite {
infinite & operator++() { return *this; }
infinite & operator++(int) { return *this; }
bool operator==(infinite &) const { return false; };
bool operator==(infinite const &) const { return false; };
};
} // namespace iterators
using iterators::function_input_iterator;
using iterators::make_function_input_iterator;
using iterators::infinite;
} // namespace boost
}
#endif

View File

@ -1,95 +0,0 @@
// (C) Copyright Jeremy Siek 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:
// 27 Feb 2001 Jeremy Siek
// Initial checkin.
#ifndef BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
#define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
#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
namespace boost {
namespace iterators {
template <class UnaryFunction>
class function_output_iterator {
private:
typedef function_output_iterator self;
class output_proxy {
public:
explicit output_proxy(UnaryFunction& f) BOOST_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
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&))
private:
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;
explicit function_output_iterator() {}
explicit function_output_iterator(const UnaryFunction& f)
: m_f(f) {}
output_proxy operator*() { return output_proxy(m_f); }
self& operator++() { return *this; }
self& operator++(int) { return *this; }
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);
}
} // namespace iterators
using iterators::function_output_iterator;
using iterators::make_function_output_iterator;
} // namespace boost
#endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP

View File

@ -7,10 +7,12 @@
#ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP
#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP
#include <boost/iterator.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/pointee.hpp>
#include <boost/indirect_reference.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/detail/indirect_traits.hpp>
@ -23,20 +25,17 @@
#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
#endif
#include <boost/iterator/detail/config_def.hpp> // must be last #include
namespace boost {
namespace iterators {
namespace boost
{
template <class Iter, class Value, class Category, class Reference, class Difference>
class indirect_iterator;
@ -45,8 +44,8 @@ namespace iterators {
template <class Iter, class Value, class Category, class Reference, class Difference>
struct indirect_base
{
typedef typename std::iterator_traits<Iter>::value_type dereferenceable;
typedef typename iterator_traits<Iter>::value_type dereferenceable;
typedef iterator_adaptor<
indirect_iterator<Iter, Value, Category, Reference, Difference>
, Iter
@ -70,7 +69,7 @@ namespace iterators {
struct indirect_base<int, int, int, int, int> {};
} // namespace detail
template <
class Iterator
, class Value = use_default
@ -108,14 +107,14 @@ namespace iterators {
: super_t(y.base())
{}
private:
private:
typename super_t::reference dereference() const
{
# if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x5A0 )
# if BOOST_WORKAROUND(__BORLANDC__, < 0x5A0 )
return const_cast<super_t::reference>(**this->base());
# else
return **this->base();
# endif
# endif
}
};
@ -133,11 +132,6 @@ namespace iterators {
return indirect_iterator<Iter, Traits>(x);
}
} // namespace iterators
using iterators::indirect_iterator;
using iterators::make_indirect_iterator;
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>

View File

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

View File

@ -4,25 +4,21 @@
#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
# define IS_LVALUE_ITERATOR_DWA2003112_HPP
#include <boost/iterator.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/detail/iterator.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 <iterator>
// should be the last #includes
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/detail/bool_trait_def.hpp>
#include <boost/iterator/detail/config_def.hpp>
#ifndef BOOST_NO_IS_CONVERTIBLE
namespace boost {
namespace iterators {
namespace detail
{
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
@ -30,20 +26,20 @@ namespace detail
// 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
#endif
// Guts of is_lvalue_iterator. Value is the iterator's value_type
// and the result is computed in the nested rebind template.
@ -54,17 +50,17 @@ namespace detail
// convertible to Value const&
struct conversion_eater
{
conversion_eater(typename add_lvalue_reference<Value>::type);
conversion_eater(Value&);
};
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 = (
@ -79,7 +75,7 @@ namespace detail
};
#undef BOOST_LVALUE_PRESERVER
//
// void specializations to handle std input and output iterators
//
@ -124,41 +120,31 @@ namespace detail
template <class It>
struct is_readable_lvalue_iterator_impl
: is_lvalue_iterator_impl<
BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type const
BOOST_DEDUCED_TYPENAME boost::detail::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
BOOST_DEDUCED_TYPENAME boost::detail::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>
{
public:
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_non_const_lvalue_iterator,(T))
};
} // namespace iterators
using iterators::is_lvalue_iterator;
using iterators::is_non_const_lvalue_iterator;
// Define the trait with full mpl lambda capability and various broken
// compiler workarounds
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_lvalue_iterator,T,::boost::detail::is_readable_lvalue_iterator_impl<T>::value)
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_non_const_lvalue_iterator,T,::boost::detail::is_non_const_lvalue_iterator_impl<T>::value)
} // namespace boost
#endif
#include <boost/iterator/detail/config_undef.hpp>
#include <boost/type_traits/detail/bool_trait_undef.hpp>
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP

View File

@ -5,23 +5,18 @@
# 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/detail/iterator.hpp>
#include <boost/type_traits/detail/bool_trait_def.hpp>
#include <boost/iterator/detail/any_conversion_eater.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
namespace boost {
namespace iterators {
namespace detail
{
// Guts of is_readable_iterator. Value is the iterator's value_type
@ -29,14 +24,14 @@ namespace detail
template <class Value>
struct is_readable_iterator_impl
{
static char tester(typename add_lvalue_reference<Value>::type, int);
static char tester(Value&, int);
static char (& tester(any_conversion_eater, ...) )[2];
template <class It>
struct rebind
{
static It& x;
BOOST_STATIC_CONSTANT(
bool
, value = (
@ -49,7 +44,7 @@ namespace detail
};
#undef BOOST_READABLE_PRESERVER
//
// void specializations to handle std input and output iterators
//
@ -94,22 +89,16 @@ namespace detail
template <class It>
struct is_readable_iterator_impl2
: is_readable_iterator_impl<
BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type const
BOOST_DEDUCED_TYPENAME boost::detail::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>
{
public:
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_readable_iterator,(T))
};
} // namespace iterators
using iterators::is_readable_iterator;
// Define the trait with full mpl lambda capability and various broken
// compiler workarounds
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
is_readable_iterator,T,::boost::detail::is_readable_iterator_impl2<T>::value)
} // namespace boost
#endif

View File

@ -8,8 +8,8 @@
#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
#include <boost/static_assert.hpp>
#include <boost/core/use_default.hpp>
#include <boost/iterator.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_facade.hpp>
@ -24,38 +24,41 @@
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
# include <boost/type_traits/remove_reference.hpp>
# if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))
# include <boost/type_traits/add_reference.hpp>
# endif
#else
# include <boost/type_traits/add_reference.hpp>
#endif
#include <boost/type_traits/add_reference.hpp>
#include <boost/iterator/detail/config_def.hpp>
#include <boost/iterator/iterator_traits.hpp>
namespace boost {
namespace iterators {
namespace boost
{
// 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
// 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_ {};
namespace iterators {
struct use_default;
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// 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_ {};
# endif
namespace detail
{
//
//
// Result type used in enable_if_convertible meta function.
// This can be an incomplete type, as only pointers to
// This can be an incomplete type, as only pointers to
// enable_if_convertible< ... >::type are used.
// We could have used void for this, but conversion to
// void* is just to easy.
@ -76,7 +79,7 @@ namespace iterators {
// public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
// {
// public:
//
//
// ...
//
// template <class OtherIterator>
@ -95,23 +98,38 @@ namespace iterators {
// 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.
// 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)
# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
template<typename From, typename To>
struct enable_if_convertible
{
typedef typename mpl::if_<
mpl::or_<
is_same<From,To>
, is_convertible<From, To>
>
, boost::detail::enable_type
, int&
>::type type;
};
# elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
template <class From, class To>
struct enable_if_convertible
{
typedef boost::iterators::detail::enable_type type;
typedef boost::detail::enable_type type;
};
# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292))
# elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
// For some reason vc7.1 needs us to "cut off" instantiation
// of is_convertible in a few cases.
template<typename From, typename To>
@ -121,22 +139,22 @@ namespace iterators {
is_same<From,To>
, is_convertible<From, To>
>
, boost::iterators::detail::enable_type
, boost::detail::enable_type
>
{};
# else
# else
template<typename From, typename To>
struct enable_if_convertible
: iterators::enable_if<
is_convertible<From, To>
, boost::iterators::detail::enable_type
, boost::detail::enable_type
>
{};
# endif
//
// Default template argument handling for iterator_adaptor
//
@ -168,9 +186,9 @@ namespace iterators {
{
typedef iterator_facade<
Derived
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
, typename boost::iterators::detail::ia_dflt_help<
, typename boost::detail::ia_dflt_help<
Value
, mpl::eval_if<
is_same<Reference,use_default>
@ -179,17 +197,17 @@ namespace iterators {
>
>::type
# else
, typename boost::iterators::detail::ia_dflt_help<
, typename boost::detail::ia_dflt_help<
Value, iterator_value<Base>
>::type
# endif
, typename boost::iterators::detail::ia_dflt_help<
, typename boost::detail::ia_dflt_help<
Traversal
, iterator_traversal<Base>
>::type
, typename boost::iterators::detail::ia_dflt_help<
, typename boost::detail::ia_dflt_help<
Reference
, mpl::eval_if<
is_same<Value,use_default>
@ -198,13 +216,13 @@ namespace iterators {
>
>::type
, typename boost::iterators::detail::ia_dflt_help<
, typename boost::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 ()
@ -212,7 +230,7 @@ namespace iterators {
BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
}
}
//
// Iterator Adaptor
//
@ -247,14 +265,14 @@ namespace iterators {
, class Difference = use_default
>
class iterator_adaptor
: public boost::iterators::detail::iterator_adaptor_base<
: public boost::detail::iterator_adaptor_base<
Derived, Base, Value, Traversal, Reference, Difference
>::type
{
friend class iterator_core_access;
protected:
typedef typename boost::iterators::detail::iterator_adaptor_base<
typedef typename boost::detail::iterator_adaptor_base<
Derived, Base, Value, Traversal, Reference, Difference
>::type super_t;
public:
@ -273,7 +291,7 @@ namespace iterators {
protected:
// for convenience in derived classes
typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
//
// lvalue access to the Base object for Derived
//
@ -289,13 +307,13 @@ namespace iterators {
// 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
{
// Maybe readd with same_distance
@ -310,17 +328,17 @@ namespace iterators {
>::type my_traversal;
# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
boost::iterators::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
boost::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
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 decrement()
void decrement()
{
BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
--m_iterator;
@ -328,7 +346,7 @@ namespace iterators {
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
{
@ -341,16 +359,11 @@ namespace iterators {
}
# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
private: // data members
Base m_iterator;
};
} // namespace iterators
using iterators::iterator_adaptor;
using iterators::enable_if_convertible;
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>

View File

@ -9,6 +9,7 @@
#include <boost/iterator/iterator_categories.hpp>
#include <boost/operators.hpp>
#include <boost/static_assert.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/detail/facade_iterator_category.hpp>
@ -19,6 +20,7 @@
#include <boost/concept_archetype.hpp>
#include <boost/mpl/aux_/msvc_eti_base.hpp>
#include <boost/mpl/bitand.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/equal_to.hpp>
@ -30,7 +32,6 @@
#include <cstddef>
namespace boost {
namespace iterators {
template <class Value, class AccessCategory>
struct access_archetype;
@ -38,7 +39,7 @@ struct access_archetype;
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
struct traversal_archetype;
namespace archetypes
namespace iterator_archetypes
{
enum {
readable_iterator_bit = 1
@ -50,19 +51,19 @@ namespace archetypes
// 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;
typedef mpl::int_<
(readable_iterator_bit|writable_iterator_bit)
>::type readable_writable_iterator_t;
typedef mpl::int_<
(readable_iterator_bit|lvalue_iterator_bit)
>::type readable_lvalue_iterator_t;
typedef mpl::int_<
(lvalue_iterator_bit|writable_iterator_bit)
>::type writable_lvalue_iterator_t;
typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
@ -118,27 +119,29 @@ namespace detail
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<
: mpl::aux::msvc_eti_base<
typename mpl::eval_if<
is_convertible<TraversalCategory, random_access_traversal_tag>
, mpl::eval_if<
iterator_archetypes::has_access<
AccessCategory
, archetypes::readable_iterator_t
, iterator_archetypes::writable_iterator_t
>
, mpl::identity<writable_operator_brackets<Value> >
, mpl::if_<
iterator_archetypes::has_access<
AccessCategory
, iterator_archetypes::readable_iterator_t
>
, readable_operator_brackets<Value>
, no_operator_brackets
>
, readable_operator_brackets<Value>
, no_operator_brackets
>
>
, mpl::identity<no_operator_brackets>
, mpl::identity<no_operator_brackets>
>::type
>::type
{};
template <class TraversalCategory>
struct traversal_archetype_impl
{
@ -151,16 +154,18 @@ namespace detail
template <class Derived, class Value, class TraversalCategory>
struct traversal_archetype_
: traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
: mpl::aux::msvc_eti_base<
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
>::type
{
typedef typename
traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
base;
traversal_archetype_() {}
traversal_archetype_(ctor_arg arg)
: base(arg)
: base(arg)
{}
};
@ -191,7 +196,7 @@ namespace detail
explicit archetype(ctor_arg arg)
: traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
{}
typedef std::ptrdiff_t difference_type;
};
};
@ -199,7 +204,13 @@ namespace detail
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; }
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
// doesn't seem to pick up != from equality_comparable
template <class Derived, class Value>
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
#endif
template <>
struct traversal_archetype_impl<forward_traversal_tag>
{
@ -207,7 +218,7 @@ namespace detail
struct archetype
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
{
archetype()
archetype()
: traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
{}
};
@ -230,7 +241,7 @@ namespace detail
{
template<class Derived, class Value>
struct archetype
: public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
: public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
{
Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
@ -289,7 +300,7 @@ namespace detail
template <class> struct undefined;
template <class AccessCategory>
struct iterator_access_archetype_impl
{
@ -298,15 +309,17 @@ struct iterator_access_archetype_impl
template <class Value, class AccessCategory>
struct iterator_access_archetype
: iterator_access_archetype_impl<
AccessCategory
>::template archetype<Value>
: mpl::aux::msvc_eti_base<
typename iterator_access_archetype_impl<
AccessCategory
>::template archetype<Value>
>::type
{
};
template <>
struct iterator_access_archetype_impl<
archetypes::readable_iterator_t
iterator_archetypes::readable_iterator_t
>
{
template <class Value>
@ -324,13 +337,15 @@ struct iterator_access_archetype_impl<
template <>
struct iterator_access_archetype_impl<
archetypes::writable_iterator_t
iterator_archetypes::writable_iterator_t
>
{
template <class Value>
struct archetype
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT(!is_const<Value>::value);
# endif
typedef void value_type;
typedef void reference;
typedef void pointer;
@ -341,13 +356,13 @@ struct iterator_access_archetype_impl<
template <>
struct iterator_access_archetype_impl<
archetypes::readable_writable_iterator_t
iterator_archetypes::readable_writable_iterator_t
>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, archetypes::readable_iterator_t
Value, iterator_archetypes::readable_iterator_t
>
{
typedef detail::read_write_proxy<Value> reference;
@ -357,12 +372,12 @@ struct iterator_access_archetype_impl<
};
template <>
struct iterator_access_archetype_impl<archetypes::readable_lvalue_iterator_t>
struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, archetypes::readable_iterator_t
Value, iterator_archetypes::readable_iterator_t
>
{
typedef Value& reference;
@ -371,26 +386,28 @@ struct iterator_access_archetype_impl<archetypes::readable_lvalue_iterator_t>
Value* operator->() const { return 0; }
};
};
template <>
struct iterator_access_archetype_impl<archetypes::writable_lvalue_iterator_t>
struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>
{
template <class Value>
struct archetype
: public virtual iterator_access_archetype<
Value, archetypes::readable_lvalue_iterator_t
Value, iterator_archetypes::readable_lvalue_iterator_t
>
{
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
BOOST_STATIC_ASSERT((!is_const<Value>::value));
# endif
};
};
template <class Value, class AccessCategory, class TraversalCategory>
struct iterator_archetype;
template <class Value, class AccessCategory, class TraversalCategory>
struct traversal_archetype_base
struct traversal_archetype_base
: detail::operator_brackets<
typename remove_cv<Value>::type
, AccessCategory
@ -412,12 +429,12 @@ namespace detail
, 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
iterator_archetypes::has_access<
AccessCategory, iterator_archetypes::writable_iterator_t
>
, remove_const<Value>
, add_const<Value>
@ -426,16 +443,15 @@ namespace detail
>::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<
typedef boost::iterator<
iterator_category
, Value
, typename traversal_archetype_base<
Value, AccessCategory, TraversalCategory
>::difference_type difference_type;
typedef typename access::pointer pointer;
typedef typename access::reference reference;
};
>::difference_type
, typename access::pointer
, typename access::reference
> workaround_iterator_base;
};
}
@ -451,18 +467,18 @@ struct iterator_archetype
, public detail::iterator_archetype_base<
Value, AccessCategory, TraversalCategory
>::workaround_iterator_base
# endif
# endif
{
// Derivation from std::iterator above caused references to nested
// types to be ambiguous, so now we have to redeclare them all
// here.
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
typedef detail::iterator_archetype_base<
Value,AccessCategory,TraversalCategory
> base;
typedef typename base::value_type value_type;
typedef typename base::reference reference;
typedef typename base::pointer pointer;
@ -493,17 +509,7 @@ struct iterator_archetype
# endif
};
} // namespace iterators
// Backward compatibility names
namespace iterator_archetypes = iterators::archetypes;
using iterators::access_archetype;
using iterators::traversal_archetype;
using iterators::iterator_archetype;
using iterators::undefined;
using iterators::iterator_access_archetype_impl;
using iterators::traversal_archetype_base;
} // namespace boost
#endif // BOOST_ITERATOR_ARCHETYPES_HPP

View File

@ -7,6 +7,7 @@
# define BOOST_ITERATOR_CATEGORIES_HPP
# include <boost/config.hpp>
# include <boost/detail/iterator.hpp>
# include <boost/iterator/detail/config_def.hpp>
# include <boost/detail/workaround.hpp>
@ -20,10 +21,7 @@
# include <boost/static_assert.hpp>
#include <iterator>
namespace boost {
namespace iterators {
//
// Traversal Categories
@ -31,34 +29,34 @@ namespace iterators {
struct no_traversal_tag {};
struct incrementable_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
{
@ -67,7 +65,7 @@ struct random_access_traversal_tag
};
namespace detail
{
{
//
// Convert a "strictly old-style" iterator category to a traversal
// tag. This is broken out into a separate metafunction to reduce
@ -99,8 +97,51 @@ namespace detail
>
{};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <>
struct old_category_to_traversal<int>
{
typedef int type;
};
# endif
template <class Traversal>
struct pure_traversal_tag
: mpl::eval_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<random_access_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,bidirectional_traversal_tag>
, mpl::identity<bidirectional_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,forward_traversal_tag>
, mpl::identity<forward_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,single_pass_traversal_tag>
, mpl::identity<single_pass_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,incrementable_traversal_tag>
, mpl::identity<incrementable_traversal_tag>
, void
>
>
>
>
>
{
};
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <>
struct pure_traversal_tag<int>
{
typedef int type;
};
# endif
} // namespace detail
//
// Convert an iterator category into a traversal tag
//
@ -109,7 +150,7 @@ 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>
, boost::detail::old_category_to_traversal<Cat>
>
{};
@ -117,7 +158,7 @@ struct iterator_category_to_traversal
template <class Iterator = mpl::_1>
struct iterator_traversal
: iterator_category_to_traversal<
typename std::iterator_traits<Iterator>::iterator_category
typename boost::detail::iterator_traits<Iterator>::iterator_category
>
{};
@ -140,75 +181,6 @@ struct iterator_traversal<mpl::_>
{};
# endif
//
// Convert an iterator traversal to one of the traversal tags.
//
template <class Traversal>
struct pure_traversal_tag
: mpl::eval_if<
is_convertible<Traversal,random_access_traversal_tag>
, mpl::identity<random_access_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,bidirectional_traversal_tag>
, mpl::identity<bidirectional_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,forward_traversal_tag>
, mpl::identity<forward_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,single_pass_traversal_tag>
, mpl::identity<single_pass_traversal_tag>
, mpl::eval_if<
is_convertible<Traversal,incrementable_traversal_tag>
, mpl::identity<incrementable_traversal_tag>
, void
>
>
>
>
>
{
};
//
// Trait to retrieve one of the iterator traversal tags from the iterator category or traversal.
//
template <class Iterator = mpl::_1>
struct pure_iterator_traversal
: pure_traversal_tag<typename iterator_traversal<Iterator>::type>
{};
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
template <>
struct pure_iterator_traversal<mpl::_1>
{
template <class T>
struct apply : pure_iterator_traversal<T>
{};
};
template <>
struct pure_iterator_traversal<mpl::_>
: pure_iterator_traversal<mpl::_1>
{};
# endif
} // namespace iterators
using iterators::no_traversal_tag;
using iterators::incrementable_traversal_tag;
using iterators::single_pass_traversal_tag;
using iterators::forward_traversal_tag;
using iterators::bidirectional_traversal_tag;
using iterators::random_access_traversal_tag;
using iterators::iterator_category_to_traversal;
using iterators::iterator_traversal;
// This import is needed for backward compatibility with Boost.Range:
// boost/range/detail/demote_iterator_traversal_tag.hpp
// It should be removed when that header is fixed.
namespace detail {
using iterators::pure_traversal_tag;
} // namespace detail
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>

View File

@ -9,6 +9,9 @@
#include <boost/concept_check.hpp>
#include <boost/iterator/iterator_categories.hpp>
// Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems.
#include <boost/detail/iterator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_integral.hpp>
@ -24,7 +27,6 @@
#include <boost/config.hpp>
#include <algorithm>
#include <iterator>
#include <boost/concept/detail/concept_def.hpp>
@ -42,8 +44,8 @@ namespace boost_concepts
, boost::CopyConstructible<Iterator>
{
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::reference reference;
typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::reference reference;
BOOST_CONCEPT_USAGE(ReadableIterator)
{
@ -54,10 +56,10 @@ namespace boost_concepts
private:
Iterator i;
};
template <
typename Iterator
, typename ValueType = BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::value_type
, typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
>
struct WritableIterator
: boost::CopyConstructible<Iterator>
@ -73,10 +75,10 @@ namespace boost_concepts
template <
typename Iterator
, typename ValueType = BOOST_DEDUCED_TYPENAME std::iterator_traits<Iterator>::value_type
, typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::value_type
>
struct WritableIteratorConcept : WritableIterator<Iterator,ValueType> {};
BOOST_concept(SwappableIterator,(Iterator))
{
BOOST_CONCEPT_USAGE(SwappableIterator)
@ -90,8 +92,8 @@ namespace boost_concepts
BOOST_concept(LvalueIterator,(Iterator))
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
BOOST_CONCEPT_USAGE(LvalueIterator)
{
value_type& r = const_cast<value_type&>(*i);
@ -101,7 +103,7 @@ namespace boost_concepts
Iterator i;
};
//===========================================================================
// Iterator Traversal Concepts
@ -142,8 +144,8 @@ namespace boost_concepts
: SinglePassIterator<Iterator>
, boost::DefaultConstructible<Iterator>
{
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef typename boost::detail::iterator_traits<Iterator>::difference_type difference_type;
BOOST_MPL_ASSERT((boost::is_integral<difference_type>));
BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
@ -153,7 +155,7 @@ namespace boost_concepts
, boost::forward_traversal_tag
> ));
};
BOOST_concept(BidirectionalTraversal,(Iterator))
: ForwardTraversal<Iterator>
{
@ -190,14 +192,14 @@ namespace boost_concepts
i = i - n;
n = i - j;
}
private:
typename BidirectionalTraversal<Iterator>::difference_type n;
Iterator i, j;
};
//===========================================================================
// Iterator Interoperability
// Iterator Interoperability
namespace detail
{
@ -219,7 +221,7 @@ namespace boost_concepts
boost::random_access_traversal_tag, boost::random_access_traversal_tag)
{
bool b;
typename std::iterator_traits<Iterator2>::difference_type n;
typename boost::detail::iterator_traits<Iterator2>::difference_type n;
b = i1 < i2;
b = i1 <= i2;
b = i1 > i2;
@ -246,10 +248,19 @@ namespace boost_concepts
BOOST_concept(InteroperableIterator,(Iterator)(ConstIterator))
{
private:
typedef typename boost::iterators::pure_iterator_traversal<Iterator>::type traversal_category;
typedef typename boost::iterators::pure_iterator_traversal<ConstIterator>::type const_traversal_category;
typedef typename boost::detail::pure_traversal_tag<
typename boost::iterator_traversal<
Iterator
>::type
>::type traversal_category;
public:
typedef typename boost::detail::pure_traversal_tag<
typename boost::iterator_traversal<
ConstIterator
>::type
>::type const_traversal_category;
public:
BOOST_CONCEPT_ASSERT((SinglePassIterator<Iterator>));
BOOST_CONCEPT_ASSERT((SinglePassIterator<ConstIterator>));
@ -260,7 +271,7 @@ namespace boost_concepts
ci = i;
}
private:
Iterator i;
ConstIterator ci;

View File

@ -7,21 +7,19 @@
#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
#define BOOST_ITERATOR_FACADE_23022003THW_HPP
#include <boost/config.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/interoperable.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/detail/facade_iterator_category.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/implicit_cast.hpp>
#include <boost/static_assert.hpp>
#include <boost/core/addressof.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_convertible.hpp>
@ -36,13 +34,10 @@
#include <boost/mpl/apply.hpp>
#include <boost/mpl/identity.hpp>
#include <cstddef>
#include <boost/iterator/detail/config_def.hpp> // this goes last
namespace boost {
namespace iterators {
namespace boost
{
// This forward declaration is required for the friend declaration
// in iterator_core_access
template <class I, class V, class TC, class R, class D> class iterator_facade;
@ -61,12 +56,6 @@ namespace iterators {
};
};
// The type trait checks if the category or traversal is at least as advanced as the specified required traversal
template< typename CategoryOrTraversal, typename Required >
struct is_traversal_at_least :
public boost::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
{};
//
// enable if for use in operator implementation.
//
@ -75,31 +64,28 @@ namespace iterators {
, class Facade2
, class Return
>
struct enable_if_interoperable :
public boost::iterators::enable_if<
is_interoperable< Facade1, Facade2 >
, Return
>
{};
//
// enable if for use in implementation of operators specific for random access traversal.
//
template <
class Facade1
, class Facade2
, class Return
>
struct enable_if_interoperable_and_random_access_traversal :
public boost::iterators::enable_if<
mpl::and_<
is_interoperable< Facade1, Facade2 >
, is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >
, is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
struct enable_if_interoperable
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
{
typedef typename mpl::if_<
mpl::or_<
is_convertible<Facade1, Facade2>
, is_convertible<Facade2, Facade1>
>
, Return
, int[3]
>::type type;
};
#else
: ::boost::iterators::enable_if<
mpl::or_<
is_convertible<Facade1, Facade2>
, is_convertible<Facade2, Facade1>
>
, Return
>
{};
#endif
//
// Generates associated types for an iterator_facade with the
@ -108,7 +94,7 @@ namespace iterators {
template <
class ValueParam
, class CategoryOrTraversal
, class Reference
, class Reference
, class Difference
>
struct iterator_facade_types
@ -116,16 +102,16 @@ namespace iterators {
typedef typename facade_iterator_category<
CategoryOrTraversal, ValueParam, Reference
>::type iterator_category;
typedef typename remove_const<ValueParam>::type value_type;
// Not the real associated pointer type
typedef typename mpl::eval_if<
boost::iterators::detail::iterator_writability_disabled<ValueParam,Reference>
boost::detail::iterator_writability_disabled<ValueParam,Reference>
, add_pointer<const value_type>
, add_pointer<value_type>
>::type pointer;
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
&& (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
|| BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
@ -161,7 +147,7 @@ namespace iterators {
// Returning a mutable reference allows nonsense like
// (*r++).mutate(), but it imposes fewer assumptions about the
// behavior of the value_type. In particular, recall that
// behavior of the value_type. In particular, recall taht
// (*r).mutate() is legal if operator* returns by value.
value_type&
operator*() const
@ -171,7 +157,7 @@ namespace iterators {
private:
mutable value_type stored_value;
};
//
// In general, we can't determine that such an iterator isn't
// writable -- we also need to store a copy of the old iterator so
@ -223,7 +209,7 @@ namespace iterators {
{
return stored_iterator;
}
private:
mutable value_type stored_value;
Iterator stored_iterator;
@ -235,7 +221,7 @@ namespace iterators {
struct is_non_proxy_reference_impl
{
static Reference r;
template <class R>
static typename mpl::if_<
is_convertible<
@ -245,17 +231,17 @@ namespace iterators {
, char[1]
, char[2]
>::type& helper(R const&);
BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
};
template <class Reference, class Value>
struct is_non_proxy_reference
: mpl::bool_<
is_non_proxy_reference_impl<Reference, Value>::value
>
{};
# else
# else
template <class Reference, class Value>
struct is_non_proxy_reference
: is_convertible<
@ -264,8 +250,8 @@ namespace iterators {
, Value const volatile*
>
{};
# endif
# endif
// A metafunction to choose the result type of postfix ++
//
// Because the C++98 input iterator requirements say that *r++ has
@ -286,16 +272,8 @@ namespace iterators {
: mpl::eval_if<
mpl::and_<
// A proxy is only needed for readable iterators
is_convertible<
Reference
// Use add_lvalue_reference to form `reference to Value` due to
// some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
// 'reference-to-reference' in the template which described in CWG
// DR106.
// http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
, typename add_lvalue_reference<Value const>::type
>
is_convertible<Reference,Value const&>
// No multipass iterator can have values that disappear
// before positions can be re-visited
, mpl::not_<
@ -316,36 +294,48 @@ namespace iterators {
// operator->() needs special support for input iterators to strictly meet the
// standard's requirements. If *i is not a reference type, we must still
// produce an lvalue to which a pointer can be formed. We do that by
// returning a proxy object containing an instance of the reference object.
template <class Reference, class Pointer>
struct operator_arrow_dispatch // proxy references
// produce a lvalue to which a pointer can be formed. We do that by
// returning an instantiation of this special proxy class template.
template <class T>
struct operator_arrow_proxy
{
struct proxy
operator_arrow_proxy(T const* px) : m_value(*px) {}
T* operator->() const { return &m_value; }
// This function is needed for MWCW and BCC, which won't call operator->
// again automatically per 13.3.1.2 para 8
operator T*() const { return &m_value; }
mutable T m_value;
};
// A metafunction that gets the result type for operator->. Also
// has a static function make() which builds the result from a
// Reference
template <class ValueType, class Reference, class Pointer>
struct operator_arrow_result
{
// CWPro8.3 won't accept "operator_arrow_result::type", and we
// need that type below, so metafunction forwarding would be a
// losing proposition here.
typedef typename mpl::if_<
is_reference<Reference>
, Pointer
, operator_arrow_proxy<ValueType>
>::type type;
static type make(Reference x)
{
explicit proxy(Reference const & x) : m_ref(x) {}
Reference* operator->() { return boost::addressof(m_ref); }
// This function is needed for MWCW and BCC, which won't call
// operator-> again automatically per 13.3.1.2 para 8
operator Reference*() { return boost::addressof(m_ref); }
Reference m_ref;
};
typedef proxy result_type;
static result_type apply(Reference const & x)
{
return result_type(x);
return implicit_cast<type>(&x);
}
};
template <class T, class Pointer>
struct operator_arrow_dispatch<T&, Pointer> // "real" references
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// Deal with ETI
template<>
struct operator_arrow_result<int, int, int>
{
typedef Pointer result_type;
static result_type apply(T& x)
{
return boost::addressof(x);
}
typedef int type;
};
# endif
// A proxy return type for operator[], needed to deal with
// iterators that may invalidate referents upon destruction.
@ -391,7 +381,7 @@ namespace iterators {
>
>
{};
template <class Iterator, class Value, class Reference>
struct operator_brackets_result
{
@ -421,34 +411,28 @@ namespace iterators {
:
# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
iterator_difference<I1>
# else
# elif BOOST_WORKAROUND(BOOST_MSVC, < 1300)
mpl::if_<
is_convertible<I2,I1>
, typename I1::difference_type
, typename I2::difference_type
>
# else
mpl::eval_if<
is_convertible<I2,I1>
, iterator_difference<I1>
, iterator_difference<I2>
>
# endif
# endif
{};
};
template <
class Derived
, class Value
, class CategoryOrTraversal
, class Reference
, class Difference
, bool IsBidirectionalTraversal
, bool IsRandomAccessTraversal
>
class iterator_facade_base;
} // namespace detail
// Macros which describe the declarations of binary operators
# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
template < \
class Derived1, class V1, class TC1, class Reference1, class Difference1 \
, class Derived2, class V2, class TC2, class Reference2, class Difference2 \
@ -457,33 +441,24 @@ namespace iterators {
operator op( \
iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
# else
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
# else
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
template < \
class Derived1, class V1, class TC1, class Reference1, class Difference1 \
, class Derived2, class V2, class TC2, class Reference2, class Difference2 \
> \
prefix typename enabler< \
prefix typename boost::detail::enable_if_interoperable< \
Derived1, Derived2 \
, typename mpl::apply2<result_type,Derived1,Derived2>::type \
>::type \
operator op( \
iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
, iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
# endif
# define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
# define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
# endif
# define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
template <class Derived, class V, class TC, class R, class D> \
prefix typename boost::iterators::enable_if< \
boost::iterators::detail::is_traversal_at_least< TC, boost::iterators::random_access_traversal_tag >, \
Derived \
>::type operator+ args
prefix Derived operator+ args
//
// Helper class for granting access to the iterator core interface.
@ -496,49 +471,41 @@ namespace iterators {
//
class iterator_core_access
{
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends.
public:
# else
template <class I, class V, class TC, class R, class D> friend class iterator_facade;
template <class I, class V, class TC, class R, class D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal>
friend class detail::iterator_facade_base;
# define BOOST_ITERATOR_FACADE_RELATION(op) \
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::iterators::detail::always_bool2);
BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::detail::always_bool2);
BOOST_ITERATOR_FACADE_RELATION(==)
BOOST_ITERATOR_FACADE_RELATION(!=)
BOOST_ITERATOR_FACADE_RELATION(<)
BOOST_ITERATOR_FACADE_RELATION(>)
BOOST_ITERATOR_FACADE_RELATION(<=)
BOOST_ITERATOR_FACADE_RELATION(>=)
# undef BOOST_ITERATOR_FACADE_RELATION
# define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op) \
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend,op, boost::iterators::detail::always_bool2);
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
# undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(
friend, -, boost::iterators::detail::choose_difference_type)
BOOST_ITERATOR_FACADE_INTEROP_HEAD(
friend, -, boost::detail::choose_difference_type)
;
BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend inline
, (iterator_facade<Derived, V, TC, R, D> const&
, typename Derived::difference_type)
, (iterator_facade<Derived, V, TC, R, D> const&
, typename Derived::difference_type)
)
;
BOOST_ITERATOR_FACADE_PLUS_HEAD(
friend inline
, (typename Derived::difference_type
, iterator_facade<Derived, V, TC, R, D> const&)
, iterator_facade<Derived, V, TC, R, D> const&)
)
;
@ -609,156 +576,11 @@ namespace iterators {
return *static_cast<I const*>(&facade);
}
private:
// objects of this class are useless
BOOST_DELETED_FUNCTION(iterator_core_access())
iterator_core_access(); //undefined
};
namespace detail {
// Implementation for forward traversal iterators
template <
class Derived
, class Value
, class CategoryOrTraversal
, class Reference
, class Difference
>
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
: public boost::iterators::detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
>::base
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
# endif
{
private:
typedef boost::iterators::detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
> associated_types;
typedef boost::iterators::detail::operator_arrow_dispatch<
Reference
, typename associated_types::pointer
> operator_arrow_dispatch_;
public:
typedef typename associated_types::value_type value_type;
typedef Reference reference;
typedef Difference difference_type;
typedef typename operator_arrow_dispatch_::result_type pointer;
typedef typename associated_types::iterator_category iterator_category;
public:
reference operator*() const
{
return iterator_core_access::dereference(this->derived());
}
pointer operator->() const
{
return operator_arrow_dispatch_::apply(*this->derived());
}
Derived& operator++()
{
iterator_core_access::increment(this->derived());
return this->derived();
}
protected:
//
// Curiously Recurring Template interface.
//
Derived& derived()
{
return *static_cast<Derived*>(this);
}
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
};
// Implementation for bidirectional traversal iterators
template <
class Derived
, class Value
, class CategoryOrTraversal
, class Reference
, class Difference
>
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
{
public:
Derived& operator--()
{
iterator_core_access::decrement(this->derived());
return this->derived();
}
Derived operator--(int)
{
Derived tmp(this->derived());
--*this;
return tmp;
}
};
// Implementation for random access traversal iterators
template <
class Derived
, class Value
, class CategoryOrTraversal
, class Reference
, class Difference
>
class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
{
private:
typedef iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > base_type;
public:
typedef typename base_type::reference reference;
typedef typename base_type::difference_type difference_type;
public:
typename boost::iterators::detail::operator_brackets_result<Derived, Value, reference>::type
operator[](difference_type n) const
{
typedef boost::iterators::detail::use_operator_brackets_proxy<Value, Reference> use_proxy;
return boost::iterators::detail::make_operator_brackets_result<Derived>(
this->derived() + n
, use_proxy()
);
}
Derived& operator+=(difference_type n)
{
iterator_core_access::advance(this->derived(), n);
return this->derived();
}
Derived& operator-=(difference_type n)
{
iterator_core_access::advance(this->derived(), -n);
return this->derived();
}
Derived operator-(difference_type x) const
{
Derived result(this->derived());
return result -= x;
}
};
} // namespace detail
//
// iterator_facade - use as a public base class for defining new
// standard-conforming iterators.
@ -770,38 +592,152 @@ namespace iterators {
, class Reference = Value&
, class Difference = std::ptrdiff_t
>
class iterator_facade :
public detail::iterator_facade_base<
Derived,
Value,
CategoryOrTraversal,
Reference,
Difference,
detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
>
class iterator_facade
# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
: public boost::detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
>::base
# undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
# endif
{
protected:
private:
//
// Curiously Recurring Template interface.
//
Derived& derived()
{
return *static_cast<Derived*>(this);
}
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
typedef boost::detail::iterator_facade_types<
Value, CategoryOrTraversal, Reference, Difference
> associated_types;
typedef boost::detail::operator_arrow_result<
typename associated_types::value_type
, Reference
, typename associated_types::pointer
> pointer_;
protected:
// For use by derived classes
typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
public:
typedef typename associated_types::value_type value_type;
typedef Reference reference;
typedef Difference difference_type;
typedef typename pointer_::type pointer;
typedef typename associated_types::iterator_category iterator_category;
reference operator*() const
{
return iterator_core_access::dereference(this->derived());
}
pointer operator->() const
{
return pointer_::make(*this->derived());
}
typename boost::detail::operator_brackets_result<Derived,Value,reference>::type
operator[](difference_type n) const
{
typedef boost::detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
return boost::detail::make_operator_brackets_result<Derived>(
this->derived() + n
, use_proxy()
);
}
Derived& operator++()
{
iterator_core_access::increment(this->derived());
return this->derived();
}
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
typename boost::detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
operator++(int)
{
typename boost::detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
tmp(this->derived());
++*this;
return tmp;
}
# endif
Derived& operator--()
{
iterator_core_access::decrement(this->derived());
return this->derived();
}
Derived operator--(int)
{
Derived tmp(this->derived());
--*this;
return tmp;
}
Derived& operator+=(difference_type n)
{
iterator_core_access::advance(this->derived(), n);
return this->derived();
}
Derived& operator-=(difference_type n)
{
iterator_core_access::advance(this->derived(), -n);
return this->derived();
}
Derived operator-(difference_type x) const
{
Derived result(this->derived());
return result -= x;
}
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
// There appears to be a bug which trashes the data of classes
// derived from iterator_facade when they are assigned unless we
// define this assignment operator. This bug is only revealed
// (so far) in STLPort debug mode, but it's clearly a codegen
// problem so we apply the workaround for all MSVC6.
iterator_facade& operator=(iterator_facade const&)
{
return *this;
}
# endif
};
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class I, class V, class TC, class R, class D>
inline typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
inline typename boost::detail::postfix_increment_result<I,V,R,TC>::type
operator++(
iterator_facade<I,V,TC,R,D>& i
, int
)
{
typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
typename boost::detail::postfix_increment_result<I,V,R,TC>::type
tmp(*static_cast<I*>(&i));
++i;
return tmp;
}
# endif
//
// Comparison operator implementation. The library supplied operators
// enables the user to provide fully interoperable constant/mutable
@ -892,7 +828,7 @@ namespace iterators {
# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP( \
op \
, boost::iterators::detail::always_bool2 \
, boost::detail::always_bool2 \
, return_prefix \
, base_op \
)
@ -900,50 +836,21 @@ namespace iterators {
BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_from)
BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_from)
BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_from)
BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_from)
# undef BOOST_ITERATOR_FACADE_RELATION
# define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type) \
{ \
/* For those compilers that do not support enable_if */ \
BOOST_STATIC_ASSERT(( \
is_interoperable< Derived1, Derived2 >::value && \
boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived1 >::type, random_access_traversal_tag >::value && \
boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived2 >::type, random_access_traversal_tag >::value \
)); \
return_prefix iterator_core_access::base_op( \
*static_cast<Derived1 const*>(&lhs) \
, *static_cast<Derived2 const*>(&rhs) \
, BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
); \
}
# define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \
op \
, boost::iterators::detail::always_bool2 \
, return_prefix \
, base_op \
)
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
# undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
// operator- requires an additional part in the static assertion
BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
BOOST_ITERATOR_FACADE_INTEROP(
-
, boost::iterators::detail::choose_difference_type
, boost::detail::choose_difference_type
, return
, distance_from
)
# undef BOOST_ITERATOR_FACADE_INTEROP
# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
# define BOOST_ITERATOR_FACADE_PLUS(args) \
BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
@ -952,28 +859,18 @@ namespace iterators {
return tmp += n; \
}
BOOST_ITERATOR_FACADE_PLUS((
iterator_facade<Derived, V, TC, R, D> const& i
, typename Derived::difference_type n
))
BOOST_ITERATOR_FACADE_PLUS((
iterator_facade<Derived, V, TC, R, D> const& i
, typename Derived::difference_type n
))
BOOST_ITERATOR_FACADE_PLUS((
typename Derived::difference_type n
BOOST_ITERATOR_FACADE_PLUS((
typename Derived::difference_type n
, iterator_facade<Derived, V, TC, R, D> const& i
))
))
# undef BOOST_ITERATOR_FACADE_PLUS
# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
} // namespace iterators
using iterators::iterator_core_access;
using iterators::iterator_facade;
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>

View File

@ -5,57 +5,88 @@
#ifndef ITERATOR_TRAITS_DWA200347_HPP
# define ITERATOR_TRAITS_DWA200347_HPP
# include <boost/detail/iterator.hpp>
# include <boost/detail/workaround.hpp>
#include <iterator>
namespace boost {
namespace boost {
namespace iterators {
// Unfortunately, g++ 2.95.x chokes when we define a class template
// iterator_category which has the same name as its
// std::iterator_category() function, probably due in part to the
// "std:: is visible globally" hack it uses. Use
// BOOST_ITERATOR_CATEGORY to write code that's portable to older
// GCCs.
// Macro for supporting old compilers, no longer needed but kept
// for backwards compatibility (it was documented).
#define BOOST_ITERATOR_CATEGORY iterator_category
# if BOOST_WORKAROUND(__GNUC__, <= 2)
# define BOOST_ITERATOR_CATEGORY iterator_category_
# else
# define BOOST_ITERATOR_CATEGORY iterator_category
# endif
template <class Iterator>
struct iterator_value
{
typedef typename std::iterator_traits<Iterator>::value_type type;
typedef typename boost::detail::iterator_traits<Iterator>::value_type type;
};
template <class Iterator>
struct iterator_reference
{
typedef typename std::iterator_traits<Iterator>::reference type;
typedef typename boost::detail::iterator_traits<Iterator>::reference type;
};
template <class Iterator>
struct iterator_pointer
{
typedef typename std::iterator_traits<Iterator>::pointer type;
typedef typename boost::detail::iterator_traits<Iterator>::pointer type;
};
template <class Iterator>
struct iterator_difference
{
typedef typename std::iterator_traits<Iterator>::difference_type type;
typedef typename boost::detail::iterator_traits<Iterator>::difference_type type;
};
template <class Iterator>
struct iterator_category
struct BOOST_ITERATOR_CATEGORY
{
typedef typename std::iterator_traits<Iterator>::iterator_category type;
typedef typename boost::detail::iterator_traits<Iterator>::iterator_category type;
};
} // namespace iterators
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <>
struct iterator_value<int>
{
typedef void type;
};
template <>
struct iterator_reference<int>
{
typedef void type;
};
using iterators::iterator_value;
using iterators::iterator_reference;
using iterators::iterator_pointer;
using iterators::iterator_difference;
using iterators::iterator_category;
template <>
struct iterator_pointer<int>
{
typedef void type;
};
template <>
struct iterator_difference<int>
{
typedef void type;
};
template <>
struct BOOST_ITERATOR_CATEGORY<int>
{
typedef void type;
};
# endif
} // namespace boost
} // namespace boost::iterator
#endif // ITERATOR_TRAITS_DWA200347_HPP

View File

@ -1,95 +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 BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
# define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
# include <boost/static_assert.hpp>
# include <boost/type_traits/is_convertible.hpp>
# include <boost/type_traits/is_same.hpp>
# include <boost/mpl/placeholders.hpp>
# include <boost/mpl/aux_/lambda_support.hpp>
namespace boost {
namespace iterators {
namespace detail {
template <bool GreaterEqual, bool LessEqual>
struct minimum_category_impl;
template <class T1, class T2>
struct error_not_related_by_convertibility;
template <>
struct minimum_category_impl<true,false>
{
template <class T1, class T2> struct apply
{
typedef T2 type;
};
};
template <>
struct minimum_category_impl<false,true>
{
template <class T1, class T2> struct apply
{
typedef T1 type;
};
};
template <>
struct minimum_category_impl<true,true>
{
template <class T1, class T2> struct apply
{
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
typedef T1 type;
};
};
template <>
struct minimum_category_impl<false,false>
{
template <class T1, class T2> struct apply
: error_not_related_by_convertibility<T1,T2>
{
};
};
} // namespace detail
//
// Returns the minimum category type or fails to compile
// if T1 and T2 are unrelated.
//
template <class T1 = mpl::_1, class T2 = mpl::_2>
struct minimum_category
{
typedef boost::iterators::detail::minimum_category_impl<
::boost::is_convertible<T1,T2>::value
, ::boost::is_convertible<T2,T1>::value
> outer;
typedef typename outer::template apply<T1,T2> inner;
typedef typename inner::type type;
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
};
template <>
struct minimum_category<mpl::_1,mpl::_2>
{
template <class T1, class T2>
struct apply : minimum_category<T1,T2>
{};
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2))
};
} // namespace iterators
} // namespace boost
#endif // BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_

View File

@ -29,18 +29,17 @@
// (David Abrahams)
# include <iterator>
# include <boost/type_traits.hpp>
# include <boost/static_assert.hpp>
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
# include <boost/detail/iterator.hpp>
# 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/iterator/detail/config_def.hpp>
# include <boost/detail/is_incrementable.hpp>
# include <boost/core/lightweight_test.hpp>
# include <boost/detail/lightweight_test.hpp>
namespace boost {
@ -77,7 +76,7 @@ template <class Iterator, class T>
void readable_iterator_test(const Iterator i1, T v)
{
Iterator i2(i1); // Copy Constructible
typedef typename std::iterator_traits<Iterator>::reference ref_t;
typedef typename detail::iterator_traits<Iterator>::reference ref_t;
ref_t r1 = *i1;
ref_t r2 = *i2;
T v1 = r1;
@ -87,11 +86,11 @@ void readable_iterator_test(const Iterator i1, T v)
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
// 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
# endif
}
template <class Iterator, class T>
@ -106,16 +105,16 @@ void writable_iterator_test(Iterator i, T v, T v2)
detail::is_incrementable<Iterator>
, detail::is_postfix_incrementable<Iterator>
>());
# endif
# endif
}
template <class Iterator>
void swappable_iterator_test(Iterator i, Iterator j)
{
Iterator i2(i), j2(j);
typename std::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
typename detail::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
iter_swap(i2, j2);
typename std::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
typename detail::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
BOOST_TEST(bi == aj && bj == ai);
}
@ -123,37 +122,37 @@ template <class Iterator, class T>
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;
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
typedef typename detail::iterator_traits<Iterator>::reference reference;
BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
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
# endif
}
template <class Iterator, class T>
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;
typedef typename detail::iterator_traits<Iterator>::value_type value_type;
typedef typename detail::iterator_traits<Iterator>::reference reference;
BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
T& v3 = *i2;
BOOST_TEST(v1 == v3);
// A non-const lvalue iterator is not neccessarily 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
# endif
}
template <class Iterator, class T>
@ -230,7 +229,7 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
{
BOOST_TEST(i == j + c);
BOOST_TEST(*i == vals[c]);
typename std::iterator_traits<Iterator>::value_type x = j[c];
typename detail::iterator_traits<Iterator>::value_type x = j[c];
BOOST_TEST(*i == x);
BOOST_TEST(*i == *(j + c));
BOOST_TEST(*i == *(c + j));
@ -246,9 +245,9 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
{
BOOST_TEST(i == k - c);
BOOST_TEST(*i == vals[N - 1 - c]);
typename std::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
typename detail::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
BOOST_TEST(*i == x);
Iterator q = k - c;
Iterator q = k - c;
BOOST_TEST(*i == *q);
BOOST_TEST(i > j);
BOOST_TEST(i >= j);

View File

@ -13,28 +13,28 @@
#include <boost/iterator/iterator_adaptor.hpp>
namespace boost {
namespace iterators {
namespace boost
{
template< class ElementIterator
, class IndexIterator>
class permutation_iterator
: public iterator_adaptor<
: public iterator_adaptor<
permutation_iterator<ElementIterator, IndexIterator>
, IndexIterator, typename std::iterator_traits<ElementIterator>::value_type
, use_default, typename std::iterator_traits<ElementIterator>::reference>
, IndexIterator, typename detail::iterator_traits<ElementIterator>::value_type
, use_default, typename detail::iterator_traits<ElementIterator>::reference>
{
typedef iterator_adaptor<
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;
, IndexIterator, typename detail::iterator_traits<ElementIterator>::value_type
, use_default, typename detail::iterator_traits<ElementIterator>::reference> super_t;
friend class iterator_core_access;
public:
permutation_iterator() : m_elt_iter() {}
explicit permutation_iterator(ElementIterator x, IndexIterator y)
explicit permutation_iterator(ElementIterator x, IndexIterator y)
: super_t(y), m_elt_iter(x) {}
template<class OtherElementIterator, class OtherIndexIterator>
@ -54,22 +54,18 @@ private:
template <class,class> friend class permutation_iterator;
#else
public:
#endif
#endif
ElementIterator m_elt_iter;
};
template <class ElementIterator, class IndexIterator>
inline permutation_iterator<ElementIterator, IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator( ElementIterator e, IndexIterator i )
{
return permutation_iterator<ElementIterator, IndexIterator>( e, i );
}
} // namespace iterators
using iterators::permutation_iterator;
using iterators::make_permutation_iterator;
} // namespace boost

View File

@ -7,10 +7,12 @@
#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
#include <boost/iterator.hpp>
#include <boost/utility.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
namespace boost {
namespace iterators {
namespace boost
{
//
//
@ -26,7 +28,7 @@ namespace iterators {
public:
reverse_iterator() {}
explicit reverse_iterator(Iterator x)
explicit reverse_iterator(Iterator x)
: super_t(x) {}
template<class OtherIterator>
@ -38,19 +40,14 @@ namespace iterators {
{}
private:
typename super_t::reference dereference() const
{
Iterator it = this->base_reference();
--it;
return *it;
}
typename super_t::reference dereference() const { return *boost::prior(this->base()); }
void increment() { --this->base_reference(); }
void decrement() { ++this->base_reference(); }
void advance(typename super_t::difference_type n)
{
this->base_reference() -= n;
this->base_reference() += -n;
}
template <class OtherIterator>
@ -62,16 +59,11 @@ namespace iterators {
};
template <class BidirectionalIterator>
inline reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x)
reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x)
{
return reverse_iterator<BidirectionalIterator>(x);
}
} // namespace iterators
using iterators::reverse_iterator;
using iterators::make_reverse_iterator;
} // namespace boost
#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP

View File

@ -7,11 +7,12 @@
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/iterator.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_class.hpp>
@ -21,41 +22,33 @@
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/result_of.hpp>
#include <iterator>
#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/type_traits/is_base_and_derived.hpp>
#endif
#include <boost/iterator/detail/config_def.hpp>
namespace boost {
namespace iterators {
namespace boost
{
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
class transform_iterator;
namespace detail
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:
typedef typename std::iterator_traits<Iterator>::reference Arg1;
// 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
, result_of<UnaryFunc(typename std::iterator_traits<Iterator>::value_type)>
>::type reference;
// To get the default for Value: remove any reference on the
@ -81,10 +74,10 @@ namespace iterators {
template <class UnaryFunc, class Iterator, class Reference, class Value>
class transform_iterator
: public boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
: public boost::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
{
typedef typename
boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
boost::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
super_t;
friend class iterator_core_access;
@ -104,7 +97,7 @@ namespace iterators {
// 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
#endif
}
template <
@ -117,7 +110,7 @@ namespace iterators {
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
, typename enable_if_convertible<OtherUnaryFunction, UnaryFunc>::type* = 0
#endif
#endif
)
: super_t(t.base()), m_f(t.functor())
{}
@ -135,7 +128,7 @@ namespace iterators {
};
template <class UnaryFunc, class Iterator>
inline transform_iterator<UnaryFunc, Iterator>
transform_iterator<UnaryFunc, Iterator>
make_transform_iterator(Iterator it, UnaryFunc fun)
{
return transform_iterator<UnaryFunc, Iterator>(it, fun);
@ -149,29 +142,31 @@ namespace iterators {
// function pointer in the iterator be 0, leading to a runtime
// crash.
template <class UnaryFunc, class Iterator>
inline typename iterators::enable_if<
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
typename mpl::if_<
#else
typename iterators::enable_if<
#endif
is_class<UnaryFunc> // We should probably find a cheaper test than is_class<>
, transform_iterator<UnaryFunc, Iterator>
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
, int[3]
#endif
>::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)
#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>
transform_iterator< Return (*)(Argument), Iterator, Return>
make_transform_iterator(Iterator it, Return (*fun)(Argument))
{
return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
}
#endif
} // namespace iterators
using iterators::transform_iterator;
using iterators::make_transform_iterator;
} // namespace boost
#include <boost/iterator/detail/config_undef.hpp>

View File

@ -1,46 +1,55 @@
// Copyright David Abrahams and Thomas Becker 2000-2006.
// Copyright Kohei Takahashi 2012-2014.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// Copyright David Abrahams and Thomas Becker 2000-2006. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// 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.hpp>
#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/detail/iterator.hpp>
#include <boost/iterator/minimum_category.hpp>
#include <boost/iterator/detail/minimum_category.hpp>
#include <utility> // for std::pair
#include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/algorithm/transformation/transform.hpp>
#include <boost/fusion/sequence/convert.hpp>
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
#include <boost/fusion/sequence/comparison/equal_to.hpp>
#include <boost/fusion/support/tag_of_fwd.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
namespace boost {
namespace iterators {
// Zip iterator forward declaration for zip_iterator_base
template<typename IteratorTuple>
class zip_iterator;
// One important design goal of the zip_iterator is to isolate all
// functionality whose implementation relies on the current tuple
// implementation. This goal has been achieved as follows: Inside
// the namespace detail there is a namespace tuple_impl_specific.
// This namespace encapsulates all functionality that is specific
// to the current Boost tuple implementation. More precisely, the
// namespace tuple_impl_specific provides the following tuple
// algorithms and meta-algorithms for the current Boost tuple
// implementation:
//
// tuple_meta_transform
// tuple_meta_accumulate
// tuple_transform
// tuple_for_each
//
// If the tuple implementation changes, all that needs to be
// replaced is the implementation of these four (meta-)algorithms.
namespace detail
{
@ -51,7 +60,7 @@ namespace iterators {
{
public:
advance_iterator(DiffType step) : m_step(step) {}
template<typename Iterator>
void operator()(Iterator& it) const
{ it += m_step; }
@ -63,102 +72,337 @@ namespace iterators {
struct increment_iterator
{
template<typename Iterator>
void operator()(Iterator& it) const
void operator()(Iterator& it)
{ ++it; }
};
//
struct decrement_iterator
{
template<typename Iterator>
void operator()(Iterator& it) const
void operator()(Iterator& it)
{ --it; }
};
//
struct dereference_iterator
{
template<typename>
struct result;
template<typename This, typename Iterator>
struct result<This(Iterator)>
{
template<typename Iterator>
struct apply
{
typedef typename
remove_cv<typename remove_reference<Iterator>::type>::type
iterator;
typedef typename iterator_reference<iterator>::type type;
iterator_traits<Iterator>::reference
type;
};
template<typename Iterator>
typename result<dereference_iterator(Iterator)>::type
operator()(Iterator const& it) const
typename apply<Iterator>::type operator()(Iterator const& it)
{ return *it; }
};
// The namespace tuple_impl_specific provides two meta-
// algorithms and two algorithms for tuples.
//
namespace tuple_impl_specific
{
// Meta-transform algorithm for tuples
//
template<typename Tuple, class UnaryMetaFun>
struct tuple_meta_transform;
template<typename Tuple, class UnaryMetaFun>
struct tuple_meta_transform_impl
{
typedef tuples::cons<
typename mpl::apply1<
typename mpl::lambda<UnaryMetaFun>::type
, typename Tuple::head_type
>::type
, typename tuple_meta_transform<
typename Tuple::tail_type
, UnaryMetaFun
>::type
> type;
};
template<typename Tuple, class UnaryMetaFun>
struct tuple_meta_transform
: mpl::eval_if<
boost::is_same<Tuple, tuples::null_type>
, mpl::identity<tuples::null_type>
, tuple_meta_transform_impl<Tuple, UnaryMetaFun>
>
{
};
// Meta-accumulate algorithm for tuples. Note: The template
// parameter StartType corresponds to the initial value in
// ordinary accumulation.
//
template<class Tuple, class BinaryMetaFun, class StartType>
struct tuple_meta_accumulate;
template<
typename Tuple
, class BinaryMetaFun
, typename StartType
>
struct tuple_meta_accumulate_impl
{
typedef typename mpl::apply2<
typename mpl::lambda<BinaryMetaFun>::type
, typename Tuple::head_type
, typename tuple_meta_accumulate<
typename Tuple::tail_type
, BinaryMetaFun
, StartType
>::type
>::type type;
};
template<
typename Tuple
, class BinaryMetaFun
, typename StartType
>
struct tuple_meta_accumulate
: mpl::eval_if<
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
mpl::or_<
#endif
boost::is_same<Tuple, tuples::null_type>
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
, boost::is_same<Tuple,int>
>
#endif
, mpl::identity<StartType>
, tuple_meta_accumulate_impl<
Tuple
, BinaryMetaFun
, StartType
>
>
{
};
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|| ( \
BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, != 0) && defined(_MSC_VER) \
)
// Not sure why intel's partial ordering fails in this case, but I'm
// assuming int's an MSVC bug-compatibility feature.
# define BOOST_TUPLE_ALGO_DISPATCH
# define BOOST_TUPLE_ALGO(algo) algo##_impl
# define BOOST_TUPLE_ALGO_TERMINATOR , int
# define BOOST_TUPLE_ALGO_RECURSE , ...
#else
# define BOOST_TUPLE_ALGO(algo) algo
# define BOOST_TUPLE_ALGO_TERMINATOR
# define BOOST_TUPLE_ALGO_RECURSE
#endif
// transform algorithm for tuples. The template parameter Fun
// must be a unary functor which is also a unary metafunction
// class that computes its return type based on its argument
// type. For example:
//
// struct to_ptr
// {
// template <class Arg>
// struct apply
// {
// typedef Arg* type;
// }
//
// template <class Arg>
// Arg* operator()(Arg x);
// };
template<typename Fun>
tuples::null_type BOOST_TUPLE_ALGO(tuple_transform)
(tuples::null_type const&, Fun BOOST_TUPLE_ALGO_TERMINATOR)
{ return tuples::null_type(); }
template<typename Tuple, typename Fun>
typename tuple_meta_transform<
Tuple
, Fun
>::type
BOOST_TUPLE_ALGO(tuple_transform)(
const Tuple& t,
Fun f
BOOST_TUPLE_ALGO_RECURSE
)
{
typedef typename tuple_meta_transform<
BOOST_DEDUCED_TYPENAME Tuple::tail_type
, Fun
>::type transformed_tail_type;
return tuples::cons<
BOOST_DEDUCED_TYPENAME mpl::apply1<
Fun, BOOST_DEDUCED_TYPENAME Tuple::head_type
>::type
, transformed_tail_type
>(
f(boost::tuples::get<0>(t)), tuple_transform(t.get_tail(), f)
);
}
#ifdef BOOST_TUPLE_ALGO_DISPATCH
template<typename Tuple, typename Fun>
typename tuple_meta_transform<
Tuple
, Fun
>::type
tuple_transform(
const Tuple& t,
Fun f
)
{
return tuple_transform_impl(t, f, 1);
}
#endif
// for_each algorithm for tuples.
//
template<typename Fun>
Fun BOOST_TUPLE_ALGO(tuple_for_each)(
tuples::null_type
, Fun f BOOST_TUPLE_ALGO_TERMINATOR
)
{ return f; }
template<typename Tuple, typename Fun>
Fun BOOST_TUPLE_ALGO(tuple_for_each)(
Tuple& t
, Fun f BOOST_TUPLE_ALGO_RECURSE)
{
f( t.get_head() );
return tuple_for_each(t.get_tail(), f);
}
#ifdef BOOST_TUPLE_ALGO_DISPATCH
template<typename Tuple, typename Fun>
Fun
tuple_for_each(
Tuple& t,
Fun f
)
{
return tuple_for_each_impl(t, f, 1);
}
#endif
// Equality of tuples. NOTE: "==" for tuples currently (7/2003)
// has problems under some compilers, so I just do my own.
// No point in bringing in a bunch of #ifdefs here. This is
// going to go away with the next tuple implementation anyway.
//
inline bool tuple_equal(tuples::null_type, tuples::null_type)
{ return true; }
template<typename Tuple1, typename Tuple2>
bool tuple_equal(
Tuple1 const& t1,
Tuple2 const& t2
)
{
return t1.get_head() == t2.get_head() &&
tuple_equal(t1.get_tail(), t2.get_tail());
}
}
//
// end namespace tuple_impl_specific
template<typename Iterator>
struct iterator_reference
{
typedef typename iterator_traits<Iterator>::reference type;
};
#ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. Instantiating the nested apply template also
// requires instantiating iterator_traits on the
// placeholder. Instead we just specialize it as a metafunction
// class.
template<>
struct iterator_reference<mpl::_1>
{
template <class T>
struct apply : iterator_reference<T> {};
};
#endif
// Metafunction to obtain the type of the tuple whose element types
// are the reference types of an iterator tuple.
//
template<typename IteratorTuple>
struct tuple_of_references
: mpl::transform<
IteratorTuple,
: tuple_impl_specific::tuple_meta_transform<
IteratorTuple,
iterator_reference<mpl::_1>
>
{
};
// Specialization for std::pair
template<typename Iterator1, typename Iterator2>
struct tuple_of_references<std::pair<Iterator1, Iterator2> >
{
typedef std::pair<
typename iterator_reference<Iterator1>::type
, typename iterator_reference<Iterator2>::type
> type;
};
// Metafunction to obtain the minimal traversal tag in a tuple
// of iterators.
//
template<typename IteratorTuple>
struct minimum_traversal_category_in_iterator_tuple
{
typedef typename mpl::transform<
typedef typename tuple_impl_specific::tuple_meta_transform<
IteratorTuple
, pure_traversal_tag<iterator_traversal<> >
>::type tuple_of_traversal_tags;
typedef typename mpl::fold<
typedef typename tuple_impl_specific::tuple_meta_accumulate<
tuple_of_traversal_tags
, random_access_traversal_tag
, minimum_category<>
, random_access_traversal_tag
>::type type;
};
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;
typedef typename minimum_category<
iterator1_traversal
, typename minimum_category<
iterator2_traversal
, random_access_traversal_tag
>::type
>::type type;
};
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) // ETI workaround
template <>
struct minimum_traversal_category_in_iterator_tuple<int>
{
typedef int type;
};
#endif
// We need to call tuple_meta_accumulate with mpl::and_ as the
// accumulating functor. To this end, we need to wrap it into
// a struct that has exactly two arguments (that is, template
// parameters) and not five, like mpl::and_ does.
//
template<typename Arg1, typename Arg2>
struct and_with_two_args
: mpl::and_<Arg1, Arg2>
{
};
# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
// out well. In this case I think it's an MPL bug
template<>
struct and_with_two_args<mpl::_1,mpl::_2>
{
template <class A1, class A2>
struct apply : mpl::and_<A1,A2>
{};
};
# endif
///////////////////////////////////////////////////////////////////
//
// Class zip_iterator_base
//
// Builds and exposes the iterator facade type from which the zip
// Builds and exposes the iterator facade type from which the zip
// iterator will be derived.
//
template<typename IteratorTuple>
@ -167,30 +411,30 @@ namespace iterators {
private:
// Reference type is the type of the tuple obtained from the
// iterators' reference types.
typedef typename
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
typedef typename iterator_traits<
typename tuples::element<0, IteratorTuple>::type
>::difference_type difference_type;
// Traversal catetgory is the minimum traversal category in the
// iterator tuple.
typedef typename
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,
value_type,
traversal_category,
reference,
difference_type
@ -202,59 +446,35 @@ namespace iterators {
{
typedef int type;
};
template <typename reference>
struct converter
{
template <typename Seq>
static reference call(Seq seq)
{
typedef typename fusion::traits::tag_of<reference>::type tag;
return fusion::convert<tag>(seq);
}
};
template <typename Reference1, typename Reference2>
struct converter<std::pair<Reference1, Reference2> >
{
typedef std::pair<Reference1, Reference2> reference;
template <typename Seq>
static reference call(Seq seq)
{
return reference(
fusion::at_c<0>(seq)
, fusion::at_c<1>(seq));
}
};
}
/////////////////////////////////////////////////////////////////////
//
// zip_iterator class definition
//
template<typename IteratorTuple>
class zip_iterator :
class zip_iterator :
public detail::zip_iterator_base<IteratorTuple>::type
{
{
// Typedef super_t as our base class.
typedef typename
// 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:
// Construction
// ============
// Default constructor
zip_iterator() { }
// 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
@ -273,19 +493,18 @@ namespace iterators {
{ return m_iterator_tuple; }
private:
// Implementation of Iterator Operations
// =====================================
// Dereferencing returns a tuple built from the dereferenced
// 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()));
{
return detail::tuple_impl_specific::tuple_transform(
get_iterator_tuple(),
detail::dereference_iterator()
);
}
// Two zip iterators are equal if all iterators in the iterator
@ -298,70 +517,69 @@ namespace iterators {
// under several compilers. No point in bringing in a bunch
// of #ifdefs here.
//
template<typename OtherIteratorTuple>
template<typename OtherIteratorTuple>
bool equal(const zip_iterator<OtherIteratorTuple>& other) const
{
return fusion::equal_to(
get_iterator_tuple(),
other.get_iterator_tuple());
return detail::tuple_impl_specific::tuple_equal(
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(
{
detail::tuple_impl_specific::tuple_for_each(
m_iterator_tuple,
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n));
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n)
);
}
// Incrementing a zip iterator means to increment all iterators in
// the iterator tuple.
void increment()
{
fusion::for_each(
m_iterator_tuple,
detail::increment_iterator());
{
detail::tuple_impl_specific::tuple_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());
{
detail::tuple_impl_specific::tuple_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
{
return fusion::at_c<0>(other.get_iterator_tuple()) -
fusion::at_c<0>(this->get_iterator_tuple());
{
return boost::tuples::get<0>(other.get_iterator_tuple()) -
boost::tuples::get<0>(this->get_iterator_tuple());
}
// Data Members
// ============
// The iterator tuple.
IteratorTuple m_iterator_tuple;
};
// Make function for zip iterator
//
template<typename IteratorTuple>
inline zip_iterator<IteratorTuple>
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
make_zip_iterator(IteratorTuple t)
{ return zip_iterator<IteratorTuple>(t); }
} // namespace iterators
using iterators::zip_iterator;
using iterators::make_zip_iterator;
} // namespace boost
}
#endif

View File

@ -1,195 +0,0 @@
// Boost next_prior.hpp header file ---------------------------------------//
// (C) Copyright Dave Abrahams and Daniel Walker 1999-2003.
// Copyright (c) Andrey Semashev 2017
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/utility for documentation.
// Revision History
// 13 Dec 2003 Added next(x, n) and prior(x, n) (Daniel Walker)
#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/advance.hpp>
#include <boost/iterator/reverse_iterator.hpp>
namespace boost {
// Helper functions for classes like bidirectional iterators not supporting
// operator+ and operator-
//
// Usage:
// const std::list<T>::iterator p = get_some_iterator();
// const std::list<T>::iterator prev = boost::prior(p);
// const std::list<T>::iterator next = boost::next(prev, 2);
// Contributed by Dave Abrahams
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;
template< typename T, typename Distance >
struct next_plus_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
return x + n;
}
};
template< typename T, typename Distance, bool HasPlusAssign = has_plus_assign< T, Distance >::value >
struct next_plus_assign_impl :
public next_plus_impl< T, Distance >
{
};
template< typename T, typename Distance >
struct next_plus_assign_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
x += n;
return x;
}
};
template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value >
struct next_advance_impl :
public next_plus_assign_impl< T, Distance >
{
};
template< typename T, typename Distance >
struct next_advance_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
boost::iterators::advance(x, n);
return x;
}
};
template< typename T, typename Distance, bool HasMinus = has_minus< T, Distance >::value >
struct prior_minus_impl;
template< typename T, typename Distance >
struct prior_minus_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
return x - n;
}
};
template< typename T, typename Distance, bool HasMinusAssign = has_minus_assign< T, Distance >::value >
struct prior_minus_assign_impl :
public prior_minus_impl< T, Distance >
{
};
template< typename T, typename Distance >
struct prior_minus_assign_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
x -= n;
return x;
}
};
template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value >
struct prior_advance_impl :
public prior_minus_assign_impl< T, Distance >
{
};
template< typename T, typename Distance >
struct prior_advance_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
// Avoid negating n to sidestep possible integer overflow
boost::iterators::reverse_iterator< T > rx(x);
boost::iterators::advance(rx, n);
return rx.base();
}
};
} // namespace next_prior_detail
template <class T>
inline T next(T x) { return ++x; }
template <class T, class Distance>
inline T next(T x, Distance n)
{
return next_prior_detail::next_advance_impl< T, Distance >::call(x, n);
}
template <class T>
inline T prior(T x) { return --x; }
template <class T, class Distance>
inline T prior(T x, Distance n)
{
return next_prior_detail::prior_advance_impl< T, Distance >::call(x, n);
}
} // namespace boost
#endif // BOOST_NEXT_PRIOR_HPP_INCLUDED

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