mirror of
https://github.com/boostorg/iterator.git
synced 2025-06-26 04:21:36 +02:00
Compare commits
1 Commits
boost-1.72
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
a9b594c925 |
390
.travis.yml
390
.travis.yml
@ -1,390 +0,0 @@
|
||||
# Copyright 2016, 2017 Peter Dimov
|
||||
# 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)
|
||||
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
python: "2.7"
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- /feature\/.*/
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
|
||||
exclude:
|
||||
- env: BOGUS_JOB=true
|
||||
|
||||
include:
|
||||
# gcc, Linux
|
||||
# Note: gcc-4.4 in C++0x mode fails zip_iterator tests with std::tuple
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: gcc-4.4
|
||||
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.4
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: gcc-4.6
|
||||
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: gcc-4.7
|
||||
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-4.8
|
||||
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-4.9
|
||||
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-5
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-6
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-7
|
||||
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-8
|
||||
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: gcc-9
|
||||
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-9
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: gcc-UBSAN
|
||||
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-9
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
|
||||
# clang, Linux
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: clang-3.5
|
||||
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.5
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.5 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: clang-3.6
|
||||
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
- libstdc++-5-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.6 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: clang-3.7
|
||||
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
- libstdc++-5-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.7 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-3.8
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
- libstdc++-6-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.8 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-3.9
|
||||
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
- libstdc++-6-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-4
|
||||
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-4.0
|
||||
- libstdc++-6-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-5
|
||||
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-5.0
|
||||
- libstdc++-7-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-5.0 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-6
|
||||
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-6.0
|
||||
- libstdc++-8-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-7
|
||||
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-7
|
||||
- libstdc++-8-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-7 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-8
|
||||
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-8
|
||||
- libstdc++-8-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-9
|
||||
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-9
|
||||
- libstdc++-9-dev
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-UBSAN
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-9
|
||||
- libstdc++-9-dev
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-libc++
|
||||
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a CXXFLAGS="-stdlib=libc++" LINKFLAGS="-stdlib=libc++"
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-9
|
||||
- libc++-9-dev
|
||||
- libc++abi-9-dev
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang-libc++-UBSAN
|
||||
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1 CXXFLAGS="-stdlib=libc++" LINKFLAGS="-stdlib=libc++"
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-9
|
||||
- libc++-9-dev
|
||||
- libc++abi-9-dev
|
||||
sources:
|
||||
- sourceline: "ppa:ubuntu-toolchain-r/test"
|
||||
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
|
||||
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
|
||||
|
||||
# clang, OS X
|
||||
# OS X builds are slow on Travis CI
|
||||
# - os: osx
|
||||
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
# osx_image: xcode9.4
|
||||
#
|
||||
# - os: osx
|
||||
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
# osx_image: xcode10.3
|
||||
|
||||
- os: osx
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17
|
||||
osx_image: xcode11.2
|
||||
|
||||
install:
|
||||
- GIT_FETCH_JOBS=8
|
||||
- BOOST_BRANCH=develop
|
||||
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
|
||||
- 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
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/iterator
|
||||
- python tools/boostdep/depinst/depinst.py --git_args "--jobs $GIT_FETCH_JOBS" iterator
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
- BUILD_JOBS=`(nproc || sysctl -n hw.ncpu) 2> /dev/null`
|
||||
- ./b2 -j $BUILD_JOBS libs/iterator/test toolset=$TOOLSET cxxstd=$CXXSTD ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on visibility=global} ${CXXFLAGS:+cxxflags="$CXXFLAGS"} ${LINKFLAGS:+linkflags="$LINKFLAGS"}
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
@ -1,34 +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
|
||||
|
||||
# Partial (add_subdirectory only) and experimental CMake support
|
||||
# Subject to change; please do not rely on the contents of this file yet.
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(BoostIterator 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
|
||||
)
|
80
appveyor.yml
80
appveyor.yml
@ -1,80 +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,msvc-12.0
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
- TOOLSET: msvc-14.0
|
||||
ADDRMD: 32,64
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
- TOOLSET: msvc-14.1
|
||||
CXXSTD: 14,17
|
||||
ADDRMD: 32,64
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
- TOOLSET: msvc-14.2
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
- TOOLSET: clang-win
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17
|
||||
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%
|
@ -13,15 +13,10 @@ 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
|
||||
<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 ;
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 <class Generator>
|
||||
class generator_iterator_policies;
|
||||
|
||||
template <class Generator>
|
||||
class generator_iterator_generator;
|
||||
|
||||
template <class Generator>
|
||||
typename generator_iterator_generator<Generator>::type
|
||||
make_generator_iterator(Generator & gen);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<h2>The Generator Iterator Generator Class</h2>
|
||||
|
||||
<p>The class generator_iterator_generator is a helper class whose purpose
|
||||
is to construct a generator iterator type. The template parameter for this
|
||||
class is the Generator function object type that is being wrapped. The
|
||||
generator iterator adaptor only holds a reference (or pointer) to the
|
||||
function object, therefore the function object must outlive the generator
|
||||
iterator adaptor constructed from it.</p>
|
||||
<pre>
|
||||
template <class Generator>
|
||||
class generator_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <i>unspecified</i> type; // the resulting generator iterator type
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border summary="">
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt><a href=
|
||||
"http://www.sgi.com/tech/stl/Generator.html">Generator</a></tt></td>
|
||||
|
||||
<td>The generator (0-ary function object) type being wrapped. The
|
||||
return type of the function must be defined as
|
||||
<tt>Generator::result_type</tt>. The function object must be a model of
|
||||
<a href=
|
||||
"http://www.sgi.com/tech/stl/Generator.html">Generator</a>.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
|
||||
<p>The generator iterator class is a model of <a href=
|
||||
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.</p>
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
<p>The generator iterator implements the member functions and operators
|
||||
required of the <a href=
|
||||
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>
|
||||
concept.<br></p>
|
||||
<hr>
|
||||
|
||||
<h2><a name="make_generator_iterator" id="make_generator_iterator">The
|
||||
Generator Iterator Object Generator</a></h2>
|
||||
|
||||
<p>The <tt>make_generator_iterator()</tt> function provides a convenient
|
||||
way to create generator iterator objects. The function saves the user the
|
||||
trouble of explicitly writing out the iterator types.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class Generator>
|
||||
typename generator_iterator_generator<Generator>::type
|
||||
make_generator_iterator(Generator & gen);
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
<p>The following program shows how <code>generator_iterator</code>
|
||||
transforms a generator into an input iterator.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <iostream>
|
||||
#include <boost/generator_iterator.hpp>
|
||||
|
||||
class my_generator
|
||||
{
|
||||
public:
|
||||
typedef int result_type;
|
||||
my_generator() : state(0) { }
|
||||
int operator()() { return ++state; }
|
||||
private:
|
||||
int state;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
my_generator gen;
|
||||
boost::generator_iterator_generator<my_generator>::type it = boost::make_generator_iterator(gen);
|
||||
for(int i = 0; i < 10; ++i, ++it)
|
||||
std::cout << *it << std::endl;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
|
||||
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
|
||||
height="31" width="88"></a></p>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
|
||||
|
||||
<p><i>Copyright © 2001 <a href=
|
||||
"http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a></i></p>
|
||||
|
||||
<p><i>Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
|
||||
copy at <a href=
|
||||
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
|
||||
</body>
|
||||
</html>
|
@ -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
|
||||
|
@ -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
|
||||
------
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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`:
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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"><boost/iterator/iterator_traits.hpp></tt> provides
|
||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">Header <tt class="docutils literal"><span class="pre"><boost/iterator/iterator_traits.hpp></span></tt> provides
|
||||
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 "multi-valued" traits template can be difficult to use in a
|
||||
metaprogramming context. <tt class="docutils literal"><boost/iterator/iterator_traits.hpp></tt>
|
||||
metaprogramming context. <tt class="docutils literal"><span class="pre"><boost/iterator/iterator_traits.hpp></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"><boost/iterator/iterator_traits.hpp></tt>:</p>
|
||||
<p>Header <tt class="docutils literal"><span class="pre"><boost/iterator/iterator_traits.hpp></span></tt>:</p>
|
||||
<pre class="literal-block">
|
||||
template <class Iterator>
|
||||
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" />
|
||||
|
@ -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
|
||||
|
||||
|
@ -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&</span></tt> (or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">T&</span></tt> once <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#200">issue 200</a>
|
||||
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is <tt class="docutils literal"><span class="pre">T&</span></tt> (or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">T&</span></tt> once <a class="reference external" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200">issue 200</a>
|
||||
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<bool>::iterator</span></tt> is almost a
|
||||
random access iterator, but the return type is not <tt class="docutils literal"><span class="pre">bool&</span></tt> (see
|
||||
<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<bool></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<X>::value</span></tt>
|
||||
yields <tt class="docutils literal"><span class="pre">true</span></tt> if, for an object <tt class="docutils literal"><span class="pre">a</span></tt> of type <tt class="docutils literal"><span class="pre">X</span></tt>, <tt class="docutils literal"><span class="pre">*a</span></tt> is
|
||||
convertible to <tt class="docutils literal"><span class="pre">iterator_traits<X>::value_type</span></tt>, and <tt class="docutils literal"><span class="pre">false</span></tt>
|
||||
@ -1007,7 +1007,7 @@ otherwise.</p>
|
||||
</div>
|
||||
<div 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
|
||||
|
@ -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
|
||||
|
@ -132,7 +132,7 @@ above are defined as follows:
|
||||
|
||||
iterator_adaptor();
|
||||
|
||||
[*Requires:] The `Base` type must be Default Constructible.[br]
|
||||
[*Requires:] The `Base` type must be Default Constructible.\n
|
||||
[*Returns:] An instance of `iterator_adaptor` with
|
||||
`m_iterator` default constructed.
|
||||
|
||||
@ -206,7 +206,7 @@ we're going to pick up right where it left off.
|
||||
.. |fac_tut| replace:: `iterator_facade` tutorial
|
||||
.. _fac_tut: 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
|
||||
|
@ -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]
|
@ -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]
|
@ -1,9 +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
|
||||
@ -32,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]
|
||||
@ -56,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]
|
||||
@ -80,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
|
||||
@ -106,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 ]
|
||||
@ -134,7 +129,7 @@ stated semantics.
|
||||
[``
|
||||
{
|
||||
X tmp = r;
|
||||
++r;
|
||||
++r;
|
||||
return tmp;
|
||||
}
|
||||
``]
|
||||
@ -146,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
|
||||
@ -163,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`]
|
||||
@ -175,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`]
|
||||
@ -187,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
|
||||
@ -212,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`]
|
||||
@ -219,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
|
||||
@ -233,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--`]
|
||||
@ -257,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
|
||||
@ -267,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]
|
||||
@ -278,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++)
|
||||
@ -291,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`]
|
||||
@ -312,9 +300,9 @@ constant object of type `Distance`.
|
||||
[`a - n`]
|
||||
[`X`]
|
||||
[``
|
||||
{
|
||||
{
|
||||
X tmp = a;
|
||||
return tmp-= n;
|
||||
return tmp-= n;
|
||||
}
|
||||
``]
|
||||
[]
|
||||
@ -332,7 +320,7 @@ constant object of type `Distance`.
|
||||
[pre: a is a *Readable Iterator*]
|
||||
]
|
||||
[
|
||||
[`a\[n\] = v`]
|
||||
[`a\[n\] = v`]
|
||||
[convertible to T]
|
||||
[`*(a + n) = v`]
|
||||
[pre: a is a *Writable iterator*]
|
||||
@ -371,6 +359,4 @@ constant object of type `Distance`.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
[endsect]
|
@ -152,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`.
|
||||
|
||||
|
||||
@ -174,13 +174,13 @@ operations.
|
||||
|
||||
counting_iterator& operator++();
|
||||
|
||||
[*Effects: ] `++m_inc`[br]
|
||||
[*Effects: ] `++m_inc`\n
|
||||
[*Returns: ] `*this`
|
||||
|
||||
|
||||
counting_iterator& operator--();
|
||||
|
||||
[*Effects: ] `--m_inc`[br]
|
||||
[*Effects: ] `--m_inc`\n
|
||||
[*Returns: ] `*this`
|
||||
|
||||
|
||||
|
@ -68,7 +68,6 @@ requirements.
|
||||
[
|
||||
[`i.dereference()`]
|
||||
[Access the value referred to]
|
||||
]
|
||||
[
|
||||
[`i.equal(j)`]
|
||||
[Compare for equality with `j`]
|
||||
@ -84,7 +83,6 @@ requirements.
|
||||
[
|
||||
[`i.advance(n)`]
|
||||
[Advance by `n` positions]
|
||||
]
|
||||
[
|
||||
[`i.distance_to(j)`]
|
||||
[Measure the distance to `j`]
|
||||
@ -141,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
|
||||
@ -167,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`:
|
||||
|
||||
@ -289,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:
|
||||
|
||||
@ -297,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:
|
||||
|
||||
@ -400,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`.
|
||||
|
||||
@ -417,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);
|
||||
@ -457,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);
|
||||
|
||||
@ -489,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,
|
||||
@ -508,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,
|
||||
@ -527,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,
|
||||
@ -546,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,
|
||||
@ -565,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,
|
||||
@ -584,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:
|
||||
|
||||
@ -605,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]
|
@ -261,17 +261,17 @@ __ ../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`.
|
||||
@ -285,7 +285,7 @@ changes:
|
||||
|
||||
class const_node_iterator
|
||||
: public boost::iterator_facade<
|
||||
const_node_iterator
|
||||
node_iterator
|
||||
, node_base **const**
|
||||
, boost::forward_traversal_tag
|
||||
>
|
||||
@ -312,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
|
||||
|
@ -178,7 +178,7 @@ operations.
|
||||
|
||||
filter_iterator();
|
||||
|
||||
[*Requires: ]`Predicate` and `Iterator` must be Default Constructible.[br]
|
||||
[*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.
|
||||
|
||||
@ -195,7 +195,7 @@ 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`
|
||||
or else`m_iter == end`. The member `m_pred` is default constructed.
|
||||
@ -205,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`.
|
||||
|
||||
|
||||
@ -235,7 +235,7 @@ 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]
|
||||
or `m_pred(*m_iter) == true`.\n
|
||||
[*Returns: ] `*this`
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ proxy object.
|
||||
|
||||
std::string s = "";
|
||||
std::copy(x.begin(), x.end(),
|
||||
boost::make_function_output_iterator(string_appender(s)));
|
||||
boost::make_function_output_iterator(string_appender(s)));
|
||||
|
||||
std::cout << s << std::endl;
|
||||
|
||||
@ -97,4 +97,4 @@ Incrementable Iterator concepts.
|
||||
|
||||
[*Returns: ] `*this`.
|
||||
|
||||
[endsect]
|
||||
[endsect]
|
@ -203,7 +203,7 @@ following operations:
|
||||
|
||||
indirect_iterator();
|
||||
|
||||
[*Requires: ] `Iterator` must be Default Constructible.[br]
|
||||
[*Requires: ] `Iterator` must be Default Constructible.\n
|
||||
[*Effects: ] Constructs an instance of `indirect_iterator` with
|
||||
a default-constructed `m_iterator`.
|
||||
|
||||
@ -225,7 +225,7 @@ following operations:
|
||||
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
|
||||
);
|
||||
|
||||
[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.[br]
|
||||
[*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]
|
@ -1,7 +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]
|
||||
@ -29,10 +28,7 @@
|
||||
|
||||
[/ Links ]
|
||||
|
||||
[def _iterator_ [@../../../iterator/doc/index.html Boost.Iterator]]
|
||||
[def _concept_check_ [@../../../concept_check/index.html Boost.ConceptCheck]]
|
||||
|
||||
[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]]
|
||||
@ -306,3 +265,4 @@ library you see today.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@ -1,55 +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]
|
@ -189,7 +189,7 @@ following operations.
|
||||
|
||||
permutation_iterator& operator++();
|
||||
|
||||
[*Effects: ] `++m_order`[br]
|
||||
[*Effects: ] `++m_order`\n
|
||||
[*Returns: ] `*this`
|
||||
|
||||
|
||||
|
@ -115,7 +115,7 @@ operations.
|
||||
|
||||
reverse_iterator();
|
||||
|
||||
[*Requires: ] `Iterator` must be Default Constructible.[br]
|
||||
[*Requires: ] `Iterator` must be Default Constructible.\n
|
||||
[*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator`
|
||||
default constructed.
|
||||
|
||||
@ -131,7 +131,7 @@ operations.
|
||||
, 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 instance of `reverse_iterator` whose
|
||||
`m_iterator` subobject is constructed from `y.base()`.
|
||||
|
||||
@ -149,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]
|
@ -56,7 +56,7 @@ original shared pointer `ints` ceases to exist after `set_range()`
|
||||
returns, the `shared_counter_iterator` objects maintain references to
|
||||
the underlying vector and thereby extend the container's lifetime.
|
||||
|
||||
[@../../example/shared_iterator_example1.cpp `shared_iterator_example1.cpp`]:
|
||||
[@../../../libs/utility/shared_iterator_example1.cpp `shared_iterator_example1.cpp`]:
|
||||
|
||||
#include "shared_container_iterator.hpp"
|
||||
#include "boost/shared_ptr.hpp"
|
||||
@ -139,7 +139,7 @@ explicitly specifying its type.
|
||||
This example, similar to the previous,
|
||||
uses `make_shared_container_iterator()` to create the iterators.
|
||||
|
||||
[@../../example/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"
|
||||
@ -200,7 +200,7 @@ 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/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"
|
||||
|
72
doc/quickbook/traits.qbk
Normal file
72
doc/quickbook/traits.qbk
Normal 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]
|
@ -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,10 +110,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.
|
||||
@ -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:
|
||||
|
||||
@ -183,7 +183,7 @@ operations:
|
||||
|
||||
[*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]
|
||||
|
@ -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
224
doc/quickbook/utilities.qbk
Normal 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]
|
@ -8,16 +8,6 @@ the zip iterator moves all the iterators in parallel.
|
||||
Dereferencing the zip iterator returns a tuple that contains
|
||||
the results of dereferencing the individual iterators.
|
||||
|
||||
The tuple of iterators is now implemented in terms of a Boost fusion sequence.
|
||||
Because of this the 'tuple' may be any Boost fusion sequence and, for backwards
|
||||
compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
|
||||
'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
|
||||
Boost fusion adapter exists. This includes, among others, a std::tuple and a std::pair.
|
||||
Just remember to include the appropriate Boost fusion adapter header files for these
|
||||
other Boost fusion adapters. The zip_iterator header file already includes the
|
||||
Boost fusion adapter header file for Boost tuple, so you need not include it yourself
|
||||
to use a Boost tuple as your 'tuple'.
|
||||
|
||||
[section:zip_example Example]
|
||||
|
||||
There are two main types of applications of the `zip_iterator`. The first
|
||||
@ -228,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`.
|
||||
|
||||
|
||||
@ -245,13 +235,13 @@ 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>
|
||||
|
@ -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
|
||||
|
@ -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<const UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>.
|
||||
<tt class="docutils literal"><span class="pre">result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>.
|
||||
Otherwise, <tt class="docutils literal"><span class="pre">reference</span></tt> is <tt class="docutils literal"><span class="pre">Reference</span></tt>.</p>
|
||||
<p>If <tt class="docutils literal"><span class="pre">Value</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">value_type</span></tt> member is
|
||||
<tt class="docutils literal"><span class="pre">remove_cv<remove_reference<reference></span> <span class="pre">>::type</span></tt>. Otherwise,
|
||||
@ -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<const UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>.</p>
|
||||
<tt class="docutils literal"><span class="pre">result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type</span></tt>.</p>
|
||||
<p>The argument <tt class="docutils literal"><span class="pre">Iterator</span></tt> shall model Readable Iterator.</p>
|
||||
</div>
|
||||
<div class="section" id="transform-iterator-models">
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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'.
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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));
|
||||
|
||||
|
@ -12,17 +12,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));
|
||||
|
||||
|
@ -12,17 +12,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));
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -16,10 +16,9 @@
|
||||
namespace boost {
|
||||
|
||||
template <class Operation>
|
||||
class binder1st {
|
||||
public:
|
||||
typedef typename Operation::result_type result_type;
|
||||
typedef typename Operation::second_argument_type argument_type;
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
@ -73,3 +72,5 @@ main(int, char*[])
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,14 +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/iterator/function_output_iterator.hpp>
|
||||
namespace boost {
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
|
@ -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
|
@ -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
|
59
include/boost/iterator.hpp
Normal file
59
include/boost/iterator.hpp
Normal 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
|
@ -1,84 +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/iterator/iterator_categories.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
namespace detail {
|
||||
template <typename InputIterator, typename Distance>
|
||||
inline BOOST_CXX14_CONSTEXPR void
|
||||
advance_impl(
|
||||
InputIterator& it
|
||||
, Distance n
|
||||
, incrementable_traversal_tag
|
||||
)
|
||||
{
|
||||
while (n > 0) {
|
||||
++it;
|
||||
--n;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename BidirectionalIterator, typename Distance>
|
||||
inline BOOST_CXX14_CONSTEXPR void
|
||||
advance_impl(
|
||||
BidirectionalIterator& it
|
||||
, Distance n
|
||||
, bidirectional_traversal_tag
|
||||
)
|
||||
{
|
||||
if (n >= 0) {
|
||||
while (n > 0) {
|
||||
++it;
|
||||
--n;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (n < 0) {
|
||||
--it;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RandomAccessIterator, typename Distance>
|
||||
inline BOOST_CXX14_CONSTEXPR void
|
||||
advance_impl(
|
||||
RandomAccessIterator& it
|
||||
, Distance n
|
||||
, random_access_traversal_tag
|
||||
)
|
||||
{
|
||||
it += n;
|
||||
}
|
||||
}
|
||||
|
||||
namespace advance_adl_barrier {
|
||||
template <typename InputIterator, typename Distance>
|
||||
inline BOOST_CXX14_CONSTEXPR void
|
||||
advance(InputIterator& it, Distance n)
|
||||
{
|
||||
detail::advance_impl(
|
||||
it, n, typename iterator_traversal<InputIterator>::type()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
using namespace advance_adl_barrier;
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using namespace iterators::advance_adl_barrier;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
@ -13,7 +13,6 @@
|
||||
# include <boost/mpl/eval_if.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template <
|
||||
class Incrementable
|
||||
@ -31,13 +30,13 @@ 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(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
@ -47,20 +46,20 @@ namespace detail
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
|
||||
# endif
|
||||
|
||||
|
||||
# endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_numeric
|
||||
: mpl::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>
|
||||
: mpl::true_ {};
|
||||
|
||||
|
||||
template <>
|
||||
struct is_numeric< ::boost::ulong_long_type>
|
||||
: mpl::true_ {};
|
||||
@ -70,7 +69,7 @@ namespace detail
|
||||
template <>
|
||||
struct is_numeric<wchar_t>
|
||||
: mpl::true_ {};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct numeric_difference
|
||||
{
|
||||
@ -78,7 +77,7 @@ namespace detail
|
||||
};
|
||||
|
||||
BOOST_STATIC_ASSERT(is_numeric<int>::value);
|
||||
|
||||
|
||||
template <class Incrementable, class CategoryOrTraversal, class Difference>
|
||||
struct counting_iterator_base
|
||||
{
|
||||
@ -90,7 +89,7 @@ namespace detail
|
||||
, iterator_traversal<Incrementable>
|
||||
>
|
||||
>::type traversal;
|
||||
|
||||
|
||||
typedef typename detail::ia_dflt_help<
|
||||
Difference
|
||||
, mpl::eval_if<
|
||||
@ -99,7 +98,7 @@ namespace detail
|
||||
, iterator_difference<Incrementable>
|
||||
>
|
||||
>::type difference;
|
||||
|
||||
|
||||
typedef iterator_adaptor<
|
||||
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
|
||||
, Incrementable // Base
|
||||
@ -107,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
|
||||
@ -137,7 +136,7 @@ namespace detail
|
||||
{
|
||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||
{
|
||||
return boost::detail::numeric_distance(x, y);
|
||||
return numeric_distance(x, y);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -155,14 +154,14 @@ 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;
|
||||
|
||||
counting_iterator() { }
|
||||
|
||||
|
||||
counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
|
||||
|
||||
counting_iterator(Incrementable x)
|
||||
@ -178,10 +177,10 @@ class counting_iterator
|
||||
)
|
||||
: super_t(t.base())
|
||||
{}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
private:
|
||||
|
||||
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
return this->base_reference();
|
||||
@ -210,11 +209,7 @@ make_counting_iterator(Incrementable x)
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -46,7 +46,8 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(__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))
|
||||
@ -87,7 +88,8 @@
|
||||
# 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__) \
|
||||
#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:
|
||||
|
||||
@ -114,9 +116,16 @@
|
||||
# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||
#endif
|
||||
|
||||
# if BOOST_WORKAROUND(__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
|
||||
|
@ -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
|
||||
|
||||
|
@ -35,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
|
||||
@ -70,8 +70,11 @@ namespace boost
|
||||
: enabled<(Cond::value)>::template base<Return>
|
||||
# else
|
||||
: mpl::identity<Return>
|
||||
# endif
|
||||
# endif
|
||||
{
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
typedef Return type;
|
||||
# endif
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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/mpl/if.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 mpl::if_<is_function<F>, F&, F>::type()
|
||||
#else
|
||||
F&()
|
||||
#endif
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class Function, class Input>
|
||||
template <class Function, class Input>
|
||||
class function_input_iterator
|
||||
: public iterator_facade<
|
||||
: public iterator_facade<
|
||||
function_input_iterator<Function, Input>,
|
||||
typename result_of_nullary_lvalue_call<Function>::type,
|
||||
typename Function::result_type,
|
||||
single_pass_traversal_tag,
|
||||
typename result_of_nullary_lvalue_call<Function>::type const &
|
||||
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,78 +42,14 @@ 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 mpl::if_<
|
||||
function_types::is_function_pointer<Function>,
|
||||
impl::function_pointer_input_iterator<Function,Input>,
|
||||
impl::function_input_iterator<Function,Input>
|
||||
>::type
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
function_types::is_function_pointer<Function>,
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
struct infinite {
|
||||
@ -159,14 +58,7 @@ namespace iterators {
|
||||
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
|
||||
|
||||
|
@ -1,62 +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>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
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;
|
||||
|
||||
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 iterators
|
||||
|
||||
using iterators::function_output_iterator;
|
||||
using iterators::make_function_output_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
|
@ -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(__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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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_
|
@ -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;
|
||||
@ -113,9 +112,9 @@ 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,8 +122,8 @@ 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);
|
||||
@ -138,8 +137,8 @@ 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);
|
||||
@ -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,7 +245,7 @@ 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;
|
||||
BOOST_TEST(*i == *q);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/detail/enable_if.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
@ -21,37 +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
|
||||
|
||||
#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
|
||||
@ -77,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;
|
||||
@ -100,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 <
|
||||
@ -113,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())
|
||||
{}
|
||||
@ -131,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);
|
||||
@ -145,9 +142,16 @@ 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)
|
||||
{
|
||||
@ -156,18 +160,13 @@ namespace iterators {
|
||||
|
||||
#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>
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -6,17 +6,15 @@
|
||||
#ifndef BOOST_INT_ITERATOR_H
|
||||
#define BOOST_INT_ITERATOR_H
|
||||
|
||||
#include <boost/iterator.hpp>
|
||||
#if !defined BOOST_MSVC
|
||||
#include <boost/operators.hpp>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <cstddef>
|
||||
//using namespace std;
|
||||
|
||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
#endif
|
||||
|
||||
// this should use random_access_iterator_helper but I've had
|
||||
@ -63,19 +61,13 @@ inline int_iterator<IntT>
|
||||
operator+(IntT n, int_iterator<IntT> t) { t += n; return t; }
|
||||
|
||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
} /* namespace iterators */
|
||||
|
||||
using iterators::int_iterator;
|
||||
|
||||
} /* namespace boost */
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
namespace boost {
|
||||
using ::int_iterator;
|
||||
namespace iterators {
|
||||
using ::int_iterator;
|
||||
}}
|
||||
using ::int_iterator;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
59
include/boost/pending/integer_range.hpp
Normal file
59
include/boost/pending/integer_range.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
// (C) Copyright David Abrahams and Jeremy Siek 2000-2001.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Revision History:
|
||||
// 04 Jan 2001 Factored counting_iterator stuff into
|
||||
// boost/counting_iterator.hpp (David Abrahams)
|
||||
|
||||
#ifndef BOOST_INTEGER_RANGE_HPP_
|
||||
#define BOOST_INTEGER_RANGE_HPP_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
|
||||
//=============================================================================
|
||||
// Counting Iterator and Integer Range Class
|
||||
|
||||
template <class IntegerType>
|
||||
struct integer_range {
|
||||
typedef counting_iterator<IntegerType> iterator;
|
||||
|
||||
typedef iterator const_iterator;
|
||||
typedef IntegerType value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef IntegerType reference;
|
||||
typedef IntegerType const_reference;
|
||||
typedef const IntegerType* pointer;
|
||||
typedef const IntegerType* const_pointer;
|
||||
typedef IntegerType size_type;
|
||||
|
||||
integer_range(IntegerType start, IntegerType finish)
|
||||
: m_start(start), m_finish(finish) { }
|
||||
|
||||
iterator begin() const { return iterator(m_start); }
|
||||
iterator end() const { return iterator(m_finish); }
|
||||
size_type size() const { return m_finish - m_start; }
|
||||
bool empty() const { return m_finish == m_start; }
|
||||
void swap(integer_range& x) {
|
||||
std::swap(m_start, x.m_start);
|
||||
std::swap(m_finish, x.m_finish);
|
||||
}
|
||||
protected:
|
||||
IntegerType m_start, m_finish;
|
||||
};
|
||||
|
||||
template <class IntegerType>
|
||||
inline integer_range<IntegerType>
|
||||
make_integer_range(IntegerType first, IntegerType last)
|
||||
{
|
||||
return integer_range<IntegerType>(first, last);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_INTEGER_RANGE_HPP_
|
@ -20,62 +20,59 @@
|
||||
// (David Abrahams)
|
||||
|
||||
# include <iterator>
|
||||
# include <assert.h>
|
||||
# include <boost/type_traits.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
||||
# include <boost/implicit_cast.hpp>
|
||||
# include <boost/core/ignore_unused.hpp>
|
||||
# include <boost/core/lightweight_test.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# include <boost/type_traits/is_pointer.hpp>
|
||||
# include <boost/type_traits/is_reference.hpp>
|
||||
# include <boost/type_traits/broken_compiler_spec.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// use this for the value type
|
||||
struct dummyT {
|
||||
struct dummyT {
|
||||
dummyT() { }
|
||||
dummyT(detail::dummy_constructor) { }
|
||||
dummyT(int x) : m_x(x) { }
|
||||
int foo() const { return m_x; }
|
||||
int foo() const { return m_x; }
|
||||
bool operator==(const dummyT& d) const { return m_x == d.m_x; }
|
||||
int m_x;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
BOOST_TT_BROKEN_COMPILER_SPEC(boost::dummyT)
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
// Tests whether type Iterator satisfies the requirements for a
|
||||
// TrivialIterator.
|
||||
// TrivialIterator.
|
||||
// Preconditions: i != j, *i == val
|
||||
template <class Iterator, class T>
|
||||
void trivial_iterator_test(const Iterator i, const Iterator j, T val)
|
||||
{
|
||||
Iterator k;
|
||||
BOOST_TEST(i == i);
|
||||
BOOST_TEST(j == j);
|
||||
BOOST_TEST(i != j);
|
||||
assert(i == i);
|
||||
assert(j == j);
|
||||
assert(i != j);
|
||||
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
T v = *i;
|
||||
#else
|
||||
typename std::iterator_traits<Iterator>::value_type v = *i;
|
||||
#endif
|
||||
BOOST_TEST(v == val);
|
||||
boost::ignore_unused(v);
|
||||
assert(v == val);
|
||||
#if 0
|
||||
// hmm, this will give a warning for transform_iterator... perhaps
|
||||
// this should be separated out into a stand-alone test since there
|
||||
// are several situations where it can't be used, like for
|
||||
// integer_range::iterator.
|
||||
BOOST_TEST(v == i->foo());
|
||||
assert(v == i->foo());
|
||||
#endif
|
||||
k = i;
|
||||
BOOST_TEST(k == k);
|
||||
BOOST_TEST(k == i);
|
||||
BOOST_TEST(k != j);
|
||||
BOOST_TEST(*k == val);
|
||||
boost::ignore_unused(k);
|
||||
assert(k == k);
|
||||
assert(k == i);
|
||||
assert(k != j);
|
||||
assert(*k == val);
|
||||
}
|
||||
|
||||
|
||||
@ -90,12 +87,12 @@ void mutable_trivial_iterator_test(const Iterator i, const Iterator j, T val)
|
||||
|
||||
// Preconditions: *i == v1, *++i == v2
|
||||
template <class Iterator, class T>
|
||||
void input_iterator_test(Iterator i, T v1, T v2)
|
||||
void input_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator i1(i);
|
||||
|
||||
BOOST_TEST(i == i1);
|
||||
BOOST_TEST(!(i != i1));
|
||||
assert(i == i1);
|
||||
assert(!(i != i1));
|
||||
|
||||
// I can see no generic way to create an input iterator
|
||||
// that is in the domain of== of i and != i.
|
||||
@ -104,25 +101,23 @@ void input_iterator_test(Iterator i, T v1, T v2)
|
||||
//
|
||||
// Iterator i2;
|
||||
//
|
||||
// BOOST_TEST(i != i2);
|
||||
// BOOST_TEST(!(i == i2));
|
||||
// assert(i != i2);
|
||||
// assert(!(i == i2));
|
||||
|
||||
BOOST_TEST(*i1 == v1);
|
||||
BOOST_TEST(*i == v1);
|
||||
assert(*i1 == v1);
|
||||
assert(*i == v1);
|
||||
|
||||
// we cannot test for equivalence of (void)++i & (void)i++
|
||||
// as i is only guaranteed to be single pass.
|
||||
BOOST_TEST(*i++ == v1);
|
||||
boost::ignore_unused(i1);
|
||||
assert(*i++ == v1);
|
||||
|
||||
i1 = i;
|
||||
|
||||
BOOST_TEST(i == i1);
|
||||
BOOST_TEST(!(i != i1));
|
||||
assert(i == i1);
|
||||
assert(!(i != i1));
|
||||
|
||||
BOOST_TEST(*i1 == v2);
|
||||
BOOST_TEST(*i == v2);
|
||||
boost::ignore_unused(i1);
|
||||
assert(*i1 == v2);
|
||||
assert(*i == v2);
|
||||
|
||||
// i is dereferencable, so it must be incrementable.
|
||||
++i;
|
||||
@ -158,21 +153,21 @@ template <> struct lvalue_test<true> {
|
||||
#endif
|
||||
|
||||
template <class Iterator, class T>
|
||||
void forward_iterator_test(Iterator i, T v1, T v2)
|
||||
void forward_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
input_iterator_test(i, v1, v2);
|
||||
|
||||
Iterator i1 = i, i2 = i;
|
||||
|
||||
BOOST_TEST(i == i1++);
|
||||
BOOST_TEST(i != ++i2);
|
||||
assert(i == i1++);
|
||||
assert(i != ++i2);
|
||||
|
||||
trivial_iterator_test(i, i1, v1);
|
||||
trivial_iterator_test(i, i2, v1);
|
||||
|
||||
++i;
|
||||
BOOST_TEST(i == i1);
|
||||
BOOST_TEST(i == i2);
|
||||
assert(i == i1);
|
||||
assert(i == i2);
|
||||
++i1;
|
||||
++i2;
|
||||
|
||||
@ -194,15 +189,15 @@ void bidirectional_iterator_test(Iterator i, T v1, T v2)
|
||||
|
||||
Iterator i1 = i, i2 = i;
|
||||
|
||||
BOOST_TEST(i == i1--);
|
||||
BOOST_TEST(i != --i2);
|
||||
assert(i == i1--);
|
||||
assert(i != --i2);
|
||||
|
||||
trivial_iterator_test(i, i1, v2);
|
||||
trivial_iterator_test(i, i2, v2);
|
||||
|
||||
--i;
|
||||
BOOST_TEST(i == i1);
|
||||
BOOST_TEST(i == i2);
|
||||
assert(i == i1);
|
||||
assert(i == i2);
|
||||
++i1;
|
||||
++i2;
|
||||
|
||||
@ -222,34 +217,32 @@ void random_access_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
const Iterator j = i;
|
||||
int c;
|
||||
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
boost::ignore_unused<value_type>();
|
||||
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type value_type;
|
||||
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
BOOST_TEST(i == j + c);
|
||||
BOOST_TEST(*i == vals[c]);
|
||||
BOOST_TEST(*i == boost::implicit_cast<value_type>(j[c]));
|
||||
BOOST_TEST(*i == *(j + c));
|
||||
BOOST_TEST(*i == *(c + j));
|
||||
assert(i == j + c);
|
||||
assert(*i == vals[c]);
|
||||
assert(*i == boost::implicit_cast<value_type>(j[c]));
|
||||
assert(*i == *(j + c));
|
||||
assert(*i == *(c + j));
|
||||
++i;
|
||||
BOOST_TEST(i > j);
|
||||
BOOST_TEST(i >= j);
|
||||
BOOST_TEST(j <= i);
|
||||
BOOST_TEST(j < i);
|
||||
assert(i > j);
|
||||
assert(i >= j);
|
||||
assert(j <= i);
|
||||
assert(j < i);
|
||||
}
|
||||
|
||||
Iterator k = j + N - 1;
|
||||
for (c = 0; c < N-1; ++c) {
|
||||
BOOST_TEST(i == k - c);
|
||||
BOOST_TEST(*i == vals[N - 1 - c]);
|
||||
BOOST_TEST(*i == boost::implicit_cast<value_type>(j[N - 1 - c]));
|
||||
Iterator q = k - c;
|
||||
boost::ignore_unused(q);
|
||||
BOOST_TEST(*i == *q);
|
||||
BOOST_TEST(i > j);
|
||||
BOOST_TEST(i >= j);
|
||||
BOOST_TEST(j <= i);
|
||||
BOOST_TEST(j < i);
|
||||
assert(i == k - c);
|
||||
assert(*i == vals[N - 1 - c]);
|
||||
assert(*i == boost::implicit_cast<value_type>(j[N - 1 - c]));
|
||||
Iterator q = k - c;
|
||||
assert(*i == *q);
|
||||
assert(i > j);
|
||||
assert(i >= j);
|
||||
assert(j <= i);
|
||||
assert(j < i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
@ -258,31 +251,18 @@ void random_access_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
template <class Iterator, class ConstIterator>
|
||||
void const_nonconst_iterator_test(Iterator i, ConstIterator j)
|
||||
{
|
||||
BOOST_TEST(i != j);
|
||||
BOOST_TEST(j != i);
|
||||
assert(i != j);
|
||||
assert(j != i);
|
||||
|
||||
ConstIterator k(i);
|
||||
BOOST_TEST(k == i);
|
||||
BOOST_TEST(i == k);
|
||||
assert(k == i);
|
||||
assert(i == k);
|
||||
|
||||
k = i;
|
||||
BOOST_TEST(k == i);
|
||||
BOOST_TEST(i == k);
|
||||
boost::ignore_unused(k);
|
||||
assert(k == i);
|
||||
assert(i == k);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::undefined;
|
||||
using iterators::trivial_iterator_test;
|
||||
using iterators::mutable_trivial_iterator_test;
|
||||
using iterators::input_iterator_test;
|
||||
using iterators::lvalue_test;
|
||||
using iterators::forward_iterator_test;
|
||||
using iterators::bidirectional_iterator_test;
|
||||
using iterators::random_access_iterator_test;
|
||||
using iterators::const_nonconst_iterator_test;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_TESTS_HPP
|
||||
|
@ -20,9 +20,7 @@
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/eval_if.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
namespace boost {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
@ -35,26 +33,26 @@ namespace detail
|
||||
template <class Iterator>
|
||||
struct iterator_pointee
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
|
||||
typedef typename iterator_traits<Iterator>::value_type value_type;
|
||||
|
||||
struct impl
|
||||
{
|
||||
template <class T>
|
||||
static char test(T const&);
|
||||
|
||||
|
||||
static char (& test(value_type&) )[2];
|
||||
|
||||
|
||||
static Iterator& x;
|
||||
};
|
||||
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, is_constant = sizeof(impl::test(*impl::x)) == 1);
|
||||
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
::boost::detail::iterator_pointee<Iterator>::is_constant
|
||||
# else
|
||||
is_constant
|
||||
# endif
|
||||
# endif
|
||||
, typename add_const<value_type>::type
|
||||
, value_type
|
||||
>::type type;
|
||||
@ -70,7 +68,7 @@ struct pointee
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // POINTEE_DWA200415_HPP
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template <typename Container>
|
||||
class shared_container_iterator : public iterator_adaptor<
|
||||
@ -38,7 +37,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
inline shared_container_iterator<Container>
|
||||
shared_container_iterator<Container>
|
||||
make_shared_container_iterator(typename Container::iterator iter,
|
||||
boost::shared_ptr<Container> const& container) {
|
||||
typedef shared_container_iterator<Container> iterator;
|
||||
@ -48,7 +47,7 @@ make_shared_container_iterator(typename Container::iterator iter,
|
||||
|
||||
|
||||
template <typename Container>
|
||||
inline std::pair<
|
||||
std::pair<
|
||||
shared_container_iterator<Container>,
|
||||
shared_container_iterator<Container> >
|
||||
make_shared_container_range(boost::shared_ptr<Container> const& container) {
|
||||
@ -58,12 +57,6 @@ make_shared_container_range(boost::shared_ptr<Container> const& container) {
|
||||
make_shared_container_iterator(container->end(),container));
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::shared_container_iterator;
|
||||
using iterators::make_shared_container_iterator;
|
||||
using iterators::make_shared_container_range;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // SHARED_CONTAINER_ITERATOR_RG08102002_HPP
|
||||
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"key": "iterator",
|
||||
"name": "Iterator",
|
||||
"authors": [
|
||||
"Dave Abrahams",
|
||||
"Jeremy Siek",
|
||||
"Thomas Witt"
|
||||
],
|
||||
"description": "The Boost Iterator Library contains two parts. The first is a system of concepts which extend the C++ standard iterator requirements. The second is a framework of components for building iterators based on these extended concepts and includes several useful iterator adaptors.",
|
||||
"category": [
|
||||
"Iterators"
|
||||
],
|
||||
"maintainers": [
|
||||
"David Abrahams <dave -at- boost-consulting.com>",
|
||||
"Thomas Witt <witt - at - acm.org>",
|
||||
"Jeffrey Lee Hellrung Jr. <jeffrey.hellrung -at- gmail.com>"
|
||||
]
|
||||
}
|
@ -3,34 +3,28 @@
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
test-suite iterator
|
||||
:
|
||||
:
|
||||
# These first two tests will run last, and are expected to fail
|
||||
# for many less-capable compilers.
|
||||
|
||||
|
||||
[ compile-fail interoperable_fail.cpp ]
|
||||
# test uses expected success, so that we catch unrelated
|
||||
# compilation problems.
|
||||
[ run is_convertible_fail.cpp ]
|
||||
[ run is_convertible_fail.cpp ]
|
||||
|
||||
[ run zip_iterator_test.cpp
|
||||
: : :
|
||||
: : :
|
||||
|
||||
# stlport's debug mode generates long symbols which overwhelm
|
||||
# vc6
|
||||
#<msvc-stlport><*><runtime-build>release
|
||||
#<msvc-stlport><*><runtime-build>release
|
||||
]
|
||||
[ run zip_iterator_test2_std_tuple.cpp ]
|
||||
[ run zip_iterator_test2_fusion_vector.cpp ]
|
||||
[ run zip_iterator_test2_fusion_list.cpp ]
|
||||
# [ run zip_iterator_test2_fusion_deque.cpp ] // See bug report for fusion https://svn.boost.org/trac/boost/ticket/11572
|
||||
[ run zip_iterator_test_fusion.cpp ]
|
||||
[ run zip_iterator_test_std_tuple.cpp ]
|
||||
[ run zip_iterator_test_std_pair.cpp ]
|
||||
|
||||
|
||||
# These tests should work for just about everything.
|
||||
[ compile is_lvalue_iterator.cpp ]
|
||||
[ compile is_readable_iterator.cpp ]
|
||||
[ compile pointee.cpp ]
|
||||
|
||||
|
||||
[ run unit_tests.cpp ]
|
||||
[ run concept_tests.cpp ]
|
||||
[ run iterator_adaptor_cc.cpp ]
|
||||
@ -47,20 +41,7 @@ test-suite iterator
|
||||
[ run counting_iterator_test.cpp ]
|
||||
[ run interoperable.cpp ]
|
||||
[ run iterator_traits_test.cpp ]
|
||||
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
||||
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
|
||||
]
|
||||
[ run function_input_iterator_test.cpp ]
|
||||
|
||||
[ run generator_iterator_test.cpp ]
|
||||
|
||||
[ run minimum_category.cpp ]
|
||||
[ compile-fail minimum_category_compile_fail.cpp ]
|
||||
|
||||
[ run next_prior_test.cpp ]
|
||||
[ run advance_test.cpp ]
|
||||
[ run distance_test.cpp ]
|
||||
[ compile adl_test.cpp ]
|
||||
[ compile range_distance_compat_test.cpp ]
|
||||
|
||||
[ run shared_iterator_test.cpp ]
|
||||
|
||||
;
|
||||
|
@ -1,25 +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)
|
||||
|
||||
#include <vector>
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/iterator/advance.hpp>
|
||||
#include <boost/iterator/distance.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Test that boost::advance/distance are not found by ADL.
|
||||
// (https://github.com/boostorg/iterator/issues/43)
|
||||
|
||||
typedef boost::array<int, 1> boost_type;
|
||||
std::vector<boost_type> std_boost(2);
|
||||
std::vector<boost_type>::iterator it = std_boost.begin();
|
||||
|
||||
advance(it, 2);
|
||||
(void)distance(it, it);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,91 +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)
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <boost/container/slist.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/iterator/advance.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
int twice(int x) { return x + x; }
|
||||
|
||||
template <typename Iterator>
|
||||
void test_advance(Iterator it_from, Iterator it_to, int n)
|
||||
{
|
||||
boost::advance(it_from, n);
|
||||
BOOST_TEST(it_from == it_to);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int array[3] = {1, 2, 3};
|
||||
int* ptr1 = array;
|
||||
int* ptr2 = array + 3;
|
||||
|
||||
{
|
||||
test_advance(ptr1, ptr2, 3);
|
||||
test_advance(ptr2, ptr1, -3);
|
||||
|
||||
test_advance(
|
||||
boost::make_transform_iterator(ptr1, twice)
|
||||
, boost::make_transform_iterator(ptr2, twice)
|
||||
, 3
|
||||
);
|
||||
test_advance(
|
||||
boost::make_transform_iterator(ptr2, twice)
|
||||
, boost::make_transform_iterator(ptr1, twice)
|
||||
, -3
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<int> ints(ptr1, ptr2);
|
||||
test_advance(ints.begin(), ints.end(), 3);
|
||||
test_advance(ints.end(), ints.begin(), -3);
|
||||
|
||||
test_advance(
|
||||
boost::make_transform_iterator(ints.begin(), twice)
|
||||
, boost::make_transform_iterator(ints.end(), twice)
|
||||
, 3
|
||||
);
|
||||
test_advance(
|
||||
boost::make_transform_iterator(ints.end(), twice)
|
||||
, boost::make_transform_iterator(ints.begin(), twice)
|
||||
, -3
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
std::list<int> ints(ptr1, ptr2);
|
||||
test_advance(ints.begin(), ints.end(), 3);
|
||||
test_advance(ints.end(), ints.begin(), -3);
|
||||
|
||||
test_advance(
|
||||
boost::make_transform_iterator(ints.begin(), twice)
|
||||
, boost::make_transform_iterator(ints.end(), twice)
|
||||
, 3
|
||||
);
|
||||
test_advance(
|
||||
boost::make_transform_iterator(ints.end(), twice)
|
||||
, boost::make_transform_iterator(ints.begin(), twice)
|
||||
, -3
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
boost::container::slist<int> ints(ptr1, ptr2);
|
||||
test_advance(ints.begin(), ints.end(), 3);
|
||||
|
||||
test_advance(
|
||||
boost::make_transform_iterator(ints.begin(), twice)
|
||||
, boost::make_transform_iterator(ints.end(), twice)
|
||||
, 3
|
||||
);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -7,22 +7,14 @@
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <cstddef>
|
||||
|
||||
struct new_random_access
|
||||
: std::random_access_iterator_tag
|
||||
, boost::random_access_traversal_tag
|
||||
{};
|
||||
|
||||
struct new_iterator
|
||||
: public boost::iterator< new_random_access, int >
|
||||
{
|
||||
typedef new_random_access iterator_category;
|
||||
typedef int value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef int* pointer;
|
||||
typedef int& reference;
|
||||
|
||||
int& operator*() const { return *m_x; }
|
||||
new_iterator& operator++() { return *this; }
|
||||
new_iterator operator++(int) { return *this; }
|
||||
@ -41,13 +33,8 @@ struct new_iterator
|
||||
new_iterator operator+(std::ptrdiff_t, new_iterator x) { return x; }
|
||||
|
||||
struct old_iterator
|
||||
: public boost::iterator<std::random_access_iterator_tag, int>
|
||||
{
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef int value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef int* pointer;
|
||||
typedef int& reference;
|
||||
|
||||
int& operator*() const { return *m_x; }
|
||||
old_iterator& operator++() { return *this; }
|
||||
old_iterator operator++(int) { return *this; }
|
||||
|
@ -153,6 +153,7 @@ template <class CountingIterator, class Value>
|
||||
void test_aux(CountingIterator start, CountingIterator finish, Value v1)
|
||||
{
|
||||
typedef typename CountingIterator::iterator_category category;
|
||||
typedef typename CountingIterator::value_type value_type;
|
||||
|
||||
// If it's a RandomAccessIterator we can do a few delicate tests
|
||||
category_test(start, finish, v1, category());
|
||||
|
@ -1,85 +0,0 @@
|
||||
// Copyright (c) 2014 Kohei Takahashi.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/iterator/zip_iterator.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef TUPLE<
|
||||
std::vector<int>::iterator,
|
||||
std::vector<std::string>::iterator
|
||||
> iterator_tuple;
|
||||
|
||||
std::vector<int> vi = boost::assign::list_of(42)(72);
|
||||
std::vector<std::string> vs = boost::assign::list_of("kokoro")("pyonpyon");
|
||||
|
||||
{
|
||||
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
|
||||
boost::zip_iterator<iterator_tuple> i2 = i1;
|
||||
|
||||
BOOST_TEST( i1 == i2);
|
||||
BOOST_TEST( i1++ == i2);
|
||||
BOOST_TEST( i1 == (i2 + 1));
|
||||
BOOST_TEST((i1 - 1) == i2);
|
||||
BOOST_TEST( i1-- == ++i2);
|
||||
BOOST_TEST( i1 == --i2);
|
||||
}
|
||||
|
||||
{
|
||||
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
|
||||
boost::zip_iterator<iterator_tuple> i2 = i1 + 1;
|
||||
|
||||
BOOST_TEST( i1 != i2);
|
||||
BOOST_TEST( i1++ != i2);
|
||||
BOOST_TEST( i1 != (i2 + 1));
|
||||
BOOST_TEST((i1 - 1) != i2);
|
||||
BOOST_TEST( i1-- != ++i2);
|
||||
BOOST_TEST( i1 != --i2);
|
||||
}
|
||||
|
||||
{
|
||||
boost::zip_iterator<iterator_tuple> i(MAKE_TUPLE(vi.begin(), vs.begin()));
|
||||
|
||||
BOOST_TEST(boost::fusion::at_c<0>(* i ) == 42);
|
||||
BOOST_TEST(boost::fusion::at_c<1>(* i ) == "kokoro");
|
||||
BOOST_TEST(boost::fusion::at_c<0>(*(i + 1)) == 72);
|
||||
BOOST_TEST(boost::fusion::at_c<1>(*(i + 1)) == "pyonpyon");
|
||||
}
|
||||
|
||||
{
|
||||
// Trac #12895
|
||||
boost::zip_iterator<
|
||||
TUPLE<int*, std::string*>
|
||||
> i(MAKE_TUPLE(&vi[0], &vs[0]));
|
||||
|
||||
BOOST_TEST(boost::fusion::at_c<0>(* i ) == 42);
|
||||
BOOST_TEST(boost::fusion::at_c<1>(* i ) == "kokoro");
|
||||
BOOST_TEST(boost::fusion::at_c<0>(*(i + 1)) == 72);
|
||||
BOOST_TEST(boost::fusion::at_c<1>(*(i + 1)) == "pyonpyon");
|
||||
}
|
||||
|
||||
{
|
||||
boost::zip_iterator<iterator_tuple> i1(MAKE_TUPLE(vi.begin(), vs.begin()));
|
||||
boost::zip_iterator<iterator_tuple> i2(MAKE_TUPLE(vi.end(), vs.end()));
|
||||
|
||||
BOOST_TEST((i2 - i1) == 2);
|
||||
++i1;
|
||||
BOOST_TEST((i2 - i1) == 1);
|
||||
--i2;
|
||||
BOOST_TEST((i2 - i1) == 0);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,857 +0,0 @@
|
||||
// (C) Copyright Dave Abrahams and Thomas Becker 2003. Distributed
|
||||
// under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
// File:
|
||||
// =====
|
||||
// zip_iterator_test_main.cpp
|
||||
|
||||
// Author:
|
||||
// =======
|
||||
// Thomas Becker
|
||||
|
||||
// Created:
|
||||
// ========
|
||||
// Jul 15, 2003
|
||||
|
||||
// Purpose:
|
||||
// ========
|
||||
// Test driver for zip_iterator.hpp
|
||||
|
||||
// Compilers Tested:
|
||||
// =================
|
||||
// Metrowerks Codewarrior Pro 7.2, 8.3
|
||||
// gcc 2.95.3
|
||||
// gcc 3.2
|
||||
// Microsoft VC 6sp5 (test fails due to some compiler bug)
|
||||
// Microsoft VC 7 (works)
|
||||
// Microsoft VC 7.1
|
||||
// Intel 5
|
||||
// Intel 6
|
||||
// Intel 7.1
|
||||
// Intel 8
|
||||
// Borland 5.5.1 (broken due to lack of support from Boost.Tuples)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Includes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/iterator/zip_iterator.hpp>
|
||||
#include <boost/iterator/zip_iterator.hpp> // 2nd #include tests #include guard.
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/iterator/is_readable_iterator.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/// Tests for https://svn.boost.org/trac/boost/ticket/1517
|
||||
int to_value(int const &v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
void category_test()
|
||||
{
|
||||
std::list<int> rng1;
|
||||
std::string rng2;
|
||||
|
||||
boost::make_zip_iterator(
|
||||
ZI_MAKE_TUPLE(
|
||||
boost::make_transform_iterator(rng1.begin(), &to_value), // BidirectionalInput
|
||||
rng2.begin() // RandomAccess
|
||||
)
|
||||
);
|
||||
}
|
||||
///
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Das Main Funktion
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int main( void )
|
||||
{
|
||||
|
||||
category_test();
|
||||
|
||||
std::cout << "\n"
|
||||
<< "***********************************************\n"
|
||||
<< "* *\n"
|
||||
<< "* Test driver for boost::zip_iterator *\n"
|
||||
<< "* Copyright Thomas Becker 2003 *\n"
|
||||
<< "* *\n"
|
||||
<< "***********************************************\n\n"
|
||||
<< std::flush;
|
||||
|
||||
size_t num_successful_tests = 0;
|
||||
size_t num_failed_tests = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator construction and dereferencing
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator construction and dereferencing: "
|
||||
<< std::flush;
|
||||
|
||||
std::vector<double> vect1(3);
|
||||
vect1[0] = 42.;
|
||||
vect1[1] = 43.;
|
||||
vect1[2] = 44.;
|
||||
|
||||
std::set<int> intset;
|
||||
intset.insert(52);
|
||||
intset.insert(53);
|
||||
intset.insert(54);
|
||||
//
|
||||
|
||||
typedef
|
||||
boost::zip_iterator<
|
||||
ZI_TUPLE<
|
||||
std::set<int>::iterator
|
||||
, std::vector<double>::iterator
|
||||
>
|
||||
> zit_mixed;
|
||||
|
||||
zit_mixed zip_it_mixed = zit_mixed(
|
||||
ZI_MAKE_TUPLE(
|
||||
intset.begin()
|
||||
, vect1.begin()
|
||||
)
|
||||
);
|
||||
|
||||
ZI_TUPLE<int, double> val_tuple(
|
||||
*zip_it_mixed);
|
||||
|
||||
ZI_TUPLE<const int&, double&> ref_tuple(
|
||||
*zip_it_mixed);
|
||||
|
||||
double dblOldVal = ZI_TUPLE_GET(1)(ref_tuple);
|
||||
ZI_TUPLE_GET(1)(ref_tuple) -= 41.;
|
||||
|
||||
if( 52 == ZI_TUPLE_GET(0)(val_tuple) &&
|
||||
42. == ZI_TUPLE_GET(1)(val_tuple) &&
|
||||
52 == ZI_TUPLE_GET(0)(ref_tuple) &&
|
||||
1. == ZI_TUPLE_GET(1)(ref_tuple) &&
|
||||
1. == *vect1.begin()
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
// Undo change to vect1
|
||||
ZI_TUPLE_GET(1)(ref_tuple) = dblOldVal;
|
||||
|
||||
#if defined(ZI_USE_BOOST_TUPLE)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator with 12 components
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterators with 12 components: "
|
||||
<< std::flush;
|
||||
|
||||
// Declare 12 containers
|
||||
//
|
||||
std::list<int> li1;
|
||||
li1.push_back(1);
|
||||
std::set<int> se1;
|
||||
se1.insert(2);
|
||||
std::vector<int> ve1;
|
||||
ve1.push_back(3);
|
||||
//
|
||||
std::list<int> li2;
|
||||
li2.push_back(4);
|
||||
std::set<int> se2;
|
||||
se2.insert(5);
|
||||
std::vector<int> ve2;
|
||||
ve2.push_back(6);
|
||||
//
|
||||
std::list<int> li3;
|
||||
li3.push_back(7);
|
||||
std::set<int> se3;
|
||||
se3.insert(8);
|
||||
std::vector<int> ve3;
|
||||
ve3.push_back(9);
|
||||
//
|
||||
std::list<int> li4;
|
||||
li4.push_back(10);
|
||||
std::set<int> se4;
|
||||
se4.insert(11);
|
||||
std::vector<int> ve4;
|
||||
ve4.push_back(12);
|
||||
|
||||
// typedefs for cons lists of iterators.
|
||||
typedef boost::tuples::cons<
|
||||
std::set<int>::iterator,
|
||||
ZI_TUPLE<
|
||||
std::vector<int>::iterator,
|
||||
std::list<int>::iterator,
|
||||
std::set<int>::iterator,
|
||||
std::vector<int>::iterator,
|
||||
std::list<int>::iterator,
|
||||
std::set<int>::iterator,
|
||||
std::vector<int>::iterator,
|
||||
std::list<int>::iterator,
|
||||
std::set<int>::iterator,
|
||||
std::vector<int>::const_iterator
|
||||
>::inherited
|
||||
> cons_11_its_type;
|
||||
//
|
||||
typedef boost::tuples::cons<
|
||||
std::list<int>::const_iterator,
|
||||
cons_11_its_type
|
||||
> cons_12_its_type;
|
||||
|
||||
// typedefs for cons lists for dereferencing the zip iterator
|
||||
// made from the cons list above.
|
||||
typedef boost::tuples::cons<
|
||||
const int&,
|
||||
ZI_TUPLE<
|
||||
int&,
|
||||
int&,
|
||||
const int&,
|
||||
int&,
|
||||
int&,
|
||||
const int&,
|
||||
int&,
|
||||
int&,
|
||||
const int&,
|
||||
const int&
|
||||
>::inherited
|
||||
> cons_11_refs_type;
|
||||
//
|
||||
typedef boost::tuples::cons<
|
||||
const int&,
|
||||
cons_11_refs_type
|
||||
> cons_12_refs_type;
|
||||
|
||||
// typedef for zip iterator with 12 elements
|
||||
typedef boost::zip_iterator<cons_12_its_type> zip_it_12_type;
|
||||
|
||||
// Declare a 12-element zip iterator.
|
||||
zip_it_12_type zip_it_12(
|
||||
cons_12_its_type(
|
||||
li1.begin(),
|
||||
cons_11_its_type(
|
||||
se1.begin(),
|
||||
ZI_MAKE_TUPLE(
|
||||
ve1.begin(),
|
||||
li2.begin(),
|
||||
se2.begin(),
|
||||
ve2.begin(),
|
||||
li3.begin(),
|
||||
se3.begin(),
|
||||
ve3.begin(),
|
||||
li4.begin(),
|
||||
se4.begin(),
|
||||
ve4.begin()
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Dereference, mess with the result a little.
|
||||
cons_12_refs_type zip_it_12_dereferenced(*zip_it_12);
|
||||
ZI_TUPLE_GET(9)(zip_it_12_dereferenced) = 42;
|
||||
|
||||
// Make a copy and move it a little to force some instantiations.
|
||||
zip_it_12_type zip_it_12_copy(zip_it_12);
|
||||
++zip_it_12_copy;
|
||||
|
||||
if( ZI_TUPLE_GET(11)(zip_it_12.get_iterator_tuple()) == ve4.begin() &&
|
||||
ZI_TUPLE_GET(11)(zip_it_12_copy.get_iterator_tuple()) == ve4.end() &&
|
||||
1 == ZI_TUPLE_GET(0)(zip_it_12_dereferenced) &&
|
||||
12 == ZI_TUPLE_GET(11)(zip_it_12_dereferenced) &&
|
||||
42 == *(li4.begin())
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator incrementing and dereferencing
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator ++ and *: "
|
||||
<< std::flush;
|
||||
|
||||
std::vector<double> vect2(3);
|
||||
vect2[0] = 2.2;
|
||||
vect2[1] = 3.3;
|
||||
vect2[2] = 4.4;
|
||||
|
||||
boost::zip_iterator<
|
||||
ZI_TUPLE<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_begin(
|
||||
ZI_MAKE_TUPLE(
|
||||
vect1.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
|
||||
boost::zip_iterator<
|
||||
ZI_TUPLE<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_run(
|
||||
ZI_MAKE_TUPLE(
|
||||
vect1.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
|
||||
boost::zip_iterator<
|
||||
ZI_TUPLE<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_end(
|
||||
ZI_MAKE_TUPLE(
|
||||
vect1.end(),
|
||||
vect2.end()
|
||||
)
|
||||
);
|
||||
|
||||
if( zip_it_run == zip_it_begin &&
|
||||
42. == ZI_TUPLE_GET(0)(*zip_it_run) &&
|
||||
2.2 == ZI_TUPLE_GET(1)(*zip_it_run) &&
|
||||
43. == ZI_TUPLE_GET(0)(*(++zip_it_run)) &&
|
||||
3.3 == ZI_TUPLE_GET(1)(*zip_it_run) &&
|
||||
44. == ZI_TUPLE_GET(0)(*(++zip_it_run)) &&
|
||||
4.4 == ZI_TUPLE_GET(1)(*zip_it_run) &&
|
||||
zip_it_end == ++zip_it_run
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator decrementing and dereferencing
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator -- and *: "
|
||||
<< std::flush;
|
||||
|
||||
if( zip_it_run == zip_it_end &&
|
||||
zip_it_end == zip_it_run-- &&
|
||||
44. == ZI_TUPLE_GET(0)(*zip_it_run) &&
|
||||
4.4 == ZI_TUPLE_GET(1)(*zip_it_run) &&
|
||||
43. == ZI_TUPLE_GET(0)(*(--zip_it_run)) &&
|
||||
3.3 == ZI_TUPLE_GET(1)(*zip_it_run) &&
|
||||
42. == ZI_TUPLE_GET(0)(*(--zip_it_run)) &&
|
||||
2.2 == ZI_TUPLE_GET(1)(*zip_it_run) &&
|
||||
zip_it_begin == zip_it_run
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator copy construction and equality
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator copy construction and equality: "
|
||||
<< std::flush;
|
||||
|
||||
boost::zip_iterator<
|
||||
ZI_TUPLE<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
> zip_it_run_copy(zip_it_run);
|
||||
|
||||
if(zip_it_run == zip_it_run && zip_it_run == zip_it_run_copy)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator inequality
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator inequality: "
|
||||
<< std::flush;
|
||||
|
||||
if(!(zip_it_run != zip_it_run_copy) && zip_it_run != ++zip_it_run_copy)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator less than
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator less than: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run_copy == zip_it_run + 1
|
||||
//
|
||||
if( zip_it_run < zip_it_run_copy &&
|
||||
!( zip_it_run < --zip_it_run_copy) &&
|
||||
zip_it_run == zip_it_run_copy
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator less than or equal
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "zip iterator less than or equal: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run_copy == zip_it_run
|
||||
//
|
||||
++zip_it_run;
|
||||
zip_it_run_copy += 2;
|
||||
|
||||
if( zip_it_run <= zip_it_run_copy &&
|
||||
zip_it_run <= --zip_it_run_copy &&
|
||||
!( zip_it_run <= --zip_it_run_copy) &&
|
||||
zip_it_run <= zip_it_run
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator greater than
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator greater than: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run_copy == zip_it_run - 1
|
||||
//
|
||||
if( zip_it_run > zip_it_run_copy &&
|
||||
!( zip_it_run > ++zip_it_run_copy) &&
|
||||
zip_it_run == zip_it_run_copy
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator greater than or equal
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator greater than or equal: "
|
||||
<< std::flush;
|
||||
|
||||
++zip_it_run;
|
||||
|
||||
// Note: zip_it_run == zip_it_run_copy + 1
|
||||
//
|
||||
if( zip_it_run >= zip_it_run_copy &&
|
||||
--zip_it_run >= zip_it_run_copy &&
|
||||
! (zip_it_run >= ++zip_it_run_copy)
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator + int
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator + int: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run == zip_it_run_copy - 1
|
||||
//
|
||||
zip_it_run = zip_it_run + 2;
|
||||
++zip_it_run_copy;
|
||||
|
||||
if( zip_it_run == zip_it_run_copy && zip_it_run == zip_it_begin + 3 )
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator - int
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator - int: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run == zip_it_run_copy, and both are at end position
|
||||
//
|
||||
zip_it_run = zip_it_run - 2;
|
||||
--zip_it_run_copy;
|
||||
--zip_it_run_copy;
|
||||
|
||||
if( zip_it_run == zip_it_run_copy && (zip_it_run - 1) == zip_it_begin )
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator +=
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator +=: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run == zip_it_run_copy, and both are at begin + 1
|
||||
//
|
||||
zip_it_run += 2;
|
||||
if( zip_it_run == zip_it_begin + 3 )
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator -=
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator -=: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run is at end position, zip_it_run_copy is at
|
||||
// begin plus one.
|
||||
//
|
||||
zip_it_run -= 2;
|
||||
if( zip_it_run == zip_it_run_copy )
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator getting member iterators
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator member iterators: "
|
||||
<< std::flush;
|
||||
|
||||
// Note: zip_it_run and zip_it_run_copy are both at
|
||||
// begin plus one.
|
||||
//
|
||||
if( ZI_TUPLE_GET(0)(zip_it_run.get_iterator_tuple()) == vect1.begin() + 1 &&
|
||||
ZI_TUPLE_GET(1)(zip_it_run.get_iterator_tuple()) == vect2.begin() + 1
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Making zip iterators
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Making zip iterators: "
|
||||
<< std::flush;
|
||||
|
||||
std::vector<ZI_TUPLE<double, double> >
|
||||
vect_of_tuples(3);
|
||||
|
||||
std::copy(
|
||||
boost::make_zip_iterator(
|
||||
ZI_MAKE_TUPLE(
|
||||
vect1.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
),
|
||||
boost::make_zip_iterator(
|
||||
ZI_MAKE_TUPLE(
|
||||
vect1.end(),
|
||||
vect2.end()
|
||||
)
|
||||
),
|
||||
vect_of_tuples.begin()
|
||||
);
|
||||
|
||||
if( 42. == ZI_TUPLE_GET(0)(*vect_of_tuples.begin()) &&
|
||||
2.2 == ZI_TUPLE_GET(1)(*vect_of_tuples.begin()) &&
|
||||
43. == ZI_TUPLE_GET(0)(*(vect_of_tuples.begin() + 1)) &&
|
||||
3.3 == ZI_TUPLE_GET(1)(*(vect_of_tuples.begin() + 1)) &&
|
||||
44. == ZI_TUPLE_GET(0)(*(vect_of_tuples.begin() + 2)) &&
|
||||
4.4 == ZI_TUPLE_GET(1)(*(vect_of_tuples.begin() + 2))
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator non-const --> const conversion
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator non-const to const conversion: "
|
||||
<< std::flush;
|
||||
|
||||
boost::zip_iterator<
|
||||
ZI_TUPLE<
|
||||
std::set<int>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_const(
|
||||
ZI_MAKE_TUPLE(
|
||||
intset.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
//
|
||||
boost::zip_iterator<
|
||||
ZI_TUPLE<
|
||||
std::set<int>::iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
>
|
||||
zip_it_half_const(
|
||||
ZI_MAKE_TUPLE(
|
||||
intset.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
//
|
||||
boost::zip_iterator<
|
||||
ZI_TUPLE<
|
||||
std::set<int>::iterator,
|
||||
std::vector<double>::iterator
|
||||
>
|
||||
>
|
||||
zip_it_non_const(
|
||||
ZI_MAKE_TUPLE(
|
||||
intset.begin(),
|
||||
vect2.begin()
|
||||
)
|
||||
);
|
||||
|
||||
zip_it_half_const = ++zip_it_non_const;
|
||||
zip_it_const = zip_it_half_const;
|
||||
++zip_it_const;
|
||||
// zip_it_non_const = ++zip_it_const; // Error: can't convert from const to non-const
|
||||
|
||||
if( 54 == ZI_TUPLE_GET(0)(*zip_it_const) &&
|
||||
4.4 == ZI_TUPLE_GET(1)(*zip_it_const) &&
|
||||
53 == ZI_TUPLE_GET(0)(*zip_it_half_const) &&
|
||||
3.3 == ZI_TUPLE_GET(1)(*zip_it_half_const)
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
#if defined(ZI_USE_BOOST_TUPLE)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Zip iterator categories
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::cout << "Zip iterator categories: "
|
||||
<< std::flush;
|
||||
|
||||
// The big iterator of the previous test has vector, list, and set iterators.
|
||||
// Therefore, it must be bidirectional, but not random access.
|
||||
bool bBigItIsBidirectionalIterator = boost::is_convertible<
|
||||
boost::iterator_traversal<zip_it_12_type>::type
|
||||
, boost::bidirectional_traversal_tag
|
||||
>::value;
|
||||
|
||||
bool bBigItIsRandomAccessIterator = boost::is_convertible<
|
||||
boost::iterator_traversal<zip_it_12_type>::type
|
||||
, boost::random_access_traversal_tag
|
||||
>::value;
|
||||
|
||||
// A combining iterator with all vector iterators must have random access
|
||||
// traversal.
|
||||
//
|
||||
typedef boost::zip_iterator<
|
||||
ZI_TUPLE<
|
||||
std::vector<double>::const_iterator,
|
||||
std::vector<double>::const_iterator
|
||||
>
|
||||
> all_vects_type;
|
||||
|
||||
bool bAllVectsIsRandomAccessIterator = boost::is_convertible<
|
||||
boost::iterator_traversal<all_vects_type>::type
|
||||
, boost::random_access_traversal_tag
|
||||
>::value;
|
||||
|
||||
// The big test.
|
||||
if( bBigItIsBidirectionalIterator &&
|
||||
! bBigItIsRandomAccessIterator &&
|
||||
bAllVectsIsRandomAccessIterator
|
||||
)
|
||||
{
|
||||
++num_successful_tests;
|
||||
std::cout << "OK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
++num_failed_tests;
|
||||
std::cout << "not OK" << std::endl;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Done
|
||||
//
|
||||
std::cout << "\nTest Result:"
|
||||
<< "\n============"
|
||||
<< "\nNumber of successful tests: " << static_cast<unsigned int>(num_successful_tests)
|
||||
<< "\nNumber of failed tests: " << static_cast<unsigned int>(num_failed_tests)
|
||||
<< std::endl;
|
||||
|
||||
return num_failed_tests;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user