Compare commits

..

45 Commits

Author SHA1 Message Date
7c9b4296a1 Fixed accessing members of the dereferenced value after iterator post-increment.
The recent commit 5777e9944b broke code such as
(*it++).foo(), where the result of dereferencing would be convertible to
the value type but did not provide the members of the value type. To mitigate
this, return a reference to the value instead of a proxy object. This will only
work for non-writable iterators (and it didn't work for writable iterators
before either) because in that case a proxy is needed to be able to intercept
operator=.

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

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

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

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

Reported in https://github.com/boostorg/iterator/issues/75.
2022-11-09 21:15:44 +03:00
f82627f2cc Updated to GHA checkout@v3 to avoid deprecation warnings. 2022-10-18 17:57:57 +03:00
ed1d96f251 GitHub Actions config update.
- Added gcc-12 and clang-13 through 15 jobs.
- Added C++23 testing for gcc and clang on Linux.
- Updated clang version for UBSAN job.
- Updated Ubuntu version for clang jobs to avoid having to use external APT
  repository.
- Updated python package installation for compatibility with Ubuntu 22.04.
2022-09-10 01:29:45 +03:00
ce52aee3ce Switched gcc-9 to ubuntu-20.04 GHA CI image. 2022-08-14 17:53:43 +03:00
17355c5ad0 Updated copyright years. 2022-08-14 14:01:45 +03:00
9504b3bced Replaced ubuntu-18.04 GHA CI images with containers.
Also use ubuntu-latest image for jobs that are running in a container.
2022-08-14 14:00:17 +03:00
2cc45f1694 Switch to macos-11 GHA image as macos-10.15 is deprecated. 2022-08-12 15:59:54 +03:00
a3269e536f Include remove_reference.hpp only when needed. 2022-07-01 00:23:19 +03:00
129245a985 Added tests for function_output_iterator. 2022-07-01 00:14:14 +03:00
1a80896934 Disabled assignment of output_proxy to output_proxy. 2022-07-01 00:13:32 +03:00
ee2d3a6596 Made output_proxy private and made its internals private. 2022-06-30 23:35:58 +03:00
cd24487161 Removed #include <utility>. 2022-06-30 23:26:52 +03:00
dd37a27067 Marked output_proxy constructor explicit. 2022-06-30 23:25:33 +03:00
7b6edb6a7d Merge pull request #73 from Hailios/rvalue_ref_func_iterator
add forward reference assignment operator to function_output_iterator
2022-06-30 23:24:11 +03:00
c924b42749 add forward reference assignment operator to function_output_iterator 2022-06-30 15:40:41 +02:00
85d935bf68 Added VS2022 job and C++20 and C++latest jobs to AppVeyor CI. 2022-06-06 02:57:44 +03:00
d175ba2450 Trim trailing spaces. 2022-01-13 17:32:11 +03:00
75ba1a50c9 Switched enable_if from MPL to TypeTraits. 2022-01-13 17:28:53 +03:00
e4ab917f79 Removed unneeded includes and added missing ones to transform_iterator. 2022-01-13 17:27:22 +03:00
c901bd6d7a Switched function_input_iterator to TypeTraits instead of MPL. 2022-01-13 17:08:55 +03:00
eb0d01126a Added support for int128 to counting_iterator. 2022-01-13 16:59:46 +03:00
abe6fbfd4b Converted counting_iterator to rely on TypeTraits instead of MPL. 2022-01-13 16:57:52 +03:00
7a200905dd Added an assignment operator to counting_iterator.
This should silence gcc warnings about deprecated implicit copy assignment
operator because of the explicitly defined copy constructor. Also, changed
constructor definitions to be defaulted when possible and added missing
includes.

Closes https://github.com/boostorg/iterator/pull/69.
2022-01-13 16:34:47 +03:00
acf35d2a87 Fixed a link to library docs and silenced b2 warning about unescaped character. 2021-11-19 18:32:24 +03:00
5ebbe941be Updated check for apt-add-repository capabilities.
In Ubuntu 20.04 there appeared an updated version of the
software-properties-common package in focal-updates, which ships a newer
apt-add-repository version that doesn't support -P/-S/-U command line arguments.

Since we cannot rely on package version checks to determine apt-add-repository
capabilities, we have to parse its --help output instead.

Also, made source list processing more protected against spaces.
2021-11-16 00:48:57 +03:00
72308ef787 Fixed git version check on Mac OS. 2021-09-26 20:40:21 +03:00
9124869bcc Updated link to AppVeyor badge. 2021-09-15 22:15:48 +03:00
216b442d23 Added GHA CI timeout. 2021-09-15 21:32:19 +03:00
c858138495 Explicitly specify address-model for MSVC.
This works around Boost.Build bug:

https://github.com/boostorg/build/issues/659
2021-09-13 10:02:47 +03:00
1c6f85d4f9 Fixed a preprocessor condition. 2021-09-12 23:36:59 +03:00
0a59f555ca Added libc++ 12 to the list of standard libs implementing C++20 std::ostream_iterator. 2021-09-12 22:52:55 +03:00
18337e990b Disable zip_iterator test with std::tuple on gcc 4.4.
libstdc++ from gcc 4.4 has a broken std::tuple that fails to compile
a constructor from a compatible tuple:

/usr/include/c++/4.4/tuple: In constructor 'std::_Head_base<_Idx, _Head, false>::_Head_base(_UHead&&) [with _UHead = std::_Head_base<0ul, const int&, false>, long unsigned int _Idx = 0ul, _Head = int]':
/usr/include/c++/4.4/tuple:179:   instantiated from 'std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(std::_Tuple_impl<_Idx, _UElements ...>&&) [with _UElements = const int&, double&, long unsigned int _Idx = 0ul, _Head = int, _Tail = double]'
/usr/include/c++/4.4/tuple:338:   instantiated from 'std::tuple<_T1, _T2>::tuple(std::tuple<_U1, _U2>&&) [with _U1 = const int&, _U2 = double&, _T1 = int, _T2 = double]'
libs/iterator/test/detail/zip_iterator_test_original.ipp:137:   instantiated from here
/usr/include/c++/4.4/tuple:94: error: cannot convert 'std::_Head_base<0ul, const int&, false>' to 'int' in initialization
2021-09-12 22:40:19 +03:00
1447c566d1 Removed CMake tests from GHA config. 2021-09-12 20:35:29 +03:00
fc281fa58a Added a README.md file. 2021-09-12 20:10:07 +03:00
b76c273946 Added GitHub Actions config. 2021-09-12 20:01:33 +03:00
f396a8fef0 Removed Travis CI config.
Since Travis CI no longer runs free jobs for open source projects,
we are switching to GitHub Actions instead.
2021-09-12 19:59:52 +03:00
5a6013e21f Merge pull request #67 from joaquintides/patch-2
supressed spurious type-limits warning
2021-08-31 20:36:32 +03:00
6dfb175cef supressed spurious type-limits warning
See https://github.com/boostorg/iterator/pull/66 for details.
2021-08-31 19:19:57 +02:00
72a7fb1b73 Update CMakeLists.txt 2021-06-10 00:56:31 +03:00
f4b47fd266 Switch from deprecated test to Lightweight Test 2021-06-07 22:03:32 -04:00
2c0145bff0 [skip ci] Merge pull request #63 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-01-20 11:28:41 +03:00
987151dde6 [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-19 23:19:27 -05:00
30 changed files with 1030 additions and 614 deletions

472
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,472 @@
# Copyright 2021-2022 Andrey Semashev
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
concurrency:
group: ${{format('{0}:{1}', github.repository, github.ref)}}
cancel-in-progress: true
env:
GIT_FETCH_JOBS: 8
NET_RETRY_COUNT: 5
DEFAULT_BUILD_VARIANT: debug,release
jobs:
posix:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
# Linux, gcc
- toolset: gcc-4.4
cxxstd: "98,0x"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.4
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.6
cxxstd: "03,0x"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.6
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.7
cxxstd: "03,11"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.7
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-4.8
- toolset: gcc-4.9
cxxstd: "03,11"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-4.9
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-latest
container: ubuntu:16.04
install:
- g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-7
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-latest
container: ubuntu:18.04
install:
- g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install:
- g++-9
- toolset: gcc-10
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,20,23"
os: ubuntu-22.04
install:
- g++-11
- toolset: gcc-12
cxxstd: "03,11,14,17,20,23"
os: ubuntu-22.04
install:
- g++-12
- name: UBSAN
toolset: gcc-11
cxxstd: "03,11,14,17,20,23"
ubsan: 1
build_variant: debug
os: ubuntu-22.04
install:
- g++-11
# Linux, clang
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "03,11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.8
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-7
# Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-latest
container: ubuntu:18.04
install:
- clang-8
- g++-7
gcc_toolchain: 7
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install:
- clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-12
- toolset: clang
compiler: clang++-13
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-15
sources:
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- toolset: clang
compiler: clang++-15
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
install:
- clang-15
- libc++-15-dev
- libc++abi-15-dev
sources:
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- name: UBSAN
toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20,2b"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
ubsan: 1
build_variant: debug
os: ubuntu-22.04
install:
- clang-14
- libc++-14-dev
- libc++abi-14-dev
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-11
timeout-minutes: 60
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
steps:
- name: Setup environment
run: |
if [ -f "/etc/debian_version" ]
then
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
export DEBIAN_FRONTEND=noninteractive
fi
if [ -n "${{matrix.container}}" ]
then
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
if [ -f "/etc/debian_version" ]
then
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ]
then
PYTHON_PACKAGE="python-is-python3"
else
PYTHON_PACKAGE="python"
fi
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake
fi
fi
git config --global pack.threads 0
- uses: actions/checkout@v3
- name: Install packages
if: matrix.install
run: |
declare -a SOURCE_KEYS SOURCES
if [ -n "${{join(matrix.source_keys, ' ')}}" ]
then
SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}")
fi
if [ -n "${{join(matrix.sources, ' ')}}" ]
then
SOURCES=("${{join(matrix.sources, '" "')}}")
fi
for key in "${SOURCE_KEYS[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
echo "Adding key: $key"
wget -O - "$key" | sudo apt-key add - && break || sleep 2
done
done
if [ ${#SOURCES[@]} -gt 0 ]
then
APT_ADD_REPO_COMMON_ARGS=("-y")
APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')"
if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ]
then
APT_ADD_REPO_COMMON_ARGS+=("-n")
fi
APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)"
for source in "${SOURCES[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}")
if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ]
then
case "$source" in
"ppa:"*)
APT_ADD_REPO_ARGS+=("-P")
;;
"deb "*)
APT_ADD_REPO_ARGS+=("-S")
;;
*)
APT_ADD_REPO_ARGS+=("-U")
;;
esac
fi
APT_ADD_REPO_ARGS+=("$source")
echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}"
sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
done
done
fi
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}}
- name: Setup GCC Toolchain
if: matrix.gcc_toolchain
run: |
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
mkdir -p "$GCC_TOOLCHAIN_ROOT"
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null)
echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV
echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV
DEPINST_ARGS=()
GIT_VERSION="$(git --version | sed -e 's/git version //')"
GIT_HAS_JOBS=1
if [ -f "/etc/debian_version" ]
then
if $(dpkg --compare-versions "$GIT_VERSION" lt 2.8.0)
then
GIT_HAS_JOBS=0
fi
else
declare -a GIT_VER=(${GIT_VERSION//./ })
declare -a GIT_MIN_VER=(2 8 0)
for ((i=0; i<${#GIT_VER[@]}; i++))
do
if [ -z "${GIT_MIN_VER[i]}" ]
then
GIT_MIN_VER[i]=0
fi
if [ "${GIT_VER[i]}" -lt "${GIT_MIN_VER[i]}" ]
then
GIT_HAS_JOBS=0
break
fi
done
fi
if [ "$GIT_HAS_JOBS" -ne 0 ]
then
DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS")
fi
cd ..
git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root"
cd boost-root
mkdir -p libs/$LIBRARY
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
DEPINST_ARGS+=("$LIBRARY")
python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}"
if [ -z "${{matrix.cmake_tests}}" ]
then
./bootstrap.sh
./b2 headers
if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ]
then
echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam
if [ -n "$GCC_TOOLCHAIN_ROOT" ]
then
echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam
fi
echo " ;" >> ~/user-config.jam
fi
fi
- name: Run tests
if: matrix.cmake_tests == ''
run: |
cd ../boost-root
B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}")
if [ -n "${{matrix.build_variant}}" ]
then
B2_ARGS+=("variant=${{matrix.build_variant}}")
else
B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT")
fi
if [ -n "${{matrix.threading}}" ]
then
B2_ARGS+=("threading=${{matrix.threading}}")
fi
if [ -n "${{matrix.ubsan}}" ]
then
export UBSAN_OPTIONS="print_stacktrace=1"
B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global")
fi
if [ -n "${{matrix.cxxflags}}" ]
then
B2_ARGS+=("cxxflags=${{matrix.cxxflags}}")
fi
if [ -n "${{matrix.linkflags}}" ]
then
B2_ARGS+=("linkflags=${{matrix.linkflags}}")
fi
B2_ARGS+=("libs/$LIBRARY/test")
./b2 "${B2_ARGS[@]}"

View File

@ -1,415 +0,0 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright 2019 Andrey Semashev
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
sudo: false
python: "2.7"
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
# gcc, Linux
# Note: gcc-4.4 in C++0x mode fails zip_iterator tests with std::tuple
- os: linux
dist: trusty
compiler: gcc-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: gcc-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: gcc-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: gcc-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-9
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
dist: bionic
compiler: gcc-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,20
addons:
apt:
packages:
- g++-10
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
dist: bionic
compiler: gcc-UBSAN
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-10
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
# clang, Linux
- os: linux
dist: trusty
compiler: clang-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.5
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.5 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: trusty
compiler: clang-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.6
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.6 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: trusty
compiler: clang-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.7
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.7 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.8 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-4
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-5
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
- libstdc++-7-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-5.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-6
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-6.0
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-7
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-7 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-8
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-9
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-9
- libstdc++-9-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-10
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20
addons:
apt:
packages:
- clang-10
- libstdc++-9-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-UBSAN
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-10
- libstdc++-9-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-libc++
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20 CXXFLAGS="-stdlib=libc++" LINKFLAGS="-stdlib=libc++"
addons:
apt:
packages:
- clang-10
- libc++-10-dev
- libc++abi-10-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-libc++-UBSAN
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1 CXXFLAGS="-stdlib=libc++" LINKFLAGS="-stdlib=libc++"
addons:
apt:
packages:
- clang-10
- libc++-10-dev
- libc++abi-10-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
# clang, OS X
# OS X builds are slow on Travis CI
# - os: osx
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
# osx_image: xcode9.4
#
# - os: osx
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
# osx_image: xcode10.3
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17
osx_image: xcode11.2
install:
- GIT_FETCH_JOBS=8
- BOOST_BRANCH=develop
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
- cd ..
- git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init tools/build
- git submodule init tools/boostdep
- git submodule init tools/boost_install
- git submodule init libs/headers
- git submodule init libs/config
- git submodule update --jobs $GIT_FETCH_JOBS
- cp -r $TRAVIS_BUILD_DIR/* libs/iterator
- python tools/boostdep/depinst/depinst.py --git_args "--jobs $GIT_FETCH_JOBS" iterator
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- BUILD_JOBS=`(nproc || sysctl -n hw.ncpu) 2> /dev/null`
- ./b2 -j $BUILD_JOBS libs/iterator/test toolset=$TOOLSET cxxstd=$CXXSTD ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on visibility=global} ${CXXFLAGS:+cxxflags="$CXXFLAGS"} ${LINKFLAGS:+linkflags="$LINKFLAGS"}
notifications:
email:
on_success: always

View File

@ -3,12 +3,9 @@
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
# Partial (add_subdirectory only) and experimental CMake support
# Subject to change; please do not rely on the contents of this file yet.
cmake_minimum_required(VERSION 3.5...3.20)
cmake_minimum_required(VERSION 3.5)
project(BoostIterator LANGUAGES CXX)
project(boost_iterator VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_iterator INTERFACE)
add_library(Boost::iterator ALIAS boost_iterator)

27
README.md Normal file
View File

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

View File

@ -15,22 +15,31 @@ branches:
environment:
matrix:
- TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
- TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
ADDRMD: 32
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-12.0
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-14.0
CXXSTD: 14,latest
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-14.1
CXXSTD: 14,17
CXXSTD: 14,17,latest
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: msvc-14.2
ADDRMD: 32,64
CXXSTD: 14,17
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
CXXSTD: 14,17,latest
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: gcc
CXXSTD: 03,11,14,1z

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,6 +8,7 @@
#define BOOST_ITERATOR_ADVANCE_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/iterator/iterator_categories.hpp>
namespace boost {
@ -28,6 +29,12 @@ namespace iterators {
}
}
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, >= 40600)
// type-limits warning issued below when n is an unsigned integral
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
#endif
template <typename BidirectionalIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(
@ -50,6 +57,10 @@ namespace iterators {
}
}
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, >= 40600)
#pragma GCC diagnostic pop
#endif
template <typename RandomAccessIterator, typename Distance>
inline BOOST_CXX14_CONSTEXPR void
advance_impl(

View File

@ -5,12 +5,21 @@
#ifndef COUNTING_ITERATOR_DWA200348_HPP
# define COUNTING_ITERATOR_DWA200348_HPP
# include <boost/iterator/iterator_adaptor.hpp>
# include <boost/config.hpp>
# include <boost/static_assert.hpp>
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
# include <limits>
# elif !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
# include <boost/type_traits/is_convertible.hpp>
# else
# include <boost/type_traits/is_arithmetic.hpp>
# endif
# include <boost/type_traits/is_integral.hpp>
# include <boost/type_traits/type_identity.hpp>
# include <boost/type_traits/conditional.hpp>
# include <boost/type_traits/integral_constant.hpp>
# include <boost/detail/numeric_traits.hpp>
# include <boost/mpl/bool.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/identity.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/iterator/iterator_adaptor.hpp>
namespace boost {
namespace iterators {
@ -45,7 +54,7 @@ namespace detail
&& boost::is_convertible<T,int>::value
));
# else
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
# endif
# endif
@ -53,23 +62,33 @@ namespace detail
template <class T>
struct is_numeric
: mpl::bool_<(::boost::iterators::detail::is_numeric_impl<T>::value)>
: boost::integral_constant<bool, ::boost::iterators::detail::is_numeric_impl<T>::value>
{};
# if defined(BOOST_HAS_LONG_LONG)
template <>
struct is_numeric< ::boost::long_long_type>
: mpl::true_ {};
struct is_numeric<boost::long_long_type>
: boost::true_type {};
template <>
struct is_numeric< ::boost::ulong_long_type>
: mpl::true_ {};
struct is_numeric<boost::ulong_long_type>
: boost::true_type {};
# endif
# if defined(BOOST_HAS_INT128)
template <>
struct is_numeric<boost::int128_type>
: boost::true_type {};
template <>
struct is_numeric<boost::uint128_type>
: boost::true_type {};
# endif
// Some compilers fail to have a numeric_limits specialization
template <>
struct is_numeric<wchar_t>
: mpl::true_ {};
: true_type {};
template <class T>
struct numeric_difference
@ -77,27 +96,40 @@ namespace detail
typedef typename boost::detail::numeric_traits<T>::difference_type type;
};
BOOST_STATIC_ASSERT(is_numeric<int>::value);
# if defined(BOOST_HAS_INT128)
// std::numeric_limits, which is used by numeric_traits, is not specialized for __int128 in some standard libraries
template <>
struct numeric_difference<boost::int128_type>
{
typedef boost::int128_type type;
};
template <>
struct numeric_difference<boost::uint128_type>
{
typedef boost::int128_type type;
};
# endif
template <class Incrementable, class CategoryOrTraversal, class Difference>
struct counting_iterator_base
{
typedef typename detail::ia_dflt_help<
CategoryOrTraversal
, mpl::eval_if<
is_numeric<Incrementable>
, mpl::identity<random_access_traversal_tag>
, typename boost::conditional<
is_numeric<Incrementable>::value
, boost::type_identity<random_access_traversal_tag>
, iterator_traversal<Incrementable>
>
>::type
>::type traversal;
typedef typename detail::ia_dflt_help<
Difference
, mpl::eval_if<
is_numeric<Incrementable>
, typename boost::conditional<
is_numeric<Incrementable>::value
, numeric_difference<Incrementable>
, iterator_difference<Incrementable>
>
>::type
>::type difference;
typedef iterator_adaptor<
@ -161,9 +193,9 @@ class counting_iterator
public:
typedef typename super_t::difference_type difference_type;
counting_iterator() { }
BOOST_DEFAULTED_FUNCTION(counting_iterator(), {})
counting_iterator(counting_iterator const& rhs) : super_t(rhs.base()) {}
BOOST_DEFAULTED_FUNCTION(counting_iterator(counting_iterator const& rhs), : super_t(rhs.base()) {})
counting_iterator(Incrementable x)
: super_t(x)
@ -180,6 +212,8 @@ class counting_iterator
{}
# endif
BOOST_DEFAULTED_FUNCTION(counting_iterator& operator=(counting_iterator const& rhs), { *static_cast< super_t* >(this) = static_cast< super_t const& >(rhs); return *this; })
private:
typename super_t::reference dereference() const
@ -191,13 +225,13 @@ class counting_iterator
difference_type
distance_to(counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& y) const
{
typedef typename mpl::if_<
detail::is_numeric<Incrementable>
, detail::number_distance<difference_type, Incrementable, OtherIncrementable>
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
>::type d;
typedef typename boost::conditional<
detail::is_numeric<Incrementable>::value
, detail::number_distance<difference_type, Incrementable, OtherIncrementable>
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
>::type d;
return d::distance(this->base(), y.base());
return d::distance(this->base(), y.base());
}
};
@ -206,8 +240,8 @@ template <class Incrementable>
inline counting_iterator<Incrementable>
make_counting_iterator(Incrementable x)
{
typedef counting_iterator<Incrementable> result_t;
return result_t(x);
typedef counting_iterator<Incrementable> result_t;
return result_t(x);
}
} // namespace iterators

View File

@ -18,9 +18,9 @@
#ifdef BOOST_ITERATOR_CONFIG_DEF
# error you have nested config_def #inclusion.
#else
#else
# define BOOST_ITERATOR_CONFIG_DEF
#endif
#endif
// We enable this always now. Otherwise, the simple case in
// libs/iterator/test/constant_iterator_arrow.cpp fails to compile
@ -50,7 +50,7 @@
|| (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \
|| BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) \
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
# define BOOST_NO_LVALUE_RETURN_DETECTION
# if 0 // test code
@ -79,7 +79,7 @@
int z2[(lvalue_deref_helper<v*>::value == 1) ? 1 : -1];
int z[(lvalue_deref_helper<value_iterator>::value) == 1 ? -1 : 1 ];
# endif
# endif
#endif
@ -112,7 +112,7 @@
#if !defined(BOOST_MSVC) && (defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_IS_CONVERTIBLE_TEMPLATE))
# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
#endif
#endif
# if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
@ -123,6 +123,6 @@
// instantiation stack backtrace. They may be due in part to the fact
// that it drops cv-qualification willy-nilly in templates.
# define BOOST_NO_ONE_WAY_ITERATOR_INTEROP
# endif
# endif
// no include guard; multiple inclusion intended

View File

@ -21,4 +21,4 @@
# undef BOOST_ITERATOR_CONFIG_DEF
#else
# error missing or nested #include config_def
#endif
#endif

View File

@ -7,10 +7,11 @@
#ifndef BOOST_ENABLE_IF_23022003THW_HPP
#define BOOST_ENABLE_IF_23022003THW_HPP
#include <boost/detail/workaround.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/config.hpp>
#include <boost/iterator/detail/config_def.hpp>
#if defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE)
#include <boost/type_traits/type_identity.hpp>
#endif
//
// Boost iterators uses its own enable_if cause we need
@ -48,7 +49,6 @@ namespace boost
struct base
{
#ifdef BOOST_NO_SFINAE
typedef T type;
// This way to do it would give a nice error message containing
@ -69,7 +69,7 @@ namespace boost
# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
: enabled<(Cond::value)>::template base<Return>
# else
: mpl::identity<Return>
: boost::type_identity<Return>
# endif
{
};

View File

@ -12,7 +12,7 @@
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/core/addressof.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/function_types/is_function_pointer.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/iterator/iterator_facade.hpp>
@ -28,6 +28,9 @@ namespace boost {
namespace iterators {
template <class Function, class Input>
class function_input_iterator;
namespace impl {
// Computes the return type of an lvalue-call with an empty argument,
@ -38,7 +41,7 @@ namespace iterators {
{
typedef typename result_of<
#ifdef BOOST_RESULT_OF_USE_TR1
typename mpl::if_<is_function<F>, F&, F>::type()
typename boost::conditional<is_function<F>::value, F&, F>::type()
#else
F&()
#endif
@ -46,21 +49,21 @@ namespace iterators {
};
template <class Function, class Input>
class function_input_iterator
: public iterator_facade<
function_input_iterator<Function, Input>,
typename result_of_nullary_lvalue_call<Function>::type,
single_pass_traversal_tag,
typename result_of_nullary_lvalue_call<Function>::type const &
class function_object_input_iterator :
public iterator_facade<
iterators::function_input_iterator<Function, Input>,
typename result_of_nullary_lvalue_call<Function>::type,
single_pass_traversal_tag,
typename result_of_nullary_lvalue_call<Function>::type const &
>
{
public:
function_input_iterator() {}
function_input_iterator(Function & f_, Input state_ = Input())
function_object_input_iterator() {}
function_object_input_iterator(Function & f_, Input state_ = Input())
: f(boost::addressof(f_)), state(state_) {}
void increment() {
if(value)
if (value)
value = none;
else
(*f)();
@ -69,10 +72,12 @@ namespace iterators {
typename result_of_nullary_lvalue_call<Function>::type const &
dereference() const {
return (value ? value : value = (*f)()).get();
if (!value)
value = (*f)();
return value.get();
}
bool equal(function_input_iterator const & other) const {
bool equal(function_object_input_iterator const & other) const {
return f == other.f && state == other.state;
}
@ -83,12 +88,12 @@ namespace iterators {
};
template <class Function, class Input>
class function_pointer_input_iterator
: public iterator_facade<
function_pointer_input_iterator<Function, Input>,
typename function_types::result_type<Function>::type,
single_pass_traversal_tag,
typename function_types::result_type<Function>::type const &
class function_pointer_input_iterator :
public iterator_facade<
iterators::function_input_iterator<Function, Input>,
typename function_types::result_type<Function>::type,
single_pass_traversal_tag,
typename function_types::result_type<Function>::type const &
>
{
public:
@ -97,7 +102,7 @@ namespace iterators {
: f(f_), state(state_) {}
void increment() {
if(value)
if (value)
value = none;
else
(*f)();
@ -106,7 +111,9 @@ namespace iterators {
typename function_types::result_type<Function>::type const &
dereference() const {
return (value ? value : value = (*f)()).get();
if (!value)
value = (*f)();
return value.get();
}
bool equal(function_pointer_input_iterator const & other) const {
@ -122,17 +129,17 @@ namespace iterators {
} // namespace impl
template <class Function, class Input>
class function_input_iterator
: public mpl::if_<
function_types::is_function_pointer<Function>,
class function_input_iterator :
public boost::conditional<
function_types::is_function_pointer<Function>::value,
impl::function_pointer_input_iterator<Function,Input>,
impl::function_input_iterator<Function,Input>
impl::function_object_input_iterator<Function,Input>
>::type
{
typedef typename mpl::if_<
function_types::is_function_pointer<Function>,
typedef typename boost::conditional<
function_types::is_function_pointer<Function>::value,
impl::function_pointer_input_iterator<Function,Input>,
impl::function_input_iterator<Function,Input>
impl::function_object_input_iterator<Function,Input>
>::type base_type;
public:
function_input_iterator(Function & f, Input i)
@ -153,7 +160,8 @@ namespace iterators {
return result_t(f, state);
}
struct infinite {
struct infinite
{
infinite & operator++() { return *this; }
infinite & operator++(int) { return *this; }
bool operator==(infinite &) const { return false; };

View File

@ -12,13 +12,53 @@
#define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
#include <iterator>
#include <boost/config.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#include <boost/type_traits/remove_reference.hpp>
#endif
namespace boost {
namespace iterators {
template <class UnaryFunction>
class function_output_iterator {
private:
typedef function_output_iterator self;
class output_proxy {
public:
explicit output_proxy(UnaryFunction& f) BOOST_NOEXCEPT : m_f(f) { }
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class T>
typename boost::disable_if_c<
boost::is_same< typename boost::remove_cv< T >::type, output_proxy >::value,
output_proxy&
>::type operator=(const T& value) {
m_f(value);
return *this;
}
#else
template <class T>
typename boost::disable_if_c<
boost::is_same< typename boost::remove_cv< typename boost::remove_reference< T >::type >::type, output_proxy >::value,
output_proxy&
>::type operator=(T&& value) {
m_f(static_cast< T&& >(value));
return *this;
}
#endif
BOOST_DEFAULTED_FUNCTION(output_proxy(output_proxy const& that), BOOST_NOEXCEPT : m_f(that.m_f) {})
BOOST_DELETED_FUNCTION(output_proxy& operator=(output_proxy const&))
private:
UnaryFunction& m_f;
};
public:
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
@ -31,17 +71,10 @@ namespace iterators {
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;
};

View File

@ -154,79 +154,160 @@ namespace iterators {
class postfix_increment_proxy
{
typedef typename iterator_value<Iterator>::type value_type;
public:
explicit postfix_increment_proxy(Iterator const& x)
: stored_value(*x)
: stored_iterator(x)
, stored_value(*x)
{}
// Returning a mutable reference allows nonsense like
// (*r++).mutate(), but it imposes fewer assumptions about the
// behavior of the value_type. In particular, recall that
// (*r).mutate() is legal if operator* returns by value.
value_type&
operator*() const
{
return this->stored_value;
}
private:
mutable value_type stored_value;
};
//
// In general, we can't determine that such an iterator isn't
// writable -- we also need to store a copy of the old iterator so
// that it can be written into.
template <class Iterator>
class writable_postfix_increment_proxy
{
typedef typename iterator_value<Iterator>::type value_type;
public:
explicit writable_postfix_increment_proxy(Iterator const& x)
: stored_value(*x)
, stored_iterator(x)
{}
// Dereferencing must return a proxy so that both *r++ = o and
// value_type(*r++) can work. In this case, *r is the same as
// *r++, and the conversion operator below is used to ensure
// readability.
writable_postfix_increment_proxy const&
operator*() const
{
return *this;
}
// Provides readability of *r++
operator value_type&() const
value_type& operator*() const
{
return stored_value;
}
// Provides writability of *r++
template <class T>
T const& operator=(T const& x) const
{
*this->stored_iterator = x;
return x;
}
// This overload just in case only non-const objects are writable
template <class T>
T& operator=(T& x) const
{
*this->stored_iterator = x;
return x;
}
// Provides X(r++)
operator Iterator const&() const
{
return stored_iterator;
}
// Provides (r++)->foo()
value_type* operator->() const
{
return boost::addressof(stored_value);
}
private:
mutable value_type stored_value;
Iterator stored_iterator;
mutable value_type stored_value;
};
template <class Iterator>
class writable_postfix_increment_dereference_proxy;
template <class T>
struct is_not_writable_postfix_increment_dereference_proxy :
public boost::true_type
{};
template <class Iterator>
struct is_not_writable_postfix_increment_dereference_proxy<
writable_postfix_increment_dereference_proxy<Iterator>
> :
public boost::false_type
{};
template <class Iterator>
class writable_postfix_increment_proxy;
//
// In general, we can't determine that such an iterator isn't
// writable -- we also need to store a copy of the old iterator so
// that it can be written into.
template <class Iterator>
class writable_postfix_increment_dereference_proxy
{
friend class writable_postfix_increment_proxy<Iterator>;
typedef typename iterator_value<Iterator>::type value_type;
public:
explicit writable_postfix_increment_dereference_proxy(Iterator const& x)
: stored_iterator(x)
, stored_value(*x)
{}
// Provides readability of *r++
operator value_type&() const
{
return this->stored_value;
}
template <class OtherIterator>
writable_postfix_increment_dereference_proxy const&
operator=(writable_postfix_increment_dereference_proxy<OtherIterator> const& x) const
{
typedef typename iterator_value<OtherIterator>::type other_value_type;
*this->stored_iterator = static_cast<other_value_type&>(x);
return *this;
}
// Provides writability of *r++
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <class T>
typename iterators::enable_if<
is_not_writable_postfix_increment_dereference_proxy< T >,
writable_postfix_increment_dereference_proxy const&
>::type operator=(T&& x) const
{
*this->stored_iterator = static_cast< T&& >(x);
return *this;
}
#else
template <class T>
typename iterators::enable_if<
is_not_writable_postfix_increment_dereference_proxy< T >,
writable_postfix_increment_dereference_proxy const&
>::type operator=(T const& x) const
{
*this->stored_iterator = x;
return *this;
}
// This overload just in case only non-const objects are writable
template <class T>
typename iterators::enable_if<
is_not_writable_postfix_increment_dereference_proxy< T >,
writable_postfix_increment_dereference_proxy const&
>::type operator=(T& x) const
{
*this->stored_iterator = x;
return *this;
}
#endif
private:
Iterator stored_iterator;
mutable value_type stored_value;
};
template <class Iterator>
class writable_postfix_increment_proxy
{
typedef typename iterator_value<Iterator>::type value_type;
public:
explicit writable_postfix_increment_proxy(Iterator const& x)
: dereference_proxy(x)
{}
writable_postfix_increment_dereference_proxy<Iterator> const&
operator*() const
{
return dereference_proxy;
}
// Provides X(r++)
operator Iterator const&() const
{
return dereference_proxy.stored_iterator;
}
// Provides (r++)->foo()
value_type* operator->() const
{
return boost::addressof(dereference_proxy.stored_value);
}
private:
writable_postfix_increment_dereference_proxy<Iterator> dereference_proxy;
};
# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

View File

@ -87,11 +87,11 @@ void readable_iterator_test(const Iterator i1, T v)
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
// I think we don't really need this as it checks the same things as
// the above code.
BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
# endif
# endif
}
template <class Iterator, class T>
@ -106,7 +106,7 @@ void writable_iterator_test(Iterator i, T v, T v2)
detail::is_incrementable<Iterator>
, detail::is_postfix_incrementable<Iterator>
>());
# endif
# endif
}
template <class Iterator>
@ -131,7 +131,7 @@ void constant_lvalue_iterator_test(Iterator i, T v1)
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
# endif
# endif
}
template <class Iterator, class T>
@ -143,17 +143,17 @@ void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
T& v3 = *i2;
BOOST_TEST(v1 == v3);
// A non-const lvalue iterator is not neccessarily writable, but we
// are assuming the value_type is assignable here
*i = v2;
T& v4 = *i2;
BOOST_TEST(v2 == v4);
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
# endif
# endif
}
template <class Iterator, class T>
@ -248,7 +248,7 @@ void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
BOOST_TEST(*i == vals[N - 1 - c]);
typename std::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
BOOST_TEST(*i == x);
Iterator q = k - c;
Iterator q = k - c;
BOOST_TEST(*i == *q);
BOOST_TEST(i > j);
BOOST_TEST(i >= j);

View File

@ -7,11 +7,11 @@
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <boost/iterator/detail/enable_if.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_class.hpp>
@ -24,7 +24,11 @@
#include <iterator>
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
# include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#endif
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
#include <boost/static_assert.hpp>
#endif
#include <boost/iterator/detail/config_def.hpp>
@ -154,7 +158,7 @@ namespace iterators {
return transform_iterator<UnaryFunc, Iterator>(it, UnaryFunc());
}
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template <class Return, class Argument, class Iterator>
inline transform_iterator< Return (*)(Argument), Iterator, Return>
make_transform_iterator(Iterator it, Return (*fun)(Argument))

View File

@ -14,5 +14,6 @@
"David Abrahams <dave -at- boost-consulting.com>",
"Thomas Witt <witt - at - acm.org>",
"Jeffrey Lee Hellrung Jr. <jeffrey.hellrung -at- gmail.com>"
]
],
"cxxstd": "03"
}

View File

@ -50,6 +50,8 @@ test-suite iterator
[ run permutation_iterator_test.cpp : : : # <stlport-iostream>on
]
[ run function_input_iterator_test.cpp ]
[ run function_output_iterator_test.cpp ]
[ compile-fail function_output_iterator_cf.cpp ]
[ run generator_iterator_test.cpp ]

View File

@ -30,7 +30,7 @@
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/next_prior.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/limits.hpp>
@ -68,7 +68,7 @@ struct unsigned_assert_nonnegative
template <class T>
struct assert_nonnegative
: boost::mpl::if_c<
: boost::conditional<
std::numeric_limits<T>::is_signed
, signed_assert_nonnegative<T>
, unsigned_assert_nonnegative<T>
@ -271,8 +271,12 @@ int main()
test_integer<long>();
test_integer<unsigned long>();
#if defined(BOOST_HAS_LONG_LONG)
test_integer< ::boost::long_long_type>();
test_integer< ::boost::ulong_long_type>();
test_integer<boost::long_long_type>();
test_integer<boost::ulong_long_type>();
#endif
#if defined(BOOST_HAS_INT128)
test_integer<boost::int128_type>();
test_integer<boost::uint128_type>();
#endif
// Test user-defined type.

View File

@ -99,6 +99,15 @@ int main()
for(std::size_t i = 0; i != 10; ++i)
BOOST_TEST_EQ(generated[i], static_cast<int>(42 + i));
// Test that incrementing the iterator returns a reference to the iterator type
{
typedef boost::iterators::function_input_iterator<counter, int> function_counter_iterator_t;
function_counter_iterator_t it1(counter_generator, 0);
function_counter_iterator_t it2(++it1);
function_counter_iterator_t it3(it2++);
BOOST_TEST_EQ(*it3, 54);
}
#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) \
&& defined(BOOST_RESULT_OF_USE_DECLTYPE)
// test the iterator with lambda expressions

View File

@ -0,0 +1,37 @@
// Copyright 2022 (c) Andrey Semashev
// Distributed under the Boost Software License Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/iterator/function_output_iterator.hpp>
namespace {
struct sum_func
{
typedef void result_type;
explicit sum_func(int& n) : m_n(n) {}
result_type operator() (int x) const
{
m_n += x;
}
private:
int& m_n;
};
} // namespace
int main()
{
int n = 0;
boost::iterators::function_output_iterator< sum_func > it1 =
boost::iterators::make_function_output_iterator(sum_func(n));
boost::iterators::function_output_iterator< sum_func > it2 =
boost::iterators::make_function_output_iterator(sum_func(n));
*it1 = *it2;
return 0;
}

View File

@ -0,0 +1,61 @@
// Copyright 2022 (c) Andrey Semashev
// Distributed under the Boost Software License Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/iterator/function_output_iterator.hpp>
namespace {
struct sum_func
{
typedef void result_type;
explicit sum_func(int& n) : m_n(n) {}
result_type operator() (int x) const
{
m_n += x;
}
private:
int& m_n;
};
} // namespace
int main()
{
{
int n = 0;
boost::iterators::function_output_iterator< sum_func > it =
boost::iterators::make_function_output_iterator(sum_func(n));
*it = 1;
++it;
*it = 2;
++it;
*it = 3;
BOOST_TEST_EQ(n, 6);
}
#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
{
int n = 0;
auto it = boost::iterators::make_function_output_iterator([&n](int x) { n -= x; });
*it = 1;
++it;
*it = 2;
++it;
*it = 3;
BOOST_TEST_EQ(n, -6);
}
#endif
return boost::report_errors();
}

View File

@ -10,7 +10,7 @@
#include <boost/call_traits.hpp>
#include <boost/polymorphic_cast.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/core/enable_if.hpp>
// This is a really, really limited test so far. All we're doing
// right now is checking that the postfix++ proxy for single-pass
@ -63,7 +63,23 @@ struct proxy
struct value
{
void mutator() {} // non-const member function
int increment_count;
int private_mutator_count;
int& shared_mutator_count;
explicit value(int& shared_mutator_count) :
increment_count(0),
private_mutator_count(0),
shared_mutator_count(shared_mutator_count)
{
}
// non-const member function
void mutator()
{
++private_mutator_count;
++shared_mutator_count;
}
};
struct input_iter
@ -75,21 +91,25 @@ struct input_iter
>
{
public:
input_iter() {}
explicit input_iter(value& val) : state(&val) {}
void increment()
{
++(state->increment_count);
}
value
dereference() const
{
return value();
return *state;
}
bool equal(input_iter const&) const
{
return false;
}
private:
value* state;
};
template <class T>
@ -198,13 +218,30 @@ int main()
{
// test for a fix to http://tinyurl.com/zuohe
// These two lines should be equivalent (and both compile)
input_iter p;
int shared_mutator_count = 0;
value val(shared_mutator_count);
input_iter p(val);
(*p).mutator();
p->mutator();
BOOST_TEST_EQ(val.increment_count, 0);
BOOST_TEST_EQ(val.private_mutator_count, 0); // mutator() should be invoked on an object returned by value
BOOST_TEST_EQ(shared_mutator_count, 2);
same_type<input_iter::pointer>(p.operator->());
}
{
// Test that accessing dereferenced value of a post-incremented iterator works
int shared_mutator_count = 0;
value val(shared_mutator_count);
input_iter p(val);
(*p++).mutator();
(p++)->mutator();
BOOST_TEST_EQ(val.increment_count, 2);
BOOST_TEST_EQ(val.private_mutator_count, 0); // mutator() should be invoked on an object returned by value
BOOST_TEST_EQ(shared_mutator_count, 2);
}
{
int x = 0;
iterator_with_proxy_reference i(x);

View File

@ -155,10 +155,11 @@ input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&,
// C++20 changed ostream_iterator::difference_type to ptrdiff_t.
// Note: gcc 10.1 defines __cplusplus to a value less than 202002L, but greater than 201703L in C++20 mode.
#if __cplusplus > 201703L && (\
(defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION >= 100100) \
) || \
defined(_MSVC_LANG) && _MSVC_LANG > 201703L && _MSVC_STL_UPDATE >= 202010L
#if (__cplusplus > 201703L && ( \
(defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION >= 100100) || \
(defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 12000) \
)) || \
(defined(_MSVC_LANG) && _MSVC_LANG > 201703L && _MSVC_STL_UPDATE >= 202010L)
#define BOOST_ITERATOR_CXX20_OSTREAM_ITERATOR
#endif

View File

@ -5,7 +5,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include <boost/test/minimal.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <boost/static_assert.hpp>
@ -59,14 +59,14 @@ void permutation_test()
permutation_type it = begin;
permutation_type end = boost::make_permutation_iterator( elements.begin(), indices.end() );
BOOST_CHECK( it == begin );
BOOST_CHECK( it != end );
BOOST_TEST( it == begin );
BOOST_TEST( it != end );
BOOST_CHECK( std::distance( begin, end ) == index_size );
BOOST_TEST( std::distance( begin, end ) == index_size );
for( index_type::iterator i_it1 = indices.begin(); it != end; ++i_it1, ++it )
{
BOOST_CHECK( *it == elements[ *i_it1 ] );
BOOST_TEST( *it == elements[ *i_it1 ] );
}
it = begin;
@ -74,14 +74,14 @@ void permutation_test()
{
index_type::iterator i_it2 = indices.begin();
std::advance( i_it2, i1 );
BOOST_CHECK( *it == elements[ *i_it2 ] );
BOOST_TEST( *it == elements[ *i_it2 ] );
}
it = begin;
std::advance(it, index_size);
for( index_type::iterator i_it3 = indices.end(); it != begin; )
{
BOOST_CHECK( *--it == elements[ *--i_it3 ] );
BOOST_TEST( *--it == elements[ *--i_it3 ] );
}
it = begin;
@ -90,14 +90,14 @@ void permutation_test()
{
index_type::iterator i_it4 = --indices.end();
std::advance( i_it4, -i2 );
BOOST_CHECK( *--it == elements[ *i_it4 ] );
BOOST_TEST( *--it == elements[ *i_it4 ] );
}
}
int test_main(int, char *[])
int main()
{
permutation_test();
return 0;
return boost::report_errors();
}

View File

@ -1,6 +1,9 @@
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
// libstdc++ from gcc 4.4 has a broken std::tuple that cannot be constructed from a compatible tuple,
// e.g. std::tuple<int, double> from std::tuple<int const&, double const&>.
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
(!defined(BOOST_LIBSTDCXX_VERSION) || BOOST_LIBSTDCXX_VERSION >= 40500)
#include <tuple>
#include <boost/fusion/adapted/std_tuple.hpp>
@ -14,8 +17,8 @@
#else
int main()
{
return 0;
}
{
return 0;
}
#endif