mirror of
https://github.com/boostorg/iterator.git
synced 2025-06-26 12:31:41 +02:00
Compare commits
1 Commits
develop
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
9b2d0b58d7 |
620
.github/workflows/ci.yml
vendored
620
.github/workflows/ci.yml
vendored
@ -1,620 +0,0 @@
|
|||||||
# Copyright 2021-2025 Andrey Semashev
|
|
||||||
#
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
name: CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- feature/**
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{format('{0}:{1}', github.repository, github.ref)}}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
GIT_FETCH_JOBS: 8
|
|
||||||
NET_RETRY_COUNT: 5
|
|
||||||
DEFAULT_BUILD_VARIANT: debug,release
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
posix:
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
# Linux, gcc
|
|
||||||
- toolset: gcc-5
|
|
||||||
cxxstd: "11,14,1z"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:16.04
|
|
||||||
install:
|
|
||||||
- g++-5
|
|
||||||
- toolset: gcc-6
|
|
||||||
cxxstd: "11,14,1z"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:18.04
|
|
||||||
install:
|
|
||||||
- g++-6
|
|
||||||
- toolset: gcc-7
|
|
||||||
cxxstd: "11,14,17"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:18.04
|
|
||||||
install:
|
|
||||||
- g++-7
|
|
||||||
- toolset: gcc-8
|
|
||||||
cxxstd: "11,14,17,2a"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:18.04
|
|
||||||
install:
|
|
||||||
- g++-8
|
|
||||||
- toolset: gcc-9
|
|
||||||
cxxstd: "11,14,17,2a"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:20.04
|
|
||||||
install:
|
|
||||||
- g++-9
|
|
||||||
- toolset: gcc-10
|
|
||||||
cxxstd: "11,14,17,20"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:20.04
|
|
||||||
install:
|
|
||||||
- g++-10
|
|
||||||
- toolset: gcc-11
|
|
||||||
cxxstd: "11,14,17,20,23"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
install:
|
|
||||||
- g++-11
|
|
||||||
- toolset: gcc-12
|
|
||||||
cxxstd: "11,14,17,20,23"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
install:
|
|
||||||
- g++-12
|
|
||||||
- toolset: gcc-13
|
|
||||||
cxxstd: "11,14,17,20,23"
|
|
||||||
os: ubuntu-24.04
|
|
||||||
install:
|
|
||||||
- g++-13
|
|
||||||
- toolset: gcc-14
|
|
||||||
cxxstd: "11,14,17,20,23,26"
|
|
||||||
os: ubuntu-24.04
|
|
||||||
install:
|
|
||||||
- g++-14
|
|
||||||
- toolset: gcc-15
|
|
||||||
cxxstd: "11,14,17,20,23,26"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:25.04
|
|
||||||
install:
|
|
||||||
- g++-15
|
|
||||||
- name: UBSAN
|
|
||||||
toolset: gcc-13
|
|
||||||
cxxstd: "11,14,17,20,23"
|
|
||||||
ubsan: 1
|
|
||||||
build_variant: debug
|
|
||||||
os: ubuntu-24.04
|
|
||||||
install:
|
|
||||||
- g++-13
|
|
||||||
|
|
||||||
# Linux, clang
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-3.5
|
|
||||||
cxxstd: "11"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:16.04
|
|
||||||
install:
|
|
||||||
- clang-3.5
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-3.6
|
|
||||||
cxxstd: "11,14"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:16.04
|
|
||||||
install:
|
|
||||||
- clang-3.6
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-3.7
|
|
||||||
cxxstd: "11,14"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:16.04
|
|
||||||
install:
|
|
||||||
- clang-3.7
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-3.8
|
|
||||||
cxxstd: "11,14"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:16.04
|
|
||||||
install:
|
|
||||||
- clang-3.8
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-3.9
|
|
||||||
cxxstd: "11,14"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:18.04
|
|
||||||
install:
|
|
||||||
- clang-3.9
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-4.0
|
|
||||||
cxxstd: "11,14"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:18.04
|
|
||||||
install:
|
|
||||||
- clang-4.0
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-5.0
|
|
||||||
cxxstd: "11,14,1z"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:18.04
|
|
||||||
install:
|
|
||||||
- clang-5.0
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-6.0
|
|
||||||
cxxstd: "11,14,17"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:18.04
|
|
||||||
install:
|
|
||||||
- clang-6.0
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-7
|
|
||||||
cxxstd: "11,14,17"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:18.04
|
|
||||||
install:
|
|
||||||
- clang-7
|
|
||||||
# Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-8
|
|
||||||
cxxstd: "11,14,17,2a"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:18.04
|
|
||||||
install:
|
|
||||||
- clang-8
|
|
||||||
- g++-7
|
|
||||||
gcc_toolchain: 7
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-9
|
|
||||||
cxxstd: "11,14,17,2a"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:20.04
|
|
||||||
install:
|
|
||||||
- clang-9
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-10
|
|
||||||
cxxstd: "11,14,17,20"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:20.04
|
|
||||||
install:
|
|
||||||
- clang-10
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-11
|
|
||||||
cxxstd: "11,14,17,20"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
install:
|
|
||||||
- clang-11
|
|
||||||
- g++-11
|
|
||||||
gcc_toolchain: 11
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-12
|
|
||||||
cxxstd: "11,14,17,20,2b"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
install:
|
|
||||||
- clang-12
|
|
||||||
- g++-11
|
|
||||||
gcc_toolchain: 11
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-13
|
|
||||||
cxxstd: "11,14,17,20,2b"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
install:
|
|
||||||
- clang-13
|
|
||||||
- g++-11
|
|
||||||
gcc_toolchain: 11
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-14
|
|
||||||
cxxstd: "11,14,17,20,2b"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
install:
|
|
||||||
- clang-14
|
|
||||||
- g++-11
|
|
||||||
gcc_toolchain: 11
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-15
|
|
||||||
cxxstd: "11,14,17,20,2b"
|
|
||||||
os: ubuntu-22.04
|
|
||||||
install:
|
|
||||||
- clang-15
|
|
||||||
- g++-11
|
|
||||||
gcc_toolchain: 11
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-16
|
|
||||||
cxxstd: "11,14,17,20,2b"
|
|
||||||
os: ubuntu-24.04
|
|
||||||
install:
|
|
||||||
- clang-16
|
|
||||||
- g++-11
|
|
||||||
gcc_toolchain: 11
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-17
|
|
||||||
cxxstd: "11,14,17,20,23,26"
|
|
||||||
os: ubuntu-24.04
|
|
||||||
install:
|
|
||||||
- clang-17
|
|
||||||
- g++-11
|
|
||||||
gcc_toolchain: 11
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-18
|
|
||||||
cxxstd: "11,14,17,20,23,26"
|
|
||||||
os: ubuntu-24.04
|
|
||||||
install:
|
|
||||||
- clang-18
|
|
||||||
- g++-13
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-19
|
|
||||||
cxxstd: "11,14,17,20,23,26"
|
|
||||||
os: ubuntu-24.04
|
|
||||||
install:
|
|
||||||
- clang-19
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-20
|
|
||||||
cxxstd: "11,14,17,20,23,26"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:25.04
|
|
||||||
install:
|
|
||||||
- clang-20
|
|
||||||
- toolset: clang
|
|
||||||
compiler: clang++-20
|
|
||||||
cxxstd: "11,14,17,20,23,26"
|
|
||||||
os: ubuntu-latest
|
|
||||||
container: ubuntu:25.04
|
|
||||||
install:
|
|
||||||
- clang-20
|
|
||||||
- libc++-20-dev
|
|
||||||
- libc++abi-20-dev
|
|
||||||
cxxflags: -stdlib=libc++
|
|
||||||
linkflags: -stdlib=libc++
|
|
||||||
- name: UBSAN
|
|
||||||
toolset: clang
|
|
||||||
compiler: clang++-18
|
|
||||||
cxxstd: "11,14,17,20,23,26"
|
|
||||||
cxxflags: -stdlib=libc++
|
|
||||||
linkflags: "-stdlib=libc++ -lubsan"
|
|
||||||
ubsan: 1
|
|
||||||
build_variant: debug
|
|
||||||
os: ubuntu-24.04
|
|
||||||
install:
|
|
||||||
- clang-18
|
|
||||||
- libc++-18-dev
|
|
||||||
- libc++abi-18-dev
|
|
||||||
|
|
||||||
- toolset: clang
|
|
||||||
cxxstd: "11,14,17,20,2b"
|
|
||||||
os: macos-13
|
|
||||||
- toolset: clang
|
|
||||||
cxxstd: "11,14,17,20,2b"
|
|
||||||
os: macos-14
|
|
||||||
- toolset: clang
|
|
||||||
cxxstd: "11,14,17,20,2b"
|
|
||||||
os: macos-15
|
|
||||||
|
|
||||||
- name: CMake tests
|
|
||||||
cmake_tests: 1
|
|
||||||
os: ubuntu-24.04
|
|
||||||
|
|
||||||
timeout-minutes: 20
|
|
||||||
runs-on: ${{matrix.os}}
|
|
||||||
container: ${{matrix.container}}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Setup environment
|
|
||||||
run: |
|
|
||||||
if [ -f "/etc/debian_version" ]
|
|
||||||
then
|
|
||||||
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
fi
|
|
||||||
if [ -n "${{matrix.container}}" ]
|
|
||||||
then
|
|
||||||
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
|
|
||||||
if [ -f "/etc/debian_version" ]
|
|
||||||
then
|
|
||||||
# Use Azure APT mirrors in containers to avoid HTTP errors due to DDoS filters triggered by lots of CI jobs launching concurrently.
|
|
||||||
# Note that not all Ubuntu versions support "mirror+file:..." URIs in APT sources, so just use Azure mirrors exclusively.
|
|
||||||
# Note also that on recent Ubuntu versions DEB822 format is used for source files.
|
|
||||||
APT_SOURCES=()
|
|
||||||
if [ -d "/etc/apt/sources.list.d" ]
|
|
||||||
then
|
|
||||||
readarray -t APT_SOURCES < <(find "/etc/apt/sources.list.d" -type f -name '*.sources' -print)
|
|
||||||
fi
|
|
||||||
if [ -f "/etc/apt/sources.list" ]
|
|
||||||
then
|
|
||||||
APT_SOURCES+=("/etc/apt/sources.list")
|
|
||||||
fi
|
|
||||||
if [ "${#APT_SOURCES[@]}" -gt 0 ]
|
|
||||||
then
|
|
||||||
sed -i -E -e 's!([^ ]+) (http|https)://(archive|security)\.ubuntu\.com/ubuntu[^ ]*(.*)!\1 http://azure.archive.ubuntu.com/ubuntu/\4!' "${APT_SOURCES[@]}"
|
|
||||||
fi
|
|
||||||
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
|
|
||||||
if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ]
|
|
||||||
then
|
|
||||||
PYTHON_PACKAGE="python-is-python3"
|
|
||||||
else
|
|
||||||
PYTHON_PACKAGE="python"
|
|
||||||
fi
|
|
||||||
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
git config --global pack.threads 0
|
|
||||||
|
|
||||||
- name: Install packages
|
|
||||||
if: matrix.install
|
|
||||||
run: |
|
|
||||||
declare -a SOURCE_KEYS SOURCES
|
|
||||||
if [ -n "${{join(matrix.source_keys, ' ')}}" ]
|
|
||||||
then
|
|
||||||
SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}")
|
|
||||||
fi
|
|
||||||
if [ -n "${{join(matrix.sources, ' ')}}" ]
|
|
||||||
then
|
|
||||||
SOURCES=("${{join(matrix.sources, '" "')}}")
|
|
||||||
fi
|
|
||||||
for key in "${SOURCE_KEYS[@]}"
|
|
||||||
do
|
|
||||||
for i in {1..$NET_RETRY_COUNT}
|
|
||||||
do
|
|
||||||
echo "Adding key: $key"
|
|
||||||
wget -O - "$key" | sudo apt-key add - && break || sleep 2
|
|
||||||
done
|
|
||||||
done
|
|
||||||
if [ ${#SOURCES[@]} -gt 0 ]
|
|
||||||
then
|
|
||||||
APT_ADD_REPO_COMMON_ARGS=("-y")
|
|
||||||
APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')"
|
|
||||||
if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ]
|
|
||||||
then
|
|
||||||
APT_ADD_REPO_COMMON_ARGS+=("-n")
|
|
||||||
fi
|
|
||||||
APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)"
|
|
||||||
for source in "${SOURCES[@]}"
|
|
||||||
do
|
|
||||||
for i in {1..$NET_RETRY_COUNT}
|
|
||||||
do
|
|
||||||
APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}")
|
|
||||||
if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ]
|
|
||||||
then
|
|
||||||
case "$source" in
|
|
||||||
"ppa:"*)
|
|
||||||
APT_ADD_REPO_ARGS+=("-P")
|
|
||||||
;;
|
|
||||||
"deb "*)
|
|
||||||
APT_ADD_REPO_ARGS+=("-S")
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
APT_ADD_REPO_ARGS+=("-U")
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
APT_ADD_REPO_ARGS+=("$source")
|
|
||||||
echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}"
|
|
||||||
sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
|
|
||||||
done
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
|
|
||||||
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}}
|
|
||||||
|
|
||||||
- name: Setup GCC Toolchain
|
|
||||||
if: matrix.gcc_toolchain
|
|
||||||
run: |
|
|
||||||
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
|
|
||||||
echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV
|
|
||||||
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
|
|
||||||
mkdir -p "$GCC_TOOLCHAIN_ROOT"
|
|
||||||
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
|
|
||||||
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
|
|
||||||
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
|
|
||||||
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
|
|
||||||
|
|
||||||
- name: Setup Boost
|
|
||||||
run: |
|
|
||||||
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
|
|
||||||
LIBRARY=${GITHUB_REPOSITORY#*/}
|
|
||||||
echo LIBRARY: $LIBRARY
|
|
||||||
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
|
|
||||||
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
|
|
||||||
echo GITHUB_REF: $GITHUB_REF
|
|
||||||
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
|
|
||||||
REF=${REF#refs/heads/}
|
|
||||||
echo REF: $REF
|
|
||||||
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
|
|
||||||
echo BOOST_BRANCH: $BOOST_BRANCH
|
|
||||||
BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null)
|
|
||||||
echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV
|
|
||||||
echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV
|
|
||||||
DEPINST_ARGS=()
|
|
||||||
GIT_VERSION="$(git --version | sed -e 's/git version //')"
|
|
||||||
GIT_HAS_JOBS=1
|
|
||||||
if [ -f "/etc/debian_version" ]
|
|
||||||
then
|
|
||||||
if $(dpkg --compare-versions "$GIT_VERSION" lt 2.8.0)
|
|
||||||
then
|
|
||||||
GIT_HAS_JOBS=0
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
declare -a GIT_VER=(${GIT_VERSION//./ })
|
|
||||||
declare -a GIT_MIN_VER=(2 8 0)
|
|
||||||
for ((i=0; i<${#GIT_VER[@]}; i++))
|
|
||||||
do
|
|
||||||
if [ -z "${GIT_MIN_VER[i]}" ]
|
|
||||||
then
|
|
||||||
GIT_MIN_VER[i]=0
|
|
||||||
fi
|
|
||||||
if [ "${GIT_VER[i]}" -lt "${GIT_MIN_VER[i]}" ]
|
|
||||||
then
|
|
||||||
GIT_HAS_JOBS=0
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
if [ "$GIT_HAS_JOBS" -ne 0 ]
|
|
||||||
then
|
|
||||||
DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS")
|
|
||||||
fi
|
|
||||||
mkdir -p snapshot
|
|
||||||
cd snapshot
|
|
||||||
echo "Downloading library snapshot: https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
|
|
||||||
curl -L --retry "$NET_RETRY_COUNT" -o "${LIBRARY}-${GITHUB_SHA}.tar.gz" "https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
|
|
||||||
tar -xf "${LIBRARY}-${GITHUB_SHA}.tar.gz"
|
|
||||||
if [ ! -d "${LIBRARY}-${GITHUB_SHA}" ]
|
|
||||||
then
|
|
||||||
echo "Library snapshot does not contain the library directory ${LIBRARY}-${GITHUB_SHA}:"
|
|
||||||
ls -la
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
rm -f "${LIBRARY}-${GITHUB_SHA}.tar.gz"
|
|
||||||
cd ..
|
|
||||||
git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root"
|
|
||||||
cd boost-root
|
|
||||||
mkdir -p libs
|
|
||||||
rm -rf "libs/$LIBRARY"
|
|
||||||
mv -f "../snapshot/${LIBRARY}-${GITHUB_SHA}" "libs/$LIBRARY"
|
|
||||||
rm -rf "../snapshot"
|
|
||||||
git submodule update --init tools/boostdep
|
|
||||||
DEPINST_ARGS+=("$LIBRARY")
|
|
||||||
python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}"
|
|
||||||
if [ -z "${{matrix.cmake_tests}}" ]
|
|
||||||
then
|
|
||||||
./bootstrap.sh
|
|
||||||
./b2 headers
|
|
||||||
if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ]
|
|
||||||
then
|
|
||||||
echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam
|
|
||||||
if [ -n "$GCC_TOOLCHAIN_ROOT" ]
|
|
||||||
then
|
|
||||||
echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam
|
|
||||||
fi
|
|
||||||
echo " ;" >> ~/user-config.jam
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
if: matrix.cmake_tests == ''
|
|
||||||
run: |
|
|
||||||
cd boost-root
|
|
||||||
B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}")
|
|
||||||
if [ -n "${{matrix.build_variant}}" ]
|
|
||||||
then
|
|
||||||
B2_ARGS+=("variant=${{matrix.build_variant}}")
|
|
||||||
else
|
|
||||||
B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT")
|
|
||||||
fi
|
|
||||||
if [ -n "${{matrix.threading}}" ]
|
|
||||||
then
|
|
||||||
B2_ARGS+=("threading=${{matrix.threading}}")
|
|
||||||
fi
|
|
||||||
if [ -n "${{matrix.ubsan}}" ]
|
|
||||||
then
|
|
||||||
export UBSAN_OPTIONS="print_stacktrace=1"
|
|
||||||
B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global")
|
|
||||||
fi
|
|
||||||
if [ -n "${{matrix.cxxflags}}" ]
|
|
||||||
then
|
|
||||||
B2_ARGS+=("cxxflags=${{matrix.cxxflags}}")
|
|
||||||
fi
|
|
||||||
if [ -n "${{matrix.linkflags}}" ]
|
|
||||||
then
|
|
||||||
B2_ARGS+=("linkflags=${{matrix.linkflags}}")
|
|
||||||
fi
|
|
||||||
B2_ARGS+=("libs/$LIBRARY/test")
|
|
||||||
./b2 "${B2_ARGS[@]}"
|
|
||||||
|
|
||||||
- name: Run CMake tests
|
|
||||||
if: matrix.cmake_tests
|
|
||||||
run: |
|
|
||||||
if [ -n "${{matrix.macosx_version_min}}" ]
|
|
||||||
then
|
|
||||||
export MACOSX_DEPLOYMENT_TARGET="${{matrix.macosx_version_min}}"
|
|
||||||
fi
|
|
||||||
cd boost-root
|
|
||||||
mkdir __build_static__ && cd __build_static__
|
|
||||||
cmake ../libs/$LIBRARY/test/test_cmake
|
|
||||||
cmake --build . --target boost_${LIBRARY}_cmake_self_test -j $BUILD_JOBS
|
|
||||||
cd ..
|
|
||||||
mkdir __build_shared__ && cd __build_shared__
|
|
||||||
cmake -DBUILD_SHARED_LIBS=On ../libs/$LIBRARY/test/test_cmake
|
|
||||||
cmake --build . --target boost_${LIBRARY}_cmake_self_test -j $BUILD_JOBS
|
|
||||||
|
|
||||||
windows:
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: cmd
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- toolset: msvc-14.3
|
|
||||||
cxxstd: "14,17,20,latest"
|
|
||||||
addrmd: 32,64
|
|
||||||
os: windows-2022
|
|
||||||
- toolset: clang-win
|
|
||||||
cxxstd: "14,17,latest"
|
|
||||||
addrmd: 32,64
|
|
||||||
os: windows-2022
|
|
||||||
- toolset: gcc
|
|
||||||
cxxstd: "11,14,17,20,23"
|
|
||||||
addrmd: 64
|
|
||||||
os: windows-2022
|
|
||||||
|
|
||||||
timeout-minutes: 20
|
|
||||||
runs-on: ${{matrix.os}}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Setup Boost
|
|
||||||
run: |
|
|
||||||
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
|
|
||||||
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
|
|
||||||
echo LIBRARY: %LIBRARY%
|
|
||||||
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
|
|
||||||
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
|
|
||||||
echo GITHUB_REF: %GITHUB_REF%
|
|
||||||
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
|
|
||||||
set BOOST_BRANCH=develop
|
|
||||||
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
|
|
||||||
echo BOOST_BRANCH: %BOOST_BRANCH%
|
|
||||||
mkdir snapshot
|
|
||||||
cd snapshot
|
|
||||||
echo Downloading library snapshot: https://github.com/%GITHUB_REPOSITORY%/archive/%GITHUB_SHA%.zip
|
|
||||||
curl -L --retry %NET_RETRY_COUNT% -o "%LIBRARY%-%GITHUB_SHA%.zip" "https://github.com/%GITHUB_REPOSITORY%/archive/%GITHUB_SHA%.zip"
|
|
||||||
tar -xf "%LIBRARY%-%GITHUB_SHA%.zip"
|
|
||||||
if not exist "%LIBRARY%-%GITHUB_SHA%\" (
|
|
||||||
echo Library snapshot does not contain the library directory %LIBRARY%-%GITHUB_SHA%:
|
|
||||||
dir
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
del /f "%LIBRARY%-%GITHUB_SHA%.zip"
|
|
||||||
cd ..
|
|
||||||
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
|
||||||
cd boost-root
|
|
||||||
if not exist "libs\" mkdir libs
|
|
||||||
if exist "libs\%LIBRARY%\" rmdir /s /q "libs\%LIBRARY%"
|
|
||||||
move /Y "..\snapshot\%LIBRARY%-%GITHUB_SHA%" "libs\%LIBRARY%"
|
|
||||||
rmdir /s /q "..\snapshot"
|
|
||||||
git submodule update --init tools/boostdep
|
|
||||||
python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" %LIBRARY%
|
|
||||||
cmd /c bootstrap
|
|
||||||
b2 -d0 headers
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: |
|
|
||||||
cd boost-root
|
|
||||||
if not "${{matrix.cxxstd}}" == "" set CXXSTD=cxxstd=${{matrix.cxxstd}}
|
|
||||||
if not "${{matrix.addrmd}}" == "" set ADDRMD=address-model=${{matrix.addrmd}}
|
|
||||||
if not "${{matrix.build_variant}}" == "" (set BUILD_VARIANT=variant=${{matrix.build_variant}}) else (set BUILD_VARIANT=variant=%DEFAULT_BUILD_VARIANT%)
|
|
||||||
b2 -j %NUMBER_OF_PROCESSORS% libs/%LIBRARY%/test toolset=${{matrix.toolset}} %CXXSTD% %ADDRMD% %BUILD_VARIANT% embed-manifest-via=linker
|
|
@ -1,27 +0,0 @@
|
|||||||
# Copyright 2018 Peter Dimov
|
|
||||||
# Copyright 2018 Andrey Semashev
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.5...3.20)
|
|
||||||
|
|
||||||
project(boost_iterator VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
|
||||||
|
|
||||||
add_library(boost_iterator INTERFACE)
|
|
||||||
add_library(Boost::iterator ALIAS boost_iterator)
|
|
||||||
|
|
||||||
target_include_directories(boost_iterator INTERFACE include)
|
|
||||||
|
|
||||||
target_link_libraries(boost_iterator
|
|
||||||
INTERFACE
|
|
||||||
Boost::assert
|
|
||||||
Boost::concept_check
|
|
||||||
Boost::config
|
|
||||||
Boost::core
|
|
||||||
Boost::detail
|
|
||||||
Boost::fusion
|
|
||||||
Boost::mpl
|
|
||||||
Boost::optional
|
|
||||||
Boost::type_traits
|
|
||||||
Boost::utility
|
|
||||||
)
|
|
27
README.md
27
README.md
@ -1,27 +0,0 @@
|
|||||||
# Boost.Iterator
|
|
||||||
|
|
||||||
Boost.Iterator, part of collection of the [Boost C++ Libraries](https://github.com/boostorg), provides tools for building and working with iterators in C++. The library also provides a number of iterator classes that can be used out of the box.
|
|
||||||
|
|
||||||
### Directories
|
|
||||||
|
|
||||||
* **doc** - Documentation sources
|
|
||||||
* **include** - Interface headers of Boost.Iterator
|
|
||||||
* **test** - Boost.Iterator unit tests
|
|
||||||
* **example** - Boost.Iterator usage examples
|
|
||||||
|
|
||||||
### More information
|
|
||||||
|
|
||||||
* [Documentation](https://boost.org/libs/iterator)
|
|
||||||
* [Report bugs](https://github.com/boostorg/iterator/issues/new). Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
|
|
||||||
* Submit your patches as [pull requests](https://github.com/boostorg/iterator/compare) against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
|
|
||||||
|
|
||||||
### Build status
|
|
||||||
|
|
||||||
Branch | GitHub Actions | AppVeyor | Test Matrix | Dependencies |
|
|
||||||
:-------------: | -------------- | -------- | ----------- | ------------ |
|
|
||||||
[`master`](https://github.com/boostorg/iterator/tree/master) | [](https://github.com/boostorg/iterator/actions?query=branch%3Amaster) | [](https://ci.appveyor.com/project/Lastique/iterator/branch/master) | [](http://www.boost.org/development/tests/master/developer/iterator.html) | [](https://pdimov.github.io/boostdep-report/master/iterator.html)
|
|
||||||
[`develop`](https://github.com/boostorg/iterator/tree/develop) | [](https://github.com/boostorg/iterator/actions?query=branch%3Adevelop) | [](https://ci.appveyor.com/project/Lastique/iterator/branch/develop) | [](http://www.boost.org/development/tests/develop/developer/iterator.html) | [](https://pdimov.github.io/boostdep-report/develop/iterator.html)
|
|
||||||
|
|
||||||
### License
|
|
||||||
|
|
||||||
Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
|
|
95
appveyor.yml
95
appveyor.yml
@ -1,95 +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-14.0
|
|
||||||
CXXSTD: 14,latest
|
|
||||||
ADDRMD: 32,64
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
|
||||||
- TOOLSET: msvc-14.1
|
|
||||||
CXXSTD: 14,17,latest
|
|
||||||
ADDRMD: 32,64
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
|
||||||
- TOOLSET: msvc-14.2
|
|
||||||
ADDRMD: 32,64
|
|
||||||
CXXSTD: 14,17,20,latest
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
|
||||||
- TOOLSET: msvc-14.3
|
|
||||||
ADDRMD: 32,64
|
|
||||||
CXXSTD: 14,17,20,latest
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
|
||||||
- TOOLSET: clang-win
|
|
||||||
ADDRMD: 32,64
|
|
||||||
CXXSTD: 14,17,latest
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
|
||||||
- TOOLSET: gcc
|
|
||||||
CXXSTD: 11,14,1z
|
|
||||||
ADDPATH: C:\cygwin\bin;
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
|
||||||
- TOOLSET: gcc
|
|
||||||
CXXSTD: 11,14,1z
|
|
||||||
ADDPATH: C:\cygwin64\bin;
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
|
||||||
- TOOLSET: gcc
|
|
||||||
CXXSTD: 11,14,1z
|
|
||||||
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
|
||||||
- TOOLSET: gcc
|
|
||||||
CXXSTD: 11,14,1z
|
|
||||||
ADDPATH: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin;
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
|
||||||
- TEST_CMAKE: 1
|
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
|
||||||
|
|
||||||
install:
|
|
||||||
- set GIT_FETCH_JOBS=8
|
|
||||||
- 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%
|
|
||||||
|
|
||||||
for:
|
|
||||||
- matrix:
|
|
||||||
only: [TEST_CMAKE: 1]
|
|
||||||
test_script:
|
|
||||||
- mkdir __build_static__
|
|
||||||
- cd __build_static__
|
|
||||||
- cmake ../libs/iterator/test/test_cmake
|
|
||||||
- cmake --build . --target boost_iterator_cmake_self_test -j %NUMBER_OF_PROCESSORS%
|
|
||||||
- cd ..
|
|
||||||
- mkdir __build_shared__
|
|
||||||
- cd __build_shared__
|
|
||||||
- cmake -DBUILD_SHARED_LIBS=On ../libs/iterator/test/test_cmake
|
|
||||||
- cmake --build . --target boost_iterator_cmake_self_test -j %NUMBER_OF_PROCESSORS%
|
|
32
build.jam
32
build.jam
@ -1,32 +0,0 @@
|
|||||||
# Copyright René Ferdinand Rivera Morell 2023-2024
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
# http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
require-b2 5.2 ;
|
|
||||||
|
|
||||||
constant boost_dependencies :
|
|
||||||
/boost/assert//boost_assert
|
|
||||||
/boost/concept_check//boost_concept_check
|
|
||||||
/boost/config//boost_config
|
|
||||||
/boost/core//boost_core
|
|
||||||
/boost/detail//boost_detail
|
|
||||||
/boost/fusion//boost_fusion
|
|
||||||
/boost/mpl//boost_mpl
|
|
||||||
/boost/optional//boost_optional
|
|
||||||
/boost/type_traits//boost_type_traits
|
|
||||||
/boost/utility//boost_utility ;
|
|
||||||
|
|
||||||
project /boost/iterator
|
|
||||||
: common-requirements
|
|
||||||
<include>include
|
|
||||||
;
|
|
||||||
|
|
||||||
explicit
|
|
||||||
[ alias boost_iterator : : : : <library>$(boost_dependencies) ]
|
|
||||||
[ alias all : boost_iterator test ]
|
|
||||||
;
|
|
||||||
|
|
||||||
call-if : boost-library iterator
|
|
||||||
;
|
|
||||||
|
|
@ -4,24 +4,20 @@
|
|||||||
|
|
||||||
using quickbook ;
|
using quickbook ;
|
||||||
|
|
||||||
xml iterator
|
xml iterator
|
||||||
:
|
:
|
||||||
quickbook/iterator.qbk
|
quickbook/iterator.qbk
|
||||||
;
|
;
|
||||||
|
|
||||||
boostbook standalone
|
boostbook standalone
|
||||||
:
|
:
|
||||||
iterator
|
iterator
|
||||||
:
|
:
|
||||||
<xsl:param>"boost.root=../../../.."
|
<xsl:param>boost.root=../../../..
|
||||||
<xsl:param>toc.max.depth=3
|
<xsl:param>toc.max.depth=3
|
||||||
<xsl:param>toc.section.depth=3
|
<xsl:param>toc.section.depth=3
|
||||||
<xsl:param>chunk.section.depth=2
|
<xsl:param>chunk.section.depth=4
|
||||||
<format>pdf:<xsl:param>"boost.url.prefix=http://www.boost.org/doc/libs/release/libs/iterator/doc/html"
|
<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
|
|
@ -11,6 +11,7 @@
|
|||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, University of Hanover `Institute for Transport
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
Railway Operation and Construction`_
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
:Author: David Goodger
|
:Author: David Goodger
|
||||||
:Contact: goodger@users.sourceforge.net
|
:Contact: goodger@users.sourceforge.net
|
||||||
|
:date: $Date$
|
||||||
|
:version: $Revision$
|
||||||
:copyright: This stylesheet has been placed in the public domain.
|
:copyright: This stylesheet has been placed in the public domain.
|
||||||
|
|
||||||
boostinspect:nolicense
|
boostinspect:nolicense
|
||||||
|
@ -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
|
|
@ -4,6 +4,7 @@
|
|||||||
%%
|
%%
|
||||||
%% o author: Alexander Schmolck (a.schmolck@gmx.net)
|
%% o author: Alexander Schmolck (a.schmolck@gmx.net)
|
||||||
%% o created: 2002-07-07 10:50:31+00:40
|
%% o created: 2002-07-07 10:50:31+00:40
|
||||||
|
%% o last modified: $Date: 2004/01/29 05:55:26 $
|
||||||
%% o keywords:
|
%% o keywords:
|
||||||
%% o license:
|
%% o license:
|
||||||
%XXX titlesec
|
%XXX titlesec
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
|
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
|
||||||
<tr><th class="docinfo-name">Date:</th>
|
<tr><th class="docinfo-name">Date:</th>
|
||||||
<td>2006-09-11</td></tr>
|
<td>2006-09-11</td></tr>
|
||||||
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://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
|
accepted for Technical Report 1 by the C++ standard
|
||||||
committee's library working group.</td>
|
committee's library working group.</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -239,29 +239,29 @@ Iterator Concepts.</p>
|
|||||||
<div class="section" id="iterator-concepts">
|
<div class="section" id="iterator-concepts">
|
||||||
<h2><a class="toc-backref" href="#id18">Iterator Concepts</a></h2>
|
<h2><a class="toc-backref" href="#id18">Iterator Concepts</a></h2>
|
||||||
<p>This proposal is formulated in terms of the new <tt class="docutils literal"><span class="pre">iterator</span> <span class="pre">concepts</span></tt>
|
<p>This proposal is formulated in terms of the new <tt class="docutils literal"><span class="pre">iterator</span> <span class="pre">concepts</span></tt>
|
||||||
as proposed in <a class="reference external" href="http://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
|
iterators suffer from the well known categorization problems that are
|
||||||
inherent to the current iterator categories.</p>
|
inherent to the current iterator categories.</p>
|
||||||
<p>This proposal does not strictly depend on proposal <a class="reference external" href="http://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
|
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>
|
||||||
<div class="section" id="interoperability">
|
<div class="section" id="interoperability">
|
||||||
<h2><a class="toc-backref" href="#id19">Interoperability</a></h2>
|
<h2><a class="toc-backref" href="#id19">Interoperability</a></h2>
|
||||||
<p>The question of iterator interoperability is poorly addressed in the
|
<p>The question of iterator interoperability is poorly addressed in the
|
||||||
current standard. There are currently two defect reports that are
|
current standard. There are currently two defect reports that are
|
||||||
concerned with interoperability issues.</p>
|
concerned with interoperability issues.</p>
|
||||||
<p>Issue <a class="reference external" href="http://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
|
are only required to be convertible to the corresponding constant
|
||||||
iterator types, but objects of these types are not required to
|
iterator types, but objects of these types are not required to
|
||||||
interoperate in comparison or subtraction expressions. This situation
|
interoperate in comparison or subtraction expressions. This situation
|
||||||
is tedious in practice and out of line with the way built in types
|
is tedious in practice and out of line with the way built in types
|
||||||
work. This proposal implements the proposed resolution to issue
|
work. This proposal implements the proposed resolution to issue
|
||||||
<a class="reference external" href="http://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
|
words, if an iterator type A has an implicit or user defined
|
||||||
conversion to an iterator type B, the iterator types are interoperable
|
conversion to an iterator type B, the iterator types are interoperable
|
||||||
and the usual set of operators are available.</p>
|
and the usual set of operators are available.</p>
|
||||||
<p>Issue <a class="reference external" href="http://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
|
reverse iterator types. The proposed new reverse_iterator template
|
||||||
fixes the issues raised in 280. It provides the desired
|
fixes the issues raised in 280. It provides the desired
|
||||||
interoperability without introducing unwanted overloads.</p>
|
interoperability without introducing unwanted overloads.</p>
|
||||||
@ -422,8 +422,8 @@ member (e.g. <a class="reference internal" href="#counting"><tt class="docutils
|
|||||||
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
|
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
|
||||||
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
|
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
|
||||||
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
|
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
|
||||||
semantics required by the preferred resolution to <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
|
semantics required by the preferred resolution to <a class="reference external" href="http://anubis.dkuug.dk/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
|
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
|
convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is
|
||||||
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
|
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
|
||||||
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach
|
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach
|
||||||
@ -2622,7 +2622,7 @@ proxy object.</p>
|
|||||||
<div class="section" id="header">
|
<div class="section" id="header">
|
||||||
<h4><a class="toc-backref" href="#id70">Header</a></h4>
|
<h4><a class="toc-backref" href="#id70">Header</a></h4>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
#include <boost/iterator/function_output_iterator.hpp>
|
#include <boost/function_output_iterator.hpp>
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
template <class UnaryFunction>
|
template <class UnaryFunction>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, `Zephyr Associates, Inc.`_
|
Lab`_, `Zephyr Associates, Inc.`_
|
||||||
|
:date: $Date$
|
||||||
|
|
||||||
:Number: This is a revised version of N1530_\ =03-0113, which was
|
:Number: This is a revised version of N1530_\ =03-0113, which was
|
||||||
accepted for Technical Report 1 by the C++ standard
|
accepted for Technical Report 1 by the C++ standard
|
||||||
@ -18,7 +19,7 @@
|
|||||||
.. Version 1.9 of this ReStructuredText document corresponds to
|
.. Version 1.9 of this ReStructuredText document corresponds to
|
||||||
n1530_, the paper accepted by the LWG.
|
n1530_, the paper accepted by the LWG.
|
||||||
|
|
||||||
.. _n1530: http://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.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
@ -139,7 +140,7 @@ as proposed in n1550_, since user-defined and especially adapted
|
|||||||
iterators suffer from the well known categorization problems that are
|
iterators suffer from the well known categorization problems that are
|
||||||
inherent to the current iterator categories.
|
inherent to the current iterator categories.
|
||||||
|
|
||||||
.. _n1550: http://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
|
This proposal does not strictly depend on proposal n1550_, as there
|
||||||
is a direct mapping between new and old categories. This proposal
|
is a direct mapping between new and old categories. This proposal
|
||||||
@ -168,8 +169,8 @@ reverse iterator types. The proposed new reverse_iterator template
|
|||||||
fixes the issues raised in 280. It provides the desired
|
fixes the issues raised in 280. It provides the desired
|
||||||
interoperability without introducing unwanted overloads.
|
interoperability without introducing unwanted overloads.
|
||||||
|
|
||||||
.. _179: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179
|
.. _179: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#179
|
||||||
.. _280: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#280
|
.. _280: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#280
|
||||||
|
|
||||||
|
|
||||||
Iterator Facade
|
Iterator Facade
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, University of Hanover `Institute for Transport
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
Railway Operation and Construction`_
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -7,7 +7,7 @@ Header
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
#include <boost/iterator/function_output_iterator.hpp>
|
#include <boost/function_output_iterator.hpp>
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
:Author:
|
:Author:
|
||||||
`Dean Michael Berris <mailto:me@deanberris.com>`_
|
`Dean Michael Berris <mailto:mikhailberis@gmail.com>`_
|
||||||
|
|
||||||
:License:
|
:License:
|
||||||
Distributed under the Boost Software License, Version 1.0
|
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 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
|
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
|
.. _InputIterator: http://www.sgi.com/tech/stl/InputIterator.html
|
||||||
|
|
||||||
The Function Input Iterator takes a function that models the Generator_ concept
|
Like the Generator Iterator, the Function Input Iterator takes a function
|
||||||
(which is basically a nullary or 0-arity function object). The first dereference
|
that models the Generator_ concept (which is basically a nullary or 0-arity
|
||||||
of the iterator at a given position invokes the generator function and stores
|
function object). Each increment of the function Function Input Iterator
|
||||||
and returns the result; subsequent dereferences at the same position simply
|
invokes the generator function and stores the value in the iterator. When
|
||||||
return the same stored result. Incrementing the iterator places it at a new
|
the iterator is dereferenced the stored value is returned.
|
||||||
position, hence a subsequent dereference will generate a new value via another
|
|
||||||
invokation of the generator function. This ensures the generator function is
|
|
||||||
invoked precisely when the iterator is requested to return a (new) value.
|
|
||||||
|
|
||||||
.. _Generator: http://www.sgi.com/tech/stl/Generator.html
|
.. _Generator: http://www.sgi.com/tech/stl/Generator.html
|
||||||
|
|
||||||
@ -64,7 +58,7 @@ Synopsis
|
|||||||
|
|
||||||
template <class Function, class State>
|
template <class Function, class State>
|
||||||
typename function_input_iterator<Function, State>
|
typename function_input_iterator<Function, State>
|
||||||
make_function_input_iterator(Function & f, State s);
|
make_function_input_iterator(Function & f);
|
||||||
|
|
||||||
struct infinite;
|
struct infinite;
|
||||||
}
|
}
|
||||||
@ -118,7 +112,7 @@ it with the ``boost::infinite`` helper class.
|
|||||||
copy(
|
copy(
|
||||||
make_function_input_iterator(f,infinite()),
|
make_function_input_iterator(f,infinite()),
|
||||||
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
|
Above, instead of creating a huge vector we rely on the STL copy algorithm
|
||||||
|
@ -68,7 +68,7 @@ proxy object.</td>
|
|||||||
<div class="section" id="header">
|
<div class="section" id="header">
|
||||||
<h1><a class="toc-backref" href="#id1">Header</a></h1>
|
<h1><a class="toc-backref" href="#id1">Header</a></h1>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
#include <boost/iterator/function_output_iterator.hpp>
|
#include <boost/function_output_iterator.hpp>
|
||||||
</pre>
|
</pre>
|
||||||
<pre class="literal-block">
|
<pre class="literal-block">
|
||||||
template <class UnaryFunction>
|
template <class UnaryFunction>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, University of Hanover `Institute for Transport
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
Railway Operation and Construction`_
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -1,162 +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/iterator/generator_iterator.hpp">boost/iterator/generator_iterator.hpp</a></p>
|
|
||||||
|
|
||||||
<p>The generator iterator adaptor makes it easier to create custom input
|
|
||||||
iterators from 0-ary functions and function objects. The adaptor takes a
|
|
||||||
<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 {
|
|
||||||
namespace iterators {
|
|
||||||
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:
|
|
||||||
using type = <i>unspecified</i>; // 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 is deduced automatically from its
|
|
||||||
<tt>operator()</tt>. The function object must be a model of
|
|
||||||
<a href=
|
|
||||||
"http://www.sgi.com/tech/stl/Generator.html">Generator</a>.</td>
|
|
||||||
</tr>
|
|
||||||
</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/iterators/generator_iterator.hpp>
|
|
||||||
|
|
||||||
class my_generator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using result_type = int;
|
|
||||||
my_generator() : state(0) { }
|
|
||||||
result_type operator()() { return ++state; }
|
|
||||||
private:
|
|
||||||
int state;
|
|
||||||
};
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
my_generator gen;
|
|
||||||
auto it = boost::iterators::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>
|
|
@ -26,6 +26,8 @@
|
|||||||
<tr class="field"><th class="field-name">organizations:</th><td class="field-body"><a class="reference external" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference external" href="http://www.osl.iu.edu">Open Systems
|
<tr class="field"><th class="field-name">organizations:</th><td class="field-body"><a class="reference external" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference external" href="http://www.osl.iu.edu">Open Systems
|
||||||
Lab</a>, <a class="reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td>
|
Lab</a>, <a class="reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr class="field"><th class="field-name">date:</th><td class="field-body">$Date$</td>
|
||||||
|
</tr>
|
||||||
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003.</td>
|
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -129,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
|
<li><a class="reference external" href="function_output_iterator.html"><tt class="docutils literal"><span class="pre">function_output_iterator</span></tt></a> (<a class="reference external" href="function_output_iterator.pdf">PDF</a>): an output iterator wrapping a unary function
|
||||||
object; each time an element is written into the dereferenced
|
object; each time an element is written into the dereferenced
|
||||||
iterator, it is passed as a parameter to the function object.</li>
|
iterator, it is passed as a parameter to the function object.</li>
|
||||||
<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
|
<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>
|
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
|
<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
|
||||||
@ -140,7 +139,7 @@ sequence, rearranged according to some sequence of integer indices.</li>
|
|||||||
bidirectional sequence in reverse. Corrects many of the
|
bidirectional sequence in reverse. Corrects many of the
|
||||||
shortcomings of C++98's <tt class="docutils literal"><span class="pre">std::reverse_iterator</span></tt>.</li>
|
shortcomings of C++98's <tt class="docutils literal"><span class="pre">std::reverse_iterator</span></tt>.</li>
|
||||||
<li><a class="reference external" href="../../utility/shared_container_iterator.html"><tt class="docutils literal"><span class="pre">shared_container_iterator</span></tt></a>: an iterator over elements of a container whose
|
<li><a class="reference external" href="../../utility/shared_container_iterator.html"><tt class="docutils literal"><span class="pre">shared_container_iterator</span></tt></a>: an iterator over elements of a container whose
|
||||||
lifetime is maintained by a <tt class="docutils literal"><span class="pre">shared_ptr</span></tt> stored in the iterator.</li>
|
lifetime is maintained by a <a class="reference external" href="../../smart_ptr/shared_ptr.htm"><tt class="docutils literal"><span class="pre">shared_ptr</span></tt></a> stored in the iterator.</li>
|
||||||
<li><a class="reference external" href="transform_iterator.html"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt></a> (<a class="reference external" href="transform_iterator.pdf">PDF</a>): an iterator over elements which are the result of
|
<li><a class="reference external" href="transform_iterator.html"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt></a> (<a class="reference external" href="transform_iterator.pdf">PDF</a>): an iterator over elements which are the result of
|
||||||
applying some functional transformation to the elements of an
|
applying some functional transformation to the elements of an
|
||||||
underlying sequence. This component also replaces the old
|
underlying sequence. This component also replaces the old
|
||||||
|
@ -19,6 +19,7 @@ __ ../../../index.htm
|
|||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
||||||
:organizations: `Boost Consulting`_, Indiana University `Open Systems
|
:organizations: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, `Zephyr Associates, Inc.`_
|
Lab`_, `Zephyr Associates, Inc.`_
|
||||||
|
:date: $Date$
|
||||||
|
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003.
|
||||||
|
|
||||||
@ -114,8 +115,8 @@ __ iterator_facade.pdf
|
|||||||
__ iterator_adaptor.pdf
|
__ iterator_adaptor.pdf
|
||||||
|
|
||||||
Both |facade| and |adaptor| as well as many of the `specialized
|
Both |facade| and |adaptor| as well as many of the `specialized
|
||||||
adaptors`_ mentioned below have been proposed for standardization;
|
adaptors`_ mentioned below have been proposed for standardization,
|
||||||
see our
|
and accepted into the first C++ technical report; see our
|
||||||
|
|
||||||
`Standard Proposal For Iterator Facade and Adaptor`__ (PDF__)
|
`Standard Proposal For Iterator Facade and Adaptor`__ (PDF__)
|
||||||
|
|
||||||
@ -145,10 +146,6 @@ iterator templates based on the Boost `iterator facade and adaptor`_.
|
|||||||
object; each time an element is written into the dereferenced
|
object; each time an element is written into the dereferenced
|
||||||
iterator, it is passed as a parameter to the function object.
|
iterator, it is passed as a parameter to the function object.
|
||||||
|
|
||||||
* |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
|
* |indirect|_ (PDF__): an iterator over the objects *pointed-to* by the
|
||||||
elements of some sequence.
|
elements of some sequence.
|
||||||
|
|
||||||
@ -186,9 +183,6 @@ __ function_input_iterator.pdf
|
|||||||
.. _function_output: function_output_iterator.html
|
.. _function_output: function_output_iterator.html
|
||||||
__ function_output_iterator.pdf
|
__ function_output_iterator.pdf
|
||||||
|
|
||||||
.. |generator| replace:: ``generator_iterator``
|
|
||||||
.. _generator: generator_iterator.htm
|
|
||||||
|
|
||||||
.. |indirect| replace:: ``indirect_iterator``
|
.. |indirect| replace:: ``indirect_iterator``
|
||||||
.. _indirect: indirect_iterator.html
|
.. _indirect: indirect_iterator.html
|
||||||
__ indirect_iterator.pdf
|
__ indirect_iterator.pdf
|
||||||
@ -219,23 +213,6 @@ __ zip_iterator.pdf
|
|||||||
Iterator Utilities
|
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
|
Traits
|
||||||
------
|
------
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, University of Hanover `Institute for Transport
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
Railway Operation and Construction`_
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
Interoperability Revisited
|
Interoperability Revisited
|
||||||
++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright Thomas Witt 2004.
|
:copyright: Copyright Thomas Witt 2004.
|
||||||
|
|
||||||
.. Distributed under the Boost
|
.. Distributed under the Boost
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
.. _N1550: http://www.boost-consulting.com/writing/n1550.html
|
.. _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
|
:Author: David Abrahams and Jeremy Siek
|
||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
||||||
:Organization: `Boost Consulting`_, Indiana University Bloomington
|
:Organization: `Boost Consulting`_, Indiana University Bloomington
|
||||||
|
:date: $Date$
|
||||||
:Copyright: Copyright David Abrahams, Jeremy Siek 2003. Use, modification and
|
:Copyright: Copyright David Abrahams, Jeremy Siek 2003. Use, modification and
|
||||||
distribution is subject to the Boost Software License,
|
distribution is subject to the Boost Software License,
|
||||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
|
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, University of Hanover `Institute for Transport
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
Railway Operation and Construction`_
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, `Zephyr Associates, Inc.`_
|
Lab`_, `Zephyr Associates, Inc.`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2004.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2004.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, `Zephyr Associates, Inc.`_
|
Lab`_, `Zephyr Associates, Inc.`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2004.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2004.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -242,8 +242,8 @@ member (e.g. <a class="reference external" href="counting_iterator.html"><tt cla
|
|||||||
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
|
into the temporary iterator <tt class="docutils literal"><span class="pre">p+n</span></tt>, which is destroyed when
|
||||||
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
|
<tt class="docutils literal"><span class="pre">operator[]</span></tt> returns.</p>
|
||||||
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
|
<p>Writable iterators built with <tt class="docutils literal"><span class="pre">iterator_facade</span></tt> implement the
|
||||||
semantics required by the preferred resolution to <a class="reference external" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">issue 299</a> and
|
semantics required by the preferred resolution to <a class="reference external" href="http://anubis.dkuug.dk/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
|
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
|
convertible to the iterator's <tt class="docutils literal"><span class="pre">value_type</span></tt>, and <tt class="docutils literal"><span class="pre">p[n]</span> <span class="pre">=</span> <span class="pre">x</span></tt> is
|
||||||
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
|
equivalent to <tt class="docutils literal"><span class="pre">*(p</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">x</span></tt> (Note: This result object may be
|
||||||
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach
|
implemented as a proxy containing a copy of <tt class="docutils literal"><span class="pre">p+n</span></tt>). This approach
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, University of Hanover `Institute for Transport
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
Railway Operation and Construction`_
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -167,9 +167,9 @@ the implementation of her iterator is free to implement an
|
|||||||
class; it will hide the one supplied by ``iterator_facade`` from
|
class; it will hide the one supplied by ``iterator_facade`` from
|
||||||
clients of her iterator.
|
clients of her iterator.
|
||||||
|
|
||||||
.. _n1550: http://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`:
|
.. _`operator arrow`:
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ The ``iterator_category`` member of ``iterator_facade`` is
|
|||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
|
|
||||||
*iterator-category*\ (CategoryOrTraversal, reference, value_type)
|
*iterator-category*\ (CategoryOrTraversal, value_type, reference)
|
||||||
|
|
||||||
where *iterator-category* is defined as follows:
|
where *iterator-category* is defined as follows:
|
||||||
|
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta name="generator" content="Docutils 0.11: http://docutils.sourceforge.net/" />
|
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
|
||||||
<title>Iterator Traits</title>
|
<title>Iterator Traits</title>
|
||||||
<meta name="author" content="David Abrahams" />
|
<meta name="author" content="David Abrahams" />
|
||||||
<meta name="organization" content="Boost Consulting" />
|
<meta name="organization" content="Boost Consulting" />
|
||||||
|
<meta name="date" content="2006-09-11" />
|
||||||
<meta name="copyright" content="Copyright David Abrahams 2004." />
|
<meta name="copyright" content="Copyright David Abrahams 2004." />
|
||||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||||
</head>
|
</head>
|
||||||
@ -23,6 +24,8 @@
|
|||||||
<td><a class="first last reference external" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a></td></tr>
|
<td><a class="first last reference external" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a></td></tr>
|
||||||
<tr><th class="docinfo-name">Organization:</th>
|
<tr><th class="docinfo-name">Organization:</th>
|
||||||
<td><a class="first last reference external" href="http://www.boost-consulting.com">Boost Consulting</a></td></tr>
|
<td><a class="first last reference external" href="http://www.boost-consulting.com">Boost Consulting</a></td></tr>
|
||||||
|
<tr><th class="docinfo-name">Date:</th>
|
||||||
|
<td>2006-09-11</td></tr>
|
||||||
<tr><th class="docinfo-name">Copyright:</th>
|
<tr><th class="docinfo-name">Copyright:</th>
|
||||||
<td>Copyright David Abrahams 2004.</td></tr>
|
<td>Copyright David Abrahams 2004.</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -34,7 +37,7 @@
|
|||||||
<col class="field-name" />
|
<col class="field-name" />
|
||||||
<col class="field-body" />
|
<col class="field-body" />
|
||||||
<tbody valign="top">
|
<tbody valign="top">
|
||||||
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">Header <tt class="docutils literal"><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
|
the ability to access an iterator's associated types using
|
||||||
MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</td>
|
MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -43,15 +46,15 @@ MPL-compatible <a class="reference external" href="../../mpl/doc/index.html#meta
|
|||||||
<div class="section" id="overview">
|
<div class="section" id="overview">
|
||||||
<h1>Overview</h1>
|
<h1>Overview</h1>
|
||||||
<p><tt class="docutils literal"><span class="pre">std::iterator_traits</span></tt> provides access to five associated types
|
<p><tt class="docutils literal"><span class="pre">std::iterator_traits</span></tt> provides access to five associated types
|
||||||
of any iterator: its <tt class="docutils literal">value_type</tt>, <tt class="docutils literal">reference</tt>, <tt class="docutils literal">pointer</tt>,
|
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">iterator_category</tt>, and <tt class="docutils literal">difference_type</tt>. Unfortunately,
|
<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
|
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>
|
provides access to these types using a standard <a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="summary">
|
<div class="section" id="summary">
|
||||||
<h1>Summary</h1>
|
<h1>Summary</h1>
|
||||||
<p>Header <tt class="docutils literal"><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">
|
<pre class="literal-block">
|
||||||
template <class Iterator>
|
template <class Iterator>
|
||||||
struct iterator_value
|
struct iterator_value
|
||||||
@ -95,6 +98,21 @@ struct iterator_category
|
|||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="section" id="broken-compiler-notes">
|
||||||
|
<h1>Broken Compiler Notes</h1>
|
||||||
|
<p>Because of workarounds in Boost, you may find that these
|
||||||
|
<a class="reference external" href="../../mpl/doc/index.html#metafunctions">metafunctions</a> actually work better than the facilities provided by
|
||||||
|
your compiler's standard library.</p>
|
||||||
|
<p>On compilers that don't support partial specialization, such as
|
||||||
|
Microsoft Visual C++ 6.0 or 7.0, you may need to manually invoke
|
||||||
|
<a class="reference external" href="../../type_traits/index.html#transformations">BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION</a> on the
|
||||||
|
<tt class="docutils literal"><span class="pre">value_type</span></tt> of pointers that are passed to these metafunctions.</p>
|
||||||
|
<p>Because of bugs in the implementation of GCC-2.9x, the name of
|
||||||
|
<tt class="docutils literal"><span class="pre">iterator_category</span></tt> is changed to <tt class="docutils literal"><span class="pre">iterator_category_</span></tt> on that
|
||||||
|
compiler. A macro, <tt class="docutils literal"><span class="pre">BOOST_ITERATOR_CATEGORY</span></tt>, that expands to
|
||||||
|
either <tt class="docutils literal"><span class="pre">iterator_category</span></tt> or <tt class="docutils literal"><span class="pre">iterator_category_</span></tt>, as
|
||||||
|
appropriate to the platform, is provided for portability.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<hr class="footer" />
|
<hr class="footer" />
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
:Author: David Abrahams
|
:Author: David Abrahams
|
||||||
:Contact: dave@boost-consulting.com
|
:Contact: dave@boost-consulting.com
|
||||||
:organization: `Boost Consulting`_
|
:organization: `Boost Consulting`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams 2004.
|
:copyright: Copyright David Abrahams 2004.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
@ -74,3 +75,24 @@ Header ``<boost/iterator/iterator_traits.hpp>``::
|
|||||||
detail::iterator_traits<Iterator>::iterator_category
|
detail::iterator_traits<Iterator>::iterator_category
|
||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Broken Compiler Notes
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Because of workarounds in Boost, you may find that these
|
||||||
|
metafunctions_ actually work better than the facilities provided by
|
||||||
|
your compiler's standard library.
|
||||||
|
|
||||||
|
On compilers that don't support partial specialization, such as
|
||||||
|
Microsoft Visual C++ 6.0 or 7.0, you may need to manually invoke
|
||||||
|
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION_ on the
|
||||||
|
``value_type`` of pointers that are passed to these metafunctions.
|
||||||
|
|
||||||
|
Because of bugs in the implementation of GCC-2.9x, the name of
|
||||||
|
``iterator_category`` is changed to ``iterator_category_`` on that
|
||||||
|
compiler. A macro, ``BOOST_ITERATOR_CATEGORY``, that expands to
|
||||||
|
either ``iterator_category`` or ``iterator_category_``, as
|
||||||
|
appropriate to the platform, is provided for portability.
|
||||||
|
|
||||||
|
.. _BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION: ../../type_traits/index.html#transformations
|
||||||
|
|
||||||
|
@ -27,10 +27,10 @@
|
|||||||
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
|
Lab</a>, <a class="last reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
|
||||||
<tr><th class="docinfo-name">Date:</th>
|
<tr><th class="docinfo-name">Date:</th>
|
||||||
<td>2006-09-11</td></tr>
|
<td>2006-09-11</td></tr>
|
||||||
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference external" href="http://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
|
accepted for Technical Report 1 by the C++ standard
|
||||||
committee's library working group. This proposal is a
|
committee's library working group. This proposal is a
|
||||||
revision of paper <a class="reference external" href="http://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>
|
||||||
<tr><th class="docinfo-name">Copyright:</th>
|
<tr><th class="docinfo-name">Copyright:</th>
|
||||||
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt
|
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt
|
||||||
@ -127,12 +127,12 @@ requirements in the iterator categories.</p>
|
|||||||
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt></td>
|
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td>Forward Iterator</td>
|
<tr><td>Forward Iterator</td>
|
||||||
<td><tt class="docutils literal"><span class="pre">*i</span></tt> is <tt class="docutils literal"><span class="pre">T&</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>
|
is resolved)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td>Random Access Iterator</td>
|
<tr><td>Random Access Iterator</td>
|
||||||
<td><tt class="docutils literal"><span class="pre">i[n]</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt> (also <tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt>
|
<td><tt class="docutils literal"><span class="pre">i[n]</span></tt> is convertible to <tt class="docutils literal"><span class="pre">T</span></tt> (also <tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt>
|
||||||
is required for mutable iterators once <a class="reference external" href="http://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>
|
is resolved)</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -141,7 +141,7 @@ is resolved)</td>
|
|||||||
single hierarchy, many useful iterators can not be appropriately
|
single hierarchy, many useful iterators can not be appropriately
|
||||||
categorized. For example, <tt class="docutils literal"><span class="pre">vector<bool>::iterator</span></tt> is almost a
|
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
|
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
|
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
|
requirements of input iterator and output iterator. This is so
|
||||||
nonintuitive that the C++ standard contradicts itself on this point.
|
nonintuitive that the C++ standard contradicts itself on this point.
|
||||||
@ -344,7 +344,7 @@ approach for specifying <tt class="docutils literal"><span class="pre">operator[
|
|||||||
direction would mean that an iterator satisfying the old Random Access
|
direction would mean that an iterator satisfying the old Random Access
|
||||||
Iterator requirements would not necessarily be a model of Readable or
|
Iterator requirements would not necessarily be a model of Readable or
|
||||||
Writable Lvalue Iterator. Instead we have chosen a design that
|
Writable Lvalue Iterator. Instead we have chosen a design that
|
||||||
matches the preferred resolution of <a class="reference external" href="http://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>
|
only required to return something convertible to the <tt class="docutils literal"><span class="pre">value_type</span></tt>
|
||||||
(for a Readable Iterator), and is required to support assignment
|
(for a Readable Iterator), and is required to support assignment
|
||||||
<tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt> (for a Writable Iterator).</p>
|
<tt class="docutils literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt> (for a Writable Iterator).</p>
|
||||||
@ -976,7 +976,7 @@ struct random_access_traversal_tag : bidirectional_traversal_tag { };
|
|||||||
<div class="section" id="addition-to-lib-iterator-traits">
|
<div class="section" id="addition-to-lib-iterator-traits">
|
||||||
<h2><a class="toc-backref" href="#id23">Addition to [lib.iterator.traits]</a></h2>
|
<h2><a class="toc-backref" href="#id23">Addition to [lib.iterator.traits]</a></h2>
|
||||||
<p>The <tt class="docutils literal"><span class="pre">is_readable_iterator</span></tt> class
|
<p>The <tt class="docutils literal"><span class="pre">is_readable_iterator</span></tt> class
|
||||||
template satisfies the <a class="reference external" href="http://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>
|
<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
|
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>
|
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>
|
||||||
<div class="section" id="footnotes">
|
<div class="section" id="footnotes">
|
||||||
<h1><a class="toc-backref" href="#id24">Footnotes</a></h1>
|
<h1><a class="toc-backref" href="#id24">Footnotes</a></h1>
|
||||||
<p>The UnaryTypeTrait concept is defined in <a class="reference external" href="http://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
|
considering adding the requirement that specializations are derived
|
||||||
from their nested <tt class="docutils literal"><span class="pre">::type</span></tt>.</p>
|
from their nested <tt class="docutils literal"><span class="pre">::type</span></tt>.</p>
|
||||||
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
|
||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, `Zephyr Associates, Inc.`_
|
Lab`_, `Zephyr Associates, Inc.`_
|
||||||
|
:date: $Date$
|
||||||
|
|
||||||
:Number: This is a revised version of n1550_\ =03-0133, which was
|
:Number: This is a revised version of n1550_\ =03-0133, which was
|
||||||
accepted for Technical Report 1 by the C++ standard
|
accepted for Technical Report 1 by the C++ standard
|
||||||
@ -37,10 +38,10 @@
|
|||||||
|
|
||||||
.. contents:: Table of Contents
|
.. contents:: Table of Contents
|
||||||
|
|
||||||
.. _n1297: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1297.html
|
.. _n1297: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html
|
||||||
.. _n1477: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1477.html
|
.. _n1477: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1477.html
|
||||||
.. _n1531: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1531.html
|
.. _n1531: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1531.html
|
||||||
.. _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
|
||||||
|
|
||||||
============
|
============
|
||||||
Motivation
|
Motivation
|
||||||
@ -75,8 +76,8 @@ requirements in the iterator categories.
|
|||||||
| |is resolved) |
|
| |is resolved) |
|
||||||
+------------------------+-----------------------------------------------------+
|
+------------------------+-----------------------------------------------------+
|
||||||
|
|
||||||
.. _issue 200: http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#200
|
.. _issue 200: http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200
|
||||||
.. _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
|
||||||
|
|
||||||
|
|
||||||
Because iterator traversal and value access are mixed together in a
|
Because iterator traversal and value access are mixed together in a
|
||||||
@ -90,7 +91,7 @@ nonintuitive that the C++ standard contradicts itself on this point.
|
|||||||
In paragraph 23.2.4/1 it says that a ``vector`` is a sequence that
|
In paragraph 23.2.4/1 it says that a ``vector`` is a sequence that
|
||||||
supports random access iterators.
|
supports random access iterators.
|
||||||
|
|
||||||
.. _issue 96: http://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
|
Another difficult-to-categorize iterator is the transform iterator, an
|
||||||
adaptor which applies a unary function object to the dereferenced
|
adaptor which applies a unary function object to the dereferenced
|
||||||
@ -790,7 +791,7 @@ The UnaryTypeTrait concept is defined in n1519_; the LWG is
|
|||||||
considering adding the requirement that specializations are derived
|
considering adding the requirement that specializations are derived
|
||||||
from their nested ``::type``.
|
from their nested ``::type``.
|
||||||
|
|
||||||
.. _n1519: http://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
|
LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_
|
Lab`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003.
|
:copyright: Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
:Author: David Abrahams
|
:Author: David Abrahams
|
||||||
:Contact: dave@boost-consulting.com
|
:Contact: dave@boost-consulting.com
|
||||||
:organization: `Boost Consulting`_
|
:organization: `Boost Consulting`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams 2004.
|
:copyright: Copyright David Abrahams 2004.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:adaptor Iterator Adaptor]
|
[section:adaptor Iterator Adaptor]
|
||||||
|
|
||||||
The `iterator_adaptor` class template adapts some `Base` [#base]_
|
The `iterator_adaptor` class template adapts some `Base` [#base]_
|
||||||
@ -46,7 +47,7 @@ that assumption.
|
|||||||
, class Reference = use_default
|
, class Reference = use_default
|
||||||
, class Difference = use_default
|
, class Difference = use_default
|
||||||
>
|
>
|
||||||
class iterator_adaptor
|
class iterator_adaptor
|
||||||
: public iterator_facade<Derived, *V'*, *C'*, *R'*, *D'*> // see details
|
: public iterator_facade<Derived, *V'*, *C'*, *R'*, *D'*> // see details
|
||||||
{
|
{
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
@ -59,21 +60,21 @@ that assumption.
|
|||||||
typedef iterator_adaptor iterator_adaptor\_;
|
typedef iterator_adaptor iterator_adaptor\_;
|
||||||
Base const& base_reference() const;
|
Base const& base_reference() const;
|
||||||
Base& base_reference();
|
Base& base_reference();
|
||||||
private: // Core iterator interface for iterator_facade.
|
private: // Core iterator interface for iterator_facade.
|
||||||
typename iterator_adaptor::reference dereference() const;
|
typename iterator_adaptor::reference dereference() const;
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||||
>
|
>
|
||||||
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
|
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
|
||||||
|
|
||||||
void advance(typename iterator_adaptor::difference_type n);
|
void advance(typename iterator_adaptor::difference_type n);
|
||||||
void increment();
|
void increment();
|
||||||
void decrement();
|
void decrement();
|
||||||
|
|
||||||
template <
|
template <
|
||||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||||
>
|
>
|
||||||
typename iterator_adaptor::difference_type distance_to(
|
typename iterator_adaptor::difference_type distance_to(
|
||||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
|
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
|
||||||
|
|
||||||
@ -131,8 +132,8 @@ above are defined as follows:
|
|||||||
|
|
||||||
iterator_adaptor();
|
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
|
[*Returns:] An instance of `iterator_adaptor` with
|
||||||
`m_iterator` default constructed.
|
`m_iterator` default constructed.
|
||||||
|
|
||||||
|
|
||||||
@ -166,7 +167,7 @@ above are defined as follows:
|
|||||||
|
|
||||||
template <
|
template <
|
||||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||||
>
|
>
|
||||||
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
|
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
|
||||||
|
|
||||||
[*Returns:] `m_iterator == x.base()`
|
[*Returns:] `m_iterator == x.base()`
|
||||||
@ -187,7 +188,7 @@ above are defined as follows:
|
|||||||
|
|
||||||
template <
|
template <
|
||||||
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
class OtherDerived, class OtherIterator, class V, class C, class R, class D
|
||||||
>
|
>
|
||||||
typename iterator_adaptor::difference_type distance_to(
|
typename iterator_adaptor::difference_type distance_to(
|
||||||
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
|
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
|
||||||
|
|
||||||
@ -205,7 +206,7 @@ we're going to pick up right where it left off.
|
|||||||
.. |fac_tut| replace:: `iterator_facade` tutorial
|
.. |fac_tut| replace:: `iterator_facade` tutorial
|
||||||
.. _fac_tut: iterator_facade.html#tutorial-example
|
.. _fac_tut: iterator_facade.html#tutorial-example
|
||||||
|
|
||||||
[blurb [*`node_base*` really *is* an iterator][br][br]
|
[blurb [*`node_base*` really *is* an iterator]\n\n
|
||||||
It's not really a very interesting iterator, since `node_base`
|
It's not really a very interesting iterator, since `node_base`
|
||||||
is an abstract class: a pointer to a `node_base` just points
|
is an abstract class: a pointer to a `node_base` just points
|
||||||
at some base subobject of an instance of some other class, and
|
at some base subobject of an instance of some other class, and
|
||||||
@ -228,7 +229,7 @@ operations on the underlying pointer, via the `node_iterator`\ 's
|
|||||||
|dereference_and_equal|_). The only real behavioral difference
|
|dereference_and_equal|_). The only real behavioral difference
|
||||||
between `node_base*` and `node_iterator` can be observed when
|
between `node_base*` and `node_iterator` can be observed when
|
||||||
they are incremented: `node_iterator` follows the
|
they are incremented: `node_iterator` follows the
|
||||||
`m_next` pointer, while `node_base*` just applies an address offset.
|
`m_next` pointer, while `node_base*` just applies an address offset.
|
||||||
|
|
||||||
.. |dereference_and_equal| replace:: `dereference` and `equal` member functions
|
.. |dereference_and_equal| replace:: `dereference` and `equal` member functions
|
||||||
.. _dereference_and_equal: iterator_facade.html#implementing-the-core-operations
|
.. _dereference_and_equal: iterator_facade.html#implementing-the-core-operations
|
||||||
@ -286,8 +287,8 @@ this technique is known not to work with Borland C++ 5.6.4 and
|
|||||||
Metrowerks CodeWarrior versions prior to 9.0]
|
Metrowerks CodeWarrior versions prior to 9.0]
|
||||||
|
|
||||||
You can see an example program that exercises this version of the
|
You can see an example program that exercises this version of the
|
||||||
node iterators
|
node iterators
|
||||||
[example_link node_iterator3.cpp..here].
|
[@../example/node_iterator3.cpp `here`].
|
||||||
|
|
||||||
|
|
||||||
In the case of `node_iter`, it's not very compelling to pass
|
In the case of `node_iter`, it's not very compelling to pass
|
||||||
@ -305,7 +306,7 @@ types to its `Base` saves the implementor of
|
|||||||
|
|
||||||
std::iterator_traits<Iterator>::*some-associated-type*
|
std::iterator_traits<Iterator>::*some-associated-type*
|
||||||
|
|
||||||
at least four times.
|
at least four times.
|
||||||
|
|
||||||
We urge you to review the documentation and implementations of
|
We urge you to review the documentation and implementations of
|
||||||
|reverse_iterator|_ and the other Boost `specialized iterator
|
|reverse_iterator|_ and the other Boost `specialized iterator
|
||||||
@ -329,4 +330,4 @@ __ index.html#specialized-adaptors
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -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]
|
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:archetypes Iterator Archetypes]
|
[section:archetypes Iterator Archetypes]
|
||||||
|
|
||||||
The `iterator_archetype` class constructs a minimal implementation of
|
The `iterator_archetype` class constructs a minimal implementation of
|
||||||
@ -40,23 +41,23 @@ The access category types provided correspond to the following
|
|||||||
standard iterator access concept combinations:
|
standard iterator access concept combinations:
|
||||||
|
|
||||||
readable_iterator_t :=
|
readable_iterator_t :=
|
||||||
|
|
||||||
Readable Iterator
|
Readable Iterator
|
||||||
|
|
||||||
writable_iterator_t :=
|
writable_iterator_t :=
|
||||||
|
|
||||||
Writeable Iterator
|
Writeable Iterator
|
||||||
|
|
||||||
readable_writable_iterator_t :=
|
readable_writable_iterator_t :=
|
||||||
|
|
||||||
Readable Iterator & Writeable Iterator & Swappable Iterator
|
Readable Iterator & Writeable Iterator & Swappable Iterator
|
||||||
|
|
||||||
readable_lvalue_iterator_t :=
|
readable_lvalue_iterator_t :=
|
||||||
|
|
||||||
Readable Iterator & Lvalue Iterator
|
Readable Iterator & Lvalue Iterator
|
||||||
|
|
||||||
writeable_lvalue_iterator_t :=
|
writeable_lvalue_iterator_t :=
|
||||||
|
|
||||||
Readable Iterator & Writeable Iterator & Swappable Iterator & Lvalue Iterator
|
Readable Iterator & Writeable Iterator & Swappable Iterator & Lvalue Iterator
|
||||||
|
|
||||||
[h3 Traits]
|
[h3 Traits]
|
||||||
@ -65,25 +66,25 @@ The nested trait types are defined as follows:
|
|||||||
|
|
||||||
|
|
||||||
if (AccessCategory == readable_iterator_t)
|
if (AccessCategory == readable_iterator_t)
|
||||||
|
|
||||||
value_type = Value
|
value_type = Value
|
||||||
reference = Value
|
reference = Value
|
||||||
pointer = Value*
|
pointer = Value*
|
||||||
|
|
||||||
else if (AccessCategory == writable_iterator_t)
|
else if (AccessCategory == writable_iterator_t)
|
||||||
|
|
||||||
value_type = void
|
value_type = void
|
||||||
reference = void
|
reference = void
|
||||||
pointer = void
|
pointer = void
|
||||||
|
|
||||||
else if (AccessCategory == readable_writable_iterator_t)
|
else if (AccessCategory == readable_writable_iterator_t)
|
||||||
|
|
||||||
value_type = Value
|
value_type = Value
|
||||||
|
|
||||||
reference :=
|
reference :=
|
||||||
|
|
||||||
A type X that is convertible to Value for which the following
|
A type X that is convertible to Value for which the following
|
||||||
expression is valid. Given an object x of type X and v of type
|
expression is valid. Given an object x of type X and v of type
|
||||||
Value.
|
Value.
|
||||||
|
|
||||||
x = v
|
x = v
|
||||||
@ -91,13 +92,13 @@ The nested trait types are defined as follows:
|
|||||||
pointer = Value*
|
pointer = Value*
|
||||||
|
|
||||||
else if (AccessCategory == readable_lvalue_iterator_t)
|
else if (AccessCategory == readable_lvalue_iterator_t)
|
||||||
|
|
||||||
value_type = Value
|
value_type = Value
|
||||||
reference = Value const&
|
reference = Value const&
|
||||||
pointer = Value const*
|
pointer = Value const*
|
||||||
|
|
||||||
else if (AccessCategory == writable_lvalue_iterator_t)
|
else if (AccessCategory == writable_lvalue_iterator_t)
|
||||||
|
|
||||||
value_type = Value
|
value_type = Value
|
||||||
reference = Value&
|
reference = Value&
|
||||||
pointer = Value*
|
pointer = Value*
|
||||||
@ -107,11 +108,11 @@ The nested trait types are defined as follows:
|
|||||||
difference_type := ptrdiff_t
|
difference_type := ptrdiff_t
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
difference_type := unspecified type
|
difference_type := unspecified type
|
||||||
|
|
||||||
|
|
||||||
iterator_category :=
|
iterator_category :=
|
||||||
|
|
||||||
A type X satisfying the following two constraints:
|
A type X satisfying the following two constraints:
|
||||||
|
|
||||||
@ -155,4 +156,5 @@ the iterator concept specified by `AccessCategory` and
|
|||||||
arguments. `iterator_archetype` does not model any other access
|
arguments. `iterator_archetype` does not model any other access
|
||||||
concepts or any more derived traversal concepts.
|
concepts or any more derived traversal concepts.
|
||||||
|
|
||||||
[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 to report better error messages when a user instantiates the
|
||||||
template with a type that does not meet the requirements of the
|
template with a type that does not meet the requirements of the
|
||||||
template. For an introduction to using concept checking classes, see
|
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]
|
[h2 `iterator_concepts.hpp` Synopsis]
|
||||||
|
|
||||||
@ -51,4 +51,4 @@ the documentation for the _concept_check_ library.
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
[section:concepts Iterator Concepts]
|
[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
|
A class or built-in type `X` models the *Readable Iterator* concept
|
||||||
for value type `T` if, in addition to `X` being Assignable and
|
for value type `T` if, in addition to `X` being Assignable and
|
||||||
@ -31,18 +32,17 @@ type `T`.
|
|||||||
[`U&`]
|
[`U&`]
|
||||||
[pre: `(*a).m` is well-defined. Equivalent to `(*a).m`.]
|
[pre: `(*a).m` is well-defined. Equivalent to `(*a).m`.]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
[endsect]
|
[h2 Writable Iterator Concept ]
|
||||||
|
|
||||||
[section:writable Writable Iterator Concept]
|
|
||||||
|
|
||||||
A class or built-in type `X` models the *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
|
if, in addition to `X` being Copy Constructible, the following
|
||||||
expressions are valid and respect the stated semantics. Writable
|
expressions are valid and respect the stated semantics. Writable
|
||||||
Iterators have an associated *set of value types*.
|
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]
|
[Expression]
|
||||||
[Return Type]
|
[Return Type]
|
||||||
@ -55,15 +55,13 @@ Iterators have an associated *set of value types*.
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
[endsect]
|
[h2 Swappable Iterator Concept]
|
||||||
|
|
||||||
[section:swappable Swappable Iterator Concept]
|
|
||||||
|
|
||||||
A class or built-in type `X` models the *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
|
if, in addition to `X` being Copy Constructible, the following
|
||||||
expressions are valid and respect the stated semantics.
|
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]
|
[Expression]
|
||||||
[Return Type]
|
[Return Type]
|
||||||
@ -79,9 +77,7 @@ expressions are valid and respect the stated semantics.
|
|||||||
[blurb *Note:* An iterator that is a model of the *Readable* and *Writable Iterator* concepts
|
[blurb *Note:* An iterator that is a model of the *Readable* and *Writable Iterator* concepts
|
||||||
is also a model of *Swappable Iterator*. *--end note*]
|
is also a model of *Swappable Iterator*. *--end note*]
|
||||||
|
|
||||||
[endsect]
|
[h2 Lvalue Iterator Concept]
|
||||||
|
|
||||||
[section:lvalue Lvalue Iterator Concept]
|
|
||||||
|
|
||||||
The *Lvalue Iterator* concept adds the requirement that the return
|
The *Lvalue Iterator* concept adds the requirement that the return
|
||||||
type of `operator*` type be a reference to the value type of the
|
type of `operator*` type be a reference to the value type of the
|
||||||
@ -105,17 +101,17 @@ iterator.
|
|||||||
|
|
||||||
[endsect]
|
[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*
|
A class or built-in type `X` models the *Incrementable Iterator*
|
||||||
concept if, in addition to `X` being Assignable and Copy
|
concept if, in addition to `X` being Assignable and Copy
|
||||||
Constructible, the following expressions are valid and respect the
|
Constructible, the following expressions are valid and respect the
|
||||||
stated semantics.
|
stated semantics.
|
||||||
|
|
||||||
|
|
||||||
[table Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible)
|
[table Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible)
|
||||||
[
|
[
|
||||||
[Expression ]
|
[Expression ]
|
||||||
@ -133,7 +129,7 @@ stated semantics.
|
|||||||
[``
|
[``
|
||||||
{
|
{
|
||||||
X tmp = r;
|
X tmp = r;
|
||||||
++r;
|
++r;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
``]
|
``]
|
||||||
@ -145,9 +141,7 @@ stated semantics.
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
[endsect]
|
[h2 Single Pass Iterator Concept]
|
||||||
|
|
||||||
[section:single_pass Single Pass Iterator Concept]
|
|
||||||
|
|
||||||
A class or built-in type `X` models the *Single Pass Iterator*
|
A class or built-in type `X` models the *Single Pass Iterator*
|
||||||
concept if the following expressions are valid and respect the stated
|
concept if the following expressions are valid and respect the stated
|
||||||
@ -162,7 +156,7 @@ semantics.
|
|||||||
[
|
[
|
||||||
[`++r`]
|
[`++r`]
|
||||||
[`X&`]
|
[`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`]
|
[`a == b`]
|
||||||
@ -174,11 +168,6 @@ semantics.
|
|||||||
[convertible to `bool`]
|
[convertible to `bool`]
|
||||||
[`!(a == b)`]
|
[`!(a == b)`]
|
||||||
]
|
]
|
||||||
[
|
|
||||||
[`iterator_traits<X>::difference_type`]
|
|
||||||
[A signed integral type representing the distance between iterators]
|
|
||||||
[]
|
|
||||||
]
|
|
||||||
[
|
[
|
||||||
[`iterator_traversal<X>::type`]
|
[`iterator_traversal<X>::type`]
|
||||||
[Convertible to`single_pass_traversal_tag`]
|
[Convertible to`single_pass_traversal_tag`]
|
||||||
@ -186,9 +175,8 @@ semantics.
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[section:forward Forward Traversal Concept]
|
[h2 Forward Traversal Concept]
|
||||||
|
|
||||||
A class or built-in type `X` models the *Forward Traversal*
|
A class or built-in type `X` models the *Forward Traversal*
|
||||||
concept if, in addition to `X` meeting the requirements of Default
|
concept if, in addition to `X` meeting the requirements of Default
|
||||||
@ -211,6 +199,11 @@ valid and respect the stated semantics.
|
|||||||
[`X&`]
|
[`X&`]
|
||||||
[`r == s` and `r` is dereferenceable implies `++r == ++s.`]
|
[`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`]
|
[`iterator_traversal<X>::type`]
|
||||||
[Convertible to `forward_traversal_tag`]
|
[Convertible to `forward_traversal_tag`]
|
||||||
@ -218,9 +211,7 @@ valid and respect the stated semantics.
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
[endsect]
|
[h2 Bidirectional Traversal Concept]
|
||||||
|
|
||||||
[section:bidirectional Bidirectional Traversal Concept]
|
|
||||||
|
|
||||||
A class or built-in type `X` models the *Bidirectional Traversal*
|
A class or built-in type `X` models the *Bidirectional Traversal*
|
||||||
concept if, in addition to `X` meeting the requirements of Forward
|
concept if, in addition to `X` meeting the requirements of Forward
|
||||||
@ -232,11 +223,11 @@ the stated semantics.
|
|||||||
[Expression]
|
[Expression]
|
||||||
[Return Type]
|
[Return Type]
|
||||||
[Assertion/Semantics/Pre-/Post-condition]
|
[Assertion/Semantics/Pre-/Post-condition]
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
[`--r`]
|
[`--r`]
|
||||||
[`X&`]
|
[`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--`]
|
[`r--`]
|
||||||
@ -256,9 +247,7 @@ the stated semantics.
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
[endsect]
|
[h2 Random Access Traversal Concept]
|
||||||
|
|
||||||
[section:random_access Random Access Traversal Concept]
|
|
||||||
|
|
||||||
A class or built-in type `X` models the *Random Access Traversal*
|
A class or built-in type `X` models the *Random Access Traversal*
|
||||||
concept if the following expressions are valid and respect the stated
|
concept if the following expressions are valid and respect the stated
|
||||||
@ -266,8 +255,8 @@ semantics. In the table below, `Distance` is
|
|||||||
`iterator_traits<X>::difference_type` and `n` represents a
|
`iterator_traits<X>::difference_type` and `n` represents a
|
||||||
constant object of type `Distance`.
|
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]
|
[Expression]
|
||||||
[Return Type]
|
[Return Type]
|
||||||
[Operational Semantics]
|
[Operational Semantics]
|
||||||
@ -277,10 +266,10 @@ constant object of type `Distance`.
|
|||||||
[`r += n`]
|
[`r += n`]
|
||||||
[ `X&`]
|
[ `X&`]
|
||||||
[``
|
[``
|
||||||
{
|
{
|
||||||
Distance m = n;
|
Distance m = n;
|
||||||
if (m >= 0)
|
if (m >= 0)
|
||||||
while (m--)
|
while (m--)
|
||||||
++r;
|
++r;
|
||||||
else
|
else
|
||||||
while (m++)
|
while (m++)
|
||||||
@ -290,18 +279,18 @@ constant object of type `Distance`.
|
|||||||
``]
|
``]
|
||||||
[ ]
|
[ ]
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
[`a + n`, `n + a`]
|
[`a + n`, `n + a`]
|
||||||
[`X`]
|
[`X`]
|
||||||
[``
|
[``
|
||||||
{
|
{
|
||||||
X tmp = a;
|
X tmp = a;
|
||||||
return tmp+= n;
|
return tmp+= n;
|
||||||
}
|
}
|
||||||
``]
|
``]
|
||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
[`r -= n`]
|
[`r -= n`]
|
||||||
[`X&`]
|
[`X&`]
|
||||||
[`return r += -n`]
|
[`return r += -n`]
|
||||||
@ -311,9 +300,9 @@ constant object of type `Distance`.
|
|||||||
[`a - n`]
|
[`a - n`]
|
||||||
[`X`]
|
[`X`]
|
||||||
[``
|
[``
|
||||||
{
|
{
|
||||||
X tmp = a;
|
X tmp = a;
|
||||||
return tmp-= n;
|
return tmp-= n;
|
||||||
}
|
}
|
||||||
``]
|
``]
|
||||||
[]
|
[]
|
||||||
@ -325,13 +314,13 @@ constant object of type `Distance`.
|
|||||||
[pre: there exists a value `n` of `Distance` such that `a + n == b`. `b == a + (b - a)`.]
|
[pre: there exists a value `n` of `Distance` such that `a + n == b`. `b == a + (b - a)`.]
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
[`a[n]`]
|
[`a\[n\]`]
|
||||||
[convertible to T]
|
[convertible to T]
|
||||||
[`*(a + n)`]
|
[`*(a + n)`]
|
||||||
[pre: a is a *Readable Iterator*]
|
[pre: a is a *Readable Iterator*]
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
[`a[n] = v`]
|
[`a\[n\] = v`]
|
||||||
[convertible to T]
|
[convertible to T]
|
||||||
[`*(a + n) = v`]
|
[`*(a + n) = v`]
|
||||||
[pre: a is a *Writable iterator*]
|
[pre: a is a *Writable iterator*]
|
||||||
@ -370,6 +359,4 @@ constant object of type `Distance`.
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[endsect]
|
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:counting Counting Iterator]
|
[section:counting Counting Iterator]
|
||||||
|
|
||||||
A `counting_iterator` adapts an object by adding an `operator*` that
|
A `counting_iterator` adapts an object by adding an `operator*` that
|
||||||
@ -17,30 +18,28 @@ into the first array via indirection through the second array.
|
|||||||
std::vector<int> numbers;
|
std::vector<int> numbers;
|
||||||
typedef std::vector<int>::iterator n_iter;
|
typedef std::vector<int>::iterator n_iter;
|
||||||
std::copy(boost::counting_iterator<int>(0),
|
std::copy(boost::counting_iterator<int>(0),
|
||||||
boost::counting_iterator<int>(N),
|
boost::counting_iterator<int>(N),
|
||||||
std::back_inserter(numbers));
|
std::back_inserter(numbers));
|
||||||
|
|
||||||
std::vector<std::vector<int>::iterator> pointers;
|
std::vector<std::vector<int>::iterator> pointers;
|
||||||
std::copy(boost::make_counting_iterator(numbers.begin()),
|
std::copy(boost::make_counting_iterator(numbers.begin()),
|
||||||
boost::make_counting_iterator(numbers.end()),
|
boost::make_counting_iterator(numbers.end()),
|
||||||
std::back_inserter(pointers));
|
std::back_inserter(pointers));
|
||||||
|
|
||||||
std::cout << "indirectly printing out the numbers from 0 to "
|
std::cout << "indirectly printing out the numbers from 0 to "
|
||||||
<< N << std::endl;
|
<< N << std::endl;
|
||||||
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
||||||
boost::make_indirect_iterator(pointers.end()),
|
boost::make_indirect_iterator(pointers.end()),
|
||||||
std::ostream_iterator<int>(std::cout, " "));
|
std::ostream_iterator<int>(std::cout, " "));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
||||||
The output is:
|
The output is:
|
||||||
|
|
||||||
[pre
|
indirectly printing out the numbers from 0 to 7
|
||||||
indirectly printing out the numbers from 0 to 7
|
0 1 2 3 4 5 6
|
||||||
0 1 2 3 4 5 6
|
|
||||||
]
|
|
||||||
|
|
||||||
The source code for this example can be found [example_link counting_iterator_example.cpp..here].
|
The source code for this example can be found [@../example/counting_iterator_example.cpp here].
|
||||||
|
|
||||||
[h2 Reference]
|
[h2 Reference]
|
||||||
|
|
||||||
@ -87,9 +86,9 @@ algorithm:
|
|||||||
random_access_traversal_tag, Incrementable, const Incrementable&)
|
random_access_traversal_tag, Incrementable, const Incrementable&)
|
||||||
else
|
else
|
||||||
return |iterator-category|_\ (
|
return |iterator-category|_\ (
|
||||||
iterator_traversal<Incrementable>::type,
|
iterator_traversal<Incrementable>::type,
|
||||||
Incrementable, const Incrementable&)
|
Incrementable, const Incrementable&)
|
||||||
|
|
||||||
[blurb *Note:* implementers are encouraged to provide an implementation of
|
[blurb *Note:* implementers are encouraged to provide an implementation of
|
||||||
`operator-` and a `difference_type` that avoids overflows in
|
`operator-` and a `difference_type` that avoids overflows in
|
||||||
the cases where `std::numeric_limits<Incrementable>::is_specialized`
|
the cases where `std::numeric_limits<Incrementable>::is_specialized`
|
||||||
@ -153,7 +152,7 @@ operations.
|
|||||||
|
|
||||||
counting_iterator();
|
counting_iterator();
|
||||||
|
|
||||||
[*Requires: ] `Incrementable` is Default Constructible.[br]
|
[*Requires: ] `Incrementable` is Default Constructible.\n
|
||||||
[*Effects: ] Default construct the member `m_inc`.
|
[*Effects: ] Default construct the member `m_inc`.
|
||||||
|
|
||||||
|
|
||||||
@ -175,14 +174,14 @@ operations.
|
|||||||
|
|
||||||
counting_iterator& operator++();
|
counting_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `++m_inc`[br]
|
[*Effects: ] `++m_inc`\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
counting_iterator& operator--();
|
counting_iterator& operator--();
|
||||||
|
|
||||||
[*Effects: ] `--m_inc`[br]
|
[*Effects: ] `--m_inc`\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
Incrementable const& base() const;
|
Incrementable const& base() const;
|
||||||
@ -190,4 +189,4 @@ operations.
|
|||||||
[*Returns: ] `m_inc`
|
[*Returns: ] `m_inc`
|
||||||
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:facade Iterator Facade]
|
[section:facade Iterator Facade]
|
||||||
|
|
||||||
While the iterator interface is rich, there is a core subset of the
|
While the iterator interface is rich, there is a core subset of the
|
||||||
@ -67,7 +68,6 @@ requirements.
|
|||||||
[
|
[
|
||||||
[`i.dereference()`]
|
[`i.dereference()`]
|
||||||
[Access the value referred to]
|
[Access the value referred to]
|
||||||
]
|
|
||||||
[
|
[
|
||||||
[`i.equal(j)`]
|
[`i.equal(j)`]
|
||||||
[Compare for equality with `j`]
|
[Compare for equality with `j`]
|
||||||
@ -83,7 +83,6 @@ requirements.
|
|||||||
[
|
[
|
||||||
[`i.advance(n)`]
|
[`i.advance(n)`]
|
||||||
[Advance by `n` positions]
|
[Advance by `n` positions]
|
||||||
]
|
|
||||||
[
|
[
|
||||||
[`i.distance_to(j)`]
|
[`i.distance_to(j)`]
|
||||||
[Measure the distance to `j`]
|
[Measure the distance to `j`]
|
||||||
@ -140,7 +139,7 @@ standardize the gateway protocol. Note that even if
|
|||||||
open a safety loophole, as every core member function preserves the
|
open a safety loophole, as every core member function preserves the
|
||||||
invariants of the iterator.
|
invariants of the iterator.
|
||||||
|
|
||||||
[h2 `operator[]`]
|
[h2 `operator\[\]`]
|
||||||
|
|
||||||
The indexing operator for a generalized iterator presents special
|
The indexing operator for a generalized iterator presents special
|
||||||
challenges. A random access iterator's `operator[]` is only
|
challenges. A random access iterator's `operator[]` is only
|
||||||
@ -166,9 +165,9 @@ the implementation of her iterator is free to implement an
|
|||||||
class; it will hide the one supplied by `iterator_facade` from
|
class; it will hide the one supplied by `iterator_facade` from
|
||||||
clients of her iterator.
|
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`:
|
.. _`operator arrow`:
|
||||||
|
|
||||||
@ -288,7 +287,7 @@ The `iterator_category` member of `iterator_facade` is
|
|||||||
|
|
||||||
.. parsed-literal::
|
.. parsed-literal::
|
||||||
|
|
||||||
*iterator-category*\ (CategoryOrTraversal, reference, value_type)
|
*iterator-category*\ (CategoryOrTraversal, value_type, reference)
|
||||||
|
|
||||||
where *iterator-category* is defined as follows:
|
where *iterator-category* is defined as follows:
|
||||||
|
|
||||||
@ -296,10 +295,10 @@ where *iterator-category* is defined as follows:
|
|||||||
|
|
||||||
The `enable_if_interoperable` template used above is for exposition
|
The `enable_if_interoperable` template used above is for exposition
|
||||||
purposes. The member operators should only be in an overload set
|
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
|
meaning that at least one of the types is convertible to the other. The
|
||||||
`enable_if_interoperable` approach uses SFINAE to take the operators
|
`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`
|
The operators should behave *as-if* `enable_if_interoperable`
|
||||||
were defined to be:
|
were defined to be:
|
||||||
|
|
||||||
@ -399,7 +398,7 @@ through member functions of class `iterator_core_access`.
|
|||||||
__ `operator arrow`_
|
__ `operator arrow`_
|
||||||
|
|
||||||
[*Returns:] If `reference` is a reference type, an object of type `pointer` equal to: `&static_cast<Derived const*>(this)->dereference()`
|
[*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),
|
`(*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`.
|
w.m)` for some temporary object `w` of type `value_type`.
|
||||||
|
|
||||||
@ -416,7 +415,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
|
|
||||||
Derived& operator++();
|
Derived& operator++();
|
||||||
|
|
||||||
[*Effects:]
|
[*Effects:]
|
||||||
|
|
||||||
static_cast<Derived*>(this)->increment();
|
static_cast<Derived*>(this)->increment();
|
||||||
return *static_cast<Derived*>(this);
|
return *static_cast<Derived*>(this);
|
||||||
@ -456,7 +455,7 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
Derived& operator-=(difference_type n);
|
Derived& operator-=(difference_type n);
|
||||||
|
|
||||||
[*Effects:]
|
[*Effects:]
|
||||||
|
|
||||||
static_cast<Derived*>(this)->advance(-n);
|
static_cast<Derived*>(this)->advance(-n);
|
||||||
return *static_cast<Derived*>(this);
|
return *static_cast<Derived*>(this);
|
||||||
|
|
||||||
@ -488,16 +487,14 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
||||||
|
|
||||||
[*Returns:]
|
[*Returns:]
|
||||||
|
|
||||||
[pre
|
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
`((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
|
`((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
|
||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
|
`((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
||||||
@ -507,16 +504,14 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
||||||
|
|
||||||
[*Returns:]
|
[*Returns:]
|
||||||
|
|
||||||
[pre
|
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
`!((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
|
`!((Dr1 const&)lhs).equal((Dr2 const&)rhs)`.
|
||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`!((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
|
`!((Dr2 const&)rhs).equal((Dr1 const&)lhs)`.
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
||||||
@ -526,16 +521,14 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
||||||
|
|
||||||
[*Returns:]
|
[*Returns:]
|
||||||
|
|
||||||
[pre
|
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) < 0`.
|
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) < 0`.
|
||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0`.
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
||||||
@ -545,16 +538,14 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
||||||
|
|
||||||
[*Returns:]
|
[*Returns:]
|
||||||
|
|
||||||
[pre
|
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) <= 0`.
|
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) <= 0`.
|
||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0`.
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
||||||
@ -564,16 +555,14 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
||||||
|
|
||||||
[*Returns:]
|
[*Returns:]
|
||||||
|
|
||||||
[pre
|
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) > 0`.
|
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) > 0`.
|
||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0`.
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
template <class Dr1, class V1, class TC1, class R1, class D1,
|
template <class Dr1, class V1, class TC1, class R1, class D1,
|
||||||
@ -583,16 +572,14 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
||||||
|
|
||||||
[*Returns:]
|
[*Returns:]
|
||||||
|
|
||||||
[pre
|
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) >= 0`.
|
`((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) >= 0`.
|
||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0`.
|
||||||
]
|
|
||||||
|
|
||||||
.. _minus:
|
.. _minus:
|
||||||
|
|
||||||
@ -604,33 +591,29 @@ w.m)` for some temporary object `w` of type `value_type`.
|
|||||||
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
|
||||||
|
|
||||||
[*Return Type:]
|
[*Return Type:]
|
||||||
|
|
||||||
[pre
|
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
`difference` shall be
|
`difference` shall be
|
||||||
`iterator_traits<Dr1>::difference_type`.
|
`iterator_traits<Dr1>::difference_type`.
|
||||||
|
|
||||||
Otherwise
|
Otherwise
|
||||||
`difference` shall be `iterator_traits<Dr2>::difference_type`
|
`difference` shall be `iterator_traits<Dr2>::difference_type`
|
||||||
]
|
|
||||||
|
|
||||||
[*Returns:]
|
[*Returns:]
|
||||||
|
|
||||||
[pre
|
|
||||||
if `is_convertible<Dr2,Dr1>::value`
|
if `is_convertible<Dr2,Dr1>::value`
|
||||||
|
|
||||||
then
|
then
|
||||||
`-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs)`.
|
`-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs)`.
|
||||||
|
|
||||||
Otherwise,
|
Otherwise,
|
||||||
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)`.
|
`((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)`.
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[include facade_tutorial.qbk]
|
[include facade_tutorial.qbk]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -1,11 +1,12 @@
|
|||||||
|
|
||||||
[section:facade_tutorial Tutorial]
|
[section:facade_tutorial Tutorial]
|
||||||
|
|
||||||
In this section we'll walk through the implementation of a few
|
In this section we'll walk through the implementation of a few
|
||||||
iterators using `iterator_facade`, based around the simple
|
iterators using `iterator_facade`, based around the simple
|
||||||
example of a linked list of polymorphic objects. This example was
|
example of a linked list of polymorphic objects. This example was
|
||||||
inspired by a
|
inspired by a
|
||||||
[@http://thread.gmane.org/gmane.comp.lib.boost.user/5100 `posting`]
|
[@http://thread.gmane.org/gmane.comp.lib.boost.user/5100 `posting`]
|
||||||
by Keith Macdonald on the
|
by Keith Macdonald on the
|
||||||
[@http://www.boost.org/more/mailing_lists.htm#users `Boost-Users`]
|
[@http://www.boost.org/more/mailing_lists.htm#users `Boost-Users`]
|
||||||
mailing list.
|
mailing list.
|
||||||
|
|
||||||
@ -29,16 +30,16 @@ Say we've written a polymorphic linked list node base class:
|
|||||||
|
|
||||||
// print to the stream
|
// print to the stream
|
||||||
virtual void print(std::ostream& s) const = 0;
|
virtual void print(std::ostream& s) const = 0;
|
||||||
|
|
||||||
// double the value
|
// double the value
|
||||||
virtual void double_me() = 0;
|
virtual void double_me() = 0;
|
||||||
|
|
||||||
void append(node_base* p)
|
void append(node_base* p)
|
||||||
{
|
{
|
||||||
if (m_next)
|
if (m_next)
|
||||||
m_next->append(p);
|
m_next->append(p);
|
||||||
else
|
else
|
||||||
m_next = p;
|
m_next = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -209,7 +210,7 @@ the concepts we want our iterator to model. Referring to the
|
|||||||
table__, we can see that the first three rows are applicable
|
table__, we can see that the first three rows are applicable
|
||||||
because `node_iterator` needs to satisfy the requirements for
|
because `node_iterator` needs to satisfy the requirements for
|
||||||
`readable iterator`_, `single pass iterator`_, and `incrementable
|
`readable iterator`_, `single pass iterator`_, and `incrementable
|
||||||
iterator`_.
|
iterator`_.
|
||||||
|
|
||||||
__ `core operations`_
|
__ `core operations`_
|
||||||
|
|
||||||
@ -253,24 +254,24 @@ make them private and grant friendship to
|
|||||||
};
|
};
|
||||||
|
|
||||||
Voila; a complete and conforming readable, forward-traversal
|
Voila; a complete and conforming readable, forward-traversal
|
||||||
iterator! For a working example of its use, see
|
iterator! For a working example of its use, see
|
||||||
[example_link node_iterator1.cpp..this program].
|
[@../example/node_iterator1.cpp `this program`].
|
||||||
|
|
||||||
__ ../../example/node_iterator1.cpp
|
__ ../example/node_iterator1.cpp
|
||||||
|
|
||||||
[h2 A constant `node_iterator`]
|
[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 term **mutable iterator** means an iterator through which
|
||||||
the object it references (its "referent") can be modified. A
|
the object it references (its "referent") can be modified. A
|
||||||
**constant iterator** is one which doesn't allow modification of
|
**constant iterator** is one which doesn't allow modification of
|
||||||
its referent.[br][br]
|
its referent.\n\n
|
||||||
The words *constant* and *mutable* don't refer to the ability to
|
The words *constant* and *mutable* don't refer to the ability to
|
||||||
modify the iterator itself. For example, an `int const*` is a
|
modify the iterator itself. For example, an `int const*` is a
|
||||||
non-\ `const` *constant iterator*, which can be incremented
|
non-\ `const` *constant iterator*, which can be incremented
|
||||||
but doesn't allow modification of its referent, and `int*
|
but doesn't allow modification of its referent, and `int*
|
||||||
const` is a `const` *mutable iterator*, which cannot be
|
const` is a `const` *mutable iterator*, which cannot be
|
||||||
modified but which allows modification of its referent.[br][br]
|
modified but which allows modification of its referent.\n\n
|
||||||
Confusing? We agree, but those are the standard terms. It
|
Confusing? We agree, but those are the standard terms. It
|
||||||
probably doesn't help much that a container's constant iterator
|
probably doesn't help much that a container's constant iterator
|
||||||
is called `const_iterator`.
|
is called `const_iterator`.
|
||||||
@ -284,7 +285,7 @@ changes:
|
|||||||
|
|
||||||
class const_node_iterator
|
class const_node_iterator
|
||||||
: public boost::iterator_facade<
|
: public boost::iterator_facade<
|
||||||
const_node_iterator
|
node_iterator
|
||||||
, node_base **const**
|
, node_base **const**
|
||||||
, boost::forward_traversal_tag
|
, boost::forward_traversal_tag
|
||||||
>
|
>
|
||||||
@ -311,7 +312,7 @@ changes:
|
|||||||
node_base **const**\ * m_node;
|
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
|
The C++ standard requires an iterator's `value_type` *not* be
|
||||||
`const`\ -qualified, so `iterator_facade` strips the
|
`const`\ -qualified, so `iterator_facade` strips the
|
||||||
`const` from its `Value` parameter in order to produce the
|
`const` from its `Value` parameter in order to produce the
|
||||||
@ -401,7 +402,7 @@ adding a templatized converting constructor [#broken]_ [#random]_:
|
|||||||
|
|
||||||
template <class OtherValue>
|
template <class OtherValue>
|
||||||
bool equal(node_iter<OtherValue> const& other) const
|
bool equal(node_iter<OtherValue> const& other) const
|
||||||
{
|
{
|
||||||
return this->m_node == other.m_node;
|
return this->m_node == other.m_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,11 +428,11 @@ adding a templatized converting constructor [#broken]_ [#random]_:
|
|||||||
`distance_to` function as well.
|
`distance_to` function as well.
|
||||||
|
|
||||||
|
|
||||||
__ ../../example/node_iterator2.hpp
|
__ ../example/node_iterator2.hpp
|
||||||
|
|
||||||
You can see an example program which exercises our interoperable
|
You can see an example program which exercises our interoperable
|
||||||
iterators
|
iterators
|
||||||
[example_link node_iterator2.cpp..here].
|
[@../example/node_iterator2.cpp `here`].
|
||||||
|
|
||||||
|
|
||||||
[h2 Telling the Truth]
|
[h2 Telling the Truth]
|
||||||
@ -466,7 +467,7 @@ appropriate:
|
|||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct enabler {};
|
struct enabler {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:filter Filter Iterator]
|
[section:filter Filter Iterator]
|
||||||
|
|
||||||
The filter iterator adaptor creates a view of an iterator range in
|
The filter iterator adaptor creates a view of an iterator range in
|
||||||
@ -18,6 +19,7 @@ This example uses `filter_iterator` and then
|
|||||||
array of integers. Then `make_filter_iterator` is is used to output
|
array of integers. Then `make_filter_iterator` is is used to output
|
||||||
the integers greater than `-2`.
|
the integers greater than `-2`.
|
||||||
|
|
||||||
|
|
||||||
struct is_positive_number {
|
struct is_positive_number {
|
||||||
bool operator()(int x) { return 0 < x; }
|
bool operator()(int x) { return 0 < x; }
|
||||||
};
|
};
|
||||||
@ -31,7 +33,7 @@ the integers greater than `-2`.
|
|||||||
base_iterator numbers(numbers_);
|
base_iterator numbers(numbers_);
|
||||||
|
|
||||||
// Example using filter_iterator
|
// Example using filter_iterator
|
||||||
typedef boost::filter_iterator<is_positive_number, base_iterator>
|
typedef boost::filter_iterator<is_positive_number, base_iterator>
|
||||||
FilterIter;
|
FilterIter;
|
||||||
|
|
||||||
is_positive_number predicate;
|
is_positive_number predicate;
|
||||||
@ -50,11 +52,11 @@ the integers greater than `-2`.
|
|||||||
// Another example using make_filter_iterator()
|
// Another example using make_filter_iterator()
|
||||||
std::copy(
|
std::copy(
|
||||||
boost::make_filter_iterator(
|
boost::make_filter_iterator(
|
||||||
std::bind(std::greater<int>(), std::placeholders::_1, -2)
|
std::bind2nd(std::greater<int>(), -2)
|
||||||
, numbers, numbers + N)
|
, numbers, numbers + N)
|
||||||
|
|
||||||
, boost::make_filter_iterator(
|
, boost::make_filter_iterator(
|
||||||
std::bind(std::greater<int>(), std::placeholders::_1, -2)
|
std::bind2nd(std::greater<int>(), -2)
|
||||||
, numbers + N, numbers + N)
|
, numbers + N, numbers + N)
|
||||||
|
|
||||||
, std::ostream_iterator<int>(std::cout, " ")
|
, std::ostream_iterator<int>(std::cout, " ")
|
||||||
@ -68,13 +70,12 @@ the integers greater than `-2`.
|
|||||||
|
|
||||||
The output is:
|
The output is:
|
||||||
|
|
||||||
[pre
|
4 5 8
|
||||||
4 5 8
|
4 5 8
|
||||||
4 5 8
|
0 -1 4 5 8
|
||||||
0 -1 4 5 8
|
|
||||||
]
|
|
||||||
|
|
||||||
The source code for this example can be found [example_link filter_iterator_example.cpp..here].
|
|
||||||
|
The source code for this example can be found [@../example/filter_iterator_example.cpp here].
|
||||||
|
|
||||||
[h2 Reference]
|
[h2 Reference]
|
||||||
|
|
||||||
@ -113,10 +114,10 @@ The source code for this example can be found [example_link filter_iterator_exam
|
|||||||
|
|
||||||
If `Iterator` models Readable Lvalue Iterator and Bidirectional Traversal
|
If `Iterator` models Readable Lvalue Iterator and Bidirectional Traversal
|
||||||
Iterator then `iterator_category` is convertible to
|
Iterator then `iterator_category` is convertible to
|
||||||
`std::bidirectional_iterator_tag`.
|
`std::bidirectional_iterator_tag`.
|
||||||
Otherwise, if `Iterator` models Readable Lvalue Iterator and Forward Traversal
|
Otherwise, if `Iterator` models Readable Lvalue Iterator and Forward Traversal
|
||||||
Iterator then `iterator_category` is convertible to
|
Iterator then `iterator_category` is convertible to
|
||||||
`std::forward_iterator_tag`.
|
`std::forward_iterator_tag`.
|
||||||
Otherwise `iterator_category` is
|
Otherwise `iterator_category` is
|
||||||
convertible to `std::input_iterator_tag`.
|
convertible to `std::input_iterator_tag`.
|
||||||
|
|
||||||
@ -163,7 +164,7 @@ following tables.
|
|||||||
[[Writable Lvalue Iterator, Bidirectional Iterator ][Mutable Bidirectional Iterator]]
|
[[Writable Lvalue Iterator, Bidirectional Iterator ][Mutable Bidirectional Iterator]]
|
||||||
]
|
]
|
||||||
|
|
||||||
`filter_iterator<P1, X>` is interoperable with `filter_iterator<P2, Y>`
|
`filter_iterator<P1, X>` is interoperable with `filter_iterator<P2, Y>`
|
||||||
if and only if `X` is interoperable with `Y`.
|
if and only if `X` is interoperable with `Y`.
|
||||||
|
|
||||||
|
|
||||||
@ -177,15 +178,15 @@ operations.
|
|||||||
|
|
||||||
filter_iterator();
|
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`
|
[*Effects: ] Constructs a `filter_iterator` whose`m_pred`, `m_iter`, and `m_end`
|
||||||
members are a default constructed.
|
members are a default constructed.
|
||||||
|
|
||||||
|
|
||||||
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
|
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
|
||||||
|
|
||||||
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
|
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
|
||||||
the first position in the range `[x,end)` such that `f(*m_iter) == true`
|
the first position in the range `[x,end)` such that `f(*m_iter) == true`
|
||||||
or else`m_iter == end`. The member `m_pred` is constructed from
|
or else`m_iter == end`. The member `m_pred` is constructed from
|
||||||
`f` and `m_end` from `end`.
|
`f` and `m_end` from `end`.
|
||||||
|
|
||||||
@ -194,9 +195,9 @@ operations.
|
|||||||
filter_iterator(Iterator x, Iterator end = Iterator());
|
filter_iterator(Iterator x, Iterator end = Iterator());
|
||||||
|
|
||||||
[*Requires: ] `Predicate` must be Default Constructible and
|
[*Requires: ] `Predicate` must be Default Constructible and
|
||||||
`Predicate` is a class type (not a function pointer).[br]
|
`Predicate` is a class type (not a function pointer).\n
|
||||||
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
|
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
|
||||||
the first position in the range `[x,end)` such that `m_pred(*m_iter) == true`
|
the first position in the range `[x,end)` such that `m_pred(*m_iter) == true`
|
||||||
or else`m_iter == end`. The member `m_pred` is default constructed.
|
or else`m_iter == end`. The member `m_pred` is default constructed.
|
||||||
|
|
||||||
|
|
||||||
@ -204,9 +205,9 @@ operations.
|
|||||||
filter_iterator(
|
filter_iterator(
|
||||||
filter_iterator<Predicate, OtherIterator> const& t
|
filter_iterator<Predicate, OtherIterator> const& t
|
||||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||||
);
|
);`
|
||||||
|
|
||||||
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
|
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.\n
|
||||||
[*Effects: ] Constructs a filter iterator whose members are copied from `t`.
|
[*Effects: ] Constructs a filter iterator whose members are copied from `t`.
|
||||||
|
|
||||||
|
|
||||||
@ -234,7 +235,8 @@ operations.
|
|||||||
|
|
||||||
[*Effects: ] Increments `m_iter` and then continues to
|
[*Effects: ] Increments `m_iter` and then continues to
|
||||||
increment `m_iter` until either `m_iter == m_end`
|
increment `m_iter` until either `m_iter == m_end`
|
||||||
or `m_pred(*m_iter) == true`.[br]
|
or `m_pred(*m_iter) == true`.\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
[endsect]
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:function_output Function Output Iterator]
|
[section:function_output Function Output Iterator]
|
||||||
|
|
||||||
The function output iterator adaptor makes it easier to create custom
|
The function output iterator adaptor makes it easier to create custom
|
||||||
@ -33,8 +34,8 @@ proxy object.
|
|||||||
x.push_back("!");
|
x.push_back("!");
|
||||||
|
|
||||||
std::string s = "";
|
std::string s = "";
|
||||||
std::copy(x.begin(), x.end(),
|
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;
|
std::cout << s << std::endl;
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ proxy object.
|
|||||||
|
|
||||||
[h3 Requirements]
|
[h3 Requirements]
|
||||||
|
|
||||||
`UnaryFunction` must be Assignable and Copy Constructible.
|
`UnaryFunction` must be Assignable and Copy Constructible.
|
||||||
|
|
||||||
[h3 Concepts]
|
[h3 Concepts]
|
||||||
|
|
||||||
@ -78,14 +79,14 @@ Incrementable Iterator concepts.
|
|||||||
|
|
||||||
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
|
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
|
||||||
|
|
||||||
[*Effects: ] Constructs an instance of `function_output_iterator`
|
[*Effects: ] Constructs an instance of `function_output_iterator`
|
||||||
with `m_f` constructed from `f`.
|
with `m_f` constructed from `f`.
|
||||||
|
|
||||||
unspecified_type operator*();
|
unspecified_type operator*();
|
||||||
|
|
||||||
[*Returns: ] An object `r` of unspecified type such that `r = t`
|
[*Returns: ] An object `r` of unspecified type such that `r = t`
|
||||||
is equivalent to `m_f(t)` for all `t`.
|
is equivalent to `m_f(t)` for all `t`.
|
||||||
|
|
||||||
|
|
||||||
function_output_iterator& operator++();
|
function_output_iterator& operator++();
|
||||||
|
|
||||||
@ -96,4 +97,4 @@ Incrementable Iterator concepts.
|
|||||||
|
|
||||||
[*Returns: ] `*this`.
|
[*Returns: ] `*this`.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:indirect Indirect Iterator]
|
[section:indirect Indirect Iterator]
|
||||||
|
|
||||||
`indirect_iterator` adapts an iterator by applying an
|
`indirect_iterator` adapts an iterator by applying an
|
||||||
@ -49,31 +50,30 @@ using the `make_indirect_iterator` helper function.
|
|||||||
const_indirect_last(pointers_to_chars + N);
|
const_indirect_last(pointers_to_chars + N);
|
||||||
|
|
||||||
std::transform(const_indirect_first, const_indirect_last,
|
std::transform(const_indirect_first, const_indirect_last,
|
||||||
mutable_indirect_first, std::bind(std::plus<char>(), 1, std::placeholders::_1));
|
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
|
||||||
|
|
||||||
std::copy(mutable_indirect_first, mutable_indirect_last,
|
std::copy(mutable_indirect_first, mutable_indirect_last,
|
||||||
std::ostream_iterator<char>(std::cout, ","));
|
std::ostream_iterator<char>(std::cout, ","));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
||||||
// Example of using make_indirect_iterator()
|
// Example of using make_indirect_iterator()
|
||||||
|
|
||||||
std::copy(boost::make_indirect_iterator(pointers_to_chars),
|
std::copy(boost::make_indirect_iterator(pointers_to_chars),
|
||||||
boost::make_indirect_iterator(pointers_to_chars + N),
|
boost::make_indirect_iterator(pointers_to_chars + N),
|
||||||
std::ostream_iterator<char>(std::cout, ","));
|
std::ostream_iterator<char>(std::cout, ","));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
||||||
The output is:
|
The output is:
|
||||||
|
|
||||||
[pre
|
a,b,c,d,e,f,g,
|
||||||
a,b,c,d,e,f,g,
|
b,c,d,e,f,g,h,
|
||||||
b,c,d,e,f,g,h,
|
a,b,c,d,e,f,g,
|
||||||
a,b,c,d,e,f,g,
|
|
||||||
]
|
|
||||||
|
|
||||||
The source code for this example can be found
|
|
||||||
[example_link indirect_iterator_example.cpp..here].
|
The source code for this example can be found
|
||||||
|
[@../example/indirect_iterator_example.cpp here].
|
||||||
|
|
||||||
|
|
||||||
[h2 Reference]
|
[h2 Reference]
|
||||||
@ -137,9 +137,9 @@ the following pseudo-code, where `V` is
|
|||||||
else
|
else
|
||||||
typedef Reference reference;
|
typedef Reference reference;
|
||||||
|
|
||||||
if (Value is use_default) then
|
if (Value is use_default) then
|
||||||
typedef pointee<V>::type\* pointer;
|
typedef pointee<V>::type\* pointer;
|
||||||
else
|
else
|
||||||
typedef Value\* pointer;
|
typedef Value\* pointer;
|
||||||
|
|
||||||
if (Difference is use_default)
|
if (Difference is use_default)
|
||||||
@ -203,8 +203,8 @@ following operations:
|
|||||||
|
|
||||||
indirect_iterator();
|
indirect_iterator();
|
||||||
|
|
||||||
[*Requires: ] `Iterator` must be Default Constructible.[br]
|
[*Requires: ] `Iterator` must be Default Constructible.\n
|
||||||
[*Effects: ] Constructs an instance of `indirect_iterator` with
|
[*Effects: ] Constructs an instance of `indirect_iterator` with
|
||||||
a default-constructed `m_iterator`.
|
a default-constructed `m_iterator`.
|
||||||
|
|
||||||
|
|
||||||
@ -225,8 +225,8 @@ following operations:
|
|||||||
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
|
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
|
||||||
);
|
);
|
||||||
|
|
||||||
[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.[br]
|
[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.\n
|
||||||
[*Effects: ] Constructs an instance of `indirect_iterator` whose
|
[*Effects: ] Constructs an instance of `indirect_iterator` whose
|
||||||
`m_iterator` subobject is constructed from `y.base()`.
|
`m_iterator` subobject is constructed from `y.base()`.
|
||||||
|
|
||||||
|
|
||||||
@ -242,13 +242,13 @@ following operations:
|
|||||||
|
|
||||||
indirect_iterator& operator++();
|
indirect_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `++m_iterator`[br]
|
[*Effects: ] `++m_iterator`\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
indirect_iterator& operator--();
|
indirect_iterator& operator--();
|
||||||
|
|
||||||
[*Effects: ] `--m_iterator`[br]
|
[*Effects: ] `--m_iterator`\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
[library Boost.Iterator
|
[library Boost.Iterator
|
||||||
[/ version 1.0.1]
|
[/ version 1.0.1]
|
||||||
[quickbook 1.6]
|
|
||||||
[authors [Abrahams, David], [Siek, Jeremy], [Witt, Thomas]]
|
[authors [Abrahams, David], [Siek, Jeremy], [Witt, Thomas]]
|
||||||
[copyright 2003 2005 David Abrahams Jeremy Siek Thomas Witt]
|
[copyright 2003 2005 David Abrahams Jeremy Siek Thomas Witt]
|
||||||
[category iterator]
|
[category iterator]
|
||||||
@ -28,11 +28,7 @@
|
|||||||
|
|
||||||
[/ Links ]
|
[/ Links ]
|
||||||
|
|
||||||
[def _iterator_ [@../../../iterator/doc/index.html Boost.Iterator]]
|
[def _iterator_ [@../../libs/iterator/doc/index.html Boost.Iterator]]
|
||||||
[def _concept_check_ [@../../../concept_check/index.html Boost.ConceptCheck]]
|
|
||||||
[template example_link[name descr]'''<ulink url="../../example/'''[name]'''">'''[descr]'''</ulink>''']
|
|
||||||
|
|
||||||
[template sub[x]'''<subscript>'''[x]'''</subscript>''']
|
|
||||||
|
|
||||||
[section:intro Introduction]
|
[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
|
patching up `vector<bool>`, though: there are lots of other
|
||||||
iterators already in use which can't be adequately represented by
|
iterators already in use which can't be adequately represented by
|
||||||
the existing concepts. For details about the new iterator
|
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]
|
[h2 Iterator Facade and Adaptor]
|
||||||
|
|
||||||
[/
|
[def _facade_ [@./iterator_facade.html facade]]
|
||||||
[def _facade_ [link iterator.generic.facade facade]]
|
[def _adaptor_ [@./iterator_adaptor.html adaptor]]
|
||||||
[def _adaptor_ [link iterator.generic.adaptor adaptor]]
|
|
||||||
]
|
|
||||||
[def _facade_ [@../iterator_facade.html facade]]
|
|
||||||
[def _adaptor_ [@../iterator_adaptor.html adaptor]]
|
|
||||||
|
|
||||||
Writing standard-conforming iterators is tricky, but the need comes
|
Writing standard-conforming iterators is tricky, but the need comes
|
||||||
up often. In order to ease the implementation of new iterators,
|
up often. In order to ease the implementation of new iterators,
|
||||||
the Boost.Iterator library provides the _facade_ class template,
|
the Boost.Iterator library provides the _facade_ class template,
|
||||||
which implements many useful defaults and compile-time checks
|
which implements many useful defaults and compile-time checks
|
||||||
designed to help the iterator author ensure that his iterator is
|
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
|
It is also common to define a new iterator that is similar to some
|
||||||
underlying iterator or iterator-like type, but that modifies 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
|
designed to take advantage of as much of the underlying type's
|
||||||
behavior as possible.
|
behavior as possible.
|
||||||
|
|
||||||
Both _facade_ and _adaptor_ as well as many of the [link iterator.specialized specialized
|
Both _facade_ and _adaptor_ as well as many of the `specialized
|
||||||
adaptors] mentioned below have been proposed for standardization
|
adaptors`_ mentioned below have been proposed for standardization
|
||||||
([@../facade-and-adaptor.html Standard Proposal For Iterator Facade and Adaptor]).
|
([@./facade-and-adaptor.html Standard Proposal For Iterator Facade and Adaptor]).
|
||||||
|
|
||||||
[h2 Specialized Adaptors]
|
[h2 Specialized Adaptors]
|
||||||
|
|
||||||
The iterator library supplies a useful suite of standard-conforming
|
The iterator library supplies a useful suite of standard-conforming
|
||||||
iterator templates based on the Boost [link
|
iterator templates based on the Boost [link
|
||||||
iterator.intro.iterator_facade_and_adaptor iterator facade and adaptor]
|
intro.iterator_facade_and_adaptor iterator facade and adaptor]
|
||||||
templates.
|
templates.
|
||||||
|
|
||||||
[def _counting_ [link iterator.specialized.counting `counting_iterator`]]
|
[def _counting_ [@./counting_iterator.html `counting_iterator`]]
|
||||||
[def _filter_ [link iterator.specialized.filter `filter_iterator`]]
|
[def _filter_ [@./filter_iterator.html `filter_iterator`]]
|
||||||
[def _function_input_ [@../function_input_iterator.html `function_input_iterator`]]
|
[def _function_ [@./function_output_iterator.html `function_output_iterator`]]
|
||||||
[def _function_output_ [link iterator.specialized.function_output `function_output_iterator`]]
|
[def _indirect_ [@./indirect_iterator.html `indirect_iterator`]]
|
||||||
[def _generator_ [@../generator_iterator.htm `generator_iterator`]]
|
[def _permutation_ [@./permutation_iterator.html `permutation_iterator`]]
|
||||||
[def _indirect_ [link iterator.specialized.indirect `indirect_iterator`]]
|
[def _reverse_ [@./reverse_iterator.html `reverse_iterator`]]
|
||||||
[def _permutation_ [link iterator.specialized.permutation `permutation_iterator`]]
|
[def _shared_ [@./shared_container_iterator.html `shared_container_iterator`]]
|
||||||
[def _reverse_ [link iterator.specialized.reverse `reverse_iterator`]]
|
[def _transform_ [@./transform_iterator.html `transform_iterator`]]
|
||||||
[def _shared_ [link iterator.specialized.shared_container `shared_container_iterator`]]
|
[def _zip_ [@./zip_iterator.html `zip_iterator`]]
|
||||||
[def _transform_ [link iterator.specialized.transform `transform_iterator`]]
|
|
||||||
[def _zip_ [link iterator.specialized.zip `zip_iterator`]]
|
|
||||||
|
|
||||||
[def _shared_ptr_ [@../../smart_ptr/shared_ptr.htm `shared_ptr`]]
|
[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
|
* _filter_: an iterator over the subset of elements of some
|
||||||
sequence which satisfy a given predicate
|
sequence which satisfy a given predicate
|
||||||
|
|
||||||
* _function_input_: an input iterator wrapping a generator (nullary
|
* _function_: an output iterator wrapping a unary function
|
||||||
function object); each time the iterator is dereferenced, the function object
|
|
||||||
is called to get the value to return.
|
|
||||||
|
|
||||||
* _function_output_: an output iterator wrapping a unary function
|
|
||||||
object; each time an element is written into the dereferenced
|
object; each time an element is written into the dereferenced
|
||||||
iterator, it is passed as a parameter to the function object.
|
iterator, it is passed as a parameter to the function object.
|
||||||
|
|
||||||
* _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
|
* _indirect_: an iterator over the objects *pointed-to* by the
|
||||||
elements of some sequence.
|
elements of some sequence.
|
||||||
|
|
||||||
@ -150,7 +132,7 @@ templates.
|
|||||||
|
|
||||||
* _reverse_: an iterator which traverses the elements of some
|
* _reverse_: an iterator which traverses the elements of some
|
||||||
bidirectional sequence in reverse. Corrects many of the
|
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
|
* _shared_: an iterator over elements of a container whose
|
||||||
lifetime is maintained by a _shared_ptr_ stored in the iterator.
|
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
|
* _transform_: an iterator over elements which are the result of
|
||||||
applying some functional transformation to the elements of an
|
applying some functional transformation to the elements of an
|
||||||
underlying sequence. This component also replaces the old
|
underlying sequence. This component also replaces the old
|
||||||
`projection_iterator_adaptor`.
|
``projection_iterator_adaptor``.
|
||||||
|
|
||||||
* _zip_: an iterator over tuples of the elements at corresponding
|
* _zip_: an iterator over tuples of the elements at corresponding
|
||||||
positions of heterogeneous underlying iterators.
|
positions of heterogeneous underlying iterators.
|
||||||
@ -167,9 +149,9 @@ templates.
|
|||||||
|
|
||||||
[h3 Traits]
|
[h3 Traits]
|
||||||
|
|
||||||
[def _pointee_ [link iterator.utilities.traits `pointee.hpp`]]
|
[def _pointee_ [@./pointee.html `pointee.hpp`]]
|
||||||
[def _iterator_traits_ [link iterator.utilities.iterator_traits `iterator_traits.hpp`]]
|
[def _iterator_traits_ [@./iterator_traits.html `iterator_traits.hpp`]]
|
||||||
[def _interoperable_ [@../interoperable.html `interoperable.hpp`]]
|
[def _interoperable_ [@./interoperable.html `interoperable.hpp`]]
|
||||||
[def _MPL_ [@../../mpl/doc/index.html [*MPL]]]
|
[def _MPL_ [@../../mpl/doc/index.html [*MPL]]]
|
||||||
|
|
||||||
* _pointee_: Provides the capability to deduce the referent types
|
* _pointee_: Provides the capability to deduce the referent types
|
||||||
@ -180,40 +162,19 @@ templates.
|
|||||||
retrieve an iterator's traits. Also corrects for the deficiencies
|
retrieve an iterator's traits. Also corrects for the deficiencies
|
||||||
of broken implementations of `std::iterator_traits`.
|
of broken implementations of `std::iterator_traits`.
|
||||||
|
|
||||||
[/
|
[\ * |interoperable|_ (PDF__): Provides an _MPL_ compatible metafunction for
|
||||||
* _interoperable_: Provides an _MPL_ compatible metafunction for
|
testing iterator interoperability
|
||||||
testing iterator interoperability
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[h3 Testing and Concept Checking]
|
[h3 Testing and Concept Checking]
|
||||||
|
|
||||||
[def _iterator_concepts_ [link iterator.concepts `iterator_concepts.hpp`]]
|
[def _iterator_concepts_ [@./iterator_concepts.html `iterator_concepts.hpp`]]
|
||||||
[def _iterator_archetypes_ [link iterator.utilities.archetypes `iterator_archetypes.hpp`]]
|
[def _iterator_archetypes_ [@./iterator_archetypes.html `iterator_archetypes.hpp`]]
|
||||||
|
|
||||||
* _iterator_concepts_: Concept checking classes for the new iterator concepts.
|
* _iterator_concepts_: Concept checking classes for the new iterator concepts.
|
||||||
|
|
||||||
* _iterator_archetypes_: Concept archetype classes for the new iterators 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]
|
[endsect]
|
||||||
|
|
||||||
[include concepts.qbk]
|
[include concepts.qbk]
|
||||||
@ -234,14 +195,12 @@ better performance and functionality.
|
|||||||
|
|
||||||
[include concept_checking.qbk]
|
[include concept_checking.qbk]
|
||||||
|
|
||||||
[include iterator_traits.qbk]
|
[include traits.qbk]
|
||||||
|
|
||||||
[include type_traits.qbk]
|
[include utilities.qbk]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[include algorithms.qbk]
|
|
||||||
|
|
||||||
[section:upgrading Upgrading from the old Boost Iterator Adaptor Library]
|
[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]]
|
[def _type_generator_ [@http://www.boost.org/more/generic_programming.html#type_generator type generator]]
|
||||||
@ -305,3 +264,5 @@ library you see today.
|
|||||||
Patterns, C++ Report, February 1995, pp. 24-27.]
|
Patterns, C++ Report, February 1995, pp. 24-27.]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
[section:iterator_traits Iterator Traits]
|
|
||||||
|
|
||||||
`std::iterator_traits` provides access to five associated types
|
|
||||||
of any iterator: its `value_type`, `reference`, `pointer`,
|
|
||||||
`iterator_category`, and `difference_type`. Unfortunately,
|
|
||||||
such a "multi-valued" traits template can be difficult to use in a
|
|
||||||
metaprogramming context. `<boost/iterator/iterator_traits.hpp>`
|
|
||||||
provides access to these types using a standard metafunctions_.
|
|
||||||
|
|
||||||
[h2 Synopsis]
|
|
||||||
|
|
||||||
Header `<boost/iterator/iterator_traits.hpp>`:
|
|
||||||
|
|
||||||
template <class Iterator>
|
|
||||||
struct iterator_value
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
std::iterator_traits<Iterator>::value_type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Iterator>
|
|
||||||
struct iterator_reference
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
std::iterator_traits<Iterator>::reference
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Iterator>
|
|
||||||
struct iterator_pointer
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
std::iterator_traits<Iterator>::pointer
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Iterator>
|
|
||||||
struct iterator_difference
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
detail::iterator_traits<Iterator>::difference_type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Iterator>
|
|
||||||
struct iterator_category
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
detail::iterator_traits<Iterator>::iterator_category
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
[endsect]
|
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:permutation Permutation Iterator]
|
[section:permutation Permutation Iterator]
|
||||||
|
|
||||||
The permutation iterator adaptor provides a permuted view of a given
|
The permutation iterator adaptor provides a permuted view of a given
|
||||||
@ -34,7 +35,7 @@ past-the-end iterator to the indices.
|
|||||||
*el_it = std::distance(elements.begin(), el_it);
|
*el_it = std::distance(elements.begin(), el_it);
|
||||||
|
|
||||||
index_type indices( index_size );
|
index_type indices( index_size );
|
||||||
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
|
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
|
||||||
*i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
|
*i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
|
||||||
std::reverse( indices.begin(), indices.end() );
|
std::reverse( indices.begin(), indices.end() );
|
||||||
|
|
||||||
@ -74,28 +75,27 @@ past-the-end iterator to the indices.
|
|||||||
|
|
||||||
The output is:
|
The output is:
|
||||||
|
|
||||||
[pre
|
The original range is : 0 1 2 3 4 5 6 7 8 9
|
||||||
The original range is : 0 1 2 3 4 5 6 7 8 9
|
The reindexing scheme is : 9 8 7 6
|
||||||
The reindexing scheme is : 9 8 7 6
|
The permutated range is : 9 8 7 6
|
||||||
The permutated range is : 9 8 7 6
|
Elements at even indices in the permutation : 9 7
|
||||||
Elements at even indices in the permutation : 9 7
|
Permutation backwards : 6 7 8 9
|
||||||
Permutation backwards : 6 7 8 9
|
Iterate backward with stride 2 : 6 8
|
||||||
Iterate backward with stride 2 : 6 8
|
|
||||||
]
|
|
||||||
|
|
||||||
The source code for this example can be found
|
The source code for this example can be found
|
||||||
[example_link permutation_iter_example.cpp..here].
|
[@../example/permutation_iter_example.cpp here].
|
||||||
|
|
||||||
[h2 Reference]
|
[h2 Reference]
|
||||||
|
|
||||||
[h3 Synopsis]
|
[h3 Synopsis]
|
||||||
|
|
||||||
template< class ElementIterator
|
template< class ElementIterator
|
||||||
, class IndexIterator
|
, class IndexIterator
|
||||||
, class ValueT = use_default
|
, class ValueT = use_default
|
||||||
, class CategoryT = use_default
|
, class CategoryT = use_default
|
||||||
, class ReferenceT = use_default
|
, class ReferenceT = use_default
|
||||||
, class DifferenceT = use_default >
|
, class DifferenceT = use_default >
|
||||||
class permutation_iterator
|
class permutation_iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -104,10 +104,10 @@ The source code for this example can be found
|
|||||||
|
|
||||||
template< class OEIter, class OIIter, class V, class C, class R, class D >
|
template< class OEIter, class OIIter, class V, class C, class R, class D >
|
||||||
permutation_iterator(
|
permutation_iterator(
|
||||||
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
|
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
|
||||||
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
|
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
|
||||||
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
|
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
|
||||||
);
|
);
|
||||||
reference operator*() const;
|
reference operator*() const;
|
||||||
permutation_iterator& operator++();
|
permutation_iterator& operator++();
|
||||||
ElementIterator const& base() const;
|
ElementIterator const& base() const;
|
||||||
@ -117,7 +117,7 @@ The source code for this example can be found
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class ElementIterator, class IndexIterator>
|
template <class ElementIterator, class IndexIterator>
|
||||||
permutation_iterator<ElementIterator, IndexIterator>
|
permutation_iterator<ElementIterator, IndexIterator>
|
||||||
make_permutation_iterator( ElementIterator e, IndexIterator i);
|
make_permutation_iterator( ElementIterator e, IndexIterator i);
|
||||||
|
|
||||||
|
|
||||||
@ -134,15 +134,15 @@ the `IndexIterator` must be convertible to the difference type of
|
|||||||
as `IndexIterator` and the same iterator access concepts as
|
as `IndexIterator` and the same iterator access concepts as
|
||||||
`ElementIterator`.
|
`ElementIterator`.
|
||||||
|
|
||||||
If `IndexIterator` models Single Pass Iterator and
|
If `IndexIterator` models Single Pass Iterator and
|
||||||
`ElementIterator` models Readable Iterator then
|
`ElementIterator` models Readable Iterator then
|
||||||
`permutation_iterator` models Input Iterator.
|
`permutation_iterator` models Input Iterator.
|
||||||
|
|
||||||
If `IndexIterator` models Forward Traversal Iterator and
|
If `IndexIterator` models Forward Traversal Iterator and
|
||||||
`ElementIterator` models Readable Lvalue Iterator then
|
`ElementIterator` models Readable Lvalue Iterator then
|
||||||
`permutation_iterator` models Forward Iterator.
|
`permutation_iterator` models Forward Iterator.
|
||||||
|
|
||||||
If `IndexIterator` models Bidirectional Traversal Iterator and
|
If `IndexIterator` models Bidirectional Traversal Iterator and
|
||||||
`ElementIterator` models Readable Lvalue Iterator then
|
`ElementIterator` models Readable Lvalue Iterator then
|
||||||
`permutation_iterator` models Bidirectional Iterator.
|
`permutation_iterator` models Bidirectional Iterator.
|
||||||
|
|
||||||
@ -173,10 +173,10 @@ following operations.
|
|||||||
|
|
||||||
template< class OEIter, class OIIter, class V, class C, class R, class D >
|
template< class OEIter, class OIIter, class V, class C, class R, class D >
|
||||||
permutation_iterator(
|
permutation_iterator(
|
||||||
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
|
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
|
||||||
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
|
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
|
||||||
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
|
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
|
||||||
);
|
);
|
||||||
|
|
||||||
[*Effects: ] Constructs `m_elt` from `r.m_elt` and
|
[*Effects: ] Constructs `m_elt` from `r.m_elt` and
|
||||||
`m_order` from `y.m_order`.
|
`m_order` from `y.m_order`.
|
||||||
@ -189,7 +189,7 @@ following operations.
|
|||||||
|
|
||||||
permutation_iterator& operator++();
|
permutation_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `++m_order`[br]
|
[*Effects: ] `++m_order`\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
@ -199,9 +199,9 @@ following operations.
|
|||||||
|
|
||||||
|
|
||||||
template <class ElementIterator, class IndexIterator>
|
template <class ElementIterator, class IndexIterator>
|
||||||
permutation_iterator<ElementIterator, IndexIterator>
|
permutation_iterator<ElementIterator, IndexIterator>
|
||||||
make_permutation_iterator(ElementIterator e, IndexIterator i);
|
make_permutation_iterator(ElementIterator e, IndexIterator i);
|
||||||
|
|
||||||
[*Returns: ] `permutation_iterator<ElementIterator, IndexIterator>(e, i)`
|
[*Returns: ] `permutation_iterator<ElementIterator, IndexIterator>(e, i)`
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:reverse Reverse Iterator]
|
[section:reverse Reverse Iterator]
|
||||||
|
|
||||||
The reverse iterator adaptor iterates through the adapted iterator
|
The reverse iterator adaptor iterates through the adapted iterator
|
||||||
@ -8,6 +9,7 @@ range in the opposite direction.
|
|||||||
The following example prints an array of characters in reverse order
|
The following example prints an array of characters in reverse order
|
||||||
using `reverse_iterator`.
|
using `reverse_iterator`.
|
||||||
|
|
||||||
|
|
||||||
char letters_[] = "hello world!";
|
char letters_[] = "hello world!";
|
||||||
const int N = sizeof(letters_)/sizeof(char) - 1;
|
const int N = sizeof(letters_)/sizeof(char) - 1;
|
||||||
typedef char* base_iterator;
|
typedef char* base_iterator;
|
||||||
@ -33,14 +35,13 @@ using `reverse_iterator`.
|
|||||||
|
|
||||||
The output is:
|
The output is:
|
||||||
|
|
||||||
[pre
|
original sequence of letters: hello world!
|
||||||
original sequence of letters: hello world!
|
sequence in reverse order: !dlrow olleh
|
||||||
sequence in reverse order: !dlrow olleh
|
sequence in double-reversed (normal) order: hello world!
|
||||||
sequence in double-reversed (normal) order: hello world!
|
|
||||||
]
|
|
||||||
|
|
||||||
The source code for this example can be found
|
The source code for this example can be found
|
||||||
[example_link reverse_iterator_example.cpp..here].
|
[@../example/reverse_iterator_example.cpp here].
|
||||||
|
|
||||||
[h2 Reference]
|
[h2 Reference]
|
||||||
|
|
||||||
@ -114,8 +115,8 @@ operations.
|
|||||||
|
|
||||||
reverse_iterator();
|
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`
|
[*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator`
|
||||||
default constructed.
|
default constructed.
|
||||||
|
|
||||||
explicit reverse_iterator(Iterator x);
|
explicit reverse_iterator(Iterator x);
|
||||||
@ -130,8 +131,8 @@ operations.
|
|||||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
|
||||||
);
|
);
|
||||||
|
|
||||||
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
|
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.\n
|
||||||
[*Effects: ] Constructs instance of `reverse_iterator` whose
|
[*Effects: ] Constructs instance of `reverse_iterator` whose
|
||||||
`m_iterator` subobject is constructed from `y.base()`.
|
`m_iterator` subobject is constructed from `y.base()`.
|
||||||
|
|
||||||
|
|
||||||
@ -148,12 +149,12 @@ operations.
|
|||||||
|
|
||||||
reverse_iterator& operator++();
|
reverse_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `--m_iterator`[br]
|
[*Effects: ] `--m_iterator`\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
reverse_iterator& operator--();
|
reverse_iterator& operator--();
|
||||||
|
|
||||||
[*Effects: ] `++m_iterator`[br]
|
[*Effects: ] `++m_iterator`\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
[section:shared_container Shared Container Iterator]
|
[section:shared_container Shared Container Iterator]
|
||||||
|
|
||||||
Defined in header [@../../../boost/iterator/shared_container_iterator.hpp `boost/iterator/shared_container_iterator.hpp`].
|
Defined in header [@../../../boost/shared_container_iterator.hpp `boost/shared_container_iterator.hpp`].
|
||||||
|
|
||||||
The purpose of the shared container iterator is to attach the lifetime
|
The purpose of the shared container iterator is to attach the lifetime
|
||||||
of a container to the lifetime of its iterators. In other words, the
|
of a container to the lifetime of its iterators. In other words, the
|
||||||
@ -24,42 +25,20 @@ iterator.
|
|||||||
[h2 Synopsis]
|
[h2 Synopsis]
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace iterators {
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
class shared_container_iterator;
|
class shared_container_iterator;
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
shared_container_iterator<Container>
|
shared_container_iterator<Container>
|
||||||
make_shared_container_iterator(typename Container::iterator base,
|
make_shared_container_iterator(typename Container::iterator base,
|
||||||
std::shared_ptr<Container> const& container);
|
|
||||||
|
|
||||||
std::pair<
|
|
||||||
typename shared_container_iterator<Container>,
|
|
||||||
typename shared_container_iterator<Container>
|
|
||||||
>
|
|
||||||
make_shared_container_range(std::shared_ptr<Container> const& container);
|
|
||||||
|
|
||||||
// Backward compatibility with boost::shared_ptr
|
|
||||||
template <typename Container>
|
|
||||||
shared_container_iterator<Container>
|
|
||||||
make_shared_container_iterator(typename Container::iterator base,
|
|
||||||
boost::shared_ptr<Container> const& container);
|
boost::shared_ptr<Container> const& container);
|
||||||
|
|
||||||
std::pair<
|
std::pair<
|
||||||
typename shared_container_iterator<Container>,
|
typename shared_container_iterator<Container>,
|
||||||
typename shared_container_iterator<Container>
|
typename shared_container_iterator<Container>
|
||||||
>
|
>
|
||||||
make_shared_container_range(boost::shared_ptr<Container> const& container);
|
make_shared_container_range(boost::shared_ptr<Container> const& container);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[note `shared_container_iterator` and its factory functions support both
|
|
||||||
`std::shared_ptr` and `boost::shared_ptr` for a smart pointer that holds
|
|
||||||
a shared reference to the container. However, the support for `boost::shared_ptr`
|
|
||||||
comes at a cost of wrapping it in a `std::shared_ptr` internally. This means
|
|
||||||
that when constructing the iterator from a `boost::shared_ptr`, the construction
|
|
||||||
will have to allocate memory for `std::shared_ptr` shared state, which may
|
|
||||||
potentially fail. It is recommended to use `std::shared_ptr` directly.]
|
|
||||||
|
|
||||||
[section:shared_container_type The Shared Container Iterator Type]
|
[section:shared_container_type The Shared Container Iterator Type]
|
||||||
|
|
||||||
@ -67,7 +46,7 @@ potentially fail. It is recommended to use `std::shared_ptr` directly.]
|
|||||||
|
|
||||||
The class template `shared_container_iterator` is the shared container
|
The class template `shared_container_iterator` is the shared container
|
||||||
iterator type. The `Container` template type argument must model the
|
iterator type. The `Container` template type argument must model the
|
||||||
[@http://www.sgi.com/tech/stl/Container.html Container] concept.
|
[@http://www.sgi.com/tech/stl/Container.html Container] concept.
|
||||||
|
|
||||||
[h2 Example]
|
[h2 Example]
|
||||||
|
|
||||||
@ -77,48 +56,48 @@ original shared pointer `ints` ceases to exist after `set_range()`
|
|||||||
returns, the `shared_counter_iterator` objects maintain references to
|
returns, the `shared_counter_iterator` objects maintain references to
|
||||||
the underlying vector and thereby extend the container's lifetime.
|
the underlying vector and thereby extend the container's lifetime.
|
||||||
|
|
||||||
[example_link shared_iterator_example1.cpp..`shared_iterator_example1.cpp`]:
|
[@../../../libs/utility/shared_iterator_example1.cpp `shared_iterator_example1.cpp`]:
|
||||||
|
|
||||||
#include <boost/iterator/shared_container_iterator.hpp>
|
#include "shared_container_iterator.hpp"
|
||||||
|
#include "boost/shared_ptr.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
|
||||||
|
typedef boost::shared_container_iterator< std::vector<int> > iterator;
|
||||||
using iterator = boost::iterators::shared_container_iterator< std::vector<int> >;
|
|
||||||
|
|
||||||
|
void set_range(iterator& i, iterator& end) {
|
||||||
void set_range(iterator& i, iterator& end) {
|
|
||||||
std::shared_ptr< std::vector<int> > ints(new std::vector<int>());
|
boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
|
||||||
|
|
||||||
ints->push_back(0);
|
ints->push_back(0);
|
||||||
ints->push_back(1);
|
ints->push_back(1);
|
||||||
ints->push_back(2);
|
ints->push_back(2);
|
||||||
ints->push_back(3);
|
ints->push_back(3);
|
||||||
ints->push_back(4);
|
ints->push_back(4);
|
||||||
ints->push_back(5);
|
ints->push_back(5);
|
||||||
|
|
||||||
i = iterator(ints->begin(), ints);
|
i = iterator(ints->begin(),ints);
|
||||||
end = iterator(ints->end(), ints);
|
end = iterator(ints->end(),ints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
iterator i, end;
|
|
||||||
|
iterator i,end;
|
||||||
set_range(i, end);
|
|
||||||
|
set_range(i,end);
|
||||||
std::copy(i, end, std::ostream_iterator<int>(std::cout, ","));
|
|
||||||
|
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
|
||||||
std::cout.put('\n');
|
std::cout.put('\n');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
The output from this part is:
|
The output from this part is:
|
||||||
|
|
||||||
[pre
|
0,1,2,3,4,5,
|
||||||
0,1,2,3,4,5,
|
|
||||||
]
|
|
||||||
|
|
||||||
[table Template Parameters
|
[table Template Parameters
|
||||||
[[Parameter][Description]]
|
[[Parameter][Description]]
|
||||||
@ -136,12 +115,8 @@ The `shared_container_iterator` type implements the member functions
|
|||||||
and operators required of the
|
and operators required of the
|
||||||
[@http://www.sgi.com/tech/stl/RandomAccessIterator.html Random Access
|
[@http://www.sgi.com/tech/stl/RandomAccessIterator.html Random Access
|
||||||
Iterator] concept, though only operations defined for the base
|
Iterator] concept, though only operations defined for the base
|
||||||
iterator will be valid. In addition it has the following constructors:
|
iterator will be valid. In addition it has the following constructor:
|
||||||
|
|
||||||
shared_container_iterator(Container::iterator const& it,
|
|
||||||
std::shared_ptr<Container> const& container)
|
|
||||||
|
|
||||||
// Backward compatibility with boost::shared_ptr
|
|
||||||
shared_container_iterator(Container::iterator const& it,
|
shared_container_iterator(Container::iterator const& it,
|
||||||
boost::shared_ptr<Container> const& container)
|
boost::shared_ptr<Container> const& container)
|
||||||
|
|
||||||
@ -149,60 +124,58 @@ iterator will be valid. In addition it has the following constructors:
|
|||||||
|
|
||||||
[section:shared_container_object_generator The Shared Container Iterator Object Generator]
|
[section:shared_container_object_generator The Shared Container Iterator Object Generator]
|
||||||
|
|
||||||
template <typename Container>
|
|
||||||
shared_container_iterator<Container>
|
|
||||||
make_shared_container_iterator(Container::iterator base,
|
|
||||||
std::shared_ptr<Container> const& container)
|
|
||||||
|
|
||||||
// Backward compatibility with boost::shared_ptr
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
shared_container_iterator<Container>
|
shared_container_iterator<Container>
|
||||||
make_shared_container_iterator(Container::iterator base,
|
make_shared_container_iterator(Container::iterator base,
|
||||||
boost::shared_ptr<Container> const& container)
|
boost::shared_ptr<Container> const& container)
|
||||||
|
|
||||||
This function provides an alternative to directly constructing a
|
This function provides an alternative to directly constructing a
|
||||||
`shared_container_iterator`. Using the object generator, a
|
`shared_container_iterator`. Using the object generator, a
|
||||||
`shared_container_iterator` can be created and passed to a function without
|
`shared_container_iterator` can be created and passed to a function without
|
||||||
explicitly specifying its type.
|
explicitly specifying its type.
|
||||||
|
|
||||||
[h2 Example]
|
[h2 Example]
|
||||||
|
|
||||||
This example, similar to the previous,
|
This example, similar to the previous,
|
||||||
uses `make_shared_container_iterator()` to create the iterators.
|
uses `make_shared_container_iterator()` to create the iterators.
|
||||||
|
|
||||||
[example_link shared_iterator_example2.cpp..`shared_iterator_example2.cpp`]:
|
[@../../../libs/utility/shared_iterator_example2.cpp `shared_iterator_example2.cpp`]:
|
||||||
|
|
||||||
#include <boost/iterator/shared_container_iterator.hpp>
|
#include "shared_container_iterator.hpp"
|
||||||
|
#include "boost/shared_ptr.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
void print_range_nl(Iterator begin, Iterator end) {
|
void print_range_nl (Iterator begin, Iterator end) {
|
||||||
using val = typename std::iterator_traits<Iterator>::value_type;
|
typedef typename std::iterator_traits<Iterator>::value_type val;
|
||||||
std::copy(begin, end, std::ostream_iterator<val>(std::cout, ","));
|
std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
|
||||||
std::cout.put('\n');
|
std::cout.put('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
using ints_t = std::shared_ptr< std::vector<int> >;
|
|
||||||
|
typedef boost::shared_ptr< std::vector<int> > ints_t;
|
||||||
{
|
{
|
||||||
ints_t ints(new std::vector<int>());
|
ints_t ints(new std::vector<int>());
|
||||||
|
|
||||||
ints->push_back(0);
|
ints->push_back(0);
|
||||||
ints->push_back(1);
|
ints->push_back(1);
|
||||||
ints->push_back(2);
|
ints->push_back(2);
|
||||||
ints->push_back(3);
|
ints->push_back(3);
|
||||||
ints->push_back(4);
|
ints->push_back(4);
|
||||||
ints->push_back(5);
|
ints->push_back(5);
|
||||||
|
|
||||||
print_range_nl(boost::iterators::make_shared_container_iterator(ints->begin(), ints),
|
print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
|
||||||
boost::iterators::make_shared_container_iterator(ints->end(), ints));
|
boost::make_shared_container_iterator(ints->end(),ints));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,63 +186,55 @@ named. The output from this example is the same as the previous.
|
|||||||
|
|
||||||
[section:shared_container_generator The Shared Container Iterator Range Generator]
|
[section:shared_container_generator The Shared Container Iterator Range Generator]
|
||||||
|
|
||||||
template <typename Container>
|
|
||||||
std::pair<
|
|
||||||
shared_container_iterator<Container>,
|
|
||||||
shared_container_iterator<Container>
|
|
||||||
>
|
|
||||||
make_shared_container_range(std::shared_ptr<Container> const& container);
|
|
||||||
|
|
||||||
// Backward compatibility with boost::shared_ptr
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
std::pair<
|
std::pair<
|
||||||
shared_container_iterator<Container>,
|
shared_container_iterator<Container>,
|
||||||
shared_container_iterator<Container>
|
shared_container_iterator<Container>
|
||||||
>
|
>
|
||||||
make_shared_container_range(boost::shared_ptr<Container> const& container);
|
make_shared_container_range(boost::shared_ptr<Container> const& container);
|
||||||
|
Class shared_container_iterator is meant primarily to return, using iterators, a range of values that we can guarantee will be alive as long as the iterators are. This is a convenience function to do just that. It is equivalent to
|
||||||
Class `shared_container_iterator` is meant primarily to return, using iterators,
|
std::make_pair(make_shared_container_iterator(container->begin(),container),
|
||||||
a range of values that we can guarantee will be alive as long as the iterators are.
|
make_shared_container_iterator(container->end(),container));
|
||||||
This is a convenience function to do just that. It is functionally equivalent to this:
|
|
||||||
|
|
||||||
std::make_pair(make_shared_container_iterator(container->begin(), container),
|
|
||||||
make_shared_container_iterator(container->end(), container));
|
|
||||||
|
|
||||||
[h2 Example]
|
[h2 Example]
|
||||||
|
|
||||||
In the following example, a range of values is returned as a pair of `shared_container_iterator` objects.
|
In the following example, a range of values is returned as a pair of shared_container_iterator objects.
|
||||||
|
|
||||||
[example_link shared_iterator_example3.cpp..`shared_iterator_example3.cpp`]:
|
[@../../../libs/utility/shared_iterator_example3.cpp `shared_iterator_example3.cpp`]:
|
||||||
|
|
||||||
#include <boost/iterator/shared_container_iterator.hpp>
|
#include "shared_container_iterator.hpp"
|
||||||
#include <algorithm> // for std::copy
|
#include "boost/shared_ptr.hpp"
|
||||||
#include <iostream>
|
#include "boost/tuple/tuple.hpp" // for boost::tie
|
||||||
|
#include <algorithm> // for std::copy
|
||||||
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
|
||||||
#include <tuple> // for std::tie
|
|
||||||
|
typedef boost::shared_container_iterator< std::vector<int> > iterator;
|
||||||
|
|
||||||
using iterator = boost::iterators::shared_container_iterator< std::vector<int> >;
|
std::pair<iterator,iterator>
|
||||||
|
|
||||||
std::pair<iterator, iterator>
|
|
||||||
return_range() {
|
return_range() {
|
||||||
std::shared_ptr< std::vector<int> > range(new std::vector<int>());
|
boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
|
||||||
range->push_back(0);
|
range->push_back(0);
|
||||||
range->push_back(1);
|
range->push_back(1);
|
||||||
range->push_back(2);
|
range->push_back(2);
|
||||||
range->push_back(3);
|
range->push_back(3);
|
||||||
range->push_back(4);
|
range->push_back(4);
|
||||||
range->push_back(5);
|
range->push_back(5);
|
||||||
return boost::iterators::make_shared_container_range(range);
|
return boost::make_shared_container_range(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
|
|
||||||
iterator i,end;
|
iterator i,end;
|
||||||
std::tie(i, end) = return_range();
|
|
||||||
|
boost::tie(i,end) = return_range();
|
||||||
std::copy(i, end, std::ostream_iterator<int>(std::cout, ","));
|
|
||||||
|
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
|
||||||
std::cout.put('\n');
|
std::cout.put('\n');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,4 +245,4 @@ the same as the previous two.
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:specialized Specialized Adaptors]
|
[section:specialized Specialized Adaptors]
|
||||||
|
|
||||||
[include ./counting_iterator.qbk]
|
[include ./counting_iterator.qbk]
|
||||||
@ -18,4 +19,4 @@
|
|||||||
|
|
||||||
[include ./zip_iterator.qbk]
|
[include ./zip_iterator.qbk]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
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]
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
[section:transform Transform Iterator]
|
[section:transform Transform Iterator]
|
||||||
|
|
||||||
The transform iterator adapts an iterator by modifying the
|
The transform iterator adapts an iterator by modifying the
|
||||||
@ -13,38 +14,37 @@ generate iterators that multiply (or add to) the value returned by
|
|||||||
dereferencing the iterator. It would be cooler to use lambda library
|
dereferencing the iterator. It would be cooler to use lambda library
|
||||||
in this example.
|
in this example.
|
||||||
|
|
||||||
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||||
const int N = sizeof(x)/sizeof(int);
|
const int N = sizeof(x)/sizeof(int);
|
||||||
|
|
||||||
typedef boost::binder1st< std::multiplies<int> > Function;
|
typedef boost::binder1st< std::multiplies<int> > Function;
|
||||||
typedef boost::transform_iterator<Function, int*> doubling_iterator;
|
typedef boost::transform_iterator<Function, int*> doubling_iterator;
|
||||||
|
|
||||||
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
|
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
|
||||||
i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
|
i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
|
||||||
|
|
||||||
std::cout << "multiplying the array by 2:" << std::endl;
|
std::cout << "multiplying the array by 2:" << std::endl;
|
||||||
while (i != i_end)
|
while (i != i_end)
|
||||||
std::cout << *i++ << " ";
|
std::cout << *i++ << " ";
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::cout << "adding 4 to each element in the array:" << std::endl;
|
std::cout << "adding 4 to each element in the array:" << std::endl;
|
||||||
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
|
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
|
||||||
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
|
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
|
||||||
std::ostream_iterator<int>(std::cout, " "));
|
std::ostream_iterator<int>(std::cout, " "));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
||||||
The output is:
|
The output is:
|
||||||
|
|
||||||
[pre
|
multiplying the array by 2:
|
||||||
multiplying the array by 2:
|
2 4 6 8 10 12 14 16
|
||||||
2 4 6 8 10 12 14 16
|
adding 4 to each element in the array:
|
||||||
adding 4 to each element in the array:
|
5 6 7 8 9 10 11 12
|
||||||
5 6 7 8 9 10 11 12
|
|
||||||
]
|
|
||||||
|
|
||||||
The source code for this example can be found
|
|
||||||
[example_link transform_iterator_example.cpp..here].
|
The source code for this example can be found
|
||||||
|
[@../example/transform_iterator_example.cpp here].
|
||||||
|
|
||||||
[h2 Reference]
|
[h2 Reference]
|
||||||
|
|
||||||
@ -52,8 +52,8 @@ The source code for this example can be found
|
|||||||
[h3 Synopsis]
|
[h3 Synopsis]
|
||||||
|
|
||||||
template <class UnaryFunction,
|
template <class UnaryFunction,
|
||||||
class Iterator,
|
class Iterator,
|
||||||
class Reference = use_default,
|
class Reference = use_default,
|
||||||
class Value = use_default>
|
class Value = use_default>
|
||||||
class transform_iterator
|
class transform_iterator
|
||||||
{
|
{
|
||||||
@ -85,8 +85,8 @@ The source code for this example can be found
|
|||||||
|
|
||||||
|
|
||||||
If `Reference` is `use_default` then the `reference` member of
|
If `Reference` is `use_default` then the `reference` member of
|
||||||
`transform_iterator` is[br]
|
`transform_iterator` is\n
|
||||||
`result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
|
`result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
|
||||||
Otherwise, `reference` is `Reference`.
|
Otherwise, `reference` is `Reference`.
|
||||||
|
|
||||||
|
|
||||||
@ -110,13 +110,13 @@ convertible to `input_iterator_tag`.
|
|||||||
|
|
||||||
|
|
||||||
The type `UnaryFunction` must be Assignable, Copy Constructible, and
|
The type `UnaryFunction` must be Assignable, Copy Constructible, and
|
||||||
the expression `f(*i)` must be valid where `f` is 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
|
type `UnaryFunction`, `i` is an object of type `Iterator`, and
|
||||||
where the type of `f(*i)` must be
|
where the type of `f(*i)` must be
|
||||||
`result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
|
`result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
|
||||||
|
|
||||||
|
|
||||||
The argument `Iterator` shall model Readable Iterator.
|
The argument `Iterator` shall model Readable Iterator.
|
||||||
|
|
||||||
|
|
||||||
[h3 Concepts]
|
[h3 Concepts]
|
||||||
@ -126,11 +126,11 @@ The resulting `transform_iterator` models the most refined of the
|
|||||||
following that is also modeled by `Iterator`.
|
following that is also modeled by `Iterator`.
|
||||||
|
|
||||||
|
|
||||||
* Writable Lvalue Iterator if `transform_iterator::reference` is a non-const reference.
|
* Writable Lvalue Iterator if `transform_iterator::reference` is a non-const reference.
|
||||||
|
|
||||||
* Readable Lvalue Iterator if `transform_iterator::reference` is a const reference.
|
* Readable Lvalue Iterator if `transform_iterator::reference` is a const reference.
|
||||||
|
|
||||||
* Readable Iterator otherwise.
|
* Readable Iterator otherwise.
|
||||||
|
|
||||||
|
|
||||||
The `transform_iterator` models the most refined standard traversal
|
The `transform_iterator` models the most refined standard traversal
|
||||||
@ -143,11 +143,11 @@ the `Iterator` argument models.
|
|||||||
|
|
||||||
|
|
||||||
[table Category
|
[table Category
|
||||||
[[If `Iterator` models][then `transform_iterator` models]]
|
[[If `Iterator` models][then `transform_iterator` models]]
|
||||||
[[Single Pass Iterator][Input Iterator]]
|
[[Single Pass Iterator][Input Iterator]]
|
||||||
[[Forward Traversal Iterator][Forward Iterator]]
|
[[Forward Traversal Iterator][Forward Iterator]]
|
||||||
[[Bidirectional Traversal Iterator][Bidirectional Iterator]]
|
[[Bidirectional Traversal Iterator][Bidirectional Iterator]]
|
||||||
[[Random Access Traversal Iterator][Random Access Iterator]]
|
[[Random Access Traversal Iterator][Random Access Iterator]]
|
||||||
]
|
]
|
||||||
|
|
||||||
If `transform_iterator` models Writable Lvalue Iterator then it is a
|
If `transform_iterator` models Writable Lvalue Iterator then it is a
|
||||||
@ -160,7 +160,7 @@ interoperable with `Y`.
|
|||||||
|
|
||||||
[h3 Operations]
|
[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
|
`transform_iterator`, `transform_iterator` provides the following
|
||||||
operations:
|
operations:
|
||||||
|
|
||||||
@ -177,13 +177,13 @@ operations:
|
|||||||
template<class F2, class I2, class R2, class V2>
|
template<class F2, class I2, class R2, class V2>
|
||||||
transform_iterator(
|
transform_iterator(
|
||||||
transform_iterator<F2, I2, R2, V2> const& t
|
transform_iterator<F2, I2, R2, V2> const& t
|
||||||
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
|
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
|
||||||
, typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
|
, typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
|
||||||
);
|
);
|
||||||
|
|
||||||
[*Returns: ] An instance of `transform_iterator` with `m_f`
|
[*Returns: ] An instance of `transform_iterator` with `m_f`
|
||||||
initialized to `t.functor()` and `m_iterator` initialized to
|
initialized to `t.functor()` and `m_iterator` initialized to
|
||||||
`t.base()`.[br]
|
`t.base()`.\n
|
||||||
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.
|
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.
|
||||||
|
|
||||||
|
|
||||||
@ -204,13 +204,13 @@ operations:
|
|||||||
|
|
||||||
transform_iterator& operator++();
|
transform_iterator& operator++();
|
||||||
|
|
||||||
[*Effects: ] `++m_iterator`[br]
|
[*Effects: ] `++m_iterator`\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
|
|
||||||
transform_iterator& operator--();
|
transform_iterator& operator--();
|
||||||
|
|
||||||
[*Effects: ] `--m_iterator`[br]
|
[*Effects: ] `--m_iterator`\n
|
||||||
[*Returns: ] `*this`
|
[*Returns: ] `*this`
|
||||||
|
|
||||||
[endsect]
|
[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 `min_category`]
|
|
||||||
|
|
||||||
`min_category` takes one or more iterator categories or iterator traversal tags
|
|
||||||
and returns the one that is the weakest (i.e. least advanced). For example:
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
is_same<
|
|
||||||
min_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]
|
@ -1,29 +1,20 @@
|
|||||||
|
|
||||||
[section:zip Zip Iterator]
|
[section:zip Zip Iterator]
|
||||||
|
|
||||||
The zip iterator provides the ability to parallel-iterate
|
The zip iterator provides the ability to parallel-iterate
|
||||||
over several controlled sequences simultaneously. A zip
|
over several controlled sequences simultaneously. A zip
|
||||||
iterator is constructed from a tuple of iterators. Moving
|
iterator is constructed from a tuple of iterators. Moving
|
||||||
the zip iterator moves all the iterators in parallel.
|
the zip iterator moves all the iterators in parallel.
|
||||||
Dereferencing the zip iterator returns a tuple that contains
|
Dereferencing the zip iterator returns a tuple that contains
|
||||||
the results of dereferencing the individual iterators.
|
the results of dereferencing the individual iterators.
|
||||||
|
|
||||||
The tuple of iterators is now implemented in terms of a Boost fusion sequence.
|
|
||||||
Because of this the 'tuple' may be any Boost fusion sequence and, for backwards
|
|
||||||
compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
|
|
||||||
'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
|
|
||||||
Boost fusion adapter exists. This includes, among others, a std::tuple and a std::pair.
|
|
||||||
Just remember to include the appropriate Boost fusion adapter header files for these
|
|
||||||
other Boost fusion adapters. The zip_iterator header file already includes the
|
|
||||||
Boost fusion adapter header file for Boost tuple, so you need not include it yourself
|
|
||||||
to use a Boost tuple as your 'tuple'.
|
|
||||||
|
|
||||||
[section:zip_example Example]
|
[section:zip_example Example]
|
||||||
|
|
||||||
There are two main types of applications of the `zip_iterator`. The first
|
There are two main types of applications of the `zip_iterator`. The first
|
||||||
one concerns runtime efficiency: If one has several controlled sequences
|
one concerns runtime efficiency: If one has several controlled sequences
|
||||||
of the same length that must be somehow processed, e.g., with the
|
of the same length that must be somehow processed, e.g., with the
|
||||||
`for_each` algorithm, then it is more efficient to perform just
|
`for_each` algorithm, then it is more efficient to perform just
|
||||||
one parallel-iteration rather than several individual iterations. For an
|
one parallel-iteration rather than several individual iterations. For an
|
||||||
example, assume that `vect_of_doubles` and `vect_of_ints`
|
example, assume that `vect_of_doubles` and `vect_of_ints`
|
||||||
are two vectors of equal length containing doubles and ints, respectively,
|
are two vectors of equal length containing doubles and ints, respectively,
|
||||||
and consider the following two iterations:
|
and consider the following two iterations:
|
||||||
@ -52,10 +43,9 @@ These two iterations can now be replaced with a single one as follows:
|
|||||||
A non-generic implementation of `zip_func` could look as follows:
|
A non-generic implementation of `zip_func` could look as follows:
|
||||||
|
|
||||||
|
|
||||||
struct zip_func
|
struct zip_func :
|
||||||
|
public std::unary_function<const boost::tuple<const double&, const int&>&, void>
|
||||||
{
|
{
|
||||||
using result_type = void;
|
|
||||||
|
|
||||||
void operator()(const boost::tuple<const double&, const int&>& t) const
|
void operator()(const boost::tuple<const double&, const int&>& t) const
|
||||||
{
|
{
|
||||||
m_f0(t.get<0>());
|
m_f0(t.get<0>());
|
||||||
@ -72,16 +62,16 @@ to make combining iterators. A combining iterator is an iterator
|
|||||||
that parallel-iterates over several controlled sequences and, upon
|
that parallel-iterates over several controlled sequences and, upon
|
||||||
dereferencing, returns the result of applying a functor to the values of the
|
dereferencing, returns the result of applying a functor to the values of the
|
||||||
sequences at the respective positions. This can now be achieved by using the
|
sequences at the respective positions. This can now be achieved by using the
|
||||||
`zip_iterator` in conjunction with the `transform_iterator`.
|
`zip_iterator` in conjunction with the `transform_iterator`.
|
||||||
|
|
||||||
Suppose, for example, that you have two vectors of doubles, say
|
Suppose, for example, that you have two vectors of doubles, say
|
||||||
`vect_1` and `vect_2`, and you need to expose to a client
|
`vect_1` and `vect_2`, and you need to expose to a client
|
||||||
a controlled sequence containing the products of the elements of
|
a controlled sequence containing the products of the elements of
|
||||||
`vect_1` and `vect_2`. Rather than placing these products
|
`vect_1` and `vect_2`. Rather than placing these products
|
||||||
in a third vector, you can use a combining iterator that calculates the
|
in a third vector, you can use a combining iterator that calculates the
|
||||||
products on the fly. Let us assume that `tuple_multiplies` is a
|
products on the fly. Let us assume that `tuple_multiplies` is a
|
||||||
functor that works like `std::multiplies`, except that it takes
|
functor that works like `std::multiplies`, except that it takes
|
||||||
its two arguments packaged in a tuple. Then the two iterators
|
its two arguments packaged in a tuple. Then the two iterators
|
||||||
`it_begin` and `it_end` defined below delimit a controlled
|
`it_begin` and `it_end` defined below delimit a controlled
|
||||||
sequence containing the products of the elements of `vect_1` and
|
sequence containing the products of the elements of `vect_1` and
|
||||||
`vect_2`:
|
`vect_2`:
|
||||||
@ -128,7 +118,7 @@ sequence containing the products of the elements of `vect_1` and
|
|||||||
|
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
class zip_iterator
|
class zip_iterator
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef /* see below */ reference;
|
typedef /* see below */ reference;
|
||||||
@ -154,8 +144,8 @@ sequence containing the products of the elements of `vect_1` and
|
|||||||
IteratorTuple m_iterator_tuple; // exposition only
|
IteratorTuple m_iterator_tuple; // exposition only
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
zip_iterator<IteratorTuple>
|
zip_iterator<IteratorTuple>
|
||||||
make_zip_iterator(IteratorTuple t);
|
make_zip_iterator(IteratorTuple t);
|
||||||
|
|
||||||
The `reference` member of `zip_iterator` is the type of the tuple
|
The `reference` member of `zip_iterator` is the type of the tuple
|
||||||
@ -168,23 +158,23 @@ of the first of the iterator types in the `IteratorTuple` argument.
|
|||||||
The `iterator_category` member of `zip_iterator` is convertible to the
|
The `iterator_category` member of `zip_iterator` is convertible to the
|
||||||
minimum of the traversal categories of the iterator types in the `IteratorTuple`
|
minimum of the traversal categories of the iterator types in the `IteratorTuple`
|
||||||
argument. For example, if the `zip_iterator` holds only vector
|
argument. For example, if the `zip_iterator` holds only vector
|
||||||
iterators, then `iterator_category` is convertible to
|
iterators, then `iterator_category` is convertible to
|
||||||
`boost::random_access_traversal_tag`. If you add a list iterator, then
|
`boost::random_access_traversal_tag`. If you add a list iterator, then
|
||||||
`iterator_category` will be convertible to `boost::bidirectional_traversal_tag`,
|
`iterator_category` will be convertible to `boost::bidirectional_traversal_tag`,
|
||||||
but no longer to `boost::random_access_traversal_tag`.
|
but no longer to `boost::random_access_traversal_tag`.
|
||||||
|
|
||||||
[h2 Requirements]
|
[h2 Requirements]
|
||||||
|
|
||||||
All iterator types in the argument `IteratorTuple` shall model Readable Iterator.
|
All iterator types in the argument `IteratorTuple` shall model Readable Iterator.
|
||||||
|
|
||||||
[h2 Concepts]
|
[h2 Concepts]
|
||||||
|
|
||||||
The resulting `zip_iterator` models Readable Iterator.
|
The resulting `zip_iterator` models Readable Iterator.
|
||||||
|
|
||||||
The fact that the `zip_iterator` models only Readable Iterator does not
|
The fact that the `zip_iterator` models only Readable Iterator does not
|
||||||
prevent you from modifying the values that the individual iterators point
|
prevent you from modifying the values that the individual iterators point
|
||||||
to. The tuple returned by the `zip_iterator`'s `operator*` is a tuple
|
to. The tuple returned by the `zip_iterator`'s `operator*` is a tuple
|
||||||
constructed from the reference types of the individual iterators, not
|
constructed from the reference types of the individual iterators, not
|
||||||
their value types. For example, if `zip_it` is a `zip_iterator` whose
|
their value types. For example, if `zip_it` is a `zip_iterator` whose
|
||||||
first member iterator is an `std::vector<double>::iterator`, then the
|
first member iterator is an `std::vector<double>::iterator`, then the
|
||||||
following line will modify the value which the first member iterator of
|
following line will modify the value which the first member iterator of
|
||||||
@ -195,7 +185,7 @@ following line will modify the value which the first member iterator of
|
|||||||
|
|
||||||
Consider the set of standard traversal concepts obtained by taking
|
Consider the set of standard traversal concepts obtained by taking
|
||||||
the most refined standard traversal concept modeled by each individual
|
the most refined standard traversal concept modeled by each individual
|
||||||
iterator type in the `IteratorTuple` argument.The `zip_iterator`
|
iterator type in the `IteratorTuple` argument.The `zip_iterator`
|
||||||
models the least refined standard traversal concept in this set.
|
models the least refined standard traversal concept in this set.
|
||||||
|
|
||||||
`zip_iterator<IteratorTuple1>` is interoperable with
|
`zip_iterator<IteratorTuple1>` is interoperable with
|
||||||
@ -228,7 +218,7 @@ operations.
|
|||||||
, IteratorTuple>::type* = 0 // exposition only
|
, 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`.
|
[*Requires:] `OtherIteratorTuple` is implicitly convertible to `IteratorTuple`.
|
||||||
|
|
||||||
|
|
||||||
@ -245,17 +235,17 @@ operations.
|
|||||||
|
|
||||||
zip_iterator& operator++();
|
zip_iterator& operator++();
|
||||||
|
|
||||||
[*Effects:] Increments each iterator in `m_iterator_tuple`.[br]
|
[*Effects:] Increments each iterator in `m_iterator_tuple`.\n
|
||||||
[*Returns:] `*this`
|
[*Returns:] `*this`
|
||||||
|
|
||||||
|
|
||||||
zip_iterator& operator--();
|
zip_iterator& operator--();
|
||||||
|
|
||||||
[*Effects:] Decrements each iterator in `m_iterator_tuple`.[br]
|
[*Effects:] Decrements each iterator in `m_iterator_tuple`.\n
|
||||||
[*Returns:] `*this`
|
[*Returns:] `*this`
|
||||||
|
|
||||||
template<typename IteratorTuple>
|
template<typename IteratorTuple>
|
||||||
zip_iterator<IteratorTuple>
|
zip_iterator<IteratorTuple>
|
||||||
make_zip_iterator(IteratorTuple t);
|
make_zip_iterator(IteratorTuple t);
|
||||||
|
|
||||||
[*Returns:] An instance of `zip_iterator<IteratorTuple>` with `m_iterator_tuple`
|
[*Returns:] An instance of `zip_iterator<IteratorTuple>` with `m_iterator_tuple`
|
||||||
@ -263,4 +253,4 @@ operations.
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
@ -3,11 +3,12 @@
|
|||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
.. _N1550: http://www.boost-consulting.com/writing/n1550.html
|
.. _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
|
:Author: David Abrahams and Jeremy Siek
|
||||||
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu
|
||||||
:Organization: `Boost Consulting`_, Indiana University Bloomington
|
:Organization: `Boost Consulting`_, Indiana University Bloomington
|
||||||
|
:date: $Date$
|
||||||
:Copyright: Copyright David Abrahams, Jeremy Siek 2003. Use, modification and
|
:Copyright: Copyright David Abrahams, Jeremy Siek 2003. Use, modification and
|
||||||
distribution is subject to the Boost Software License,
|
distribution is subject to the Boost Software License,
|
||||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
|
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, University of Hanover `Institute for Transport
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
Railway Operation and Construction`_
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -99,7 +99,7 @@ private:
|
|||||||
</pre>
|
</pre>
|
||||||
<p>If <tt class="docutils literal"><span class="pre">Reference</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">reference</span></tt> member of
|
<p>If <tt class="docutils literal"><span class="pre">Reference</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">reference</span></tt> member of
|
||||||
<tt class="docutils literal"><span class="pre">transform_iterator</span></tt> is
|
<tt class="docutils literal"><span class="pre">transform_iterator</span></tt> is
|
||||||
<tt class="docutils literal"><span class="pre">result_of<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>
|
Otherwise, <tt class="docutils literal"><span class="pre">reference</span></tt> is <tt class="docutils literal"><span class="pre">Reference</span></tt>.</p>
|
||||||
<p>If <tt class="docutils literal"><span class="pre">Value</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">value_type</span></tt> member is
|
<p>If <tt class="docutils literal"><span class="pre">Value</span></tt> is <tt class="docutils literal"><span class="pre">use_default</span></tt> then the <tt class="docutils literal"><span class="pre">value_type</span></tt> member is
|
||||||
<tt class="docutils literal"><span class="pre">remove_cv<remove_reference<reference></span> <span class="pre">>::type</span></tt>. Otherwise,
|
<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">
|
<div class="section" id="transform-iterator-requirements">
|
||||||
<h1><a class="toc-backref" href="#id3"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
|
<h1><a class="toc-backref" href="#id3"><tt class="docutils literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
|
||||||
<p>The type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and
|
<p>The type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and
|
||||||
the expression <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be valid where <tt class="docutils literal"><span class="pre">f</span></tt> is 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
|
type <tt class="docutils literal"><span class="pre">UnaryFunction</span></tt>, <tt class="docutils literal"><span class="pre">i</span></tt> is an object of type <tt class="docutils literal"><span class="pre">Iterator</span></tt>, and
|
||||||
where the type of <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be
|
where the type of <tt class="docutils literal"><span class="pre">f(*i)</span></tt> must be
|
||||||
<tt class="docutils literal"><span class="pre">result_of<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>
|
<p>The argument <tt class="docutils literal"><span class="pre">Iterator</span></tt> shall model Readable Iterator.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="transform-iterator-models">
|
<div class="section" id="transform-iterator-models">
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
:organization: `Boost Consulting`_, Indiana University `Open Systems
|
||||||
Lab`_, University of Hanover `Institute for Transport
|
Lab`_, University of Hanover `Institute for Transport
|
||||||
Railway Operation and Construction`_
|
Railway Operation and Construction`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
:copyright: Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
If ``Reference`` is ``use_default`` then the ``reference`` member of
|
If ``Reference`` is ``use_default`` then the ``reference`` member of
|
||||||
``transform_iterator`` is
|
``transform_iterator`` is
|
||||||
``result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
|
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
|
||||||
Otherwise, ``reference`` is ``Reference``.
|
Otherwise, ``reference`` is ``Reference``.
|
||||||
|
|
||||||
If ``Value`` is ``use_default`` then the ``value_type`` member is
|
If ``Value`` is ``use_default`` then the ``value_type`` member is
|
||||||
@ -64,10 +64,10 @@ convertible to ``input_iterator_tag``.
|
|||||||
...................................
|
...................................
|
||||||
|
|
||||||
The type ``UnaryFunction`` must be Assignable, Copy Constructible, and
|
The type ``UnaryFunction`` must be Assignable, Copy Constructible, and
|
||||||
the expression ``f(*i)`` must be valid where ``f`` is 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
|
type ``UnaryFunction``, ``i`` is an object of type ``Iterator``, and
|
||||||
where the type of ``f(*i)`` must be
|
where the type of ``f(*i)`` must be
|
||||||
``result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
|
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
|
||||||
|
|
||||||
The argument ``Iterator`` shall model Readable Iterator.
|
The argument ``Iterator`` shall model Readable Iterator.
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
:Author: David Abrahams, Thomas Becker
|
:Author: David Abrahams, Thomas Becker
|
||||||
:Contact: dave@boost-consulting.com, thomas@styleadvisor.com
|
:Contact: dave@boost-consulting.com, thomas@styleadvisor.com
|
||||||
:organization: `Boost Consulting`_, `Zephyr Associates, Inc.`_
|
:organization: `Boost Consulting`_, `Zephyr Associates, Inc.`_
|
||||||
|
:date: $Date$
|
||||||
:copyright: Copyright David Abrahams and Thomas Becker 2003.
|
:copyright: Copyright David Abrahams and Thomas Becker 2003.
|
||||||
|
|
||||||
.. _`Boost Consulting`: http://www.boost-consulting.com
|
.. _`Boost Consulting`: http://www.boost-consulting.com
|
||||||
|
@ -8,13 +8,3 @@ iterator is constructed from a tuple of iterators. Moving
|
|||||||
the zip iterator moves all the iterators in parallel.
|
the zip iterator moves all the iterators in parallel.
|
||||||
Dereferencing the zip iterator returns a tuple that contains
|
Dereferencing the zip iterator returns a tuple that contains
|
||||||
the results of dereferencing the individual iterators.
|
the results of dereferencing the individual iterators.
|
||||||
|
|
||||||
The tuple of iterators is now implemented in terms of a Boost fusion sequence.
|
|
||||||
Because of this the 'tuple' may be any Boost fusion sequence and, for backwards
|
|
||||||
compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
|
|
||||||
'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
|
|
||||||
Boost fusion adapter exists. This includes, among others, a std::tuple and a std::pair.
|
|
||||||
Just remember to include the appropriate Boost fusion adapter header files for these
|
|
||||||
other Boost fusion adapters. The zip_iterator header file already includes the
|
|
||||||
Boost fusion adapter header file for Boost tuple, so you need not include it yourself
|
|
||||||
to use a Boost tuple as your 'tuple'.
|
|
||||||
|
@ -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
|
void operator()(const boost::tuple<const double&, const int&>& t) const
|
||||||
{
|
{
|
||||||
|
@ -41,12 +41,12 @@ int main(int, char*[])
|
|||||||
|
|
||||||
// Use indirect iterator to print out numbers by accessing
|
// Use indirect iterator to print out numbers by accessing
|
||||||
// them through the array of pointers.
|
// them through the array of pointers.
|
||||||
std::cout << "indirectly printing out the numbers from 0 to "
|
std::cout << "indirectly printing out the numbers from 0 to "
|
||||||
<< N << std::endl;
|
<< N << std::endl;
|
||||||
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
||||||
boost::make_indirect_iterator(pointers.end()),
|
boost::make_indirect_iterator(pointers.end()),
|
||||||
std::ostream_iterator<int>(std::cout, " "));
|
std::ostream_iterator<int>(std::cout, " "));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
return boost::exit_success;
|
return boost::exit_success;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/iterator/filter_iterator.hpp>
|
#include <boost/iterator/filter_iterator.hpp>
|
||||||
#include <boost/bind/bind.hpp>
|
|
||||||
#include <boost/cstdlib.hpp> // for exit_success
|
#include <boost/cstdlib.hpp> // for exit_success
|
||||||
|
|
||||||
struct is_positive_number {
|
struct is_positive_number {
|
||||||
@ -19,10 +18,10 @@ int main()
|
|||||||
{
|
{
|
||||||
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
|
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||||
const int N = sizeof(numbers_)/sizeof(int);
|
const int N = sizeof(numbers_)/sizeof(int);
|
||||||
|
|
||||||
typedef int* base_iterator;
|
typedef int* base_iterator;
|
||||||
base_iterator numbers(numbers_);
|
base_iterator numbers(numbers_);
|
||||||
|
|
||||||
// Example using make_filter_iterator()
|
// Example using make_filter_iterator()
|
||||||
std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
|
std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
|
||||||
boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
|
boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
|
||||||
@ -32,7 +31,7 @@ int main()
|
|||||||
// Example using filter_iterator
|
// Example using filter_iterator
|
||||||
typedef boost::filter_iterator<is_positive_number, base_iterator>
|
typedef boost::filter_iterator<is_positive_number, base_iterator>
|
||||||
FilterIter;
|
FilterIter;
|
||||||
|
|
||||||
is_positive_number predicate;
|
is_positive_number predicate;
|
||||||
FilterIter filter_iter_first(predicate, numbers, numbers + N);
|
FilterIter filter_iter_first(predicate, numbers, numbers + N);
|
||||||
FilterIter filter_iter_last(predicate, numbers + N, numbers + N);
|
FilterIter filter_iter_last(predicate, numbers + N, numbers + N);
|
||||||
@ -43,17 +42,17 @@ int main()
|
|||||||
// Another example using make_filter_iterator()
|
// Another example using make_filter_iterator()
|
||||||
std::copy(
|
std::copy(
|
||||||
boost::make_filter_iterator(
|
boost::make_filter_iterator(
|
||||||
boost::bind(std::greater<int>(), boost::placeholders::_1, -2)
|
std::bind2nd(std::greater<int>(), -2)
|
||||||
, numbers, numbers + N)
|
, numbers, numbers + N)
|
||||||
|
|
||||||
, boost::make_filter_iterator(
|
, boost::make_filter_iterator(
|
||||||
boost::bind(std::greater<int>(), boost::placeholders::_1, -2)
|
std::bind2nd(std::greater<int>(), -2)
|
||||||
, numbers + N, numbers + N)
|
, numbers + N, numbers + N)
|
||||||
|
|
||||||
, std::ostream_iterator<int>(std::cout, " ")
|
, std::ostream_iterator<int>(std::cout, " ")
|
||||||
);
|
);
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
return boost::exit_success;
|
return boost::exit_success;
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,14 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/iterator/function_output_iterator.hpp>
|
#include <boost/function_output_iterator.hpp>
|
||||||
|
|
||||||
struct string_appender
|
struct string_appender
|
||||||
{
|
{
|
||||||
string_appender(std::string& s)
|
string_appender(std::string& s)
|
||||||
: m_str(&s)
|
: m_str(&s)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void operator()(const std::string& x) const
|
void operator()(const std::string& x) const
|
||||||
{
|
{
|
||||||
*m_str += x;
|
*m_str += x;
|
||||||
@ -37,9 +37,9 @@ int main(int, char*[])
|
|||||||
x.push_back("!");
|
x.push_back("!");
|
||||||
|
|
||||||
std::string s = "";
|
std::string s = "";
|
||||||
std::copy(x.begin(), x.end(),
|
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;
|
std::cout << s << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/bind/bind.hpp>
|
|
||||||
#include <boost/iterator/indirect_iterator.hpp>
|
#include <boost/iterator/indirect_iterator.hpp>
|
||||||
|
|
||||||
int main(int, char*[])
|
int main(int, char*[])
|
||||||
@ -21,13 +20,13 @@ int main(int, char*[])
|
|||||||
pointers_to_chars[i] = &characters[i];
|
pointers_to_chars[i] = &characters[i];
|
||||||
|
|
||||||
// Example of using indirect_iterator
|
// Example of using indirect_iterator
|
||||||
|
|
||||||
boost::indirect_iterator<char**, char>
|
boost::indirect_iterator<char**, char>
|
||||||
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
|
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
|
||||||
|
|
||||||
std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
|
std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
||||||
// Example of making mutable and constant indirect iterators
|
// Example of making mutable and constant indirect iterators
|
||||||
|
|
||||||
@ -42,19 +41,19 @@ int main(int, char*[])
|
|||||||
const_indirect_last(pointers_to_chars + N);
|
const_indirect_last(pointers_to_chars + N);
|
||||||
|
|
||||||
std::transform(const_indirect_first, const_indirect_last,
|
std::transform(const_indirect_first, const_indirect_last,
|
||||||
mutable_indirect_first, boost::bind(std::plus<char>(), 1, boost::placeholders::_1));
|
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
|
||||||
|
|
||||||
std::copy(mutable_indirect_first, mutable_indirect_last,
|
std::copy(mutable_indirect_first, mutable_indirect_last,
|
||||||
std::ostream_iterator<char>(std::cout, ","));
|
std::ostream_iterator<char>(std::cout, ","));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
|
||||||
// Example of using make_indirect_iterator()
|
// Example of using make_indirect_iterator()
|
||||||
|
|
||||||
std::copy(boost::make_indirect_iterator(pointers_to_chars),
|
std::copy(boost::make_indirect_iterator(pointers_to_chars),
|
||||||
boost::make_indirect_iterator(pointers_to_chars + N),
|
boost::make_indirect_iterator(pointers_to_chars + N),
|
||||||
std::ostream_iterator<char>(std::cout, ","));
|
std::ostream_iterator<char>(std::cout, ","));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ struct node_base
|
|||||||
|
|
||||||
virtual void print(std::ostream& s) const = 0;
|
virtual void print(std::ostream& s) const = 0;
|
||||||
virtual void double_me() = 0;
|
virtual void double_me() = 0;
|
||||||
|
|
||||||
void append(node_base* p)
|
void append(node_base* p)
|
||||||
{
|
{
|
||||||
if (m_next)
|
if (m_next)
|
||||||
@ -32,7 +32,7 @@ struct node_base
|
|||||||
else
|
else
|
||||||
m_next = p;
|
m_next = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
node_base* m_next;
|
node_base* m_next;
|
||||||
};
|
};
|
||||||
@ -52,9 +52,9 @@ struct node : node_base
|
|||||||
|
|
||||||
void print(std::ostream& s) const { s << this->m_value; }
|
void print(std::ostream& s) const { s << this->m_value; }
|
||||||
void double_me() { m_value += m_value; }
|
void double_me() { m_value += m_value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T m_value;
|
T m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NODE_DWA2004110_HPP
|
#endif // NODE_DWA2004110_HPP
|
||||||
|
@ -11,17 +11,7 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(BOOST_NO_CXX11_SMART_PTR)
|
|
||||||
|
|
||||||
std::auto_ptr<node<int> > nodes(new node<int>(42));
|
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<std::string>(" is greater than "));
|
||||||
nodes->append(new node<int>(13));
|
nodes->append(new node<int>(13));
|
||||||
|
|
||||||
@ -30,7 +20,7 @@ int main()
|
|||||||
, std::ostream_iterator<node_base>(std::cout, " ")
|
, std::ostream_iterator<node_base>(std::cout, " ")
|
||||||
);
|
);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::for_each(
|
std::for_each(
|
||||||
node_iterator(nodes.get()), node_iterator()
|
node_iterator(nodes.get()), node_iterator()
|
||||||
, std::mem_fun_ref(&node_base::double_me)
|
, std::mem_fun_ref(&node_base::double_me)
|
||||||
|
@ -28,10 +28,10 @@ class node_iterator
|
|||||||
|
|
||||||
void increment()
|
void increment()
|
||||||
{ m_node = m_node->next(); }
|
{ m_node = m_node->next(); }
|
||||||
|
|
||||||
bool equal(node_iterator const& other) const
|
bool equal(node_iterator const& other) const
|
||||||
{ return this->m_node == other.m_node; }
|
{ return this->m_node == other.m_node; }
|
||||||
|
|
||||||
node_base& dereference() const
|
node_base& dereference() const
|
||||||
{ return *m_node; }
|
{ return *m_node; }
|
||||||
|
|
||||||
|
@ -12,33 +12,23 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(BOOST_NO_CXX11_SMART_PTR)
|
|
||||||
|
|
||||||
std::auto_ptr<node<int> > nodes(new node<int>(42));
|
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<std::string>(" is greater than "));
|
||||||
nodes->append(new node<int>(13));
|
nodes->append(new node<int>(13));
|
||||||
|
|
||||||
// Check interoperability
|
// Check interoperability
|
||||||
assert(node_iterator(nodes.get()) == node_const_iterator(nodes.get()));
|
assert(node_iterator(nodes.get()) == node_const_iterator(nodes.get()));
|
||||||
assert(node_const_iterator(nodes.get()) == node_iterator(nodes.get()));
|
assert(node_const_iterator(nodes.get()) == node_iterator(nodes.get()));
|
||||||
|
|
||||||
assert(node_iterator(nodes.get()) != node_const_iterator());
|
assert(node_iterator(nodes.get()) != node_const_iterator());
|
||||||
assert(node_const_iterator(nodes.get()) != node_iterator());
|
assert(node_const_iterator(nodes.get()) != node_iterator());
|
||||||
|
|
||||||
std::copy(
|
std::copy(
|
||||||
node_iterator(nodes.get()), node_iterator()
|
node_iterator(nodes.get()), node_iterator()
|
||||||
, std::ostream_iterator<node_base>(std::cout, " ")
|
, std::ostream_iterator<node_base>(std::cout, " ")
|
||||||
);
|
);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::for_each(
|
std::for_each(
|
||||||
node_iterator(nodes.get()), node_iterator()
|
node_iterator(nodes.get()), node_iterator()
|
||||||
, boost::mem_fn(&node_base::double_me)
|
, boost::mem_fn(&node_base::double_me)
|
||||||
|
@ -6,7 +6,11 @@
|
|||||||
|
|
||||||
# include "node.hpp"
|
# include "node.hpp"
|
||||||
# include <boost/iterator/iterator_facade.hpp>
|
# include <boost/iterator/iterator_facade.hpp>
|
||||||
# include <type_traits>
|
|
||||||
|
# ifndef BOOST_NO_SFINAE
|
||||||
|
# include <boost/type_traits/is_convertible.hpp>
|
||||||
|
# include <boost/utility/enable_if.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
template <class Value>
|
template <class Value>
|
||||||
class node_iter
|
class node_iter
|
||||||
@ -29,13 +33,21 @@ class node_iter
|
|||||||
template <class OtherValue>
|
template <class OtherValue>
|
||||||
node_iter(
|
node_iter(
|
||||||
node_iter<OtherValue> const& other
|
node_iter<OtherValue> const& other
|
||||||
, typename std::enable_if<
|
# ifndef BOOST_NO_SFINAE
|
||||||
std::is_convertible<OtherValue*,Value*>::value
|
, typename boost::enable_if<
|
||||||
|
boost::is_convertible<OtherValue*,Value*>
|
||||||
, enabler
|
, enabler
|
||||||
>::type = enabler()
|
>::type = enabler()
|
||||||
|
# endif
|
||||||
)
|
)
|
||||||
: m_node(other.m_node) {}
|
: m_node(other.m_node) {}
|
||||||
|
|
||||||
|
|
||||||
|
# if !BOOST_WORKAROUND(__GNUC__, == 2)
|
||||||
|
private: // GCC2 can't grant friendship to template member functions
|
||||||
|
friend class boost::iterator_core_access;
|
||||||
|
# endif
|
||||||
|
|
||||||
template <class OtherValue>
|
template <class OtherValue>
|
||||||
bool equal(node_iter<OtherValue> const& other) const
|
bool equal(node_iter<OtherValue> const& other) const
|
||||||
{
|
{
|
||||||
@ -51,7 +63,7 @@ class node_iter
|
|||||||
# else
|
# else
|
||||||
private:
|
private:
|
||||||
template <class> friend class node_iter;
|
template <class> friend class node_iter;
|
||||||
# endif
|
# endif
|
||||||
Value* m_node;
|
Value* m_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,33 +12,23 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined(BOOST_NO_CXX11_SMART_PTR)
|
|
||||||
|
|
||||||
std::auto_ptr<node<int> > nodes(new node<int>(42));
|
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<std::string>(" is greater than "));
|
||||||
nodes->append(new node<int>(13));
|
nodes->append(new node<int>(13));
|
||||||
|
|
||||||
// Check interoperability
|
// Check interoperability
|
||||||
assert(node_iterator(nodes.get()) == node_const_iterator(nodes.get()));
|
assert(node_iterator(nodes.get()) == node_const_iterator(nodes.get()));
|
||||||
assert(node_const_iterator(nodes.get()) == node_iterator(nodes.get()));
|
assert(node_const_iterator(nodes.get()) == node_iterator(nodes.get()));
|
||||||
|
|
||||||
assert(node_iterator(nodes.get()) != node_const_iterator());
|
assert(node_iterator(nodes.get()) != node_const_iterator());
|
||||||
assert(node_const_iterator(nodes.get()) != node_iterator());
|
assert(node_const_iterator(nodes.get()) != node_iterator());
|
||||||
|
|
||||||
std::copy(
|
std::copy(
|
||||||
node_iterator(nodes.get()), node_iterator()
|
node_iterator(nodes.get()), node_iterator()
|
||||||
, std::ostream_iterator<node_base>(std::cout, " ")
|
, std::ostream_iterator<node_base>(std::cout, " ")
|
||||||
);
|
);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::for_each(
|
std::for_each(
|
||||||
node_iterator(nodes.get()), node_iterator()
|
node_iterator(nodes.get()), node_iterator()
|
||||||
, boost::mem_fn(&node_base::double_me)
|
, boost::mem_fn(&node_base::double_me)
|
||||||
|
@ -6,7 +6,11 @@
|
|||||||
|
|
||||||
# include "node.hpp"
|
# include "node.hpp"
|
||||||
# include <boost/iterator/iterator_adaptor.hpp>
|
# include <boost/iterator/iterator_adaptor.hpp>
|
||||||
# include <type_traits>
|
|
||||||
|
# ifndef BOOST_NO_SFINAE
|
||||||
|
# include <boost/type_traits/is_convertible.hpp>
|
||||||
|
# include <boost/utility/enable_if.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
template <class Value>
|
template <class Value>
|
||||||
class node_iter
|
class node_iter
|
||||||
@ -23,7 +27,7 @@ class node_iter
|
|||||||
typedef boost::iterator_adaptor<
|
typedef boost::iterator_adaptor<
|
||||||
node_iter<Value>, Value*, boost::use_default, boost::forward_traversal_tag
|
node_iter<Value>, Value*, boost::use_default, boost::forward_traversal_tag
|
||||||
> super_t;
|
> super_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
node_iter()
|
node_iter()
|
||||||
: super_t(0) {}
|
: super_t(0) {}
|
||||||
@ -34,17 +38,19 @@ class node_iter
|
|||||||
template <class OtherValue>
|
template <class OtherValue>
|
||||||
node_iter(
|
node_iter(
|
||||||
node_iter<OtherValue> const& other
|
node_iter<OtherValue> const& other
|
||||||
, typename std::enable_if<
|
# ifndef BOOST_NO_SFINAE
|
||||||
std::is_convertible<OtherValue*,Value*>::value
|
, typename boost::enable_if<
|
||||||
|
boost::is_convertible<OtherValue*,Value*>
|
||||||
, enabler
|
, enabler
|
||||||
>::type = enabler()
|
>::type = enabler()
|
||||||
|
# endif
|
||||||
)
|
)
|
||||||
: super_t(other.base()) {}
|
: super_t(other.base()) {}
|
||||||
|
|
||||||
# if !BOOST_WORKAROUND(__GNUC__, == 2)
|
# if !BOOST_WORKAROUND(__GNUC__, == 2)
|
||||||
private: // GCC2 can't grant friendship to template member functions
|
private: // GCC2 can't grant friendship to template member functions
|
||||||
friend class boost::iterator_core_access;
|
friend class boost::iterator_core_access;
|
||||||
# endif
|
# endif
|
||||||
void increment() { this->base_reference() = this->base()->next(); }
|
void increment() { this->base_reference() = this->base()->next(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ int main() {
|
|||||||
*el_it = std::distance(elements.begin(), el_it);
|
*el_it = std::distance(elements.begin(), el_it);
|
||||||
|
|
||||||
index_type indices( index_size );
|
index_type indices( index_size );
|
||||||
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
|
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
|
||||||
*i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
|
*i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
|
||||||
std::reverse( indices.begin(), indices.end() );
|
std::reverse( indices.begin(), indices.end() );
|
||||||
|
|
||||||
|
@ -15,13 +15,13 @@ int main(int, char*[])
|
|||||||
const int N = sizeof(letters_)/sizeof(char) - 1;
|
const int N = sizeof(letters_)/sizeof(char) - 1;
|
||||||
typedef char* base_iterator;
|
typedef char* base_iterator;
|
||||||
base_iterator letters(letters_);
|
base_iterator letters(letters_);
|
||||||
|
|
||||||
std::cout << "original sequence of letters:\t\t\t"
|
std::cout << "original sequence of letters:\t\t\t"
|
||||||
<< letters_ << std::endl;
|
<< letters_ << std::endl;
|
||||||
|
|
||||||
// Use reverse_iterator to print a sequence of letters in reverse
|
// Use reverse_iterator to print a sequence of letters in reverse
|
||||||
// order.
|
// order.
|
||||||
|
|
||||||
boost::reverse_iterator<base_iterator>
|
boost::reverse_iterator<base_iterator>
|
||||||
reverse_letters_first(letters + N),
|
reverse_letters_first(letters + N),
|
||||||
reverse_letters_last(letters);
|
reverse_letters_last(letters);
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
// (C) Copyright Jeremy Siek 2000-2004.
|
// (C) Copyright Jeremy Siek 2000-2004.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -15,11 +15,10 @@
|
|||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template <class Operation>
|
template <class Operation>
|
||||||
class binder1st {
|
class binder1st
|
||||||
public:
|
: public std::unary_function<typename Operation::second_argument_type,
|
||||||
typedef typename Operation::result_type result_type;
|
typename Operation::result_type> {
|
||||||
typedef typename Operation::second_argument_type argument_type;
|
|
||||||
protected:
|
protected:
|
||||||
Operation op;
|
Operation op;
|
||||||
typename Operation::first_argument_type value;
|
typename Operation::first_argument_type value;
|
||||||
@ -30,7 +29,7 @@ namespace boost {
|
|||||||
: op(x), value(y) {}
|
: op(x), value(y) {}
|
||||||
typename Operation::result_type
|
typename Operation::result_type
|
||||||
operator()(const typename Operation::second_argument_type& x) const {
|
operator()(const typename Operation::second_argument_type& x) const {
|
||||||
return op(value, x);
|
return op(value, x);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,6 +69,8 @@ main(int, char*[])
|
|||||||
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
|
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
|
||||||
std::ostream_iterator<int>(std::cout, " "));
|
std::ostream_iterator<int>(std::cout, " "));
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,18 +1,56 @@
|
|||||||
// (C) Copyright Andrey Semashev 2017.
|
// (C) Copyright Jeremy Siek 2001.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// Revision History:
|
||||||
|
|
||||||
|
// 27 Feb 2001 Jeremy Siek
|
||||||
|
// Initial checkin.
|
||||||
|
|
||||||
#ifndef BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
#ifndef BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
||||||
#define BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
#define BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
||||||
|
|
||||||
// This is a deprecated header left for backward compatibility.
|
#include <iterator>
|
||||||
// Use boost/iterator/function_output_iterator.hpp instead.
|
|
||||||
|
|
||||||
#include <boost/config/header_deprecated.hpp>
|
namespace boost {
|
||||||
|
|
||||||
BOOST_HEADER_DEPRECATED("<boost/iterator/function_output_iterator.hpp>")
|
template <class UnaryFunction>
|
||||||
|
class function_output_iterator {
|
||||||
|
typedef function_output_iterator self;
|
||||||
|
public:
|
||||||
|
typedef std::output_iterator_tag iterator_category;
|
||||||
|
typedef void value_type;
|
||||||
|
typedef void difference_type;
|
||||||
|
typedef void pointer;
|
||||||
|
typedef void reference;
|
||||||
|
|
||||||
#include <boost/iterator/function_output_iterator.hpp>
|
explicit function_output_iterator() {}
|
||||||
|
|
||||||
|
explicit function_output_iterator(const UnaryFunction& f)
|
||||||
|
: m_f(f) {}
|
||||||
|
|
||||||
|
struct output_proxy {
|
||||||
|
output_proxy(UnaryFunction& f) : m_f(f) { }
|
||||||
|
template <class T> output_proxy& operator=(const T& value) {
|
||||||
|
m_f(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
UnaryFunction& m_f;
|
||||||
|
};
|
||||||
|
output_proxy operator*() { return output_proxy(m_f); }
|
||||||
|
self& operator++() { return *this; }
|
||||||
|
self& operator++(int) { return *this; }
|
||||||
|
private:
|
||||||
|
UnaryFunction m_f;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class UnaryFunction>
|
||||||
|
inline function_output_iterator<UnaryFunction>
|
||||||
|
make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) {
|
||||||
|
return function_output_iterator<UnaryFunction>(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
// (C) Copyright Andrey Semashev 2025.
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
#ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
|
||||||
#define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
|
||||||
|
|
||||||
// This is a deprecated header left for backward compatibility.
|
|
||||||
// Please use <boost/iterator/generator_iterator.hpp> instead.
|
|
||||||
|
|
||||||
#include <boost/iterator/generator_iterator.hpp>
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
|
|
@ -1,46 +0,0 @@
|
|||||||
#ifndef BOOST_INDIRECT_REFERENCE_DWA200415_HPP
|
|
||||||
#define BOOST_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 <type_traits>
|
|
||||||
|
|
||||||
#include <boost/detail/is_incrementable.hpp>
|
|
||||||
#include <boost/iterator/iterator_traits.hpp>
|
|
||||||
#include <boost/pointee.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template< typename P >
|
|
||||||
struct smart_ptr_reference
|
|
||||||
{
|
|
||||||
using type = boost::pointee_t< P >&;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template< typename P >
|
|
||||||
struct indirect_reference :
|
|
||||||
std::conditional<
|
|
||||||
detail::is_incrementable< P >::value,
|
|
||||||
iterator_reference< P >,
|
|
||||||
detail::smart_ptr_reference< P >
|
|
||||||
>::type
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename P >
|
|
||||||
using indirect_reference_t = typename indirect_reference< P >::type;
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_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,74 +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 detail
|
|
||||||
|
|
||||||
namespace advance_adl_barrier {
|
|
||||||
|
|
||||||
template< typename InputIterator, typename Distance >
|
|
||||||
inline BOOST_CXX14_CONSTEXPR void advance(InputIterator& it, Distance n)
|
|
||||||
{
|
|
||||||
detail::advance_impl(it, n, typename iterator_traversal< InputIterator >::type());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace advance_adl_barrier
|
|
||||||
|
|
||||||
using namespace advance_adl_barrier;
|
|
||||||
|
|
||||||
} // namespace iterators
|
|
||||||
|
|
||||||
using namespace iterators::advance_adl_barrier;
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif
|
|
@ -2,219 +2,214 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
#ifndef BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
|
#ifndef COUNTING_ITERATOR_DWA200348_HPP
|
||||||
#define BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
|
# define COUNTING_ITERATOR_DWA200348_HPP
|
||||||
|
|
||||||
#include <limits>
|
# include <boost/iterator/iterator_adaptor.hpp>
|
||||||
#include <type_traits>
|
# include <boost/detail/numeric_traits.hpp>
|
||||||
|
# include <boost/mpl/bool.hpp>
|
||||||
#include <boost/config.hpp>
|
# include <boost/mpl/if.hpp>
|
||||||
#include <boost/core/use_default.hpp>
|
# include <boost/mpl/identity.hpp>
|
||||||
#include <boost/detail/numeric_traits.hpp>
|
# include <boost/mpl/eval_if.hpp>
|
||||||
#include <boost/iterator/iterator_adaptor.hpp>
|
|
||||||
#include <boost/iterator/iterator_categories.hpp>
|
|
||||||
#include <boost/iterator/detail/if_default.hpp>
|
|
||||||
#include <boost/iterator/detail/eval_if_default.hpp>
|
|
||||||
#include <boost/iterator/detail/type_traits/type_identity.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace iterators {
|
|
||||||
|
|
||||||
template<
|
template <
|
||||||
typename Incrementable,
|
class Incrementable
|
||||||
typename CategoryOrTraversal,
|
, class CategoryOrTraversal
|
||||||
typename Difference
|
, class Difference
|
||||||
>
|
>
|
||||||
class counting_iterator;
|
class counting_iterator;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail
|
||||||
|
|
||||||
// Try to detect numeric types at compile time in ways compatible
|
|
||||||
// with the limitations of the compiler and library.
|
|
||||||
template< typename T >
|
|
||||||
struct is_numeric :
|
|
||||||
public std::integral_constant< bool, std::numeric_limits< T >::is_specialized >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_numeric< long long > :
|
|
||||||
public std::true_type
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_numeric< unsigned long long > :
|
|
||||||
public std::true_type
|
|
||||||
{};
|
|
||||||
|
|
||||||
#if defined(BOOST_HAS_INT128)
|
|
||||||
template<>
|
|
||||||
struct is_numeric< boost::int128_type > :
|
|
||||||
public std::true_type
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct is_numeric< boost::uint128_type > :
|
|
||||||
public std::true_type
|
|
||||||
{};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Some compilers fail to have a numeric_limits specialization
|
|
||||||
template<>
|
|
||||||
struct is_numeric< wchar_t > :
|
|
||||||
public std::true_type
|
|
||||||
{};
|
|
||||||
|
|
||||||
template< typename T >
|
|
||||||
struct numeric_difference
|
|
||||||
{
|
{
|
||||||
using type = typename boost::detail::numeric_traits< T >::difference_type;
|
// Try to detect numeric types at compile time in ways compatible
|
||||||
};
|
// with the limitations of the compiler and library.
|
||||||
|
template <class T>
|
||||||
|
struct is_numeric_impl
|
||||||
|
{
|
||||||
|
// For a while, this wasn't true, but we rely on it below. This is a regression assert.
|
||||||
|
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
|
||||||
|
|
||||||
|
# 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 = (
|
||||||
|
boost::is_convertible<int,T>::value
|
||||||
|
&& boost::is_convertible<T,int>::value
|
||||||
|
));
|
||||||
|
# else
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# endif
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(BOOST_HAS_INT128)
|
template <class T>
|
||||||
// std::numeric_limits, which is used by numeric_traits, is not specialized for __int128 in some standard libraries
|
struct is_numeric
|
||||||
template<>
|
: mpl::bool_<(::boost::detail::is_numeric_impl<T>::value)>
|
||||||
struct numeric_difference< boost::int128_type >
|
{};
|
||||||
{
|
|
||||||
using type = boost::int128_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
# if defined(BOOST_HAS_LONG_LONG)
|
||||||
struct numeric_difference< boost::uint128_type >
|
template <>
|
||||||
{
|
struct is_numeric< ::boost::long_long_type>
|
||||||
using type = boost::int128_type;
|
: mpl::true_ {};
|
||||||
};
|
|
||||||
#endif
|
template <>
|
||||||
|
struct is_numeric< ::boost::ulong_long_type>
|
||||||
|
: mpl::true_ {};
|
||||||
|
# endif
|
||||||
|
|
||||||
template< typename Incrementable, typename CategoryOrTraversal, typename Difference, bool IsNumeric = is_numeric< Incrementable >::value >
|
// Some compilers fail to have a numeric_limits specialization
|
||||||
struct counting_iterator_types
|
template <>
|
||||||
{
|
struct is_numeric<wchar_t>
|
||||||
using traversal = detail::eval_if_default_t<
|
: mpl::true_ {};
|
||||||
CategoryOrTraversal,
|
|
||||||
iterator_traversal< Incrementable >
|
template <class T>
|
||||||
>;
|
struct numeric_difference
|
||||||
|
{
|
||||||
|
typedef typename boost::detail::numeric_traits<T>::difference_type type;
|
||||||
|
};
|
||||||
|
|
||||||
using difference = detail::eval_if_default_t<
|
BOOST_STATIC_ASSERT(is_numeric<int>::value);
|
||||||
Difference,
|
|
||||||
iterator_difference< Incrementable >
|
template <class Incrementable, class CategoryOrTraversal, class Difference>
|
||||||
>;
|
struct counting_iterator_base
|
||||||
};
|
{
|
||||||
|
typedef typename detail::ia_dflt_help<
|
||||||
|
CategoryOrTraversal
|
||||||
|
, mpl::eval_if<
|
||||||
|
is_numeric<Incrementable>
|
||||||
|
, mpl::identity<random_access_traversal_tag>
|
||||||
|
, iterator_traversal<Incrementable>
|
||||||
|
>
|
||||||
|
>::type traversal;
|
||||||
|
|
||||||
|
typedef typename detail::ia_dflt_help<
|
||||||
|
Difference
|
||||||
|
, mpl::eval_if<
|
||||||
|
is_numeric<Incrementable>
|
||||||
|
, numeric_difference<Incrementable>
|
||||||
|
, iterator_difference<Incrementable>
|
||||||
|
>
|
||||||
|
>::type difference;
|
||||||
|
|
||||||
|
typedef iterator_adaptor<
|
||||||
|
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
|
||||||
|
, Incrementable // Base
|
||||||
|
, Incrementable // Value
|
||||||
|
# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||||
|
const // MSVC won't strip this. Instead we enable Thomas'
|
||||||
|
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
|
||||||
|
# endif
|
||||||
|
, traversal
|
||||||
|
, Incrementable const& // reference
|
||||||
|
, difference
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
template< typename Incrementable, typename CategoryOrTraversal, typename Difference >
|
// Template class distance_policy_select -- choose a policy for computing the
|
||||||
struct counting_iterator_types< Incrementable, CategoryOrTraversal, Difference, true >
|
// distance between counting_iterators at compile-time based on whether or not
|
||||||
{
|
// the iterator wraps an integer or an iterator, using "poor man's partial
|
||||||
using traversal = detail::if_default_t<
|
// specialization".
|
||||||
CategoryOrTraversal,
|
|
||||||
random_access_traversal_tag
|
|
||||||
>;
|
|
||||||
|
|
||||||
using difference = detail::eval_if_default_t<
|
template <bool is_integer> struct distance_policy_select;
|
||||||
Difference,
|
|
||||||
numeric_difference< Incrementable >
|
|
||||||
>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename Incrementable, typename CategoryOrTraversal, typename Difference >
|
// A policy for wrapped iterators
|
||||||
struct counting_iterator_base
|
template <class Difference, class Incrementable1, class Incrementable2>
|
||||||
{
|
struct iterator_distance
|
||||||
using iterator_types = counting_iterator_types< Incrementable, CategoryOrTraversal, Difference >;
|
{
|
||||||
|
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||||
|
{
|
||||||
|
return y - x;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
using type = iterator_adaptor<
|
// A policy for wrapped numbers
|
||||||
counting_iterator< Incrementable, CategoryOrTraversal, Difference >, // self
|
template <class Difference, class Incrementable1, class Incrementable2>
|
||||||
Incrementable, // Base
|
struct number_distance
|
||||||
#ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
{
|
||||||
const // MSVC won't strip this. Instead we enable Thomas'
|
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||||
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
|
{
|
||||||
#endif
|
return numeric_distance(x, y);
|
||||||
Incrementable, // Value
|
}
|
||||||
typename iterator_types::traversal,
|
};
|
||||||
Incrementable const&, // reference
|
}
|
||||||
typename iterator_types::difference
|
|
||||||
>;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A distance calculation policy for wrapped iterators
|
template <
|
||||||
template< typename Difference, typename Incrementable1, typename Incrementable2 >
|
class Incrementable
|
||||||
struct iterator_distance
|
, class CategoryOrTraversal = use_default
|
||||||
{
|
, class Difference = use_default
|
||||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
|
||||||
{
|
|
||||||
return y - x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A distance calculation policy for wrapped numbers
|
|
||||||
template< typename Difference, typename Incrementable1, typename Incrementable2 >
|
|
||||||
struct number_distance
|
|
||||||
{
|
|
||||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
|
||||||
{
|
|
||||||
return boost::detail::numeric_distance(x, y);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template<
|
|
||||||
typename Incrementable,
|
|
||||||
typename CategoryOrTraversal = use_default,
|
|
||||||
typename Difference = use_default
|
|
||||||
>
|
>
|
||||||
class counting_iterator :
|
class counting_iterator
|
||||||
public detail::counting_iterator_base< Incrementable, CategoryOrTraversal, Difference >::type
|
: public detail::counting_iterator_base<
|
||||||
|
Incrementable, CategoryOrTraversal, Difference
|
||||||
|
>::type
|
||||||
{
|
{
|
||||||
|
typedef typename detail::counting_iterator_base<
|
||||||
|
Incrementable, CategoryOrTraversal, Difference
|
||||||
|
>::type super_t;
|
||||||
|
|
||||||
friend class iterator_core_access;
|
friend class iterator_core_access;
|
||||||
|
|
||||||
private:
|
public:
|
||||||
using super_t = typename detail::counting_iterator_base<
|
typedef typename super_t::difference_type difference_type;
|
||||||
Incrementable, CategoryOrTraversal, Difference
|
|
||||||
>::type;
|
|
||||||
|
|
||||||
public:
|
counting_iterator() { }
|
||||||
using reference = typename super_t::reference;
|
|
||||||
using difference_type = typename super_t::difference_type;
|
counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
|
||||||
|
|
||||||
counting_iterator() = default;
|
counting_iterator(Incrementable x)
|
||||||
|
: super_t(x)
|
||||||
counting_iterator(counting_iterator const&) = default;
|
|
||||||
counting_iterator& operator=(counting_iterator const&) = default;
|
|
||||||
|
|
||||||
counting_iterator(Incrementable x) :
|
|
||||||
super_t(x)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
# if 0
|
||||||
reference dereference() const
|
template<class OtherIncrementable>
|
||||||
|
counting_iterator(
|
||||||
|
counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& t
|
||||||
|
, typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
|
||||||
|
)
|
||||||
|
: super_t(t.base())
|
||||||
|
{}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
typename super_t::reference dereference() const
|
||||||
{
|
{
|
||||||
return this->base_reference();
|
return this->base_reference();
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename OtherIncrementable >
|
template <class OtherIncrementable>
|
||||||
difference_type
|
difference_type
|
||||||
distance_to(counting_iterator< OtherIncrementable, CategoryOrTraversal, Difference > const& y) const
|
distance_to(counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& y) const
|
||||||
{
|
{
|
||||||
using distance_traits = typename std::conditional<
|
typedef typename mpl::if_<
|
||||||
detail::is_numeric< Incrementable >::value,
|
detail::is_numeric<Incrementable>
|
||||||
detail::number_distance< difference_type, Incrementable, OtherIncrementable >,
|
, detail::number_distance<difference_type, Incrementable, OtherIncrementable>
|
||||||
detail::iterator_distance< difference_type, Incrementable, OtherIncrementable >
|
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
|
||||||
>::type;
|
>::type d;
|
||||||
|
|
||||||
return distance_traits::distance(this->base(), y.base());
|
return d::distance(this->base(), y.base());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Manufacture a counting iterator for an arbitrary incrementable type
|
// Manufacture a counting iterator for an arbitrary incrementable type
|
||||||
template< typename Incrementable >
|
template <class Incrementable>
|
||||||
inline counting_iterator< Incrementable > make_counting_iterator(Incrementable x)
|
inline counting_iterator<Incrementable>
|
||||||
|
make_counting_iterator(Incrementable x)
|
||||||
{
|
{
|
||||||
return counting_iterator< Incrementable >(x);
|
typedef counting_iterator<Incrementable> result_t;
|
||||||
|
return result_t(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace iterators
|
|
||||||
|
|
||||||
using iterators::counting_iterator;
|
} // namespace boost::iterator
|
||||||
using iterators::make_counting_iterator;
|
|
||||||
|
|
||||||
} // namespace boost
|
#endif // COUNTING_ITERATOR_DWA200348_HPP
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_COUNTING_ITERATOR_DWA200348_HPP
|
|
||||||
|
19
include/boost/iterator/detail/any_conversion_eater.hpp
Normal file
19
include/boost/iterator/detail/any_conversion_eater.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||||
|
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||||
|
# define ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||||
|
|
||||||
|
namespace boost { namespace detail {
|
||||||
|
|
||||||
|
// This type can be used in traits to "eat" up the one user-defined
|
||||||
|
// implicit conversion allowed.
|
||||||
|
struct any_conversion_eater
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
any_conversion_eater(T const&);
|
||||||
|
};
|
||||||
|
|
||||||
|
}} // namespace boost::detail
|
||||||
|
|
||||||
|
#endif // ANY_CONVERSION_EATER_DWA20031117_HPP
|
@ -18,14 +18,16 @@
|
|||||||
|
|
||||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||||
# error you have nested config_def #inclusion.
|
# error you have nested config_def #inclusion.
|
||||||
#else
|
#else
|
||||||
# define BOOST_ITERATOR_CONFIG_DEF
|
# define BOOST_ITERATOR_CONFIG_DEF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We enable this always now. Otherwise, the simple case in
|
// We enable this always now. Otherwise, the simple case in
|
||||||
// libs/iterator/test/constant_iterator_arrow.cpp fails to compile
|
// libs/iterator/test/constant_iterator_arrow.cpp fails to compile
|
||||||
// because the operator-> return is improperly deduced as a non-const
|
// because the operator-> return is improperly deduced as a non-const
|
||||||
// pointer.
|
// pointer.
|
||||||
|
#if 1 || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||||
|
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
|
||||||
|
|
||||||
// Recall that in general, compilers without partial specialization
|
// Recall that in general, compilers without partial specialization
|
||||||
// can't strip constness. Consider counting_iterator, which normally
|
// can't strip constness. Consider counting_iterator, which normally
|
||||||
@ -42,4 +44,94 @@
|
|||||||
|
|
||||||
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
|
# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
|
||||||
|
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x5A0)) \
|
||||||
|
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \
|
||||||
|
|| BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) \
|
||||||
|
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||||
|
|
||||||
|
# define BOOST_NO_LVALUE_RETURN_DETECTION
|
||||||
|
|
||||||
|
# if 0 // test code
|
||||||
|
struct v {};
|
||||||
|
|
||||||
|
typedef char (&no)[3];
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
no foo(T const&, ...);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
char foo(T&, int);
|
||||||
|
|
||||||
|
|
||||||
|
struct value_iterator
|
||||||
|
{
|
||||||
|
v operator*() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct lvalue_deref_helper
|
||||||
|
{
|
||||||
|
static T& x;
|
||||||
|
enum { value = (sizeof(foo(*x,0)) == 1) };
|
||||||
|
};
|
||||||
|
|
||||||
|
int z2[(lvalue_deref_helper<v*>::value == 1) ? 1 : -1];
|
||||||
|
int z[(lvalue_deref_helper<value_iterator>::value) == 1 ? -1 : 1 ];
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
|
||||||
|
# define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(__GNUC__, == 2) \
|
||||||
|
|| BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__) \
|
||||||
|
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
|
# define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile:
|
||||||
|
|
||||||
|
# if 0 // test code
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
template <class T>
|
||||||
|
struct foo
|
||||||
|
{
|
||||||
|
foo(T);
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
foo(foo<U> const& other) : p(other.p) { }
|
||||||
|
|
||||||
|
T p;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool x = boost::is_convertible<foo<int const*>, foo<int*> >::value;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(BOOST_MSVC) && (defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_IS_CONVERTIBLE_TEMPLATE))
|
||||||
|
# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
|
# define BOOST_ARG_DEPENDENT_TYPENAME typename
|
||||||
|
# else
|
||||||
|
# define BOOST_ARG_DEPENDENT_TYPENAME
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(__GNUC__, == 2) && BOOST_WORKAROUND(__GNUC_MINOR__, BOOST_TESTED_AT(95)) \
|
||||||
|
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||||
|
|
||||||
|
// GCC-2.95 eagerly instantiates templated constructors and conversion
|
||||||
|
// operators in convertibility checks, causing premature errors.
|
||||||
|
//
|
||||||
|
// Borland's problems are harder to diagnose due to lack of an
|
||||||
|
// instantiation stack backtrace. They may be due in part to the fact
|
||||||
|
// that it drops cv-qualification willy-nilly in templates.
|
||||||
|
# define BOOST_NO_ONE_WAY_ITERATOR_INTEROP
|
||||||
|
# endif
|
||||||
|
|
||||||
// no include guard; multiple inclusion intended
|
// no include guard; multiple inclusion intended
|
||||||
|
@ -11,10 +11,15 @@
|
|||||||
// 23/02/03 thw
|
// 23/02/03 thw
|
||||||
//
|
//
|
||||||
|
|
||||||
#undef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
#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
|
||||||
|
|
||||||
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
#ifdef BOOST_ITERATOR_CONFIG_DEF
|
||||||
# undef BOOST_ITERATOR_CONFIG_DEF
|
# undef BOOST_ITERATOR_CONFIG_DEF
|
||||||
#else
|
#else
|
||||||
# error missing or nested #include config_def
|
# error missing or nested #include config_def
|
||||||
#endif
|
#endif
|
||||||
|
86
include/boost/iterator/detail/enable_if.hpp
Normal file
86
include/boost/iterator/detail/enable_if.hpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// (C) Copyright David Abrahams 2002.
|
||||||
|
// (C) Copyright Jeremy Siek 2002.
|
||||||
|
// (C) Copyright Thomas Witt 2002.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
#ifndef BOOST_ENABLE_IF_23022003THW_HPP
|
||||||
|
#define BOOST_ENABLE_IF_23022003THW_HPP
|
||||||
|
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
#include <boost/mpl/identity.hpp>
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_def.hpp>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Boost iterators uses its own enable_if cause we need
|
||||||
|
// special semantics for deficient compilers.
|
||||||
|
// 23/02/03 thw
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace iterators
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Base machinery for all kinds of enable if
|
||||||
|
//
|
||||||
|
template<bool>
|
||||||
|
struct enabled
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
struct base
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// For compilers that don't support "Substitution Failure Is Not An Error"
|
||||||
|
// enable_if falls back to always enabled. See comments
|
||||||
|
// on operator implementation for consequences.
|
||||||
|
//
|
||||||
|
template<>
|
||||||
|
struct enabled<false>
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
struct base
|
||||||
|
{
|
||||||
|
#ifdef BOOST_NO_SFINAE
|
||||||
|
|
||||||
|
typedef T type;
|
||||||
|
|
||||||
|
// This way to do it would give a nice error message containing
|
||||||
|
// invalid overload, but has the big disadvantage that
|
||||||
|
// there is no reference to user code in the error message.
|
||||||
|
//
|
||||||
|
// struct invalid_overload;
|
||||||
|
// typedef invalid_overload type;
|
||||||
|
//
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Cond,
|
||||||
|
class Return>
|
||||||
|
struct enable_if
|
||||||
|
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
|
||||||
|
: enabled<(Cond::value)>::template base<Return>
|
||||||
|
# else
|
||||||
|
: mpl::identity<Return>
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
|
typedef Return type;
|
||||||
|
# endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace iterators
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
|
||||||
|
#endif // BOOST_ENABLE_IF_23022003THW_HPP
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
* https://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Andrey Semashev
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_ITERATOR_DETAIL_EVAL_IF_DEFAULT_HPP_INCLUDED_
|
|
||||||
#define BOOST_ITERATOR_DETAIL_EVAL_IF_DEFAULT_HPP_INCLUDED_
|
|
||||||
|
|
||||||
#include <boost/core/use_default.hpp>
|
|
||||||
#include <boost/iterator/detail/type_traits/type_identity.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace iterators {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
// If T is use_default, return the result of invoking
|
|
||||||
// DefaultNullaryFn, otherwise - of NondefaultNullaryFn.
|
|
||||||
// By default, NondefaultNullaryFn returns T, which means
|
|
||||||
// the metafunction can be called with just two parameters
|
|
||||||
// and in that case will return either T or the result of
|
|
||||||
// invoking DefaultNullaryFn.
|
|
||||||
template< typename T, typename DefaultNullaryFn, typename NondefaultNullaryFn = detail::type_identity< T > >
|
|
||||||
struct eval_if_default
|
|
||||||
{
|
|
||||||
using type = typename NondefaultNullaryFn::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename DefaultNullaryFn, typename NondefaultNullaryFn >
|
|
||||||
struct eval_if_default< use_default, DefaultNullaryFn, NondefaultNullaryFn >
|
|
||||||
{
|
|
||||||
using type = typename DefaultNullaryFn::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename T, typename DefaultNullaryFn, typename NondefaultNullaryFn = detail::type_identity< T > >
|
|
||||||
using eval_if_default_t = typename eval_if_default< T, DefaultNullaryFn, NondefaultNullaryFn >::type;
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
} // namespace iterators
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_DETAIL_EVAL_IF_DEFAULT_HPP_INCLUDED_
|
|
@ -2,178 +2,199 @@
|
|||||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||||
#define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||||
|
|
||||||
#include <iterator>
|
# include <boost/iterator/iterator_categories.hpp>
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include <boost/mp11/utility.hpp>
|
# include <boost/mpl/or.hpp> // used in iterator_tag inheritance logic
|
||||||
|
# include <boost/mpl/and.hpp>
|
||||||
|
# include <boost/mpl/if.hpp>
|
||||||
|
# include <boost/mpl/eval_if.hpp>
|
||||||
|
# include <boost/mpl/identity.hpp>
|
||||||
|
# include <boost/mpl/assert.hpp>
|
||||||
|
|
||||||
#include <boost/iterator/iterator_categories.hpp>
|
# include <boost/type_traits/is_same.hpp>
|
||||||
#include <boost/iterator/detail/type_traits/conjunction.hpp>
|
# include <boost/type_traits/is_const.hpp>
|
||||||
#include <boost/iterator/detail/type_traits/disjunction.hpp>
|
# include <boost/type_traits/is_reference.hpp>
|
||||||
#include <boost/iterator/detail/config_def.hpp> // try to keep this last
|
# include <boost/type_traits/is_convertible.hpp>
|
||||||
|
|
||||||
|
# include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
|
# include <boost/iterator/detail/config_def.hpp> // try to keep this last
|
||||||
|
|
||||||
|
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||||
|
# include <boost/detail/indirect_traits.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// iterator_category deduction for iterator_facade
|
// iterator_category deduction for iterator_facade
|
||||||
//
|
//
|
||||||
|
|
||||||
namespace boost {
|
// forward declaration
|
||||||
namespace iterators {
|
namespace boost { struct use_default; }
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
namespace boost { namespace detail {
|
||||||
|
|
||||||
template< typename T >
|
struct input_output_iterator_tag
|
||||||
struct is_const_lvalue_reference :
|
: std::input_iterator_tag
|
||||||
public std::false_type
|
{
|
||||||
{};
|
// Using inheritance for only input_iterator_tag helps to avoid
|
||||||
|
// ambiguities when a stdlib implementation dispatches on a
|
||||||
template< typename T >
|
// function which is overloaded on both input_iterator_tag and
|
||||||
struct is_const_lvalue_reference< T const& > :
|
// output_iterator_tag, as STLPort does, in its __valid_range
|
||||||
public std::true_type
|
// function. I claim it's better to avoid the ambiguity in these
|
||||||
{};
|
// cases.
|
||||||
|
operator std::output_iterator_tag() const
|
||||||
#endif // BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
{
|
||||||
|
return std::output_iterator_tag();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// True iff the user has explicitly disabled writability of this
|
// True iff the user has explicitly disabled writability of this
|
||||||
// iterator. Pass the iterator_facade's Value parameter and its
|
// iterator. Pass the iterator_facade's Value parameter and its
|
||||||
// nested ::reference type.
|
// nested ::reference type.
|
||||||
//
|
//
|
||||||
template< typename ValueParam, typename Reference >
|
template <class ValueParam, class Reference>
|
||||||
struct iterator_writability_disabled :
|
struct iterator_writability_disabled
|
||||||
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
|
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
|
||||||
public detail::disjunction<
|
: mpl::or_<
|
||||||
detail::is_const_lvalue_reference< Reference >,
|
is_const<Reference>
|
||||||
std::is_const< Reference >,
|
, boost::detail::indirect_traits::is_reference_to_const<Reference>
|
||||||
std::is_const< ValueParam >
|
, is_const<ValueParam>
|
||||||
>
|
>
|
||||||
# else
|
# else
|
||||||
public std::is_const< ValueParam >
|
: is_const<ValueParam>
|
||||||
# endif
|
# endif
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
|
||||||
template< typename Traversal, typename ValueParam, typename Reference >
|
|
||||||
using is_traversal_of_input_iterator = detail::conjunction<
|
|
||||||
std::is_convertible< Traversal, single_pass_traversal_tag >,
|
|
||||||
|
|
||||||
// check for readability
|
|
||||||
std::is_convertible< Reference, ValueParam >
|
|
||||||
>;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Convert an iterator_facade's traversal category, Value parameter,
|
// Convert an iterator_facade's traversal category, Value parameter,
|
||||||
// and ::reference type to an appropriate old-style category.
|
// and ::reference type to an appropriate old-style category.
|
||||||
//
|
//
|
||||||
// Due to changeset 21683, this now never results in a category convertible
|
// If writability has been disabled per the above metafunction, the
|
||||||
// to output_iterator_tag.
|
// result will not be convertible to output_iterator_tag.
|
||||||
//
|
//
|
||||||
// Change at: https://svn.boost.org/trac/boost/changeset/21683
|
// Otherwise, if Traversal == single_pass_traversal_tag, the following
|
||||||
template< typename Traversal, typename ValueParam, typename Reference >
|
// 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
|
||||||
|
//
|
||||||
|
template <class Traversal, class ValueParam, class Reference>
|
||||||
struct iterator_facade_default_category
|
struct iterator_facade_default_category
|
||||||
|
: mpl::eval_if<
|
||||||
|
mpl::and_<
|
||||||
|
is_reference<Reference>
|
||||||
|
, is_convertible<Traversal,forward_traversal_tag>
|
||||||
|
>
|
||||||
|
, mpl::eval_if<
|
||||||
|
is_convertible<Traversal,random_access_traversal_tag>
|
||||||
|
, mpl::identity<std::random_access_iterator_tag>
|
||||||
|
, mpl::if_<
|
||||||
|
is_convertible<Traversal,bidirectional_traversal_tag>
|
||||||
|
, std::bidirectional_iterator_tag
|
||||||
|
, std::forward_iterator_tag
|
||||||
|
>
|
||||||
|
>
|
||||||
|
, typename mpl::eval_if<
|
||||||
|
mpl::and_<
|
||||||
|
is_convertible<Traversal, single_pass_traversal_tag>
|
||||||
|
|
||||||
|
// check for readability
|
||||||
|
, is_convertible<Reference, ValueParam>
|
||||||
|
>
|
||||||
|
, mpl::identity<std::input_iterator_tag>
|
||||||
|
, mpl::identity<Traversal>
|
||||||
|
>
|
||||||
|
>
|
||||||
{
|
{
|
||||||
using type = typename std::conditional<
|
|
||||||
detail::is_traversal_of_input_iterator< Traversal, ValueParam, Reference >::value,
|
|
||||||
std::input_iterator_tag,
|
|
||||||
Traversal
|
|
||||||
>::type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Specialization for the (typical) case when the reference type is an actual reference
|
|
||||||
template< typename Traversal, typename ValueParam, typename Referenced >
|
|
||||||
struct iterator_facade_default_category< Traversal, ValueParam, Referenced& >
|
|
||||||
{
|
|
||||||
using type = mp11::mp_cond<
|
|
||||||
std::is_convertible< Traversal, random_access_traversal_tag >, std::random_access_iterator_tag,
|
|
||||||
std::is_convertible< Traversal, bidirectional_traversal_tag >, std::bidirectional_iterator_tag,
|
|
||||||
std::is_convertible< Traversal, forward_traversal_tag >, std::forward_iterator_tag,
|
|
||||||
detail::is_traversal_of_input_iterator< Traversal, ValueParam, Referenced& >, std::input_iterator_tag,
|
|
||||||
std::true_type, Traversal
|
|
||||||
>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename Traversal, typename ValueParam, typename Reference >
|
|
||||||
using iterator_facade_default_category_t = typename iterator_facade_default_category< Traversal, ValueParam, Reference >::type;
|
|
||||||
|
|
||||||
// True iff T is convertible to an old-style iterator category.
|
// True iff T is convertible to an old-style iterator category.
|
||||||
template< typename T >
|
template <class T>
|
||||||
struct is_iterator_category :
|
struct is_iterator_category
|
||||||
public detail::disjunction<
|
: mpl::or_<
|
||||||
std::is_convertible< T, std::input_iterator_tag >,
|
is_convertible<T,std::input_iterator_tag>
|
||||||
std::is_convertible< T, std::output_iterator_tag >
|
, is_convertible<T,std::output_iterator_tag>
|
||||||
>
|
>
|
||||||
{};
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template< typename T >
|
template <class T>
|
||||||
struct is_iterator_traversal :
|
struct is_iterator_traversal
|
||||||
public std::is_convertible< T, incrementable_traversal_tag >
|
: is_convertible<T,incrementable_traversal_tag>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// A composite iterator_category tag convertible to Category (a pure
|
// A composite iterator_category tag convertible to Category (a pure
|
||||||
// old-style category) and Traversal (a pure traversal tag).
|
// old-style category) and Traversal (a pure traversal tag).
|
||||||
// Traversal must be a strict increase of the traversal power given by
|
// Traversal must be a strict increase of the traversal power given by
|
||||||
// Category.
|
// Category.
|
||||||
//
|
//
|
||||||
template< typename Category, typename Traversal >
|
template <class Category, class Traversal>
|
||||||
struct iterator_category_with_traversal :
|
struct iterator_category_with_traversal
|
||||||
public Category,
|
: Category, Traversal
|
||||||
public Traversal
|
|
||||||
{
|
{
|
||||||
|
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
// Make sure this isn't used to build any categories where
|
// Make sure this isn't used to build any categories where
|
||||||
// convertibility to Traversal is redundant. Should just use the
|
// convertibility to Traversal is redundant. Should just use the
|
||||||
// Category element in that case.
|
// Category element in that case.
|
||||||
static_assert(
|
BOOST_MPL_ASSERT_NOT((
|
||||||
!std::is_convertible< iterator_category_to_traversal_t< Category >, Traversal >::value,
|
is_convertible<
|
||||||
"Category transformed to corresponding traversal must be convertible to Traversal."
|
typename iterator_category_to_traversal<Category>::type
|
||||||
);
|
, Traversal
|
||||||
|
>));
|
||||||
|
|
||||||
static_assert(is_iterator_category< Category >::value, "Category must be an STL iterator category.");
|
BOOST_MPL_ASSERT((is_iterator_category<Category>));
|
||||||
static_assert(!is_iterator_category< Traversal >::value, "Traversal must not be an STL iterator category.");
|
BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
|
||||||
static_assert(!is_iterator_traversal< Category >::value, "Category must not be a traversal tag.");
|
BOOST_MPL_ASSERT_NOT((is_iterator_traversal<Category>));
|
||||||
static_assert(is_iterator_traversal< Traversal >::value, "Traversal must be a traversal tag.");
|
# if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
|
||||||
|
BOOST_MPL_ASSERT((is_iterator_traversal<Traversal>));
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// Computes an iterator_category tag whose traversal is Traversal and
|
// Computes an iterator_category tag whose traversal is Traversal and
|
||||||
// which is appropriate for an iterator
|
// which is appropriate for an iterator
|
||||||
template< typename Traversal, typename ValueParam, typename Reference >
|
template <class Traversal, class ValueParam, class Reference>
|
||||||
struct facade_iterator_category_impl
|
struct facade_iterator_category_impl
|
||||||
{
|
{
|
||||||
static_assert(!is_iterator_category< Traversal >::value, "Traversal must not be an STL iterator category.");
|
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||||
|
BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
|
||||||
using category = iterator_facade_default_category_t< Traversal, ValueParam, Reference >;
|
# endif
|
||||||
|
|
||||||
using type = typename std::conditional<
|
typedef typename iterator_facade_default_category<
|
||||||
std::is_same<
|
Traversal,ValueParam,Reference
|
||||||
Traversal,
|
>::type category;
|
||||||
typename iterator_category_to_traversal< category >::type
|
|
||||||
>::value,
|
typedef typename mpl::if_<
|
||||||
category,
|
is_same<
|
||||||
iterator_category_with_traversal< category, Traversal >
|
Traversal
|
||||||
>::type;
|
, typename iterator_category_to_traversal<category>::type
|
||||||
|
>
|
||||||
|
, category
|
||||||
|
, iterator_category_with_traversal<category,Traversal>
|
||||||
|
>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename Traversal, typename ValueParam, typename Reference >
|
|
||||||
using facade_iterator_category_impl_t = typename facade_iterator_category_impl< Traversal, ValueParam, Reference >::type;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Compute an iterator_category for iterator_facade
|
// Compute an iterator_category for iterator_facade
|
||||||
//
|
//
|
||||||
template< typename CategoryOrTraversal, typename ValueParam, typename Reference >
|
template <class CategoryOrTraversal, class ValueParam, class Reference>
|
||||||
struct facade_iterator_category
|
struct facade_iterator_category
|
||||||
|
: mpl::eval_if<
|
||||||
|
is_iterator_category<CategoryOrTraversal>
|
||||||
|
, mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
|
||||||
|
, facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
|
||||||
|
>
|
||||||
{
|
{
|
||||||
using type = mp11::mp_eval_if<
|
|
||||||
is_iterator_category< CategoryOrTraversal >,
|
|
||||||
CategoryOrTraversal, // old-style categories are fine as-is
|
|
||||||
facade_iterator_category_impl_t, CategoryOrTraversal, ValueParam, Reference
|
|
||||||
>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}} // namespace boost::iterators::detail
|
}} // namespace boost::detail
|
||||||
|
|
||||||
#include <boost/iterator/detail/config_undef.hpp>
|
# include <boost/iterator/detail/config_undef.hpp>
|
||||||
|
|
||||||
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
* https://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Andrey Semashev
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOST_ITERATOR_DETAIL_IF_DEFAULT_HPP_INCLUDED_
|
|
||||||
#define BOOST_ITERATOR_DETAIL_IF_DEFAULT_HPP_INCLUDED_
|
|
||||||
|
|
||||||
#include <boost/core/use_default.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace iterators {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
// If T is use_default, return Default, otherwise - Nondefault.
|
|
||||||
// By default, Nondefault is T, which means
|
|
||||||
// the metafunction can be called with just two parameters
|
|
||||||
// and in that case will return either T or Default.
|
|
||||||
template< typename T, typename Default, typename Nondefault = T >
|
|
||||||
struct if_default
|
|
||||||
{
|
|
||||||
using type = Nondefault;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename Default, typename Nondefault >
|
|
||||||
struct if_default< use_default, Default, Nondefault >
|
|
||||||
{
|
|
||||||
using type = Default;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename T, typename Default, typename Nondefault = T >
|
|
||||||
using if_default_t = typename if_default< T, Default, Nondefault >::type;
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
} // namespace iterators
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_DETAIL_IF_DEFAULT_HPP_INCLUDED_
|
|
116
include/boost/iterator/detail/minimum_category.hpp
Normal file
116
include/boost/iterator/detail/minimum_category.hpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||||
|
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP
|
||||||
|
# define MINIMUM_CATEGORY_DWA20031119_HPP
|
||||||
|
|
||||||
|
# include <boost/type_traits/is_convertible.hpp>
|
||||||
|
# include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
|
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||||
|
|
||||||
|
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
|
||||||
|
;
|
||||||
|
|
||||||
|
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
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user