Compare commits

..

1 Commits

Author SHA1 Message Date
4c316ee035 Rework as esp-idf component 2023-11-23 17:17:05 +01:00
113 changed files with 4332 additions and 4662 deletions

View File

@ -1,4 +1,4 @@
# Copyright 2021-2025 Andrey Semashev
# Copyright 2021 Andrey Semashev
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
@ -33,283 +33,209 @@ jobs:
matrix:
include:
# Linux, gcc
- toolset: gcc-4.4
cxxstd: "98,0x"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.4
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.6
cxxstd: "03,0x"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.6
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.7
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.7
- toolset: gcc-4.8
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11"
os: ubuntu-18.04
install:
- g++-4.8
- toolset: gcc-4.9
cxxstd: "11"
os: ubuntu-latest
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.9
- toolset: gcc-5
cxxstd: "11,14,1z"
os: ubuntu-latest
cxxstd: "03,11,14,1z"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-5
- toolset: gcc-6
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install:
- g++-6
- toolset: gcc-7
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install:
- g++-7
- toolset: gcc-8
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install:
- g++-8
- toolset: gcc-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install:
- g++-9
- toolset: gcc-10
cxxstd: "11,14,17,20"
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- g++-10
- toolset: gcc-11
cxxstd: "11,14,17,20,23"
os: ubuntu-22.04
cxxstd: "03,11,14,17,20"
os: ubuntu-20.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
sources:
- "ppa:ubuntu-toolchain-r/test"
- name: UBSAN
toolset: gcc-13
cxxstd: "11,14,17,20,23"
toolset: gcc-11
cxxstd: "03,11,14,17,20"
ubsan: 1
build_variant: debug
os: ubuntu-24.04
os: ubuntu-20.04
install:
- g++-13
- g++-11
sources:
- "ppa:ubuntu-toolchain-r/test"
# Linux, clang
- toolset: clang
compiler: clang++-3.5
cxxstd: "11"
os: ubuntu-latest
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "11,14"
os: ubuntu-latest
cxxstd: "03,11,14"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "11,14"
os: ubuntu-latest
cxxstd: "03,11,14"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "11,14"
os: ubuntu-latest
cxxstd: "03,11,14"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.8
- toolset: clang
compiler: clang++-3.9
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11,14"
os: ubuntu-18.04
install:
- clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11,14"
os: ubuntu-18.04
install:
- clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install:
- clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install:
- clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "11,14,17"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install:
- clang-7
# Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode
- toolset: clang
compiler: clang++-8
cxxstd: "11,14,17,2a"
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install:
- clang-8
- g++-7
gcc_toolchain: 7
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17,2a"
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,20"
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "11,14,17,20"
os: ubuntu-22.04
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-11
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-12
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-12
- g++-11
gcc_toolchain: 11
- toolset: clang
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.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
sources:
- "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- toolset: clang
compiler: clang++-19
cxxstd: "11,14,17,20,23,26"
os: ubuntu-24.04
install:
- clang-19
- libc++-19-dev
- libc++abi-19-dev
sources:
- "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
- clang-12
- libc++-12-dev
- libc++abi-12-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- name: UBSAN
toolset: clang
compiler: clang++-18
cxxstd: "11,14,17,20,23,26"
compiler: clang++-12
cxxstd: "03,11,14,17,20"
cxxflags: -stdlib=libc++
linkflags: "-stdlib=libc++ -lubsan"
linkflags: -stdlib=libc++
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-20.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
timeout-minutes: 20
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
timeout-minutes: 60
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
@ -327,17 +253,13 @@ jobs:
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
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ python python3 perl git cmake
fi
fi
git config --global pack.threads 0
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: |
@ -452,25 +374,11 @@ jobs:
then
DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS")
fi
mkdir -p snapshot
cd snapshot
echo "Downloading library snapshot: https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
curl -L --retry "$NET_RETRY_COUNT" -o "${LIBRARY}-${GITHUB_SHA}.tar.gz" "https://github.com/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz"
tar -xf "${LIBRARY}-${GITHUB_SHA}.tar.gz"
if [ ! -d "${LIBRARY}-${GITHUB_SHA}" ]
then
echo "Library snapshot does not contain the library directory ${LIBRARY}-${GITHUB_SHA}:"
ls -la
exit 1
fi
rm -f "${LIBRARY}-${GITHUB_SHA}.tar.gz"
cd ..
git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root"
cd boost-root
mkdir -p libs
rm -rf "libs/$LIBRARY"
mv -f "../snapshot/${LIBRARY}-${GITHUB_SHA}" "libs/$LIBRARY"
rm -rf "../snapshot"
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[@]}"
@ -492,7 +400,7 @@ jobs:
- name: Run tests
if: matrix.cmake_tests == ''
run: |
cd boost-root
cd ../boost-root
B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}")
if [ -n "${{matrix.build_variant}}" ]
then
@ -519,96 +427,3 @@ jobs:
fi
B2_ARGS+=("libs/$LIBRARY/test")
./b2 "${B2_ARGS[@]}"
- name: Run CMake tests
if: matrix.cmake_tests
run: |
if [ -n "${{matrix.macosx_version_min}}" ]
then
export MACOSX_DEPLOYMENT_TARGET="${{matrix.macosx_version_min}}"
fi
cd boost-root
mkdir __build_static__ && cd __build_static__
cmake ../libs/$LIBRARY/test/test_cmake
cmake --build . --target boost_${LIBRARY}_cmake_self_test -j $BUILD_JOBS
cd ..
mkdir __build_shared__ && cd __build_shared__
cmake -DBUILD_SHARED_LIBS=On ../libs/$LIBRARY/test/test_cmake
cmake --build . --target boost_${LIBRARY}_cmake_self_test -j $BUILD_JOBS
windows:
defaults:
run:
shell: cmd
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: "14"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- 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,2a"
addrmd: 64
os: windows-2019
timeout-minutes: 20
runs-on: ${{matrix.os}}
steps:
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
mkdir snapshot
cd snapshot
echo Downloading library snapshot: https://github.com/%GITHUB_REPOSITORY%/archive/%GITHUB_SHA%.zip
curl -L --retry %NET_RETRY_COUNT% -o "%LIBRARY%-%GITHUB_SHA%.zip" "https://github.com/%GITHUB_REPOSITORY%/archive/%GITHUB_SHA%.zip"
tar -xf "%LIBRARY%-%GITHUB_SHA%.zip"
if not exist "%LIBRARY%-%GITHUB_SHA%\" (
echo Library snapshot does not contain the library directory %LIBRARY%-%GITHUB_SHA%:
dir
exit /b 1
)
del /f "%LIBRARY%-%GITHUB_SHA%.zip"
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
if not exist "libs\" mkdir libs
if exist "libs\%LIBRARY%\" rmdir /s /q "libs\%LIBRARY%"
move /Y "..\snapshot\%LIBRARY%-%GITHUB_SHA%" "libs\%LIBRARY%"
rmdir /s /q "..\snapshot"
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
run: |
cd boost-root
if not "${{matrix.cxxstd}}" == "" set CXXSTD=cxxstd=${{matrix.cxxstd}}
if not "${{matrix.addrmd}}" == "" set ADDRMD=address-model=${{matrix.addrmd}}
if not "${{matrix.build_variant}}" == "" (set BUILD_VARIANT=variant=${{matrix.build_variant}}) else (set BUILD_VARIANT=variant=%DEFAULT_BUILD_VARIANT%)
b2 -j %NUMBER_OF_PROCESSORS% libs/%LIBRARY%/test toolset=${{matrix.toolset}} %CXXSTD% %ADDRMD% %BUILD_VARIANT% embed-manifest-via=linker

View File

@ -3,6 +3,8 @@
# 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
if(NOT DEFINED IDF_TARGET)
cmake_minimum_required(VERSION 3.5...3.20)
project(boost_iterator VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
@ -17,11 +19,43 @@ target_link_libraries(boost_iterator
Boost::assert
Boost::concept_check
Boost::config
Boost::conversion
Boost::core
Boost::detail
Boost::function_types
Boost::fusion
Boost::mpl
Boost::optional
Boost::smart_ptr
Boost::static_assert
Boost::type_traits
Boost::utility
)
else()
FILE(GLOB_RECURSE headers include/*.h include/*.hpp)
idf_component_register(
SRCS
${headers}
INCLUDE_DIRS
include
REQUIRES
boost_assert
boost_concept_check
boost_config
boost_conversion
boost_core
boost_detail
boost_function_types
boost_fusion
boost_mpl
boost_optional
boost_smart_ptr
boost_static_assert
boost_type_traits
boost_utility
)
endif()

View File

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

View File

@ -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
;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
Lab</a>, <a class="reference external" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td>
</tr>
<tr class="field"><th class="field-name">date:</th><td class="field-body">$Date$</td>
</tr>
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003.</td>
</tr>
</tbody>
@ -140,7 +142,7 @@ sequence, rearranged according to some sequence of integer indices.</li>
bidirectional sequence in reverse. Corrects many of the
shortcomings of C++98's <tt class="docutils literal"><span class="pre">std::reverse_iterator</span></tt>.</li>
<li><a class="reference external" href="../../utility/shared_container_iterator.html"><tt class="docutils literal"><span class="pre">shared_container_iterator</span></tt></a>: an iterator over elements of a container whose
lifetime is maintained by a <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
applying some functional transformation to the elements of an
underlying sequence. This component also replaces the old

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -48,14 +48,14 @@ information is needed, call on `indirect_reference`.
Both of these templates are essential to the correct functioning of
[link iterator.specialized.indirect `indirect_iterator`].
[h2 `min_category`]
[h2 `minimum_category`]
`min_category` takes one or more iterator categories or iterator traversal tags
`minimum_category` takes two iterator categories or two iterator traversal tags
and returns the one that is the weakest (i.e. least advanced). For example:
static_assert(
is_same<
min_category<
minimum_category<
std::forward_iterator_tag,
std::random_access_iterator_tag
>::type,

View File

@ -52,10 +52,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:
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
{
m_f0(t.get<0>());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,11 @@
// 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_NO_LVALUE_RETURN_DETECTION
#undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
#ifdef BOOST_ITERATOR_CONFIG_DEF
# undef BOOST_ITERATOR_CONFIG_DEF

View File

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

View File

@ -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_

View File

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

View File

@ -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_

View 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 MINIMUM_CATEGORY_DWA20031119_HPP
# define MINIMUM_CATEGORY_DWA20031119_HPP
# include <boost/iterator/minimum_category.hpp>
namespace boost {
// This import below (as well as the whole header) is for backward compatibility
// with boost/token_iterator.hpp. It should be removed as soon as that header is fixed.
namespace detail {
using iterators::minimum_category;
} // namespace detail
} // namespace boost
#endif // MINIMUM_CATEGORY_DWA20031119_HPP

View File

@ -1,53 +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) 2024 Georgiy Guminov
*/
/*!
* \file iterator/detail/type_traits/conjunction.hpp
*
* This header contains definition of \c conjunction type trait.
*/
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_
#include <type_traits>
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
namespace boost {
namespace iterators {
namespace detail {
using std::conjunction;
} // namespace detail
} // namespace iterator
} // namespace boost
#else
#include <boost/type_traits/conjunction.hpp>
namespace boost {
namespace iterators {
namespace detail {
using boost::conjunction;
} // namespace detail
} // namespace iterator
} // namespace boost
#endif
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_CONJUNCTION_HPP_INCLUDED_

View File

@ -1,53 +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) 2024 Georgiy Guminov
*/
/*!
* \file iterator/detail/type_traits/disjunction.hpp
*
* This header contains definition of \c disjunction type trait.
*/
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_
#include <type_traits>
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
namespace boost {
namespace iterators {
namespace detail {
using std::disjunction;
} // namespace detail
} // namespace iterator
} // namespace boost
#else
#include <boost/type_traits/disjunction.hpp>
namespace boost {
namespace iterators {
namespace detail {
using boost::disjunction;
} // namespace detail
} // namespace iterator
} // namespace boost
#endif
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_DISJUNCTION_HPP_INCLUDED_

View File

@ -1,53 +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) 2024 Georgiy Guminov
*/
/*!
* \file iterator/detail/type_traits/negation.hpp
*
* This header contains definition of \c negation type trait.
*/
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_
#include <type_traits>
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if (defined(__cpp_lib_logical_traits) && (__cpp_lib_logical_traits >= 201510l)) || \
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 140) && (_MSC_FULL_VER >= 190023918) && (BOOST_CXX_VERSION >= 201703l))
namespace boost {
namespace iterators {
namespace detail {
using std::negation;
} // namespace detail
} // namespace iterator
} // namespace boost
#else
#include <boost/type_traits/negation.hpp>
namespace boost {
namespace iterators {
namespace detail {
using boost::negation;
} // namespace detail
} // namespace iterator
} // namespace boost
#endif
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_NEGATION_HPP_INCLUDED_

View File

@ -1,54 +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
*/
/*!
* \file iterator/detail/type_traits/type_identity.hpp
*
* This header contains definition of \c negation type trait.
*/
#ifndef BOOST_ITERATOR_DETAIL_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED_
#define BOOST_ITERATOR_DETAIL_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED_
#include <type_traits>
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#if (defined(__cpp_lib_type_identity) && (__cpp_lib_type_identity >= 201806l)) || \
/* Note: MSVC 19.21 does not define _MSVC_LANG to 202002 in c++latest (C++20) mode but to a value larger than 201703 */ \
(defined(BOOST_MSSTL_VERSION) && (BOOST_MSSTL_VERSION >= 142) && (_MSC_VER >= 1921) && (BOOST_CXX_VERSION > 201703l))
namespace boost {
namespace iterators {
namespace detail {
using std::type_identity;
} // namespace detail
} // namespace iterator
} // namespace boost
#else
#include <boost/type_traits/type_identity.hpp>
namespace boost {
namespace iterators {
namespace detail {
using boost::type_identity;
} // namespace detail
} // namespace iterator
} // namespace boost
#endif
#endif // BOOST_ITERATOR_DETAIL_TYPE_TRAITS_TYPE_IDENTITY_HPP_INCLUDED_

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,67 +4,68 @@
// 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_REVERSE_ITERATOR_23022003THW_HPP
#define BOOST_ITERATOR_REVERSE_ITERATOR_23022003THW_HPP
#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP
#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/enable_if_convertible.hpp>
namespace boost {
namespace iterators {
template< typename Iterator >
class reverse_iterator :
public iterator_adaptor< reverse_iterator< Iterator >, Iterator >
{
friend class iterator_core_access;
//
//
//
template <class Iterator>
class reverse_iterator
: public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
{
typedef iterator_adaptor< reverse_iterator<Iterator>, Iterator > super_t;
private:
using super_t = iterator_adaptor< reverse_iterator< Iterator >, Iterator >;
friend class iterator_core_access;
public:
reverse_iterator() = default;
public:
reverse_iterator() {}
explicit reverse_iterator(Iterator x) :
super_t(x)
{}
explicit reverse_iterator(Iterator x)
: super_t(x) {}
template<
typename OtherIterator,
typename = enable_if_convertible_t< OtherIterator, Iterator >
>
reverse_iterator(reverse_iterator< OtherIterator > const& r) :
super_t(r.base())
{}
template<class OtherIterator>
reverse_iterator(
reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
)
: super_t(r.base())
{}
private:
typename super_t::reference dereference() const
{
Iterator it = this->base_reference();
--it;
return *it;
}
private:
typename super_t::reference dereference() const
{
Iterator it = this->base_reference();
--it;
return *it;
}
void increment() { --this->base_reference(); }
void decrement() { ++this->base_reference(); }
void increment() { --this->base_reference(); }
void decrement() { ++this->base_reference(); }
void advance(typename super_t::difference_type n)
{
this->base_reference() -= n;
}
void advance(typename super_t::difference_type n)
{
this->base_reference() -= n;
}
template< typename OtherIterator >
typename super_t::difference_type distance_to(reverse_iterator< OtherIterator > const& y) const
{
return this->base_reference() - y.base();
}
};
template <class OtherIterator>
typename super_t::difference_type
distance_to(reverse_iterator<OtherIterator> const& y) const
{
return this->base_reference() - y.base();
}
};
template< typename Iterator >
inline reverse_iterator< Iterator > make_reverse_iterator(Iterator x)
{
return reverse_iterator< Iterator >(x);
}
template <class BidirectionalIterator>
inline reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x)
{
return reverse_iterator<BidirectionalIterator>(x);
}
} // namespace iterators
@ -73,4 +74,4 @@ using iterators::make_reverse_iterator;
} // namespace boost
#endif // BOOST_ITERATOR_REVERSE_ITERATOR_23022003THW_HPP
#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,14 +7,15 @@
#include <boost/iterator/filter_iterator.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/new_iterator_tests.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/concept_check.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/iterator/iterator_archetypes.hpp>
#include <boost/cstdlib.hpp>
#include <type_traits>
#include <deque>
#include <iostream>
using boost::dummyT;
@ -228,12 +229,12 @@ int main()
filter_iter(one_or_four(), array, array+N)
, dummyT(1), dummyT(4));
static_assert(
!std::is_convertible<
BOOST_STATIC_ASSERT(
(!boost::is_convertible<
boost::iterator_traversal<filter_iter>::type
, boost::random_access_traversal_tag
>::value,
"Filter interator must have a random_access_traversal_tag.");
>::value
));
//# endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,9 +13,10 @@
#include <numeric>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/iterator/is_readable_iterator.hpp>
#include <boost/iterator/is_lvalue_iterator.hpp>
#include <boost/iterator/enable_if_convertible.hpp>
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
# include <boost/iterator/is_readable_iterator.hpp>
# include <boost/iterator/is_lvalue_iterator.hpp>
#endif
#include <boost/pending/iterator_tests.hpp>
# include <boost/core/lightweight_test.hpp>
@ -28,6 +29,8 @@
#include "static_assert_same.hpp"
#include <boost/iterator/detail/config_def.hpp>
using boost::dummyT;
typedef std::deque<int> storage;
@ -53,6 +56,9 @@ struct ptr_iterator
, V*
, V
, boost::random_access_traversal_tag
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
, V&
#endif
>
{
private:
@ -61,6 +67,9 @@ private:
, V*
, V
, boost::random_access_traversal_tag
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
, V&
#endif
> super_t;
public:
@ -199,10 +208,9 @@ main()
test = static_assert_same<Iter1::reference, int&>::value;
test = static_assert_same<Iter1::pointer, int*>::value;
test = static_assert_same<Iter1::difference_type, std::ptrdiff_t>::value;
static_assert(
std::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value,
"Iterator must have a random access category."
);
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT((boost::is_convertible<Iter1::iterator_category, std::random_access_iterator_tag>::value));
#endif
}
{
@ -211,10 +219,16 @@ main()
test = static_assert_same<Iter1::value_type, int>::value;
test = static_assert_same<Iter1::reference, const int&>::value;
static_assert(boost::is_readable_iterator<Iter1>::value, "Iter1 is expected to be readable.");
static_assert(boost::is_lvalue_iterator<Iter1>::value, "Iter1 is expected to be lvalue iterator.");
#if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
BOOST_STATIC_ASSERT(boost::is_readable_iterator<Iter1>::value);
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter1>::value);
# endif
#endif
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) // borland drops constness
test = static_assert_same<Iter1::pointer, int const*>::value;
#endif
}
{
@ -224,16 +238,14 @@ main()
test = static_assert_same<Iter::value_type, int>::value;
test = static_assert_same<Iter::reference, int const&>::value;
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) // borland drops constness
test = static_assert_same<Iter::pointer, int const*>::value;
#endif
static_assert(
boost::is_non_const_lvalue_iterator<BaseIter>::value,
"boost::is_non_const_lvalue_iterator<BaseIter>::value is expected to be true."
);
static_assert(
boost::is_lvalue_iterator<Iter>::value,
"boost::is_lvalue_iterator<Iter>::value is expected to be true."
);
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
BOOST_STATIC_ASSERT(boost::is_non_const_lvalue_iterator<BaseIter>::value);
BOOST_STATIC_ASSERT(boost::is_lvalue_iterator<Iter>::value);
#endif
typedef modify_traversal<BaseIter, boost::incrementable_traversal_tag> IncrementableIter;

View File

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

View File

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

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