diff --git a/.drone.star b/.drone.star new file mode 100644 index 00000000..0db25622 --- /dev/null +++ b/.drone.star @@ -0,0 +1,36 @@ +# Use, modification, and distribution are +# subject to the Boost Software License, Version 1.0. (See accompanying +# file LICENSE.txt) +# +# Copyright Rene Rivera 2020. + +# For Drone CI we use the Starlark scripting language to reduce duplication. +# As the yaml syntax for Drone CI is rather limited. +# +# +globalenv={} +linuxglobalimage="cppalliance/droneubuntu1604:1" +windowsglobalimage="cppalliance/dronevs2019" + +def main(ctx): + return [ + linux_cxx("TOOLSET=gcc COMPILER=g++ CXXSTD=03,11 Job 0", "g++", packages="", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': 'b6589fc6ab'}, globalenv=globalenv), + linux_cxx("TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11 Job 1", "g++-4.7", packages="g++-4.7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.7', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv), + linux_cxx("TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11 Job 2", "g++-4.8", packages="g++-4.8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.8', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': 'da4b9237ba'}, globalenv=globalenv), + linux_cxx("TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11 Job 3", "g++-4.9", packages="g++-4.9", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.9', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv), + linux_cxx("TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z Job 4", "g++-5", packages="g++-5", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '1b64538924'}, globalenv=globalenv), + linux_cxx("TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z Job 5", "g++-6", packages="g++-6", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'ac3478d69a'}, globalenv=globalenv), + linux_cxx("TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 Job 6", "g++-7", packages="g++-7", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '03,11,14,17', 'DRONE_JOB_UUID': 'c1dfd96eea'}, globalenv=globalenv), + linux_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=03,11 Job 7", "clang++", packages="", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '03,11', 'DRONE_JOB_UUID': '902ba3cda1'}, globalenv=globalenv), + linux_cxx("TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03, Job 8", "clang++-3.5", packages="clang-3.5 libstdc++-4.9-dev", llvm_os="precise", llvm_ver="3.5", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.5', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'fe5dbbcea5'}, globalenv=globalenv), + linux_cxx("TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03, Job 9", "clang++-3.6", packages="clang-3.6", llvm_os="precise", llvm_ver="3.6", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.6', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '0ade7c2cf9'}, globalenv=globalenv), + linux_cxx("TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03, Job 10", "clang++-3.7", packages="clang-3.7", llvm_os="precise", llvm_ver="3.7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.7', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'b1d5781111'}, globalenv=globalenv), + linux_cxx("TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03, Job 11", "clang++-3.8", packages="clang-3.8 libstdc++-4.9-dev", llvm_os="precise", llvm_ver="3.8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.8', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '17ba079149'}, globalenv=globalenv), + linux_cxx("TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03, Job 12", "clang++-3.9", packages="clang-3.9 libstdc++-4.9-dev", llvm_os="precise", llvm_ver="3.9", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.9', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': '7b52009b64'}, globalenv=globalenv), + linux_cxx("TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03, Job 13", "clang++-4.0", packages="clang-4.0", llvm_os="trusty", llvm_ver="4.0", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'bd307a3ec3'}, globalenv=globalenv), + linux_cxx("TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03, Job 14", "clang++-5.0", packages="clang-5.0", llvm_os="trusty", llvm_ver="5.0", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'fa35e19212'}, globalenv=globalenv), + osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,1 Job 15", "clang++", packages="", buildtype="boost", buildscript="drone", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '03,11,14,1z', 'DRONE_JOB_UUID': 'f1abd67035'}, globalenv=globalenv), + ] + +# from https://github.com/boostorg/boost-ci +load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx") diff --git a/.drone/drone.sh b/.drone/drone.sh new file mode 100755 index 00000000..a10e6eee --- /dev/null +++ b/.drone/drone.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Copyright 2020 Rene Rivera, Sam Darwin +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) + +set -e +export TRAVIS_BUILD_DIR=$(pwd) +export DRONE_BUILD_DIR=$(pwd) +export TRAVIS_BRANCH=$DRONE_BRANCH +export VCS_COMMIT_ID=$DRONE_COMMIT +export GIT_COMMIT=$DRONE_COMMIT +export REPO_NAME=$DRONE_REPO +export PATH=~/.local/bin:/usr/local/bin:$PATH + +if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then + +echo '==================================> INSTALL' + +BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true +cd .. +git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root +cd boost-root +git submodule update --init tools/build +git submodule update --init libs/config +git submodule update --init tools/boostdep +cp -r $TRAVIS_BUILD_DIR/* libs/optional +python tools/boostdep/depinst/depinst.py optional +./bootstrap.sh +./b2 headers + +echo '==================================> SCRIPT' + +echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam +./b2 libs/optional/test toolset=$TOOLSET cxxstd=$CXXSTD + +fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..bf415cb5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,614 @@ +name: CI + +on: + pull_request: + push: + branches: + - master + - develop + - feature/** + +env: + UBSAN_OPTIONS: print_stacktrace=1 + +jobs: + posix: + strategy: + fail-fast: false + matrix: + include: + - toolset: gcc-4.8 + cxxstd: "03,11" + os: ubuntu-latest + container: ubuntu:18.04 + install: g++-4.8-multilib + address-model: 32,64 + - toolset: gcc-5 + cxxstd: "03,11,14,1z" + os: ubuntu-latest + container: ubuntu:18.04 + install: g++-5-multilib + address-model: 32,64 + - toolset: gcc-6 + cxxstd: "03,11,14,1z" + os: ubuntu-latest + container: ubuntu:18.04 + install: g++-6-multilib + address-model: 32,64 + - toolset: gcc-7 + cxxstd: "03,11,14,17" + os: ubuntu-latest + container: ubuntu:18.04 + install: g++-7-multilib + address-model: 32,64 + - toolset: gcc-8 + cxxstd: "03,11,14,17,2a" + os: ubuntu-20.04 + install: g++-8-multilib + address-model: 32,64 + - toolset: gcc-9 + cxxstd: "03,11,14,17,2a" + os: ubuntu-20.04 + install: g++-9-multilib + address-model: 32,64 + - toolset: gcc-10 + cxxstd: "03,11,14,17,2a" + os: ubuntu-20.04 + install: g++-10-multilib + address-model: 32,64 + - toolset: gcc-11 + cxxstd: "03,11,14,17,20" + os: ubuntu-22.04 + install: g++-11-multilib + address-model: 32,64 + - toolset: gcc-12 + cxxstd: "03,11,14,17,20,2b" + os: ubuntu-22.04 + install: g++-12-multilib + address-model: 32,64 + - toolset: gcc-13 + cxxstd: "03,11,14,17,20,2b" + os: ubuntu-24.04 + install: g++-13-multilib + address-model: 32,64 + - toolset: clang + compiler: clang++-3.9 + cxxstd: "03,11,14" + os: ubuntu-latest + container: ubuntu:18.04 + install: clang-3.9 + - toolset: clang + compiler: clang++-4.0 + cxxstd: "03,11,14" + os: ubuntu-latest + container: ubuntu:18.04 + install: clang-4.0 + - toolset: clang + compiler: clang++-5.0 + cxxstd: "03,11,14,1z" + os: ubuntu-latest + container: ubuntu:18.04 + install: clang-5.0 + - toolset: clang + compiler: clang++-6.0 + cxxstd: "03,11,14,17" + os: ubuntu-20.04 + install: clang-6.0 + - toolset: clang + compiler: clang++-7 + cxxstd: "03,11,14,17" + os: ubuntu-20.04 + install: clang-7 + - toolset: clang + compiler: clang++-8 + cxxstd: "03,11,14,17" + os: ubuntu-20.04 + install: clang-8 + - toolset: clang + compiler: clang++-9 + cxxstd: "03,11,14,17,2a" + os: ubuntu-20.04 + install: clang-9 + - toolset: clang + compiler: clang++-10 + cxxstd: "03,11,14,17,2a" + os: ubuntu-20.04 + - toolset: clang + compiler: clang++-11 + cxxstd: "03,11,14,17,2a" + os: ubuntu-20.04 + - toolset: clang + compiler: clang++-12 + cxxstd: "03,11,14,17,20" + os: ubuntu-20.04 + - toolset: clang + compiler: clang++-13 + cxxstd: "03,11,14,17,20,2b" + container: ubuntu:22.04 + os: ubuntu-latest + install: clang-13 + - toolset: clang + compiler: clang++-14 + cxxstd: "03,11,14,17,20,2b" + container: ubuntu:22.04 + os: ubuntu-latest + install: clang-14 + - toolset: clang + compiler: clang++-15 + cxxstd: "03,11,14,17,20,2b" + container: ubuntu:22.04 + os: ubuntu-latest + install: clang-15 + - toolset: clang + compiler: clang++-16 + cxxstd: "03,11,14,17,20,2b" + os: ubuntu-24.04 + install: clang-16 + - toolset: clang + compiler: clang++-17 + cxxstd: "03,11,14,17,20,2b" + os: ubuntu-24.04 + install: clang-17 + - toolset: clang + cxxstd: "03,11,14,17,20,2b" + os: macos-13 + + runs-on: ${{matrix.os}} + container: + image: ${{matrix.container}} + volumes: + - /node20217:/node20217:rw,rshared + - ${{ startsWith(matrix.container, 'ubuntu:1') && '/node20217:/__e/node20:ro,rshared' || ' ' }} + + defaults: + run: + shell: bash + + steps: + - name: Setup container environment + if: matrix.container + run: | + apt-get update + apt-get -y install sudo python3 git g++ curl + if [[ "${{matrix.container}}" == "ubuntu:1"* ]]; then + # Node 20 doesn't work with Ubuntu 16/18 glibc: https://github.com/actions/checkout/issues/1590 + curl -sL https://archives.boost.io/misc/node/node-v20.9.0-linux-x64-glibc-217.tar.xz | tar -xJ --strip-components 1 -C /node20217 + fi + + - uses: actions/checkout@v4 + + - name: Install packages + if: matrix.install + run: | + sudo apt-get update + sudo apt-get -y install ${{matrix.install}} + + - name: Setup Boost + run: | + echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY + LIBRARY=${GITHUB_REPOSITORY#*/} + echo LIBRARY: $LIBRARY + echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV + echo GITHUB_BASE_REF: $GITHUB_BASE_REF + echo GITHUB_REF: $GITHUB_REF + REF=${GITHUB_BASE_REF:-$GITHUB_REF} + REF=${REF#refs/heads/} + echo REF: $REF + BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true + echo BOOST_BRANCH: $BOOST_BRANCH + cd .. + git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY + git submodule update --init tools/boostdep + python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY + ./bootstrap.sh + ./b2 -d0 headers + + - name: Create user-config.jam + if: matrix.compiler + run: | + echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam + + - name: Run tests + run: | + cd ../boost-root + ./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release + + windows: + strategy: + fail-fast: false + matrix: + include: + - toolset: msvc-14.0 + cxxstd: 14,latest + 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,20,latest" + addrmd: 32,64 + os: windows-2022 + - toolset: gcc + cxxstd: "03,11,14,17,2a" + addrmd: 64 + os: windows-2019 + + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v3 + + - name: Setup Boost + shell: cmd + 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% + cd .. + git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% + cmd /c bootstrap + b2 -d0 headers + + - name: Run tests + shell: cmd + run: | + cd ../boost-root + b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker + + posix-cmake-subdir: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-20.04 + - os: ubuntu-22.04 + - os: macos-12 + - os: macos-13 + + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v3 + + - name: Install packages + if: matrix.install + run: sudo apt-get -y install ${{matrix.install}} + + - name: Setup Boost + run: | + echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY + LIBRARY=${GITHUB_REPOSITORY#*/} + echo LIBRARY: $LIBRARY + echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV + echo GITHUB_BASE_REF: $GITHUB_BASE_REF + echo GITHUB_REF: $GITHUB_REF + REF=${GITHUB_BASE_REF:-$GITHUB_REF} + REF=${REF#refs/heads/} + echo REF: $REF + BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true + echo BOOST_BRANCH: $BOOST_BRANCH + cd .. + git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY + + - name: Use library with add_subdirectory + run: | + cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test + mkdir __build__ && cd __build__ + cmake .. + cmake --build . + ctest --output-on-failure --no-tests=error + + posix-cmake-install: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-20.04 + - os: ubuntu-22.04 + - os: macos-12 + - os: macos-13 + + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v3 + + - name: Install packages + if: matrix.install + run: sudo apt-get -y install ${{matrix.install}} + + - name: Setup Boost + run: | + echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY + LIBRARY=${GITHUB_REPOSITORY#*/} + echo LIBRARY: $LIBRARY + echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV + echo GITHUB_BASE_REF: $GITHUB_BASE_REF + echo GITHUB_REF: $GITHUB_REF + REF=${GITHUB_BASE_REF:-$GITHUB_REF} + REF=${REF#refs/heads/} + echo REF: $REF + BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true + echo BOOST_BRANCH: $BOOST_BRANCH + cd .. + git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY + + - name: Configure + run: | + cd ../boost-root + mkdir __build__ && cd __build__ + cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local .. + + - name: Install + run: | + cd ../boost-root/__build__ + cmake --build . --target install + + - name: Use the installed library + run: | + cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__ + cmake -DCMAKE_INSTALL_PREFIX=~/.local .. + cmake --build . + ctest --output-on-failure --no-tests=error + + posix-cmake-test: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-20.04 + - os: ubuntu-22.04 + - os: macos-12 + - os: macos-13 + + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v3 + + - name: Install packages + if: matrix.install + run: sudo apt-get -y install ${{matrix.install}} + + - name: Setup Boost + run: | + echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY + LIBRARY=${GITHUB_REPOSITORY#*/} + echo LIBRARY: $LIBRARY + echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV + echo GITHUB_BASE_REF: $GITHUB_BASE_REF + echo GITHUB_REF: $GITHUB_REF + REF=${GITHUB_BASE_REF:-$GITHUB_REF} + REF=${REF#refs/heads/} + echo REF: $REF + BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true + echo BOOST_BRANCH: $BOOST_BRANCH + cd .. + git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY + + - name: Configure + run: | + cd ../boost-root + mkdir __build__ && cd __build__ + cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON .. + + - name: Build tests + run: | + cd ../boost-root/__build__ + cmake --build . --target tests + + - name: Run tests + run: | + cd ../boost-root/__build__ + ctest --output-on-failure --no-tests=error + + windows-cmake-subdir: + strategy: + fail-fast: false + matrix: + include: + - os: windows-2019 + - os: windows-2022 + + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v3 + + - name: Setup Boost + shell: cmd + 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% + cd .. + git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% + + - name: Use library with add_subdirectory (Debug) + shell: cmd + run: | + cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test + mkdir __build__ && cd __build__ + cmake .. + cmake --build . --config Debug + ctest --output-on-failure --no-tests=error -C Debug + + - name: Use library with add_subdirectory (Release) + shell: cmd + run: | + cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test/__build__ + cmake --build . --config Release + ctest --output-on-failure --no-tests=error -C Release + + windows-cmake-install: + strategy: + fail-fast: false + matrix: + include: + - os: windows-2019 + - os: windows-2022 + + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v3 + + - name: Setup Boost + shell: cmd + 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% + cd .. + git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% + + - name: Configure + shell: cmd + run: | + cd ../boost-root + mkdir __build__ && cd __build__ + cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix .. + + - name: Install (Debug) + shell: cmd + run: | + cd ../boost-root/__build__ + cmake --build . --target install --config Debug + + - name: Install (Release) + shell: cmd + run: | + cd ../boost-root/__build__ + cmake --build . --target install --config Release + + - name: Use the installed library (Debug) + shell: cmd + run: | + cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test && mkdir __build__ && cd __build__ + cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix .. + cmake --build . --config Debug + ctest --output-on-failure --no-tests=error -C Debug + + - name: Use the installed library (Release) + shell: cmd + run: | + cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test/__build__ + cmake --build . --config Release + ctest --output-on-failure --no-tests=error -C Release + + windows-cmake-test: + strategy: + fail-fast: false + matrix: + include: + - os: windows-2019 + - os: windows-2022 + + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v3 + + - name: Setup Boost + shell: cmd + 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% + cd .. + git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root + cd boost-root + xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ + git submodule update --init tools/boostdep + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% + + - name: Configure + shell: cmd + run: | + cd ../boost-root + mkdir __build__ && cd __build__ + cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DBUILD_TESTING=ON .. + + - name: Build tests (Debug) + shell: cmd + run: | + cd ../boost-root/__build__ + cmake --build . --target tests --config Debug + + - name: Run tests (Debug) + shell: cmd + run: | + cd ../boost-root/__build__ + ctest --output-on-failure --no-tests=error -C Debug + + - name: Build tests (Release) + shell: cmd + run: | + cd ../boost-root/__build__ + cmake --build . --target tests --config Release + + - name: Run tests (Release) + shell: cmd + run: | + cd ../boost-root/__build__ + ctest --output-on-failure --no-tests=error -C Release diff --git a/.travis.yml b/.travis.yml index 2903ba19..b6055859 100644 --- a/.travis.yml +++ b/.travis.yml @@ -151,6 +151,7 @@ matrix: - llvm-toolchain-precise-3.9 - os: linux + dist: trusty compiler: clang++-4.0 env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z addons: @@ -162,6 +163,7 @@ matrix: - llvm-toolchain-trusty-4.0 - os: linux + dist: trusty compiler: clang++-5.0 env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z addons: diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c836a4c..80799e10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,28 +1,33 @@ -# Copyright 2019 Mike Dev +# Generated by `boostdep --cmake optional` +# Copyright 2020, 2021 Peter Dimov # 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 -# -# NOTE: CMake support for Boost.Optional is currently experimental at best -# and the interface is likely to change in the future - -cmake_minimum_required( VERSION 3.5 ) -project( BoostOptional ) - -add_library( boost_optional INTERFACE ) -add_library( Boost::optional ALIAS boost_optional ) - -target_include_directories( boost_optional INTERFACE include ) - -target_link_libraries( boost_optional - INTERFACE - Boost::assert - Boost::config - Boost::core - Boost::detail - Boost::move - Boost::predef - Boost::static_assert - Boost::throw_exception - Boost::type_traits - Boost::utility +# https://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.5...3.20) + +project(boost_optional VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) + +add_library(boost_optional INTERFACE) +add_library(Boost::optional ALIAS boost_optional) + +target_include_directories(boost_optional INTERFACE include) +if(NOT CMAKE_VERSION VERSION_LESS "3.19") + file(GLOB_RECURSE headers include/*.hpp) + target_sources(boost_optional PRIVATE ${headers}) +endif() + +target_link_libraries(boost_optional + INTERFACE + Boost::assert + Boost::config + Boost::core + Boost::throw_exception + Boost::type_traits ) +target_compile_features(boost_optional INTERFACE cxx_std_11) + +if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") + + add_subdirectory(test) + +endif() diff --git a/build.jam b/build.jam new file mode 100644 index 00000000..b08ea0b0 --- /dev/null +++ b/build.jam @@ -0,0 +1,23 @@ +# 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/config//boost_config + /boost/core//boost_core + /boost/throw_exception//boost_throw_exception + /boost/type_traits//boost_type_traits ; + +project /boost/optional ; + +explicit + [ alias boost_optional : : : : $(boost_dependencies) include ] + [ alias all : boost_optional test ] + ; + +call-if : boost-library optional + ; diff --git a/doc/00_optional.qbk b/doc/00_optional.qbk index 00b60965..4809c285 100644 --- a/doc/00_optional.qbk +++ b/doc/00_optional.qbk @@ -2,7 +2,7 @@ [quickbook 1.4] [authors [Cacciola Carballal, Fernando Luis]] [copyright 2003-2007 Fernando Luis Cacciola Carballal] - [copyright 2014-2018 Andrzej Krzemieński] + [copyright 2014-2024 Andrzej Krzemieński] [category miscellaneous] [id optional] [dirname optional] @@ -38,30 +38,36 @@ Distributed under the Boost Software License, Version 1.0. [/ Other web resources ] [def __HASKELL__ [@http://www.haskell.org/ Haskell]] -[def __SGI_DEFAULT_CONSTRUCTIBLE__ [@http://www.sgi.com/tech/stl/DefaultConstructible.html `DefaultConstructible`]] -[def __SGI_LESS_THAN_COMPARABLE__ [@http://www.sgi.com/tech/stl/LessThanComparable.html `LessThanComparable`]] -[def __SGI_EQUALITY_COMPARABLE__ [@http://www.sgi.com/tech/stl/EqualityComparable.html `EqualityComparable`]] -[def __SGI_GENERATOR__ [@http://www.sgi.com/tech/stl/Generator.html `Generator`]] +[def __STD_DEFAULT_CONSTRUCTIBLE__ [@https://en.cppreference.com/w/cpp/named_req/DefaultConstructible `DefaultConstructible`]] +[def __STD_LESS_THAN_COMPARABLE__ [@https://en.cppreference.com/w/cpp/named_req/LessThanComparable `LessThanComparable`]] +[def __STD_EQUALITY_COMPARABLE__ [@https://en.cppreference.com/w/cpp/named_req/EqualityComparable `EqualityComparable`]] +[def __SGI_GENERATOR__ [@http://www.rrsd.com/software_development/stl/stl/Generator.html `Generator`]] [/ Icons ] [def __SPACE__ [$images/space.png]] -[def __GO_TO__ [$images/callouts/R.png]] +[def __GO_TO__ [$images/R.png]] + +[/ Common terms ] + +[def __UB__ [@https://en.cppreference.com/w/cpp/language/ub ['undefined behavior]]] [section Introduction] -Class template `optional` is a wrapper for representing 'optional' (or 'nullable') objects who may not (yet) contain a valid value. Optional objects offer full value semantics; they are good for passing by value and usage inside STL containers. This is a header-only library. +Class template `optional` is a wrapper for representing 'optional' (or 'nullable') +objects who may not (yet) contain a valid value. Optional objects offer full value semantics; +they are good for passing by value and usage inside STL containers. This is a header-only C++11 library. [heading Problem] -Suppose we want to read a parameter form a config file which represents some integral value, let's call it `"MaxValue"`. It is possible that this parameter is not specified; such situation is no error. It is valid to not specify the parameter and in that case the program is supposed to behave slightly differently. Also, suppose that any possible value of type `int` is a valid value for `"MaxValue"`, so we cannot just use `-1` to represent the absence of the parameter in the config file. +Suppose we want to read a parameter from a config file which represents some integral value, let's call it `"MaxValue"`. It is possible that this parameter is not specified; such situation is no error. It is valid to not specify the parameter and in that case the program is supposed to behave slightly differently. Also, suppose that any possible value of type `int` is a valid value for `"MaxValue"`, so we cannot just use `-1` to represent the absence of the parameter in the config file. [heading Solution] This is how you solve it with `boost::optional`: #include - + boost::optional getConfigParam(std::string name); // return either an int or a `not-an-int` int main() @@ -71,22 +77,20 @@ This is how you solve it with `boost::optional`: else runWithNoMax(); } - + [endsect] [include 01_quick_start.qbk] -[section Tutorial] -[include 10_motivation.qbk] +[section:design Design Overview and Rationale] [include 11_development.qbk] -[include 12_when_to_use.qbk] -[include 13_relational_operators.qbk] -[include 14_io.qbk] -[include 15_optional_references.qbk] -[include 16_in_place_factories.qbk] -[include 17_gotchas.qbk] -[include 18_exception_safety.qbk] -[include 19_type_requirements.qbk] -[include 1A_on_performance.qbk] +[include 12_relational_operators.qbk] +[include 13_convenience.qbk] +[include 15_io.qbk] +[include 16_optional_references.qbk] +[include 17_in_place_factories.qbk] +[include 18_gotchas.qbk] +[include 19_exception_safety.qbk] +[include 1A_type_requirements.qbk] [endsect] [section:reference Reference] [include 21_ref_none.qbk] @@ -99,8 +103,11 @@ This is how you solve it with `boost::optional`: [endsect] [include 29_ref_optional_convenience.qbk] [endsect] +[section:advice Advice] +[include 31_when_to_use.qbk] +[include 32_on_performance.qbk] +[endsect] [include 90_dependencies.qbk] -[include 91_relnotes.qbk] -[include 92_acknowledgments.qbk] - - +[include 91_comparison_with_std.qbk] +[include 92_relnotes.qbk] +[include 93_acknowledgments.qbk] diff --git a/doc/01_quick_start.qbk b/doc/01_quick_start.qbk index 6bfc3982..9d2c35de 100644 --- a/doc/01_quick_start.qbk +++ b/doc/01_quick_start.qbk @@ -10,22 +10,30 @@ ] -[section Quick Start] +[section Quick Overview] [section Optional return values] -Let's write and use a converter function that converts a `std::string` to an `int`. It is possible that for a given string (e.g. `"cat"`) there exists no value of type `int` capable of representing the conversion result. We do not consider such situation an error. We expect that the converter can be used only to check if the conversion is possible. A natural signature for this function can be: +Let's write and use a converter function that converts a `std::string` to an `int`. +It is possible that for a given string (e.g. `"cat"`) there exists no value of type +`int` capable of representing the conversion result. We do not consider such +situation an error. We expect that the converter can be used only to check if +the conversion is possible. A natural signature for this function can be: #include boost::optional convert(const std::string& text); -All necessary functionality can be included with one header ``. The above function signature means that the function can either return a value of type `int` or a flag indicating that no value of `int` is available. This does not indicate an error. It is like one additional value of `int`. This is how we can use our function: +All necessary functionality can be included with one header ``. +The above function signature means that the function can either return a value +of type `int` or a flag indicating that no value of `int` is available. +This does not indicate an error. It is like one additional value of `int`. +This is how we can use our function: const std::string& text = /*... */; boost::optional oi = convert(text); // move-construct if (oi) // contextual conversion to bool int i = *oi; // operator* - + In order to test if `optional` contains a value, we use the contextual conversion to type `bool`. Because of this we can combine the initialization of the optional object and the test into one instruction: if (boost::optional oi = convert(text)) @@ -34,7 +42,7 @@ In order to test if `optional` contains a value, we use the contextual conversio We extract the contained value with `operator*` (and with `operator->` where it makes sense). An attempt to extract the contained value of an uninitialized optional object is an ['undefined behaviour] (UB). This implementation guards the call with `BOOST_ASSERT`. Therefore you should be sure that the contained value is there before extracting. For instance, the following code is reasonably UB-safe: int i = *convert("100"); - + This is because we know that string value `"100"` converts to a valid value of `int`. If you do not like this potential UB, you can use an alternative way of extracting the contained value: try { @@ -44,18 +52,18 @@ This is because we know that string value `"100"` converts to a valid value of ` // deal with it } -This version throws an exception upon an attempt to access a non-existent contained value. If your way of dealing with the missing value is to use some default, like `0`, there exists a yet another alternative: +This version throws an exception upon an attempt to access a nonexistent contained value. If your way of dealing with the missing value is to use some default, like `0`, there exists a yet another alternative: int k = convert(text).value_or(0); - + This uses the `atoi`-like approach to conversions: if `text` does not represent an integral number just return `0`. Finally, you can provide a callback to be called when trying to access the contained value fails: int fallback_to_default() { - cerr << "could not convert; using -1 instead" << endl; + cerr << "could not convert; using -1 instead" << endl; return -1; } - + int l = convert(text).value_or_eval(fallback_to_default); This will call the provided callback and return whatever the callback returns. The callback can have side effects: they will only be observed when the optional object does not contain a value. @@ -63,7 +71,7 @@ This will call the provided callback and return whatever the callback returns. T Now, let's consider how function `convert` can be implemented. boost::optional convert(const std::string& text) - { + { std::stringstream s(text); int i; if ((s >> i) && s.get() == std::char_traits::eof()) @@ -72,7 +80,7 @@ Now, let's consider how function `convert` can be implemented. return boost::none; } -Observe the two return statements. `return i` uses the converting constructor that can create `optional` from `T`. Thus constructed optional object is initialized and its value is a copy of `i`. The other return statement uses another converting constructor from a special tag `boost::none`. It is used to indicate that we want to create an uninitialized optional object. +Observe the two return statements. `return i` uses the converting constructor that can create `optional` from `T`. Thus constructed optional object is initialized and its value is a copy of `i`. The other return statement uses another converting constructor from a special tag `boost::none`. It is used to indicate that we want to create an uninitialized optional object. [endsect] @@ -91,7 +99,7 @@ We could write function `convert` in a slightly different manner, so that it has return ans; } -The default constructor of `optional` creates an unitialized optional object. Unlike with `int`s you cannot have an `optional` in an indeterminate state. Its state is always well defined. Instruction `ans = i` initializes the optional object. It uses the 'mixed' assignment from `int`. In general, for `optional`, when an assignment from `T` is invoked, it can do two things. If the optional object is not initialized (our case here), it initializes the contained value using `T`'s copy constructor. If the optional object is already initialized, it assigns the new value to it using `T`'s copy assignment. +The default constructor of `optional` creates an uninitialized optional object. Unlike with `int`s you cannot have an `optional` in an indeterminate state. Its state is always well defined. Instruction `ans = i` initializes the optional object. It uses the 'mixed' assignment from `int`. In general, for `optional`, when an assignment from `T` is invoked, it can do two things. If the optional object is not initialized (our case here), it initializes the contained value using `T`'s copy constructor. If the optional object is already initialized, it assigns the new value to it using `T`'s copy assignment. [endsect] [section Optional data members] @@ -101,42 +109,23 @@ Suppose we want to implement a ['lazy load] optimization. This is because we do class Widget { mutable boost::optional resource_; - + public: Widget() {} - + const Resource& getResource() const // not thread-safe { if (resource_ == boost::none) resource_.emplace("resource", "arguments"); - + return *resource_; } }; - -`optional`'s default constructor creates an uninitialized optional. No call to `Resource`'s default constructor is attempted. `Resource` doesn't have to be __SGI_DEFAULT_CONSTRUCTIBLE__. In function `getResource` we first check if `resource_` is initialized. This time we do not use the contextual conversion to `bool`, but a comparison with `boost::none`. These two ways are equivalent. Function `emplace` initializes the optional in-place by perfect-forwarding the arguments to the constructor of `Resource`. No copy- or move-construction is involved here. `Resource` doesn't even have to be `MoveConstructible`. -[note Function `emplace` is only available on compilers that support rvalue references and variadic templates. If your compiler does not support these features and you still need to avoid any move-constructions, use [link boost_optional.tutorial.in_place_factories In-Place Factories].] +`optional`'s default constructor creates an uninitialized optional. No call to `Resource`'s default constructor is attempted. `Resource` doesn't have to be __STD_DEFAULT_CONSTRUCTIBLE__. In function `getResource` we first check if `resource_` is initialized. This time we do not use the contextual conversion to `bool`, but a comparison with `boost::none`. These two ways are equivalent. Function `emplace` initializes the optional in-place by perfect-forwarding the arguments to the constructor of `Resource`. No copy- or move-construction is involved here. `Resource` doesn't even have to be `MoveConstructible`. -[endsect] - -[section Bypassing unnecessary default construction] - -Suppose we have class `Date`, which does not have a default constructor: there is no good candidate for a default date. We have a function that returns two dates in form of a `boost::tuple`: - - boost::tuple getPeriod(); - -In other place we want to use the result of `getPeriod`, but want the two dates to be named: `begin` and `end`. We want to implement something like 'multiple return values': +[note Function `emplace` is only available on compilers that support rvalue references and variadic templates. If your compiler does not support these features and you still need to avoid any move-constructions, use [link boost_optional.design.in_place_factories In-Place Factories].] - Date begin, end; // Error: no default ctor! - boost::tie(begin, end) = getPeriod(); - -The second line works already, this is the capability of __BOOST_TUPLE__ library, but the first line won't work. We could set some invented initial dates, but it is confusing and may be an unacceptable cost, given that these values will be overwritten in the next line anyway. This is where `optional` can help: - - boost::optional begin, end; - boost::tie(begin, end) = getPeriod(); - -It works because inside `boost::tie` a move-assignment from `T` is invoked on `optional`, which internally calls a move-constructor of `T`. [endsect] [section Storage in containers] @@ -144,15 +133,63 @@ It works because inside `boost::tie` a move-assignment from `T` is invoked on `o Suppose you want to ask users to choose some number (an `int`). One of the valid responses is to choose nothing, which is represented by an uninitialized `optional`. You want to make a histogram showing how many times each choice was made. You can use an `std::map`: std::map, int> choices; - + for (int i = 0; i < LIMIT; ++i) { boost::optional choice = readChoice(); ++choices[choice]; } - -This works because `optional` is __SGI_LESS_THAN_COMPARABLE__ whenever `T` is __SGI_LESS_THAN_COMPARABLE__. In this case the state of being uninitialized is treated as a yet another value of `T`, which is compared less than any value of `T`. + +This works because `optional` is __STD_LESS_THAN_COMPARABLE__ whenever `T` is __STD_LESS_THAN_COMPARABLE__. +In this case the state of being uninitialized is treated as a yet another value of `T`, +which is compared less than any value of `T`. +`optional` can also be stored as a key in `std::unordered_map` and `std::unordered_set` +as it provides specializations for `std::hash`. [endsect] +[section Monadic interface] + +The monadic interface of `optional` allows the application of functions +to optional values without resorting to the usage of explicit `if`-statements. + +Function `map` takes a function mapping type `T` onto type `U` and maps an `optional` +onto an `optional` using the provided function. + + int length(const string& s){ return s.size(); }; + + optional null{}, thin{""}, word{"word"}; + assert (null.map(length) == none); + assert (thin.map(length) == 0); + assert (word.map(length) == 4); + +Function `flat_map` is similar, but it requires the function to return an +`optional` for some type `V`. This `optional` becomes the return type of +`flat_map`. + + optional first_char(const string& s) { + if (s.empty()) return none; + else return s[0]; + }; + + optional null{}, thin{""}, word{"word"}; + assert (null.flat_map(first_char) == none); + assert (thin.flat_map(first_char) == none); + assert (word.flat_map(first_char) == 'w'); + +These functions can be combined in one expression reflecting a chain of computations: + + auto get_contents(path p) -> optional; + auto trim(string) -> string; + auto length(string) -> int; + + auto trimmed_size_of(optional p) -> int + { + return p.flat_map(get_contents) + .map(trim) + .map(length) + .value_or(0); + } + + [endsect] - +[endsect] diff --git a/doc/10_motivation.qbk b/doc/10_motivation.qbk deleted file mode 100644 index fe5b6dac..00000000 --- a/doc/10_motivation.qbk +++ /dev/null @@ -1,80 +0,0 @@ -[/ - Boost.Optional - - Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal - Copyright (c) 2014 Andrzej Krzemienski - - 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) -] - -[section Motivation] - -Consider these functions which should return a value but which might not have -a value to return: - -* (A) `double sqrt(double n );` -* (B) `char get_async_input();` -* (C) `point polygon::get_any_point_effectively_inside();` - -There are different approaches to the issue of not having a value to return. - -A typical approach is to consider the existence of a valid return value as a -postcondition, so that if the function cannot compute the value to return, it -has either undefined behavior (and can use assert in a debug build) or uses a -runtime check and throws an exception if the postcondition is violated. This -is a reasonable choice for example, for function (A), because the lack of a -proper return value is directly related to an invalid parameter (out of domain -argument), so it is appropriate to require the callee to supply only parameters -in a valid domain for execution to continue normally. - -However, function (B), because of its asynchronous nature, does not fail just -because it can't find a value to return; so it is incorrect to consider such -a situation an error and assert or throw an exception. This function must -return, and somehow, must tell the callee that it is not returning a meaningful -value. - -A similar situation occurs with function (C): it is conceptually an error to -ask a ['null-area] polygon to return a point inside itself, but in many -applications, it is just impractical for performance reasons to treat this as -an error (because detecting that the polygon has no area might be too expensive -to be required to be tested previously), and either an arbitrary point -(typically at infinity) is returned, or some efficient way to tell the callee -that there is no such point is used. - -There are various mechanisms to let functions communicate that the returned -value is not valid. One such mechanism, which is quite common since it has -zero or negligible overhead, is to use a special value which is reserved to -communicate this. Classical examples of such special values are `EOF`, -`string::npos`, points at infinity, etc... - -When those values exist, i.e. the return type can hold all meaningful values -['plus] the ['signal] value, this mechanism is quite appropriate and well known. -Unfortunately, there are cases when such values do not exist. In these cases, -the usual alternative is either to use a wider type, such as `int` in place of -`char`; or a compound type, such as `std::pair`. - -Returning a `std::pair`, thus attaching a boolean flag to the result -which indicates if the result is meaningful, has the advantage that can be -turned into a consistent idiom since the first element of the pair can be -whatever the function would conceptually return. For example, the last two -functions could have the following interface: - - std::pair get_async_input(); - std::pair polygon::get_any_point_effectively_inside(); - -These functions use a consistent interface for dealing with possibly nonexistent -results: - - std::pair p = poly.get_any_point_effectively_inside(); - if ( p.second ) - flood_fill(p.first); - -However, not only is this quite a burden syntactically, it is also error prone -since the user can easily use the function result (first element of the pair) -without ever checking if it has a valid value. - -Clearly, we need a better idiom. - -[endsect] diff --git a/doc/11_development.qbk b/doc/11_development.qbk index de5d00d7..e5ef1ed3 100644 --- a/doc/11_development.qbk +++ b/doc/11_development.qbk @@ -2,250 +2,129 @@ Boost.Optional Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal + Copyright (c) 2024 andrzej Krzemieński 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) ] -[section Design Overview] - -[section The models] - -In C++, we can ['declare] an object (a variable) of type `T`, and we can give this -variable an ['initial value] (through an ['initializer]. (cf. 8.5)). -When a declaration includes a non-empty initializer (an initial value is given), -it is said that the object has been initialized. -If the declaration uses an empty initializer (no initial value is given), and -neither default nor value initialization applies, it is said that the object is -[*uninitialized]. Its actual value exist but has an ['indeterminate initial value] -(cf. 8.5/11). -`optional` intends to formalize the notion of initialization (or lack of it) -allowing a program to test whether an object has been initialized and stating -that access to the value of an uninitialized object is undefined behavior. That -is, when a variable is declared as `optional` and no initial value is given, -the variable is ['formally] uninitialized. A formally uninitialized optional object -has conceptually no value at all and this situation can be tested at runtime. It -is formally ['undefined behavior] to try to access the value of an uninitialized -optional. An uninitialized optional can be assigned a value, in which case its initialization state changes to initialized. Furthermore, given the formal -treatment of initialization states in optional objects, it is even possible to -reset an optional to ['uninitialized]. - -In C++ there is no formal notion of uninitialized objects, which means that -objects always have an initial value even if indeterminate. -As discussed on the previous section, this has a drawback because you need -additional information to tell if an object has been effectively initialized. -One of the typical ways in which this has been historically dealt with is via -a special value: `EOF`, `npos`, -1, etc... This is equivalent to adding the -special value to the set of possible values of a given type. This super set of -`T` plus some ['nil_t]—where `nil_t` is some stateless POD—can be modeled in modern -languages as a [*discriminated union] of T and nil_t. Discriminated unions are -often called ['variants]. A variant has a ['current type], which in our case is either -`T` or `nil_t`. -Using the __BOOST_VARIANT__ library, this model can be implemented in terms of `boost::variant`. -There is precedent for a discriminated union as a model for an optional value: -the __HASKELL__ [*Maybe] built-in type constructor. Thus, a discriminated union -`T+nil_t` serves as a conceptual foundation. - -A `variant` follows naturally from the traditional idiom of extending -the range of possible values adding an additional sentinel value with the -special meaning of ['Nothing]. However, this additional ['Nothing] value is largely -irrelevant for our purpose since our goal is to formalize the notion of -uninitialized objects and, while a special extended value can be used to convey -that meaning, it is not strictly necessary in order to do so. - -The observation made in the last paragraph about the irrelevant nature of the -additional `nil_t` with respect to [_purpose] of `optional` suggests an -alternative model: a ['container] that either has a value of `T` or nothing. - -As of this writing I don't know of any precedent for a variable-size -fixed-capacity (of 1) stack-based container model for optional values, yet I -believe this is the consequence of the lack of practical implementations of -such a container rather than an inherent shortcoming of the container model. - -In any event, both the discriminated-union or the single-element container -models serve as a conceptual ground for a class representing optional—i.e. -possibly uninitialized—objects. -For instance, these models show the ['exact] semantics required for a wrapper -of optional values: - -Discriminated-union: - -* [*deep-copy] semantics: copies of the variant implies copies of the value. -* [*deep-relational] semantics: comparisons between variants matches both -current types and values -* If the variant's current type is `T`, it is modeling an ['initialized] optional. -* If the variant's current type is not `T`, it is modeling an ['uninitialized] -optional. -* Testing if the variant's current type is `T` models testing if the optional -is initialized -* Trying to extract a `T` from a variant when its current type is not `T`, models -the undefined behavior of trying to access the value of an uninitialized optional - -Single-element container: - -* [*deep-copy] semantics: copies of the container implies copies of the value. -* [*deep-relational] semantics: comparisons between containers compare container -size and if match, contained value -* If the container is not empty (contains an object of type `T`), it is modeling -an ['initialized] optional. -* If the container is empty, it is modeling an ['uninitialized] optional. -* Testing if the container is empty models testing if the optional is -initialized -* Trying to extract a `T` from an empty container models the undefined behavior -of trying to access the value of an uninitialized optional +[section Design Goals] + +In C++ you can create an automatic object of a scalar type, and manipulate it, +without assigning it the initial value. + + { + int i; // indeterminate value + populate(&i); + cout << i; + } + +Such an object is said to have ['indeterminate value]. If you subsequently +assign a proper value to the object, all is fine; but if the program tries to +read an indeterminate value, this is ['undefined behavior'], and since C++26 +this is ['erroneous behavior]. +In any case, the program is now likely to do something else than what the +programmer intended. In case you have some object `i`, and you do not know if it +has an indeterminate value, or a normal, intended, value, there is no way to +check it, because the checking would require reading the value. + +This is one of the primary problems that `optional` was intended to address: so +that you may have a type that knows whether it has been assigned a proper value, +and it can tell you that if requested. + +In the case of type `int` the internal representation of such a class could be: + + class OptionalInt + { + bool _has_value = false; + int _value; + }; + +In the general case, the internal representation is something equivalent to: + + template + class Optional + { + bool _has_value = false; + alignas(T) char _value [sizeof(T)]; + }; + +Next, because we need to pass around these "optional" `int`s as normal `int`s, +like returning them from functions, when copying, we need to copy `_has_value`, +which indicates whether we have the value or not, and, if we do have value, and +only then, to also copy `_value`. + +This means that our type requires ['deep copy] semantics. + +[note +This is a C++ equivalent of a +[@https://hackage.haskell.org/package/base-4.20.0.1/docs/Data-Maybe.html Maybe] +monad in [@http://www.haskell.org/ Haskell]. +] [endsect] -[section The semantics] - -Objects of type `optional` are intended to be used in places where objects of -type `T` would but which might be uninitialized. Hence, `optional`'s purpose is -to formalize the additional possibly uninitialized state. -From the perspective of this role, `optional` can have the same operational -semantics of `T` plus the additional semantics corresponding to this special -state. -As such, `optional` could be thought of as a ['supertype] of `T`. Of course, we -can't do that in C++, so we need to compose the desired semantics using a -different mechanism. -Doing it the other way around, that is, making `optional` a ['subtype] of `T` -is not only conceptually wrong but also impractical: it is not allowed to -derive from a non-class type, such as a built-in type. - -We can draw from the purpose of `optional` the required basic semantics: - -* [*Default Construction:] To introduce a formally uninitialized wrapped -object. -* [*Direct Value Construction via copy:] To introduce a formally initialized -wrapped object whose value is obtained as a copy of some object. -* [*Deep Copy Construction:] To obtain a new yet equivalent wrapped object. -* [*Direct Value Assignment (upon initialized):] To assign a value to the -wrapped object. -* [*Direct Value Assignment (upon uninitialized):] To initialize the wrapped -object with a value obtained as a copy of some object. -* [*Assignment (upon initialized):] To assign to the wrapped object the value -of another wrapped object. -* [*Assignment (upon uninitialized):] To initialize the wrapped object with -value of another wrapped object. -* [*Deep Relational Operations (when supported by the type T):] To compare -wrapped object values taking into account the presence of uninitialized states. -* [*Value access:] To unwrap the wrapped object. -* [*Initialization state query:] To determine if the object is formally -initialized or not. -* [*Swap:] To exchange wrapped objects. (with whatever exception safety -guarantees are provided by `T`'s swap). -* [*De-initialization:] To release the wrapped object (if any) and leave the -wrapper in the uninitialized state. - -Additional operations are useful, such as converting constructors and -converting assignments, in-place construction and assignment, and safe -value access via a pointer to the wrapped object or null. +[section:iface Interface Design] +One part of the interface is for modifying and setting the initial state of +the object. It has to be able to say that -[endsect] +* we want to store a specific value of type `T`, +* we want to store no value. + +The default constructor stores no value. Other than that, we require that +the assignment and construction from a `T` reflects the former, while assignment +and construction of a special ['tag] value `none` reflect the latter need. + + optional o1; // contains no value + optional o2 = 2; // contains value 2 + optional o3 = none; // contains no value + + o1 = 1; // assign value 1 + o2 = none; // assign a no-value + o3 = {}; // assign a no-value + +[heading Inspecting the State] + +Inspecting the state of an optional object requires two steps: -[section The Interface] - -Since the purpose of optional is to allow us to use objects with a formal -uninitialized additional state, the interface could try to follow the -interface of the underlying `T` type as much as possible. In order to choose -the proper degree of adoption of the native `T` interface, the following must -be noted: Even if all the operations supported by an instance of type `T` are -defined for the entire range of values for such a type, an `optional` -extends such a set of values with a new value for which most -(otherwise valid) operations are not defined in terms of `T`. - -Furthermore, since `optional` itself is merely a `T` wrapper (modeling a `T` -supertype), any attempt to define such operations upon uninitialized optionals -will be totally artificial w.r.t. `T`. - -This library chooses an interface which follows from `T`'s interface only for -those operations which are well defined (w.r.t the type `T`) even if any of the -operands are uninitialized. These operations include: construction, -copy-construction, assignment, swap and relational operations. - -For the value access operations, which are undefined (w.r.t the type `T`) when -the operand is uninitialized, a different interface is chosen (which will be -explained next). - -Also, the presence of the possibly uninitialized state requires additional -operations not provided by `T` itself which are supported by a special interface. - -[heading Lexically-hinted Value Access in the presence of possibly -uninitialized optional objects: The operators * and ->] - -A relevant feature of a pointer is that it can have a [*null pointer value]. -This is a ['special] value which is used to indicate that the pointer is not -referring to any object at all. In other words, null pointer values convey -the notion of nonexistent objects. - -This meaning of the null pointer value allowed pointers to became a ['de -facto] standard for handling optional objects because all you have to do -to refer to a value which you don't really have is to use a null pointer -value of the appropriate type. Pointers have been used for decades—from -the days of C APIs to modern C++ libraries—to ['refer] to optional (that is, -possibly nonexistent) objects; particularly as optional arguments to a -function, but also quite often as optional data members. - -The possible presence of a null pointer value makes the operations that -access the pointee's value possibly undefined, therefore, expressions which -use dereference and access operators, such as: `( *p = 2 )` and `( p->foo() )`, -implicitly convey the notion of optionality, and this information is tied to -the ['syntax] of the expressions. That is, the presence of operators `*` and `->` -tell by themselves —without any additional context— that the expression will -be undefined unless the implied pointee actually exist. - -Such a ['de facto] idiom for referring to optional objects can be formalized -in the form of a concept: the __OPTIONAL_POINTEE__ concept. -This concept captures the syntactic usage of operators `*`, `->` and -contextual conversion to `bool` to convey the notion of optionality. - -However, pointers are good to [_refer] to optional objects, but not particularly -good to handle the optional objects in all other respects, such as initializing -or moving/copying them. The problem resides in the shallow-copy of pointer -semantics: if you need to effectively move or copy the object, pointers alone -are not enough. The problem is that copies of pointers do not imply copies of -pointees. For example, as was discussed in the motivation, pointers alone -cannot be used to return optional objects from a function because the object -must move outside from the function and into the caller's context. - -A solution to the shallow-copy problem that is often used is to resort to -dynamic allocation and use a smart pointer to automatically handle the details -of this. For example, if a function is to optionally return an object `X`, it can -use `shared_ptr` as the return value. However, this requires dynamic allocation -of `X`. If `X` is a built-in or small POD, this technique is very poor in terms of -required resources. Optional objects are essentially values so it is very -convenient to be able to use automatic storage and deep-copy semantics to -manipulate optional values just as we do with ordinary values. Pointers do -not have this semantics, so are inappropriate for the initialization and -transport of optional values, yet are quite convenient for handling the access -to the possible undefined value because of the idiomatic aid present in the -__OPTIONAL_POINTEE__ concept incarnated by pointers. - - -[heading Optional as a model of OptionalPointee] - -For value access operations `optional<>` uses operators `*` and `->` to -lexically warn about the possibly uninitialized state appealing to the -familiar pointer semantics w.r.t. to null pointers. +* check if we have the value or not, +* if so, read the stored value. + +This 'procedure' is characteristic of inspecting pointers in C++, therefore the +pointer-like syntax was chosen to represent this. + + void inspect (optional os) + { + if (os) { // contextual conversion to `bool` + read_string(*os); // `operator*` to access the stored value + read_int(os->size()); // `operator->` as shortcut for accessing members + } + } + +Also, similarly to pointers, if you access the value when it is not there, +you trigger __UB__. +This library detects and reports it via +[@../../../assert/assert.html `BOOST_ASSERT()`]. This common property of +pointers and `optional<>` has been formalized into a concept __OPTIONAL_POINTEE__. + +However, there is also the counter-intuitive part. All pointers embed ['shallow-copy] +semantics: when you copy a pointer, the pointed-to object stays at the same location +and you can access it via either of the pointers. This is unlike optional objects +where the represented value is copied along. [caution -However, it is particularly important to note that `optional<>` objects -are not pointers. [_`optional<>` is not, and does not model, a pointer]. +Optional objects are not pointers. ] -For instance, `optional<>` does not have shallow-copy so does not alias: -two different optionals never refer to the ['same] value unless `T` itself is -a reference (but may have ['equivalent] values). -The difference between an `optional` and a pointer must be kept in mind, -particularly because the semantics of relational operators are different: -since `optional` is a value-wrapper, relational operators are deep: they -compare optional values; but relational operators for pointers are shallow: -they do not compare pointee values. -As a result, you might be able to replace `optional` by `T*` on some -situations but not always. Specifically, on generic code written for both, -you cannot use relational operators directly, and must use the template -functions __FUNCTION_EQUAL_POINTEES__ and __FUNCTION_LESS_POINTEES__ instead. +There is a similar difference in relational operations: they compare deeply for +`optional<>`, while they are shallow for pointers. -[endsect] +[note +When you need a deep relational operations that work uniformly for `optional<>` +and pointers in generic contexts, use functions +[@../../../utility/OptionalPointee.html#equal `equal_pointees()`] and +[@../../../utility/OptionalPointee.html#less `less_pointees()`]. +] [endsect] diff --git a/doc/13_relational_operators.qbk b/doc/12_relational_operators.qbk similarity index 84% rename from doc/13_relational_operators.qbk rename to doc/12_relational_operators.qbk index 861a4e86..3336bec0 100644 --- a/doc/13_relational_operators.qbk +++ b/doc/12_relational_operators.qbk @@ -1,37 +1,37 @@  [section Relational operators] -Type `optional` is __SGI_EQUALITY_COMPARABLE__ whenever `T` is __SGI_EQUALITY_COMPARABLE__. Two optional objects containing a value compare in the same way as their contained values. The uninitialized state of `optional` is treated as a distinct value, equal to itself, and unequal to any value of type `T`: +Type `optional` is __STD_EQUALITY_COMPARABLE__ whenever `T` is __STD_EQUALITY_COMPARABLE__. Two optional objects containing a value compare in the same way as their contained values. The uninitialized state of `optional` is treated as a distinct value, equal to itself, and unequal to any value of type `T`: boost::optional oN = boost::none; boost::optional o0 = 0; boost::optional o1 = 1; - + assert(oN != o0); assert(o1 != oN); assert(o0 != o1); assert(oN == oN); assert(o0 == o0); - -The converting constructor from `T` as well as from `boost::none` implies the existence and semantics of the mixed comparison between `T` and `optional` as well as between `none_t` and `optionl`: + +The converting constructor from `T` as well as from `boost::none` implies the existence and semantics of the mixed comparison between `T` and `optional` as well as between `none_t` and `optional`: assert(oN != 0); assert(o1 != boost::none); assert(o0 != 1); assert(oN == boost::none); assert(o0 == 0); - + This mixed comparison has a practical interpretation, which is occasionally useful: boost::optional choice = ask_user(); if (choice == 2) start_procedure_2(); - + In the above example, the meaning of the comparison is 'user chose number 2'. If user chose nothing, he didn't choose number 2. -In case where `optional` is compared to `none`, it is not required that `T` be __SGI_EQUALITY_COMPARABLE__. +In case where `optional` is compared to `none`, it is not required that `T` be __STD_EQUALITY_COMPARABLE__. -In a similar manner, type `optional` is __SGI_LESS_THAN_COMPARABLE__ whenever `T` is __SGI_LESS_THAN_COMPARABLE__. The optional object containing no value is compared less than any value of `T`. To illustrate this, if the default ordering of `size_t` is {`0`, `1`, `2`, ...}, the default ordering of `optional` is {`boost::none`, `0`, `1`, `2`, ...}. This order does not have a practical interpretation. The goal is to have any semantically correct default ordering in order for `optional` to be usable in ordered associative containers (wherever `T` is usable). +In a similar manner, type `optional` is __STD_LESS_THAN_COMPARABLE__ whenever `T` is __STD_LESS_THAN_COMPARABLE__. The optional object containing no value is compared less than any value of `T`. To illustrate this, if the default ordering of `size_t` is {`0`, `1`, `2`, ...}, the default ordering of `optional` is {`boost::none`, `0`, `1`, `2`, ...}. This order does not have a practical interpretation. The goal is to have any semantically correct default ordering in order for `optional` to be usable in ordered associative containers (wherever `T` is usable). Mixed relational operators are the only case where the contained value of an optional object can be inspected without the usage of value accessing function (`operator*`, `value`, `value_or`). [endsect] diff --git a/doc/13_convenience.qbk b/doc/13_convenience.qbk new file mode 100644 index 00000000..0989b5a7 --- /dev/null +++ b/doc/13_convenience.qbk @@ -0,0 +1,102 @@ + +[section Convenience Conversions and Deductions] + +Unlike `std::optional`, `boost::optional` does not offer a number of +"convenience" converting constructors, mixed relational operations and +deductions for class template parameters. + + std::optional oi = 1; // OK + + std:string_view sv = "hi"; + std::optional os = sv; // OK + os == sv; // OK + + std::optional osv; + std::optional os2 = osv; // OK + os2 == osv; // OK + +They are practical, and sometimes stem from the argument for consistency: +if `(optT && *optT == u)` works then `(optT == u)` should also work. + +However, these intelligent convenience functions sometimes produce results +that are counter to the programmer intentions and produce silent bugs. + +Consider a more complicated example: + + Threshold th = /*...*/; + std::optional o = th; + assert (o); + +In this code, can we expect that thus initialized `optional` contains a value? +The answer is: it depends on the type of `Threshold`. It can be defined as: + + using Threshold = std::optional; + +And then the assertion will fire. This is because in this case the intelligence +decides that since we already have an optional, the additional wrapping into +a yet another optional is unnecessary. + +If we explicitly specify the template type, the situation doesn't get less +complicated. + + Threshold th; + std::optional o = th; + assert(o); + +Can this assertion fire? Now we have two competing constructors: + + template + optional(U const&); + + template + optional(optional const&); + +Which one will get chosen? Actually, we are lucky, and it is going to be the +first one due to concept tricks. But let's try a different example: + + Threshold th; + std::optional o = th; + assert(o); + assert(o == th); + +Here, the first assertion passes, but the second one fires. This is because +there are two competing overloads of the comparison operator: + + template + bool operator==(optional const&, U const&); + + template + bool operator==(optional const&, optional const&); + +And this time there is no concept trickery, so the second overload is chosen, +and gives different results: we are comparing an optional object `th`, which does +not contain a value, with an optional object `o` which does contain a value. + +This problem -- that the operations compile, but have runtime behavior counter +to programmer's intuition -- gains new significance with the introduction of +concepts to C++. + + static_assert(std::equality_comparable_with, Threshold>); + +Concepts have both syntactic constraints and semantic constraints. Syntactic +constraints are statically checked by the compiler. For semantic constraints, +functions that use the concept trust the programmer that these constraints are +met, and if not, this is __UB__. + +These are problems with `std::optional`. `boost::optional` doesn't have these +problems, because it does not offer the said convenience operations. + +The design principle for `boost::optional` is not to offer functionality that +nicely deduces the programmer intentions in 95% of the cases, and in the remaining +5% renders effects counter to programmer expectations. + +Instead, this library recommends using a more verbose syntax that works in 100% +of the cases: + + Threshold th; + auto o = boost::make_potional(th); // *always* add a new layer of optionality + + return boost::equal_pointees(o, th); // *always* unpack optionals for comparison + return o && *o == th; // *always* treat the right-hand side argument as value + +[endsect] diff --git a/doc/14_io.qbk b/doc/15_io.qbk similarity index 100% rename from doc/14_io.qbk rename to doc/15_io.qbk diff --git a/doc/15_optional_references.qbk b/doc/16_optional_references.qbk similarity index 93% rename from doc/15_optional_references.qbk rename to doc/16_optional_references.qbk index acb1226f..10664d72 100644 --- a/doc/15_optional_references.qbk +++ b/doc/16_optional_references.qbk @@ -16,14 +16,19 @@ some operations are not available in this case: * Value-access via pointer Also, even though `optional` treats it wrapped pseudo-object much as -a real value, a true real reference is stored so aliasing will ocurr: +a real value, a true real reference is stored so aliasing will occur: * Copies of `optional` will copy the references but all these references will nonetheless refer to the same object. * Value-access will actually provide access to the referenced object rather than the reference itself. -[caution On compilers that do not conform to Standard C++ rules of reference binding, some operations on optional references are disabled in order to prevent subtle bugs. For more details see [link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section].] +[caution +On compilers that do not conform to Standard C++ rules of reference binding, +some operations on optional references are disabled in order to prevent subtle +bugs. For more details see +[link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section]. +] [heading Rvalue references] @@ -45,7 +50,7 @@ the first time) to the object. Clearly, there is no other choice. optional orb(x) ; ora = orb ; // now 'ora' is bound to 'x' through 'rx' *ora = 2 ; // Changes value of 'x' through 'ora' - assert(x==2); + assert(x==2); If you assign to a bare C++ reference, the assignment is forwarded to the referenced object; its value changes but the reference is never rebound. @@ -71,8 +76,8 @@ bare C++ references. optional orb(rb) ; ora = orb ; // 'ora' is rebound to 'b' *ora = 3 ; // Changes value of 'b' (not 'a') - assert(a==1); - assert(b==3); + assert(a==1); + assert(b==3); [heading Rationale] diff --git a/doc/16_in_place_factories.qbk b/doc/17_in_place_factories.qbk similarity index 100% rename from doc/16_in_place_factories.qbk rename to doc/17_in_place_factories.qbk diff --git a/doc/17_gotchas.qbk b/doc/18_gotchas.qbk similarity index 92% rename from doc/17_gotchas.qbk rename to doc/18_gotchas.qbk index 5cfa36b7..8e894e9a 100644 --- a/doc/17_gotchas.qbk +++ b/doc/18_gotchas.qbk @@ -61,12 +61,12 @@ When an optional object that contains a value is moved from (is a source of move assert (opi); assert (*opi == nullptr); -Quite a lot of people expect that when an object that contains a value is moved from, its contained value should be destroyed. This is not so, for performance reasons. Current semantics allow the implementation of `boost::opiotnal` to be trivially copyable when `T` is trivial. +Quite a lot of people expect that when an object that contains a value is moved from, its contained value should be destroyed. This is not so, for performance reasons. Current semantics allow the implementation of `boost::optional` to be trivially copyable when `T` is trivial. [endsect] [section Mixed relational comparisons] -Because `T` is convertible to `optional` and because `opiotnal` is __SGI_LESS_THAN_COMPARABLE__ when `T` is __SGI_LESS_THAN_COMPARABLE__, +Because `T` is convertible to `optional` and because `optional` is __STD_LESS_THAN_COMPARABLE__ when `T` is __STD_LESS_THAN_COMPARABLE__, you can sometimes get an unexpected runtime result where you would rather expect a compiler error: optional Flight_plan::weight(); // sometimes no weight can be returned @@ -80,7 +80,7 @@ you can sometimes get an unexpected runtime result where you would rather expect [section False positive with -Wmaybe-uninitialized] -Sometimes on GCC compilers below version 5.1 you may get an -Wmaybe-uninitialized warning when copiling with option -02 on a perfectly valid `boost::optional` usage. For instance in this program: +Sometimes on GCC compilers below version 5.1 you may get an -Wmaybe-uninitialized warning when compiling with option -02 on a perfectly valid `boost::optional` usage. For instance in this program: #include @@ -108,4 +108,4 @@ This is obviously redundant, but makes the warning disappear. [endsect] -[endsect] \ No newline at end of file +[endsect] diff --git a/doc/18_exception_safety.qbk b/doc/19_exception_safety.qbk similarity index 97% rename from doc/18_exception_safety.qbk rename to doc/19_exception_safety.qbk index 331104b7..bb779a9b 100644 --- a/doc/18_exception_safety.qbk +++ b/doc/19_exception_safety.qbk @@ -51,7 +51,7 @@ Operation `emplace` provides basic exception safety guarantee. If it throws, the Unless `swap` on optional is customized, its primary implementation forwards calls to `T`'s `swap` or move constructor (depending on the initialization state of the optional objects). Thus, if both `T`'s `swap` and move constructor never throw, `swap` on `optional` never throws. similarly, if both `T`'s `swap` and move constructor offer strong guarantee, `swap` on `optional` also offers a strong guarantee. -In case `swap` on optional is customized, the call to `T`'s move constructor are replaced with the calls to `T`'s default constructor followed by `swap`. (This is more useful on older compilers that do not support move semantics, when one wants to acheive stronger exception safety guarantees.) In this case the exception safety guarantees for `swap` are reliant on the guarantees of `T`'s `swap` and default constructor +In case `swap` on optional is customized, the call to `T`'s move constructor are replaced with the calls to `T`'s default constructor followed by `swap`. (This is more useful on older compilers that do not support move semantics, when one wants to achieve stronger exception safety guarantees.) In this case the exception safety guarantees for `swap` are reliant on the guarantees of `T`'s `swap` and default constructor [endsect] diff --git a/doc/19_type_requirements.qbk b/doc/1A_type_requirements.qbk similarity index 91% rename from doc/19_type_requirements.qbk rename to doc/1A_type_requirements.qbk index 033a6eb3..214fcbff 100644 --- a/doc/19_type_requirements.qbk +++ b/doc/1A_type_requirements.qbk @@ -7,8 +7,8 @@ The very minimum requirement of `optional` is that `T` is a complete type and assert(o == none); // check if initialized assert(!o); // o.value(); // always throws - -But this is practically useless. In order for `optional` to be able to do anything useful and offer all the spectrum of ways of accessing the contained value, `T` needs to have at least one accessible constructor. In that case you need to initialize the optional object with function `emplace()`, or if your compiler does not support it, resort to [link boost_optional.tutorial.in_place_factories In-Place Factories]: + +But this is practically useless. In order for `optional` to be able to do anything useful and offer all the spectrum of ways of accessing the contained value, `T` needs to have at least one accessible constructor. In that case you need to initialize the optional object with function `emplace()`, or if your compiler does not support it, resort to [link boost_optional.design.in_place_factories In-Place Factories]: optional o; o.emplace("T", "ctor", "params"); @@ -17,13 +17,13 @@ If `T` is __MOVE_CONSTRUCTIBLE__, `optional` is also __MOVE_CONSTRUCTIBLE__ a optional o = make_T(); optional p = optional(); - + If `T` is __COPY_CONSTRUCTIBLE__, `optional` is also __COPY_CONSTRUCTIBLE__ and can be easily initialized from an lvalue of type `T`: T v = make_T(); optional o = v; optional p = o; - + If `T` is not `MoveAssignable`, it is still possible to reset the value of `optional` using function `emplace()`: optional o = make_T(); @@ -33,6 +33,6 @@ If `T` is `Moveable` (both __MOVE_CONSTRUCTIBLE__ and `MoveAssignable`) then `op Similarly, if `T` is `Copyable` (both __COPY_CONSTRUCTIBLE__ and `CopyAssignable`) then `optional` is also `Copyable` and additionally can be constructed and assigned from an lvalue of type `T`. -`T` ['is not] required to be __SGI_DEFAULT_CONSTRUCTIBLE__. +`T` ['is not] required to be __STD_DEFAULT_CONSTRUCTIBLE__. [endsect] diff --git a/doc/21_ref_none.qbk b/doc/21_ref_none.qbk index 011eff7c..65eaa81f 100644 --- a/doc/21_ref_none.qbk +++ b/doc/21_ref_none.qbk @@ -17,8 +17,8 @@ namespace boost { class none_t {/* see below */}; -const none_t none (/* see below */); - +inline constexpr none_t none (/* see below */); + } // namespace boost ``` diff --git a/doc/23_ref_optional_io.qbk b/doc/23_ref_optional_io.qbk index a9425d46..57f06779 100644 --- a/doc/23_ref_optional_io.qbk +++ b/doc/23_ref_optional_io.qbk @@ -26,11 +26,11 @@ template template std::basic_ostream& operator<<(std::basic_ostream& out, none_t const&); ``[link reference_operator_ostream_none __GO_TO__]`` - + template std::basic_istream& operator>>(std::basic_istream& in, optional& v); ``[link reference_operator_istream __GO_TO__]`` - + } // namespace boost ``` @@ -41,10 +41,11 @@ template [#reference_operator_ostream] - -`template ` [br] -\u00A0\u00A0\u00A0\u00A0`std::basic_ostream&` [br] -\u00A0\u00A0\u00A0\u00A0`operator<<(std::basic_ostream& out, optional const& v);` +``` +template +std::basic_ostream& +operator<<(std::basic_ostream& out, optional const& v); +``` * [*Effect:] Outputs an implementation-defined string. The output contains the information about whether the optional object contains a value or not. If `v` contains a value, the output contains result of calling `out << *v`. * [*Returns:] `out`. @@ -52,9 +53,11 @@ template __SPACE__ [#reference_operator_ostream_none] -`template ` [br] -\u00A0\u00A0\u00A0\u00A0`std::basic_ostream&` [br] -\u00A0\u00A0\u00A0\u00A0`operator<<(std::basic_ostream& out, none_t);` +``` +template +std::basic_ostream& +operator<<(std::basic_ostream& out, none_t); +``` * [*Effect:] Outputs an implementation-defined string. * [*Returns:] `out`. @@ -62,12 +65,14 @@ __SPACE__ __SPACE__ [#reference_operator_istream] -`template ` [br] -\u00A0\u00A0\u00A0\u00A0`std::basic_ostream&` [br] -\u00A0\u00A0\u00A0\u00A0`operator>>(std::basic_istream& in, optional& v);` +``` +template +std::basic_ostream& +operator>>(std::basic_istream& in, optional& v); +``` -* [*Requires:] `T` is __SGI_DEFAULT_CONSTRUCTIBLE__ and __MOVE_CONSTRUCTIBLE__. -* [*Effect:] Reads the value of optional object from `in`. If the string representation indicates that the optional object should contain a value, `v` contains a value and its contained value is obtained as if by default-constructing an object `o` of type `T` and then calling `in >> o`; otherwise `v` does not contain a value, and the previously contained value (if any) has been destroyed. +* [*Requires:] `T` is __STD_DEFAULT_CONSTRUCTIBLE__ and __MOVE_CONSTRUCTIBLE__. +* [*Effect:] Reads the value of optional object from `in`. If the string representation indicates that the optional object should contain a value, `v` contains a value and its contained value is obtained as if by default-constructing an object `o` of type `T` and then calling `in >> o`; otherwise `v` does not contain a value, and the previously contained value (if any) has been destroyed. * [*Returns:] `out`. [endsect] diff --git a/doc/27_ref_optional_synopsis.qbk b/doc/27_ref_optional_synopsis.qbk index bcd18e87..d0df811c 100644 --- a/doc/27_ref_optional_synopsis.qbk +++ b/doc/27_ref_optional_synopsis.qbk @@ -16,10 +16,10 @@ namespace boost { class in_place_init_t { /* see below */ } ; ``[link reference_in_place_init __GO_TO__]`` - const in_place_init_t in_place_init ( /* see below */ ) ; + inline constexpr in_place_init_t in_place_init ( /* see below */ ) ; class in_place_init_if_t { /*see below*/ } ; ``[link reference_in_place_init_if __GO_TO__]`` - const in_place_init_if_t in_place_init_if ( /*see below*/ ) ; + inline constexpr in_place_init_if_t in_place_init_if ( /*see below*/ ) ; template class optional ; ``[link reference_operator_template __GO_TO__]`` @@ -73,6 +73,16 @@ } // namespace boost + namespace std { + + template + struct hash > ; ``[link reference_std_hash_spec __GO_TO__]`` + + template + struct hash > ; ``[link reference_std_hash_spec __GO_TO__]`` + + } // namespace std + [endsect] @@ -92,7 +102,7 @@ } -Classes `in_place_init_t` and `in_place_init_if_t` are empty clsses. Their purpose is to control overload resolution in the initialization of optional objects. +Classes `in_place_init_t` and `in_place_init_if_t` are empty classes. Their purpose is to control overload resolution in the initialization of optional objects. They are empty, trivially copyable classes with disabled default constructor. [endsect] @@ -218,7 +228,7 @@ They are empty, trivially copyable classes with disabled default constructor. [#reference_operator_template_spec] template - class optional // specilization for lvalue references + class optional // specialization for lvalue references { public : diff --git a/doc/28_ref_optional_semantics.qbk b/doc/28_ref_optional_semantics.qbk index 2fa75008..9a5986f9 100644 --- a/doc/28_ref_optional_semantics.qbk +++ b/doc/28_ref_optional_semantics.qbk @@ -163,7 +163,7 @@ assert (!uninit); optional> uinit2 ( std::move(uninit) ) ; assert ( uninit2 == uninit ); -optional> init( std::uniqye_ptr(new T(2)) ); +optional> init( std::unique_ptr(new T(2)) ); assert ( **init == T(2) ) ; optional> init2 ( std::move(init) ) ; @@ -233,7 +233,7 @@ __SPACE__ arguments `std::forward(args)...`. * [*Postconditions:] `*this` is initialized. * [*Throws:] Any exception thrown by the selected constructor of `T`. -* [*Notes: ] `T` need not be __MOVE_CONSTRUCTIBLE__. On compilers that do not suppor variadic templates or rvalue references, this constuctor is available in limited functionality. For details [link optional_emplace_workaround see here]. +* [*Notes: ] `T` need not be __MOVE_CONSTRUCTIBLE__. * [*Example:] `` @@ -257,7 +257,7 @@ __SPACE__ * [*Effect:] If `condition` is `true`, initializes the contained value as if direct-non-list-initializing an object of type `T` with the arguments `std::forward(args)...`. * [*Postconditions:] `bool(*this) == condition`. * [*Throws:] Any exception thrown by the selected constructor of `T`. -* [*Notes: ] `T` need not be __MOVE_CONSTRUCTIBLE__. On compilers that do not suppor variadic templates or rvalue references, this constuctor is available in limited functionality. For details [link optional_emplace_workaround see here]. +* [*Notes: ] `T` need not be __MOVE_CONSTRUCTIBLE__. * [*Example:] `` @@ -281,7 +281,7 @@ factory. * [*Postconditions: ] `*this` is [_initialized] and its value is ['directly given] from the factory `f` (i.e., the value [_is not copied]). * [*Throws:] Whatever the `T` constructor called by the factory throws. -* [*Notes:] See [link boost_optional.tutorial.in_place_factories In-Place Factories] +* [*Notes:] See [link boost_optional.design.in_place_factories In-Place Factories] * [*Exception Safety:] Exceptions can only be thrown during the call to the `T` constructor used by the factory; in that case, this constructor has no effect. @@ -502,7 +502,7 @@ __SPACE__ * [*Postconditions: ] `*this` is [_initialized]. * [*Throws:] Whatever the selected `T`'s constructor throws. * [*Exception Safety:] If an exception is thrown during the initialization of `T`, `*this` is ['uninitialized]. -* [*Notes:] `T` need not be __MOVE_CONSTRUCTIBLE__ or `MoveAssignable`. On compilers that do not suppor variadic templates or rvalue references, this function is available in limited functionality. For details [link optional_emplace_workaround see here]. +* [*Notes:] `T` need not be __MOVE_CONSTRUCTIBLE__ or `MoveAssignable`. * [*Example:] `` T v; @@ -524,7 +524,7 @@ factory. * [*Postconditions: ] `*this` is [_initialized] and its value is ['directly given] from the factory `f` (i.e., the value [_is not copied]). * [*Throws:] Whatever the `T` constructor called by the factory throws. -* [*Notes:] See [link boost_optional.tutorial.in_place_factories In-Place Factories] +* [*Notes:] See [link boost_optional.design.in_place_factories In-Place Factories] * [*Exception Safety:] Exceptions can only be thrown during the call to the `T` constructor used by the factory; in that case, the `optional` object will be reset to be ['uninitialized]. @@ -875,7 +875,7 @@ __SPACE__ [: `template optional::optional(R&& r) noexcept;`] * [*Postconditions:] `bool(*this) == true`; `addressof(**this) == addressof(r)`. * [*Remarks:] Unless `R` is an lvalue reference, the program is ill-formed. This constructor does not participate in overload resolution if `decay` is an instance of `boost::optional`. -* [*Notes:] This constructor is declared `explicit` on compilers that do not correctly suport binding to const lvalues of integral types. For more details [link optional_reference_binding see here]. +* [*Notes:] This constructor is declared `explicit` on compilers that do not correctly support binding to const lvalues of integral types. For more details [link optional_reference_binding see here]. * [*Example:] `` T v; @@ -963,7 +963,7 @@ __SPACE__ * [*Postconditions:] `bool(*this) == bool(rhs)`. -* [*Notes:] This behaviour is called ['rebinding semantics]. See [link boost_optional.tutorial.optional_references.rebinding_semantics_for_assignment_of_optional_references here] for details. +* [*Notes:] This behaviour is called ['rebinding semantics]. See [link boost_optional.design.optional_references.rebinding_semantics_for_assignment_of_optional_references here] for details. * [*Example:] `` @@ -1136,21 +1136,21 @@ __SPACE__ [#reference_optional_ref_reset_value] [: `template void optional::reset ( R&& r) noexcept;`] * [*Effects:] Equivalent to `*this = std::forward(r)`. -* [*Remarks:] This function is depprecated. +* [*Remarks:] This function is deprecated. __SPACE__ [#reference_optional_ref_is_initialized] [: `bool optional::is_initialized() const noexcept;`] * [*Effects:] Equivalent to `return bool(*this)`. -* [*Remarks:] This function is depprecated. +* [*Remarks:] This function is deprecated. __SPACE__ [#reference_optional_ref_get_value_or_value] [: `template T& optional::get_value_or( R&& r ) const noexcept;`] * [*Effects:] Equivalent to `return value_or(std::forward(r);`. -* [*Remarks:] This function is depprecated. +* [*Remarks:] This function is deprecated. [endsect] @@ -1216,7 +1216,7 @@ __SPACE__ [: `bool operator == ( optional const& x, optional const& y );`] -* [*Requires:] `T` shall meet requirements of __SGI_EQUALITY_COMPARABLE__. +* [*Requires:] `T` shall meet requirements of __STD_EQUALITY_COMPARABLE__. * [*Returns:] If both `x` and `y` are initialized, `(*x == *y)`. If only `x` or `y` is initialized, `false`. If both are uninitialized, `true`. * [*Notes:] This definition guarantees that `optional` not containing a value is compared unequal to any `optional` containing any value, and equal to any other `optional` not containing a value. @@ -1249,7 +1249,7 @@ __SPACE__ * [*Returns:] `(!y) ? false : (!x) ? true : *x < *y`. * [*Notes:] This definition guarantees that `optional` not containing a value is ordered as less than any `optional` containing any value, and equivalent to any other `optional` not containing a value. Pointers have shallow relational operators while `optional` has deep relational operators. Do not use `operator<` directly in generic code -which expect to be given either an `optional` or a pointer; use __FUNCTION_LESS_POINTEES__ instead. `T` need not be __SGI_LESS_THAN_COMPARABLE__. Only single `operator<` is required. Other relational operations are defined in terms of this one. If `T`'s `operator<` satisfies the axioms of __SGI_LESS_THAN_COMPARABLE__ (transitivity, antisymmetry and irreflexivity), `optinal` is __SGI_LESS_THAN_COMPARABLE__. +which expect to be given either an `optional` or a pointer; use __FUNCTION_LESS_POINTEES__ instead. `T` need not be __STD_LESS_THAN_COMPARABLE__. Only single `operator<` is required. Other relational operations are defined in terms of this one. If `T`'s `operator<` satisfies the axioms of __STD_LESS_THAN_COMPARABLE__ (transitivity, antisymmetry and irreflexivity), `optional` is __STD_LESS_THAN_COMPARABLE__. * [*Example:] `` optional oN, oN_; @@ -1310,7 +1310,7 @@ __SPACE__ [: `bool operator == ( none_t, optional const& x ) noexcept;`] * [*Returns:] `!x`. -* [*Notes:] `T` need not meet requirements of __SGI_EQUALITY_COMPARABLE__. +* [*Notes:] `T` need not meet requirements of __STD_EQUALITY_COMPARABLE__. __SPACE__ @@ -1386,7 +1386,7 @@ __SPACE__ [#reference_swap_optional_reference] [: `void swap ( optional& x, optional& y ) noexcept ;`] -* [*Postconditions:] `x` refers to what `y` refererred to before the swap (if anything). `y` refers to whatever `x` referred to before the swap. +* [*Postconditions:] `x` refers to what `y` referred to before the swap (if anything). `y` refers to whatever `x` referred to before the swap. * [*Example:] `` @@ -1408,3 +1408,37 @@ assert (addressof(*opt0) == addressof(y)); `` [endsect] + + +[section Detailed Semantics - std::hash Specializations] + +__SPACE__ +[#reference_std_hash_spec] + +`` +namespace std { + +template +struct hash > ; + +template +struct hash > ; + +} // namespace std +`` + +The specialization `hash>` is enabled if and only if +`hash>` is enabled. When enabled, for an object `o` +of type `optional`, if `o.has_value() == true`, then `hash>()(o)` + evaluates to the same value as `hash>()(*o)`; otherwise it +evaluates to an unspecified value. +The member functions are not guaranteed to be `noexcept`. + +[caution +You may get compiler errors when your program provides specializations for +`std::hash>`. If this happens, define macro +`BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH` to suppress the specializations +of `std::hash` in this library. +] + +[endsect] diff --git a/doc/12_when_to_use.qbk b/doc/31_when_to_use.qbk similarity index 98% rename from doc/12_when_to_use.qbk rename to doc/31_when_to_use.qbk index 80dff54b..b1b44712 100644 --- a/doc/12_when_to_use.qbk +++ b/doc/31_when_to_use.qbk @@ -11,7 +11,7 @@ Here, having received an empty `vec` and having no `size_t` to return is not a [ Another typical situation is to indicate that we do not have a value yet, but we expect to have it later. This notion can be used in implementing solutions like lazy initialization or a two-phase initialization. -`optional` can be used to take a non-__SGI_DEFAULT_CONSTRUCTIBLE__ type `T` and create a sibling type with a default constructor. This is a way to add a ['null-state] to any type that doesn't have it already. +`optional` can be used to take a non-__STD_DEFAULT_CONSTRUCTIBLE__ type `T` and create a sibling type with a default constructor. This is a way to add a ['null-state] to any type that doesn't have it already. Sometimes type `T` already provides a built-in null-state, but it may still be useful to wrap it into `optional`. Consider `std::string`. When you read a piece of text from a GUI form or a DB table, it is hardly ever that the empty string indicates anything else but a missing text. And some data bases do not even distinguish between a null string entry and a non-null string of length 0. Still, it may be practical to use `optional` to indicate in the returned type that we want to treat the empty string in a special dedicated program path: diff --git a/doc/1A_on_performance.qbk b/doc/32_on_performance.qbk similarity index 96% rename from doc/1A_on_performance.qbk rename to doc/32_on_performance.qbk index 968b18fe..fc3bf8b3 100644 --- a/doc/1A_on_performance.qbk +++ b/doc/32_on_performance.qbk @@ -19,7 +19,7 @@ Lifetime of the `T` inside `_storage` is manually controlled with placement-`new T _storage; }; -We call it a ['direct] storage. This makes `optional` a trivially-copyable type for scalar `T`s. This only works for compilers that support defaulted functions (including defaulted move assignment and constructor). On compilers without defaulted functions we still use the direct storage, but `optional` is no longer recognized as trivially-copyable. Apart from scalar types, we leave the programmer a way of customizing her type, so that it is reconized by `optional` as candidate for optimized storage, by specializing type trait `boost::opitonal_config::optional_uses_direct_storage_for`: +We call it a ['direct] storage. This makes `optional` a trivially-copyable type for scalar `T`s. This only works for compilers that support defaulted functions (including defaulted move assignment and constructor). On compilers without defaulted functions we still use the direct storage, but `optional` is no longer recognized as trivially-copyable. Apart from scalar types, we leave the programmer a way of customizing her type, so that it is recognized by `optional` as candidate for optimized storage, by specializing type trait `boost::optional_config::optional_uses_direct_storage_for`: struct X // not trivial { @@ -86,7 +86,7 @@ Which gives us the following layout (and smaller total size): [$images/opt_align3.png] -Sometimes it requires detailed consideration what data we make optional. In our case above, if we determine that both minimum and maximum value can be provided or not provided together, but one is never provided without the other, we can make only one optional memebr: +Sometimes it requires detailed consideration what data we make optional. In our case above, if we determine that both minimum and maximum value can be provided or not provided together, but one is never provided without the other, we can make only one optional member: struct Limits { diff --git a/doc/90_dependencies.qbk b/doc/90_dependencies.qbk index b5fa97c6..8f849a19 100644 --- a/doc/90_dependencies.qbk +++ b/doc/90_dependencies.qbk @@ -17,65 +17,26 @@ The implementation uses the following other Boost modules: # assert # config # core -# detail -# move -# mpl # static_assert # throw_exception # type_traits -# utility [endsect] -[section Emplace operations in older compilers][#optional_emplace_workaround] - -Certain constructors and functions in the interface of `optional` perform a 'perfect forwarding' of arguments: - - template optional(in_place_init_t, Args&&... args); - template optional(in_place_init_if_t, bool condition, Args&&... args); - template void emplace(Args&&... args); - -On compilers that do not support variadic templates, each of these functions is substituted with two overloads, one forwarding a single argument, the other forwarding zero arguments. This forms the following set: - - template optional(in_place_init_t, Arg&& arg); - optional(in_place_init_t); - - template optional(in_place_init_if_t, bool condition, Arg&& arg); - optional(in_place_init_if_t, bool condition); - - template void emplace(Arg&& arg); - void emplace(); - -On compilers that do not support rvalue references, each of these functions is substituted with three overloadss: taking `const` and non-`const` lvalue reference, and third forwarding zero arguments. This forms the following set: - - template optional(in_place_init_t, const Arg& arg); - template optional(in_place_init_t, Arg& arg); - optional(in_place_init_t); - - template optional(in_place_init_if_t, bool condition, const Arg& arg); - template optional(in_place_init_if_t, bool condition, Arg& arg); - optional(in_place_init_if_t, bool condition); - - template void emplace(const Arg& arg); - template void emplace(Arg& arg); - void emplace(); - -This workaround addressess about 40% of all use cases. If this is insufficient, you need to resort to using [link boost_optional.tutorial.in_place_factories In-Place Factories]. -[endsect] [section Optional Reference Binding][#optional_reference_binding] -A number of compilers incorrectly treat const lvalues of integral type as rvalues, and create an illegal temporary when binding to an lvalue reference to const in some expressions. This could result in creating an optional lvalue reference that is in fact bound to an unexpected temporary rather than to the intended object. In order to prevent hard to find run-time bugs, this library performs compile-time checks to prevent expressions that would otherwise bind an optional reference to an unexpected temporary. As a consequence, on certain compilers certain pieces of functionality in optional references are missing. In order to maintain a portability of your code across diferent compilers, it is recommended that you only stick to the minimum portable interface of optional references: prefer direct-initialization and copy assignment of optional references to copy-initialization and assignment from `T&`: +A number of compilers incorrectly treat const lvalues of integral type as rvalues, and create an illegal temporary when binding to an lvalue reference to const in some expressions. This could result in creating an optional lvalue reference that is in fact bound to an unexpected temporary rather than to the intended object. In order to prevent hard to find run-time bugs, this library performs compile-time checks to prevent expressions that would otherwise bind an optional reference to an unexpected temporary. As a consequence, on certain compilers certain pieces of functionality in optional references are missing. In order to maintain a portability of your code across different compilers, it is recommended that you only stick to the minimum portable interface of optional references: prefer direct-initialization and copy assignment of optional references to copy-initialization and assignment from `T&`: const int i = 0; optional or1; optional or2 = i; // caution: not portable or1 = i; // caution: not portable - + optional or3(i); // portable or1 = optional(i); // portable -Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4.5, 5.1, 5.2; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0. In order to check if your compiler correctly implements reference binding use this test program. +Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4.5, 5.1, 5.2; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0. In order to check if your compiler correctly implements reference binding use this test program. #include @@ -88,13 +49,13 @@ Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4 assert(&ii == &global_i); } - void operator=(const int& ii) + void operator=(const int& ii) { assert(&ii == &global_i); } void operator=(int&&) // remove this if your compiler doesn't have rvalue refs - { + { assert(false); } }; @@ -110,7 +71,7 @@ Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4 TestingReferenceBinding ttt2 = iref; ttt2 = iref; } - + [endsect] -[endsect] \ No newline at end of file +[endsect] diff --git a/doc/91_comparison_with_std.qbk b/doc/91_comparison_with_std.qbk new file mode 100644 index 00000000..e72dd46f --- /dev/null +++ b/doc/91_comparison_with_std.qbk @@ -0,0 +1,48 @@ +[/ + Boost.Optional + + Copyright (c) 2015 - 2024 Andrzej Krzemieński + + 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) +] + + +[section:std_comp Comparison with `std::optional`] + +[table + [] + [ [[*`boost::optional`]] [[*`std::optional`]] [] ] + [ [`optional o = none;`] [`optional o = nullopt;`] [Different name for no-value tag.] ] + [ [`optional o {in_place_init, a, b};`] [`optional o {in_place, a, b};`] [Different name for in-place initialization tag.] ] + [ [] [`optional> o {in_place, {1, 2, 3}};` + + `o.emplace({4, 5, 6});`] [No in-place initialization with initializer-list in `boost`.] ] + [ [`optional o {in_place_init_if, cond, a, b};`] [] [No syntax for conditional in-place initialization in `std`.] ] + [ [`optional o {cond, x};`] [] [No syntax for conditional initialization from `T` in `std`.] ] + [ [`optional o {U{}};` + + `optional o {optional{}};`] [`optional o = U{};` + + `optional o = optional{}`] [Constructors form `U` and `optional` are explicit in `boost` and implicit in `std`.] ] + [ [] [`optional o = 1;`] [No clever deduction of of `optional`'s template parameters in initialization in `boost`. ]] + [ [`optional o;`] [] [No optional references in `std`.] ] + [ [] [`constexpr optional o;`] [No `constexpr` interface in `boost`.] ] + [ [`o.map(&f);` + + `o.flat_map(&of);` ] [`o.transform(&f);` + + `o.and_then(&of);`] [Different names and signatures for monadic interface functions. `boost` takes callbacks by value, `std` by universal reference.] ] + [ [] [`o.or_else(&of);`] [No `or_else` function in `boost`.] ] + [ [`o.value_or_eval(&f);`] [] [No `value_or_eval` function in `std`.] ] + [ [] [`optional{} == U{}`; + + `optional{} == optional{}`] [No comparisons with `U` or `optional` in `boost`.] ] + [ [`make_optional(cond, v);`] [] [No `make_optional` with condition in `std`.] ] + [ [] [`make_optional(a, b);`] [No `make_optional` with specified `T` in `boost`.] ] + [ [`std::cout << optional{};`] [] [No printing to IOStreams in `std`.]] +] + + +[endsect][/ std_comp] diff --git a/doc/91_relnotes.qbk b/doc/92_relnotes.qbk similarity index 65% rename from doc/91_relnotes.qbk rename to doc/92_relnotes.qbk index a29137ce..7d0df4cc 100644 --- a/doc/91_relnotes.qbk +++ b/doc/92_relnotes.qbk @@ -1,7 +1,7 @@ [/ Boost.Optional - Copyright (c) 2015 - 2018 Andrzej Krzemienski + Copyright (c) 2015 - 2023 Andrzej Krzemienski Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -11,17 +11,71 @@ [section:relnotes Release Notes] +[heading Boost Release 1.87] + +* *Breaking change.* Dropped support for C++03. C++11 is now the required minimum; at least some C++11 features. +* Dropped dependency on Boost.Utility. +* Dropped dependency on Boost.Predef. +* Dropped dependency on Boost.StaticAssert. +* Dropped dependency on Boost.Move. +* A bit faster implementation of some relational operations. +* *Warning.* In the future releases we intend to introduce the range interface + into `optional`, so that `std::ranges::range>` will be `true`. + This may affect the overload resolution in programs that make decisions based + on predicates such as `std::ranges::range`. +* Tags `in_place_init` and `in_place_init_if` become `inline constexpr` and therewith leave smaller footprint in the executable. This addresses [@https://github.com/boostorg/optional/issues/103 issue #103]. + + +[heading Boost Release 1.85] + +* Fixed the implementation for trivial types. Now it is slower, because it always initializes the `T`, but it avoids undefined behavior when `optional` is copied. This fixes [@https://github.com/boostorg/optional/issues/108 issue #108]. +* Fixed some `-Wmaybe-uninitialized` warnings in GCC 12. Thanks to Christian Mazakas for the fix. +* Dropped dependency on Boost.Detail. + +[heading Boost Release 1.83] + +* Deprecated support for C++03 and earlier, C++11 will be required in release 1.86. + +[heading Boost Release 1.80] + +* [*Breaking change:] Added specializations for `std::hash>`. This fixes [@https://github.com/boostorg/optional/issues/55 issue #55]. You may get compiler errors when your program provides specializations for `std::hash>`. If this happens, define macro `BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH` to suppress the specializations of `std::hash` in this library. + +[heading Boost Release 1.79] + +* Fixed [@https://github.com/boostorg/optional/issues/98 issue #98]. +* Fixed [@https://github.com/boostorg/optional/issues/92 issue #92]. +* Added support for `BOOST_NO_IOSTREAM`. +* Now aligned storage uses `unsigned char` rather than `char` to avoid UB. +* Now using cv-unqualified `value_type` with placement `new` to avoid UB. + +[heading Boost Release 1.76] + +* Fixed MSVC warning C4702. + +[heading Boost Release 1.75] + +* `boost::none` is `constexpr`-declared. + +* Fixed [@https://github.com/boostorg/optional/issues/78 issue #78]. + +[heading Boost Release 1.73] + +* Fixed [@https://github.com/boostorg/optional/issues/78 issue #78]. +* `boost::none` is now declared as an inline variable (on compilers that support it): there is only one instance of `boost::none` across all translation units. +* Fixed a number of compilation errors in GCC 4.4.7 in `optional` for trivial `T`s. Thanks to Robert Leahy for the fix. For details see [@https://github.com/boostorg/optional/pull/80 pr #78]. +* Now suppressing warning `-Wweak-vtables`. + [heading Boost Release 1.69] * Remove deprecation mark from `reset()` method (without arguments). * Fixed [@https://github.com/boostorg/optional/issues/59 issue #59]. -* Fixed bug with initialization of certain wrapper types in clang with -std=c++03. See [@https://github.com/boostorg/optional/pull/64 pr #64]. +* Fixed bug with initialization of certain wrapper types in clang with -std=c++03. See [@https://github.com/boostorg/optional/pull/64 pr #64]. [heading Boost Release 1.68] * Added member function `has_value()` for compatibility with `std::optional` ([@https://github.com/boostorg/optional/issues/52 issue #52]). * Added member function `map()` for transforming `optional` into `optional` using a function of type `T -> U`. -* Added member function `flat_map()` for transforming `optional` into `optional` using a function of type `T -> optonal`. +* Added member function `flat_map()` for transforming `optional` into `optional` using a function of type `T -> optional`. [heading Boost Release 1.67] @@ -53,7 +107,7 @@ * the `sizeof` of optional reference is that of a pointer, * some bugs connected to copying optional references are gone, * all run-time bugs caused by incorrect reference binding on some compilers are now turned into compile-time errors, - * you can swap optional references: it is like swapping pointers: shalow, underlying objects are not affected, + * you can swap optional references: it is like swapping pointers: shallow, underlying objects are not affected, * optional references to abstract types work. * Documented nested typedefs ([@https://svn.boost.org/trac/boost/ticket/5193 Trac #5193]). * Made the perfect-forwarding constructor SFINAE-friendly, which fixes [@https://svn.boost.org/trac/boost/ticket/12002 Trac #12002]. However, this only works in the newer platforms that correctly implement C++11 ``. diff --git a/doc/92_acknowledgments.qbk b/doc/93_acknowledgments.qbk similarity index 100% rename from doc/92_acknowledgments.qbk rename to doc/93_acknowledgments.qbk diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 2fc6463e..c33abf8f 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -26,23 +26,25 @@ install images images/opt_align2.png images/opt_align3.png images/opt_align4.png + images/R.png + images/space.png : html/images ; - + boostbook standalone : optional : - html:boost.root=../../../.. - html:boost.libraries=../../../../libs/libraries.htm - chapter.autolabel=0 - chunk.section.depth=8 - toc.section.depth=2 - toc.max.depth=2 - generate.section.toc.level=1 - pdf:img.src.path=$(images)/ - pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/libs/optional/doc/html + html:"boost.root=../../../.." + html:"boost.libraries=../../../../libs/libraries.htm" + "chapter.autolabel=0" + "chunk.section.depth=8" + "toc.section.depth=1" + "toc.max.depth=2" + "generate.section.toc.level=1" + pdf:"img.src.path=$(images)/" + pdf:"boost.url.prefix=http://www.boost.org/doc/libs/release/libs/optional/doc/html" docbook:on ; diff --git a/doc/html/boost_optional/a_note_about_optional_bool_.html b/doc/html/boost_optional/a_note_about_optional_bool_.html deleted file mode 100644 index 64f37f68..00000000 --- a/doc/html/boost_optional/a_note_about_optional_bool_.html +++ /dev/null @@ -1,108 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- optional<bool> should - be used with special caution and consideration. -

-

- First, it is functionally similar to a tristate boolean (false, maybe, true) - —such as boost::tribool— - except that in a tristate boolean, the maybe state represents - a valid value, unlike the corresponding state of an uninitialized - optional<bool>. It - should be carefully considered if an optional<bool> - instead of a tribool is really - needed. -

-

- Second, although optional<> - provides a contextual conversion to bool - in C++11, this falls back to an implicit conversion on older compilers. This - conversion refers to the initialization state and not to the contained value. - Using optional<bool> can - lead to subtle errors due to the implicit bool - conversion: -

-
void foo ( bool v ) ;
-void bar()
-{
-    optional<bool> v = try();
-
-    // The following intended to pass the value of 'v' to foo():
-    foo(v);
-    // But instead, the initialization state is passed
-    // due to a typo: it should have been foo(*v).
-}
-
-

- The only implicit conversion is to bool, - and it is safe in the sense that typical integral promotions don't apply (i.e. - if foo() - takes an int instead, it won't - compile). -

-

- Third, mixed comparisons with bool - work differently than similar mixed comparisons between pointers and bool, so the results might surprise you: -

-
optional<bool> oEmpty(none), oTrue(true), oFalse(false);
-
-if (oEmpty == none);  // renders true
-if (oEmpty == false); // renders false!
-if (oEmpty == true);  // renders false!
-
-if (oFalse == none);  // renders false
-if (oFalse == false); // renders true!
-if (oFalse == true);  // renders false
-
-if (oTrue == none);   // renders false
-if (oTrue == false);  // renders false
-if (oTrue == true);   // renders true
-
-

- In other words, for optional<>, the following assertion does not hold: -

-
assert((opt == false) == (!opt));
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/acknowledgements.html b/doc/html/boost_optional/acknowledgements.html deleted file mode 100644 index c6f9f2f7..00000000 --- a/doc/html/boost_optional/acknowledgements.html +++ /dev/null @@ -1,130 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHome -
-
- -

- - Pre-formal - review -

-
    -
  • - Peter Dimov suggested the name 'optional', and was the first to point out - the need for aligned storage. -
  • -
  • - Douglas Gregor developed 'type_with_alignment', and later Eric Friedman - coded 'aligned_storage', which are the core of the optional class implementation. -
  • -
  • - Andrei Alexandrescu and Brian Parker also worked with aligned storage techniques - and their work influenced the current implementation. -
  • -
  • - Gennadiy Rozental made extensive and important comments which shaped the - design. -
  • -
  • - Vesa Karvonen and Douglas Gregor made quite useful comparisons between - optional, variant and any; and made other relevant comments. -
  • -
  • - Douglas Gregor and Peter Dimov commented on comparisons and evaluation - in boolean contexts. -
  • -
  • - Eric Friedman helped understand the issues involved with aligned storage, - move/copy operations and exception safety. -
  • -
  • - Many others have participated with useful comments: Aleksey Gurotov, Kevlin - Henney, David Abrahams, and others I can't recall. -
  • -
-

- - Post-formal - review -

-
    -
  • - William Kempf carefully considered the originally proposed interface and - suggested the new interface which is currently used. He also started and - fueled the discussion about the analogy optional<>/smart pointer - and about relational operators. -
  • -
  • - Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson - focused on the relational semantics of optional (originally undefined); - concluding with the fact that the pointer-like interface doesn't make it - a pointer so it shall have deep relational operators. -
  • -
  • - Augustus Saunders also explored the different relational semantics between - optional<> and a pointer and developed the OptionalPointee concept - as an aid against potential conflicts on generic code. -
  • -
  • - Joel de Guzman noticed that optional<> can be seen as an API on top - of variant<T,nil_t>. -
  • -
  • - Dave Gomboc explained the meaning and usage of the Haskell analog to optional<>: - the Maybe type constructor (analogy originally pointed out by David Sankel). -
  • -
  • - Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, - Rob Stewart, and others. -
  • -
  • - Joel de Guzman made the case for the support of references and helped with - the proper semantics. -
  • -
  • - Mat Marcus shown the virtues of a value-oriented interface, influencing - the current design, and contributed the idea of "none". -
  • -
  • - Vladimir Batov's design of Boost.Convert library motivated the development - of value accessors for optional: - functions value, value_or, value_or_eval. -
  • -
-
- - - -
-
-
-PrevUpHome -
- - diff --git a/doc/html/boost_optional/acknowledgments.html b/doc/html/boost_optional/acknowledgments.html deleted file mode 100644 index b09cf6e1..00000000 --- a/doc/html/boost_optional/acknowledgments.html +++ /dev/null @@ -1,125 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHome -
-
- -

- - Pre-formal - review -

-
    -
  • - Peter Dimov suggested the name 'optional', and was the first to point out - the need for aligned storage. -
  • -
  • - Douglas Gregor developed 'type_with_alignment', and later Eric Friedman - coded 'aligned_storage', which are the core of the optional class implementation. -
  • -
  • - Andrei Alexandrescu and Brian Parker also worked with aligned storage techniques - and their work influenced the current implementation. -
  • -
  • - Gennadiy Rozental made extensive and important comments which shaped the - design. -
  • -
  • - Vesa Karvonen and Douglas Gregor made quite useful comparisons between - optional, variant and any; and made other relevant comments. -
  • -
  • - Douglas Gregor and Peter Dimov commented on comparisons and evaluation - in boolean contexts. -
  • -
  • - Eric Friedman helped understand the issues involved with aligned storage, - move/copy operations and exception safety. -
  • -
  • - Many others have participated with useful comments: Aleksey Gurotov, Kevlin - Henney, David Abrahams, and others I can't recall. -
  • -
-

- - Post-formal - review -

-
    -
  • - William Kempf carefully considered the originally proposed interface and - suggested the new interface which is currently used. He also started and - fueled the discussion about the analogy optional<>/smart pointer - and about relational operators. -
  • -
  • - Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson - focused on the relational semantics of optional (originally undefined); - concluding with the fact that the pointer-like interface doesn't make it - a pointer so it shall have deep relational operators. -
  • -
  • - Augustus Saunders also explored the different relational semantics between - optional<> and a pointer and developed the OptionalPointee concept - as an aid against potential conflicts on generic code. -
  • -
  • - Joel de Guzman noticed that optional<> can be seen as an API on top - of variant<T,nil_t>. -
  • -
  • - Dave Gomboc explained the meaning and usage of the Haskell analog to optional<>: - the Maybe type constructor (analogy originally pointed out by David Sankel). -
  • -
  • - Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, - Rob Stewart, and others. -
  • -
  • - Joel de Guzman made the case for the support of references and helped with - the proper semantics. -
  • -
  • - Mat Marcus shown the virtues of a value-oriented interface, influencing - the current design, and contributed the idea of "none". -
  • -
-
- - - -
-
-
-PrevUpHome -
- - diff --git a/doc/html/boost_optional/dependencies_and_portability.html b/doc/html/boost_optional/dependencies_and_portability.html deleted file mode 100644 index bc235f84..00000000 --- a/doc/html/boost_optional/dependencies_and_portability.html +++ /dev/null @@ -1,91 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- -

- The implementation uses the following other Boost modules: -

-
    -
  1. - assert -
  2. -
  3. - config -
  4. -
  5. - core -
  6. -
  7. - detail -
  8. -
  9. - move -
  10. -
  11. - mpl -
  12. -
  13. - static_assert -
  14. -
  15. - throw_exception -
  16. -
  17. - type_traits -
  18. -
  19. - utility -
  20. -
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/dependencies_and_portability/emplace_operations_in_older_compilers.html b/doc/html/boost_optional/dependencies_and_portability/emplace_operations_in_older_compilers.html deleted file mode 100644 index a35c4a2c..00000000 --- a/doc/html/boost_optional/dependencies_and_portability/emplace_operations_in_older_compilers.html +++ /dev/null @@ -1,90 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Certain constructors and functions - in the interface of optional - perform a 'perfect forwarding' of arguments: -

-
template<class... Args> optional(in_place_init_t, Args&&... args);
-template<class... Args> optional(in_place_init_if_t, bool condition, Args&&... args);
-template<class... Args> void emplace(Args&&... args);
-
-

- On compilers that do not support variadic templates, each of these functions - is substituted with two overloads, one forwarding a single argument, the - other forwarding zero arguments. This forms the following set: -

-
template<class Arg> optional(in_place_init_t, Arg&& arg);
-optional(in_place_init_t);
-
-template<class Arg> optional(in_place_init_if_t, bool condition, Arg&& arg);
-optional(in_place_init_if_t, bool condition);
-
-template<class Arg> void emplace(Arg&& arg);
-void emplace();
-
-

- On compilers that do not support rvalue references, each of these functions - is substituted with three overloadss: taking const - and non-const lvalue reference, - and third forwarding zero arguments. This forms the following set: -

-
template<class Arg> optional(in_place_init_t, const Arg& arg);
-template<class Arg> optional(in_place_init_t, Arg& arg);
-optional(in_place_init_t);
-
-template<class Arg> optional(in_place_init_if_t, bool condition, const Arg& arg);
-template<class Arg> optional(in_place_init_if_t, bool condition, Arg& arg);
-optional(in_place_init_if_t, bool condition);
-
-template<class Arg> void emplace(const Arg& arg);
-template<class Arg> void emplace(Arg& arg);
-void emplace();
-
-

- This workaround addressess about 40% of all use cases. If this is insufficient, - you need to resort to using In-Place - Factories. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html b/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html deleted file mode 100644 index 7a191d27..00000000 --- a/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html +++ /dev/null @@ -1,107 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- A number of compilers incorrectly - treat const lvalues of integral type as rvalues, and create an illegal temporary - when binding to an lvalue reference to const in some expressions. This could - result in creating an optional lvalue reference that is in fact bound to - an unexpected temporary rather than to the intended object. In order to prevent - hard to find run-time bugs, this library performs compile-time checks to - prevent expressions that would otherwise bind an optional reference to an - unexpected temporary. As a consequence, on certain compilers certain pieces - of functionality in optional references are missing. In order to maintain - a portability of your code across diferent compilers, it is recommended that - you only stick to the minimum portable interface of optional references: - prefer direct-initialization and copy assignment of optional references to - copy-initialization and assignment from T&: -

-
const int i = 0;
-optional<const int&> or1;
-optional<const int&> or2 = i;  // caution: not portable
-or1 = i;                       // caution: not portable
-
-optional<const int&> or3(i);   // portable
-or1 = optional<const int&>(i); // portable
-
-

- Compilers known to have these deficiencies include GCC versions 4.2, 4.3, - 4.4, 4.5, 5.1, 5.2; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0. - In order to check if your compiler correctly implements reference binding - use this test program. -

-
#include <cassert>
-
-const int global_i = 0;
-
-struct TestingReferenceBinding
-{
-  TestingReferenceBinding(const int& ii)
-  {
-    assert(&ii == &global_i);
-  }
-
-  void operator=(const int& ii)
-  {
-    assert(&ii == &global_i);
-  }
-
-  void operator=(int&&) // remove this if your compiler doesn't have rvalue refs
-  {
-    assert(false);
-  }
-};
-
-int main()
-{
-  const int& iref = global_i;
-  assert(&iref == &global_i);
-
-  TestingReferenceBinding ttt = global_i;
-  ttt = global_i;
-
-  TestingReferenceBinding ttt2 = iref;
-  ttt2 = iref;
-}
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/detailed_semantics.html b/doc/html/boost_optional/detailed_semantics.html deleted file mode 100644 index b93515fc..00000000 --- a/doc/html/boost_optional/detailed_semantics.html +++ /dev/null @@ -1,1975 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Because T might be of reference - type, in the sequel, those entries whose semantic depends on T being of reference type or not will be - distinguished using the following convention: -

-
    -
  • - If the entry reads: optional<T(not - a ref)>, the - description corresponds only to the case where T - is not of reference type. -
  • -
  • - If the entry reads: optional<T&>, the description corresponds only - to the case where T is - of reference type. -
  • -
  • - If the entry reads: optional<T>, the description is the same for both - cases. -
  • -
-
- - - - - -
[Note]Note

- The following section contains various assert() which are used only to show the postconditions - as sample code. It is not implied that the type T - must support each particular expression but that if the expression is supported, - the implied condition holds. -

-

- space -

-

- - optional - class member functions -

-

- space -

-

- optional<T>::optional() noexcept; -

-
    -
  • - Effect: Default-Constructs an optional. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
  • - Notes: T's default constructor is not called. -
  • -
  • - Example: -
    optional<T> def ;
    -assert ( !def ) ;
    -
    -
  • -
-

- space -

-

- optional<T>::optional( none_t ) noexcept; -

-
    -
  • - Effect: Constructs an optional - uninitialized. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
  • - Notes: T's - default constructor is not called. - The expression boost::none denotes an instance of boost::none_t that can be used as the parameter. -
  • -
  • - Example: -
    #include <boost/none.hpp>
    -optional<T> n(none) ;
    -assert ( !n ) ;
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)>::optional( T const& v ) -

-
    -
  • - Requires: is_copy_constructible<T>::value - is true. -
  • -
  • - Effect: Directly-Constructs an optional. -
  • -
  • - Postconditions: *this is initialized - and its value is a copy of v. -
  • -
  • - Throws: Whatever T::T( - T const& ) - throws. -
  • -
  • - Notes: T::T( - T const& ) - is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T - const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -assert ( *opt == v ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( T& ref ) -

-
    -
  • - Effect: Directly-Constructs an optional. -
  • -
  • - Postconditions: *this is initialized - and its value is an instance of an internal type wrapping the reference - ref. -
  • -
  • - Throws: Nothing. -
  • -
  • - Example: -
    T v;
    -T& vref = v ;
    -optional<T&> opt(vref);
    -assert ( *opt == v ) ;
    -++ v ; // mutate referee
    -assert (*opt == v);
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)>::optional( T&& - v ) -

-
    -
  • - Requires: is_move_constructible<T>::value - is true. -
  • -
  • - Effect: Directly-Move-Constructs an optional. -
  • -
  • - Postconditions: *this is initialized - and its value is move-constructed from v. -
  • -
  • - Throws: Whatever T::T( - T&& - ) throws. -
  • -
  • - Notes: T::T( - T&& - ) is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T&& ); - in that case, the state of v - is determined by exception safety guarantees for T::T(T&&). -
  • -
  • - Example: -
    T v1, v2;
    -optional<T> opt(std::move(v1));
    -assert ( *opt == v2 ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( T&& ref ) = delete -

-
  • - Notes: This constructor is deleted -
-

- space -

-

- optional<T (not a ref)>::optional( bool condition, T const& v ) ; -

-

- optional<T&> ::optional( bool condition, T& - v ) ; -

-
  • - If condition is true, same as: -
-

- optional<T (not a ref)>::optional( T const& v ) -

-

- optional<T&> ::optional( T& - v ) -

-
  • - otherwise, same as: -
-

- optional<T (not a ref)>::optional() -

-

- optional<T&> ::optional() -

-

- space -

-

- optional<T (not a ref)>::optional( optional const& rhs ); -

-
    -
  • - Requires: is_copy_constructible<T>::value - is true. -
  • -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs is initialized, - *this - is initialized and its value is a copy of the value - of rhs; else *this is - uninitialized. -
  • -
  • - Throws: Whatever T::T( - T const& ) - throws. -
  • -
  • - Notes: If rhs is initialized, T::T(T const& ) - is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T - const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    optional<T> uninit ;
    -assert (!uninit);
    -
    -optional<T> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -optional<T> init( T(2) );
    -assert ( *init == T(2) ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( init2 == init ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( optional const& rhs ); -

-
    -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is another reference to the same object referenced - by *rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: If rhs - is initialized, both *this - and *rhs - will reefer to the same object (they alias). -
  • -
  • - Example: -
    optional<T&> uninit ;
    -assert (!uninit);
    -
    -optional<T&> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -T v = 2 ; T& ref = v ;
    -optional<T> init(ref);
    -assert ( *init == v ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( *init2 == v ) ;
    -
    -v = 3 ;
    -
    -assert ( *init  == 3 ) ;
    -assert ( *init2 == 3 ) ;
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)>::optional( optional&& rhs - ) noexcept(see below); -

-
    -
  • - Requires: is_move_constructible<T>::value - is true. -
  • -
  • - Effect: Move-constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is move constructed from rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( - T&& - ) throws. -
  • -
  • - Notes: If rhs - is initialized, T::T( T - && ) - is called. The expression inside noexcept - is equivalent to is_nothrow_move_constructible<T>::value. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T&& ); - in that case, rhs remains - initialized and the value of *rhs is determined by exception safety - of T::T(T&&). -
  • -
  • - Example: -
    optional<std::unique_ptr<T>> uninit ;
    -assert (!uninit);
    -
    -optional<std::unique_ptr<T>> uinit2 ( std::move(uninit) ) ;
    -assert ( uninit2 == uninit );
    -
    -optional<std::unique_ptr<T>> init( std::uniqye_ptr<T>(new T(2)) );
    -assert ( **init == T(2) ) ;
    -
    -optional<std::unique_ptr<T>> init2 ( std::move(init) ) ;
    -assert ( init );
    -assert ( *init == nullptr );
    -assert ( init2 );
    -assert ( **init2 == T(2) ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( optional && - rhs ); -

-
    -
  • - Effect: Move-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is another reference to the same object referenced - by *rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: If rhs - is initialized, both *this - and *rhs - will reefer to the same object (they alias). -
  • -
  • - Example: -
    optional<std::unique_ptr<T>&> uninit ;
    -assert (!uninit);
    -
    -optional<std::unique_ptr<T>&> uinit2 ( std::move(uninit) ) ;
    -assert ( uninit2 == uninit );
    -
    -std::unique_ptr<T> v(new T(2)) ;
    -optional<std::unique_ptr<T>&> init(v);
    -assert ( *init == v ) ;
    -
    -optional<std::unique_ptr<T>&> init2 ( std::move(init) ) ;
    -assert ( *init2 == v ) ;
    -
    -*v = 3 ;
    -
    -assert ( **init  == 3 ) ;
    -assert ( **init2 == 3 ) ;
    -
    -
  • -
-

- space -

-

- template<U> explicit optional<T - (not a ref)>::optional( optional<U> const& rhs ); -

-
    -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is a copy of the value - of rhs converted to type T; - else *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( - U const& ) - throws. -
  • -
  • - Notes: T::T( - U const& ) - is called if rhs is initialized, - which requires a valid conversion from U - to T. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( U - const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    optional<double> x(123.4);
    -assert ( *x == 123.4 ) ;
    -
    -optional<int> y(x) ;
    -assert( *y == 123 ) ;
    -
    -
  • -
-

- space -

-

- template<U> explicit optional<T - (not a ref)>::optional( optional<U>&& - rhs ); -

-
    -
  • - Effect: Move-constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is move constructed from *rhs; else *this is uninitialized. -
  • -
  • - Throws: Whatever T::T( - U&& - ) throws. -
  • -
  • - Notes: T::T( - U&& - ) is called if rhs - is initialized, which requires a valid conversion from U - to T. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( U&& ); - in that case, rhs remains - initialized and the value of *rhs is determined by exception safety - guarantee of T::T( U&& ). -
  • -
  • - Example: -
    optional<double> x(123.4);
    -assert ( *x == 123.4 ) ;
    -
    -optional<int> y(std::move(x)) ;
    -assert( *y == 123 ) ;
    -
    -
  • -
-

- space -

-

- template<InPlaceFactory> - explicit optional<T - (not a ref)>::optional( InPlaceFactory const& f ); -

-

- template<TypedInPlaceFactory> - explicit optional<T - (not a ref)>::optional( TypedInPlaceFactory const& f ); -

-
    -
  • - Effect: Constructs an optional - with a value of T obtained - from the factory. -
  • -
  • - Postconditions: *this is initialized - and its value is directly given from the factory - f (i.e., the value is not copied). -
  • -
  • - Throws: Whatever the T - constructor called by the factory throws. -
  • -
  • - Notes: See In-Place - Factories -
  • -
  • - Exception Safety: Exceptions can only - be thrown during the call to the T - constructor used by the factory; in that case, this constructor has no - effect. -
  • -
  • - Example: -
    class C { C ( char, double, std::string ) ; } ;
    -
    -C v('A',123.4,"hello");
    -
    -optional<C> x( in_place   ('A', 123.4, "hello") ); // InPlaceFactory used
    -optional<C> y( in_place<C>('A', 123.4, "hello") ); // TypedInPlaceFactory used
    -
    -assert ( *x == v ) ;
    -assert ( *y == v ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T>::operator= ( none_t ) noexcept; -

-
    -
  • - Effect: If *this is initialized destroys its contained - value. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( T - const& - rhs ) - ; -

-
    -
  • - Effect: Assigns the value rhs to an optional. -
  • -
  • - Postconditions: *this is initialized and its value is a - copy of rhs. -
  • -
  • - Throws: Whatever T::operator=( T const& ) or T::T(T const&) throws. -
  • -
  • - Notes: If *this was initialized, T's - assignment operator is used, otherwise, its copy-constructor is used. -
  • -
  • - Exception Safety: In the event of an exception, - the initialization state of *this is unchanged and its value unspecified - as far as optional is concerned - (it is up to T's operator=()). - If *this - is initially uninitialized and T's - copy constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T x;
    -optional<T> def ;
    -optional<T> opt(x) ;
    -
    -T y;
    -def = y ;
    -assert ( *def == y ) ;
    -opt = y ;
    -assert ( *opt == y ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>& - optional<T&>::operator= ( T& - rhs ) - ; -

-
    -
  • - Effect: (Re)binds the wrapped reference. -
  • -
  • - Postconditions: *this is initialized and it references the - same object referenced by rhs. -
  • -
  • - Notes: If *this was initialized, it is rebound - to the new object. See here - for details on this behavior. -
  • -
  • - Example: -
    int a = 1 ;
    -int b = 2 ;
    -T& ra = a ;
    -T& rb = b ;
    -optional<int&> def ;
    -optional<int&> opt(ra) ;
    -
    -def = rb ; // binds 'def' to 'b' through 'rb'
    -assert ( *def == b ) ;
    -*def = a ; // changes the value of 'b' to a copy of the value of 'a'
    -assert ( b == a ) ;
    -int c = 3;
    -int& rc = c ;
    -opt = rc ; // REBINDS to 'c' through 'rc'
    -c = 4 ;
    -assert ( *opt == 4 ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( T&& rhs - ) ; -

-
    -
  • - Effect: Moves the value rhs to an optional. -
  • -
  • - Postconditions: *this is initialized and its value is moved - from rhs. -
  • -
  • - Throws: Whatever T::operator=( T&& ) - or T::T(T - &&) throws. -
  • -
  • - Notes: If *this was initialized, T's - move-assignment operator is used, otherwise, its move-constructor is used. -
  • -
  • - Exception Safety: In the event of an exception, - the initialization state of *this is unchanged and its value unspecified - as far as optional is concerned - (it is up to T's operator=()). - If *this - is initially uninitialized and T's - move constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T x;
    -optional<T> def ;
    -optional<T> opt(x) ;
    -
    -T y1, y2, yR;
    -def = std::move(y1) ;
    -assert ( *def == yR ) ;
    -opt = std::move(y2) ;
    -assert ( *opt == yR ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>& - optional<T&>::operator= ( T&& - rhs ) - = delete; -

-
  • - Notes: This assignment operator is deleted. -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( optional - const& - rhs ) - ; -

-
    -
  • - Effect: Assigns another optional to an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is a copy of the value - of rhs; else *this is - uninitialized. -
  • -
  • - Throws: Whatever T::operator( T const&) - or T::T( T - const& - ) throws. -
  • -
  • - Notes: If both *this and rhs - are initially initialized, T's - assignment operator is used. If *this is initially initialized but rhs is uninitialized, T's - [destructor] is called. If *this is initially uninitialized but rhs is initialized, T's - copy constructor is called. -
  • -
  • - Exception Safety: In the event of an exception, - the initialization state of *this is unchanged and its value unspecified - as far as optional is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - copy constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -optional<T> def ;
    -
    -opt = def ;
    -assert ( !def ) ;
    -// previous value (copy of 'v') destroyed from within 'opt'.
    -
    -
  • -
-

- space -

-

- optional<T&> & optional<T&>::operator= ( optional<T&> - const& - rhs ) - ; -

-
    -
  • - Effect: (Re)binds thee wrapped reference. -
  • -
  • - Postconditions: If *rhs is initialized, *this is initialized and it references the - same object referenced by *rhs; otherwise, *this is uninitialized (and references no - object). -
  • -
  • - Notes: If *this was initialized and so is *rhs, - *this - is rebound to the new object. See here - for details on this behavior. -
  • -
  • - Example: -
    int a = 1 ;
    -int b = 2 ;
    -T& ra = a ;
    -T& rb = b ;
    -optional<int&> def ;
    -optional<int&> ora(ra) ;
    -optional<int&> orb(rb) ;
    -
    -def = orb ; // binds 'def' to 'b' through 'rb' wrapped within 'orb'
    -assert ( *def == b ) ;
    -*def = ora ; // changes the value of 'b' to a copy of the value of 'a'
    -assert ( b == a ) ;
    -int c = 3;
    -int& rc = c ;
    -optional<int&> orc(rc) ;
    -ora = orc ; // REBINDS ora to 'c' through 'rc'
    -c = 4 ;
    -assert ( *ora == 4 ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( optional&& rhs - ) noexcept(see below); -

-
    -
  • - Effect: Move-assigns another optional to an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is moved from *rhs, rhs - remains initialized; else *this is uninitialized. -
  • -
  • - Throws: Whatever T::operator( T&& - ) or T::T( - T && - ) throws. -
  • -
  • - Notes: If both *this and rhs - are initially initialized, T's - move assignment operator is used. If *this is - initially initialized but rhs - is uninitialized, T's [destructor] - is called. If *this - is initially uninitialized but rhs - is initialized, T's move - constructor is called. The expression inside noexcept - is equivalent to is_nothrow_move_constructible<T>::value - && is_nothrow_move_assignable<T>::value. -
  • -
  • - Exception Safety: In the event of an exception, - the initialization state of *this is unchanged and its value unspecified - as far as optional is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - move constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    optional<T> opt(T(2)) ;
    -optional<T> def ;
    -
    -opt = def ;
    -assert ( def ) ;
    -assert ( opt ) ;
    -assert ( *opt == T(2) ) ;
    -
    -
  • -
-

- space -

-

- optional<T&> & optional<T&>::operator= ( optional<T&>&& - rhs ) - ; -

-
  • - Effect: Same as optional<T&>::operator= ( optional<T&> const& rhs ). -
-

- space -

-

- template<U> optional& - optional<T (not a ref)>::operator= ( optional<U> - const& - rhs ) - ; -

-
    -
  • - Effect: Assigns another convertible optional - to an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is a copy of the value - of rhs converted - to type T; else *this is - uninitialized. -
  • -
  • - Throws: Whatever T::operator=( U const& ) or T::T( - U const& ) - throws. -
  • -
  • - Notes: If both *this and rhs are initially initialized, - T's assignment - operator (from U) - is used. If *this - is initially initialized but rhs - is uninitialized, T's - destructor is called. If *this is initially uninitialized but rhs - is initialized, T's converting - constructor (from U) - is called. -
  • -
  • - Exception Safety: In the event of an exception, - the initialization state of *this is unchanged and its value unspecified - as far as optional is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - converting constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T v;
    -optional<T> opt0(v);
    -optional<U> opt1;
    -
    -opt1 = opt0 ;
    -assert ( *opt1 == static_cast<U>(v) ) ;
    -
    -
  • -
-

- space -

-

- template<U> optional& - optional<T (not a ref)>::operator= ( optional<U>&& - rhs ) - ; -

-
    -
  • - Effect: Move-assigns another convertible - optional to an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is moved from the value of rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Whatever T::operator=( U&& ) - or T::T( U&& ) - throws. -
  • -
  • - Notes: If both *this and rhs - are initially initialized, T's - assignment operator (from U&&) is used. If *this is initially initialized but rhs is uninitialized, T's - destructor is called. If *this is initially uninitialized but rhs is initialized, T's - converting constructor (from U&&) is called. -
  • -
  • - Exception Safety: In the event of an exception, - the initialization state of *this is unchanged and its value unspecified - as far as optional is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - converting constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T v;
    -optional<T> opt0(v);
    -optional<U> opt1;
    -
    -opt1 = std::move(opt0) ;
    -assert ( *opt1 == static_cast<U>(v) ) ;
    -
    -
  • -
-

- space -

-

- template<class... Args> void optional<T - (not a ref)>::emplace( Args...&& - args ); -

-
    -
  • - Requires: The compiler supports rvalue - references and variadic templates. -
  • -
  • - Effect: If *this is initialized calls *this = - none. Then initializes in-place - the contained value as if direct-initializing an object of type T with std::forward<Args>(args).... -
  • -
  • - Postconditions: *this is initialized. -
  • -
  • - Throws: Whatever the selected T's constructor throws. -
  • -
  • - Notes: T - need not be MoveConstructible - or MoveAssignable. -
  • -
  • - Exception Safety: If an exception is thrown - during the initialization of T, - *this - is uninitialized. -
  • -
-

- space -

-

- template<InPlaceFactory> - optional<T>& optional<T (not a ref)>::operator=( InPlaceFactory - const& - f ); -

-

- template<TypedInPlaceFactory> - optional<T>& optional<T (not a ref)>::operator=( TypedInPlaceFactory - const& - f ); -

-
    -
  • - Effect: Assigns an optional - with a value of T obtained - from the factory. -
  • -
  • - Postconditions: *this is initialized - and its value is directly given from the factory - f (i.e., the value is not copied). -
  • -
  • - Throws: Whatever the T - constructor called by the factory throws. -
  • -
  • - Notes: See In-Place - Factories -
  • -
  • - Exception Safety: Exceptions can only - be thrown during the call to the T - constructor used by the factory; in that case, the optional - object will be reset to be uninitialized. -
  • -
-

- space -

-

- void optional<T - (not a ref)>::reset( T const& v ) ; -

-
  • - Deprecated: same as operator= ( T - const& - v) - ; -
-

- space -

-

- void optional<T>::reset() noexcept ; -

-
  • - Deprecated: Same as operator=( none_t ); -
-

- space -

-

- T const& optional<T - (not a ref)>::get() const ; -

-

- T& - optional<T (not a ref)>::get() ; -

-

- inline T - const& - get ( - optional<T (not a ref)> const& ) ; -

-

- inline T& get ( optional<T - (not a ref)> - &) ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: A reference to the contained - value -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted via - BOOST_ASSERT(). -
  • -
-

- space -

-

- T const& optional<T&>::get() const ; -

-

- T& - optional<T&>::get() ; -

-

- inline T - const& - get ( - optional<T&> const& ) ; -

-

- inline T& get ( optional<T&> - &) ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: The - reference contained. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted via - BOOST_ASSERT(). -
  • -
-

- space -

-

- T const& optional<T - (not a ref)>::operator*() const& ; -

-

- T& - optional<T (not a ref)>::operator*() &; -

-

- T&& - optional<T (not a ref)>::operator*() &&; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: A reference to the contained - value -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted via - BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions these - three overloads are replaced with the classical two: a const - and non-const member functions. -
  • -
  • - Example: -
    T v ;
    -optional<T> opt ( v );
    -T const& u = *opt;
    -assert ( u == v ) ;
    -T w ;
    -*opt = w ;
    -assert ( *opt == w ) ;
    -
    -
  • -
-

- space -

-

- T const& optional<T&>::operator*() const& ; -

-

- T & - optional<T&>::operator*() & ; -

-

- T & - optional<T&>::operator*() && ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: The - reference contained. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted via - BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions these - three overloads are replaced with the classical two: a const - and non-const member functions. -
  • -
  • - Example: -
    T v ;
    -T& vref = v ;
    -optional<T&> opt ( vref );
    -T const& vref2 = *opt;
    -assert ( vref2 == v ) ;
    -++ v ;
    -assert ( *opt == v ) ;
    -
    -
  • -
-

- space -

-

- T const& optional<T>::value() const& ; -

-

- T& - optional<T>::value() & ; -

-

- T&& - optional<T>::value() && ; -

-
    -
  • - Returns: A reference to the contained - value, if *this - is initialized. -
  • -
  • - Throws: An instance of bad_optional_access, - if *this - is not initialized. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions these three overloads are replaced with - the classical two: a const - and non-const member functions. -
  • -
  • - Example: -
    T v ;
    -optional<T> o0, o1 ( v );
    -assert ( o1.value() == v );
    -
    -try {
    -  o0.value(); // throws
    -  assert ( false );
    -}
    -catch(bad_optional_access&) {
    -  assert ( true );
    -}
    -
    - space -
  • -
-

- template<class U> T optional<T>::value_or(U && - v) const& ; -

-

- template<class U> T optional<T>::value_or(U && - v) && ; -

-
    -
  • - Requires: T - is CopyConstructible. -
  • -
  • - Returns: First overload: bool(*this) ? **this : static_cast<T>(forward<U>(v)). - second overload: bool(*this) ? - std::move(**this) : - static_cast<T>(forward<U>(v)). -
  • -
  • - Throws: Any exception thrown by the selected - constructor of T. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions these three overloads are replaced with - the classical two: a const - and non-const member functions. - On compilers without rvalue reference support the type of v becomes U - const&. -
  • -
-

- space -

-

- T const& optional<T - (not a ref)>::get_value_or( - T const& default) const ; -

-

- T& - optional<T (not a ref)>::get_value_or( T& - default ) - ; -

-

- inline T - const& - get_optional_value_or ( - optional<T (not a ref)> const& o, T const& default ) ; -

-

- inline T& get_optional_value_or - ( optional<T - (not a ref)>& - o, T& default ) ; -

-
    -
  • - Deprecated: Use value_or() instead. -
  • -
  • - Returns: A reference to the contained - value, if any, or default. -
  • -
  • - Throws: Nothing. -
  • -
  • - Example: -
    T v, z ;
    -optional<T> def;
    -T const& y = def.get_value_or(z);
    -assert ( y == z ) ;
    -
    -optional<T> opt ( v );
    -T const& u = get_optional_value_or(opt,z);
    -assert ( u == v ) ;
    -assert ( u != z ) ;
    -
    -
  • -
-

- space -

-

- T const* optional<T - (not a ref)>::get_ptr() const ; -

-

- T* - optional<T (not a ref)>::get_ptr() ; -

-

- inline T - const* get_pointer ( - optional<T (not a ref)> const& ) ; -

-

- inline T* get_pointer - ( optional<T - (not a ref)> - &) ; -

-
    -
  • - Returns: If *this is initialized, a pointer to the contained - value; else 0 (null). -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The contained value is permanently - stored within *this, - so you should not hold nor delete this pointer -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -optional<T> const copt(v);
    -T* p = opt.get_ptr() ;
    -T const* cp = copt.get_ptr();
    -assert ( p == get_pointer(opt) );
    -assert ( cp == get_pointer(copt) ) ;
    -
    -
  • -
-

- space -

-

- T const* optional<T - (not a ref)>::operator ->() - const ; -

-

- T* - optional<T (not a ref)>::operator ->() ; -

-
    -
  • - Requires: *this is initialized. -
  • -
  • - Returns: A pointer to the contained value. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted via - BOOST_ASSERT(). -
  • -
  • - Example: -
    struct X { int mdata ; } ;
    -X x ;
    -optional<X> opt (x);
    -opt->mdata = 2 ;
    -
    -
  • -
-

- space -

-

- explicit optional<T>::operator bool() const ; -

-
    -
  • - Returns: get_ptr() != 0. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: On compilers that do not support - explicit conversion operators this falls back to safe-bool idiom. -
  • -
  • - Example: -
    optional<T> def ;
    -assert ( def == 0 );
    -optional<T> opt ( v ) ;
    -assert ( opt );
    -assert ( opt != 0 );
    -
    -
  • -
-

- space -

-

- bool optional<T>::operator!() noexcept ; -

-
    -
  • - Returns: If *this is uninitialized, true; - else false. -
  • -
  • - Notes: This operator is provided for those - compilers which can't use the unspecified-bool-type operator - in certain boolean contexts. -
  • -
  • - Example: -
    optional<T> opt ;
    -assert ( !opt );
    -*opt = some_T ;
    -
    -// Notice the "double-bang" idiom here.
    -assert ( !!opt ) ;
    -
    -
  • -
-

- space -

-

- bool optional<T>::is_initialized() - const ; -

-
  • - Deprecated: Same as explicit - operator bool - () ; -
-

- space -

-

- - Free - functions -

-

- space -

-

- optional<T (not a ref)> make_optional( T const& v ) -

-
    -
  • - Returns: optional<T>(v) for the deduced type - T of v. -
  • -
  • - Example: -
    template<class T> void foo ( optional<T> const& opt ) ;
    -
    -foo ( make_optional(1+1) ) ; // Creates an optional<int>
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)> make_optional( bool condition, T const& v ) -

-
    -
  • - Returns: optional<T>(condition,v) - for the deduced type T - of v. -
  • -
  • - Example: -
    optional<double> calculate_foo()
    -{
    -  double val = compute_foo();
    -  return make_optional(is_not_nan_and_finite(val),val);
    -}
    -
    -optional<double> v = calculate_foo();
    -if ( !v )
    -  error("foo wasn't computed");
    -
    -
  • -
-

- space -

-

- bool operator - == ( optional<T> const& x, optional<T> - const& - y ); -

-
    -
  • - Requires: T - shall meet requirements of EqualityComparable. -
  • -
  • - Returns: If both x - and y are initialized, - (*x - == *y). If - only x or y is initialized, false. - If both are uninitialized, true. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: Pointers have shallow relational - operators while optional - has deep relational operators. Do not use operator - == directly in generic code which - expect to be given either an optional<T> or a pointer; use equal_pointees() - instead -
  • -
  • - Example: -
    T x(12);
    -T y(12);
    -T z(21);
    -optional<T> def0 ;
    -optional<T> def1 ;
    -optional<T> optX(x);
    -optional<T> optY(y);
    -optional<T> optZ(z);
    -
    -// Identity always hold
    -assert ( def0 == def0 );
    -assert ( optX == optX );
    -
    -// Both uninitialized compare equal
    -assert ( def0 == def1 );
    -
    -// Only one initialized compare unequal.
    -assert ( def0 != optX );
    -
    -// Both initialized compare as (*lhs == *rhs)
    -assert ( optX == optY ) ;
    -assert ( optX != optZ ) ;
    -
    -
  • -
-

- space -

-

- bool operator - < ( optional<T> const& x, optional<T> - const& - y ); -

-
    -
  • - Requires: T - shall meet requirements of LessThanComparable. -
  • -
  • - Returns: If y - is not initialized, false. - If y is initialized and - x is not initialized, - true. If both x and y - are initialized, (*x - < *y). -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: Pointers have shallow relational - operators while optional - has deep relational operators. Do not use operator - < directly in generic code which - expect to be given either an optional<T> or a pointer; use less_pointees() - instead. -
  • -
  • - Example: -
    T x(12);
    -T y(34);
    -optional<T> def ;
    -optional<T> optX(x);
    -optional<T> optY(y);
    -
    -// Identity always hold
    -assert ( !(def < def) );
    -assert ( optX == optX );
    -
    -// Both uninitialized compare equal
    -assert ( def0 == def1 );
    -
    -// Only one initialized compare unequal.
    -assert ( def0 != optX );
    -
    -// Both initialized compare as (*lhs == *rhs)
    -assert ( optX == optY ) ;
    -assert ( optX != optZ ) ;
    -
    -
  • -
-

- space -

-

- bool operator - != ( optional<T> const& x, optional<T> - const& - y ); -

-
    -
  • - Returns: !( - x == - y ); -
  • -
  • - Throws: Nothing. -
  • -
-

- space -

-

- bool operator - > ( optional<T> const& x, optional<T> - const& - y ); -

-
    -
  • - Returns: ( - y < - x ); -
  • -
  • - Throws: Nothing. -
  • -
-

- space -

-

- bool operator - <= ( - optional<T> const& x, optional<T> - const& - y ); -

-
    -
  • - Returns: !( - y < - x ); -
  • -
  • - Throws: Nothing. -
  • -
-

- space -

-

- bool operator - >= ( - optional<T> const& x, optional<T> - const& - y ); -

-
    -
  • - Returns: !( - x<y ); -
  • -
  • - Throws: Nothing. -
  • -
-

- bool operator - == ( optional<T> const& x, none_t - ) noexcept; -

-
    -
  • - Returns: !x. -
  • -
  • - Notes: T - need not meet requirements of EqualityComparable. -
  • -
-

- space -

-

- bool operator - != ( optional<T> const& x, none_t - ) noexcept; -

-
  • - Returns: !( - x == - y ); -
-

- space -

-

- void swap - ( optional<T>& - x, optional<T>& y ) ; -

-
    -
  • - Effect: If both x - and y are initialized, - calls swap(*x,*y) using std::swap. - If only one is initialized, say x, - calls: y.reset(*x); x.reset(); If none is initialized, does nothing. -
  • -
  • - Postconditions: The states of x and y - interchanged. -
  • -
  • - Throws: If both are initialized, whatever - swap(T&,T&) - throws. If only one is initialized, whatever T::T ( T&& - ) throws. -
  • -
  • - Notes: If both are initialized, swap(T&,T&) - is used unqualified but with std::swap - introduced in scope. If only one is initialized, T::~T() and T::T( - T&& - ) is called. -
  • -
  • - Exception Safety: If both are initialized, - this operation has the exception safety guarantees of swap(T&,T&). - If only one is initialized, it has the same basic guarantee as optional<T>::operator= ( T&& - ). -
  • -
  • - Example: -
    T x(12);
    -T y(21);
    -optional<T> def0 ;
    -optional<T> def1 ;
    -optional<T> optX(x);
    -optional<T> optY(y);
    -
    -boost::swap(def0,def1); // no-op
    -
    -boost::swap(def0,optX);
    -assert ( *def0 == x );
    -assert ( !optX );
    -
    -boost::swap(def0,optX); // Get back to original values
    -
    -boost::swap(optX,optY);
    -assert ( *optX == y );
    -assert ( *optY == x );
    -
    -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/development.html b/doc/html/boost_optional/development.html deleted file mode 100644 index 70bc6e44..00000000 --- a/doc/html/boost_optional/development.html +++ /dev/null @@ -1,412 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- -

- In C++, we can declare an object (a variable) of type - T, and we can give this variable - an initial value (through an initializer. - (cf. 8.5)). When a declaration includes a non-empty initializer (an initial - value is given), it is said that the object has been initialized. If the - declaration uses an empty initializer (no initial value is given), and neither - default nor value initialization applies, it is said that the object is - uninitialized. Its actual value exist but - has an indeterminate initial value (cf. 8.5/11). optional<T> intends - to formalize the notion of initialization (or lack of it) allowing a program - to test whether an object has been initialized and stating that access to - the value of an uninitialized object is undefined behavior. That is, when - a variable is declared as optional<T> - and no initial value is given, the variable is formally - uninitialized. A formally uninitialized optional object has conceptually - no value at all and this situation can be tested at runtime. It is formally - undefined behavior to try to access the value of an - uninitialized optional. An uninitialized optional can be assigned a value, - in which case its initialization state changes to initialized. Furthermore, - given the formal treatment of initialization states in optional objects, - it is even possible to reset an optional to uninitialized. -

-

- In C++ there is no formal notion of uninitialized objects, which means that - objects always have an initial value even if indeterminate. As discussed - on the previous section, this has a drawback because you need additional - information to tell if an object has been effectively initialized. One of - the typical ways in which this has been historically dealt with is via a - special value: EOF, npos, -1, etc... This is equivalent to - adding the special value to the set of possible values of a given type. This - super set of T plus some - nil_t—where nil_t - is some stateless POD—can be modeled in modern languages as a discriminated union of T and nil_t. Discriminated - unions are often called variants. A variant has a current - type, which in our case is either T - or nil_t. Using the Boost.Variant library, this model - can be implemented in terms of boost::variant<T,nil_t>. - There is precedent for a discriminated union as a model for an optional value: - the Haskell Maybe - built-in type constructor. Thus, a discriminated union T+nil_t - serves as a conceptual foundation. -

-

- A variant<T,nil_t> follows naturally from the traditional - idiom of extending the range of possible values adding an additional sentinel - value with the special meaning of Nothing. However, - this additional Nothing value is largely irrelevant - for our purpose since our goal is to formalize the notion of uninitialized - objects and, while a special extended value can be used to convey that meaning, - it is not strictly necessary in order to do so. -

-

- The observation made in the last paragraph about the irrelevant nature of - the additional nil_t with - respect to purpose of optional<T> suggests - an alternative model: a container that either has a - value of T or nothing. -

-

- As of this writing I don't know of any precedent for a variable-size fixed-capacity - (of 1) stack-based container model for optional values, yet I believe this - is the consequence of the lack of practical implementations of such a container - rather than an inherent shortcoming of the container model. -

-

- In any event, both the discriminated-union or the single-element container - models serve as a conceptual ground for a class representing optional—i.e. - possibly uninitialized—objects. For instance, these models show the exact - semantics required for a wrapper of optional values: -

-

- Discriminated-union: -

-
    -
  • - deep-copy semantics: copies of the variant - implies copies of the value. -
  • -
  • - deep-relational semantics: comparisons - between variants matches both current types and values -
  • -
  • - If the variant's current type is T, - it is modeling an initialized optional. -
  • -
  • - If the variant's current type is not T, - it is modeling an uninitialized optional. -
  • -
  • - Testing if the variant's current type is T - models testing if the optional is initialized -
  • -
  • - Trying to extract a T - from a variant when its current type is not T, - models the undefined behavior of trying to access the value of an uninitialized - optional -
  • -
-

- Single-element container: -

-
    -
  • - deep-copy semantics: copies of the container - implies copies of the value. -
  • -
  • - deep-relational semantics: comparisons - between containers compare container size and if match, contained value -
  • -
  • - If the container is not empty (contains an object of type T), it is modeling an initialized - optional. -
  • -
  • - If the container is empty, it is modeling an uninitialized - optional. -
  • -
  • - Testing if the container is empty models testing if the optional is initialized -
  • -
  • - Trying to extract a T - from an empty container models the undefined behavior of trying to access - the value of an uninitialized optional -
  • -
-
-
- -

- Objects of type optional<T> - are intended to be used in places where objects of type T - would but which might be uninitialized. Hence, optional<T>'s - purpose is to formalize the additional possibly uninitialized state. From - the perspective of this role, optional<T> - can have the same operational semantics of T - plus the additional semantics corresponding to this special state. As such, - optional<T> could - be thought of as a supertype of T. - Of course, we can't do that in C++, so we need to compose the desired semantics - using a different mechanism. Doing it the other way around, that is, making - optional<T> a - subtype of T - is not only conceptually wrong but also impractical: it is not allowed to - derive from a non-class type, such as a built-in type. -

-

- We can draw from the purpose of optional<T> - the required basic semantics: -

-
    -
  • - Default Construction: To introduce a - formally uninitialized wrapped object. -
  • -
  • - Direct Value Construction via copy: - To introduce a formally initialized wrapped object whose value is obtained - as a copy of some object. -
  • -
  • - Deep Copy Construction: To obtain a - new yet equivalent wrapped object. -
  • -
  • - Direct Value Assignment (upon initialized): - To assign a value to the wrapped object. -
  • -
  • - Direct Value Assignment (upon uninitialized): - To initialize the wrapped object with a value obtained as a copy of some - object. -
  • -
  • - Assignment (upon initialized): To assign - to the wrapped object the value of another wrapped object. -
  • -
  • - Assignment (upon uninitialized): To - initialize the wrapped object with value of another wrapped object. -
  • -
  • - Deep Relational Operations (when supported by the - type T): To compare wrapped object values taking into account - the presence of uninitialized states. -
  • -
  • - Value access: To unwrap the wrapped - object. -
  • -
  • - Initialization state query: To determine - if the object is formally initialized or not. -
  • -
  • - Swap: To exchange wrapped objects. (with - whatever exception safety guarantees are provided by T's - swap). -
  • -
  • - De-initialization: To release the wrapped - object (if any) and leave the wrapper in the uninitialized state. -
  • -
-

- Additional operations are useful, such as converting constructors and converting - assignments, in-place construction and assignment, and safe value access - via a pointer to the wrapped object or null. -

-
-
- -

- Since the purpose of optional is to allow us to use objects with a formal - uninitialized additional state, the interface could try to follow the interface - of the underlying T type - as much as possible. In order to choose the proper degree of adoption of - the native T interface, the - following must be noted: Even if all the operations supported by an instance - of type T are defined for - the entire range of values for such a type, an optional<T> - extends such a set of values with a new value for which most (otherwise valid) - operations are not defined in terms of T. -

-

- Furthermore, since optional<T> - itself is merely a T wrapper - (modeling a T supertype), - any attempt to define such operations upon uninitialized optionals will be - totally artificial w.r.t. T. -

-

- This library chooses an interface which follows from T's - interface only for those operations which are well defined (w.r.t the type - T) even if any of the operands - are uninitialized. These operations include: construction, copy-construction, - assignment, swap and relational operations. -

-

- For the value access operations, which are undefined (w.r.t the type T) when the operand is uninitialized, a - different interface is chosen (which will be explained next). -

-

- Also, the presence of the possibly uninitialized state requires additional - operations not provided by T - itself which are supported by a special interface. -

-
- - Lexically-hinted - Value Access in the presence of possibly untitialized optional objects: The - operators * and -> -
-

- A relevant feature of a pointer is that it can have a null - pointer value. This is a special value which - is used to indicate that the pointer is not referring to any object at all. - In other words, null pointer values convey the notion of nonexistent objects. -

-

- This meaning of the null pointer value allowed pointers to became a de - facto standard for handling optional objects because all you have - to do to refer to a value which you don't really have is to use a null pointer - value of the appropriate type. Pointers have been used for decades—from - the days of C APIs to modern C++ libraries—to refer - to optional (that is, possibly nonexistent) objects; particularly as optional - arguments to a function, but also quite often as optional data members. -

-

- The possible presence of a null pointer value makes the operations that access - the pointee's value possibly undefined, therefore, expressions which use - dereference and access operators, such as: ( - *p = 2 ) - and ( p->foo() ), implicitly - convey the notion of optionality, and this information is tied to the syntax - of the expressions. That is, the presence of operators * - and -> tell by themselves - —without any additional context— that the expression will be undefined - unless the implied pointee actually exist. -

-

- Such a de facto idiom for referring to optional objects - can be formalized in the form of a concept: the OptionalPointee - concept. This concept captures the syntactic usage of operators *, -> - and contextual conversion to bool - to convey the notion of optionality. -

-

- However, pointers are good to refer - to optional objects, but not particularly good to handle the optional objects - in all other respects, such as initializing or moving/copying them. The problem - resides in the shallow-copy of pointer semantics: if you need to effectively - move or copy the object, pointers alone are not enough. The problem is that - copies of pointers do not imply copies of pointees. For example, as was discussed - in the motivation, pointers alone cannot be used to return optional objects - from a function because the object must move outside from the function and - into the caller's context. -

-

- A solution to the shallow-copy problem that is often used is to resort to - dynamic allocation and use a smart pointer to automatically handle the details - of this. For example, if a function is to optionally return an object X, it can use shared_ptr<X> - as the return value. However, this requires dynamic allocation of X. If X - is a built-in or small POD, this technique is very poor in terms of required - resources. Optional objects are essentially values so it is very convenient - to be able to use automatic storage and deep-copy semantics to manipulate - optional values just as we do with ordinary values. Pointers do not have - this semantics, so are inappropriate for the initialization and transport - of optional values, yet are quite convenient for handling the access to the - possible undefined value because of the idiomatic aid present in the OptionalPointee concept - incarnated by pointers. -

-
- - Optional<T> - as a model of OptionalPointee -
-

- For value access operations optional<> uses operators * - and -> to lexically warn - about the possibly uninitialized state appealing to the familiar pointer - semantics w.r.t. to null pointers. -

-
- - - - - -
[Warning]Warning

- However, it is particularly important to note that optional<> objects are not pointers. optional<> is not, and does not model, a pointer. -

-

- For instance, optional<> - does not have shallow-copy so does not alias: two different optionals never - refer to the same value unless T - itself is a reference (but may have equivalent values). - The difference between an optional<T> - and a pointer must be kept in mind, particularly because the semantics of - relational operators are different: since optional<T> - is a value-wrapper, relational operators are deep: they compare optional - values; but relational operators for pointers are shallow: they do not compare - pointee values. As a result, you might be able to replace optional<T> - by T* - on some situations but not always. Specifically, on generic code written - for both, you cannot use relational operators directly, and must use the - template functions equal_pointees() - and less_pointees() - instead. -

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/discussion.html b/doc/html/boost_optional/discussion.html deleted file mode 100644 index d17a70e8..00000000 --- a/doc/html/boost_optional/discussion.html +++ /dev/null @@ -1,128 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Consider these functions which should return a value but which might not have - a value to return: -

-
    -
  • - (A) double sqrt(double n ); -
  • -
  • - (B) char get_async_input(); -
  • -
  • - (C) point polygon::get_any_point_effectively_inside(); -
  • -
-

- There are different approaches to the issue of not having a value to return. -

-

- A typical approach is to consider the existence of a valid return value as - a postcondition, so that if the function cannot compute the value to return, - it has either undefined behavior (and can use assert in a debug build) or uses - a runtime check and throws an exception if the postcondition is violated. This - is a reasonable choice for example, for function (A), because the lack of a - proper return value is directly related to an invalid parameter (out of domain - argument), so it is appropriate to require the callee to supply only parameters - in a valid domain for execution to continue normally. -

-

- However, function (B), because of its asynchronous nature, does not fail just - because it can't find a value to return; so it is incorrect to consider such - a situation an error and assert or throw an exception. This function must return, - and somehow, must tell the callee that it is not returning a meaningful value. -

-

- A similar situation occurs with function (C): it is conceptually an error to - ask a null-area polygon to return a point inside itself, - but in many applications, it is just impractical for performance reasons to - treat this as an error (because detecting that the polygon has no area might - be too expensive to be required to be tested previously), and either an arbitrary - point (typically at infinity) is returned, or some efficient way to tell the - callee that there is no such point is used. -

-

- There are various mechanisms to let functions communicate that the returned - value is not valid. One such mechanism, which is quite common since it has - zero or negligible overhead, is to use a special value which is reserved to - communicate this. Classical examples of such special values are EOF, string::npos, points - at infinity, etc... -

-

- When those values exist, i.e. the return type can hold all meaningful values - plus the signal value, this mechanism - is quite appropriate and well known. Unfortunately, there are cases when such - values do not exist. In these cases, the usual alternative is either to use - a wider type, such as int in place - of char; or a compound type, such - as std::pair<point,bool>. -

-

- Returning a std::pair<T,bool>, thus attaching a boolean flag to the result - which indicates if the result is meaningful, has the advantage that can be - turned into a consistent idiom since the first element of the pair can be whatever - the function would conceptually return. For example, the last two functions - could have the following interface: -

-
std::pair<char,bool> get_async_input();
-std::pair<point,bool> polygon::get_any_point_effectively_inside();
-
-

- These functions use a consistent interface for dealing with possibly nonexistent - results: -

-
std::pair<point,bool> p = poly.get_any_point_effectively_inside();
-if ( p.second )
-    flood_fill(p.first);
-
-

- However, not only is this quite a burden syntactically, it is also error prone - since the user can easily use the function result (first element of the pair) - without ever checking if it has a valid value. -

-

- Clearly, we need a better idiom. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/examples.html b/doc/html/boost_optional/examples.html deleted file mode 100644 index 64a95a97..00000000 --- a/doc/html/boost_optional/examples.html +++ /dev/null @@ -1,147 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- -
optional<char> get_async_input()
-{
-    if ( !queue.empty() )
-        return optional<char>(queue.top());
-    else return optional<char>(); // uninitialized
-}
-
-void receive_async_message()
-{
-    optional<char> rcv ;
-    // The safe boolean conversion from 'rcv' is used here.
-    while ( (rcv = get_async_input()) && !timeout() )
-        output(*rcv);
-}
-
-
-
- -
optional<string> name ;
-if ( database.open() )
-{
-    name = database.lookup(employer_name) ;
-}
-else
-{
-    if ( can_ask_user )
-        name = user.ask(employer_name) ;
-}
-
-if ( name )
-    print(*name);
-else print("employer's name not found!");
-
-
-
- -
class figure
-{
-    public:
-
-    figure()
-    {
-        // data member 'm_clipping_rect' is uninitialized at this point.
-    }
-
-    void clip_in_rect ( rect const& rect )
-    {
-        ....
-        m_clipping_rect = rect ; // initialized here.
-    }
-
-    void draw ( canvas& cvs )
-    {
-        if ( m_clipping_rect )
-            do_clipping(*m_clipping_rect);
-
-        cvs.drawXXX(..);
-    }
-
-    // this can return NULL.
-    rect const* get_clipping_rect() { return get_pointer(m_clipping_rect); }
-
-    private :
-
-    optional<rect> m_clipping_rect ;
-
-};
-
-
-
- -
class ExpensiveCtor { ... } ;
-class Fred
-{
-    Fred() : mLargeVector(10000) {}
-
-    std::vector< optional<ExpensiveCtor> > mLargeVector ;
-} ;
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/exception_safety_guarantees.html b/doc/html/boost_optional/exception_safety_guarantees.html deleted file mode 100644 index 25379180..00000000 --- a/doc/html/boost_optional/exception_safety_guarantees.html +++ /dev/null @@ -1,170 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- This library assumes that T's - destructor does not throw exceptions. If it does, the behaviour of many operations - on optional<T> is - undefined. -

-

- The following mutating operations never throw exceptions: -

-
    -
  • - optional<T>::operator= ( none_t ) noexcept -
  • -
  • - optional<T>::reset() noexcept -
  • -
-

- In addition, the following constructors and the destructor never throw exceptions: -

-
    -
  • - optional<T>::optional() - noexcept -
  • -
  • - optional<T>::optional( none_t ) noexcept -
  • -
-

- Regarding the following assignment functions: -

-
    -
  • - optional<T>::operator= ( optional<T> const& ) -
  • -
  • - optional<T>::operator= ( T const& ) -
  • -
  • - template<class U> optional<T>::operator= ( optional<U> const& ) -
  • -
  • - template<class InPlaceFactory> optional<T>::operator= ( InPlaceFactory - const& - ) -
  • -
  • - template<class TypedInPlaceFactory> optional<T>::operator= ( TypedInPlaceFactory - const& - ) -
  • -
  • - optional<T>::reset( T const& ) -
  • -
-

- They forward calls to the corresponding T's - constructors or assignments (depending on whether the optional object is initialized - or not); so if both T's constructor - and the assignment provide strong exception safety guarantee, optional<T>'s assignment - also provides strong exception safety guarantee; otherwise we only get the - basic guarantee. Additionally, if both involved T's - constructor and the assignment never throw, optional<T>'s - assignment also never throws. -

-

- Unless T's constructor or assignment - throws, assignments to optional<T> - do not throw anything else on its own. A throw during assignment never changes - the initialization state of any optional object involved: -

-
optional<T> opt1(val1);
-optional<T> opt2(val2);
-assert(opt1);
-assert(opt2);
-
-try
-{
-  opt1 = opt2; // throws
-}
-catch(...)
-{
-  assert(opt1);
-  assert(opt2);
-}
-
-

- This also applies to move assignments/constructors. However, move operations - are made no-throw more often. -

-

- Operation emplace provides - basic exception safety guarantee. If it throws, the optional object becomes - uninitialized regardless of its initial state, and its previous contained value - (if any) is destroyed. It doesn't call any assignment or move/copy constructor - on T. -

-

- - Swap -

-

- Unless swap on optional is - customized, its primary implementation forwards calls to T's - swap or move constructor (depending - on the initialization state of the optional objects). Thus, if both T's swap - and move constructor never throw, swap - on optional<T> never - throws. similarly, if both T's - swap and move constructor offer - strong guarantee, swap on - optional<T> also - offers a strong guarantee. -

-

- In case swap on optional is - customized, the call to T's - move constructor are replaced with the calls to T's - default constructor followed by swap. - (This is more useful on older compilers that do not support move semantics, - when one wants to acheive stronger exception safety guarantees.) In this case - the exception safety guarantees for swap - are reliant on the guarantees of T's - swap and default constructor -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/implementation_notes.html b/doc/html/boost_optional/implementation_notes.html deleted file mode 100644 index 48d476cd..00000000 --- a/doc/html/boost_optional/implementation_notes.html +++ /dev/null @@ -1,55 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- optional<T> is - currently implemented using a custom aligned storage facility built from alignment_of and type_with_alignment - (both from Type Traits). It uses a separate boolean flag to indicate the initialization - state. Placement new with T's - copy/move constructor and T's - destructor are explicitly used to initialize, copy, move and destroy optional - values. As a result, T's default - constructor is effectively by-passed, but the exception guarantees are basic. - It is planned to replace the current implementation with another with stronger - exception safety, such as a future boost::variant. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/in_place_factories.html b/doc/html/boost_optional/in_place_factories.html deleted file mode 100644 index 1cc1e05f..00000000 --- a/doc/html/boost_optional/in_place_factories.html +++ /dev/null @@ -1,196 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- One of the typical problems with wrappers and containers is that their interfaces - usually provide an operation to initialize or assign the contained object as - a copy of some other object. This not only requires the underlying type to - be Copy Constructible, - but also requires the existence of a fully constructed object, often temporary, - just to follow the copy from: -

-
struct X
-{
-    X ( int, std::string ) ;
-} ;
-
-class W
-{
-    X wrapped_ ;
-
-    public:
-
-    W ( X const& x ) : wrapped_(x) {}
-} ;
-
-void foo()
-{
-    // Temporary object created.
-    W ( X(123,"hello") ) ;
-}
-
-

- A solution to this problem is to support direct construction of the contained - object right in the container's storage. In this scheme, the user only needs - to supply the arguments to the constructor to use in the wrapped object construction. -

-
class W
-{
-    X wrapped_ ;
-
-    public:
-
-    W ( X const& x ) : wrapped_(x) {}
-    W ( int a0, std::string a1) : wrapped_(a0,a1) {}
-} ;
-
-void foo()
-{
-    // Wrapped object constructed in-place
-    // No temporary created.
-    W (123,"hello") ;
-}
-
-

- A limitation of this method is that it doesn't scale well to wrapped objects - with multiple constructors nor to generic code were the constructor overloads - are unknown. -

-

- The solution presented in this library is the family of InPlaceFactories - and TypedInPlaceFactories. These factories - are a family of classes which encapsulate an increasing number of arbitrary - constructor parameters and supply a method to construct an object of a given - type using those parameters at an address specified by the user via placement - new. -

-

- For example, one member of this family looks like: -

-
template<class T,class A0, class A1>
-class TypedInPlaceFactory2
-{
-    A0 m_a0 ; A1 m_a1 ;
-
-    public:
-
-    TypedInPlaceFactory2( A0 const& a0, A1 const& a1 ) : m_a0(a0), m_a1(a1) {}
-
-    void construct ( void* p ) { new (p) T(m_a0,m_a1) ; }
- } ;
-
-

- A wrapper class aware of this can use it as: -

-
class W
-{
-    X wrapped_ ;
-
-    public:
-
-    W ( X const& x ) : wrapped_(x) {}
-    W ( TypedInPlaceFactory2 const& fac ) { fac.construct(&wrapped_) ; }
-} ;
-
-void foo()
-{
-    // Wrapped object constructed in-place via a TypedInPlaceFactory.
-    // No temporary created.
-    W ( TypedInPlaceFactory2<X,int,std::string>(123,"hello")) ;
-}
-
-

- The factories are divided in two groups: -

-
    -
  • - TypedInPlaceFactories: those which - take the target type as a primary template parameter. -
  • -
  • - InPlaceFactories: those with a template - construct(void*) member - function taking the target type. -
  • -
-

- Within each group, all the family members differ only in the number of parameters - allowed. -

-

- This library provides an overloaded set of helper template functions to construct - these factories without requiring unnecessary template parameters: -

-
template<class A0,...,class AN>
-InPlaceFactoryN <A0,...,AN> in_place ( A0 const& a0, ..., AN const& aN) ;
-
-template<class T,class A0,...,class AN>
-TypedInPlaceFactoryN <T,A0,...,AN> in_place ( T const& a0, A0 const& a0, ..., AN const& aN) ;
-
-

- In-place factories can be used generically by the wrapper and user as follows: -

-
class W
-{
-    X wrapped_ ;
-
-    public:
-
-    W ( X const& x ) : wrapped_(x) {}
-
-    template< class InPlaceFactory >
-    W ( InPlaceFactory const& fac ) { fac.template <X>construct(&wrapped_) ; }
-
-} ;
-
-void foo()
-{
-    // Wrapped object constructed in-place via a InPlaceFactory.
-    // No temporary created.
-    W ( in_place(123,"hello") ) ;
-}
-
-

- The factories are implemented in the headers: in_place_factory.hpp - and typed_in_place_factory.hpp -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/motivation.html b/doc/html/boost_optional/motivation.html deleted file mode 100644 index ee00899c..00000000 --- a/doc/html/boost_optional/motivation.html +++ /dev/null @@ -1,128 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Consider these functions which should return a value but which might not have - a value to return: -

-
    -
  • - (A) double sqrt(double n ); -
  • -
  • - (B) char get_async_input(); -
  • -
  • - (C) point polygon::get_any_point_effectively_inside(); -
  • -
-

- There are different approaches to the issue of not having a value to return. -

-

- A typical approach is to consider the existence of a valid return value as - a postcondition, so that if the function cannot compute the value to return, - it has either undefined behavior (and can use assert in a debug build) or uses - a runtime check and throws an exception if the postcondition is violated. This - is a reasonable choice for example, for function (A), because the lack of a - proper return value is directly related to an invalid parameter (out of domain - argument), so it is appropriate to require the callee to supply only parameters - in a valid domain for execution to continue normally. -

-

- However, function (B), because of its asynchronous nature, does not fail just - because it can't find a value to return; so it is incorrect to consider such - a situation an error and assert or throw an exception. This function must return, - and somehow, must tell the callee that it is not returning a meaningful value. -

-

- A similar situation occurs with function (C): it is conceptually an error to - ask a null-area polygon to return a point inside itself, - but in many applications, it is just impractical for performance reasons to - treat this as an error (because detecting that the polygon has no area might - be too expensive to be required to be tested previously), and either an arbitrary - point (typically at infinity) is returned, or some efficient way to tell the - callee that there is no such point is used. -

-

- There are various mechanisms to let functions communicate that the returned - value is not valid. One such mechanism, which is quite common since it has - zero or negligible overhead, is to use a special value which is reserved to - communicate this. Classical examples of such special values are EOF, string::npos, points - at infinity, etc... -

-

- When those values exist, i.e. the return type can hold all meaningful values - plus the signal value, this mechanism - is quite appropriate and well known. Unfortunately, there are cases when such - values do not exist. In these cases, the usual alternative is either to use - a wider type, such as int in place - of char; or a compound type, such - as std::pair<point,bool>. -

-

- Returning a std::pair<T,bool>, thus attaching a boolean flag to the result - which indicates if the result is meaningful, has the advantage that can be - turned into a consistent idiom since the first element of the pair can be whatever - the function would conceptually return. For example, the last two functions - could have the following interface: -

-
std::pair<char,bool> get_async_input();
-std::pair<point,bool> polygon::get_any_point_effectively_inside();
-
-

- These functions use a consistent interface for dealing with possibly nonexistent - results: -

-
std::pair<point,bool> p = poly.get_any_point_effectively_inside();
-if ( p.second )
-    flood_fill(p.first);
-
-

- However, not only is this quite a burden syntactically, it is also error prone - since the user can easily use the function result (first element of the pair) - without ever checking if it has a valid value. -

-

- Clearly, we need a better idiom. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/optional_references.html b/doc/html/boost_optional/optional_references.html deleted file mode 100644 index 4da272ed..00000000 --- a/doc/html/boost_optional/optional_references.html +++ /dev/null @@ -1,114 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- This library allows the template parameter T - to be of reference type: T&, and to some extent, T - const&. -

-

- However, since references are not real objects some restrictions apply and - some operations are not available in this case: -

-
    -
  • - Converting constructors -
  • -
  • - Converting assignment -
  • -
  • - InPlace construction -
  • -
  • - InPlace assignment -
  • -
  • - Value-access via pointer -
  • -
-

- Also, even though optional<T&> - treats it wrapped pseudo-object much as a real value, a true real reference - is stored so aliasing will ocurr: -

-
    -
  • - Copies of optional<T&> - will copy the references but all these references will nonetheless refer - to the same object. -
  • -
  • - Value-access will actually provide access to the referenced object rather - than the reference itself. -
  • -
-
- - - - - -
[Warning]Warning

- On compilers that do not conform to Standard C++ rules of reference binding, - operations on optional references might give adverse results: rather than - binding a reference to a designated object they may create an unexpected - temporary and bind to it. For more details see Dependencies - and Portability section. -

-

- - Rvalue - references -

-

- Rvalue references and lvalue references to const have the ability in C++ to - extend the life time of a temporary they bind to. Optional references do not - have this capability, therefore to avoid surprising effects it is not possible - to initialize an optional references from a temporary. Optional rvalue references - are disabled altogether. Also, the initialization and assignment of an optional - reference to const from rvalue reference is disabled. -

-
const int& i = 1;            // legal
-optional<const int&> oi = 1; // illegal
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/quick_start.html b/doc/html/boost_optional/quick_start.html deleted file mode 100644 index 0ef16bc8..00000000 --- a/doc/html/boost_optional/quick_start.html +++ /dev/null @@ -1,169 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- -

- Let's write and use a converter function that converts a std::string - to an int. It is possible that - for a given string (e.g. "cat") - there exists no value of type int - capable of representing the conversion result. We do not consider such situation - an error. We expect that the converter can be used only to check if the conversion - is possible. A natural signature for this function can be: -

-
#include <boost/optional.hpp>
-boost::optional<int> convert(const std::string& text);
-
-

- All necessary functionality can be included with one header <boost/optional.hpp>. - The above function signature means that the function can either return a - value of type int or a flag - indicating that no value of int - is available. This does not indicate an error. It is like one additional - value of int. This is how we - can use our function: -

-
const std::string& text = /*... */;
-boost::optional<int> oi = convert(text); // move-construct
-if (oi)                                  // contextual conversion to bool
-  int i = *oi;                           // operator*
-
-

- In order to test if optional - contains a value, we use the contextual conversion to type bool. Because of this we can combine the initialization - of the optional object and the test into one instruction: -

-
if (boost::optional<int> oi = convert(text))
-  int i = *oi;
-
-

- We extract the contained value with operator* (and with operator-> where it makes sense). An attempt to - extract the contained value of an uninitialized optional object is an undefined - behaviour (UB). This implementation guards the call with BOOST_ASSERT. Therefore you should be sure - that the contained value is there before extracting. For instance, the following - code is reasonably UB-safe: -

-
int i = *convert("100");
-
-

- This is because we know that string value "100" - converts to a valid value of int. - If you do not like this potential UB, you can use an alternative way of extracting - the contained value: -

-
try {
-  int j = convert(text).value();
-}
-catch (const boost::bad_optional_access&) {
-  // deal with it
-}
-
-

- This version throws an exception upon an attempt to access a non-existent - contained value. If your way of dealing with the missing value is to use - some default, like 0, there exists - a yet another alternative: -

-
int k = convert(text).value_or(0);
-
-

- This uses the atoi-like approach - to conversions: if text does - not represent an integral number just return 0. - Finally, you can provide a callback to be called when trying to access the - contained value fails: -

-
int fallback_to_default()
-{
-  cerr << "could not convert; using -1 instead" << endl;
-  return -1;
-}
-
-int l = convert(text).value_or_eval(fallback_to_default);
-
-

- This will call the provided callback and return whatever the callback returns. - The callback can have side effects: they will only be observed when the optional - object does not contain a value. -

-

- Now, let's consider how function convert - can be implemented. -

-
boost::optional<int> convert(const std::string& text)
-{
-  std::stringstream s(text);
-  int i;
-  if ((s >> i) && s.get() == std::char_traits<char>::eof())
-    return i;
-  else
-    return boost::none;
-}
-
-

- Observe the two return statements. return - i uses the converting constructor - that can create optional<T> - from T. Thus constructed - optional object is initialized and its value is a copy of i. - The other return statement uses another converting constructor from a special - tag boost::none. It is used to indicate that we want - to create an uninitialized optional object. -

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html b/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html deleted file mode 100644 index e039e0ce..00000000 --- a/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html +++ /dev/null @@ -1,75 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Suppose we have class Date, - which does not have a default constructor: there is no good candidate for - a default date. We have a function that returns two dates in form of a boost::tuple: -

-
boost::tuple<Date, Date> getPeriod();
-
-

- In other place we want to use the result of getPeriod, - but want the two dates to be named: begin - and end. We want to implement - something like 'multiple return values': -

-
Date begin, end; // Error: no default ctor!
-boost::tie(begin, end) = getPeriod();
-
-

- The second line works already, this is the capability of Boost.Tuple - library, but the first line won't work. We could set some invented initial - dates, but it is confusing and may be an unacceptable cost, given that these - values will be overwritten in the next line anyway. This is where optional can help: -

-
boost::optional<Date> begin, end;
-boost::tie(begin, end) = getPeriod();
-
-

- It works because inside boost::tie a - move-assignment from T is - invoked on optional<T>, - which internally calls a move-constructor of T. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/quick_start/optional_automatic_variables.html b/doc/html/boost_optional/quick_start/optional_automatic_variables.html deleted file mode 100644 index f7b66648..00000000 --- a/doc/html/boost_optional/quick_start/optional_automatic_variables.html +++ /dev/null @@ -1,75 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- We could write function convert - in a slightly different manner, so that it has a single return-statement: -

-
boost::optional<int> convert(const std::string& text)
-{
-  boost::optional<int> ans;
-  std::stringstream s(text);
-  int i;
-  if ((s >> i) && s.get() == std::char_traits<char>::eof())
-    ans = i;
-
-  return ans;
-}
-
-

- The default constructor of optional - creates an unitialized optional object. Unlike with ints - you cannot have an optional<int> - in an indeterminate state. Its state is always well defined. Instruction - ans = - i initializes the optional object. - It uses the 'mixed' assignment from int. - In general, for optional<T>, - when an assignment from T - is invoked, it can do two things. If the optional object is not initialized - (our case here), it initializes the contained value using T's - copy constructor. If the optional object is already initialized, it assigns - the new value to it using T's - copy assignment. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/quick_start/optional_data_members.html b/doc/html/boost_optional/quick_start/optional_data_members.html deleted file mode 100644 index a06aa105..00000000 --- a/doc/html/boost_optional/quick_start/optional_data_members.html +++ /dev/null @@ -1,94 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Suppose we want to implement a lazy load optimization. - This is because we do not want to perform an expensive initialization of - our Resource until (if at - all) it is really used. We can do it this way: -

-
class Widget
-{
-  mutable boost::optional<const Resource> resource_;
-
-public:
-  Widget() {}
-
-  const Resource& getResource() const // not thread-safe
-  {
-    if (resource_ == boost::none)
-        resource_.emplace("resource", "arguments");
-
-    return *resource_;
-  }
-};
-
-

- optional's default constructor - creates an uninitialized optional. No call to Resource's - default constructor is attempted. Resource - doesn't have to be DefaultConstructible. In function - getResource we first check - if resource_ is initialized. - This time we do not use the contextual conversion to bool, - but a comparison with boost::none. - These two ways are equivalent. Function emplace - initializes the optional in-place by perfect-forwarding the arguments to - the constructor of Resource. - No copy- or move-construction is involved here. Resource - doesn't even have to be MoveConstructible. -

-
- - - - - -
[Note]Note

- Function emplace is only - available on compilers that support rvalue references and variadic templates. - If your compiler does not support these features and you still need to - avoid any move-constructions, use In-Place - Factories. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/quick_start/optional_return_values.html b/doc/html/boost_optional/quick_start/optional_return_values.html deleted file mode 100644 index 9ad85ef1..00000000 --- a/doc/html/boost_optional/quick_start/optional_return_values.html +++ /dev/null @@ -1,135 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Let's write and use a converter function that converts an a std::string - to an int. It is possible that - for a given string (e.g. "cat") - there exist no value of type int - capable of representing the conversion result. We do not consider such situation - an error. We expect that the converter can be used only to check if the conversion - is possible. A natural signature for this function can be: -

-
#include <boost/optional.hpp>
-boost::optionl<int> convert(const std::string& text);
-
-

- All necessary functionality can be included with one header <boost/optional.hpp>. - The above function signature means that the function can either return a - value of type int or a flag - indicating that no value of int - is available. This does not indicate an error. It is like one additional - value of int. This is how we - can use our function: -

-
const std::string& text = /*... */;
-boost::optionl<int> oi = convert(text); // move-construct
-if (oi)                                 // contextual conversion to bool
-  int i = *oi;                          // operator*
-
-

- In order to test if optional - contains a value, we use the contextual conversion to type bool. Because of this we can combine the initialization - of the optional object and the test into one instruction: -

-
if (boost::optionl<int> oi = convert(text))
-  int i = *oi;
-
-

- We extract the contained value with operator* (and with operator-> where it makes sense). An attempt to - extract the contained value of an uninitialized optional object is an undefined - behaviour (UB). This implementation guards the call with BOOST_ASSERT. Therefore you should be sure - that the contained value is there before extracting. For instance, the following - code is reasonably UB-safe: -

-
int i = *convert("100");
-
-

- This is because we know that string value "100" - converts to a valid value of int. - If you do not like this potential UB, you can use an alternative way of extracting - the contained value: -

-
try {
-  int j = convert(text).value();
-}
-catch (const boost::bad_optional_access&) {
-  // deal with it
-}
-
-

- This version throws an exception upon an attempt to access a non-existent - contained value. If your way of dealing with the missing value is to use - some default, like 0, there exists - a yet another alternative: -

-
int k = convert(text).value_or(0);
-
-

- This uses the atoi-like approach - to conversions: if text does - not represent an integral number just return 0. - Now, let's consider how function convert - can be implemented. -

-
boost::optionl<int> convert(const std::string& text)
-{
-  std::stringstream s(text);
-  int i;
-  if ((s >> i) && s.get() == std::char_traits<char>::eof())
-    return i;
-  else
-    return boost::none;
-}
-
-

- Observe the two return statements. return - i uses the converting constructor - that can create optional<T> - from T. Thus constructed - optional object is initialized and its value is a copy of i. - The other return statement uses another converting constructor from a special - tag boost::none. It is used to indicate that we want - to create an uninitialized optional object. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/quick_start/storage_in_containers.html b/doc/html/boost_optional/quick_start/storage_in_containers.html deleted file mode 100644 index 4c145f11..00000000 --- a/doc/html/boost_optional/quick_start/storage_in_containers.html +++ /dev/null @@ -1,64 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Suppose you want to ask users to choose some number (an int). - One of the valid responses is to choose nothing, which is represented by - an uninitialized optional<int>. - You want to make a histogram showing how many times each choice was made. - You can use an std::map: -

-
std::map<boost::optional<int>, int> choices;
-
-for (int i = 0; i < LIMIT; ++i) {
-  boost::optional<int> choice = readChoice();
-  ++choices[choice];
-}
-
-

- This works because optional<T> - is LessThanComparable whenever T is LessThanComparable. In this case - the state of being uninitialized is treated as a yet another value of T, which is compared less than any value - of T. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/rebinding_semantics_for_assignment_of_optional_references.html b/doc/html/boost_optional/rebinding_semantics_for_assignment_of_optional_references.html deleted file mode 100644 index bfcba148..00000000 --- a/doc/html/boost_optional/rebinding_semantics_for_assignment_of_optional_references.html +++ /dev/null @@ -1,148 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- If you assign to an uninitialized optional<T&> - the effect is to bind (for the first time) to the object. Clearly, there is - no other choice. -

-
int x = 1 ;
-int& rx = x ;
-optional<int&> ora ;
-optional<int&> orb(x) ;
-ora = orb ; // now 'ora' is bound to 'x' through 'rx'
-*ora = 2 ; // Changes value of 'x' through 'ora'
-assert(x==2);
-
-

- If you assign to a bare C++ reference, the assignment is forwarded to the referenced - object; its value changes but the reference is never rebound. -

-
int a = 1 ;
-int& ra = a ;
-int b = 2 ;
-int& rb = b ;
-ra = rb ; // Changes the value of 'a' to 'b'
-assert(a==b);
-b = 3 ;
-assert(ra!=b); // 'ra' is not rebound to 'b'
-
-

- Now, if you assign to an initialized optional<T&>, - the effect is to rebind to the new object - instead of assigning the referee. This is unlike bare C++ references. -

-
int a = 1 ;
-int b = 2 ;
-int& ra = a ;
-int& rb = b ;
-optional<int&> ora(ra) ;
-optional<int&> orb(rb) ;
-ora = orb ; // 'ora' is rebound to 'b'
-*ora = 3 ; // Changes value of 'b' (not 'a')
-assert(a==1);
-assert(b==3);
-
-

- - Rationale -

-

- Rebinding semantics for the assignment of initialized - optional references has been - chosen to provide consistency among initialization states - even at the expense of lack of consistency with the semantics of bare C++ references. - It is true that optional<U> strives - to behave as much as possible as U - does whenever it is initialized; but in the case when U - is T&, - doing so would result in inconsistent behavior w.r.t to the lvalue initialization - state. -

-

- Imagine optional<T&> - forwarding assignment to the referenced object (thus changing the referenced - object value but not rebinding), and consider the following code: -

-
optional<int&> a = get();
-int x = 1 ;
-int& rx = x ;
-optional<int&> b(rx);
-a = b ;
-
-

- What does the assignment do? -

-

- If a is uninitialized, - the answer is clear: it binds to x - (we now have another reference to x). - But what if a is already initialized? - it would change the value of the referenced object (whatever that is); which - is inconsistent with the other possible case. -

-

- If optional<T&> - would assign just like T& - does, you would never be able to use Optional's assignment without explicitly - handling the previous initialization state unless your code is capable of functioning - whether after the assignment, a - aliases the same object as b - or not. -

-

- That is, you would have to discriminate in order to be consistent. -

-

- If in your code rebinding to another object is not an option, then it is very - likely that binding for the first time isn't either. In such case, assignment - to an uninitialized optional<T&> - shall be prohibited. It is quite possible that in such a scenario it is a precondition - that the lvalue must be already initialized. If it isn't, then binding for - the first time is OK while rebinding is not which is IMO very unlikely. In - such a scenario, you can assign the value itself directly, as in: -

-
assert(!!opt);
-*opt=value;
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/acknowledgements.html b/doc/html/boost_optional/reference/acknowledgements.html deleted file mode 100644 index f5a719de..00000000 --- a/doc/html/boost_optional/reference/acknowledgements.html +++ /dev/null @@ -1,131 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHome -
-
- -
- - Pre-formal - review -
-
    -
  • - Peter Dimov suggested the name 'optional', and was the first to point - out the need for aligned storage. -
  • -
  • - Douglas Gregor developed 'type_with_alignment', and later Eric Friedman - coded 'aligned_storage', which are the core of the optional class implementation. -
  • -
  • - Andrei Alexandrescu and Brian Parker also worked with aligned storage - techniques and their work influenced the current implementation. -
  • -
  • - Gennadiy Rozental made extensive and important comments which shaped - the design. -
  • -
  • - Vesa Karvonen and Douglas Gregor made quite useful comparisons between - optional, variant and any; and made other relevant comments. -
  • -
  • - Douglas Gregor and Peter Dimov commented on comparisons and evaluation - in boolean contexts. -
  • -
  • - Eric Friedman helped understand the issues involved with aligned storage, - move/copy operations and exception safety. -
  • -
  • - Many others have participated with useful comments: Aleksey Gurotov, - Kevlin Henney, David Abrahams, and others I can't recall. -
  • -
-
- - Post-formal - review -
-
    -
  • - William Kempf carefully considered the originally proposed interface - and suggested the new interface which is currently used. He also started - and fueled the discussion about the analogy optional<>/smart pointer - and about relational operators. -
  • -
  • - Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson - focused on the relational semantics of optional (originally undefined); - concluding with the fact that the pointer-like interface doesn't make - it a pointer so it shall have deep relational operators. -
  • -
  • - Augustus Saunders also explored the different relational semantics between - optional<> and a pointer and developed the OptionalPointee concept - as an aid against potential conflicts on generic code. -
  • -
  • - Joel de Guzman noticed that optional<> can be seen as an API on - top of variant<T,nil_t>. -
  • -
  • - Dave Gomboc explained the meaning and usage of the Haskell analog to - optional<>: the Maybe type constructor (analogy originally pointed - out by David Sankel). -
  • -
  • - Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, - Rob Stewart, and others. -
  • -
  • - Joel de Guzman made the case for the support of references and helped - with the proper semantics. -
  • -
  • - Mat Marcus shown the virtues of a value-oriented interface, influencing - the current design, and contributed the idea of "none". -
  • -
  • - Vladimir Batov's design of Boost.Convert library motivated the development - of value accessors for optional: - functions value, value_or, value_or_eval. -
  • -
-
- - - -
-
-
-PrevUpHome -
- - diff --git a/doc/html/boost_optional/reference/dependencies_and_portability.html b/doc/html/boost_optional/reference/dependencies_and_portability.html deleted file mode 100644 index 5128861e..00000000 --- a/doc/html/boost_optional/reference/dependencies_and_portability.html +++ /dev/null @@ -1,84 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- -

- The implementation uses the following other Boost modules: -

-
    -
  1. - assert -
  2. -
  3. - config -
  4. -
  5. - core -
  6. -
  7. - detail -
  8. -
  9. - move -
  10. -
  11. - mpl -
  12. -
  13. - static_assert -
  14. -
  15. - throw_exception -
  16. -
  17. - type_traits -
  18. -
  19. - utility -
  20. -
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/dependencies_and_portability/optional_reference_binding.html b/doc/html/boost_optional/reference/dependencies_and_portability/optional_reference_binding.html deleted file mode 100644 index 16c16378..00000000 --- a/doc/html/boost_optional/reference/dependencies_and_portability/optional_reference_binding.html +++ /dev/null @@ -1,100 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- On compilers that do not conform to Standard C++ rules of reference binding, - operations on optional references might give adverse results: rather than - binding a reference to a designated object they may create an unexpected - temporary and bind to it. Compilers known to have these deficiencies include - GCC versions 4.2, 4.3, 4.4, 4.5; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, - 11.0, 12.0. On these compilers prefer using direct-initialization and copy - assignment of optional references to copy-initialization and assignment - from T&: -

-
const int i = 0;
-optional<const int&> or1;
-optional<const int&> or2 = i;  // not portable
-or1 = i;                       // not portable
-
-optional<const int&> or3(i);   // portable
-or1 = optional<const int&>(i); // portable
-
-

- In order to check if your compiler correctly implements reference binding - use this test program. -

-
#include <cassert>
-
-const int global_i = 0;
-
-struct TestingReferenceBinding
-{
-  TestingReferenceBinding(const int& ii)
-  {
-    assert(&ii == &global_i);
-  }
-
-  void operator=(const int& ii)
-  {
-    assert(&ii == &global_i);
-  }
-
-  void operator=(int&&) // remove this if your compiler doesn't have rvalue refs
-  {
-    assert(false);
-  }
-};
-
-int main()
-{
-  const int& iref = global_i;
-  assert(&iref == &global_i);
-
-  TestingReferenceBinding ttt = global_i;
-  ttt = global_i;
-
-  TestingReferenceBinding ttt2 = iref;
-  ttt2 = iref;
-}
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_.html b/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_.html deleted file mode 100644 index 363379c1..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_.html +++ /dev/null @@ -1,63 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- -

-

-
namespace boost {
-
-class bad_optional_access : public std::logic_error
-{
-public:
-    bad_optional_access(); R
-};
-
-} // namespace boost
-
-

-

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_/detailed_semantics.html b/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_/detailed_semantics.html deleted file mode 100644 index b1823243..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_/detailed_semantics.html +++ /dev/null @@ -1,60 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- space -

-

- bad_optional_access(); -

-
    -
  • - Effect: Constructs an object of class - bad_optional_access. -
  • -
  • - Postconditions: what() returns an implementation-defined - NTBS. -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_hpp_.html b/doc/html/boost_optional/reference/header__boost_optional_hpp_.html deleted file mode 100644 index c8d6b9e4..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_hpp_.html +++ /dev/null @@ -1,47 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- This is an alias for header <boost/optional/optional.hpp>. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_fwd_hpp_.html b/doc/html/boost_optional/reference/header__boost_optional_optional_fwd_hpp_.html deleted file mode 100644 index ee81dd92..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_fwd_hpp_.html +++ /dev/null @@ -1,66 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- -

-

-
namespace boost {
-
-template <class T> class optional ;
-
-template <class T> void swap ( optional<T>& , optional<T>& );
-
-template <class T> struct optional_swap_should_use_default_constructor ;
-
-} // namespace boost
-
-

-

-

- This header only contains declarations. -

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics.html deleted file mode 100644 index b7d25f5b..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics.html +++ /dev/null @@ -1,2423 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Because T might be of reference - type, in the sequel, those entries whose semantic depends on T being of reference type or not will - be distinguished using the following convention: -

-
    -
  • - If the entry reads: optional<T(not - a ref)>, - the description corresponds only to the case where T - is not of reference type. -
  • -
  • - If the entry reads: optional<T&>, the description corresponds - only to the case where T - is of reference type. -
  • -
  • - If the entry reads: optional<T>, the description is the same for - both cases. -
  • -
-
- - - - - -
[Note]Note

- The following section contains various assert() which are used only to show the postconditions - as sample code. It is not implied that the type T - must support each particular expression but that if the expression is - supported, the implied condition holds. -

-

- space -

-
- - optional - class member functions -
-

- space -

-

- optional<T>::optional() - noexcept; -

-
    -
  • - Effect: Default-Constructs an optional. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
  • - Notes: T's default constructor is not called. -
  • -
  • - Example: -
    optional<T> def ;
    -assert ( !def ) ;
    -
    -
  • -
-

- space -

-

- optional<T>::optional( - none_t ) - noexcept; -

-
    -
  • - Effect: Constructs an optional uninitialized. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
  • - Notes: T's - default constructor is not called. - The expression boost::none - denotes an instance of boost::none_t - that can be used as the parameter. -
  • -
  • - Example: -
    #include <boost/none.hpp>
    -optional<T> n(none) ;
    -assert ( !n ) ;
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)>::optional( T const& v ) -

-
    -
  • - Requires: is_copy_constructible<T>::value - is true. -
  • -
  • - Effect: Directly-Constructs an optional. -
  • -
  • - Postconditions: *this is initialized - and its value is a copy of v. -
  • -
  • - Throws: Whatever T::T( T const& - ) throws. -
  • -
  • - Notes: T::T( T const& - ) is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -assert ( *opt == v ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( - T& - ref ) -

-
    -
  • - Effect: Directly-Constructs an optional. -
  • -
  • - Postconditions: *this is initialized - and its value is an instance of an internal type wrapping the reference - ref. -
  • -
  • - Throws: Nothing. -
  • -
  • - Example: -
    T v;
    -T& vref = v ;
    -optional<T&> opt(vref);
    -assert ( *opt == v ) ;
    -++ v ; // mutate referee
    -assert (*opt == v);
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)>::optional( T&& v - ) -

-
    -
  • - Requires: is_move_constructible<T>::value - is true. -
  • -
  • - Effect: Directly-Move-Constructs an - optional. -
  • -
  • - Postconditions: *this is initialized - and its value is move-constructed from v. -
  • -
  • - Throws: Whatever T::T( T&& ) - throws. -
  • -
  • - Notes: T::T( T&& ) - is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T&& ); - in that case, the state of v - is determined by exception safety guarantees for T::T(T&&). -
  • -
  • - Example: -
    T v1, v2;
    -optional<T> opt(std::move(v1));
    -assert ( *opt == v2 ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( - T&& - ref ) - = delete -

-
  • - Notes: This constructor is deleted -
-

- space -

-

- optional<T (not a ref)>::optional( bool condition, - T const& v ) ; -

-

- optional<T&> - ::optional( bool condition, - T& - v ) - ; -

-
  • - If condition is true, same as: -
-

- optional<T (not a ref)>::optional( T const& v ) -

-

- optional<T&> - ::optional( T& v ) -

-
  • - otherwise, same as: -
-

- optional<T (not a ref)>::optional() -

-

- optional<T&> - ::optional() -

-

- space -

-

- optional<T (not a ref)>::optional( optional - const& - rhs ); -

-
    -
  • - Requires: is_copy_constructible<T>::value - is true. -
  • -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs is initialized, - *this - is initialized and its value is a copy of the - value of rhs; else - *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( T const& - ) throws. -
  • -
  • - Notes: If rhs is initialized, T::T(T const& ) - is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    optional<T> uninit ;
    -assert (!uninit);
    -
    -optional<T> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -optional<T> init( T(2) );
    -assert ( *init == T(2) ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( init2 == init ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( - optional const& rhs - ); -

-
    -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is another reference to the same object - referenced by *rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: If rhs - is initialized, both *this and *rhs will refer to the same object - (they alias). -
  • -
  • - Example: -
    optional<T&> uninit ;
    -assert (!uninit);
    -
    -optional<T&> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -T v = 2 ; T& ref = v ;
    -optional<T> init(ref);
    -assert ( *init == v ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( *init2 == v ) ;
    -
    -v = 3 ;
    -
    -assert ( *init  == 3 ) ;
    -assert ( *init2 == 3 ) ;
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)>::optional( optional&& rhs - ) noexcept(see below); -

-
    -
  • - Requires: is_move_constructible<T>::value - is true. -
  • -
  • - Effect: Move-constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is move constructed from rhs; else *this is uninitialized. -
  • -
  • - Throws: Whatever T::T( T&& ) - throws. -
  • -
  • - Remarks: The expression inside noexcept is equivalent to is_nothrow_move_constructible<T>::value. -
  • -
  • - Notes: If rhs - is initialized, T::T( T && - ) is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T&& ); - in that case, rhs remains - initialized and the value of *rhs is determined by exception safety - of T::T(T&&). -
  • -
  • - Example: -
    optional<std::unique_ptr<T>> uninit ;
    -assert (!uninit);
    -
    -optional<std::unique_ptr<T>> uinit2 ( std::move(uninit) ) ;
    -assert ( uninit2 == uninit );
    -
    -optional<std::unique_ptr<T>> init( std::uniqye_ptr<T>(new T(2)) );
    -assert ( **init == T(2) ) ;
    -
    -optional<std::unique_ptr<T>> init2 ( std::move(init) ) ;
    -assert ( init );
    -assert ( *init == nullptr );
    -assert ( init2 );
    -assert ( **init2 == T(2) ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( - optional && - rhs ); -

-
    -
  • - Effect: Move-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is another reference to the same object - referenced by *rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: If rhs - is initialized, both *this and *rhs will refer to the same object - (they alias). -
  • -
  • - Example: -
    optional<std::unique_ptr<T>&> uninit ;
    -assert (!uninit);
    -
    -optional<std::unique_ptr<T>&> uinit2 ( std::move(uninit) ) ;
    -assert ( uninit2 == uninit );
    -
    -std::unique_ptr<T> v(new T(2)) ;
    -optional<std::unique_ptr<T>&> init(v);
    -assert ( *init == v ) ;
    -
    -optional<std::unique_ptr<T>&> init2 ( std::move(init) ) ;
    -assert ( *init2 == v ) ;
    -
    -*v = 3 ;
    -
    -assert ( **init  == 3 ) ;
    -assert ( **init2 == 3 ) ;
    -
    -
  • -
-

- space -

-

- template<U> explicit optional<T - (not a ref)>::optional( - optional<U> const& rhs ); -

-
    -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is a copy of the - value of rhs converted to type T; - else *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( U const& - ) throws. -
  • -
  • - Notes: T::T( U const& - ) is called if rhs is initialized, which requires - a valid conversion from U - to T. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( U const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    optional<double> x(123.4);
    -assert ( *x == 123.4 ) ;
    -
    -optional<int> y(x) ;
    -assert( *y == 123 ) ;
    -
    -
  • -
-

- space -

-

- template<U> explicit optional<T - (not a ref)>::optional( - optional<U>&& - rhs ); -

-
    -
  • - Effect: Move-constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is move-constructed from *rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( U&& ) - throws. -
  • -
  • - Notes: T::T( U&& ) - is called if rhs is - initialized, which requires a valid conversion from U - to T. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( U&& ); - in that case, rhs remains - initialized and the value of *rhs is determined by exception safety - guarantee of T::T( U&& - ). -
  • -
  • - Example: -
    optional<double> x(123.4);
    -assert ( *x == 123.4 ) ;
    -
    -optional<int> y(std::move(x)) ;
    -assert( *y == 123 ) ;
    -
    -
  • -
-

- space -

-

- template<InPlaceFactory> - explicit optional<T - (not a ref)>::optional( - InPlaceFactory const& f ); -

-

- template<TypedInPlaceFactory> - explicit optional<T - (not a ref)>::optional( - TypedInPlaceFactory const& f ); -

-
    -
  • - Effect: Constructs an optional with a value of T obtained from the factory. -
  • -
  • - Postconditions: *this is initialized - and its value is directly given from the factory - f (i.e., the value - is not copied). -
  • -
  • - Throws: Whatever the T constructor called by the factory - throws. -
  • -
  • - Notes: See In-Place - Factories -
  • -
  • - Exception Safety: Exceptions can only - be thrown during the call to the T - constructor used by the factory; in that case, this constructor has - no effect. -
  • -
  • - Example: -
    class C { C ( char, double, std::string ) ; } ;
    -
    -C v('A',123.4,"hello");
    -
    -optional<C> x( in_place   ('A', 123.4, "hello") ); // InPlaceFactory used
    -optional<C> y( in_place<C>('A', 123.4, "hello") ); // TypedInPlaceFactory used
    -
    -assert ( *x == v ) ;
    -assert ( *y == v ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T>::operator= ( none_t - ) noexcept; -

-
    -
  • - Effect: If *this is initialized destroys its contained - value. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( T - const& - rhs ) - ; -

-
    -
  • - Effect: Assigns the value rhs to an optional. -
  • -
  • - Postconditions: *this is initialized and its value is - a copy of rhs. -
  • -
  • - Throws: Whatever T::operator=( T const& - ) or T::T(T const&) - throws. -
  • -
  • - Notes: If *this was initialized, T's assignment operator is used, - otherwise, its copy-constructor is used. -
  • -
  • - Exception Safety: In the event of - an exception, the initialization state of *this is unchanged and its value unspecified - as far as optional - is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - copy constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T x;
    -optional<T> def ;
    -optional<T> opt(x) ;
    -
    -T y;
    -def = y ;
    -assert ( *def == y ) ;
    -opt = y ;
    -assert ( *opt == y ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>& - optional<T&>::operator= ( T& rhs - ) ; -

-
    -
  • - Effect: (Re)binds the wrapped reference. -
  • -
  • - Postconditions: *this is initialized and it references - the same object referenced by rhs. -
  • -
  • - Notes: If *this was initialized, it is rebound - to the new object. See here - for details on this behavior. -
  • -
  • - Example: -
    int a = 1 ;
    -int b = 2 ;
    -T& ra = a ;
    -T& rb = b ;
    -optional<int&> def ;
    -optional<int&> opt(ra) ;
    -
    -def = rb ; // binds 'def' to 'b' through 'rb'
    -assert ( *def == b ) ;
    -*def = a ; // changes the value of 'b' to a copy of the value of 'a'
    -assert ( b == a ) ;
    -int c = 3;
    -int& rc = c ;
    -opt = rc ; // REBINDS to 'c' through 'rc'
    -c = 4 ;
    -assert ( *opt == 4 ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( T&& rhs - ) ; -

-
    -
  • - Effect: Moves the value rhs to an optional. -
  • -
  • - Postconditions: *this is initialized and its value is - moved from rhs. -
  • -
  • - Throws: Whatever T::operator=( T&& ) - or T::T(T &&) - throws. -
  • -
  • - Notes: If *this was initialized, T's move-assignment operator is used, - otherwise, its move-constructor is used. -
  • -
  • - Exception Safety: In the event of - an exception, the initialization state of *this is unchanged and its value unspecified - as far as optional - is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - move constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T x;
    -optional<T> def ;
    -optional<T> opt(x) ;
    -
    -T y1, y2, yR;
    -def = std::move(y1) ;
    -assert ( *def == yR ) ;
    -opt = std::move(y2) ;
    -assert ( *opt == yR ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>& - optional<T&>::operator= ( T&& rhs - ) = - delete; -

-
  • - Notes: This assignment operator is - deleted. -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( optional - const& - rhs ) - ; -

-
    -
  • - Requires: T - is CopyConstructible and CopyAssignable. -
  • -
  • -

    - Effects: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns *rhs - to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with *rhs -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this; -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Exception Safety: If any exception - is thrown, the initialization state of *this and rhs - remains unchanged. If an exception is thrown during the call to T's copy constructor, no effect. - If an exception is thrown during the call to T's - copy assignment, the state of its contained value is as defined by - the exception safety guarantee of T's - copy assignment. -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -optional<T> def ;
    -
    -opt = def ;
    -assert ( !def ) ;
    -// previous value (copy of 'v') destroyed from within 'opt'.
    -
    -
  • -
-

- space -

-

- optional<T&> - & optional<T&>::operator= ( optional<T&> const& rhs - ) ; -

-
    -
  • - Effect: (Re)binds thee wrapped reference. -
  • -
  • - Postconditions: If *rhs is initialized, *this - is initialized and it references the same object referenced by *rhs; - otherwise, *this - is uninitialized (and references no object). -
  • -
  • - Notes: If *this was initialized and so is *rhs, - *this - is rebound to the new object. See here - for details on this behavior. -
  • -
  • - Example: -
    int a = 1 ;
    -int b = 2 ;
    -T& ra = a ;
    -T& rb = b ;
    -optional<int&> def ;
    -optional<int&> ora(ra) ;
    -optional<int&> orb(rb) ;
    -
    -def = orb ; // binds 'def' to 'b' through 'rb' wrapped within 'orb'
    -assert ( *def == b ) ;
    -*def = ora ; // changes the value of 'b' to a copy of the value of 'a'
    -assert ( b == a ) ;
    -int c = 3;
    -int& rc = c ;
    -optional<int&> orc(rc) ;
    -ora = orc ; // REBINDS ora to 'c' through 'rc'
    -c = 4 ;
    -assert ( *ora == 4 ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( optional&& rhs - ) noexcept(see below); -

-
    -
  • - Requires: T - is MoveConstructible - and MoveAssignable. -
  • -
  • -

    - Effects: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns std::move(*rhs) to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with std::move(*rhs) -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this; -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Remarks: The expression inside noexcept is equivalent to is_nothrow_move_constructible<T>::value && - is_nothrow_move_assignable<T>::value. -
  • -
  • - Exception Safety: If any exception - is thrown, the initialization state of *this and rhs - remains unchanged. If an exception is thrown during the call to T's move constructor, the state of - *rhs - is determined by the exception safety guarantee of T's - move constructor. If an exception is thrown during the call to T's - move-assignment, the state of **this and *rhs is determined by the exception - safety guarantee of T's move assignment. -
  • -
  • - Example: -
    optional<T> opt(T(2)) ;
    -optional<T> def ;
    -
    -opt = def ;
    -assert ( def ) ;
    -assert ( opt ) ;
    -assert ( *opt == T(2) ) ;
    -
    -
  • -
-

- space -

-

- optional<T&> - & optional<T&>::operator= ( optional<T&>&& rhs - ) ; -

-
  • - Effect: Same as optional<T&>::operator= ( optional<T&> - const& - rhs ). -
-

- space -

-

- template<U> optional& - optional<T (not a ref)>::operator= ( optional<U> const& rhs - ) ; -

-
    -
  • -

    - Effect: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns *rhs - to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with *rhs -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this. -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Exception Safety: If any exception - is thrown, the result of the expression bool(*this) remains unchanged. If an exception - is thrown during the call to T's - constructor, no effect. If an exception is thrown during the call to - T's assignment, the - state of its contained value is as defined by the exception safety - guarantee of T's copy - assignment. -
  • -
  • - Example: -
    T v;
    -optional<T> opt0(v);
    -optional<U> opt1;
    -
    -opt1 = opt0 ;
    -assert ( *opt1 == static_cast<U>(v) ) ;
    -
    -
  • -
-

- space -

-

- template<U> optional& - optional<T (not a ref)>::operator= ( optional<U>&& rhs - ) ; -

-
    -
  • -

    - Effect: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns std::move(*rhs) to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with std::move(*rhs) -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this. -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Exception Safety: If any exception - is thrown, the result of the expression bool(*this) remains unchanged. If an exception - is thrown during the call to T's - constructor, no effect. If an exception is thrown during the call to - T's assignment, the - state of its contained value is as defined by the exception safety - guarantee of T's copy - assignment. -
  • -
  • - Example: -
    T v;
    -optional<T> opt0(v);
    -optional<U> opt1;
    -
    -opt1 = std::move(opt0) ;
    -assert ( opt0 );
    -assert ( opt1 )
    -assert ( *opt1 == static_cast<U>(v) ) ;
    -
    -
  • -
-

- space -

-

- template<class... Args> - void optional<T - (not a ref)>::emplace( - Args...&& - args ); -

-
    -
  • - Requires: The compiler supports rvalue - references and variadic templates. -
  • -
  • - Effect: If *this is initialized calls *this = none. - Then initializes in-place the contained value as if direct-initializing - an object of type T - with std::forward<Args>(args).... -
  • -
  • - Postconditions: *this is initialized. -
  • -
  • - Throws: Whatever the selected T's constructor throws. -
  • -
  • - Exception Safety: If an exception - is thrown during the initialization of T, - *this - is uninitialized. -
  • -
  • - Notes: T - need not be MoveConstructible - or MoveAssignable. - On compilers that do not support variadic templates, the signature - falls back to two overloads:template<class - Arg> - void emplace(Arg&& arg) and void - emplace(). - On compilers that do not support rvalue references, the signature falls - back to three overloads: taking const - and non-const lvalue reference, - and third with empty function argument list. -
  • -
  • - Example: -
    T v;
    -optional<const T> opt;
    -opt.emplace(0);  // create in-place using ctor T(int)
    -opt.emplace();   // destroy previous and default-construct another T
    -opt.emplace(v);  // destroy and copy-construct in-place (no assignment called)
    -
    -
  • -
-

- space -

-

- template<InPlaceFactory> - optional<T>& - optional<T (not a ref)>::operator=( InPlaceFactory - const& - f ); -

-

- template<TypedInPlaceFactory> - optional<T>& - optional<T (not a ref)>::operator=( TypedInPlaceFactory - const& - f ); -

-
    -
  • - Effect: Assigns an optional - with a value of T obtained - from the factory. -
  • -
  • - Postconditions: *this is initialized - and its value is directly given from the factory - f (i.e., the value - is not copied). -
  • -
  • - Throws: Whatever the T constructor called by the factory - throws. -
  • -
  • - Notes: See In-Place - Factories -
  • -
  • - Exception Safety: Exceptions can only - be thrown during the call to the T - constructor used by the factory; in that case, the optional - object will be reset to be uninitialized. -
  • -
-

- space -

-

- void optional<T - (not a ref)>::reset( T const& v ) ; -

-
  • - Deprecated: same as operator= - ( T - const& - v) - ; -
-

- space -

-

- void optional<T>::reset() noexcept - ; -

-
  • - Deprecated: Same as operator=( - none_t ); -
-

- space -

-

- T const& optional<T - (not a ref)>::get() const ; -

-

- T& - optional<T (not a ref)>::get() ; -

-

- inline T - const& - get ( - optional<T (not a ref)> const& ) ; -

-

- inline T& get - ( optional<T - (not a ref)> - &) ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: A reference to the contained - value -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). -
  • -
-

- space -

-

- T const& optional<T&>::get() const ; -

-

- T& - optional<T&>::get() ; -

-

- inline T - const& - get ( - optional<T&> - const& - ) ; -

-

- inline T& get - ( optional<T&> &) - ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: The - reference contained. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). -
  • -
-

- space -

-

- T const& optional<T - (not a ref)>::operator*() - const& - ; -

-

- T& - optional<T (not a ref)>::operator*() &; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: A reference to the contained - value -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions - these two overloads are replaced with the classical two: a const and non-const - member functions. -
  • -
  • - Example: -
    T v ;
    -optional<T> opt ( v );
    -T const& u = *opt;
    -assert ( u == v ) ;
    -T w ;
    -*opt = w ;
    -assert ( *opt == w ) ;
    -
    -
  • -
-

- space -

-

- T&& - optional<T (not a ref)>::operator*() &&; -

-
    -
  • - Requires: *this contains a value. -
  • -
  • - Effects: Equivalent to return std::move(*val);. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions - this overload is not present. -
  • -
-

- space -

-

- T & - optional<T&>::operator*() - const& - ; -

-

- T & - optional<T&>::operator*() - & ; -

-

- T & - optional<T&>::operator*() - && ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: The - reference contained. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions - these three overloads are replaced with the classical two: a const and non-const - member functions. -
  • -
  • - Example: -
    T v ;
    -T& vref = v ;
    -optional<T&> opt ( vref );
    -T const& vref2 = *opt;
    -assert ( vref2 == v ) ;
    -++ v ;
    -assert ( *opt == v ) ;
    -
    -
  • -
-

- space -

-

- T const& optional<T>::value() const& ; -

-

- T& - optional<T>::value() & ; -

-
    -
  • - Effects: Equivalent to return bool(*this) ? *val : throw bad_optional_access();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions these two overloads are replaced - with the classical two: a const - and non-const member functions. -
  • -
  • - Example: -
    T v ;
    -optional<T> o0, o1 ( v );
    -assert ( o1.value() == v );
    -
    -try {
    -  o0.value(); // throws
    -  assert ( false );
    -}
    -catch(bad_optional_access&) {
    -  assert ( true );
    -}
    -
    -
  • -
-

- space -

-

- T&& - optional<T>::value() && ; -

-
    -
  • - Effects: Equivalent to return bool(*this) ? std::move(*val) : throw bad_optional_access();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is not present. -
  • -
-

- space -

-

- template<class U> T optional<T>::value_or(U && - v) - const& - ; -

-
    -
  • - Effects: Equivalent to if (*this) return **this; else return - std::forward<U>(v);. -
  • -
  • - Remarks: If T - is not CopyConstructible or U && - is not convertible to T, - the program is ill-formed. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is replaced with the - const-qualified member - function. On compilers without rvalue reference support the type of - v becomes U const&. -
  • -
-

- space -

-

- template<class U> T optional<T>::value_or(U && - v) - && ; -

-
    -
  • - Effects: Equivalent to if (*this) return std::move(**this); else return std::forward<U>(v);. -
  • -
  • - Remarks: If T - is not MoveConstructible - or U && - is not convertible to T, - the program is ill-formed. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is not present. -
  • -
-

- space -

-

- template<class F> T optional<T>::value_or_eval(F f) const& ; -

-
    -
  • - Requires: T - is CopyConstructible and F models a Generator whose result type - is convertible to T. -
  • -
  • - Effects: if - (*this) return **this; else return f();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is replaced with the - const-qualified member - function. -
  • -
  • - Example: -
    int complain_and_0()
    -{
    -  clog << "no value returned, using default" << endl;
    -  return 0;
    -}
    -
    -optional<int> o1 = 1;
    -optional<int> oN = none;
    -
    -int i = o1.value_or_eval(complain_and_0); // fun not called
    -assert (i == 1);
    -
    -int j = oN.value_or_eval(complain_and_0); // fun called
    -assert (i == 0);
    -
    -
  • -
-

- space -

-

- template<class F> T optional<T>::value_or_eval(F f) && - ; -

-
    -
  • - Requires: T - is MoveConstructible - and F models a Generator - whose result type is convertible to T. -
  • -
  • - Effects: if - (*this) return std::move(**this); else return - f();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is not present. -
  • -
-

- space -

-

- T const& optional<T - (not a ref)>::get_value_or( - T const& default) const ; -

-

- T& - optional<T (not a ref)>::get_value_or( T& default - ) ; -

-

- inline T - const& - get_optional_value_or ( - optional<T (not a ref)> const& o, T const& default ) ; -

-

- inline T& get_optional_value_or - ( optional<T - (not a ref)>& - o, - T& - default ) - ; -

-
    -
  • - Deprecated: Use value_or() instead. -
  • -
  • - Returns: A reference to the contained - value, if any, or default. -
  • -
  • - Throws: Nothing. -
  • -
  • - Example: -
    T v, z ;
    -optional<T> def;
    -T const& y = def.get_value_or(z);
    -assert ( y == z ) ;
    -
    -optional<T> opt ( v );
    -T const& u = get_optional_value_or(opt,z);
    -assert ( u == v ) ;
    -assert ( u != z ) ;
    -
    -
  • -
-

- space -

-

- T const* optional<T - (not a ref)>::get_ptr() - const ; -

-

- T* - optional<T (not a ref)>::get_ptr() ; -

-

- inline T - const* - get_pointer ( - optional<T (not a ref)> const& ) ; -

-

- inline T* get_pointer - ( optional<T - (not a ref)> - &) ; -

-
    -
  • - Returns: If *this is initialized, a pointer to the - contained value; else 0 - (null). -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The contained value is permanently - stored within *this, - so you should not hold nor delete this pointer -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -optional<T> const copt(v);
    -T* p = opt.get_ptr() ;
    -T const* cp = copt.get_ptr();
    -assert ( p == get_pointer(opt) );
    -assert ( cp == get_pointer(copt) ) ;
    -
    -
  • -
-

- space -

-

- T const* optional<T - (not a ref)>::operator ->() - const ; -

-

- T* - optional<T (not a ref)>::operator - ->() ; -

-
    -
  • - Requires: *this is initialized. -
  • -
  • - Returns: A pointer to the contained - value. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). -
  • -
  • - Example: -
    struct X { int mdata ; } ;
    -X x ;
    -optional<X> opt (x);
    -opt->mdata = 2 ;
    -
    -
  • -
-

- space -

-

- explicit optional<T>::operator - bool() - const noexcept - ; -

-
    -
  • - Returns: get_ptr() != 0. -
  • -
  • - Notes: On compilers that do not support - explicit conversion operators this falls back to safe-bool idiom. -
  • -
  • - Example: -
    optional<T> def ;
    -assert ( def == 0 );
    -optional<T> opt ( v ) ;
    -assert ( opt );
    -assert ( opt != 0 );
    -
    -
  • -
-

- space -

-

- bool optional<T>::operator!() noexcept - ; -

-
    -
  • - Returns: If *this is uninitialized, true; else false. -
  • -
  • - Notes: This operator is provided for - those compilers which can't use the unspecified-bool-type - operator in certain boolean contexts. -
  • -
  • - Example: -
    optional<T> opt ;
    -assert ( !opt );
    -*opt = some_T ;
    -
    -// Notice the "double-bang" idiom here.
    -assert ( !!opt ) ;
    -
    -
  • -
-

- space -

-

- bool optional<T>::is_initialized() const ; -

-
  • - Deprecated: Same as explicit operator - bool () - ; -
-

- space -

-
- - Free - functions -
-

- space -

-

- optional<T (not a ref)> make_optional( T const& v ) -

-
    -
  • - Returns: optional<T>(v) for the deduced - type T of v. -
  • -
  • - Example: -
    template<class T> void foo ( optional<T> const& opt ) ;
    -
    -foo ( make_optional(1+1) ) ; // Creates an optional<int>
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)> make_optional( bool condition, - T const& v ) -

-
    -
  • - Returns: optional<T>(condition,v) for the deduced - type T of v. -
  • -
  • - Example: -
    optional<double> calculate_foo()
    -{
    -  double val = compute_foo();
    -  return make_optional(is_not_nan_and_finite(val),val);
    -}
    -
    -optional<double> v = calculate_foo();
    -if ( !v )
    -  error("foo wasn't computed");
    -
    -
  • -
-

- space -

-

- bool operator - == ( - optional<T> const& x, optional<T> const& y ); -

-
    -
  • - Requires: T - shall meet requirements of EqualityComparable. -
  • -
  • - Returns: If both x - and y are initialized, - (*x - == *y). - If only x or y is initialized, false. - If both are uninitialized, true. -
  • -
  • - Notes: This definition guarantees - that optional<T> - not containing a value is compared unequal to any optional<T> containing any value, and equal - to any other optional<T> not containing a value. Pointers - have shallow relational operators while optional - has deep relational operators. Do not use operator== directly in generic code which expect - to be given either an optional<T> or a pointer; use equal_pointees() - instead -
  • -
  • - Example: -
    optional<T> oN, oN_;
    -optional<T> o1(T(1)), o1_(T(1));
    -optional<T> o2(T(2));
    -
    -assert ( oN == oN );  // Identity implies equality
    -assert ( o1 == o1 );  //
    -
    -assert ( oN == oN_ ); // Both uninitialized compare equal
    -
    -assert ( oN != o1 );  // Initialized unequal to initialized.
    -
    -assert ( o1 == o1_ ); // Both initialized compare as (*lhs == *rhs)
    -assert ( o1 != o2 );  //
    -
    -
  • -
-

- space -

-

- bool operator - < ( - optional<T> const& x, optional<T> const& y ); -

-
    -
  • - Requires: Expression *x < *y shall be well-formed and its result - shall be convertible to bool. -
  • -
  • - Returns: (!y) ? false : (!x) ? true : *x < - *y. -
  • -
  • - Notes: This definition guarantees - that optional<T> - not containing a value is ordered as less than any optional<T> containing any value, and equivalent - to any other optional<T> not containing a value. Pointers - have shallow relational operators while optional - has deep relational operators. Do not use operator< directly in generic code which - expect to be given either an optional<T> or a pointer; use less_pointees() - instead. T need not - be LessThanComparable. Only - single operator< - is required. Other relational operations are defined in terms of this - one. If T's operator< - satisfies the axioms of LessThanComparable (transitivity, - antisymmetry and irreflexivity), optinal<T> is LessThanComparable. -
  • -
  • - Example: -
    optional<T> oN, oN_;
    -optional<T> o0(T(0));
    -optional<T> o1(T(1));
    -
    -assert ( !(oN < oN) );  // Identity implies equivalence
    -assert ( !(o1 < o1) );
    -
    -assert ( !(oN < oN_) ); // Two uninitialized are equivalent
    -assert ( !(oN_ < oN) );
    -
    -assert ( oN < o0 );     // Uninitialized is less than initialized
    -assert ( !(o0 < oN) );
    -
    -assert ( o1 < o2 ) ;    // Two initialized compare as (*lhs < *rhs)
    -assert ( !(o2 < o1) ) ;
    -assert ( !(o2 < o2) ) ;
    -
    -
  • -
-

- space -

-

- bool operator - != ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: !( - x == - y ); -
-

- space -

-

- bool operator - > ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: ( - y < - x ); -
-

- space -

-

- bool operator - <= ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: !( - y < - x ); -
-

- space -

-

- bool operator - >= ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: !( - x < - y ); -
-

- space -

-

- bool operator - == ( - optional<T> const& x, none_t ) - noexcept; -

-

- bool operator - == ( - none_t, - optional<T> const& x ) noexcept; -

-
-

- space -

-

- bool operator - != ( - optional<T> const& x, none_t ) - noexcept; -

-

- bool operator - != ( - none_t, - optional<T> const& x ) noexcept; -

-
  • - Returns: !( - x == - y ); -
-

- space -

-

- void swap - ( optional<T>& x, optional<T>& y - ) ; -

-
    -
  • - Requires: Lvalues of type T shall be swappable and T shall be MoveConstructible. -
  • -
  • -

    - Effects: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - calls swap(*(*this), *rhs) -

    -
    -

    - initializes the contained value of *this as if direct-initializing - an object of type T - with the expression std::move(*rhs), followed by rhs.val->T::~T(), - *this - contains a value and rhs - does not contain a value -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - initializes the contained value of rhs - as if direct-initializing an object of type T with the expression - std::move(*(*this)), - followed by val->T::~T(), *this does not contain a value - and rhs contains - a value -

    -
    -

    - no effect -

    -
    -
  • -
  • - Postconditions: The states of x and y - interchanged. -
  • -
  • - Throws: If both are initialized, whatever - swap(T&,T&) - throws. If only one is initialized, whatever T::T ( T&& ) - throws. -
  • -
  • - Example: -
    T x(12);
    -T y(21);
    -optional<T> def0 ;
    -optional<T> def1 ;
    -optional<T> optX(x);
    -optional<T> optY(y);
    -
    -boost::swap(def0,def1); // no-op
    -
    -boost::swap(def0,optX);
    -assert ( *def0 == x );
    -assert ( !optX );
    -
    -boost::swap(def0,optX); // Get back to original values
    -
    -boost::swap(optX,optY);
    -assert ( *optX == y );
    -assert ( *optY == x );
    -
    -
  • -
-

- space -

-

- void swap - ( optional<T&>& x, optional<T&>& y - ) noexcept - ; -

-
    -
  • - Postconditions: x - refers to what y refererred - to before the swap (if anything). y - refers to whatever x - referred to before the swap. -
  • -
  • - Example: -
    T x(12);
    -T y(21);
    -
    -optional<T&> opt0;
    -optional<T&> optX (x);
    -optional<T&> optY (y);
    -
    -boost::swap(optX, optY);
    -assert (addressof(*optX) == addressof(y));
    -assert (addressof(*optY) == addressof(x));
    -
    -boost::swap(opt0, optX);
    -assert ( opt0 );
    -assert ( !optX );
    -assert (addressof(*opt0) == addressof(y));
    -
    - [endsect] -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics____free_functions.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics____free_functions.html deleted file mode 100644 index 462f1093..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics____free_functions.html +++ /dev/null @@ -1,447 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- space -

-

- optional<T> make_optional( - T const& v ) -

-
    -
  • - Returns: optional<T>(v) for the deduced - type T of v. -
  • -
  • - Example: -
    template<class T> void foo ( optional<T> const& opt ) ;
    -
    -foo ( make_optional(1+1) ) ; // Creates an optional<int>
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)> make_optional( bool condition, - T const& v ) -

-
    -
  • - Returns: optional<T>(condition,v) for the deduced - type T of v. -
  • -
  • - Example: -
    optional<double> calculate_foo()
    -{
    -  double val = compute_foo();
    -  return make_optional(is_not_nan_and_finite(val),val);
    -}
    -
    -optional<double> v = calculate_foo();
    -if ( !v )
    -  error("foo wasn't computed");
    -
    -
  • -
-

- space -

-

- bool operator - == ( - optional<T> const& x, optional<T> const& y ); -

-
    -
  • - Requires: T - shall meet requirements of EqualityComparable. -
  • -
  • - Returns: If both x - and y are initialized, - (*x - == *y). - If only x or y is initialized, false. - If both are uninitialized, true. -
  • -
  • - Notes: This definition guarantees - that optional<T> - not containing a value is compared unequal to any optional<T> containing any value, and equal - to any other optional<T> not containing a value. Pointers - have shallow relational operators while optional - has deep relational operators. Do not use operator== directly in generic code which expect - to be given either an optional<T> or a pointer; use equal_pointees() - instead -
  • -
  • - Example: -
    optional<T> oN, oN_;
    -optional<T> o1(T(1)), o1_(T(1));
    -optional<T> o2(T(2));
    -
    -assert ( oN == oN );  // Identity implies equality
    -assert ( o1 == o1 );  //
    -
    -assert ( oN == oN_ ); // Both uninitialized compare equal
    -
    -assert ( oN != o1 );  // Initialized unequal to initialized.
    -
    -assert ( o1 == o1_ ); // Both initialized compare as (*lhs == *rhs)
    -assert ( o1 != o2 );  //
    -
    -
  • -
-

- space -

-

- bool operator - < ( - optional<T> const& x, optional<T> const& y ); -

-
    -
  • - Requires: Expression *x < *y shall be well-formed and its result - shall be convertible to bool. -
  • -
  • - Returns: (!y) ? false : (!x) ? true : *x < - *y. -
  • -
  • - Notes: This definition guarantees - that optional<T> - not containing a value is ordered as less than any optional<T> containing any value, and equivalent - to any other optional<T> not containing a value. Pointers - have shallow relational operators while optional - has deep relational operators. Do not use operator< directly in generic code which - expect to be given either an optional<T> or a pointer; use less_pointees() - instead. T need not - be LessThanComparable. Only - single operator< - is required. Other relational operations are defined in terms of this - one. If T's operator< - satisfies the axioms of LessThanComparable (transitivity, - antisymmetry and irreflexivity), optinal<T> is LessThanComparable. -
  • -
  • - Example: -
    optional<T> oN, oN_;
    -optional<T> o0(T(0));
    -optional<T> o1(T(1));
    -
    -assert ( !(oN < oN) );  // Identity implies equivalence
    -assert ( !(o1 < o1) );
    -
    -assert ( !(oN < oN_) ); // Two uninitialized are equivalent
    -assert ( !(oN_ < oN) );
    -
    -assert ( oN < o0 );     // Uninitialized is less than initialized
    -assert ( !(o0 < oN) );
    -
    -assert ( o1 < o2 ) ;    // Two initialized compare as (*lhs < *rhs)
    -assert ( !(o2 < o1) ) ;
    -assert ( !(o2 < o2) ) ;
    -
    -
  • -
-

- space -

-

- bool operator - != ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: !( - x == - y ); -
-

- space -

-

- bool operator - > ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: ( - y < - x ); -
-

- space -

-

- bool operator - <= ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: !( - y < - x ); -
-

- space -

-

- bool operator - >= ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: !( - x < - y ); -
-

- space -

-

- bool operator - == ( - optional<T> const& x, none_t ) - noexcept; -

-

- bool operator - == ( - none_t, - optional<T> const& x ) noexcept; -

-
-

- space -

-

- bool operator - != ( - optional<T> const& x, none_t ) - noexcept; -

-

- bool operator - != ( - none_t, - optional<T> const& x ) noexcept; -

-
  • - Returns: !( - x == - y ); -
-

- space -

-

- void swap - ( optional<T>& x, optional<T>& y - ) ; -

-
    -
  • - Requires: Lvalues of type T shall be swappable and T shall be MoveConstructible. -
  • -
  • -

    - Effects: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - calls swap(*(*this), *rhs) -

    -
    -

    - initializes the contained value of *this as if direct-initializing - an object of type T - with the expression std::move(*rhs), followed by rhs.val->T::~T(), - *this - contains a value and rhs - does not contain a value -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - initializes the contained value of rhs - as if direct-initializing an object of type T with the expression - std::move(*(*this)), - followed by val->T::~T(), *this does not contain a value - and rhs contains - a value -

    -
    -

    - no effect -

    -
    -
  • -
  • - Postconditions: The states of x and y - interchanged. -
  • -
  • - Throws: If both are initialized, whatever - swap(T&,T&) - throws. If only one is initialized, whatever T::T ( T&& ) - throws. -
  • -
  • - Example: -
    T x(12);
    -T y(21);
    -optional<T> def0 ;
    -optional<T> def1 ;
    -optional<T> optX(x);
    -optional<T> optY(y);
    -
    -boost::swap(def0,def1); // no-op
    -
    -boost::swap(def0,optX);
    -assert ( *def0 == x );
    -assert ( !optX );
    -
    -boost::swap(def0,optX); // Get back to original values
    -
    -boost::swap(optX,optY);
    -assert ( *optX == y );
    -assert ( *optY == x );
    -
    -
  • -
-

- space -

-

- void swap - ( optional<T&>& x, optional<T&>& y - ) noexcept - ; -

-
    -
  • - Postconditions: x - refers to what y refererred - to before the swap (if anything). y - refers to whatever x - referred to before the swap. -
  • -
  • - Example: -
    T x(12);
    -T y(21);
    -
    -optional<T&> opt0;
    -optional<T&> optX (x);
    -optional<T&> optY (y);
    -
    -boost::swap(optX, optY);
    -assert (addressof(*optX) == addressof(y));
    -assert (addressof(*optY) == addressof(x));
    -
    -boost::swap(opt0, optX);
    -assert ( opt0 );
    -assert ( !optX );
    -assert (addressof(*opt0) == addressof(y));
    -
    - [endsect] -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics____optional_references.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics____optional_references.html deleted file mode 100644 index 7eedfaba..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics____optional_references.html +++ /dev/null @@ -1,57 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- space -

-

- optional<&>::optional() - noexcept; -

-

- optional<&>::optional(none_t) noexcept; -

-
  • - Postconditions: *this refers to nothing. -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics____optional_values.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics____optional_values.html deleted file mode 100644 index 5fd63913..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics____optional_values.html +++ /dev/null @@ -1,1983 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - - - - -
[Note]Note

- The following section contains various assert() which are used only to show the postconditions - as sample code. It is not implied that the type T - must support each particular expression but that if the expression is - supported, the implied condition holds. -

-

- space -

-

- optional<T>::optional() - noexcept; -

-
    -
  • - Effect: Default-Constructs an optional. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
  • - Notes: T's default constructor is not called. -
  • -
  • - Example: -
    optional<T> def ;
    -assert ( !def ) ;
    -
    -
  • -
-

- space -

-

- optional<T>::optional( - none_t ) - noexcept; -

-
    -
  • - Effect: Constructs an optional uninitialized. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
  • - Notes: T's - default constructor is not called. - The expression boost::none - denotes an instance of boost::none_t - that can be used as the parameter. -
  • -
  • - Example: -
    #include <boost/none.hpp>
    -optional<T> n(none) ;
    -assert ( !n ) ;
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)>::optional( T const& v ) -

-
    -
  • - Requires: is_copy_constructible<T>::value - is true. -
  • -
  • - Effect: Directly-Constructs an optional. -
  • -
  • - Postconditions: *this is initialized - and its value is a copy of v. -
  • -
  • - Throws: Whatever T::T( T const& - ) throws. -
  • -
  • - Notes: T::T( T const& - ) is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -assert ( *opt == v ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( - T& - ref ) -

-
    -
  • - Effect: Directly-Constructs an optional. -
  • -
  • - Postconditions: *this is initialized - and its value is an instance of an internal type wrapping the reference - ref. -
  • -
  • - Throws: Nothing. -
  • -
  • - Example: -
    T v;
    -T& vref = v ;
    -optional<T&> opt(vref);
    -assert ( *opt == v ) ;
    -++ v ; // mutate referee
    -assert (*opt == v);
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)>::optional( T&& v - ) -

-
    -
  • - Requires: is_move_constructible<T>::value - is true. -
  • -
  • - Effect: Directly-Move-Constructs an - optional. -
  • -
  • - Postconditions: *this is initialized - and its value is move-constructed from v. -
  • -
  • - Throws: Whatever T::T( T&& ) - throws. -
  • -
  • - Notes: T::T( T&& ) - is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T&& ); - in that case, the state of v - is determined by exception safety guarantees for T::T(T&&). -
  • -
  • - Example: -
    T v1, v2;
    -optional<T> opt(std::move(v1));
    -assert ( *opt == v2 ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( - T&& - ref ) - = delete -

-
  • - Notes: This constructor is deleted -
-

- space -

-

- optional<T (not a ref)>::optional( bool condition, - T const& v ) ; -

-

- optional<T&> - ::optional( bool condition, - T& - v ) - ; -

-
  • - If condition is true, same as: -
-

- optional<T (not a ref)>::optional( T const& v ) -

-

- optional<T&> - ::optional( T& v ) -

-
  • - otherwise, same as: -
-

- optional<T (not a ref)>::optional() -

-

- optional<T&> - ::optional() -

-

- space -

-

- optional<T (not a ref)>::optional( optional - const& - rhs ); -

-
    -
  • - Requires: is_copy_constructible<T>::value - is true. -
  • -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs is initialized, - *this - is initialized and its value is a copy of the - value of rhs; else - *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( T const& - ) throws. -
  • -
  • - Notes: If rhs is initialized, T::T(T const& ) - is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    optional<T> uninit ;
    -assert (!uninit);
    -
    -optional<T> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -optional<T> init( T(2) );
    -assert ( *init == T(2) ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( init2 == init ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( - optional const& rhs - ); -

-
    -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is another reference to the same object - referenced by *rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: If rhs - is initialized, both *this and *rhs will refer to the same object - (they alias). -
  • -
  • - Example: -
    optional<T&> uninit ;
    -assert (!uninit);
    -
    -optional<T&> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -T v = 2 ; T& ref = v ;
    -optional<T> init(ref);
    -assert ( *init == v ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( *init2 == v ) ;
    -
    -v = 3 ;
    -
    -assert ( *init  == 3 ) ;
    -assert ( *init2 == 3 ) ;
    -
    -
  • -
-

- space -

-

- optional<T (not a ref)>::optional( optional&& rhs - ) noexcept(see below); -

-
    -
  • - Requires: is_move_constructible<T>::value - is true. -
  • -
  • - Effect: Move-constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is move constructed from rhs; else *this is uninitialized. -
  • -
  • - Throws: Whatever T::T( T&& ) - throws. -
  • -
  • - Remarks: The expression inside noexcept is equivalent to is_nothrow_move_constructible<T>::value. -
  • -
  • - Notes: If rhs - is initialized, T::T( T && - ) is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T&& ); - in that case, rhs remains - initialized and the value of *rhs is determined by exception safety - of T::T(T&&). -
  • -
  • - Example: -
    optional<std::unique_ptr<T>> uninit ;
    -assert (!uninit);
    -
    -optional<std::unique_ptr<T>> uinit2 ( std::move(uninit) ) ;
    -assert ( uninit2 == uninit );
    -
    -optional<std::unique_ptr<T>> init( std::uniqye_ptr<T>(new T(2)) );
    -assert ( **init == T(2) ) ;
    -
    -optional<std::unique_ptr<T>> init2 ( std::move(init) ) ;
    -assert ( init );
    -assert ( *init == nullptr );
    -assert ( init2 );
    -assert ( **init2 == T(2) ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>::optional( - optional && - rhs ); -

-
    -
  • - Effect: Move-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is another reference to the same object - referenced by *rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: If rhs - is initialized, both *this and *rhs will refer to the same object - (they alias). -
  • -
  • - Example: -
    optional<std::unique_ptr<T>&> uninit ;
    -assert (!uninit);
    -
    -optional<std::unique_ptr<T>&> uinit2 ( std::move(uninit) ) ;
    -assert ( uninit2 == uninit );
    -
    -std::unique_ptr<T> v(new T(2)) ;
    -optional<std::unique_ptr<T>&> init(v);
    -assert ( *init == v ) ;
    -
    -optional<std::unique_ptr<T>&> init2 ( std::move(init) ) ;
    -assert ( *init2 == v ) ;
    -
    -*v = 3 ;
    -
    -assert ( **init  == 3 ) ;
    -assert ( **init2 == 3 ) ;
    -
    -
  • -
-

- space -

-

- template<U> explicit optional<T - (not a ref)>::optional( - optional<U> const& rhs ); -

-
    -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is a copy of the - value of rhs converted to type T; - else *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( U const& - ) throws. -
  • -
  • - Notes: T::T( U const& - ) is called if rhs is initialized, which requires - a valid conversion from U - to T. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( U const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    optional<double> x(123.4);
    -assert ( *x == 123.4 ) ;
    -
    -optional<int> y(x) ;
    -assert( *y == 123 ) ;
    -
    -
  • -
-

- space -

-

- template<U> explicit optional<T - (not a ref)>::optional( - optional<U>&& - rhs ); -

-
    -
  • - Effect: Move-constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is move-constructed from *rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( U&& ) - throws. -
  • -
  • - Notes: T::T( U&& ) - is called if rhs is - initialized, which requires a valid conversion from U - to T. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( U&& ); - in that case, rhs remains - initialized and the value of *rhs is determined by exception safety - guarantee of T::T( U&& - ). -
  • -
  • - Example: -
    optional<double> x(123.4);
    -assert ( *x == 123.4 ) ;
    -
    -optional<int> y(std::move(x)) ;
    -assert( *y == 123 ) ;
    -
    -
  • -
-

- space -

-

- template<InPlaceFactory> - explicit optional<T - (not a ref)>::optional( - InPlaceFactory const& f ); -

-

- template<TypedInPlaceFactory> - explicit optional<T - (not a ref)>::optional( - TypedInPlaceFactory const& f ); -

-
    -
  • - Effect: Constructs an optional with a value of T obtained from the factory. -
  • -
  • - Postconditions: *this is initialized - and its value is directly given from the factory - f (i.e., the value - is not copied). -
  • -
  • - Throws: Whatever the T constructor called by the factory - throws. -
  • -
  • - Notes: See In-Place - Factories -
  • -
  • - Exception Safety: Exceptions can only - be thrown during the call to the T - constructor used by the factory; in that case, this constructor has - no effect. -
  • -
  • - Example: -
    class C { C ( char, double, std::string ) ; } ;
    -
    -C v('A',123.4,"hello");
    -
    -optional<C> x( in_place   ('A', 123.4, "hello") ); // InPlaceFactory used
    -optional<C> y( in_place<C>('A', 123.4, "hello") ); // TypedInPlaceFactory used
    -
    -assert ( *x == v ) ;
    -assert ( *y == v ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T>::operator= ( none_t - ) noexcept; -

-
    -
  • - Effect: If *this is initialized destroys its contained - value. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( T - const& - rhs ) - ; -

-
    -
  • - Effect: Assigns the value rhs to an optional. -
  • -
  • - Postconditions: *this is initialized and its value is - a copy of rhs. -
  • -
  • - Throws: Whatever T::operator=( T const& - ) or T::T(T const&) - throws. -
  • -
  • - Notes: If *this was initialized, T's assignment operator is used, - otherwise, its copy-constructor is used. -
  • -
  • - Exception Safety: In the event of - an exception, the initialization state of *this is unchanged and its value unspecified - as far as optional - is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - copy constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T x;
    -optional<T> def ;
    -optional<T> opt(x) ;
    -
    -T y;
    -def = y ;
    -assert ( *def == y ) ;
    -opt = y ;
    -assert ( *opt == y ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>& - optional<T&>::operator= ( T& rhs - ) ; -

-
    -
  • - Effect: (Re)binds the wrapped reference. -
  • -
  • - Postconditions: *this is initialized and it references - the same object referenced by rhs. -
  • -
  • - Notes: If *this was initialized, it is rebound - to the new object. See here - for details on this behavior. -
  • -
  • - Example: -
    int a = 1 ;
    -int b = 2 ;
    -T& ra = a ;
    -T& rb = b ;
    -optional<int&> def ;
    -optional<int&> opt(ra) ;
    -
    -def = rb ; // binds 'def' to 'b' through 'rb'
    -assert ( *def == b ) ;
    -*def = a ; // changes the value of 'b' to a copy of the value of 'a'
    -assert ( b == a ) ;
    -int c = 3;
    -int& rc = c ;
    -opt = rc ; // REBINDS to 'c' through 'rc'
    -c = 4 ;
    -assert ( *opt == 4 ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( T&& rhs - ) ; -

-
    -
  • - Effect: Moves the value rhs to an optional. -
  • -
  • - Postconditions: *this is initialized and its value is - moved from rhs. -
  • -
  • - Throws: Whatever T::operator=( T&& ) - or T::T(T &&) - throws. -
  • -
  • - Notes: If *this was initialized, T's move-assignment operator is used, - otherwise, its move-constructor is used. -
  • -
  • - Exception Safety: In the event of - an exception, the initialization state of *this is unchanged and its value unspecified - as far as optional - is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - move constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T x;
    -optional<T> def ;
    -optional<T> opt(x) ;
    -
    -T y1, y2, yR;
    -def = std::move(y1) ;
    -assert ( *def == yR ) ;
    -opt = std::move(y2) ;
    -assert ( *opt == yR ) ;
    -
    -
  • -
-

- space -

-

- optional<T&>& - optional<T&>::operator= ( T&& rhs - ) = - delete; -

-
  • - Notes: This assignment operator is - deleted. -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( optional - const& - rhs ) - ; -

-
    -
  • - Requires: T - is CopyConstructible and CopyAssignable. -
  • -
  • -

    - Effects: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns *rhs - to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with *rhs -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this; -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Exception Safety: If any exception - is thrown, the initialization state of *this and rhs - remains unchanged. If an exception is thrown during the call to T's copy constructor, no effect. - If an exception is thrown during the call to T's - copy assignment, the state of its contained value is as defined by - the exception safety guarantee of T's - copy assignment. -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -optional<T> def ;
    -
    -opt = def ;
    -assert ( !def ) ;
    -// previous value (copy of 'v') destroyed from within 'opt'.
    -
    -
  • -
-

- space -

-

- optional<T&> - & optional<T&>::operator= ( optional<T&> const& rhs - ) ; -

-
    -
  • - Effect: (Re)binds thee wrapped reference. -
  • -
  • - Postconditions: If *rhs is initialized, *this - is initialized and it references the same object referenced by *rhs; - otherwise, *this - is uninitialized (and references no object). -
  • -
  • - Notes: If *this was initialized and so is *rhs, - *this - is rebound to the new object. See here - for details on this behavior. -
  • -
  • - Example: -
    int a = 1 ;
    -int b = 2 ;
    -T& ra = a ;
    -T& rb = b ;
    -optional<int&> def ;
    -optional<int&> ora(ra) ;
    -optional<int&> orb(rb) ;
    -
    -def = orb ; // binds 'def' to 'b' through 'rb' wrapped within 'orb'
    -assert ( *def == b ) ;
    -*def = ora ; // changes the value of 'b' to a copy of the value of 'a'
    -assert ( b == a ) ;
    -int c = 3;
    -int& rc = c ;
    -optional<int&> orc(rc) ;
    -ora = orc ; // REBINDS ora to 'c' through 'rc'
    -c = 4 ;
    -assert ( *ora == 4 ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T (not a ref)>::operator= ( optional&& rhs - ) noexcept(see below); -

-
    -
  • - Requires: T - is MoveConstructible - and MoveAssignable. -
  • -
  • -

    - Effects: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns std::move(*rhs) to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with std::move(*rhs) -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this; -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Remarks: The expression inside noexcept is equivalent to is_nothrow_move_constructible<T>::value && - is_nothrow_move_assignable<T>::value. -
  • -
  • - Exception Safety: If any exception - is thrown, the initialization state of *this and rhs - remains unchanged. If an exception is thrown during the call to T's move constructor, the state of - *rhs - is determined by the exception safety guarantee of T's - move constructor. If an exception is thrown during the call to T's - move-assignment, the state of **this and *rhs is determined by the exception - safety guarantee of T's move assignment. -
  • -
  • - Example: -
    optional<T> opt(T(2)) ;
    -optional<T> def ;
    -
    -opt = def ;
    -assert ( def ) ;
    -assert ( opt ) ;
    -assert ( *opt == T(2) ) ;
    -
    -
  • -
-

- space -

-

- optional<T&> - & optional<T&>::operator= ( optional<T&>&& rhs - ) ; -

-
  • - Effect: Same as optional<T&>::operator= ( optional<T&> - const& - rhs ). -
-

- space -

-

- template<U> optional& - optional<T (not a ref)>::operator= ( optional<U> const& rhs - ) ; -

-
    -
  • -

    - Effect: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns *rhs - to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with *rhs -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this. -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Exception Safety: If any exception - is thrown, the result of the expression bool(*this) remains unchanged. If an exception - is thrown during the call to T's - constructor, no effect. If an exception is thrown during the call to - T's assignment, the - state of its contained value is as defined by the exception safety - guarantee of T's copy - assignment. -
  • -
  • - Example: -
    T v;
    -optional<T> opt0(v);
    -optional<U> opt1;
    -
    -opt1 = opt0 ;
    -assert ( *opt1 == static_cast<U>(v) ) ;
    -
    -
  • -
-

- space -

-

- template<U> optional& - optional<T (not a ref)>::operator= ( optional<U>&& rhs - ) ; -

-
    -
  • -

    - Effect: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns std::move(*rhs) to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with std::move(*rhs) -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this. -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Exception Safety: If any exception - is thrown, the result of the expression bool(*this) remains unchanged. If an exception - is thrown during the call to T's - constructor, no effect. If an exception is thrown during the call to - T's assignment, the - state of its contained value is as defined by the exception safety - guarantee of T's copy - assignment. -
  • -
  • - Example: -
    T v;
    -optional<T> opt0(v);
    -optional<U> opt1;
    -
    -opt1 = std::move(opt0) ;
    -assert ( opt0 );
    -assert ( opt1 )
    -assert ( *opt1 == static_cast<U>(v) ) ;
    -
    -
  • -
-

- space -

-

- template<class... Args> - void optional<T - (not a ref)>::emplace( - Args...&& - args ); -

-
    -
  • - Requires: The compiler supports rvalue - references and variadic templates. -
  • -
  • - Effect: If *this is initialized calls *this = none. - Then initializes in-place the contained value as if direct-initializing - an object of type T - with std::forward<Args>(args).... -
  • -
  • - Postconditions: *this is initialized. -
  • -
  • - Throws: Whatever the selected T's constructor throws. -
  • -
  • - Exception Safety: If an exception - is thrown during the initialization of T, - *this - is uninitialized. -
  • -
  • - Notes: T - need not be MoveConstructible - or MoveAssignable. - On compilers that do not support variadic templates, the signature - falls back to two overloads:template<class - Arg> - void emplace(Arg&& arg) and void - emplace(). - On compilers that do not support rvalue references, the signature falls - back to three overloads: taking const - and non-const lvalue reference, - and third with empty function argument list. -
  • -
  • - Example: -
    T v;
    -optional<const T> opt;
    -opt.emplace(0);  // create in-place using ctor T(int)
    -opt.emplace();   // destroy previous and default-construct another T
    -opt.emplace(v);  // destroy and copy-construct in-place (no assignment called)
    -
    -
  • -
-

- space -

-

- template<InPlaceFactory> - optional<T>& - optional<T (not a ref)>::operator=( InPlaceFactory - const& - f ); -

-

- template<TypedInPlaceFactory> - optional<T>& - optional<T (not a ref)>::operator=( TypedInPlaceFactory - const& - f ); -

-
    -
  • - Effect: Assigns an optional - with a value of T obtained - from the factory. -
  • -
  • - Postconditions: *this is initialized - and its value is directly given from the factory - f (i.e., the value - is not copied). -
  • -
  • - Throws: Whatever the T constructor called by the factory - throws. -
  • -
  • - Notes: See In-Place - Factories -
  • -
  • - Exception Safety: Exceptions can only - be thrown during the call to the T - constructor used by the factory; in that case, the optional - object will be reset to be uninitialized. -
  • -
-

- space -

-

- void optional<T - (not a ref)>::reset( T const& v ) ; -

-
  • - Deprecated: same as operator= - ( T - const& - v) - ; -
-

- space -

-

- void optional<T>::reset() noexcept - ; -

-
  • - Deprecated: Same as operator=( - none_t ); -
-

- space -

-

- T const& optional<T - (not a ref)>::get() const ; -

-

- T& - optional<T (not a ref)>::get() ; -

-

- inline T - const& - get ( - optional<T (not a ref)> const& ) ; -

-

- inline T& get - ( optional<T - (not a ref)> - &) ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: A reference to the contained - value -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). -
  • -
-

- space -

-

- T const& optional<T&>::get() const ; -

-

- T& - optional<T&>::get() ; -

-

- inline T - const& - get ( - optional<T&> - const& - ) ; -

-

- inline T& get - ( optional<T&> &) - ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: The - reference contained. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). -
  • -
-

- space -

-

- T const& optional<T - (not a ref)>::operator*() - const& - ; -

-

- T& - optional<T (not a ref)>::operator*() &; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: A reference to the contained - value -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions - these two overloads are replaced with the classical two: a const and non-const - member functions. -
  • -
  • - Example: -
    T v ;
    -optional<T> opt ( v );
    -T const& u = *opt;
    -assert ( u == v ) ;
    -T w ;
    -*opt = w ;
    -assert ( *opt == w ) ;
    -
    -
  • -
-

- space -

-

- T&& - optional<T (not a ref)>::operator*() &&; -

-
    -
  • - Requires: *this contains a value. -
  • -
  • - Effects: Equivalent to return std::move(*val);. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions - this overload is not present. -
  • -
-

- space -

-

- T & - optional<T&>::operator*() - const& - ; -

-

- T & - optional<T&>::operator*() - & ; -

-

- T & - optional<T&>::operator*() - && ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: The - reference contained. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions - these three overloads are replaced with the classical two: a const and non-const - member functions. -
  • -
  • - Example: -
    T v ;
    -T& vref = v ;
    -optional<T&> opt ( vref );
    -T const& vref2 = *opt;
    -assert ( vref2 == v ) ;
    -++ v ;
    -assert ( *opt == v ) ;
    -
    -
  • -
-

- space -

-

- T const& optional<T>::value() const& ; -

-

- T& - optional<T>::value() & ; -

-
    -
  • - Effects: Equivalent to return bool(*this) ? *val : throw bad_optional_access();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions these two overloads are replaced - with the classical two: a const - and non-const member functions. -
  • -
  • - Example: -
    T v ;
    -optional<T> o0, o1 ( v );
    -assert ( o1.value() == v );
    -
    -try {
    -  o0.value(); // throws
    -  assert ( false );
    -}
    -catch(bad_optional_access&) {
    -  assert ( true );
    -}
    -
    -
  • -
-

- space -

-

- T&& - optional<T>::value() && ; -

-
    -
  • - Effects: Equivalent to return bool(*this) ? std::move(*val) : throw bad_optional_access();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is not present. -
  • -
-

- space -

-

- template<class U> T optional<T>::value_or(U && - v) - const& - ; -

-
    -
  • - Effects: Equivalent to if (*this) return **this; else return - std::forward<U>(v);. -
  • -
  • - Remarks: If T - is not CopyConstructible or U && - is not convertible to T, - the program is ill-formed. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is replaced with the - const-qualified member - function. On compilers without rvalue reference support the type of - v becomes U const&. -
  • -
-

- space -

-

- template<class U> T optional<T>::value_or(U && - v) - && ; -

-
    -
  • - Effects: Equivalent to if (*this) return std::move(**this); else return std::forward<U>(v);. -
  • -
  • - Remarks: If T - is not MoveConstructible - or U && - is not convertible to T, - the program is ill-formed. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is not present. -
  • -
-

- space -

-

- template<class F> T optional<T>::value_or_eval(F f) const& ; -

-
    -
  • - Requires: T - is CopyConstructible and F models a Generator whose result type - is convertible to T. -
  • -
  • - Effects: if - (*this) return **this; else return f();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is replaced with the - const-qualified member - function. -
  • -
  • - Example: -
    int complain_and_0()
    -{
    -  clog << "no value returned, using default" << endl;
    -  return 0;
    -}
    -
    -optional<int> o1 = 1;
    -optional<int> oN = none;
    -
    -int i = o1.value_or_eval(complain_and_0); // fun not called
    -assert (i == 1);
    -
    -int j = oN.value_or_eval(complain_and_0); // fun called
    -assert (i == 0);
    -
    -
  • -
-

- space -

-

- template<class F> T optional<T>::value_or_eval(F f) && - ; -

-
    -
  • - Requires: T - is MoveConstructible - and F models a Generator - whose result type is convertible to T. -
  • -
  • - Effects: if - (*this) return std::move(**this); else return - f();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is not present. -
  • -
-

- space -

-

- T const& optional<T - (not a ref)>::get_value_or( - T const& default) const ; -

-

- T& - optional<T (not a ref)>::get_value_or( T& default - ) ; -

-

- inline T - const& - get_optional_value_or ( - optional<T (not a ref)> const& o, T const& default ) ; -

-

- inline T& get_optional_value_or - ( optional<T - (not a ref)>& - o, - T& - default ) - ; -

-
    -
  • - Deprecated: Use value_or() instead. -
  • -
  • - Returns: A reference to the contained - value, if any, or default. -
  • -
  • - Throws: Nothing. -
  • -
  • - Example: -
    T v, z ;
    -optional<T> def;
    -T const& y = def.get_value_or(z);
    -assert ( y == z ) ;
    -
    -optional<T> opt ( v );
    -T const& u = get_optional_value_or(opt,z);
    -assert ( u == v ) ;
    -assert ( u != z ) ;
    -
    -
  • -
-

- space -

-

- T const* optional<T - (not a ref)>::get_ptr() - const ; -

-

- T* - optional<T (not a ref)>::get_ptr() ; -

-

- inline T - const* - get_pointer ( - optional<T (not a ref)> const& ) ; -

-

- inline T* get_pointer - ( optional<T - (not a ref)> - &) ; -

-
    -
  • - Returns: If *this is initialized, a pointer to the - contained value; else 0 - (null). -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The contained value is permanently - stored within *this, - so you should not hold nor delete this pointer -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -optional<T> const copt(v);
    -T* p = opt.get_ptr() ;
    -T const* cp = copt.get_ptr();
    -assert ( p == get_pointer(opt) );
    -assert ( cp == get_pointer(copt) ) ;
    -
    -
  • -
-

- space -

-

- T const* optional<T - (not a ref)>::operator ->() - const ; -

-

- T* - optional<T (not a ref)>::operator - ->() ; -

-
    -
  • - Requires: *this is initialized. -
  • -
  • - Returns: A pointer to the contained - value. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). -
  • -
  • - Example: -
    struct X { int mdata ; } ;
    -X x ;
    -optional<X> opt (x);
    -opt->mdata = 2 ;
    -
    -
  • -
-

- space -

-

- explicit optional<T>::operator - bool() - const noexcept - ; -

-
    -
  • - Returns: get_ptr() != 0. -
  • -
  • - Notes: On compilers that do not support - explicit conversion operators this falls back to safe-bool idiom. -
  • -
  • - Example: -
    optional<T> def ;
    -assert ( def == 0 );
    -optional<T> opt ( v ) ;
    -assert ( opt );
    -assert ( opt != 0 );
    -
    -
  • -
-

- space -

-

- bool optional<T>::operator!() noexcept - ; -

-
    -
  • - Returns: If *this is uninitialized, true; else false. -
  • -
  • - Notes: This operator is provided for - those compilers which can't use the unspecified-bool-type - operator in certain boolean contexts. -
  • -
  • - Example: -
    optional<T> opt ;
    -assert ( !opt );
    -*opt = some_T ;
    -
    -// Notice the "double-bang" idiom here.
    -assert ( !!opt ) ;
    -
    -
  • -
-

- space -

-

- bool optional<T>::is_initialized() const ; -

-
  • - Deprecated: Same as explicit operator - bool () - ; -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___free_functions.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___free_functions.html deleted file mode 100644 index b46bcce0..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___free_functions.html +++ /dev/null @@ -1,521 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- space -

-

- optional<T> make_optional( - T const& v ) -

-
    -
  • - Returns: optional<T>(v) for the deduced - type T of v. -
  • -
  • - Example: -
    template<class T> void foo ( optional<T> const& opt ) ;
    -
    -foo ( make_optional(1+1) ) ; // Creates an optional<int>
    -
    -
  • -
-

- space -

-

- optional<std::decay_t<T>> - make_optional( - T && - v ) -

-
  • - Returns: optional<std::decay_t<T>>(std::move(v)) for the deduced - type T of v. -
-

- space -

-

- optional<T> make_optional( - bool condition, T const& v ) -

-
    -
  • - Returns: optional<T>(condition, v) for the deduced - type T of v. -
  • -
  • - Example: -
    optional<double> calculate_foo()
    -{
    -  double val = compute_foo();
    -  return make_optional(is_not_nan_and_finite(val),val);
    -}
    -
    -optional<double> v = calculate_foo();
    -if ( !v )
    -  error("foo wasn't computed");
    -
    -
  • -
-

- space -

-

- optional<std::decay_t<T>> - make_optional( - bool condition, T && v - ) -

-
  • - Returns: optional<std::decay_t<T>>(condition, std::move(v)) for the deduced - type T of v. -
-

- space -

-

- bool operator - == ( - optional<T> const& x, optional<T> const& y ); -

-
    -
  • - Requires: T - shall meet requirements of EqualityComparable. -
  • -
  • - Returns: If both x - and y are initialized, - (*x - == *y). - If only x or y is initialized, false. - If both are uninitialized, true. -
  • -
  • - Notes: This definition guarantees - that optional<T> - not containing a value is compared unequal to any optional<T> containing any value, and equal - to any other optional<T> not containing a value. Pointers - have shallow relational operators while optional - has deep relational operators. Do not use operator== directly in generic code which expect - to be given either an optional<T> or a pointer; use equal_pointees() - instead -
  • -
  • - Example: -
    optional<T> oN, oN_;
    -optional<T> o1(T(1)), o1_(T(1));
    -optional<T> o2(T(2));
    -
    -assert ( oN == oN );  // Identity implies equality
    -assert ( o1 == o1 );  //
    -
    -assert ( oN == oN_ ); // Both uninitialized compare equal
    -
    -assert ( oN != o1 );  // Initialized unequal to initialized.
    -
    -assert ( o1 == o1_ ); // Both initialized compare as (*lhs == *rhs)
    -assert ( o1 != o2 );  //
    -
    -
  • -
-

- space -

-

- bool operator - < ( - optional<T> const& x, optional<T> const& y ); -

-
    -
  • - Requires: Expression *x < *y shall be well-formed and its result - shall be convertible to bool. -
  • -
  • - Returns: (!y) ? false : (!x) ? true : *x < - *y. -
  • -
  • - Notes: This definition guarantees - that optional<T> - not containing a value is ordered as less than any optional<T> containing any value, and equivalent - to any other optional<T> not containing a value. Pointers - have shallow relational operators while optional - has deep relational operators. Do not use operator< directly in generic code which - expect to be given either an optional<T> or a pointer; use less_pointees() - instead. T need not - be LessThanComparable. Only - single operator< - is required. Other relational operations are defined in terms of this - one. If T's operator< - satisfies the axioms of LessThanComparable (transitivity, - antisymmetry and irreflexivity), optinal<T> is LessThanComparable. -
  • -
  • - Example: -
    optional<T> oN, oN_;
    -optional<T> o0(T(0));
    -optional<T> o1(T(1));
    -
    -assert ( !(oN < oN) );  // Identity implies equivalence
    -assert ( !(o1 < o1) );
    -
    -assert ( !(oN < oN_) ); // Two uninitialized are equivalent
    -assert ( !(oN_ < oN) );
    -
    -assert ( oN < o0 );     // Uninitialized is less than initialized
    -assert ( !(o0 < oN) );
    -
    -assert ( o1 < o2 ) ;    // Two initialized compare as (*lhs < *rhs)
    -assert ( !(o2 < o1) ) ;
    -assert ( !(o2 < o2) ) ;
    -
    -
  • -
-

- space -

-

- bool operator - != ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: !( - x == - y ); -
-

- space -

-

- bool operator - > ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: ( - y < - x ); -
-

- space -

-

- bool operator - <= ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: !( - y < - x ); -
-

- space -

-

- bool operator - >= ( - optional<T> const& x, optional<T> const& y ); -

-
  • - Returns: !( - x < - y ); -
-

- space -

-

- bool operator - == ( - optional<T> const& x, none_t ) - noexcept; -

-

- bool operator - == ( - none_t, - optional<T> const& x ) noexcept; -

-
-

- space -

-

- bool operator - != ( - optional<T> const& x, none_t ) - noexcept; -

-

- bool operator - != ( - none_t, - optional<T> const& x ) noexcept; -

-
  • - Returns: bool(x); -
-

- space -

-

- auto get_pointer - ( optional<T>& o - ) -> - typename optional<T>::pointer_type - ; -

-

- auto get_pointer - ( optional<T> const& o ) -> typename optional<T>::pointer_const_type - ; -

-
    -
  • - Returns: o.get_ptr(). -
  • -
  • - Throws: Nothing. -
  • -
-

- space -

-

- auto get_optional_value_or - ( optional<T>& o, typename optional<T>::reference_type def - ) -> - typename optional<T>::reference_type - ; -

-

- auto get_optional_value_or - ( optional<T> const& o, typename optional<T>::reference_const_type def - ) -> - typename optional<T>::reference_const_type - ; -

-
    -
  • - Returns: o.get_value_or(def). -
  • -
  • - Throws: Nothing. -
  • -
  • - Remarks: This function is deprecated. -
  • -
-

- space -

-

- void swap - ( optional<T>& x, optional<T>& y - ) ; -

-
    -
  • - Requires: Lvalues of type T shall be swappable and T shall be MoveConstructible. -
  • -
  • -

    - Effects: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - calls swap(*(*this), *rhs) -

    -
    -

    - initializes the contained value of *this as if direct-initializing - an object of type T - with the expression std::move(*rhs), followed by rhs.val->T::~T(), - *this - contains a value and rhs - does not contain a value -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - initializes the contained value of rhs - as if direct-initializing an object of type T with the expression - std::move(*(*this)), - followed by val->T::~T(), *this does not contain a value - and rhs contains - a value -

    -
    -

    - no effect -

    -
    -
  • -
  • - Postconditions: The states of x and y - interchanged. -
  • -
  • - Throws: If both are initialized, whatever - swap(T&,T&) - throws. If only one is initialized, whatever T::T ( T&& ) - throws. -
  • -
  • - Example: -
    T x(12);
    -T y(21);
    -optional<T> def0 ;
    -optional<T> def1 ;
    -optional<T> optX(x);
    -optional<T> optY(y);
    -
    -boost::swap(def0,def1); // no-op
    -
    -boost::swap(def0,optX);
    -assert ( *def0 == x );
    -assert ( !optX );
    -
    -boost::swap(def0,optX); // Get back to original values
    -
    -boost::swap(optX,optY);
    -assert ( *optX == y );
    -assert ( *optY == x );
    -
    -
  • -
-

- space -

-

- void swap - ( optional<T&>& x, optional<T&>& y - ) noexcept - ; -

-
    -
  • - Postconditions: x - refers to what y refererred - to before the swap (if anything). y - refers to whatever x - referred to before the swap. -
  • -
  • - Example: -
    T x(12);
    -T y(21);
    -
    -optional<T&> opt0;
    -optional<T&> optX (x);
    -optional<T&> optY (y);
    -
    -boost::swap(optX, optY);
    -assert (addressof(*optX) == addressof(y));
    -assert (addressof(*optY) == addressof(x));
    -
    -boost::swap(opt0, optX);
    -assert ( opt0 );
    -assert ( !optX );
    -assert (addressof(*opt0) == addressof(y));
    -
    -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html deleted file mode 100644 index e526f765..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html +++ /dev/null @@ -1,552 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- space -

-

- optional<T&>::optional() - noexcept; -

-

- optional<T&>::optional(none_t) noexcept; -

-
  • - Postconditions: bool(*this) == false; *this refers to nothing. -
-

- space -

-

- template<class R> optional<T&>::optional(R&& r) noexcept; -

-
    -
  • - Postconditions: bool(*this) == true; addressof(**this) == addressof(r). -
  • -
  • - Remarks: Unless R - is an lvalue reference, the program is ill-formed. This constructor - does not participate in overload resolution if decay<R> is an instance of boost::optional. -
  • -
  • - Notes: This constructor is declared - explicit on compilers - that do not correctly suport binding to const lvalues of integral types. - For more details see here. -
  • -
  • - Example: -
    T v;
    -T& vref = v ;
    -optional<T&> opt(vref);
    -assert ( *opt == v ) ;
    -++ v ; // mutate referee
    -assert (*opt == v);
    -
    -
  • -
-

- space -

-

- template<class R> optional<T&>::optional(bool cond, R&& - r) - noexcept; -

-
    -
  • - Effects: Initializes ref with expression cond ? - addressof(r) : nullptr. -
  • -
  • - Postconditions: bool(*this) == cond; If bool(*this), addressof(**this) == addressof(r). -
  • -
  • - Remarks: Unless R - is an lvalue reference, the program is ill-formed. This constructor - does not participate in overload resolution if decay<R> is an instance of boost::optional. -
  • -
-

- space -

-

- optional<T&>::optional ( - optional const& rhs - ) noexcept - ; -

-
    -
  • - Effects: Initializes ref with expression rhs.ref. -
  • -
  • - Postconditions: bool(*this) == bool(rhs). -
  • -
  • - Example: -
    optional<T&> uninit ;
    -assert (!uninit);
    -
    -optional<T&> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -T v = 2 ; T& ref = v ;
    -optional<T> init(ref);
    -assert ( *init == v ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( *init2 == v ) ;
    -
    -v = 3 ;
    -
    -assert ( *init  == 3 ) ;
    -assert ( *init2 == 3 ) ;
    -
    -
  • -
-

- space -

-

- template<class U> explicit - optional<T&>::optional ( - optional<U&> - const& - rhs ) - noexcept ; -

-
    -
  • - Requires: is_convertible<U&, T&>::value - is true. -
  • -
  • - Effects: Initializes ref with expression rhs.ref. -
  • -
  • - Postconditions: bool(*this) == bool(rhs). -
  • -
-

- space -

-

- optional<T&>::operator= ( none_t - ) noexcept - ; -

-
    -
  • - Effects: Assigns ref - with expression nullptr. -
  • -
  • - returns: *this. -
  • -
  • - Postconditions: bool(*this) == false. -
  • -
-

- optional& - optional<T&>::operator= ( optional - const& - rhs ) - noexcept ; -

-
    -
  • - Effects: Assigns ref - with expression rhs.ref. -
  • -
  • - returns: *this. -
  • -
  • - Postconditions: bool(*this) == bool(rhs). -
  • -
  • - Notes: This behaviour is called rebinding - semantics. See here - for details. -
  • -
  • - Example: -
    int a = 1 ;
    -int b = 2 ;
    -T& ra = a ;
    -T& rb = b ;
    -optional<int&> def ;
    -optional<int&> ora(ra) ;
    -optional<int&> orb(rb) ;
    -
    -def = orb ; // binds 'def' to 'b' through 'rb' wrapped within 'orb'
    -assert ( *def == b ) ;
    -*def = ora ; // changes the value of 'b' to a copy of the value of 'a'
    -assert ( b == a ) ;
    -int c = 3;
    -int& rc = c ;
    -optional<int&> orc(rc) ;
    -ora = orc ; // REBINDS ora to 'c' through 'rc'
    -c = 4 ;
    -assert ( *ora == 4 ) ;
    -
    -
  • -
-

- template<class U> optional& optional<T&>::operator= ( optional<U&> const& rhs - ) noexcept - ; -

-
    -
  • - Requires: is_convertible<U&, T&>::value - is true. -
  • -
  • - Effects: Assigns ref - with expression rhs.ref. -
  • -
  • - returns: *this. -
  • -
  • - Postconditions: bool(*this) == bool(rhs). -
  • -
-

- space -

-

- template<class R> optional& optional<T&>::operator= ( R&& r - ) noexcept - ; -

-
    -
  • - Effects: Assigns ref - with expression r. -
  • -
  • - returns: *this. -
  • -
  • - Postconditions: bool(*this) == true. -
  • -
  • - Remarks: Unless R - is an lvalue reference, the program is ill-formed. This function does - not participate in overload resolution if decay<R> is an instance of boost::optional. -
  • -
  • - Example: -
    int a = 1 ;
    -int b = 2 ;
    -T& ra = a ;
    -T& rb = b ;
    -optional<int&> def ;
    -optional<int&> opt(ra) ;
    -
    -def = rb ; // binds 'def' to 'b' through 'rb'
    -assert ( *def == b ) ;
    -*def = a ; // changes the value of 'b' to a copy of the value of 'a'
    -assert ( b == a ) ;
    -int c = 3;
    -int& rc = c ;
    -opt = rc ; // REBINDS to 'c' through 'rc'
    -c = 4 ;
    -assert ( *opt == 4 ) ;
    -
    -
  • -
-

- space -

-

- void optional<T&>::emplace( R&& r - ) noexcept - ; -

-
    -
  • - Effects: Assigns ref - with expression r. -
  • -
  • - Postconditions: bool(*this) == true. -
  • -
  • - Remarks: Unless R - is an lvalue reference, the program is ill-formed. This function does - not participate in overload resolution if decay<R> is an instance of boost::optional. -
  • -
-

- space -

-

- T& - optional<T&>::get() const ; -

-

- T& - optional<T&>::operator *() - const ; -

-
    -
  • - Requires: bool(*this) == true. -
  • -
  • - Effects: Returns *ref. -
  • -
  • - Throws: Nothing. -
  • -
  • - Example: -
    T v ;
    -T& vref = v ;
    -optional<T&> opt ( vref );
    -T const& vref2 = *opt;
    -assert ( vref2 == v ) ;
    -++ v ;
    -assert ( *opt == v ) ;
    -
    -
  • -
-

- space -

-

- T* - optional<T&>::operator -> - () const - ; -

-
    -
  • - Requires: bool(*this) == true. -
  • -
  • - Effects: Returns ref. -
  • -
  • - Throws: Nothing. -
  • -
-

- space -

-

- T& - optional<T&>::value() const ; -

-
  • - Effects: Equivalent to return bool(*this) ? *val : throw bad_optional_access();. -
-

- space -

-

- template<class R> T& optional<T&>::value_or( R&& r - ) const - noexcept; -

-
    -
  • - Effects: Equivalent to if (*this) return **this; else return - r;. -
  • -
  • - Remarks: Unless R - is an lvalue reference, the program is ill-formed. -
  • -
-

- space -

-

- template<class F> T& optional<T&>::value_or( F f ) const ; -

-
    -
  • - Effects: Equivalent to if (*this) return **this; else return - f();. -
  • -
  • - Remarks: Unless decltype(f()) is an lvalue reference, the program - is ill-formed. -
  • -
-

- space -

-

- template<class F> auto optional<T&>::map( F f ) const -> see below; -

-
    -
  • - Effects: Equivalent to if (*this) return f(**this); else return none;. -
  • -
  • - Remarks: The return type of this function - is optional<decltype(f(**this))>. -
  • -
-

- space -

-

- template<class F> auto optional<T&>::flat_map( - F f - ) const - -> see below; -

-
    -
  • - Requires: The return type of expression - f(**this) - is optional<U> - for some object or reference type U. -
  • -
  • - Effects: Equivalent to if (*this) return f(**this); else return none;. -
  • -
  • - Remarks: The return type of this function - is optional<U>. -
  • -
-

- space -

-

- T* - optional<T&>::get_ptr () - const noexcept; -

-
  • - Returns: ref. -
-

- space -

-

- bool has_value() const noexcept; -

-

- optional<T&>::operator bool - () const - noexcept; -

-
  • - Returns: bool(ref). -
-

- space -

-

- optional<T&>::operator ! () const noexcept; -

-
  • - Returns: !bool(ref). -
-

- space -

-

- void optional<T&>::reset() noexcept; -

-
  • - Effects: Same as *this = none. -
-

- space -

-

- template<class R> void optional<T&>::reset ( R&& - r) - noexcept; -

-
    -
  • - Effects: Equivalent to *this = std::forward<R>(r). -
  • -
  • - Remarks: This function is depprecated. -
  • -
-

- space -

-

- bool optional<T&>::is_initialized() const noexcept; -

-
    -
  • - Effects: Equivalent to return bool(*this). -
  • -
  • - Remarks: This function is depprecated. -
  • -
-

- space -

-

- template<class R> T& optional<T&>::get_value_or( R&& r - ) const - noexcept; -

-
    -
  • - Effects: Equivalent to return value_or(std::forward<R>(r);. -
  • -
  • - Remarks: This function is depprecated. -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html deleted file mode 100644 index ca180f49..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html +++ /dev/null @@ -1,1788 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - - - - -
[Note]Note

- The following section contains various assert() which are used only to show the postconditions - as sample code. It is not implied that the type T - must support each particular expression but that if the expression is - supported, the implied condition holds. -

-

- space -

-

- optional<T>::optional() - noexcept; -

-
    -
  • - Effect: Default-Constructs an optional. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
  • - Notes: T's default constructor is not called. -
  • -
  • - Example: -
    optional<T> def ;
    -assert ( !def ) ;
    -
    -
  • -
-

- space -

-

- optional<T>::optional( - none_t ) - noexcept; -

-
    -
  • - Effect: Constructs an optional uninitialized. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
  • - Notes: T's - default constructor is not called. - The expression boost::none - denotes an instance of boost::none_t - that can be used as the parameter. -
  • -
  • - Example: -
    #include <boost/none.hpp>
    -optional<T> n(none) ;
    -assert ( !n ) ;
    -
    -
  • -
-

- space -

-

- optional<T>::optional( - T const& v ) -

-
    -
  • - Requires: is_copy_constructible<T>::value - is true. -
  • -
  • - Effect: Directly-Constructs an optional. -
  • -
  • - Postconditions: *this is initialized - and its value is a copy of v. -
  • -
  • - Throws: Whatever T::T( T const& - ) throws. -
  • -
  • - Notes: T::T( T const& - ) is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -assert ( *opt == v ) ;
    -
    -
  • -
-

- space -

-

- optional<T>::optional( - T&& - v ) -

-
    -
  • - Requires: is_move_constructible<T>::value - is true. -
  • -
  • - Effect: Directly-Move-Constructs an - optional. -
  • -
  • - Postconditions: *this is initialized - and its value is move-constructed from v. -
  • -
  • - Throws: Whatever T::T( T&& ) - throws. -
  • -
  • - Notes: T::T( T&& ) - is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T&& ); - in that case, the state of v - is determined by exception safety guarantees for T::T(T&&). -
  • -
  • - Example: -
    T v1, v2;
    -optional<T> opt(std::move(v1));
    -assert ( *opt == v2 ) ;
    -
    -
  • -
-

- space -

-

- optional<T>::optional( - bool condition, T const& v ) ; -

-
  • - If condition is true, same as: -
-

- optional<T>::optional( - T const& v ) -

-
  • - otherwise, same as: -
-

- optional<T>::optional() -

-

- space -

-

- optional<T>::optional( - optional const& rhs - ); -

-
    -
  • - Requires: is_copy_constructible<T>::value - is true. -
  • -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs is initialized, - *this - is initialized and its value is a copy of the - value of rhs; else - *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( T const& - ) throws. -
  • -
  • - Notes: If rhs is initialized, T::T(T const& ) - is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    optional<T> uninit ;
    -assert (!uninit);
    -
    -optional<T> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -optional<T> init( T(2) );
    -assert ( *init == T(2) ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( init2 == init ) ;
    -
    -
  • -
-

- space -

-

- optional<T>::optional( - optional&& - rhs ) - noexcept(see - below); -

-
    -
  • - Requires: is_move_constructible<T>::value - is true. -
  • -
  • - Effect: Move-constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is move constructed from rhs; else *this is uninitialized. -
  • -
  • - Throws: Whatever T::T( T&& ) - throws. -
  • -
  • - Remarks: The expression inside noexcept is equivalent to is_nothrow_move_constructible<T>::value. -
  • -
  • - Notes: If rhs - is initialized, T::T( T && - ) is called. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( T&& ); - in that case, rhs remains - initialized and the value of *rhs is determined by exception safety - of T::T(T&&). -
  • -
  • - Example: -
    optional<std::unique_ptr<T>> uninit ;
    -assert (!uninit);
    -
    -optional<std::unique_ptr<T>> uinit2 ( std::move(uninit) ) ;
    -assert ( uninit2 == uninit );
    -
    -optional<std::unique_ptr<T>> init( std::uniqye_ptr<T>(new T(2)) );
    -assert ( **init == T(2) ) ;
    -
    -optional<std::unique_ptr<T>> init2 ( std::move(init) ) ;
    -assert ( init );
    -assert ( *init == nullptr );
    -assert ( init2 );
    -assert ( **init2 == T(2) ) ;
    -
    -
  • -
-

- space -

-

- template<U> explicit optional<T>::optional( optional<U> const& rhs - ); -

-
    -
  • - Effect: Copy-Constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is a copy of the - value of rhs converted to type T; - else *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( U const& - ) throws. -
  • -
  • - Notes: T::T( U const& - ) is called if rhs is initialized, which requires - a valid conversion from U - to T. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( U const& - ); in that case, this constructor - has no effect. -
  • -
  • - Example: -
    optional<double> x(123.4);
    -assert ( *x == 123.4 ) ;
    -
    -optional<int> y(x) ;
    -assert( *y == 123 ) ;
    -
    -
  • -
-

- space -

-

- template<U> explicit optional<T>::optional( optional<U>&& rhs - ); -

-
    -
  • - Effect: Move-constructs an optional. -
  • -
  • - Postconditions: If rhs - is initialized, *this - is initialized and its value is move-constructed from *rhs; - else *this - is uninitialized. -
  • -
  • - Throws: Whatever T::T( U&& ) - throws. -
  • -
  • - Notes: T::T( U&& ) - is called if rhs is - initialized, which requires a valid conversion from U - to T. -
  • -
  • - Exception Safety: Exceptions can only - be thrown during T::T( U&& ); - in that case, rhs remains - initialized and the value of *rhs is determined by exception safety - guarantee of T::T( U&& - ). -
  • -
  • - Example: -
    optional<double> x(123.4);
    -assert ( *x == 123.4 ) ;
    -
    -optional<int> y(std::move(x)) ;
    -assert( *y == 123 ) ;
    -
    -
  • -
-

- space -

-

- template<class... Args> - explicit optional<T>::optional( in_place_init_t, Args&&... ars - ); -

-
    -
  • - Requires: is_constructible_v<T, Args&&...> is true. -
  • -
  • - Effect: Initializes the contained - value as if direct-non-list-initializing an object of type T with the arguments std::forward<Args>(args).... -
  • -
  • - Postconditions: *this is initialized. -
  • -
  • - Throws: Any exception thrown by the - selected constructor of T. -
  • -
  • - Notes: T - need not be MoveConstructible. - On compilers that do not suppor variadic templates or rvalue references, - this constuctor is available in limited functionality. For details - see here. -
  • -
  • - Example: -
    // creates an std::mutex using its default constructor
    -optional<std::mutex> om {in_place_init};
    -assert (om);
    -
    -// creates a unique_lock by calling unique_lock(*om, std::defer_lock)
    -optional<std::unique_lock<std::mutex>> ol {in_place_init, *om, std::defer_lock};
    -assert (ol);
    -assert (!ol->owns_lock());
    -
    -
  • -
-

- space -

-

- template<class... Args> - explicit optional<T>::optional( in_place_init_if_t, bool condition, - Args&&... - ars ); -

-
    -
  • - Requires: is_constructible_v<T, Args&&...> is true. -
  • -
  • - Effect: If condition - is true, initializes the - contained value as if direct-non-list-initializing an object of type - T with the arguments - std::forward<Args>(args).... -
  • -
  • - Postconditions: bool(*this) == condition. -
  • -
  • - Throws: Any exception thrown by the - selected constructor of T. -
  • -
  • - Notes: T - need not be MoveConstructible. - On compilers that do not suppor variadic templates or rvalue references, - this constuctor is available in limited functionality. For details - see here. -
  • -
  • - Example: -
    optional<std::vector<std::string>> ov1 {in_place_init_if, false, 3, "A"};
    -assert (!ov1);
    -
    -optional<std::vector<std::string>> ov2 {in_place_init_if, true, 3, "A"};
    -assert (ov2);
    -assert (ov2->size() == 3);
    -
    -
  • -
-

- space -

-

- template<InPlaceFactory> - explicit optional<T>::optional( InPlaceFactory - const& - f ); -

-

- template<TypedInPlaceFactory> - explicit optional<T>::optional( TypedInPlaceFactory - const& - f ); -

-
    -
  • - Effect: Constructs an optional with a value of T obtained from the factory. -
  • -
  • - Postconditions: *this is initialized - and its value is directly given from the factory - f (i.e., the value - is not copied). -
  • -
  • - Throws: Whatever the T constructor called by the factory - throws. -
  • -
  • - Notes: See In-Place - Factories -
  • -
  • - Exception Safety: Exceptions can only - be thrown during the call to the T - constructor used by the factory; in that case, this constructor has - no effect. -
  • -
  • - Example: -
    class C { C ( char, double, std::string ) ; } ;
    -
    -C v('A',123.4,"hello");
    -
    -optional<C> x( in_place   ('A', 123.4, "hello") ); // InPlaceFactory used
    -optional<C> y( in_place<C>('A', 123.4, "hello") ); // TypedInPlaceFactory used
    -
    -assert ( *x == v ) ;
    -assert ( *y == v ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T>::operator= ( none_t - ) noexcept; -

-
    -
  • - Effect: If *this is initialized destroys its contained - value. -
  • -
  • - Postconditions: *this is uninitialized. -
  • -
-

- space -

-

- optional& - optional<T>::operator= ( T const& rhs ) ; -

-
    -
  • - Effect: Assigns the value rhs to an optional. -
  • -
  • - Postconditions: *this is initialized and its value is - a copy of rhs. -
  • -
  • - Throws: Whatever T::operator=( T const& - ) or T::T(T const&) - throws. -
  • -
  • - Notes: If *this was initialized, T's assignment operator is used, - otherwise, its copy-constructor is used. -
  • -
  • - Exception Safety: In the event of - an exception, the initialization state of *this is unchanged and its value unspecified - as far as optional - is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - copy constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T x;
    -optional<T> def ;
    -optional<T> opt(x) ;
    -
    -T y;
    -def = y ;
    -assert ( *def == y ) ;
    -opt = y ;
    -assert ( *opt == y ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T>::operator= ( T&& rhs - ) ; -

-
    -
  • - Effect: Moves the value rhs to an optional. -
  • -
  • - Postconditions: *this is initialized and its value is - moved from rhs. -
  • -
  • - Throws: Whatever T::operator=( T&& ) - or T::T(T &&) - throws. -
  • -
  • - Notes: If *this was initialized, T's move-assignment operator is used, - otherwise, its move-constructor is used. -
  • -
  • - Exception Safety: In the event of - an exception, the initialization state of *this is unchanged and its value unspecified - as far as optional - is concerned (it is up to T's - operator=()). - If *this - is initially uninitialized and T's - move constructor fails, *this is left properly uninitialized. -
  • -
  • - Example: -
    T x;
    -optional<T> def ;
    -optional<T> opt(x) ;
    -
    -T y1, y2, yR;
    -def = std::move(y1) ;
    -assert ( *def == yR ) ;
    -opt = std::move(y2) ;
    -assert ( *opt == yR ) ;
    -
    -
  • -
-

- space -

-

- optional& - optional<T>::operator= ( optional - const& - rhs ) - ; -

-
    -
  • - Requires: T - is CopyConstructible and CopyAssignable. -
  • -
  • -

    - Effects: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns *rhs - to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with *rhs -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this; -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Exception Safety: If any exception - is thrown, the initialization state of *this and rhs - remains unchanged. If an exception is thrown during the call to T's copy constructor, no effect. - If an exception is thrown during the call to T's - copy assignment, the state of its contained value is as defined by - the exception safety guarantee of T's - copy assignment. -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -optional<T> def ;
    -
    -opt = def ;
    -assert ( !def ) ;
    -// previous value (copy of 'v') destroyed from within 'opt'.
    -
    -
  • -
-

- space -

-

- optional& - optional<T>::operator= ( optional&& rhs - ) noexcept(see below); -

-
    -
  • - Requires: T - is MoveConstructible - and MoveAssignable. -
  • -
  • -

    - Effects: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns std::move(*rhs) to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with std::move(*rhs) -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this; -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Remarks: The expression inside noexcept is equivalent to is_nothrow_move_constructible<T>::value && - is_nothrow_move_assignable<T>::value. -
  • -
  • - Exception Safety: If any exception - is thrown, the initialization state of *this and rhs - remains unchanged. If an exception is thrown during the call to T's move constructor, the state of - *rhs - is determined by the exception safety guarantee of T's - move constructor. If an exception is thrown during the call to T's - move-assignment, the state of **this and *rhs is determined by the exception - safety guarantee of T's move assignment. -
  • -
  • - Example: -
    optional<T> opt(T(2)) ;
    -optional<T> def ;
    -
    -opt = def ;
    -assert ( def ) ;
    -assert ( opt ) ;
    -assert ( *opt == T(2) ) ;
    -
    -
  • -
-

- space -

-

- template<U> optional& - optional<T>::operator= ( optional<U> const& rhs - ) ; -

-
    -
  • -

    - Effect: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns *rhs - to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with *rhs -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this. -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Exception Safety: If any exception - is thrown, the result of the expression bool(*this) remains unchanged. If an exception - is thrown during the call to T's - constructor, no effect. If an exception is thrown during the call to - T's assignment, the - state of its contained value is as defined by the exception safety - guarantee of T's copy - assignment. -
  • -
  • - Example: -
    T v;
    -optional<T> opt0(v);
    -optional<U> opt1;
    -
    -opt1 = opt0 ;
    -assert ( *opt1 == static_cast<U>(v) ) ;
    -
    -
  • -
-

- space -

-

- template<U> optional& - optional<T>::operator= ( optional<U>&& rhs - ) ; -

-
    -
  • -

    - Effect: -

    -
    ----- - - - - - - - - - - - - - - - - - - -
    - -

    - *this contains a value -

    -
    -

    - *this does not contain a value -

    -
    -

    - rhs - contains a value -

    -
    -

    - assigns std::move(*rhs) to the contained value -

    -
    -

    - initializes the contained value as if direct-initializing - an object of type T - with std::move(*rhs) -

    -
    -

    - rhs - does not contain a value -

    -
    -

    - destroys the contained value by calling val->T::~T() -

    -
    -

    - no effect -

    -
    -
  • -
  • - Returns: *this. -
  • -
  • - Postconditions: bool(rhs) == bool(*this). -
  • -
  • - Exception Safety: If any exception - is thrown, the result of the expression bool(*this) remains unchanged. If an exception - is thrown during the call to T's - constructor, no effect. If an exception is thrown during the call to - T's assignment, the - state of its contained value is as defined by the exception safety - guarantee of T's copy - assignment. -
  • -
  • - Example: -
    T v;
    -optional<T> opt0(v);
    -optional<U> opt1;
    -
    -opt1 = std::move(opt0) ;
    -assert ( opt0 );
    -assert ( opt1 )
    -assert ( *opt1 == static_cast<U>(v) ) ;
    -
    -
  • -
-

- space -

-

- template<class... Args> - void optional<T>::emplace( Args&&... args - ); -

-
    -
  • - Requires: The compiler supports rvalue - references and variadic templates. -
  • -
  • - Effect: If *this is initialized calls *this = none. - Then initializes in-place the contained value as if direct-initializing - an object of type T - with std::forward<Args>(args).... -
  • -
  • - Postconditions: *this is initialized. -
  • -
  • - Throws: Whatever the selected T's constructor throws. -
  • -
  • - Exception Safety: If an exception - is thrown during the initialization of T, - *this - is uninitialized. -
  • -
  • - Notes: T - need not be MoveConstructible - or MoveAssignable. - On compilers that do not suppor variadic templates or rvalue references, - this function is available in limited functionality. For details see here. -
  • -
  • - Example: -
    T v;
    -optional<const T> opt;
    -opt.emplace(0);  // create in-place using ctor T(int)
    -opt.emplace();   // destroy previous and default-construct another T
    -opt.emplace(v);  // destroy and copy-construct in-place (no assignment called)
    -
    -
  • -
-

- space -

-

- template<InPlaceFactory> - optional<T>& - optional<T>::operator=( InPlaceFactory const& f ); -

-

- template<TypedInPlaceFactory> - optional<T>& - optional<T>::operator=( TypedInPlaceFactory const& f ); -

-
    -
  • - Effect: Assigns an optional - with a value of T obtained - from the factory. -
  • -
  • - Postconditions: *this is initialized - and its value is directly given from the factory - f (i.e., the value - is not copied). -
  • -
  • - Throws: Whatever the T constructor called by the factory - throws. -
  • -
  • - Notes: See In-Place - Factories -
  • -
  • - Exception Safety: Exceptions can only - be thrown during the call to the T - constructor used by the factory; in that case, the optional - object will be reset to be uninitialized. -
  • -
-

- space -

-

- void optional<T>::reset( T const& v ) ; -

-
  • - Deprecated: same as operator= - ( T - const& - v) - ; -
-

- space -

-

- void optional<T>::reset() noexcept - ; -

-
  • - Effects: Same as operator=( none_t - ); -
-

- space -

-

- T const& optional<T>::get() const ; -

-

- T& - optional<T>::get() ; -

-

- inline T - const& - get ( - optional<T> const& ) ; -

-

- inline T& get - ( optional<T> &) - ; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: A reference to the contained - value -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). -
  • -
-

- space -

-

- T const& optional<T>::operator*() const& ; -

-

- T& - optional<T>::operator*() - &; -

-
    -
  • - Requires: *this is initialized -
  • -
  • - Returns: A reference to the contained - value -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions - these two overloads are replaced with the classical two: a const and non-const - member functions. -
  • -
  • - Example: -
    T v ;
    -optional<T> opt ( v );
    -T const& u = *opt;
    -assert ( u == v ) ;
    -T w ;
    -*opt = w ;
    -assert ( *opt == w ) ;
    -
    -
  • -
-

- space -

-

- T&& - optional<T>::operator*() - &&; -

-
    -
  • - Requires: *this contains a value. -
  • -
  • - Effects: Equivalent to return std::move(*val);. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). - On compilers that do not support ref-qualifiers on member functions - this overload is not present. -
  • -
-

- space -

-

- T const& optional<T>::value() const& ; -

-

- T& - optional<T>::value() & ; -

-
    -
  • - Effects: Equivalent to return bool(*this) ? *val : throw bad_optional_access();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions these two overloads are replaced - with the classical two: a const - and non-const member functions. -
  • -
  • - Example: -
    T v ;
    -optional<T> o0, o1 ( v );
    -assert ( o1.value() == v );
    -
    -try {
    -  o0.value(); // throws
    -  assert ( false );
    -}
    -catch(bad_optional_access&) {
    -  assert ( true );
    -}
    -
    -
  • -
-

- space -

-

- T&& - optional<T>::value() && ; -

-
    -
  • - Effects: Equivalent to return bool(*this) ? std::move(*val) : throw bad_optional_access();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is not present. -
  • -
-

- space -

-

- template<class U> T optional<T>::value_or(U && - v) - const& - ; -

-
    -
  • - Effects: Equivalent to if (*this) return **this; else return - std::forward<U>(v);. -
  • -
  • - Remarks: If T - is not CopyConstructible or U && - is not convertible to T, - the program is ill-formed. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is replaced with the - const-qualified member - function. On compilers without rvalue reference support the type of - v becomes U const&. -
  • -
-

- space -

-

- template<class U> T optional<T>::value_or(U && - v) - && ; -

-
    -
  • - Effects: Equivalent to if (*this) return std::move(**this); else return std::forward<U>(v);. -
  • -
  • - Remarks: If T - is not MoveConstructible - or U && - is not convertible to T, - the program is ill-formed. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is not present. -
  • -
-

- space -

-

- template<class F> T optional<T>::value_or_eval(F f) const& ; -

-
    -
  • - Requires: T - is CopyConstructible and F models a Generator whose result type - is convertible to T. -
  • -
  • - Effects: if - (*this) return **this; else return f();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is replaced with the - const-qualified member - function. -
  • -
  • - Example: -
    int complain_and_0()
    -{
    -  clog << "no value returned, using default" << endl;
    -  return 0;
    -}
    -
    -optional<int> o1 = 1;
    -optional<int> oN = none;
    -
    -int i = o1.value_or_eval(complain_and_0); // fun not called
    -assert (i == 1);
    -
    -int j = oN.value_or_eval(complain_and_0); // fun called
    -assert (i == 0);
    -
    -
  • -
-

- space -

-

- template<class F> T optional<T>::value_or_eval(F f) && - ; -

-
    -
  • - Requires: T - is MoveConstructible - and F models a Generator - whose result type is convertible to T. -
  • -
  • - Effects: if - (*this) return std::move(**this); else return - f();. -
  • -
  • - Notes: On compilers that do not support - ref-qualifiers on member functions this overload is not present. -
  • -
-

- space -

-

- template<class F> auto optional<T>::map(F f) const& -> - see below ; -

-

- template<class F> auto optional<T>::map(F f) & -> see below - ; -

-
    -
  • - Effects: if - (*this) return f(**this); else return - none; -
  • -
  • - Notes: The return type of these overloads - is optional<decltype(f(**this))>. - On compilers that do not support ref-qualifiers on member functions, - these two (as well as the next one) overloads are replaced with good - old const and non-const overloads. -
  • -
  • - Example: -
    auto length = [](const string& s){ return s.size(); };
    -optional<string> o1 {}, o2 {"cat"};
    -optional<size_t> os1 = o1.map(length), os2 = o2.map(length);
    -assert ( !os1 ) ;
    -assert ( os2 ) ;
    -assert ( *os2 == 3 ) ;
    -
    -
  • -
-

- space -

-

- template<class F> auto optional<T>::map(F f) && - -> see below - ; -

-
    -
  • - Effects: if - (*this) return f(std::move(**this)); else return - none; -
  • -
  • - Notes: The return type of this overload - is optional<decltype(f(istd::move(**this)))>. -
  • -
-

- space -

-

- template<class F> auto optional<T>::flat_map(F f) const& -> - see below ; -

-

- template<class F> auto optional<T>::flat_map(F f) & -> see below - ; -

-
    -
  • - Requires: The return type of expression - f(**this) - is optional<U> - for some object or reference type U. -
  • -
  • - Effects: if - (*this) return f(**this); else return - none; -
  • -
  • - Notes: The return type of these overloads - is optional<U>. - On compilers that do not support ref-qualifiers on member functions, - these two (as well as the next one) overloads are replaced with good - old const and non-const overloads. -
  • -
  • - Example: -
    optional<char> first_char(const string& s) {
    -  return s.empty() ? none : optional<char>(s[0]);
    -};
    -optional<string> o1 {}, o2 {"cat"};
    -optional<char> os1 = o1.flat_map(first_char), os2 = o2.flat_map(first_char);
    -assert ( !os1 ) ;
    -assert ( os2 ) ;
    -assert ( *os2 == 'c' ) ;
    -
    - space -
  • -
-

- template<class F> auto optional<T>::flat_map(F f) && - -> see below - ; -

-
    -
  • - Requires: The return type of expression - f(std::move(**this)) - is optional<U> - for some object or reference type U. -
  • -
  • - Effects: if - (*this) return f(std::move(**this)); else return - none; -
  • -
  • - Notes: The return type of this overload - is optional<U>. -
  • -
-

- space -

-

- T const& optional<T>::get_value_or( T const& default) const ; -

-

- T& - optional<T>::get_value_or( - T& - default ) - ; -

-
    -
  • - Deprecated: Use value_or() instead. -
  • -
  • - Returns: A reference to the contained - value, if any, or default. -
  • -
  • - Throws: Nothing. -
  • -
  • - Example: -
    T v, z ;
    -optional<T> def;
    -T const& y = def.get_value_or(z);
    -assert ( y == z ) ;
    -
    -optional<T> opt ( v );
    -T const& u = opt.get_value_or(z);
    -assert ( u == v ) ;
    -assert ( u != z ) ;
    -
    -
  • -
-

- space -

-

- T const* optional<T>::get_ptr() const ; -

-

- T* - optional<T>::get_ptr() - ; -

-
    -
  • - Returns: If *this is initialized, a pointer to the - contained value; else 0 - (null). -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The contained value is permanently - stored within *this, - so you should not hold nor delete this pointer -
  • -
  • - Example: -
    T v;
    -optional<T> opt(v);
    -optional<T> const copt(v);
    -T* p = opt.get_ptr() ;
    -T const* cp = copt.get_ptr();
    -assert ( p == get_pointer(opt) );
    -assert ( cp == get_pointer(copt) ) ;
    -
    -
  • -
-

- space -

-

- T const* optional<T>::operator - ->() const - ; -

-

- T* - optional<T>::operator ->() - ; -

-
    -
  • - Requires: *this is initialized. -
  • -
  • - Returns: A pointer to the contained - value. -
  • -
  • - Throws: Nothing. -
  • -
  • - Notes: The requirement is asserted - via BOOST_ASSERT(). -
  • -
  • - Example: -
    struct X { int mdata ; } ;
    -X x ;
    -optional<X> opt (x);
    -opt->mdata = 2 ;
    -
    -
  • -
-

- space -

-

- explicit optional<T>::operator - bool() - const noexcept - ; -

-

- bool optional<T>::has_value() const noexcept ; -

-
    -
  • - Returns: get_ptr() != 0. -
  • -
  • - Notes: On compilers that do not support - explicit conversion operators this falls back to safe-bool idiom. -
  • -
  • - Example: -
    optional<T> def ;
    -assert ( def == 0 );
    -optional<T> opt ( v ) ;
    -assert ( opt );
    -assert ( opt != 0 );
    -
    -
  • -
-

- space -

-

- bool optional<T>::operator!() noexcept - ; -

-
    -
  • - Returns: If *this is uninitialized, true; else false. -
  • -
  • - Notes: This operator is provided for - those compilers which can't use the unspecified-bool-type - operator in certain boolean contexts. -
  • -
  • - Example: -
    optional<T> opt ;
    -assert ( !opt );
    -*opt = some_T ;
    -
    -// Notice the "double-bang" idiom here.
    -assert ( !!opt ) ;
    -
    -
  • -
-

- space -

-

- bool optional<T>::is_initialized() const ; -

-
  • - Deprecated: Same as explicit operator - bool () - ; -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header__boost_optional_hpp_.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header__boost_optional_hpp_.html deleted file mode 100644 index 8496d372..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header__boost_optional_hpp_.html +++ /dev/null @@ -1,47 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- This is an alias for header <boost/optional/optional.hpp>. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_in_place_init.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_in_place_init.html deleted file mode 100644 index be67b67b..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_in_place_init.html +++ /dev/null @@ -1,61 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
namespace boost {
-
-class in_place_init_t { /* see below */ } ;
-const in_place_init_t in_place_init ( /* see below */ ) ;
-
-class in_place_init_if_t { /*see below*/ } ;
-const in_place_init_if_t in_place_init_if ( /*see below*/ ) ;
-
-}
-
-

- Classes in_place_init_t - and in_place_init_if_t - are empty clsses. Their purpose is to control overload resolution in the - initialization of optional objects. They are empty, trivially copyable - classes with disabled default constructor. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html deleted file mode 100644 index 8cef0ab3..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html +++ /dev/null @@ -1,118 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
template <class T>
-class optional<T&> // specilization for lvalue references
-{
-public :
-
-    typedef T& value_type;
-    typedef T& reference_type;
-    typedef T& reference_const_type; // no const propagation
-    typedef T& rval_reference_type;
-    typedef T* pointer_type;
-    typedef T* pointer_const_type;   // no const propagation
-
-    optional () noexcept ; R
-
-    optional ( none_t ) noexcept ; R
-
-    template<class R> optional(R&& r) noexcept ;  R
-
-    template <class R> optional(bool cond, R&& r) noexcept ; R
-
-    optional ( optional const& rhs ) noexcept ; R
-
-    template<class U> explicit optional ( optional<U&> const& rhs ) noexcept ; R
-
-    optional& operator = ( none_t ) noexcept ; R
-
-    optional& operator = ( optional const& rhs ) noexcept; R
-
-    template<class U> optional& operator = ( optional<U&> const& rhs ) noexcept ; R
-
-    template<class R> optional& operator = (R&& r) noexcept ; R
-
-    template<class R> void emplace ( R&& r ) noexcept ; R
-
-    T& get() const ; R
-    T& operator *() const ; R
-
-    T* operator ->() const ; R
-
-    T& value() const& ; R
-
-    template<class R> T& value_or( R && r ) const noexcept ; R
-
-    template<class F> T& value_or_eval( F f ) const ; R
-
-    template<class F> auto map( F f ) const -> see below; R
-
-    template<class F> auto flat_map( F f ) const -> see below; R
-
-    T* get_ptr() const noexcept ; R
-
-    bool has_value() const noexcept ; R
-
-    explicit operator bool() const noexcept ; R
-
-    bool operator!() const noexcept ; R
-
-    void reset() noexcept ; R
-
-    // deprecated methods
-
-    // (deprecated)
-    template<class R> void reset ( R && r ) noexcept ; R
-
-    // (deprecated)
-    bool is_initialized() const noexcept ; R
-
-    // (deprecated)
-    template<class R> T& get_value_or( R && r ) constnoexcept; R
-
-private:
-    T* ref; // exposition only
-};
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html deleted file mode 100644 index f6ed7da8..00000000 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html +++ /dev/null @@ -1,153 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
template <class T>
-class optional
-{
-public :
-
-    typedef T         value_type ;
-    typedef T &       reference_type ;
-    typedef T const&  reference_const_type ;
-    typedef T &&      rval_reference_type ;
-    typedef T *       pointer_type ;
-    typedef T const*  pointer_const_type ;
-
-    optional () noexcept ; R
-
-    optional ( none_t ) noexcept ; R
-
-    optional ( T const& v ) ; R
-
-    optional ( T&& v ) ; R
-
-    optional ( bool condition, T const& v ) ; R
-
-    optional ( optional const& rhs ) ; R
-
-    optional ( optional&& rhs ) noexcept(see below) ; R
-
-    template<class U> explicit optional ( optional<U> const& rhs ) ; R
-
-    template<class U> explicit optional ( optional<U>&& rhs ) ; R
-
-    template<class... Args> explicit optional ( in_place_init_t, Args&&... args ) ; R
-
-    template<class... Args> explicit optional ( in_place_init_if_t, bool condition, Args&&... args ) ; R
-
-    template<class InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ; R
-
-    template<class TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ; R
-
-    optional& operator = ( none_t ) noexcept ; R
-
-    optional& operator = ( T const& v ) ; R
-
-    optional& operator = ( T&& v ) ; R
-
-    optional& operator = ( optional const& rhs ) ; R
-
-    optional& operator = ( optional&& rhs ) noexcept(see below) ; R
-
-    template<class U> optional& operator = ( optional<U> const& rhs ) ; R
-
-    template<class U> optional& operator = ( optional<U>&& rhs ) ; R
-
-    template<class... Args> void emplace ( Args&&... args ) ; R
-
-    template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ; R
-
-    template<class TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ; R
-
-    T const& get() const ; R
-    T&       get() ; R
-
-    T const* operator ->() const ; R
-    T*       operator ->() ; R
-
-    T const& operator *() const& ; R
-    T&       operator *() & ; R
-    T&&      operator *() && ; R
-
-    T const& value() const& ; R
-    T&       value() & ; R
-    T&&      value() && ; R
-
-    template<class U> T value_or( U && v ) const& ; R
-    template<class U> T value_or( U && v ) && ; R
-
-    template<class F> T value_or_eval( F f ) const& ; R
-    template<class F> T value_or_eval( F f ) && ; R
-
-    template<class F> auto map( F f ) const& -> see below; R
-    template<class F> auto map( F f ) & -> see below; R
-    template<class F> auto map( F f ) && -> see below; R
-
-    template<class F> auto flat_map( F f ) const& -> see below; R
-    template<class F> auto flat_map( F f ) & -> see below; R
-    template<class F> auto flat_map( F f ) && -> see below; R
-
-    T const* get_ptr() const ; R
-    T*       get_ptr() ; R
-
-    bool has_value() const noexcept ; R
-
-    explicit operator bool() const noexcept ; R
-
-    bool operator!() const noexcept ; R
-
-    void reset() noexcept ; R
-
-    // deprecated methods
-
-    // (deprecated)
-    void reset ( T const& ) ; R
-
-    // (deprecated)
-    bool is_initialized() const ; R
-
-    // (deprecated)
-    T const& get_value_or( T const& default ) const ; R
-};
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/io_header.html b/doc/html/boost_optional/reference/io_header.html deleted file mode 100644 index fd8599f6..00000000 --- a/doc/html/boost_optional/reference/io_header.html +++ /dev/null @@ -1,72 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- -

-

-
#include <istream>
-#include <ostream>
-#include <boost/optional/optional.hpp>
-
-namespace boost {
-
-template <class CharType, class CharTrait, class T>
-  std::basic_ostream<CharType, CharTrait>&
-  operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v); R
-
-  template <class CharType, class CharTrait>
-  std::basic_ostream<CharType, CharTrait>&
-  operator<<(std::basic_ostream<CharType, CharTrait>& out, none_t const&); R
-
-template<class CharType, class CharTrait, class T>
-  std::basic_istream<CharType, CharTrait>&
-  operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v); R
-
-} // namespace boost
-
-

-

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/io_header/io_semantics.html b/doc/html/boost_optional/reference/io_header/io_semantics.html deleted file mode 100644 index 2e8ed56c..00000000 --- a/doc/html/boost_optional/reference/io_header/io_semantics.html +++ /dev/null @@ -1,112 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- template - <class - CharType, - class CharTrait, class T> -
    std::basic_ostream<CharType, CharTrait>&
    operator<<(std::basic_ostream<CharType, CharTrait>& - out, - optional<T> const& v); -

-
    -
  • - Effect: Outputs an implementation-defined - string. The output contains the information about whether the optional - object contains a value or not. If v - contains a value, the output contains result of calling out << - *v. -
  • -
  • - Returns: out. -
  • -
-

- space -

-

- template <class CharType, class CharTrait, - class T>
    std::basic_ostream<CharType, CharTrait>& -
    operator<<(std::basic_ostream<CharType, CharTrait>& out, none_t); -

-
    -
  • - Effect: Outputs an implementation-defined - string. -
  • -
  • - Returns: out. -
  • -
-

- space -

-

- template <class CharType, class CharTrait, - class T>
    std::basic_ostream<CharType, CharTrait>& -
    operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v); -

-
    -
  • - Requires: T - is DefaultConstructible and - MoveConstructible. -
  • -
  • - Effect: Reads the value of optional - object from in. If - the string representation indicates that the optional object should - contain a value, v - contains a value and its contained value is obtained as if by default-constructing - an object o of type - T and then calling - in >> - o; otherwise v does not contain a value, and the - previously contained value (if any) has been destroyed. -
  • -
  • - Returns: out. -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/reference/relnotes.html b/doc/html/boost_optional/reference/relnotes.html deleted file mode 100644 index c67535ea..00000000 --- a/doc/html/boost_optional/reference/relnotes.html +++ /dev/null @@ -1,183 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- - Boost Release - X.XX -
-
  • - Now boost::optional is specialized for reference - parameters. This way the sizeof - of optional reference is that of a pointer, and a number of bugs is avoided. -
-
- - Boost Release - 1.60 -
-
  • - Changed the implementation of boost::none - again. Now it is a const object with internal linkage (as any other tag). - This fixes Trac - #11203. -
-
- - Boost Release - 1.59 -
-
    -
  • - For C++03 compilers, added 0-argument overload for member function emplace(), - and therewith removed the dependency on <boost/utility/in_place_factory.hpp>. -
  • -
  • - Fixed Trac - #11241. -
  • -
-
- - Boost Release - 1.58 -
-
    -
  • - boost::none_t is no longer convertible from - literal 0. This avoids a - bug where optional<rational<int>> - oi = - 0; - would initialize an optional object with no contained value. -
  • -
  • - Improved the trick that prevents streaming out optional - without header optional_io.hpp - by using safe-bool idiom. This addresses Trac - #10825. -
  • -
  • - IOStream operators are now mentioned in documentation. -
  • -
  • - Added a way to manually disable move semantics: just define macro BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES. - This can be used to work around Trac - #10399. -
  • -
  • - It is no longer possible to assign optional<U> to optional<T> when U - is not assignable or convertible to T - (Trac #11087). -
  • -
  • - Value accessors now work correctly on rvalues of optional<T&> (Trac - #10839). -
  • -
-
- - Boost Release - 1.57 -
-
  • - Git pull #9: - "Supply <string> - to fix C++03 compile error on logic_error("...")". -
-
- - Boost Release - 1.56 -
-
    -
  • - Added support for rvalue references. Now optional<T> works with moveable but non-copyable - T's, -
  • -
  • - Improved swap (now uses - move operations), -
  • -
  • - Added function emplace(). This is the last of the requests from - Trac #1841, -
  • -
  • - optional is moveable, - including conditional noexcept - specifications, which make it move_if_noexcept-friendly, -
  • -
  • - Using explicit operator bool() on platforms that support it (Trac - #4227) (breaking change), -
  • -
  • - Forward declaration of operator<<(ostream&, optional - const&) - to prevent inadvertent incorrect serialization of optional objects, -
  • -
  • - Removed deprecated function reset() from examples (Trac - #9005), -
  • -
  • - Equality comparison with boost::none - does not require that T - be EqualityComparable, -
  • -
  • - Optional rvalue references are explicitly disallowed, -
  • -
  • - Binding temporaries to optional references is explicitly disallowed (breaking - change), -
  • -
  • - More ways to access the contained value, functions value(), value_or(), value_or_eval(), -
  • -
  • - Updated and reorganized documentation, added tutorial and quick guide - sections. -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html deleted file mode 100644 index 3d846966..00000000 --- a/doc/html/boost_optional/relnotes.html +++ /dev/null @@ -1,311 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- - Boost - Release 1.69 -

-
    -
  • - Remove deprecation mark from reset() method (without arguments). -
  • -
  • - Fixed issue - #59. -
  • -
  • - Fixed bug with initialization of certain wrapper types in clang with -std=c++03. - See pr #64. -
  • -
-

- - Boost - Release 1.68 -

-
    -
  • - Added member function has_value() for compatibility with std::optional (issue - #52). -
  • -
  • - Added member function map() for transforming optional<T> into optional<U> using a function of type T -> U. -
  • -
  • - Added member function flat_map() for transforming optional<T> into optional<U> using a function of type T -> optonal<U>. -
  • -
-

- - Boost - Release 1.67 -

-
    -
  • - Fixed issue - #46. -
  • -
  • - Fixed -Wzero-as-null-pointer-constant warnings. -
  • -
-

- - Boost - Release 1.66 -

-
    -
  • - On newer compilers optional - is now trivially-copyable for scalar Ts. - This uses a different storage (just T - rather than aligned_storage). - We require the compiler to support defaulted functions. -
  • -
  • - Changed the implementation of operator== to get rid of the -Wmaybe-uninitialized false-positive warning - from GCC. -
  • -
-

- - Boost - Release 1.63 -

-
    -
  • - Added two new in-place constructors. They work similarly to emplace() - functions: they initialize the contained value by perfect-forwarding the - obtained arguments. One constructor always initializes the contained value, - the other based on a boolean condition. -
  • -
  • - Syntax o = - {} now correctly un-initializes - optional, just like in std::optional. -
  • -
  • - Fixed Trac #12203. -
  • -
  • - Fixed Trac #12563. -
  • -
-

- - Boost - Release 1.62 -

-
-

- - Boost - Release 1.61 -

-
    -
  • - Now boost::optional is specialized for reference - parameters. This addresses a couple of issues: -
      -
    • - the sizeof of optional - reference is that of a pointer, -
    • -
    • - some bugs connected to copying optional references are gone, -
    • -
    • - all run-time bugs caused by incorrect reference binding on some compilers - are now turned into compile-time errors, -
    • -
    • - you can swap optional references: it is like swapping pointers: shalow, - underlying objects are not affected, -
    • -
    • - optional references to abstract types work. -
    • -
    -
  • -
  • - Documented nested typedefs (Trac - #5193). -
  • -
  • - Made the perfect-forwarding constructor SFINAE-friendly, which fixes Trac #12002. - However, this only works in the newer platforms that correctly implement - C++11 <type_traits>. -
  • -
  • - Fixed Trac #10445. -
  • -
-

- - Boost - Release 1.60 -

-
  • - Changed the implementation of boost::none - again. Now it is a const object with internal linkage (as any other tag). - This fixes Trac - #11203. -
-

- - Boost - Release 1.59 -

-
    -
  • - For C++03 compilers, added 0-argument overload for member function emplace(), - and therewith removed the dependency on <boost/utility/in_place_factory.hpp>. -
  • -
  • - Fixed Trac #11241. -
  • -
-

- - Boost - Release 1.58 -

-
    -
  • - boost::none_t is no longer convertible from - literal 0. This avoids a bug - where optional<rational<int>> oi = 0; would - initialize an optional object with no contained value. -
  • -
  • - Improved the trick that prevents streaming out optional - without header optional_io.hpp - by using safe-bool idiom. This addresses Trac - #10825. -
  • -
  • - IOStream operators are now mentioned in documentation. -
  • -
  • - Added a way to manually disable move semantics: just define macro BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES. - This can be used to work around Trac - #10399. -
  • -
  • - It is no longer possible to assign optional<U> to optional<T> when U - is not assignable or convertible to T - (Trac #11087). -
  • -
  • - Value accessors now work correctly on rvalues of optional<T&> (Trac - #10839). -
  • -
-

- - Boost - Release 1.57 -

-
  • - Git pull #9: - "Supply <string> - to fix C++03 compile error on logic_error("...")". -
-

- - Boost - Release 1.56 -

-
    -
  • - Added support for rvalue references. Now optional<T> works with moveable but non-copyable - T's, -
  • -
  • - Improved swap (now uses - move operations), -
  • -
  • - Added function emplace(). This is the last of the requests from - Trac #1841, -
  • -
  • - optional is moveable, including - conditional noexcept specifications, - which make it move_if_noexcept-friendly, -
  • -
  • - Using explicit operator bool() on platforms that support it (Trac - #4227) (breaking change), -
  • -
  • - Forward declaration of operator<<(ostream&, optional - const&) - to prevent inadvertent incorrect serialization of optional objects, -
  • -
  • - Removed deprecated function reset() from examples (Trac - #9005), -
  • -
  • - Equality comparison with boost::none - does not require that T - be EqualityComparable, -
  • -
  • - Optional rvalue references are explicitly disallowed, -
  • -
  • - Binding temporaries to optional references is explicitly disallowed (breaking - change), -
  • -
  • - More ways to access the contained value, functions value(), value_or(), value_or_eval(), -
  • -
  • - Updated and reorganized documentation, added tutorial and quick guide sections. -
  • -
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/synopsis.html b/doc/html/boost_optional/synopsis.html deleted file mode 100644 index 0de90e79..00000000 --- a/doc/html/boost_optional/synopsis.html +++ /dev/null @@ -1,174 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
// In Header: <boost/optional/optional.hpp>
-
-namespace boost {
-
-template<class T>
-class optional
-{
-    public :
-
-    // (If T is of reference type, the parameters and results by reference are by value)
-
-    optional () noexcept ; R
-
-    optional ( none_t ) noexcept ; R
-
-    optional ( T const& v ) ; R
-
-    optional ( T&& v ) ; R
-
-    // [new in 1.34]
-    optional ( bool condition, T const& v ) ; R
-
-    optional ( optional const& rhs ) ; R
-
-    optional ( optional&& rhs ) noexcept(see below) ; R
-
-    template<class U> explicit optional ( optional<U> const& rhs ) ; R
-
-    template<class U> explicit optional ( optional<U>&& rhs ) ; R
-
-    template<class InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ; R
-
-    template<class TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ; R
-
-    optional& operator = ( none_t ) noexcept ; R
-
-    optional& operator = ( T const& v ) ; R
-
-    optional& operator = ( T&& v ) ; R
-
-    optional& operator = ( optional const& rhs ) ; R
-
-    optional& operator = ( optional&& rhs ) noexcept(see below) ; R
-
-    template<class U> optional& operator = ( optional<U> const& rhs ) ; R
-
-    template<class U> optional& operator = ( optional<U>&& rhs ) ; R
-
-    template<class... Args> void emplace ( Args...&& args ) ; R
-
-    template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ; R
-
-    template<class TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ; R
-
-    T const& get() const ; R
-    T&       get() ; R
-
-    T const* operator ->() const ; R
-    T*       operator ->() ; R
-
-    T const& operator *() const& ; R
-    T&       operator *() &; R
-    T&&      operator *() &&; R
-
-    T const& value() const& ; R
-    T&       value() & ; R
-    T&&      value() && ; R
-
-    template<class U> T value_or( U && v ) const& ; R
-    template<class U> T value_or( U && v ) && ; R
-
-    T const* get_ptr() const ; R
-    T*       get_ptr() ; R
-
-    explicit operator bool() const ; R
-
-    bool operator!() const noexcept ; R
-
-    // deprecated methods
-
-    // (deprecated)
-    void reset() noexcept ; R
-
-    // (deprecated)
-    void reset ( T const& ) ; R
-
-    // (deprecated)
-    bool is_initialized() const ; R
-
-    // (deprecated)
-    T const& get_value_or( T const& default ) const ; R
-};
-
-template<class T> inline bool operator == ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator != ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator <  ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator >  ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator <= ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator >= ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator == ( optional<T> const& x, none_t ) noexcept ; R
-
-template<class T> inline bool operator != ( optional<T> const& x, none_t ) noexcept ; R
-
-template<class T> inline optional<T> make_optional ( T const& v ) ; R
-
-template<class T> inline optional<T> make_optional ( bool condition, T const& v ) ; R
-
-template<class T> inline T const& get_optional_value_or ( optional<T> const& opt, T const& default ) ; R
-
-template<class T> inline T const& get ( optional<T> const& opt ) ; R
-
-template<class T> inline T& get ( optional<T> & opt ) ; R
-
-template<class T> inline T const* get ( optional<T> const* opt ) ; R
-
-template<class T> inline T* get ( optional<T>* opt ) ; R
-
-template<class T> inline T const* get_pointer ( optional<T> const& opt ) ; R
-
-template<class T> inline T* get_pointer ( optional<T> & opt ) ; R
-
-template<class T> inline void swap( optional<T>& x, optional<T>& y ) ; R
-
-} // namespace boost
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial.html b/doc/html/boost_optional/tutorial.html deleted file mode 100644 index 8f033e8c..00000000 --- a/doc/html/boost_optional/tutorial.html +++ /dev/null @@ -1,523 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- -

- Consider these functions which should return a value but which might not - have a value to return: -

-
    -
  • - (A) double sqrt(double n ); -
  • -
  • - (B) char get_async_input(); -
  • -
  • - (C) point polygon::get_any_point_effectively_inside(); -
  • -
-

- There are different approaches to the issue of not having a value to return. -

-

- A typical approach is to consider the existence of a valid return value as - a postcondition, so that if the function cannot compute the value to return, - it has either undefined behavior (and can use assert in a debug build) or - uses a runtime check and throws an exception if the postcondition is violated. - This is a reasonable choice for example, for function (A), because the lack - of a proper return value is directly related to an invalid parameter (out - of domain argument), so it is appropriate to require the callee to supply - only parameters in a valid domain for execution to continue normally. -

-

- However, function (B), because of its asynchronous nature, does not fail - just because it can't find a value to return; so it is incorrect to consider - such a situation an error and assert or throw an exception. This function - must return, and somehow, must tell the callee that it is not returning a - meaningful value. -

-

- A similar situation occurs with function (C): it is conceptually an error - to ask a null-area polygon to return a point inside - itself, but in many applications, it is just impractical for performance - reasons to treat this as an error (because detecting that the polygon has - no area might be too expensive to be required to be tested previously), and - either an arbitrary point (typically at infinity) is returned, or some efficient - way to tell the callee that there is no such point is used. -

-

- There are various mechanisms to let functions communicate that the returned - value is not valid. One such mechanism, which is quite common since it has - zero or negligible overhead, is to use a special value which is reserved - to communicate this. Classical examples of such special values are EOF, string::npos, - points at infinity, etc... -

-

- When those values exist, i.e. the return type can hold all meaningful values - plus the signal value, this mechanism - is quite appropriate and well known. Unfortunately, there are cases when - such values do not exist. In these cases, the usual alternative is either - to use a wider type, such as int - in place of char; or a compound - type, such as std::pair<point,bool>. -

-

- Returning a std::pair<T,bool>, thus attaching a boolean flag to the - result which indicates if the result is meaningful, has the advantage that - can be turned into a consistent idiom since the first element of the pair - can be whatever the function would conceptually return. For example, the - last two functions could have the following interface: -

-
std::pair<char,bool> get_async_input();
-std::pair<point,bool> polygon::get_any_point_effectively_inside();
-
-

- These functions use a consistent interface for dealing with possibly nonexistent - results: -

-
std::pair<point,bool> p = poly.get_any_point_effectively_inside();
-if ( p.second )
-    flood_fill(p.first);
-
-

- However, not only is this quite a burden syntactically, it is also error - prone since the user can easily use the function result (first element of - the pair) without ever checking if it has a valid value. -

-

- Clearly, we need a better idiom. -

-
-
- - -
- -

- In C++, we can declare an object (a variable) of type - T, and we can give this - variable an initial value (through an initializer. - (cf. 8.5)). When a declaration includes a non-empty initializer (an initial - value is given), it is said that the object has been initialized. If the - declaration uses an empty initializer (no initial value is given), and - neither default nor value initialization applies, it is said that the object - is uninitialized. Its actual value exist - but has an indeterminate initial value (cf. 8.5/11). - optional<T> - intends to formalize the notion of initialization (or lack of it) allowing - a program to test whether an object has been initialized and stating that - access to the value of an uninitialized object is undefined behavior. That - is, when a variable is declared as optional<T> and no initial value is given, the - variable is formally uninitialized. A formally uninitialized - optional object has conceptually no value at all and this situation can - be tested at runtime. It is formally undefined behavior - to try to access the value of an uninitialized optional. An uninitialized - optional can be assigned a value, in which case its initialization state - changes to initialized. Furthermore, given the formal treatment of initialization - states in optional objects, it is even possible to reset an optional to - uninitialized. -

-

- In C++ there is no formal notion of uninitialized objects, which means - that objects always have an initial value even if indeterminate. As discussed - on the previous section, this has a drawback because you need additional - information to tell if an object has been effectively initialized. One - of the typical ways in which this has been historically dealt with is via - a special value: EOF, - npos, -1, etc... This is - equivalent to adding the special value to the set of possible values of - a given type. This super set of T - plus some nil_t—where nil_t - is some stateless POD—can be modeled in modern languages as a discriminated union of T and nil_t. Discriminated - unions are often called variants. A variant has a - current type, which in our case is either T or nil_t. - Using the Boost.Variant - library, this model can be implemented in terms of boost::variant<T,nil_t>. There is precedent for a discriminated - union as a model for an optional value: the Haskell - Maybe built-in type constructor. Thus, - a discriminated union T+nil_t - serves as a conceptual foundation. -

-

- A variant<T,nil_t> follows naturally from the traditional - idiom of extending the range of possible values adding an additional sentinel - value with the special meaning of Nothing. However, - this additional Nothing value is largely irrelevant - for our purpose since our goal is to formalize the notion of uninitialized - objects and, while a special extended value can be used to convey that - meaning, it is not strictly necessary in order to do so. -

-

- The observation made in the last paragraph about the irrelevant nature - of the additional nil_t - with respect to purpose of optional<T> - suggests an alternative model: a container that either - has a value of T or nothing. -

-

- As of this writing I don't know of any precedent for a variable-size fixed-capacity - (of 1) stack-based container model for optional values, yet I believe this - is the consequence of the lack of practical implementations of such a container - rather than an inherent shortcoming of the container model. -

-

- In any event, both the discriminated-union or the single-element container - models serve as a conceptual ground for a class representing optional—i.e. - possibly uninitialized—objects. For instance, these models show the - exact semantics required for a wrapper of optional - values: -

-

- Discriminated-union: -

-
    -
  • - deep-copy semantics: copies of the - variant implies copies of the value. -
  • -
  • - deep-relational semantics: comparisons - between variants matches both current types and values -
  • -
  • - If the variant's current type is T, - it is modeling an initialized optional. -
  • -
  • - If the variant's current type is not T, - it is modeling an uninitialized optional. -
  • -
  • - Testing if the variant's current type is T - models testing if the optional is initialized -
  • -
  • - Trying to extract a T - from a variant when its current type is not T, - models the undefined behavior of trying to access the value of an uninitialized - optional -
  • -
-

- Single-element container: -

-
    -
  • - deep-copy semantics: copies of the - container implies copies of the value. -
  • -
  • - deep-relational semantics: comparisons - between containers compare container size and if match, contained value -
  • -
  • - If the container is not empty (contains an object of type T), it is modeling an initialized - optional. -
  • -
  • - If the container is empty, it is modeling an uninitialized - optional. -
  • -
  • - Testing if the container is empty models testing if the optional is - initialized -
  • -
  • - Trying to extract a T - from an empty container models the undefined behavior of trying to - access the value of an uninitialized optional -
  • -
-
-
- -

- Objects of type optional<T> are intended to be used in places where - objects of type T would - but which might be uninitialized. Hence, optional<T>'s purpose is to formalize the additional - possibly uninitialized state. From the perspective of this role, optional<T> - can have the same operational semantics of T - plus the additional semantics corresponding to this special state. As such, - optional<T> - could be thought of as a supertype of T. Of course, we can't do that in C++, - so we need to compose the desired semantics using a different mechanism. - Doing it the other way around, that is, making optional<T> a subtype of - T is not only conceptually - wrong but also impractical: it is not allowed to derive from a non-class - type, such as a built-in type. -

-

- We can draw from the purpose of optional<T> the required basic semantics: -

-
    -
  • - Default Construction: To introduce - a formally uninitialized wrapped object. -
  • -
  • - Direct Value Construction via copy: - To introduce a formally initialized wrapped object whose value is obtained - as a copy of some object. -
  • -
  • - Deep Copy Construction: To obtain - a new yet equivalent wrapped object. -
  • -
  • - Direct Value Assignment (upon initialized): - To assign a value to the wrapped object. -
  • -
  • - Direct Value Assignment (upon uninitialized): - To initialize the wrapped object with a value obtained as a copy of - some object. -
  • -
  • - Assignment (upon initialized): To - assign to the wrapped object the value of another wrapped object. -
  • -
  • - Assignment (upon uninitialized): To - initialize the wrapped object with value of another wrapped object. -
  • -
  • - Deep Relational Operations (when supported by - the type T): To compare wrapped object values taking into - account the presence of uninitialized states. -
  • -
  • - Value access: To unwrap the wrapped - object. -
  • -
  • - Initialization state query: To determine - if the object is formally initialized or not. -
  • -
  • - Swap: To exchange wrapped objects. - (with whatever exception safety guarantees are provided by T's swap). -
  • -
  • - De-initialization: To release the - wrapped object (if any) and leave the wrapper in the uninitialized - state. -
  • -
-

- Additional operations are useful, such as converting constructors and converting - assignments, in-place construction and assignment, and safe value access - via a pointer to the wrapped object or null. -

-
-
- -

- Since the purpose of optional is to allow us to use objects with a formal - uninitialized additional state, the interface could try to follow the interface - of the underlying T type - as much as possible. In order to choose the proper degree of adoption of - the native T interface, - the following must be noted: Even if all the operations supported by an - instance of type T are - defined for the entire range of values for such a type, an optional<T> - extends such a set of values with a new value for which most (otherwise - valid) operations are not defined in terms of T. -

-

- Furthermore, since optional<T> itself is merely a T - wrapper (modeling a T supertype), - any attempt to define such operations upon uninitialized optionals will - be totally artificial w.r.t. T. -

-

- This library chooses an interface which follows from T's - interface only for those operations which are well defined (w.r.t the type - T) even if any of the operands - are uninitialized. These operations include: construction, copy-construction, - assignment, swap and relational operations. -

-

- For the value access operations, which are undefined (w.r.t the type T) when the operand is uninitialized, - a different interface is chosen (which will be explained next). -

-

- Also, the presence of the possibly uninitialized state requires additional - operations not provided by T - itself which are supported by a special interface. -

-
- - Lexically-hinted - Value Access in the presence of possibly untitialized optional objects: - The operators * and -> -
-

- A relevant feature of a pointer is that it can have a null - pointer value. This is a special value - which is used to indicate that the pointer is not referring to any object - at all. In other words, null pointer values convey the notion of nonexistent - objects. -

-

- This meaning of the null pointer value allowed pointers to became a de - facto standard for handling optional objects because all you - have to do to refer to a value which you don't really have is to use a - null pointer value of the appropriate type. Pointers have been used for - decades—from the days of C APIs to modern C++ libraries—to refer - to optional (that is, possibly nonexistent) objects; particularly as optional - arguments to a function, but also quite often as optional data members. -

-

- The possible presence of a null pointer value makes the operations that - access the pointee's value possibly undefined, therefore, expressions which - use dereference and access operators, such as: ( - *p - = 2 ) and ( - p->foo() ), implicitly convey the notion of optionality, - and this information is tied to the syntax of the - expressions. That is, the presence of operators * - and -> tell by themselves - —without any additional context— that the expression will be undefined - unless the implied pointee actually exist. -

-

- Such a de facto idiom for referring to optional objects - can be formalized in the form of a concept: the OptionalPointee - concept. This concept captures the syntactic usage of operators *, -> - and contextual conversion to bool - to convey the notion of optionality. -

-

- However, pointers are good to refer - to optional objects, but not particularly good to handle the optional objects - in all other respects, such as initializing or moving/copying them. The - problem resides in the shallow-copy of pointer semantics: if you need to - effectively move or copy the object, pointers alone are not enough. The - problem is that copies of pointers do not imply copies of pointees. For - example, as was discussed in the motivation, pointers alone cannot be used - to return optional objects from a function because the object must move - outside from the function and into the caller's context. -

-

- A solution to the shallow-copy problem that is often used is to resort - to dynamic allocation and use a smart pointer to automatically handle the - details of this. For example, if a function is to optionally return an - object X, it can use shared_ptr<X> - as the return value. However, this requires dynamic allocation of X. If X - is a built-in or small POD, this technique is very poor in terms of required - resources. Optional objects are essentially values so it is very convenient - to be able to use automatic storage and deep-copy semantics to manipulate - optional values just as we do with ordinary values. Pointers do not have - this semantics, so are inappropriate for the initialization and transport - of optional values, yet are quite convenient for handling the access to - the possible undefined value because of the idiomatic aid present in the - OptionalPointee - concept incarnated by pointers. -

-
- - Optional<T> - as a model of OptionalPointee -
-

- For value access operations optional<> uses operators * - and -> to lexically warn - about the possibly uninitialized state appealing to the familiar pointer - semantics w.r.t. to null pointers. -

-
- - - - - -
[Warning]Warning

- However, it is particularly important to note that optional<> objects are not pointers. optional<> is not, and does not model, a - pointer. -

-

- For instance, optional<> does not have shallow-copy so does - not alias: two different optionals never refer to the same - value unless T itself is - a reference (but may have equivalent values). The - difference between an optional<T> and a pointer must be kept in mind, - particularly because the semantics of relational operators are different: - since optional<T> - is a value-wrapper, relational operators are deep: they compare optional - values; but relational operators for pointers are shallow: they do not - compare pointee values. As a result, you might be able to replace optional<T> - by T* - on some situations but not always. Specifically, on generic code written - for both, you cannot use relational operators directly, and must use the - template functions equal_pointees() - and less_pointees() - instead. -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/a_note_about_optional_bool_.html b/doc/html/boost_optional/tutorial/a_note_about_optional_bool_.html deleted file mode 100644 index ffd5c3dc..00000000 --- a/doc/html/boost_optional/tutorial/a_note_about_optional_bool_.html +++ /dev/null @@ -1,108 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- optional<bool> should - be used with special caution and consideration. -

-

- First, it is functionally similar to a tristate boolean (false, maybe, true) - —such as boost::tribool— - except that in a tristate boolean, the maybe state represents - a valid value, unlike the corresponding state of an uninitialized - optional<bool>. - It should be carefully considered if an optional<bool> - instead of a tribool is really - needed. -

-

- Second, although optional<> provides a contextual conversion - to bool in C++11, this falls - back to an implicit conversion on older compilers. This conversion refers - to the initialization state and not to the contained value. Using optional<bool> can - lead to subtle errors due to the implicit bool - conversion: -

-
void foo ( bool v ) ;
-void bar()
-{
-    optional<bool> v = try();
-
-    // The following intended to pass the value of 'v' to foo():
-    foo(v);
-    // But instead, the initialization state is passed
-    // due to a typo: it should have been foo(*v).
-}
-
-

- The only implicit conversion is to bool, - and it is safe in the sense that typical integral promotions don't apply - (i.e. if foo() - takes an int instead, it won't - compile). -

-

- Third, mixed comparisons with bool - work differently than similar mixed comparisons between pointers and bool, so the results might surprise you: -

-
optional<bool> oEmpty(none), oTrue(true), oFalse(false);
-
-if (oEmpty == none);  // renders true
-if (oEmpty == false); // renders false!
-if (oEmpty == true);  // renders false!
-
-if (oFalse == none);  // renders false
-if (oFalse == false); // renders true!
-if (oFalse == true);  // renders false
-
-if (oTrue == none);   // renders false
-if (oTrue == false);  // renders false
-if (oTrue == true);   // renders true
-
-

- In other words, for optional<>, the following assertion does not - hold: -

-
assert((opt == false) == (!opt));
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/design_overview.html b/doc/html/boost_optional/tutorial/design_overview.html deleted file mode 100644 index 31a192b5..00000000 --- a/doc/html/boost_optional/tutorial/design_overview.html +++ /dev/null @@ -1,184 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- -

- In C++, we can declare an object (a variable) of type - T, and we can give this - variable an initial value (through an initializer. - (cf. 8.5)). When a declaration includes a non-empty initializer (an initial - value is given), it is said that the object has been initialized. If the - declaration uses an empty initializer (no initial value is given), and - neither default nor value initialization applies, it is said that the object - is uninitialized. Its actual value exist - but has an indeterminate initial value (cf. 8.5/11). - optional<T> - intends to formalize the notion of initialization (or lack of it) allowing - a program to test whether an object has been initialized and stating that - access to the value of an uninitialized object is undefined behavior. That - is, when a variable is declared as optional<T> and no initial value is given, the - variable is formally uninitialized. A formally uninitialized - optional object has conceptually no value at all and this situation can - be tested at runtime. It is formally undefined behavior - to try to access the value of an uninitialized optional. An uninitialized - optional can be assigned a value, in which case its initialization state - changes to initialized. Furthermore, given the formal treatment of initialization - states in optional objects, it is even possible to reset an optional to - uninitialized. -

-

- In C++ there is no formal notion of uninitialized objects, which means - that objects always have an initial value even if indeterminate. As discussed - on the previous section, this has a drawback because you need additional - information to tell if an object has been effectively initialized. One - of the typical ways in which this has been historically dealt with is via - a special value: EOF, - npos, -1, etc... This is - equivalent to adding the special value to the set of possible values of - a given type. This super set of T - plus some nil_t—where nil_t - is some stateless POD—can be modeled in modern languages as a discriminated union of T and nil_t. Discriminated - unions are often called variants. A variant has a - current type, which in our case is either T or nil_t. - Using the Boost.Variant - library, this model can be implemented in terms of boost::variant<T,nil_t>. There is precedent for a discriminated - union as a model for an optional value: the Haskell - Maybe built-in type constructor. Thus, - a discriminated union T+nil_t - serves as a conceptual foundation. -

-

- A variant<T,nil_t> follows naturally from the traditional - idiom of extending the range of possible values adding an additional sentinel - value with the special meaning of Nothing. However, - this additional Nothing value is largely irrelevant - for our purpose since our goal is to formalize the notion of uninitialized - objects and, while a special extended value can be used to convey that - meaning, it is not strictly necessary in order to do so. -

-

- The observation made in the last paragraph about the irrelevant nature - of the additional nil_t - with respect to purpose of optional<T> - suggests an alternative model: a container that either - has a value of T or nothing. -

-

- As of this writing I don't know of any precedent for a variable-size fixed-capacity - (of 1) stack-based container model for optional values, yet I believe this - is the consequence of the lack of practical implementations of such a container - rather than an inherent shortcoming of the container model. -

-

- In any event, both the discriminated-union or the single-element container - models serve as a conceptual ground for a class representing optional—i.e. - possibly uninitialized—objects. For instance, these models show the - exact semantics required for a wrapper of optional - values: -

-

- Discriminated-union: -

-
    -
  • - deep-copy semantics: copies of the - variant implies copies of the value. -
  • -
  • - deep-relational semantics: comparisons - between variants matches both current types and values -
  • -
  • - If the variant's current type is T, - it is modeling an initialized optional. -
  • -
  • - If the variant's current type is not T, - it is modeling an uninitialized optional. -
  • -
  • - Testing if the variant's current type is T - models testing if the optional is initialized -
  • -
  • - Trying to extract a T - from a variant when its current type is not T, - models the undefined behavior of trying to access the value of an uninitialized - optional -
  • -
-

- Single-element container: -

-
    -
  • - deep-copy semantics: copies of the - container implies copies of the value. -
  • -
  • - deep-relational semantics: comparisons - between containers compare container size and if match, contained value -
  • -
  • - If the container is not empty (contains an object of type T), it is modeling an initialized - optional. -
  • -
  • - If the container is empty, it is modeling an uninitialized - optional. -
  • -
  • - Testing if the container is empty models testing if the optional is - initialized -
  • -
  • - Trying to extract a T - from an empty container models the undefined behavior of trying to - access the value of an uninitialized optional -
  • -
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/design_overview/the_interface.html b/doc/html/boost_optional/tutorial/design_overview/the_interface.html deleted file mode 100644 index 0bb4a963..00000000 --- a/doc/html/boost_optional/tutorial/design_overview/the_interface.html +++ /dev/null @@ -1,187 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Since the purpose of optional is to allow us to use objects with a formal - uninitialized additional state, the interface could try to follow the interface - of the underlying T type - as much as possible. In order to choose the proper degree of adoption of - the native T interface, - the following must be noted: Even if all the operations supported by an - instance of type T are - defined for the entire range of values for such a type, an optional<T> - extends such a set of values with a new value for which most (otherwise - valid) operations are not defined in terms of T. -

-

- Furthermore, since optional<T> itself is merely a T - wrapper (modeling a T supertype), - any attempt to define such operations upon uninitialized optionals will - be totally artificial w.r.t. T. -

-

- This library chooses an interface which follows from T's - interface only for those operations which are well defined (w.r.t the type - T) even if any of the operands - are uninitialized. These operations include: construction, copy-construction, - assignment, swap and relational operations. -

-

- For the value access operations, which are undefined (w.r.t the type T) when the operand is uninitialized, - a different interface is chosen (which will be explained next). -

-

- Also, the presence of the possibly uninitialized state requires additional - operations not provided by T - itself which are supported by a special interface. -

-
- - Lexically-hinted - Value Access in the presence of possibly uninitialized optional objects: - The operators * and -> -
-

- A relevant feature of a pointer is that it can have a null - pointer value. This is a special value - which is used to indicate that the pointer is not referring to any object - at all. In other words, null pointer values convey the notion of nonexistent - objects. -

-

- This meaning of the null pointer value allowed pointers to became a de - facto standard for handling optional objects because all you - have to do to refer to a value which you don't really have is to use a - null pointer value of the appropriate type. Pointers have been used for - decades—from the days of C APIs to modern C++ libraries—to refer - to optional (that is, possibly nonexistent) objects; particularly as optional - arguments to a function, but also quite often as optional data members. -

-

- The possible presence of a null pointer value makes the operations that - access the pointee's value possibly undefined, therefore, expressions which - use dereference and access operators, such as: ( - *p - = 2 ) and ( - p->foo() ), implicitly convey the notion of optionality, - and this information is tied to the syntax of the - expressions. That is, the presence of operators * - and -> tell by themselves - —without any additional context— that the expression will be undefined - unless the implied pointee actually exist. -

-

- Such a de facto idiom for referring to optional objects - can be formalized in the form of a concept: the OptionalPointee concept. This - concept captures the syntactic usage of operators *, - -> and contextual conversion - to bool to convey the notion - of optionality. -

-

- However, pointers are good to refer - to optional objects, but not particularly good to handle the optional objects - in all other respects, such as initializing or moving/copying them. The - problem resides in the shallow-copy of pointer semantics: if you need to - effectively move or copy the object, pointers alone are not enough. The - problem is that copies of pointers do not imply copies of pointees. For - example, as was discussed in the motivation, pointers alone cannot be used - to return optional objects from a function because the object must move - outside from the function and into the caller's context. -

-

- A solution to the shallow-copy problem that is often used is to resort - to dynamic allocation and use a smart pointer to automatically handle the - details of this. For example, if a function is to optionally return an - object X, it can use shared_ptr<X> - as the return value. However, this requires dynamic allocation of X. If X - is a built-in or small POD, this technique is very poor in terms of required - resources. Optional objects are essentially values so it is very convenient - to be able to use automatic storage and deep-copy semantics to manipulate - optional values just as we do with ordinary values. Pointers do not have - this semantics, so are inappropriate for the initialization and transport - of optional values, yet are quite convenient for handling the access to - the possible undefined value because of the idiomatic aid present in the - OptionalPointee - concept incarnated by pointers. -

-
- - Optional<T> - as a model of OptionalPointee -
-

- For value access operations optional<> uses operators * - and -> to lexically warn - about the possibly uninitialized state appealing to the familiar pointer - semantics w.r.t. to null pointers. -

-
- - - - - -
[Caution]Caution

- However, it is particularly important to note that optional<> objects are not pointers. optional<> is not, and does not model, a - pointer. -

-

- For instance, optional<> does not have shallow-copy so does - not alias: two different optionals never refer to the same - value unless T itself is - a reference (but may have equivalent values). The - difference between an optional<T> and a pointer must be kept in mind, - particularly because the semantics of relational operators are different: - since optional<T> - is a value-wrapper, relational operators are deep: they compare optional - values; but relational operators for pointers are shallow: they do not - compare pointee values. As a result, you might be able to replace optional<T> - by T* - on some situations but not always. Specifically, on generic code written - for both, you cannot use relational operators directly, and must use the - template functions equal_pointees() - and less_pointees() - instead. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/design_overview/the_semantics.html b/doc/html/boost_optional/tutorial/design_overview/the_semantics.html deleted file mode 100644 index dbc1ab02..00000000 --- a/doc/html/boost_optional/tutorial/design_overview/the_semantics.html +++ /dev/null @@ -1,121 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Objects of type optional<T> are intended to be used in places where - objects of type T would - but which might be uninitialized. Hence, optional<T>'s purpose is to formalize the additional - possibly uninitialized state. From the perspective of this role, optional<T> - can have the same operational semantics of T - plus the additional semantics corresponding to this special state. As such, - optional<T> - could be thought of as a supertype of T. Of course, we can't do that in C++, - so we need to compose the desired semantics using a different mechanism. - Doing it the other way around, that is, making optional<T> a subtype of - T is not only conceptually - wrong but also impractical: it is not allowed to derive from a non-class - type, such as a built-in type. -

-

- We can draw from the purpose of optional<T> the required basic semantics: -

-
    -
  • - Default Construction: To introduce - a formally uninitialized wrapped object. -
  • -
  • - Direct Value Construction via copy: - To introduce a formally initialized wrapped object whose value is obtained - as a copy of some object. -
  • -
  • - Deep Copy Construction: To obtain - a new yet equivalent wrapped object. -
  • -
  • - Direct Value Assignment (upon initialized): - To assign a value to the wrapped object. -
  • -
  • - Direct Value Assignment (upon uninitialized): - To initialize the wrapped object with a value obtained as a copy of - some object. -
  • -
  • - Assignment (upon initialized): To - assign to the wrapped object the value of another wrapped object. -
  • -
  • - Assignment (upon uninitialized): To - initialize the wrapped object with value of another wrapped object. -
  • -
  • - Deep Relational Operations (when supported by - the type T): To compare wrapped object values taking into - account the presence of uninitialized states. -
  • -
  • - Value access: To unwrap the wrapped - object. -
  • -
  • - Initialization state query: To determine - if the object is formally initialized or not. -
  • -
  • - Swap: To exchange wrapped objects. - (with whatever exception safety guarantees are provided by T's swap). -
  • -
  • - De-initialization: To release the - wrapped object (if any) and leave the wrapper in the uninitialized - state. -
  • -
-

- Additional operations are useful, such as converting constructors and converting - assignments, in-place construction and assignment, and safe value access - via a pointer to the wrapped object or null. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/exception_safety_guarantees.html b/doc/html/boost_optional/tutorial/exception_safety_guarantees.html deleted file mode 100644 index c75dab07..00000000 --- a/doc/html/boost_optional/tutorial/exception_safety_guarantees.html +++ /dev/null @@ -1,175 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- This library assumes that T's - destructor does not throw exceptions. If it does, the behaviour of many operations - on optional<T> is - undefined. -

-

- The following mutating operations never throw exceptions: -

-
    -
  • - optional<T>::operator= ( none_t - ) noexcept -
  • -
  • - optional<T>::reset() noexcept -
  • -
-

- In addition, the following constructors and the destructor never throw exceptions: -

-
    -
  • - optional<T>::optional() - noexcept -
  • -
  • - optional<T>::optional( - none_t ) - noexcept -
  • -
-

- Regarding the following assignment functions: -

-
    -
  • - optional<T>::operator= ( optional<T> const& ) -
  • -
  • - optional<T>::operator= ( T const& ) -
  • -
  • - template<class U> optional<T>::operator= ( optional<U> const& ) -
  • -
  • - template<class InPlaceFactory> optional<T>::operator= ( InPlaceFactory - const& - ) -
  • -
  • - template<class TypedInPlaceFactory> optional<T>::operator= ( TypedInPlaceFactory - const& - ) -
  • -
  • - optional<T>::reset( T const& ) -
  • -
-

- They forward calls to the corresponding T's - constructors or assignments (depending on whether the optional object is - initialized or not); so if both T's - constructor and the assignment provide strong exception safety guarantee, - optional<T>'s - assignment also provides strong exception safety guarantee; otherwise we - only get the basic guarantee. Additionally, if both involved T's constructor and the assignment never - throw, optional<T>'s - assignment also never throws. -

-

- Unless T's constructor or - assignment throws, assignments to optional<T> - do not throw anything else on its own. A throw during assignment never changes - the initialization state of any optional object involved: -

-
optional<T> opt1(val1);
-optional<T> opt2(val2);
-assert(opt1);
-assert(opt2);
-
-try
-{
-  opt1 = opt2; // throws
-}
-catch(...)
-{
-  assert(opt1);
-  assert(opt2);
-}
-
-

- This also applies to move assignments/constructors. However, move operations - are made no-throw more often. -

-

- Operation emplace provides - basic exception safety guarantee. If it throws, the optional object becomes - uninitialized regardless of its initial state, and its previous contained - value (if any) is destroyed. It doesn't call any assignment or move/copy - constructor on T. -

-
- - Swap -
-

- Unless swap on optional is - customized, its primary implementation forwards calls to T's - swap or move constructor - (depending on the initialization state of the optional objects). Thus, if - both T's swap - and move constructor never throw, swap - on optional<T> never - throws. similarly, if both T's - swap and move constructor - offer strong guarantee, swap - on optional<T> also - offers a strong guarantee. -

-

- In case swap on optional - is customized, the call to T's - move constructor are replaced with the calls to T's - default constructor followed by swap. - (This is more useful on older compilers that do not support move semantics, - when one wants to acheive stronger exception safety guarantees.) In this - case the exception safety guarantees for swap - are reliant on the guarantees of T's - swap and default constructor -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/gotchas.html b/doc/html/boost_optional/tutorial/gotchas.html deleted file mode 100644 index c11cad2f..00000000 --- a/doc/html/boost_optional/tutorial/gotchas.html +++ /dev/null @@ -1,112 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- -

- optional<bool> - should be used with special caution and consideration. -

-

- First, it is functionally similar to a tristate boolean (false, maybe, - true) —such as boost::tribool— - except that in a tristate boolean, the maybe state represents - a valid value, unlike the corresponding state of an uninitialized - optional<bool>. - It should be carefully considered if an optional<bool> instead of a tribool - is really needed. -

-

- Second, although optional<> provides a contextual conversion - to bool in C++11, this falls - back to an implicit conversion on older compilers. This conversion refers - to the initialization state and not to the contained value. Using optional<bool> - can lead to subtle errors due to the implicit bool - conversion: -

-
void foo ( bool v ) ;
-void bar()
-{
-    optional<bool> v = try();
-
-    // The following intended to pass the value of 'v' to foo():
-    foo(v);
-    // But instead, the initialization state is passed
-    // due to a typo: it should have been foo(*v).
-}
-
-

- The only implicit conversion is to bool, - and it is safe in the sense that typical integral promotions don't apply - (i.e. if foo() - takes an int instead, it won't - compile). -

-

- Third, mixed comparisons with bool - work differently than similar mixed comparisons between pointers and bool, so the results might surprise you: -

-
optional<bool> oEmpty(none), oTrue(true), oFalse(false);
-
-if (oEmpty == none);  // renders true
-if (oEmpty == false); // renders false!
-if (oEmpty == true);  // renders false!
-
-if (oFalse == none);  // renders false
-if (oFalse == false); // renders true!
-if (oFalse == true);  // renders false
-
-if (oTrue == none);   // renders false
-if (oTrue == false);  // renders false
-if (oTrue == true);   // renders true
-
-

- In other words, for optional<>, the following assertion does not - hold: -

-
assert((opt == false) == (!opt));
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html b/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html deleted file mode 100644 index 240ee0fc..00000000 --- a/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html +++ /dev/null @@ -1,77 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Sometimes on GCC compilers below version 5.1 you may get an -Wmaybe-uninitialized - warning when copiling with option -02 on a perfectly valid boost::optional usage. For instance in this - program: -

-
#include <boost/optional.hpp>
-
-boost::optional<int> getitem();
-
-int main(int argc, const char *[])
-{
-  boost::optional<int> a = getitem();
-  boost::optional<int> b;
-
-  if (argc > 0)
-    b = argc;
-
-  if (a != b)
-    return 1;
-
-  return 0;
-}
-
-

- This is a bug in the compiler. As a workaround (provided in this - Stack Overflow question) use the following way of initializing - an optional containing no value: -

-
boost::optional<int> b = boost::make_optional(false, int());
-
-

- This is obviously redundant, but makes the warning disappear. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/gotchas/mixed_relational_comparisons.html b/doc/html/boost_optional/tutorial/gotchas/mixed_relational_comparisons.html deleted file mode 100644 index 8d25f0d3..00000000 --- a/doc/html/boost_optional/tutorial/gotchas/mixed_relational_comparisons.html +++ /dev/null @@ -1,59 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Because T is convertible - to optional<T> - and because opiotnal<T> - is LessThanComparable when T is LessThanComparable, you can sometimes - get an unexpected runtime result where you would rather expect a compiler - error: -

-
optional<double> Flight_plan::weight(); // sometimes no weight can be returned
-
-bool is_aircraft_too_heavy(Flight_plan const& p)
-{
-   return p.weight() > p.aircraft().max_weight(); // compiles!
-}                                                 // returns false when the optional contains no value 
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/gotchas/moved_from__optional_.html b/doc/html/boost_optional/tutorial/gotchas/moved_from__optional_.html deleted file mode 100644 index 7a4e4448..00000000 --- a/doc/html/boost_optional/tutorial/gotchas/moved_from__optional_.html +++ /dev/null @@ -1,63 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- When an optional object that contains a value is moved from (is a source - of move constructor or assignment) it still contains a value and its contained - value is left in a moved-from state. This can be illustrated with the following - example. -

-
optional<std::unique_ptr<int>> opi {std::make_unique<int>(1)};
-optional<std::unique_ptr<int>> opj = std::move(opi);
-assert (opi);
-assert (*opi == nullptr);
-
-

- Quite a lot of people expect that when an object that contains a value - is moved from, its contained value should be destroyed. This is not so, - for performance reasons. Current semantics allow the implementation of - boost::opiotnal<T> - to be trivially copyable when T - is trivial. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/in_place_factories.html b/doc/html/boost_optional/tutorial/in_place_factories.html deleted file mode 100644 index 5f0c4261..00000000 --- a/doc/html/boost_optional/tutorial/in_place_factories.html +++ /dev/null @@ -1,197 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- One of the typical problems with wrappers and containers is that their interfaces - usually provide an operation to initialize or assign the contained object - as a copy of some other object. This not only requires the underlying type - to be CopyConstructible, but also requires - the existence of a fully constructed object, often temporary, just to follow - the copy from: -

-
struct X
-{
-    X ( int, std::string ) ;
-} ;
-
-class W
-{
-    X wrapped_ ;
-
-    public:
-
-    W ( X const& x ) : wrapped_(x) {}
-} ;
-
-void foo()
-{
-    // Temporary object created.
-    W ( X(123,"hello") ) ;
-}
-
-

- A solution to this problem is to support direct construction of the contained - object right in the container's storage. In this scheme, the user only needs - to supply the arguments to the constructor to use in the wrapped object construction. -

-
class W
-{
-    X wrapped_ ;
-
-    public:
-
-    W ( X const& x ) : wrapped_(x) {}
-    W ( int a0, std::string a1) : wrapped_(a0,a1) {}
-} ;
-
-void foo()
-{
-    // Wrapped object constructed in-place
-    // No temporary created.
-    W (123,"hello") ;
-}
-
-

- A limitation of this method is that it doesn't scale well to wrapped objects - with multiple constructors nor to generic code were the constructor overloads - are unknown. -

-

- The solution presented in this library is the family of InPlaceFactories - and TypedInPlaceFactories. These factories - are a family of classes which encapsulate an increasing number of arbitrary - constructor parameters and supply a method to construct an object of a given - type using those parameters at an address specified by the user via placement - new. -

-

- For example, one member of this family looks like: -

-
template<class T,class A0, class A1>
-class TypedInPlaceFactory2
-{
-    A0 m_a0 ; A1 m_a1 ;
-
-    public:
-
-    TypedInPlaceFactory2( A0 const& a0, A1 const& a1 ) : m_a0(a0), m_a1(a1) {}
-
-    void construct ( void* p ) { new (p) T(m_a0,m_a1) ; }
- } ;
-
-

- A wrapper class aware of this can use it as: -

-
class W
-{
-    X wrapped_ ;
-
-    public:
-
-    W ( X const& x ) : wrapped_(x) {}
-    W ( TypedInPlaceFactory2 const& fac ) { fac.construct(&wrapped_) ; }
-} ;
-
-void foo()
-{
-    // Wrapped object constructed in-place via a TypedInPlaceFactory.
-    // No temporary created.
-    W ( TypedInPlaceFactory2<X,int,std::string>(123,"hello")) ;
-}
-
-

- The factories are divided in two groups: -

-
    -
  • - TypedInPlaceFactories: those which - take the target type as a primary template parameter. -
  • -
  • - InPlaceFactories: those with a - template construct(void*) - member function taking the target type. -
  • -
-

- Within each group, all the family members differ only in the number of parameters - allowed. -

-

- This library provides an overloaded set of helper template functions to construct - these factories without requiring unnecessary template parameters: -

-
template<class A0,...,class AN>
-InPlaceFactoryN <A0,...,AN> in_place ( A0 const& a0, ..., AN const& aN) ;
-
-template<class T,class A0,...,class AN>
-TypedInPlaceFactoryN <T,A0,...,AN> in_place ( T const& a0, A0 const& a0, ..., AN const& aN) ;
-
-

- In-place factories can be used generically by the wrapper and user as follows: -

-
class W
-{
-    X wrapped_ ;
-
-    public:
-
-    W ( X const& x ) : wrapped_(x) {}
-
-    template< class InPlaceFactory >
-    W ( InPlaceFactory const& fac ) { fac.template <X>construct(&wrapped_) ; }
-
-} ;
-
-void foo()
-{
-    // Wrapped object constructed in-place via a InPlaceFactory.
-    // No temporary created.
-    W ( in_place(123,"hello") ) ;
-}
-
-

- The factories are implemented in the headers: in_place_factory.hpp - and typed_in_place_factory.hpp -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/io_operators.html b/doc/html/boost_optional/tutorial/io_operators.html deleted file mode 100644 index 713b2838..00000000 --- a/doc/html/boost_optional/tutorial/io_operators.html +++ /dev/null @@ -1,87 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- It is possible to use optional<T> - with IO streams, provided that T - can be used with streams. IOStream operators are defined in a separate header. -

-

-

-
#include <iostream>
-#include <boost/optional/optional_io.hpp>
-
-int main()
-{
-  boost::optional<int> o1 = 1, oN = boost::none;
-  std::cout << o1;
-  std::cin >> oN;
-}
-
-

-

-

- The current implementation does not guarantee any particular output. What - it guarantees is that if streaming out and then back in T - gives the same value, then streaming out and then back in optional<T> - will also give back the same result: -

-

-

-
#include <cassert>
-#include <sstream>
-#include <boost/optional/optional_io.hpp>
-
-int main()
-{
-  boost::optional<int> o1 = 1, oN = boost::none;
-  boost::optional<int> x1, x2;
-  std::stringstream s;
-  s << o1 << oN;
-  s >> x1 >> x2;
-  assert (o1 == x1);
-  assert (oN == x2);
-}
-
-

-

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/motivation.html b/doc/html/boost_optional/tutorial/motivation.html deleted file mode 100644 index 3b9f43cf..00000000 --- a/doc/html/boost_optional/tutorial/motivation.html +++ /dev/null @@ -1,129 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Consider these functions which should return a value but which might not - have a value to return: -

-
    -
  • - (A) double sqrt(double n ); -
  • -
  • - (B) char get_async_input(); -
  • -
  • - (C) point polygon::get_any_point_effectively_inside(); -
  • -
-

- There are different approaches to the issue of not having a value to return. -

-

- A typical approach is to consider the existence of a valid return value as - a postcondition, so that if the function cannot compute the value to return, - it has either undefined behavior (and can use assert in a debug build) or - uses a runtime check and throws an exception if the postcondition is violated. - This is a reasonable choice for example, for function (A), because the lack - of a proper return value is directly related to an invalid parameter (out - of domain argument), so it is appropriate to require the callee to supply - only parameters in a valid domain for execution to continue normally. -

-

- However, function (B), because of its asynchronous nature, does not fail - just because it can't find a value to return; so it is incorrect to consider - such a situation an error and assert or throw an exception. This function - must return, and somehow, must tell the callee that it is not returning a - meaningful value. -

-

- A similar situation occurs with function (C): it is conceptually an error - to ask a null-area polygon to return a point inside - itself, but in many applications, it is just impractical for performance - reasons to treat this as an error (because detecting that the polygon has - no area might be too expensive to be required to be tested previously), and - either an arbitrary point (typically at infinity) is returned, or some efficient - way to tell the callee that there is no such point is used. -

-

- There are various mechanisms to let functions communicate that the returned - value is not valid. One such mechanism, which is quite common since it has - zero or negligible overhead, is to use a special value which is reserved - to communicate this. Classical examples of such special values are EOF, string::npos, - points at infinity, etc... -

-

- When those values exist, i.e. the return type can hold all meaningful values - plus the signal value, this mechanism - is quite appropriate and well known. Unfortunately, there are cases when - such values do not exist. In these cases, the usual alternative is either - to use a wider type, such as int - in place of char; or a compound - type, such as std::pair<point,bool>. -

-

- Returning a std::pair<T,bool>, thus attaching a boolean flag to the - result which indicates if the result is meaningful, has the advantage that - can be turned into a consistent idiom since the first element of the pair - can be whatever the function would conceptually return. For example, the - last two functions could have the following interface: -

-
std::pair<char,bool> get_async_input();
-std::pair<point,bool> polygon::get_any_point_effectively_inside();
-
-

- These functions use a consistent interface for dealing with possibly nonexistent - results: -

-
std::pair<point,bool> p = poly.get_any_point_effectively_inside();
-if ( p.second )
-    flood_fill(p.first);
-
-

- However, not only is this quite a burden syntactically, it is also error - prone since the user can easily use the function result (first element of - the pair) without ever checking if it has a valid value. -

-

- Clearly, we need a better idiom. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/optional_references.html b/doc/html/boost_optional/tutorial/optional_references.html deleted file mode 100644 index fb0fb564..00000000 --- a/doc/html/boost_optional/tutorial/optional_references.html +++ /dev/null @@ -1,117 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- -

- This library allows the template parameter T - to be of reference type: T&, and to some extent, T const&. -

-

- However, since references are not real objects some restrictions apply - and some operations are not available in this case: -

-
    -
  • - Converting constructors -
  • -
  • - Converting assignment -
  • -
  • - InPlace construction -
  • -
  • - InPlace assignment -
  • -
  • - Value-access via pointer -
  • -
-

- Also, even though optional<T&> treats it wrapped pseudo-object - much as a real value, a true real reference is stored so aliasing will - ocurr: -

-
    -
  • - Copies of optional<T&> will copy the references but - all these references will nonetheless refer to the same object. -
  • -
  • - Value-access will actually provide access to the referenced object - rather than the reference itself. -
  • -
-
- - - - - -
[Caution]Caution

- On compilers that do not conform to Standard C++ rules of reference binding, - some operations on optional references are disabled in order to prevent - subtle bugs. For more details see Dependencies - and Portability section. -

-
- - Rvalue - references -
-

- Rvalue references and lvalue references to const have the ability in C++ - to extend the life time of a temporary they bind to. Optional references - do not have this capability, therefore to avoid surprising effects it is - not possible to initialize an optional references from a temporary. Optional - rvalue references are disabled altogether. Also, the initialization and - assignment of an optional reference to const from rvalue reference is disabled. -

-
const int& i = 1;            // legal
-optional<const int&> oi = 1; // illegal
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html b/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html deleted file mode 100644 index 6e827d09..00000000 --- a/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html +++ /dev/null @@ -1,147 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- If you assign to an uninitialized optional<T&> the effect is to bind (for the - first time) to the object. Clearly, there is no other choice. -

-
int x = 1 ;
-int& rx = x ;
-optional<int&> ora ;
-optional<int&> orb(x) ;
-ora = orb ; // now 'ora' is bound to 'x' through 'rx'
-*ora = 2 ; // Changes value of 'x' through 'ora'
-assert(x==2);
-
-

- If you assign to a bare C++ reference, the assignment is forwarded to the - referenced object; its value changes but the reference is never rebound. -

-
int a = 1 ;
-int& ra = a ;
-int b = 2 ;
-int& rb = b ;
-ra = rb ; // Changes the value of 'a' to 'b'
-assert(a==b);
-b = 3 ;
-assert(ra!=b); // 'ra' is not rebound to 'b'
-
-

- Now, if you assign to an initialized optional<T&>, - the effect is to rebind to the new object - instead of assigning the referee. This is unlike bare C++ references. -

-
int a = 1 ;
-int b = 2 ;
-int& ra = a ;
-int& rb = b ;
-optional<int&> ora(ra) ;
-optional<int&> orb(rb) ;
-ora = orb ; // 'ora' is rebound to 'b'
-*ora = 3 ; // Changes value of 'b' (not 'a')
-assert(a==1);
-assert(b==3);
-
-
- - Rationale -
-

- Rebinding semantics for the assignment of initialized - optional references has - been chosen to provide consistency among initialization - states even at the expense of lack of consistency with the semantics - of bare C++ references. It is true that optional<U> strives to behave as much as possible - as U does whenever it is - initialized; but in the case when U - is T&, - doing so would result in inconsistent behavior w.r.t to the lvalue initialization - state. -

-

- Imagine optional<T&> - forwarding assignment to the referenced object (thus changing the referenced - object value but not rebinding), and consider the following code: -

-
optional<int&> a = get();
-int x = 1 ;
-int& rx = x ;
-optional<int&> b(rx);
-a = b ;
-
-

- What does the assignment do? -

-

- If a is uninitialized, - the answer is clear: it binds to x - (we now have another reference to x). - But what if a is already - initialized? it would change the value of the referenced - object (whatever that is); which is inconsistent with the other possible - case. -

-

- If optional<T&> - would assign just like T& does, you would never be able to use - Optional's assignment without explicitly handling the previous initialization - state unless your code is capable of functioning whether after the assignment, - a aliases the same object - as b or not. -

-

- That is, you would have to discriminate in order to be consistent. -

-

- If in your code rebinding to another object is not an option, then it is - very likely that binding for the first time isn't either. In such case, - assignment to an uninitialized optional<T&> shall be prohibited. It is quite - possible that in such a scenario it is a precondition that the lvalue must - be already initialized. If it isn't, then binding for the first time is - OK while rebinding is not which is IMO very unlikely. In such a scenario, - you can assign the value itself directly, as in: -

-
assert(!!opt);
-*opt=value;
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/performance_considerations.html b/doc/html/boost_optional/tutorial/performance_considerations.html deleted file mode 100644 index 19fe1ed8..00000000 --- a/doc/html/boost_optional/tutorial/performance_considerations.html +++ /dev/null @@ -1,265 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Technical details aside, the memory layout of optional<T> - for a generic T is more-less - this: -

-
template <typename T>
-class optional
-{
-  bool _initialized;
-  std::aligned_storage_t<sizeof(t), alignof(T)> _storage;
-};
-
-

- Lifetime of the T inside - _storage is manually controlled - with placement-news and pseudo-destructor - calls. However, for scalar Ts - we use a different way of storage, by simply holding a T: -

-
template <typename T>
-class optional
-{
-  bool _initialized;
-  T _storage;
-};
-
-

- We call it a direct storage. This makes optional<T> a - trivially-copyable type for scalar Ts. - This only works for compilers that support defaulted functions (including - defaulted move assignment and constructor). On compilers without defaulted - functions we still use the direct storage, but optional<T> - is no longer recognized as trivially-copyable. Apart from scalar types, we - leave the programmer a way of customizing her type, so that it is reconized - by optional as candidate - for optimized storage, by specializing type trait boost::opitonal_config::optional_uses_direct_storage_for: -

-
struct X // not trivial
-{
-  X() {}
-};
-
-namespace boost { namespace optional_config {
-
-  template <> struct optional_uses_direct_storage_for<X> : boost::true_type {};
-
-}}
-
-
- - Controlling - the size -
-

- For the purpose of the following analysis, considering memory layouts, we - can think of it as: -

-
template <typename T>
-class optional
-{
-  bool _initialized;
-  T _storage;
-};
-
-

- Given type optional<int>, and - assuming that sizeof(int) == - 4, we will get sizeof(optional<int>) - == 8. - This is so because of the alignment rules, for our two members we get the - following alignment: -

-

- opt_align1 -

-

- This means you can fit twice as many ints - as optional<int>s into - the same space of memory. Therefore, if the size of the objects is critical - for your application (e.g., because you want to utilize your CPU cache in - order to gain performance) and you have determined you are willing to trade - the code clarity, it is recommended that you simply go with type int and use some 'magic value' to represent - not-an-int, or use something like markable library. -

-

- Even if you cannot spare any value of int - to represent not-an-int (e.g., because every value is - useful, or you do want to signal not-an-int explicitly), - at least for Trivial types - you should consider storing the value and the bool - flag representing the null-state separately. Consider - the following class: -

-
struct Record
-{
-  optional<int> _min;
-  optional<int> _max;
-};
-
-

- Its memory layout can be depicted as follows: -

-

- opt_align2 -

-

- This is exactly the same as if we had the following members: -

-
struct Record
-{
-  bool _has_min;
-  int  _min;
-  bool _has_max;
-  int  _max;
-};
-
-

- But when they are stored separately, we at least have an option to reorder - them like this: -

-
struct Record
-{
-  bool _has_min;
-  bool _has_max;
-  int  _min;
-  int  _max;
-};
-
-

- Which gives us the following layout (and smaller total size): -

-

- opt_align3 -

-

- Sometimes it requires detailed consideration what data we make optional. - In our case above, if we determine that both minimum and maximum value can - be provided or not provided together, but one is never provided without the - other, we can make only one optional memebr: -

-
struct Limits
-{
-  int  _min;
-  int  _max;
-};
-
-struct Record
-{
-  optional<Limits> _limits;
-};
-
-

- This would give us the following layout: -

-

- opt_align4 -

-
- - Optional - function parameters -
-

- Having function parameters of type const - optional<T>& - may incur certain unexpected run-time cost connected to copy construction - of T. Consider the following - code. -

-
void fun(const optional<Big>& v)
-{
-  if (v) doSomethingWith(*v);
-  else   doSomethingElse();
-}
-
-int main()
-{
-  optional<Big> ov;
-  Big v;
-  fun(none);
-  fun(ov); // no copy
-  fun(v);  // copy constructor of Big
-}
-
-

- No copy elision or move semantics can save us from copying type Big here. Not that we need any copy, but - this is how optional works. - In order to avoid copying in this case, one could provide second overload - of fun: -

-
void fun(const Big& v)
-{
-  doSomethingWith(v);
-}
-
-int main()
-{
-  optional<Big> ov;
-  Big v;
-  fun(ov); // no copy
-  fun(v);  // no copy: second overload selected
-}
-
-

- Alternatively, you could consider using an optional reference instead: -

-
void fun(optional<const Big&> v) // note where the reference is
-{
-  if (v) doSomethingWith(*v);
-  else   doSomethingElse();
-}
-
-int main()
-{
-  optional<Big> ov;
-  Big v;
-  fun(none);
-  fun(ov); // doesn't compile
-  fun(v);  // no copy
-}
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html b/doc/html/boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html deleted file mode 100644 index ee693eee..00000000 --- a/doc/html/boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html +++ /dev/null @@ -1,149 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- If you assign to an uninitialized optional<T&> - the effect is to bind (for the first time) to the object. Clearly, there - is no other choice. -

-
int x = 1 ;
-int& rx = x ;
-optional<int&> ora ;
-optional<int&> orb(x) ;
-ora = orb ; // now 'ora' is bound to 'x' through 'rx'
-*ora = 2 ; // Changes value of 'x' through 'ora'
-assert(x==2);
-
-

- If you assign to a bare C++ reference, the assignment is forwarded to the - referenced object; its value changes but the reference is never rebound. -

-
int a = 1 ;
-int& ra = a ;
-int b = 2 ;
-int& rb = b ;
-ra = rb ; // Changes the value of 'a' to 'b'
-assert(a==b);
-b = 3 ;
-assert(ra!=b); // 'ra' is not rebound to 'b'
-
-

- Now, if you assign to an initialized optional<T&>, - the effect is to rebind to the new object - instead of assigning the referee. This is unlike bare C++ references. -

-
int a = 1 ;
-int b = 2 ;
-int& ra = a ;
-int& rb = b ;
-optional<int&> ora(ra) ;
-optional<int&> orb(rb) ;
-ora = orb ; // 'ora' is rebound to 'b'
-*ora = 3 ; // Changes value of 'b' (not 'a')
-assert(a==1);
-assert(b==3);
-
-
- - Rationale -
-

- Rebinding semantics for the assignment of initialized - optional references has been - chosen to provide consistency among initialization - states even at the expense of lack of consistency with the semantics - of bare C++ references. It is true that optional<U> - strives to behave as much as possible as U - does whenever it is initialized; but in the case when U - is T&, - doing so would result in inconsistent behavior w.r.t to the lvalue initialization - state. -

-

- Imagine optional<T&> - forwarding assignment to the referenced object (thus changing the referenced - object value but not rebinding), and consider the following code: -

-
optional<int&> a = get();
-int x = 1 ;
-int& rx = x ;
-optional<int&> b(rx);
-a = b ;
-
-

- What does the assignment do? -

-

- If a is uninitialized, - the answer is clear: it binds to x - (we now have another reference to x). - But what if a is already - initialized? it would change the value of the referenced - object (whatever that is); which is inconsistent with the other possible - case. -

-

- If optional<T&> - would assign just like T& does, you would never be able to use - Optional's assignment without explicitly handling the previous initialization - state unless your code is capable of functioning whether after the assignment, - a aliases the same object - as b or not. -

-

- That is, you would have to discriminate in order to be consistent. -

-

- If in your code rebinding to another object is not an option, then it is - very likely that binding for the first time isn't either. In such case, assignment - to an uninitialized optional<T&> - shall be prohibited. It is quite possible that in such a scenario it is a - precondition that the lvalue must be already initialized. If it isn't, then - binding for the first time is OK while rebinding is not which is IMO very - unlikely. In such a scenario, you can assign the value itself directly, as - in: -

-
assert(!!opt);
-*opt=value;
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/relational_operators.html b/doc/html/boost_optional/tutorial/relational_operators.html deleted file mode 100644 index 376bdccd..00000000 --- a/doc/html/boost_optional/tutorial/relational_operators.html +++ /dev/null @@ -1,113 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Type optional<T> is - EqualityComparable whenever T is EqualityComparable. Two optional - objects containing a value compare in the same way as their contained values. - The uninitialized state of optional<T> - is treated as a distinct value, equal to itself, and unequal to any value - of type T: -

-
boost::optional<int> oN = boost::none;
-boost::optional<int> o0 = 0;
-boost::optional<int> o1 = 1;
-
-assert(oN != o0);
-assert(o1 != oN);
-assert(o0 != o1);
-assert(oN == oN);
-assert(o0 == o0);
-
-

- The converting constructor from T - as well as from boost::none implies the existence and semantics - of the mixed comparison between T - and optional<T> as - well as between none_t and - optionl<T>: -

-
assert(oN != 0);
-assert(o1 != boost::none);
-assert(o0 != 1);
-assert(oN == boost::none);
-assert(o0 == 0);
-
-

- This mixed comparison has a practical interpretation, which is occasionally - useful: -

-
boost::optional<int> choice = ask_user();
-if (choice == 2)
-    start_procedure_2();
-
-

- In the above example, the meaning of the comparison is 'user chose number - 2'. If user chose nothing, he didn't choose number 2. -

-

- In case where optional<T> is - compared to none, it is not - required that T be EqualityComparable. -

-

- In a similar manner, type optional<T> - is LessThanComparable whenever T is LessThanComparable. The optional - object containing no value is compared less than any value of T. To illustrate this, if the default ordering - of size_t is {0, 1, - 2, ...}, the default ordering - of optional<size_t> - is {boost::none, 0, - 1, 2, - ...}. This order does not have a practical interpretation. The goal is to - have any semantically correct default ordering in order for optional<T> to - be usable in ordered associative containers (wherever T - is usable). -

-

- Mixed relational operators are the only case where the contained value of - an optional object can be inspected without the usage of value accessing - function (operator*, - value, value_or). -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/type_requirements.html b/doc/html/boost_optional/tutorial/type_requirements.html deleted file mode 100644 index d213a4f5..00000000 --- a/doc/html/boost_optional/tutorial/type_requirements.html +++ /dev/null @@ -1,109 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- The very minimum requirement of optional<T> - is that T is a complete type - and that it has a publicly accessible destructor. T - doesn't even need to be constructible. You can use a very minimum interface: -

-
optional<T> o;     // uninitialized
-assert(o == none); // check if initialized
-assert(!o);        //
-o.value();         // always throws
-
-

- But this is practically useless. In order for optional<T> - to be able to do anything useful and offer all the spectrum of ways of accessing - the contained value, T needs - to have at least one accessible constructor. In that case you need to initialize - the optional object with function emplace(), or if your compiler does not support it, - resort to In-Place - Factories: -

-
optional<T> o;
-o.emplace("T", "ctor", "params");
-
-

- If T is MoveConstructible, - optional<T> is - also MoveConstructible and - can be easily initialized from an rvalue of type T - and be passed by value: -

-
optional<T> o = make_T();
-optional<T> p = optional<T>();
-
-

- If T is CopyConstructible, optional<T> is - also CopyConstructible - and can be easily initialized from an lvalue of type T: -

-
T v = make_T();
-optional<T> o = v;
-optional<T> p = o;
-
-

- If T is not MoveAssignable, it is still possible to - reset the value of optional<T> - using function emplace(): -

-
optional<const T> o = make_T();
-o.emplace(make_another_T());
-
-

- If T is Moveable - (both MoveConstructible and - MoveAssignable) then optional<T> is - also Moveable and additionally - can be constructed and assigned from an rvalue of type T. -

-

- Similarly, if T is Copyable (both CopyConstructible and CopyAssignable) then optional<T> - is also Copyable and additionally - can be constructed and assigned from an lvalue of type T. -

-

- T is not - required to be DefaultConstructible. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/tutorial/when_to_use_optional.html b/doc/html/boost_optional/tutorial/when_to_use_optional.html deleted file mode 100644 index 3caec24d..00000000 --- a/doc/html/boost_optional/tutorial/when_to_use_optional.html +++ /dev/null @@ -1,142 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- It is recommended to use optional<T> - in situations where there is exactly one, clear (to all parties) reason for - having no value of type T, - and where the lack of value is as natural as having any regular value of - T. One example of such situation - is asking the user in some GUI form to optionally specify some limit on an - int value, but the user is allowed - to say 'I want the number not to be constrained by the maximum'. For another - example, consider a config parameter specifying how many threads the application - should launch. Leaving this parameter unspecified means that the application - should decide itself. For yet another example, consider a function returning - the index of the smallest element in a vector. - We need to be prepared for the situation, where the vector - is empty. Therefore a natural signature for such function would be: -

-
template <typename T>
-optional<size_t> find_smallest_elem(const std::vector<T>& vec);
-
-

- Here, having received an empty vec - and having no size_t to return - is not a failure but a normal, - albeit irregular, situation. -

-

- Another typical situation is to indicate that we do not have a value yet, - but we expect to have it later. This notion can be used in implementing solutions - like lazy initialization or a two-phase initialization. -

-

- optional can be used to take - a non-DefaultConstructible type T and create a sibling type with a default - constructor. This is a way to add a null-state to any - type that doesn't have it already. -

-

- Sometimes type T already - provides a built-in null-state, but it may still be useful to wrap it into - optional. Consider std::string. - When you read a piece of text from a GUI form or a DB table, it is hardly - ever that the empty string indicates anything else but a missing text. And - some data bases do not even distinguish between a null string entry and a - non-null string of length 0. Still, it may be practical to use optional<string> - to indicate in the returned type that we want to treat the empty string in - a special dedicated program path: -

-
if(boost::optional<std::string> name = ask_user_name()) {
-    assert(*name != "");
-    logon_as(*name);
-}
-else {
-    skip_logon();
-}
-
-

- In the example above, the assertion indicates that if we choose to use this - technique, we must translate the empty string state to an optional object - with no contained value (inside function ask_user_name). -

-
- - Not - recommended usages -
-

- It is not recommended to use optional - to indicate that we were not able to compute a value because of a failure. - It is difficult to define what a failure is, but it usually has one common - characteristic: an associated information on the cause of the failure. This - can be the type and member data of an exception object, or an error code. - It is a bad design to signal a failure and not inform about the cause. If - you do not want to use exceptions, and do not like the fact that by returning - error codes you cannot return the computed value, you can use Expected - library. It is sort of Boost.Variant - that contains either a computed value or a reason why the computation failed. -

-

- Sometimes the distinction into what is a failure and what is a valid but - irregular result is blurry and depends on a particular usage and personal - preference. Consider a function that converts a string - to an int. Is it a failure that - you cannot convert? It might in some cases, but in other you may call it - exactly for the purpose of figuring out if a given string - is convertible, and you are not even interested in the resulting value. Sometimes - when a conversion fails you may not consider it a failure, but you need to - know why it cannot be converted; for instance at which character it is determined - that the conversion is impossible. In this case returning optional<T> - will not suffice. Finally, there is a use case where an input string that - does not represent an int is - not a failure condition, but during the conversion we use resources whose - acquisition may fail. In that case the natural representation is to both - return optional<int> and - signal failure: -

-
optional<int> convert1(const string& str); // throws
-expected<ErrorT, optional<int>> convert2(const string& str); // return either optional or error
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_optional/type_requirements.html b/doc/html/boost_optional/type_requirements.html deleted file mode 100644 index e1ee7778..00000000 --- a/doc/html/boost_optional/type_requirements.html +++ /dev/null @@ -1,61 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- At the very minimum for optional<T> - to work with a minimum interface it is required that T - has a publicly accessible no-throw destructor. In that case you need to initialize - the optional object with function emplace() or use InPlaceFactories. - Additionally, if T is Moveable, optional<T> - is also Moveable and can be - easily initialized from an rvalue of type T - and be passed by value. Additionally, if T - is Copyable, optional<T> is - also Copyable and can be easily - initialized from an lvalue of type T. -

-

- T is - not required to be Default - Constructible. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/images/opt_align1.png b/doc/html/images/opt_align1.png deleted file mode 100644 index 50e0205e..00000000 Binary files a/doc/html/images/opt_align1.png and /dev/null differ diff --git a/doc/html/images/opt_align2.png b/doc/html/images/opt_align2.png deleted file mode 100644 index fd7c079c..00000000 Binary files a/doc/html/images/opt_align2.png and /dev/null differ diff --git a/doc/html/images/opt_align3.png b/doc/html/images/opt_align3.png deleted file mode 100644 index 7ca6ec80..00000000 Binary files a/doc/html/images/opt_align3.png and /dev/null differ diff --git a/doc/html/images/opt_align4.png b/doc/html/images/opt_align4.png deleted file mode 100644 index c7f9b724..00000000 Binary files a/doc/html/images/opt_align4.png and /dev/null differ diff --git a/doc/html/index.html b/doc/html/index.html deleted file mode 100644 index 39d99e7b..00000000 --- a/doc/html/index.html +++ /dev/null @@ -1,154 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
Next
-
-
-

-Boost.Optional

-

-Fernando Luis Cacciola Carballal -

-
-
-
-

- 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) -

-
-
- -
- -

- Class template optional is - a wrapper for representing 'optional' (or 'nullable') objects who may not (yet) - contain a valid value. Optional objects offer full value semantics; they are - good for passing by value and usage inside STL containers. This is a header-only - library. -

-

- - Problem -

-

- Suppose we want to read a parameter form a config file which represents some - integral value, let's call it "MaxValue". - It is possible that this parameter is not specified; such situation is no error. - It is valid to not specify the parameter and in that case the program is supposed - to behave slightly differently. Also, suppose that any possible value of type - int is a valid value for "MaxValue", so we cannot just use - -1 - to represent the absence of the parameter in the config file. -

-

- - Solution -

-

- This is how you solve it with boost::optional: -

-
#include <boost/optional.hpp>
-
-boost::optional<int> getConfigParam(std::string name);  // return either an int or a `not-an-int`
-
-int main()
-{
-  if (boost::optional<int> oi = getConfigParam("MaxValue")) // did I get a real int?
-    runWithMax(*oi);                                        // use my int
-  else
-    runWithNoMax();
-}
-
-
-
- - - -

Last revised: November 08, 2018 at 17:44:53 GMT

-
-
Next
- - diff --git a/doc/html/optional/reference.html b/doc/html/optional/reference.html deleted file mode 100644 index d3b0ab72..00000000 --- a/doc/html/optional/reference.html +++ /dev/null @@ -1,89 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- -
- -

-

-
namespace boost {
-
-class none_t {/* see below */};
-
-const none_t none (/* see below */);
-
-} // namespace boost
-
-

-

-

- Class none_t is meant to - serve as a tag for selecting appropriate overloads of from optional's interface. It is an empty, - trivially copyable class with disabled default constructor. -

-

- Constant none is used to - indicate an optional object that does not contain a value in initialization, - assignment and relational operations of optional. -

-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/optional/reference/header__boost_optional_optional_hpp_.html b/doc/html/optional/reference/header__boost_optional_optional_hpp_.html deleted file mode 100644 index c416301b..00000000 --- a/doc/html/optional/reference/header__boost_optional_optional_hpp_.html +++ /dev/null @@ -1,111 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -
- -
// In Header: <boost/optional/optional.hpp>
-
-namespace boost {
-
-class in_place_init_t { /* see below */ } ; R
-const in_place_init_t in_place_init ( /* see below */ ) ;
-
-class in_place_init_if_t { /*see below*/ } ; R
-const in_place_init_if_t in_place_init_if ( /*see below*/ ) ;
-
-template <class T>
-class optional ; R
-
-template <class T>
-class optional<T&> ; R
-
-template<class T> inline bool operator == ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator != ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator <  ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator >  ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator <= ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator >= ( optional<T> const& x, optional<T> const& y ) ; R
-
-template<class T> inline bool operator == ( optional<T> const& x, none_t ) noexcept ; R
-
-template<class T> inline bool operator != ( optional<T> const& x, none_t ) noexcept ; R
-
-template<class T> inline optional<T> make_optional ( T const& v ) ; R
-
-template<class T> inline optional<std::decay_t<T>> make_optional ( T && v ) ; R
-
-template<class T> inline optional<T> make_optional ( bool condition, T const& v ) ; R
-
-template<class T> inline optional<std::decay_t<T>> make_optional ( bool condition, T && v ) ; R
-
-template<class T> inline auto get_optional_value_or ( optional<T> const& opt, typename optional<T>::reference_const_type def ) -> typename optional<T>::reference_const_type; R
-
-template<class T> inline auto get_optional_value_or ( optional<T> const& opt, typename optional<T>::reference_type def ) -> typename optional<T>::reference_type ; R
-
-template<class T> inline T const& get ( optional<T> const& opt ) ; R
-
-template<class T> inline T& get ( optional<T> & opt ) ; R
-
-template<class T> inline T const* get ( optional<T> const* opt ) ; R
-
-template<class T> inline T* get ( optional<T>* opt ) ; R
-
-template<class T> inline auto get_pointer ( optional<T> const& opt ) -> see below; R
-
-template<class T> inline auto get_pointer ( optional<T> & opt ) -> see below; R
-
-template<class T> inline void swap( optional<T>& x, optional<T>& y ) ; R
-
-template<class T> inline void swap( optional<T&>& x, optional<T&>& y ) ; R
-
-} // namespace boost
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/optional/tutorial.html b/doc/html/optional/tutorial.html deleted file mode 100644 index 972f9f70..00000000 --- a/doc/html/optional/tutorial.html +++ /dev/null @@ -1,153 +0,0 @@ - - - -Codestin Search App - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- -

- Consider these functions which should return a value but which might not - have a value to return: -

-
    -
  • - (A) double sqrt(double n ); -
  • -
  • - (B) char get_async_input(); -
  • -
  • - (C) point polygon::get_any_point_effectively_inside(); -
  • -
-

- There are different approaches to the issue of not having a value to return. -

-

- A typical approach is to consider the existence of a valid return value as - a postcondition, so that if the function cannot compute the value to return, - it has either undefined behavior (and can use assert in a debug build) or - uses a runtime check and throws an exception if the postcondition is violated. - This is a reasonable choice for example, for function (A), because the lack - of a proper return value is directly related to an invalid parameter (out - of domain argument), so it is appropriate to require the callee to supply - only parameters in a valid domain for execution to continue normally. -

-

- However, function (B), because of its asynchronous nature, does not fail - just because it can't find a value to return; so it is incorrect to consider - such a situation an error and assert or throw an exception. This function - must return, and somehow, must tell the callee that it is not returning a - meaningful value. -

-

- A similar situation occurs with function (C): it is conceptually an error - to ask a null-area polygon to return a point inside - itself, but in many applications, it is just impractical for performance - reasons to treat this as an error (because detecting that the polygon has - no area might be too expensive to be required to be tested previously), and - either an arbitrary point (typically at infinity) is returned, or some efficient - way to tell the callee that there is no such point is used. -

-

- There are various mechanisms to let functions communicate that the returned - value is not valid. One such mechanism, which is quite common since it has - zero or negligible overhead, is to use a special value which is reserved - to communicate this. Classical examples of such special values are EOF, string::npos, - points at infinity, etc... -

-

- When those values exist, i.e. the return type can hold all meaningful values - plus the signal value, this mechanism - is quite appropriate and well known. Unfortunately, there are cases when - such values do not exist. In these cases, the usual alternative is either - to use a wider type, such as int - in place of char; or a compound - type, such as std::pair<point,bool>. -

-

- Returning a std::pair<T,bool>, thus attaching a boolean flag to the - result which indicates if the result is meaningful, has the advantage that - can be turned into a consistent idiom since the first element of the pair - can be whatever the function would conceptually return. For example, the - last two functions could have the following interface: -

-
std::pair<char,bool> get_async_input();
-std::pair<point,bool> polygon::get_any_point_effectively_inside();
-
-

- These functions use a consistent interface for dealing with possibly nonexistent - results: -

-
std::pair<point,bool> p = poly.get_any_point_effectively_inside();
-if ( p.second )
-    flood_fill(p.first);
-
-

- However, not only is this quite a burden syntactically, it is also error - prone since the user can easily use the function result (first element of - the pair) without ever checking if it has a valid value. -

-

- Clearly, we need a better idiom. -

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/images/callouts/R.png b/doc/images/R.png similarity index 100% rename from doc/html/images/callouts/R.png rename to doc/images/R.png diff --git a/doc/html/images/space.png b/doc/images/space.png similarity index 100% rename from doc/html/images/space.png rename to doc/images/space.png diff --git a/include/boost/none.hpp b/include/boost/none.hpp index a37c45c5..3e7a9500 100644 --- a/include/boost/none.hpp +++ b/include/boost/none.hpp @@ -13,6 +13,7 @@ #ifndef BOOST_NONE_17SEP2003_HPP #define BOOST_NONE_17SEP2003_HPP +#include "boost/config.hpp" #include "boost/none_t.hpp" // NOTE: Borland users have to include this header outside any precompiled headers @@ -23,7 +24,7 @@ namespace boost { #ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE -none_t const none = (static_cast(0)) ; +BOOST_INLINE_VARIABLE none_t BOOST_CONSTEXPR_OR_CONST none = (static_cast(0)) ; #elif defined BOOST_OPTIONAL_USE_SINGLETON_DEFINITION_OF_NONE @@ -35,7 +36,7 @@ namespace detail { namespace optional_detail { { static const T instance; }; - + template const T none_instance::instance = T(); // global, but because 'tis a template, no cpp file required @@ -44,16 +45,15 @@ namespace detail { namespace optional_detail { namespace { // TU-local - const none_t& none = detail::optional_detail::none_instance::instance; + const none_t& none = detail::optional_detail::none_instance::instance; } #else -const none_t none ((none_t::init_tag())); +BOOST_INLINE_CONSTEXPR none_t none ((none_t::init_tag())); #endif // older definitions } // namespace boost #endif // header guard - diff --git a/include/boost/none_t.hpp b/include/boost/none_t.hpp index 008f369d..1c8e0761 100644 --- a/include/boost/none_t.hpp +++ b/include/boost/none_t.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// Copyright (C) 2014, 2015 Andrzej Krzemienski. +// Copyright (C) 2014, 2024 Andrzej Krzemienski. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -13,6 +13,22 @@ #ifndef BOOST_NONE_T_17SEP2003_HPP #define BOOST_NONE_T_17SEP2003_HPP +#include +#include + +#if defined (BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \ +|| defined(BOOST_NO_CXX11_LAMBDAS) || defined(BOOST_NO_CXX11_DECLTYPE_N3276) \ +|| defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) \ +|| defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) || defined(BOOST_NO_CXX11_STATIC_ASSERT) + +#error "Boost.Optional requires some C++11 features since version 1.87. If you have an older C++ version use Boost.Optional version 1.86 or earlier." + +#elif defined(BOOST_NO_CXX11_REF_QUALIFIERS) || defined(BOOST_NO_CXX11_NOEXCEPT) || defined(BOOST_NO_CXX11_DEFAULTED_MOVES) + +BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.Optional 1.83 and will be removed in Boost.Optional 1.88.") + +#endif + namespace boost { #ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE @@ -29,7 +45,7 @@ class none_t {}; struct none_t { struct init_tag{}; - explicit none_t(init_tag){} // to disable default constructor + explicit BOOST_CONSTEXPR none_t(init_tag){} // to disable default constructor }; #endif // old implementation workarounds diff --git a/include/boost/optional/bad_optional_access.hpp b/include/boost/optional/bad_optional_access.hpp index cabf43fb..add78675 100644 --- a/include/boost/optional/bad_optional_access.hpp +++ b/include/boost/optional/bad_optional_access.hpp @@ -19,6 +19,11 @@ namespace boost { +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wweak-vtables" +#endif + class bad_optional_access : public std::logic_error { public: @@ -27,6 +32,10 @@ class bad_optional_access : public std::logic_error {} }; +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + } // namespace boost #endif diff --git a/include/boost/optional/detail/experimental_traits.hpp b/include/boost/optional/detail/experimental_traits.hpp index b51f5f10..4d4abe8b 100644 --- a/include/boost/optional/detail/experimental_traits.hpp +++ b/include/boost/optional/detail/experimental_traits.hpp @@ -12,19 +12,14 @@ #ifndef BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP #define BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP -#include -#include -#include #include - + // The condition to use POD implementation #ifdef BOOST_OPTIONAL_CONFIG_NO_POD_SPEC # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES #elif defined BOOST_OPTIONAL_CONFIG_NO_SPEC_FOR_TRIVIAL_TYPES # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES -#elif !defined BOOST_HAS_TRIVIAL_CONSTRUCTOR -# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES #elif !defined BOOST_HAS_TRIVIAL_MOVE_ASSIGN # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES #elif !defined BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR @@ -35,37 +30,14 @@ # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES #elif !defined BOOST_HAS_TRIVIAL_DESTRUCTOR # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES -#elif BOOST_WORKAROUND(BOOST_GCC, < 50000) -# define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES #endif -// GCC 5 or higher, or clang with libc++ or clang with libstdc++ 5 or higher -#if __cplusplus >= 201103L -# if BOOST_WORKAROUND(BOOST_GCC, >= 50000) -# define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS -# elif (defined BOOST_CLANG) -# if BOOST_LIB_STD_CXX > 0 -# define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS -# elif BOOST_LIB_STD_GNU >= 441200023 && BOOST_LIB_STD_GNU != 450600023 && BOOST_LIB_STD_GNU != 450600026 && BOOST_LIB_STD_GNU != 460800003 && BOOST_LIB_STD_GNU != 450400026 && BOOST_LIB_STD_GNU != 460700026 -# define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS -# endif -# endif -#endif - -#ifndef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS -# define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) -#else -# include -# define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) std::is_trivially_default_constructible::value -#endif - - namespace boost { namespace optional_detail { - + #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES template -struct is_type_trivially_copyable +struct is_trivially_semiregular : boost::conditional<(boost::has_trivial_copy_constructor::value && boost::has_trivial_move_constructor::value && boost::has_trivial_destructor::value && @@ -75,30 +47,13 @@ struct is_type_trivially_copyable {}; #else template -struct is_type_trivially_copyable +struct is_trivially_semiregular : boost::conditional<(boost::is_scalar::value && !boost::is_const::value && !boost::is_volatile::value), boost::true_type, boost::false_type>::type {}; #endif - -#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES -template -struct optional_uses_direct_storage_for_ - : boost::conditional< (is_type_trivially_copyable::value && BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T)) || - (boost::is_scalar::value && !boost::is_const::value && !boost::is_volatile::value) - , boost::true_type, boost::false_type>::type -{}; -#else -template -struct optional_uses_direct_storage_for_ - : boost::conditional<(boost::is_scalar::value && !boost::is_const::value && !boost::is_volatile::value) - , boost::true_type, boost::false_type>::type -{}; -#endif - - }} // boost::optional_detail #endif diff --git a/include/boost/optional/detail/old_optional_implementation.hpp b/include/boost/optional/detail/old_optional_implementation.hpp deleted file mode 100644 index f8dc260d..00000000 --- a/include/boost/optional/detail/old_optional_implementation.hpp +++ /dev/null @@ -1,1058 +0,0 @@ -// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. -// Copyright (C) 2014-2016 Andrzej Krzemienski. -// -// 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) -// -// See http://www.boost.org/libs/optional for documentation. -// -// You are welcome to contact the maintainer at: -// akrzemi1@gmail.com - -#ifndef BOOST_OPTIONAL_DETAIL_OLD_OPTIONAL_IMPLEMENTATION_AJK_28JAN2015_HPP -#define BOOST_OPTIONAL_DETAIL_OLD_OPTIONAL_IMPLEMENTATION_AJK_28JAN2015_HPP - -#include -#include -#include -#include - -namespace boost { - -namespace optional_detail { - - -template -struct types_when_isnt_ref -{ - typedef T const& reference_const_type ; - typedef T & reference_type ; -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - typedef T && rval_reference_type ; - typedef T && reference_type_of_temporary_wrapper; -#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES - // GCC 4.4 has support for an early draft of rvalue references. The conforming version below - // causes warnings about returning references to a temporary. - static T&& move(T&& r) { return r; } -#else - static rval_reference_type move(reference_type r) { return boost::move(r); } -#endif -#endif - typedef T const* pointer_const_type ; - typedef T * pointer_type ; - typedef T const& argument_type ; -} ; - -template -struct types_when_is_ref -{ - typedef BOOST_DEDUCED_TYPENAME remove_reference::type raw_type ; - - typedef raw_type& reference_const_type ; - typedef raw_type& reference_type ; -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - typedef BOOST_DEDUCED_TYPENAME remove_const::type&& rval_reference_type ; - typedef raw_type& reference_type_of_temporary_wrapper; - static reference_type move(reference_type r) { return r; } -#endif - typedef raw_type* pointer_const_type ; - typedef raw_type* pointer_type ; - typedef raw_type& argument_type ; -} ; - -template -void prevent_binding_rvalue_ref_to_optional_lvalue_ref() -{ -#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES - BOOST_STATIC_ASSERT_MSG( - !boost::is_lvalue_reference::value || !boost::is_rvalue_reference::value, - "binding rvalue references to optional lvalue references is disallowed"); -#endif -} - -struct optional_tag {} ; - -template -class optional_base : public optional_tag -{ - private : - - typedef -#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) - BOOST_DEDUCED_TYPENAME -#endif - ::boost::detail::make_reference_content::type internal_type ; - - typedef aligned_storage storage_type ; - - typedef types_when_isnt_ref types_when_not_ref ; - typedef types_when_is_ref types_when_ref ; - - typedef optional_base this_type ; - - protected : - - typedef T value_type ; - - typedef true_type is_reference_tag ; - typedef false_type is_not_reference_tag ; - - typedef BOOST_DEDUCED_TYPENAME is_reference::type is_reference_predicate ; - - public: - typedef BOOST_DEDUCED_TYPENAME conditional::type types ; - - protected: - typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ; - typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ; -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type rval_reference_type ; - typedef BOOST_DEDUCED_TYPENAME types::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ; -#endif - typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ; - typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ; - typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ; - - // Creates an optional uninitialized. - // No-throw - optional_base() - : - m_initialized(false) {} - - // Creates an optional uninitialized. - // No-throw - optional_base ( none_t ) - : - m_initialized(false) {} - - // Creates an optional initialized with 'val'. - // Can throw if T::T(T const&) does - optional_base ( argument_type val ) - : - m_initialized(false) - { - construct(val); - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // move-construct an optional initialized from an rvalue-ref to 'val'. - // Can throw if T::T(T&&) does - optional_base ( rval_reference_type val ) - : - m_initialized(false) - { - construct( boost::move(val) ); - } -#endif - - // Creates an optional initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional. - // Can throw if T::T(T const&) does - optional_base ( bool cond, argument_type val ) - : - m_initialized(false) - { - if ( cond ) - construct(val); - } - - // Creates a deep copy of another optional - // Can throw if T::T(T const&) does - optional_base ( optional_base const& rhs ) - : - m_initialized(false) - { - if ( rhs.is_initialized() ) - construct(rhs.get_impl()); - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Creates a deep move of another optional - // Can throw if T::T(T&&) does - optional_base ( optional_base&& rhs ) - : - m_initialized(false) - { - if ( rhs.is_initialized() ) - construct( boost::move(rhs.get_impl()) ); - } -#endif - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - - template - explicit optional_base ( Expr&& expr, PtrExpr const* tag ) - : - m_initialized(false) - { - construct(boost::forward(expr),tag); - } - -#else - // This is used for both converting and in-place constructions. - // Derived classes use the 'tag' to select the appropriate - // implementation (the correct 'construct()' overload) - template - explicit optional_base ( Expr const& expr, Expr const* tag ) - : - m_initialized(false) - { - construct(expr,tag); - } - -#endif - - - // No-throw (assuming T::~T() doesn't) - ~optional_base() { destroy() ; } - - // Assigns from another optional (deep-copies the rhs value) - void assign ( optional_base const& rhs ) - { - if (is_initialized()) - { - if ( rhs.is_initialized() ) - assign_value(rhs.get_impl(), is_reference_predicate() ); - else destroy(); - } - else - { - if ( rhs.is_initialized() ) - construct(rhs.get_impl()); - } - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Assigns from another optional (deep-moves the rhs value) - void assign ( optional_base&& rhs ) - { - if (is_initialized()) - { - if ( rhs.is_initialized() ) - assign_value(boost::move(rhs.get_impl()), is_reference_predicate() ); - else destroy(); - } - else - { - if ( rhs.is_initialized() ) - construct(boost::move(rhs.get_impl())); - } - } -#endif - - // Assigns from another _convertible_ optional (deep-copies the rhs value) - template - void assign ( optional const& rhs ) - { - if (is_initialized()) - { - if ( rhs.is_initialized() ) -#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES - assign_value(rhs.get(), is_reference_predicate() ); -#else - assign_value(static_cast(rhs.get()), is_reference_predicate() ); -#endif - - else destroy(); - } - else - { - if ( rhs.is_initialized() ) -#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES - construct(rhs.get()); -#else - construct(static_cast(rhs.get())); -#endif - } - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // move-assigns from another _convertible_ optional (deep-moves from the rhs value) - template - void assign ( optional&& rhs ) - { - typedef BOOST_DEDUCED_TYPENAME optional::rval_reference_type ref_type; - if (is_initialized()) - { - if ( rhs.is_initialized() ) - assign_value(static_cast(rhs.get()), is_reference_predicate() ); - else destroy(); - } - else - { - if ( rhs.is_initialized() ) - construct(static_cast(rhs.get())); - } - } -#endif - - // Assigns from a T (deep-copies the rhs value) - void assign ( argument_type val ) - { - if (is_initialized()) - assign_value(val, is_reference_predicate() ); - else construct(val); - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Assigns from a T (deep-moves the rhs value) - void assign ( rval_reference_type val ) - { - if (is_initialized()) - assign_value( boost::move(val), is_reference_predicate() ); - else construct( boost::move(val) ); - } -#endif - - // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED - // No-throw (assuming T::~T() doesn't) - void assign ( none_t ) BOOST_NOEXCEPT { destroy(); } - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - template - void assign_expr ( Expr&& expr, ExprPtr const* tag ) - { - if (is_initialized()) - assign_expr_to_initialized(boost::forward(expr),tag); - else construct(boost::forward(expr),tag); - } -#else - template - void assign_expr ( Expr const& expr, Expr const* tag ) - { - if (is_initialized()) - assign_expr_to_initialized(expr,tag); - else construct(expr,tag); - } -#endif - -#endif - - public : - - // Destroys the current value, if any, leaving this UNINITIALIZED - // No-throw (assuming T::~T() doesn't) - void reset() BOOST_NOEXCEPT { destroy(); } - - // **DEPPRECATED** Replaces the current value -if any- with 'val' - void reset ( argument_type val ) { assign(val); } - - // Returns a pointer to the value if this is initialized, otherwise, - // returns NULL. - // No-throw - pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; } - pointer_type get_ptr() { return m_initialized ? get_ptr_impl() : 0 ; } - - bool is_initialized() const { return m_initialized ; } - - protected : - - void construct ( argument_type val ) - { - ::new (m_storage.address()) internal_type(val) ; - m_initialized = true ; - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - void construct ( rval_reference_type val ) - { - ::new (m_storage.address()) internal_type( types::move(val) ) ; - m_initialized = true ; - } -#endif - - -#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) - // Constructs in-place - // upon exception *this is always uninitialized - template - void emplace_assign ( Args&&... args ) - { - destroy(); - ::new (m_storage.address()) internal_type( boost::forward(args)... ); - m_initialized = true ; - } -#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - template - void emplace_assign ( Arg&& arg ) - { - destroy(); - ::new (m_storage.address()) internal_type( boost::forward(arg) ); - m_initialized = true ; - } - - void emplace_assign () - { - destroy(); - ::new (m_storage.address()) internal_type(); - m_initialized = true ; - } -#else - template - void emplace_assign ( const Arg& arg ) - { - destroy(); - ::new (m_storage.address()) internal_type( arg ); - m_initialized = true ; - } - - template - void emplace_assign ( Arg& arg ) - { - destroy(); - ::new (m_storage.address()) internal_type( arg ); - m_initialized = true ; - } - - void emplace_assign () - { - destroy(); - ::new (m_storage.address()) internal_type(); - m_initialized = true ; - } -#endif - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Constructs in-place using the given factory - template - void construct ( Expr&& factory, in_place_factory_base const* ) - { - BOOST_STATIC_ASSERT ( !is_reference_predicate::value ) ; - boost_optional_detail::construct(factory, m_storage.address()); - m_initialized = true ; - } - - // Constructs in-place using the given typed factory - template - void construct ( Expr&& factory, typed_in_place_factory_base const* ) - { - BOOST_STATIC_ASSERT ( !is_reference_predicate::value ) ; - factory.apply(m_storage.address()) ; - m_initialized = true ; - } - - template - void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag ) - { - destroy(); - construct(factory,tag); - } - - // Constructs in-place using the given typed factory - template - void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag ) - { - destroy(); - construct(factory,tag); - } - -#else - // Constructs in-place using the given factory - template - void construct ( Expr const& factory, in_place_factory_base const* ) - { - BOOST_STATIC_ASSERT ( !is_reference_predicate::value ) ; - boost_optional_detail::construct(factory, m_storage.address()); - m_initialized = true ; - } - - // Constructs in-place using the given typed factory - template - void construct ( Expr const& factory, typed_in_place_factory_base const* ) - { - BOOST_STATIC_ASSERT ( !is_reference_predicate::value ) ; - factory.apply(m_storage.address()) ; - m_initialized = true ; - } - - template - void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag ) - { - destroy(); - construct(factory,tag); - } - - // Constructs in-place using the given typed factory - template - void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag ) - { - destroy(); - construct(factory,tag); - } -#endif - -#endif - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Constructs using any expression implicitly convertible to the single argument - // of a one-argument T constructor. - // Converting constructions of optional from optional uses this function with - // 'Expr' being of type 'U' and relying on a converting constructor of T from U. - template - void construct ( Expr&& expr, void const* ) - { - new (m_storage.address()) internal_type(boost::forward(expr)) ; - m_initialized = true ; - } - - // Assigns using a form any expression implicitly convertible to the single argument - // of a T's assignment operator. - // Converting assignments of optional from optional uses this function with - // 'Expr' being of type 'U' and relying on a converting assignment of T from U. - template - void assign_expr_to_initialized ( Expr&& expr, void const* ) - { - assign_value(boost::forward(expr), is_reference_predicate()); - } -#else - // Constructs using any expression implicitly convertible to the single argument - // of a one-argument T constructor. - // Converting constructions of optional from optional uses this function with - // 'Expr' being of type 'U' and relying on a converting constructor of T from U. - template - void construct ( Expr const& expr, void const* ) - { - new (m_storage.address()) internal_type(expr) ; - m_initialized = true ; - } - - // Assigns using a form any expression implicitly convertible to the single argument - // of a T's assignment operator. - // Converting assignments of optional from optional uses this function with - // 'Expr' being of type 'U' and relying on a converting assignment of T from U. - template - void assign_expr_to_initialized ( Expr const& expr, void const* ) - { - assign_value(expr, is_reference_predicate()); - } - -#endif - -#ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION - // BCB5.64 (and probably lower versions) workaround. - // The in-place factories are supported by means of catch-all constructors - // and assignment operators (the functions are parameterized in terms of - // an arbitrary 'Expr' type) - // This compiler incorrectly resolves the overload set and sinks optional and optional - // to the 'Expr'-taking functions even though explicit overloads are present for them. - // Thus, the following overload is needed to properly handle the case when the 'lhs' - // is another optional. - // - // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error - // instead of choosing the wrong overload - // -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Notice that 'Expr' will be optional or optional (but not optional_base<..>) - template - void construct ( Expr&& expr, optional_tag const* ) - { - if ( expr.is_initialized() ) - { - // An exception can be thrown here. - // It it happens, THIS will be left uninitialized. - new (m_storage.address()) internal_type(types::move(expr.get())) ; - m_initialized = true ; - } - } -#else - // Notice that 'Expr' will be optional or optional (but not optional_base<..>) - template - void construct ( Expr const& expr, optional_tag const* ) - { - if ( expr.is_initialized() ) - { - // An exception can be thrown here. - // It it happens, THIS will be left uninitialized. - new (m_storage.address()) internal_type(expr.get()) ; - m_initialized = true ; - } - } -#endif -#endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION - - void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; } - void assign_value ( argument_type val, is_reference_tag ) { construct(val); } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - void assign_value ( rval_reference_type val, is_not_reference_tag ) { get_impl() = static_cast(val); } - void assign_value ( rval_reference_type val, is_reference_tag ) { construct( static_cast(val) ); } -#endif - - void destroy() - { - if ( m_initialized ) - destroy_impl(is_reference_predicate()) ; - } - - reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; } - reference_type get_impl() { return dereference(get_object(), is_reference_predicate() ) ; } - - pointer_const_type get_ptr_impl() const { return cast_ptr(get_object(), is_reference_predicate() ) ; } - pointer_type get_ptr_impl() { return cast_ptr(get_object(), is_reference_predicate() ) ; } - - private : - - // internal_type can be either T or reference_content -#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS) - // This workaround is supposed to silence GCC warnings about broken strict aliasing rules - internal_type const* get_object() const - { - union { void const* ap_pvoid; internal_type const* as_ptype; } caster = { m_storage.address() }; - return caster.as_ptype; - } - internal_type * get_object() - { - union { void* ap_pvoid; internal_type* as_ptype; } caster = { m_storage.address() }; - return caster.as_ptype; - } -#else - internal_type const* get_object() const { return static_cast(m_storage.address()); } - internal_type * get_object() { return static_cast (m_storage.address()); } -#endif - - // reference_content lacks an implicit conversion to T&, so the following is needed to obtain a proper reference. - reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; } - reference_type dereference( internal_type* p, is_not_reference_tag ) { return *p ; } - reference_const_type dereference( internal_type const* p, is_reference_tag ) const { return p->get() ; } - reference_type dereference( internal_type* p, is_reference_tag ) { return p->get() ; } - -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581)) - void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; } -#else - void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->~T() ; m_initialized = false ; } -#endif - - void destroy_impl ( is_reference_tag ) { m_initialized = false ; } - - // If T is of reference type, trying to get a pointer to the held value must result in a compile-time error. - // Decent compilers should disallow conversions from reference_content* to T*, but just in case, - // the following olverloads are used to filter out the case and guarantee an error in case of T being a reference. - pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; } - pointer_type cast_ptr( internal_type * p, is_not_reference_tag ) { return p ; } - pointer_const_type cast_ptr( internal_type const* p, is_reference_tag ) const { return &p->get() ; } - pointer_type cast_ptr( internal_type * p, is_reference_tag ) { return &p->get() ; } - - bool m_initialized ; - storage_type m_storage ; -} ; - -} // namespace optional_detail - -template -class optional : public optional_detail::optional_base -{ - typedef optional_detail::optional_base base ; - - public : - - typedef optional this_type ; - - typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ; - typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ; - typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ; -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ; - typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ; -#endif - typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ; - typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ; - typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ; - - // Creates an optional uninitialized. - // No-throw - optional() BOOST_NOEXCEPT : base() {} - - // Creates an optional uninitialized. - // No-throw - optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {} - - // Creates an optional initialized with 'val'. - // Can throw if T::T(T const&) does - optional ( argument_type val ) : base(val) {} - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Creates an optional initialized with 'move(val)'. - // Can throw if T::T(T &&) does - optional ( rval_reference_type val ) : base( boost::forward(val) ) - {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();} -#endif - - // Creates an optional initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional. - // Can throw if T::T(T const&) does - optional ( bool cond, argument_type val ) : base(cond,val) {} - - // NOTE: MSVC needs templated versions first - - // Creates a deep copy of another convertible optional - // Requires a valid conversion from U to T. - // Can throw if T::T(U const&) does - template - explicit optional ( optional const& rhs ) - : - base() - { - if ( rhs.is_initialized() ) - this->construct(rhs.get()); - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Creates a deep move of another convertible optional - // Requires a valid conversion from U to T. - // Can throw if T::T(U&&) does - template - explicit optional ( optional && rhs ) - : - base() - { - if ( rhs.is_initialized() ) - this->construct( boost::move(rhs.get()) ); - } -#endif - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT - // Creates an optional with an expression which can be either - // (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n); - // (b) An instance of TypedInPlaceFactory ( i.e. in_place(a,b,...,n); - // (c) Any expression implicitly convertible to the single type - // of a one-argument T's constructor. - // (d*) Weak compilers (BCB) might also resolved Expr as optional and optional - // even though explicit overloads are present for these. - // Depending on the above some T ctor is called. - // Can throw if the resolved T ctor throws. -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - - - template - explicit optional ( Expr&& expr, - BOOST_DEDUCED_TYPENAME boost::disable_if_c< - (boost::is_base_of::type>::value) || - boost::is_same::type, none_t>::value, bool >::type = true - ) - : base(boost::forward(expr),boost::addressof(expr)) - {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref();} - -#else - template - explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {} -#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES -#endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT - - // Creates a deep copy of another optional - // Can throw if T::T(T const&) does - optional ( optional const& rhs ) : base( static_cast(rhs) ) {} - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Creates a deep move of another optional - // Can throw if T::T(T&&) does - optional ( optional && rhs ) - BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value) - : base( boost::move(rhs) ) - {} - -#endif - // No-throw (assuming T::~T() doesn't) - ~optional() {} - -#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) - // Assigns from an expression. See corresponding constructor. - // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - - template - BOOST_DEDUCED_TYPENAME boost::disable_if_c< - boost::is_base_of::type>::value || - boost::is_same::type, none_t>::value, - optional& - >::type - operator= ( Expr&& expr ) - { - optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref(); - this->assign_expr(boost::forward(expr),boost::addressof(expr)); - return *this ; - } - -#else - template - optional& operator= ( Expr const& expr ) - { - this->assign_expr(expr,boost::addressof(expr)); - return *this ; - } -#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES -#endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) - - // Copy-assigns from another convertible optional (converts && deep-copies the rhs value) - // Requires a valid conversion from U to T. - // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED - template - optional& operator= ( optional const& rhs ) - { - this->assign(rhs); - return *this ; - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Move-assigns from another convertible optional (converts && deep-moves the rhs value) - // Requires a valid conversion from U to T. - // Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED - template - optional& operator= ( optional && rhs ) - { - this->assign(boost::move(rhs)); - return *this ; - } -#endif - - // Assigns from another optional (deep-copies the rhs value) - // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED - // (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw) - optional& operator= ( optional const& rhs ) - { - this->assign( static_cast(rhs) ) ; - return *this ; - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Assigns from another optional (deep-moves the rhs value) - optional& operator= ( optional && rhs ) - BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && ::boost::is_nothrow_move_assignable::value) - { - this->assign( static_cast(rhs) ) ; - return *this ; - } -#endif - - // Assigns from a T (deep-copies the rhs value) - // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED - optional& operator= ( argument_type val ) - { - this->assign( val ) ; - return *this ; - } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - // Assigns from a T (deep-moves the rhs value) - optional& operator= ( rval_reference_type val ) - { - optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref(); - this->assign( boost::move(val) ) ; - return *this ; - } -#endif - - // Assigns from a "none" - // Which destroys the current value, if any, leaving this UNINITIALIZED - // No-throw (assuming T::~T() doesn't) - optional& operator= ( none_t none_ ) BOOST_NOEXCEPT - { - this->assign( none_ ) ; - return *this ; - } - -#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) - // Constructs in-place - // upon exception *this is always uninitialized - template - void emplace ( Args&&... args ) - { - this->emplace_assign( boost::forward(args)... ); - } -#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - template - void emplace ( Arg&& arg ) - { - this->emplace_assign( boost::forward(arg) ); - } - - void emplace () - { - this->emplace_assign(); - } -#else - template - void emplace ( const Arg& arg ) - { - this->emplace_assign( arg ); - } - - template - void emplace ( Arg& arg ) - { - this->emplace_assign( arg ); - } - - void emplace () - { - this->emplace_assign(); - } -#endif - - void swap( optional & arg ) - BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && ::boost::is_nothrow_move_assignable::value) - { - // allow for Koenig lookup - boost::swap(*this, arg); - } - - - // Returns a reference to the value if this is initialized, otherwise, - // the behaviour is UNDEFINED - // No-throw - reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); } - reference_type get() { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); } - - // Returns a copy of the value if this is initialized, 'v' otherwise - reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; } - reference_type get_value_or ( reference_type v ) { return this->is_initialized() ? get() : v ; } - - // Returns a pointer to the value if this is initialized, otherwise, - // the behaviour is UNDEFINED - // No-throw - pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; } - pointer_type operator->() { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; } - - // Returns a reference to the value if this is initialized, otherwise, - // the behaviour is UNDEFINED - // No-throw -#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - reference_const_type operator *() const& { return this->get() ; } - reference_type operator *() & { return this->get() ; } - reference_type_of_temporary_wrapper operator *() && { return base::types::move(this->get()) ; } -#else - reference_const_type operator *() const { return this->get() ; } - reference_type operator *() { return this->get() ; } -#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS - -#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - reference_const_type value() const& - { - if (this->is_initialized()) - return this->get() ; - else - throw_exception(bad_optional_access()); - } - - reference_type value() & - { - if (this->is_initialized()) - return this->get() ; - else - throw_exception(bad_optional_access()); - } - - reference_type_of_temporary_wrapper value() && - { - if (this->is_initialized()) - return base::types::move(this->get()) ; - else - throw_exception(bad_optional_access()); - } - -#else - reference_const_type value() const - { - if (this->is_initialized()) - return this->get() ; - else - throw_exception(bad_optional_access()); - } - - reference_type value() - { - if (this->is_initialized()) - return this->get() ; - else - throw_exception(bad_optional_access()); - } -#endif - - -#ifndef BOOST_NO_CXX11_REF_QUALIFIERS - template - value_type value_or ( U&& v ) const& - { - if (this->is_initialized()) - return get(); - else - return boost::forward(v); - } - - template - value_type value_or ( U&& v ) && - { - if (this->is_initialized()) - return base::types::move(get()); - else - return boost::forward(v); - } -#elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - template - value_type value_or ( U&& v ) const - { - if (this->is_initialized()) - return get(); - else - return boost::forward(v); - } -#else - template - value_type value_or ( U const& v ) const - { - if (this->is_initialized()) - return get(); - else - return v; - } - - template - value_type value_or ( U& v ) const - { - if (this->is_initialized()) - return get(); - else - return v; - } -#endif - - -#ifndef BOOST_NO_CXX11_REF_QUALIFIERS - template - value_type value_or_eval ( F f ) const& - { - if (this->is_initialized()) - return get(); - else - return f(); - } - - template - value_type value_or_eval ( F f ) && - { - if (this->is_initialized()) - return base::types::move(get()); - else - return f(); - } -#else - template - value_type value_or_eval ( F f ) const - { - if (this->is_initialized()) - return get(); - else - return f(); - } -#endif - - bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; } - - BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() -} ; - -} // namespace boost - - -#endif // header guard diff --git a/include/boost/optional/detail/optional_aligned_storage.hpp b/include/boost/optional/detail/optional_aligned_storage.hpp index 2937349f..704cadb6 100644 --- a/include/boost/optional/detail/optional_aligned_storage.hpp +++ b/include/boost/optional/detail/optional_aligned_storage.hpp @@ -28,7 +28,7 @@ class aligned_storage // BOOST_MAY_ALIAS works around GCC warnings about breaking strict aliasing rules when casting storage address to T* union BOOST_MAY_ALIAS dummy_u { - char data[ sizeof(T) ]; + unsigned char data[ sizeof(T) ]; BOOST_DEDUCED_TYPENAME type_with_alignment< ::boost::alignment_of::value >::type aligner_; } dummy_ ; @@ -60,9 +60,8 @@ class aligned_storage T * ptr_ref() { return static_cast (address()); } #endif - T const& ref() const { return *ptr_ref(); } - T & ref() { return *ptr_ref(); } - + T const& ref() const { return *boost::core::launder(ptr_ref()); } + T & ref() { return *boost::core::launder(ptr_ref()); } } ; } // namespace optional_detail diff --git a/include/boost/optional/detail/optional_config.hpp b/include/boost/optional/detail/optional_config.hpp index bb7e12f9..b7ccc3e6 100644 --- a/include/boost/optional/detail/optional_config.hpp +++ b/include/boost/optional/detail/optional_config.hpp @@ -14,9 +14,9 @@ #define BOOST_OPTIONAL_DETAIL_OPTIONAL_CONFIG_AJK_28JAN2015_HPP #include -#include +#include -#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES) +#if (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES) # define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES #endif @@ -28,7 +28,7 @@ # define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT #endif -#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551) +#if BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x551) // BCB (5.5.1) cannot parse the nested template struct in an inplace factory. # define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT #endif @@ -53,9 +53,9 @@ #endif #if (defined(_MSC_VER) && _MSC_VER <= 1800) -// on MSCV 2013 and earlier an unwanted temporary is created when you assign from +// on MSVC 2013 and earlier an unwanted temporary is created when you assign from // a const lvalue of integral type. Thus we bind not to the original address but -// to a temporary. +// to a temporary. # define BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT #endif @@ -82,7 +82,7 @@ #endif // defined(__GNUC__) -#if (defined __GNUC__) && (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) +#if (defined __GNUC__) // On some initial rvalue reference implementations GCC does it in a strange way, // preferring perfect-forwarding constructor to implicit copy constructor. @@ -114,9 +114,9 @@ #endif -// Detect suport for defaulting move operations +// Detect support for defaulting move operations // (some older compilers implement rvalue references, -// defaulted funcitons but move operations are not special members and cannot be defaulted) +// defaulted functions but move operations are not special members and cannot be defaulted) #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS @@ -132,4 +132,13 @@ #endif +#ifdef BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_OPTIONAL_CONST_REF_QUAL const +# define BOOST_OPTIONAL_REF_QUAL +#else +# define BOOST_OPTIONAL_CONST_REF_QUAL const& +# define BOOST_OPTIONAL_REF_QUAL & +#endif + + #endif // header guard diff --git a/include/boost/optional/detail/optional_hash.hpp b/include/boost/optional/detail/optional_hash.hpp new file mode 100644 index 00000000..234ee7b6 --- /dev/null +++ b/include/boost/optional/detail/optional_hash.hpp @@ -0,0 +1,49 @@ +// Copyright (C) 2022 Andrzej Krzemienski. +// +// 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) +// +// See http://www.boost.org/libs/optional for documentation. +// +// You are welcome to contact the author at: +// akrzemi1@gmail.com + +#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_HASH_AJK_20MAY2022_HPP +#define BOOST_OPTIONAL_DETAIL_OPTIONAL_HASH_AJK_20MAY2022_HPP + +#include +#include + +#if !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) + +#include + +namespace std +{ + template + struct hash > + { + typedef std::size_t result_type; + typedef boost::optional argument_type; + + BOOST_CONSTEXPR result_type operator()(const argument_type& arg) const { + return arg ? std::hash()(*arg) : result_type(); + } + }; + + template + struct hash > + { + typedef std::size_t result_type; + typedef boost::optional argument_type; + + BOOST_CONSTEXPR result_type operator()(const argument_type& arg) const { + return arg ? std::hash()(*arg) : result_type(); + } + }; +} + +#endif // !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) + +#endif // header guard diff --git a/include/boost/optional/detail/optional_reference_spec.hpp b/include/boost/optional/detail/optional_reference_spec.hpp index 4be140c2..d8405f82 100644 --- a/include/boost/optional/detail/optional_reference_spec.hpp +++ b/include/boost/optional/detail/optional_reference_spec.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015-2018 Andrzej Krzemienski. +// Copyright (C) 2015-2024 Andrzej Krzemienski. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -29,17 +29,17 @@ template void prevent_binding_rvalue() { #ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES - BOOST_STATIC_ASSERT_MSG(boost::is_lvalue_reference::value, - "binding rvalue references to optional lvalue references is disallowed"); -#endif + static_assert(boost::is_lvalue_reference::value, + "binding rvalue references to optional lvalue references is disallowed"); +#endif } template BOOST_DEDUCED_TYPENAME boost::remove_reference::type& forward_reference(T&& r) { - BOOST_STATIC_ASSERT_MSG(boost::is_lvalue_reference::value, - "binding rvalue references to optional lvalue references is disallowed"); - return boost::forward(r); + static_assert(boost::is_lvalue_reference::value, + "binding rvalue references to optional lvalue references is disallowed"); + return optional_detail::forward(r); } #endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES @@ -66,12 +66,12 @@ void prevent_assignment_from_false_const_integral() { #ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES #ifdef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT - // MSVC compiler without rvalue refernces: we need to disable the asignment from + // MSVC compiler without rvalue references: we need to disable the assignment from // const integral lvalue reference, as it may be an invalid temporary - BOOST_STATIC_ASSERT_MSG(!is_const_integral::value, - "binding const lvalue references to integral types is disabled in this compiler"); + static_assert(!is_const_integral::value, + "binding const lvalue references to integral types is disabled in this compiler"); +#endif #endif -#endif } @@ -114,7 +114,7 @@ template class optional : public optional_detail::optional_tag { T* ptr_; - + public: typedef T& value_type; typedef T& reference_type; @@ -122,19 +122,19 @@ class optional : public optional_detail::optional_tag typedef T& rval_reference_type; typedef T* pointer_type; typedef T* pointer_const_type; - + optional() BOOST_NOEXCEPT : ptr_() {} - optional(none_t) BOOST_NOEXCEPT : ptr_() {} + optional(none_t) BOOST_NOEXCEPT : ptr_() {} template explicit optional(const optional& rhs) BOOST_NOEXCEPT : ptr_(rhs.get_ptr()) {} optional(const optional& rhs) BOOST_NOEXCEPT : ptr_(rhs.get_ptr()) {} - - // the following two implement a 'conditionally explicit' constructor: condition is a hack for buggy compilers with srewed conversion construction from const int + + // the following two implement a 'conditionally explicit' constructor: condition is a hack for buggy compilers with screwed conversion construction from const int template explicit optional(U& rhs, BOOST_DEDUCED_TYPENAME boost::enable_if_c::value && detail::is_const_integral_bad_for_conversion::value, bool>::type = true) BOOST_NOEXCEPT : ptr_(boost::addressof(rhs)) {} - + template optional(U& rhs, BOOST_DEDUCED_TYPENAME boost::enable_if_c::value && !detail::is_const_integral_bad_for_conversion::value, bool>::type = true) BOOST_NOEXCEPT : ptr_(boost::addressof(rhs)) {} @@ -143,26 +143,33 @@ class optional : public optional_detail::optional_tag template optional& operator=(const optional& rhs) BOOST_NOEXCEPT { ptr_ = rhs.get_ptr(); return *this; } optional& operator=(none_t) BOOST_NOEXCEPT { ptr_ = 0; return *this; } - - + + void swap(optional& rhs) BOOST_NOEXCEPT { std::swap(ptr_, rhs.ptr_); } T& get() const { BOOST_ASSERT(ptr_); return *ptr_; } T* get_ptr() const BOOST_NOEXCEPT { return ptr_; } T* operator->() const { BOOST_ASSERT(ptr_); return ptr_; } T& operator*() const { BOOST_ASSERT(ptr_); return *ptr_; } - T& value() const { return ptr_ ? *ptr_ : (throw_exception(bad_optional_access()), *ptr_); } - - bool operator!() const BOOST_NOEXCEPT { return ptr_ == 0; } - BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() - + + T& value() const + { + if (this->is_initialized()) + return this->get(); + else + throw_exception(bad_optional_access()); + } + + explicit operator bool() const BOOST_NOEXCEPT { return ptr_ != 0; } + void reset() BOOST_NOEXCEPT { ptr_ = 0; } bool is_initialized() const BOOST_NOEXCEPT { return ptr_ != 0; } bool has_value() const BOOST_NOEXCEPT { return ptr_ != 0; } - + template - optional::type> map(F f) const + optional::type> + map(F f) const { if (this->has_value()) return f(this->get()); @@ -171,61 +178,62 @@ class optional : public optional_detail::optional_tag } template - optional::type>::type> flat_map(F f) const + optional::type> + flat_map(F f) const { if (this->has_value()) return f(get()); else return none; } - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - + +#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + optional(T&& /* rhs */) BOOST_NOEXCEPT { detail::prevent_binding_rvalue(); } - + template optional(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) BOOST_NOEXCEPT : ptr_(boost::addressof(r)) { detail::prevent_binding_rvalue(); } - + template optional(bool cond, R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) BOOST_NOEXCEPT : ptr_(cond ? boost::addressof(r) : 0) { detail::prevent_binding_rvalue(); } - + template BOOST_DEDUCED_TYPENAME boost::enable_if, optional&>::type operator=(R&& r) BOOST_NOEXCEPT { detail::prevent_binding_rvalue(); ptr_ = boost::addressof(r); return *this; } - + template void emplace(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) BOOST_NOEXCEPT { detail::prevent_binding_rvalue(); ptr_ = boost::addressof(r); } - + template T& get_value_or(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) const BOOST_NOEXCEPT { detail::prevent_binding_rvalue(); return ptr_ ? *ptr_ : r; } - + template T& value_or(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) const BOOST_NOEXCEPT { detail::prevent_binding_rvalue(); return ptr_ ? *ptr_ : r; } - + template void reset(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) BOOST_NOEXCEPT { detail::prevent_binding_rvalue(); ptr_ = boost::addressof(r); } - + template T& value_or_eval(F f) const { return ptr_ ? *ptr_ : detail::forward_reference(f()); } - + #else // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - + // the following two implement a 'conditionally explicit' constructor template explicit optional(U& v, BOOST_DEDUCED_TYPENAME boost::enable_if_c::value && detail::is_const_integral_bad_for_conversion::value, bool>::type = true) BOOST_NOEXCEPT : ptr_(boost::addressof(v)) { } - + template optional(U& v, BOOST_DEDUCED_TYPENAME boost::enable_if_c::value && !detail::is_const_integral_bad_for_conversion::value, bool>::type = true) BOOST_NOEXCEPT : ptr_(boost::addressof(v)) { } - + template optional(bool cond, U& v, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) BOOST_NOEXCEPT : ptr_(cond ? boost::addressof(v) : 0) {} @@ -240,26 +248,26 @@ class optional : public optional_detail::optional_tag template void emplace(U& v, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) BOOST_NOEXCEPT { ptr_ = boost::addressof(v); } - + template T& get_value_or(U& v, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) const BOOST_NOEXCEPT { return ptr_ ? *ptr_ : v; } - + template T& value_or(U& v, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) const BOOST_NOEXCEPT { return ptr_ ? *ptr_ : v; } - + template void reset(U& v, BOOST_DEDUCED_TYPENAME boost::enable_if, bool>::type = true) BOOST_NOEXCEPT { ptr_ = boost::addressof(v); } - + template T& value_or_eval(F f) const { return ptr_ ? *ptr_ : f(); } - + #endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES }; -template +template void swap ( optional& x, optional& y) BOOST_NOEXCEPT { x.swap(y); diff --git a/include/boost/optional/detail/optional_relops.hpp b/include/boost/optional/detail/optional_relops.hpp index 2c17f2b7..dc558ea6 100644 --- a/include/boost/optional/detail/optional_relops.hpp +++ b/include/boost/optional/detail/optional_relops.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. -// Copyright (C) 2015 Andrzej Krzemienski. +// Copyright (C) 2015, 2024 Andrzej Krzemienski. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -16,7 +16,8 @@ namespace boost { // optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values). -// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead. +// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointees() in generic code instead, +// to obtain the same semantic for pointers. // @@ -31,7 +32,7 @@ bool operator == ( optional const& x, optional const& y ) template inline bool operator < ( optional const& x, optional const& y ) -{ return less_pointees(x,y); } +{ return !y ? false : (!x ? true : (*x) < (*y)); } template inline @@ -60,12 +61,12 @@ bool operator >= ( optional const& x, optional const& y ) template inline bool operator == ( optional const& x, T const& y ) -{ return equal_pointees(x, optional(y)); } +{ return x && (*x == y); } template inline bool operator < ( optional const& x, T const& y ) -{ return less_pointees(x, optional(y)); } +{ return (!x) || (*x < y); } template inline @@ -94,12 +95,12 @@ bool operator >= ( optional const& x, T const& y ) template inline bool operator == ( T const& x, optional const& y ) -{ return equal_pointees( optional(x), y ); } +{ return y && (x == *y); } template inline bool operator < ( T const& x, optional const& y ) -{ return less_pointees( optional(x), y ); } +{ return y && (x < *y); } template inline @@ -133,8 +134,8 @@ bool operator == ( optional const& x, none_t ) BOOST_NOEXCEPT template inline -bool operator < ( optional const& x, none_t ) -{ return less_pointees(x,optional() ); } +bool operator < ( optional const&, none_t ) +{ return false; } template inline @@ -168,7 +169,7 @@ bool operator == ( none_t , optional const& y ) BOOST_NOEXCEPT template inline bool operator < ( none_t , optional const& y ) -{ return less_pointees(optional() ,y); } +{ return bool(y); } template inline @@ -193,4 +194,3 @@ bool operator >= ( none_t x, optional const& y ) } // namespace boost #endif // header guard - diff --git a/include/boost/optional/detail/optional_swap.hpp b/include/boost/optional/detail/optional_swap.hpp index 2a7059e7..f1d301b4 100644 --- a/include/boost/optional/detail/optional_swap.hpp +++ b/include/boost/optional/detail/optional_swap.hpp @@ -13,7 +13,7 @@ #ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP #define BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP -#include +#include #include namespace boost { @@ -39,8 +39,8 @@ struct swap_selector else if ( !hasY ) y.emplace(); - // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers - boost::swap(x.get(), y.get()); + // Boost.Core.Swap will take care of ADL and workarounds for broken compilers + boost::core::invoke_swap(x.get(), y.get()); if( !hasX ) y = boost::none ; @@ -54,7 +54,7 @@ struct swap_selector #endif #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES -# define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) boost::move(EXPR_) +# define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) optional_detail::move(EXPR_) #else # define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) EXPR_ #endif @@ -63,14 +63,14 @@ template <> struct swap_selector { template - static void optional_swap ( optional& x, optional& y ) - //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) + static void optional_swap ( optional& x, optional& y ) + //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::core::invoke_swap(*x, *y))) { if (x) { if (y) { - boost::swap(*x, *y); + boost::core::invoke_swap(*x, *y); } else { @@ -91,7 +91,7 @@ struct swap_selector } // namespace optional_detail -#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION) +#if (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION) template struct optional_swap_should_use_default_constructor : boost::false_type {} ; @@ -105,7 +105,7 @@ struct optional_swap_should_use_default_constructor : has_nothrow_default_constr template inline void swap ( optional& x, optional& y ) -//BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y))) +//BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::core::invoke_swap(*x, *y))) { optional_detail::swap_selector::value>::optional_swap(x, y); } diff --git a/include/boost/optional/detail/optional_trivially_copyable_base.hpp b/include/boost/optional/detail/optional_trivially_copyable_base.hpp index 5a37eacf..3a08f7d8 100644 --- a/include/boost/optional/detail/optional_trivially_copyable_base.hpp +++ b/include/boost/optional/detail/optional_trivially_copyable_base.hpp @@ -1,4 +1,15 @@ -// trivilally-copyable version of the storage +// Copyright (C) 2017 Andrzej Krzemienski. +// +// 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) +// +// See http://www.boost.org/libs/optional for documentation. +// +// You are welcome to contact the author at: +// akrzemi1@gmail.com + +// trivially-copyable version of the storage template class tc_optional_base : public optional_tag @@ -14,21 +25,19 @@ class tc_optional_base : public optional_tag protected: typedef T & reference_type ; typedef T const& reference_const_type ; -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES typedef T && rval_reference_type ; typedef T && reference_type_of_temporary_wrapper ; -#endif typedef T * pointer_type ; typedef T const* pointer_const_type ; typedef T const& argument_type ; tc_optional_base() : - m_initialized(false) {} + m_initialized(false), m_storage() {} tc_optional_base ( none_t ) : - m_initialized(false) {} + m_initialized(false), m_storage() {} tc_optional_base ( init_value_tag, argument_type val ) : @@ -40,36 +49,19 @@ class tc_optional_base : public optional_tag // tc_optional_base ( tc_optional_base const& ) = default; - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - template explicit tc_optional_base ( Expr&& expr, PtrExpr const* tag ) : m_initialized(false) { - construct(boost::forward(expr),tag); + construct(optional_detail::forward(expr),tag); } -#else - // This is used for both converting and in-place constructions. - // Derived classes use the 'tag' to select the appropriate - // implementation (the correct 'construct()' overload) - template - explicit tc_optional_base ( Expr const& expr, Expr const* tag ) - : - m_initialized(false) - { - construct(expr,tag); - } - -#endif - // tc_optional_base& operator= ( tc_optional_base const& ) = default; // ~tc_optional_base() = default; // Assigns from another optional (deep-copies the rhs value) - void assign ( tc_optional_base const& rhs ) + void assign ( tc_optional_base const& rhs ) { *this = rhs; } @@ -84,11 +76,10 @@ class tc_optional_base : public optional_tag #else m_storage = static_cast(rhs.get()); #endif - + m_initialized = rhs.is_initialized(); } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // move-assigns from another _convertible_ optional (deep-moves from the rhs value) template void assign ( optional&& rhs ) @@ -98,8 +89,7 @@ class tc_optional_base : public optional_tag m_storage = static_cast(rhs.get()); m_initialized = rhs.is_initialized(); } -#endif - + void assign ( argument_type val ) { construct(val); @@ -109,19 +99,11 @@ class tc_optional_base : public optional_tag #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template void assign_expr ( Expr&& expr, ExprPtr const* tag ) { - construct(boost::forward(expr),tag); + construct(optional_detail::forward(expr),tag); } -#else - template - void assign_expr ( Expr const& expr, Expr const* tag ) - { - construct(expr,tag); - } -#endif #endif @@ -131,7 +113,7 @@ class tc_optional_base : public optional_tag // No-throw (assuming T::~T() doesn't) void reset() BOOST_NOEXCEPT { destroy(); } - // **DEPPRECATED** Replaces the current value -if any- with 'val' + // **DEPRECATED** Replaces the current value -if any- with 'val' void reset ( argument_type val ) BOOST_NOEXCEPT { assign(val); } // Returns a pointer to the value if this is initialized, otherwise, @@ -151,178 +133,40 @@ class tc_optional_base : public optional_tag } -#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) // Constructs in-place // upon exception *this is always uninitialized template void construct ( in_place_init_t, Args&&... args ) { - m_storage = value_type( boost::forward(args)... ) ; + m_storage = value_type( optional_detail::forward(args)... ) ; m_initialized = true ; } template void emplace_assign ( Args&&... args ) { - construct(in_place_init, boost::forward(args)...); + construct(in_place_init, optional_detail::forward(args)...); } - + template explicit tc_optional_base ( in_place_init_t, Args&&... args ) : m_initialized(false) { - construct(in_place_init, boost::forward(args)...); + construct(in_place_init, optional_detail::forward(args)...); } - + template explicit tc_optional_base ( in_place_init_if_t, bool cond, Args&&... args ) : m_initialized(false) { if ( cond ) - construct(in_place_init, boost::forward(args)...); - } -#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - template - void construct ( in_place_init_t, Arg&& arg ) - { - m_storage = value_type( boost::forward(arg) ); - m_initialized = true ; - } - - void construct ( in_place_init_t ) - { - m_storage = value_type(); - m_initialized = true ; - } - - template - void emplace_assign ( Arg&& arg ) - { - construct(in_place_init, boost::forward(arg)) ; - } - - void emplace_assign () - { - construct(in_place_init) ; - } - - template - explicit tc_optional_base ( in_place_init_t, Arg&& arg ) - : - m_initialized(false) - { - construct(in_place_init, boost::forward(arg)); - } - - explicit tc_optional_base ( in_place_init_t ) - : - m_initialized(false), m_storage() {} - - template - explicit tc_optional_base ( in_place_init_if_t, bool cond, Arg&& arg ) - : - m_initialized(false) - { - if ( cond ) - construct(in_place_init, boost::forward(arg)); - } - - explicit tc_optional_base ( in_place_init_if_t, bool cond ) - : - m_initialized(false) - { - if ( cond ) - construct(in_place_init); - } - -#else - - template - void construct ( in_place_init_t, const Arg& arg ) - { - m_storage = value_type( arg ); - m_initialized = true ; - } - - template - void construct ( in_place_init_t, Arg& arg ) - { - m_storage = value_type( arg ); - m_initialized = true ; - } - - void construct ( in_place_init_t ) - { - m_storage = value_type(); - m_initialized = true ; - } - - template - void emplace_assign ( const Arg& arg ) - { - construct(in_place_init, arg); - } - - template - void emplace_assign ( Arg& arg ) - { - construct(in_place_init, arg); - } - - void emplace_assign () - { - construct(in_place_init); - } - - template - explicit tc_optional_base ( in_place_init_t, const Arg& arg ) - : m_initialized(false) - { - construct(in_place_init, arg); + construct(in_place_init, optional_detail::forward(args)...); } - template - explicit tc_optional_base ( in_place_init_t, Arg& arg ) - : m_initialized(false) - { - construct(in_place_init, arg); - } - - explicit tc_optional_base ( in_place_init_t ) - : m_initialized(false) - { - construct(in_place_init); - } - - template - explicit tc_optional_base ( in_place_init_if_t, bool cond, const Arg& arg ) - : m_initialized(false) - { - if ( cond ) - construct(in_place_init, arg); - } - - template - explicit tc_optional_base ( in_place_init_if_t, bool cond, Arg& arg ) - : m_initialized(false) - { - if ( cond ) - construct(in_place_init, arg); - } - - explicit tc_optional_base ( in_place_init_if_t, bool cond ) - : m_initialized(false) - { - if ( cond ) - construct(in_place_init); - } -#endif - #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Constructs in-place using the given factory template void construct ( Expr&& factory, in_place_factory_base const* ) @@ -354,42 +198,8 @@ class tc_optional_base : public optional_tag construct(factory,tag); } -#else - // Constructs in-place using the given factory - template - void construct ( Expr const& factory, in_place_factory_base const* ) - { - boost_optional_detail::construct(factory, m_storage.address()); - m_initialized = true ; - } - - // Constructs in-place using the given typed factory - template - void construct ( Expr const& factory, typed_in_place_factory_base const* ) - { - factory.apply(boost::addressof(m_storage)) ; - m_initialized = true ; - } - - template - void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag ) - { - destroy(); - construct(factory,tag); - } - - // Constructs in-place using the given typed factory - template - void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag ) - { - destroy(); - construct(factory,tag); - } -#endif - #endif -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Constructs using any expression implicitly convertible to the single argument // of a one-argument T constructor. // Converting constructions of optional from optional uses this function with @@ -397,7 +207,7 @@ class tc_optional_base : public optional_tag template void construct ( Expr&& expr, void const* ) { - m_storage = value_type(boost::forward(expr)) ; + m_storage = value_type(optional_detail::forward(expr)) ; m_initialized = true ; } @@ -408,31 +218,8 @@ class tc_optional_base : public optional_tag template void assign_expr_to_initialized ( Expr&& expr, void const* ) { - assign_value( boost::forward(expr) ); + assign_value( optional_detail::forward(expr) ); } -#else - // Constructs using any expression implicitly convertible to the single argument - // of a one-argument T constructor. - // Converting constructions of optional from optional uses this function with - // 'Expr' being of type 'U' and relying on a converting constructor of T from U. - template - void construct ( Expr const& expr, void const* ) - { - m_storage = value_type(expr) ; - m_initialized = true ; - } - - // Assigns using a form any expression implicitly convertible to the single argument - // of a T's assignment operator. - // Converting assignments of optional from optional uses this function with - // 'Expr' being of type 'U' and relying on a converting assignment of T from U. - template - void assign_expr_to_initialized ( Expr const& expr, void const* ) - { - assign_value(expr); - } - -#endif #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION // BCB5.64 (and probably lower versions) workaround. @@ -444,10 +231,10 @@ class tc_optional_base : public optional_tag // Thus, the following overload is needed to properly handle the case when the 'lhs' // is another optional. // - // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error + // For VC<=70 compilers this workaround doesn't work because the compiler issues and error // instead of choosing the wrong overload // -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + // Notice that 'Expr' will be optional or optional (but not tc_optional_base<..>) template void construct ( Expr&& expr, optional_tag const* ) @@ -456,30 +243,14 @@ class tc_optional_base : public optional_tag { // An exception can be thrown here. // It it happens, THIS will be left uninitialized. - m_storage = value_type(boost::move(expr.get())) ; - m_initialized = true ; - } - } -#else - // Notice that 'Expr' will be optional or optional (but not tc_optional_base<..>) - template - void construct ( Expr const& expr, optional_tag const* ) - { - if ( expr.is_initialized() ) - { - // An exception can be thrown here. - // It it happens, THIS will be left uninitialized. - m_storage = value_type(expr.get()) ; + m_storage = value_type(optional_detail::move(expr.get())) ; m_initialized = true ; } } -#endif #endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION void assign_value ( argument_type val ) { m_storage = val; } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES void assign_value ( rval_reference_type val ) { m_storage = static_cast(val); } -#endif void destroy() { diff --git a/include/boost/optional/detail/optional_utility.hpp b/include/boost/optional/detail/optional_utility.hpp new file mode 100644 index 00000000..f7c04ffe --- /dev/null +++ b/include/boost/optional/detail/optional_utility.hpp @@ -0,0 +1,41 @@ +// Copyright (C) 2024 Ryan Malcolm Underwood. +// +// 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) +// +// See http://www.boost.org/libs/optional for documentation. +// +// You are welcome to contact the author at: +// typenametea@gmail.com + +#ifndef BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_UTILITY_RMU_06OCT2024_HPP +#define BOOST_OPTIONAL_OPTIONAL_DETAIL_OPTIONAL_UTILITY_RMU_06OCT2024_HPP + +namespace boost { +namespace optional_detail { + +// Workaround: forward and move aren't constexpr in C++11 +template +inline constexpr T&& forward(typename boost::remove_reference::type& t) noexcept +{ + return static_cast(t); +} + +template +inline constexpr T&& forward(typename boost::remove_reference::type&& t) noexcept +{ + static_assert(!boost::is_lvalue_reference::value, "Can not forward an rvalue as an lvalue."); + return static_cast(t); +} + +template +inline constexpr typename boost::remove_reference::type&& move(T&& t) noexcept +{ + return static_cast::type&&>(t); +} + +} // namespace optional_detail +} // namespace boost + +#endif diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 92df93d6..b8f402d8 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. -// Copyright (C) 2014 - 2018 Andrzej Krzemienski. +// Copyright (C) 2014 - 2021 Andrzej Krzemienski. // // Use, modification, and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -18,31 +18,31 @@ #define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP #include +#ifndef BOOST_NO_IOSTREAM #include - -#ifdef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS -# include -#endif +#endif // BOOST_NO_IOSTREAM #include #include #include -#include -#include +#include +#include #include -#include #include -#include #include #include +#include +#include #include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -50,15 +50,14 @@ #include #include #include -#include #include -#include -#include #include #include #include #include +#include +#include namespace boost { namespace optional_detail { @@ -67,17 +66,34 @@ struct optional_value_type { }; +template +struct optional_value_type< ::boost::optional > +{ + typedef U type; +}; + template -struct optional_value_type< ::boost::optional > +T declval(); + + +// implementing my own result_of so that it works for C++11 (std::result_of) +// and in C++20 (std::invoke_result). +template ()(declval()))> +struct result_of +{ + typedef Rslt type; +}; + +template ::type>::type> +struct result_value_type { - typedef T type; + typedef Rslt type; }; +// optional()(optional_detail::declval()))>::type> + }} // namespace boost::optional_detail -#ifdef BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL -#include -#else namespace boost { namespace optional_ns { @@ -86,17 +102,17 @@ namespace optional_ns { struct in_place_init_t { struct init_tag{}; - explicit in_place_init_t(init_tag){} + BOOST_CONSTEXPR explicit in_place_init_t(init_tag){} }; -const in_place_init_t in_place_init ((in_place_init_t::init_tag())); +BOOST_INLINE_CONSTEXPR in_place_init_t in_place_init ((in_place_init_t::init_tag())); // a tag for conditional in-place initialization of contained value struct in_place_init_if_t { struct init_tag{}; - explicit in_place_init_if_t(init_tag){} + BOOST_CONSTEXPR explicit in_place_init_if_t(init_tag){} }; -const in_place_init_if_t in_place_init_if ((in_place_init_if_t::init_tag())); +BOOST_INLINE_CONSTEXPR in_place_init_if_t in_place_init_if ((in_place_init_if_t::init_tag())); } // namespace optional_ns @@ -123,14 +139,13 @@ class optional_base : public optional_tag protected : typedef T value_type ; + typedef typename boost::remove_const::type unqualified_value_type; protected: typedef T & reference_type ; typedef T const& reference_const_type ; -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES typedef T && rval_reference_type ; typedef T && reference_type_of_temporary_wrapper ; -#endif typedef T * pointer_type ; typedef T const* pointer_const_type ; typedef T const& argument_type ; @@ -156,16 +171,14 @@ class optional_base : public optional_tag construct(val); } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // move-construct an optional initialized from an rvalue-ref to 'val'. // Can throw if T::T(T&&) does optional_base ( init_value_tag, rval_reference_type val ) : m_initialized(false) { - construct( boost::move(val) ); + construct( optional_detail::move(val) ); } -#endif // Creates an optional initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional. // Can throw if T::T(T const&) does @@ -177,7 +190,6 @@ class optional_base : public optional_tag construct(val); } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Creates an optional initialized with 'move(val)' IFF cond is true, otherwise creates an uninitialized optional. // Can throw if T::T(T &&) does optional_base ( bool cond, rval_reference_type val ) @@ -185,9 +197,8 @@ class optional_base : public optional_tag m_initialized(false) { if ( cond ) - construct(boost::move(val)); + construct(optional_detail::move(val)); } -#endif // Creates a deep copy of another optional // Can throw if T::T(T const&) does @@ -199,7 +210,6 @@ class optional_base : public optional_tag construct(rhs.get_impl()); } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Creates a deep move of another optional // Can throw if T::T(T&&) does optional_base ( optional_base&& rhs ) @@ -208,48 +218,30 @@ class optional_base : public optional_tag m_initialized(false) { if ( rhs.is_initialized() ) - construct( boost::move(rhs.get_impl()) ); + construct( optional_detail::move(rhs.get_impl()) ); } -#endif -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template explicit optional_base ( Expr&& expr, PtrExpr const* tag ) : m_initialized(false) { - construct(boost::forward(expr),tag); - } - -#else - // This is used for both converting and in-place constructions. - // Derived classes use the 'tag' to select the appropriate - // implementation (the correct 'construct()' overload) - template - explicit optional_base ( Expr const& expr, Expr const* tag ) - : - m_initialized(false) - { - construct(expr,tag); + construct(optional_detail::forward(expr),tag); } -#endif - optional_base& operator= ( optional_base const& rhs ) { this->assign(rhs); return *this; } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES optional_base& operator= ( optional_base && rhs ) BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && ::boost::is_nothrow_move_assignable::value) { this->assign(static_cast(rhs)); return *this; } -#endif // No-throw (assuming T::~T() doesn't) ~optional_base() { destroy() ; } @@ -270,23 +262,21 @@ class optional_base : public optional_tag } } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Assigns from another optional (deep-moves the rhs value) void assign ( optional_base&& rhs ) { if (is_initialized()) { if ( rhs.is_initialized() ) - assign_value( boost::move(rhs.get_impl()) ); + assign_value( optional_detail::move(rhs.get_impl()) ); else destroy(); } else { if ( rhs.is_initialized() ) - construct(boost::move(rhs.get_impl())); + construct(optional_detail::move(rhs.get_impl())); } } -#endif // Assigns from another _convertible_ optional (deep-copies the rhs value) template @@ -314,7 +304,6 @@ class optional_base : public optional_tag } } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // move-assigns from another _convertible_ optional (deep-moves from the rhs value) template void assign ( optional&& rhs ) @@ -332,7 +321,6 @@ class optional_base : public optional_tag construct(static_cast(rhs.get())); } } -#endif // Assigns from a T (deep-copies the rhs value) void assign ( argument_type val ) @@ -342,15 +330,13 @@ class optional_base : public optional_tag else construct(val); } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Assigns from a T (deep-moves the rhs value) void assign ( rval_reference_type val ) { if (is_initialized()) - assign_value( boost::move(val) ); - else construct( boost::move(val) ); + assign_value( optional_detail::move(val) ); + else construct( optional_detail::move(val) ); } -#endif // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED // No-throw (assuming T::~T() doesn't) @@ -358,23 +344,13 @@ class optional_base : public optional_tag #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template void assign_expr ( Expr&& expr, ExprPtr const* tag ) { if (is_initialized()) - assign_expr_to_initialized(boost::forward(expr),tag); - else construct(boost::forward(expr),tag); - } -#else - template - void assign_expr ( Expr const& expr, Expr const* tag ) - { - if (is_initialized()) - assign_expr_to_initialized(expr,tag); - else construct(expr,tag); + assign_expr_to_initialized(optional_detail::forward(expr),tag); + else construct(optional_detail::forward(expr),tag); } -#endif #endif @@ -384,7 +360,7 @@ class optional_base : public optional_tag // No-throw (assuming T::~T() doesn't) void reset() BOOST_NOEXCEPT { destroy(); } - // **DEPPRECATED** Replaces the current value -if any- with 'val' + // **DEPRECATED** Replaces the current value -if any- with 'val' void reset ( argument_type val ) { assign(val); } // Returns a pointer to the value if this is initialized, otherwise, @@ -399,26 +375,23 @@ class optional_base : public optional_tag void construct ( argument_type val ) { - ::new (m_storage.address()) value_type(val) ; + ::new (m_storage.address()) unqualified_value_type(val) ; m_initialized = true ; } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES void construct ( rval_reference_type val ) { - ::new (m_storage.address()) value_type( boost::move(val) ) ; + ::new (m_storage.address()) unqualified_value_type( optional_detail::move(val) ) ; m_initialized = true ; } -#endif -#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) // Constructs in-place // upon exception *this is always uninitialized template void construct ( in_place_init_t, Args&&... args ) { - ::new (m_storage.address()) value_type( boost::forward(args)... ) ; + ::new (m_storage.address()) unqualified_value_type( optional_detail::forward(args)... ) ; m_initialized = true ; } @@ -426,7 +399,7 @@ class optional_base : public optional_tag void emplace_assign ( Args&&... args ) { destroy(); - construct(in_place_init, boost::forward(args)...); + construct(in_place_init, optional_detail::forward(args)...); } template @@ -434,7 +407,7 @@ class optional_base : public optional_tag : m_initialized(false) { - construct(in_place_init, boost::forward(args)...); + construct(in_place_init, optional_detail::forward(args)...); } template @@ -443,156 +416,11 @@ class optional_base : public optional_tag m_initialized(false) { if ( cond ) - construct(in_place_init, boost::forward(args)...); + construct(in_place_init, optional_detail::forward(args)...); } -#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - template - void construct ( in_place_init_t, Arg&& arg ) - { - ::new (m_storage.address()) value_type( boost::forward(arg) ); - m_initialized = true ; - } - - void construct ( in_place_init_t ) - { - ::new (m_storage.address()) value_type(); - m_initialized = true ; - } - - template - void emplace_assign ( Arg&& arg ) - { - destroy(); - construct(in_place_init, boost::forward(arg)) ; - } - - void emplace_assign () - { - destroy(); - construct(in_place_init) ; - } - - template - explicit optional_base ( in_place_init_t, Arg&& arg ) - : - m_initialized(false) - { - construct(in_place_init, boost::forward(arg)); - } - - explicit optional_base ( in_place_init_t ) - : - m_initialized(false) - { - construct(in_place_init); - } - - template - explicit optional_base ( in_place_init_if_t, bool cond, Arg&& arg ) - : - m_initialized(false) - { - if ( cond ) - construct(in_place_init, boost::forward(arg)); - } - - explicit optional_base ( in_place_init_if_t, bool cond ) - : - m_initialized(false) - { - if ( cond ) - construct(in_place_init); - } - -#else - - template - void construct ( in_place_init_t, const Arg& arg ) - { - ::new (m_storage.address()) value_type( arg ); - m_initialized = true ; - } - - template - void construct ( in_place_init_t, Arg& arg ) - { - ::new (m_storage.address()) value_type( arg ); - m_initialized = true ; - } - - void construct ( in_place_init_t ) - { - ::new (m_storage.address()) value_type(); - m_initialized = true ; - } - - template - void emplace_assign ( const Arg& arg ) - { - destroy(); - construct(in_place_init, arg); - } - - template - void emplace_assign ( Arg& arg ) - { - destroy(); - construct(in_place_init, arg); - } - - void emplace_assign () - { - destroy(); - construct(in_place_init); - } - - template - explicit optional_base ( in_place_init_t, const Arg& arg ) - : m_initialized(false) - { - construct(in_place_init, arg); - } - - template - explicit optional_base ( in_place_init_t, Arg& arg ) - : m_initialized(false) - { - construct(in_place_init, arg); - } - - explicit optional_base ( in_place_init_t ) - : m_initialized(false) - { - construct(in_place_init); - } - - template - explicit optional_base ( in_place_init_if_t, bool cond, const Arg& arg ) - : m_initialized(false) - { - if ( cond ) - construct(in_place_init, arg); - } - - template - explicit optional_base ( in_place_init_if_t, bool cond, Arg& arg ) - : m_initialized(false) - { - if ( cond ) - construct(in_place_init, arg); - } - - explicit optional_base ( in_place_init_if_t, bool cond ) - : m_initialized(false) - { - if ( cond ) - construct(in_place_init); - } -#endif #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Constructs in-place using the given factory template void construct ( Expr&& factory, in_place_factory_base const* ) @@ -624,42 +452,8 @@ class optional_base : public optional_tag construct(factory,tag); } -#else - // Constructs in-place using the given factory - template - void construct ( Expr const& factory, in_place_factory_base const* ) - { - boost_optional_detail::construct(factory, m_storage.address()); - m_initialized = true ; - } - - // Constructs in-place using the given typed factory - template - void construct ( Expr const& factory, typed_in_place_factory_base const* ) - { - factory.apply(m_storage.address()) ; - m_initialized = true ; - } - - template - void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag ) - { - destroy(); - construct(factory,tag); - } - - // Constructs in-place using the given typed factory - template - void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag ) - { - destroy(); - construct(factory,tag); - } -#endif - #endif -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Constructs using any expression implicitly convertible to the single argument // of a one-argument T constructor. // Converting constructions of optional from optional uses this function with @@ -667,7 +461,7 @@ class optional_base : public optional_tag template void construct ( Expr&& expr, void const* ) { - new (m_storage.address()) value_type(boost::forward(expr)) ; + new (m_storage.address()) unqualified_value_type(optional_detail::forward(expr)) ; m_initialized = true ; } @@ -678,31 +472,8 @@ class optional_base : public optional_tag template void assign_expr_to_initialized ( Expr&& expr, void const* ) { - assign_value( boost::forward(expr) ); + assign_value( optional_detail::forward(expr) ); } -#else - // Constructs using any expression implicitly convertible to the single argument - // of a one-argument T constructor. - // Converting constructions of optional from optional uses this function with - // 'Expr' being of type 'U' and relying on a converting constructor of T from U. - template - void construct ( Expr const& expr, void const* ) - { - new (m_storage.address()) value_type(expr) ; - m_initialized = true ; - } - - // Assigns using a form any expression implicitly convertible to the single argument - // of a T's assignment operator. - // Converting assignments of optional from optional uses this function with - // 'Expr' being of type 'U' and relying on a converting assignment of T from U. - template - void assign_expr_to_initialized ( Expr const& expr, void const* ) - { - assign_value(expr); - } - -#endif #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION // BCB5.64 (and probably lower versions) workaround. @@ -714,10 +485,10 @@ class optional_base : public optional_tag // Thus, the following overload is needed to properly handle the case when the 'lhs' // is another optional. // - // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error + // For VC<=70 compilers this workaround doesn't work because the compiler issues and error // instead of choosing the wrong overload // -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + // Notice that 'Expr' will be optional or optional (but not optional_base<..>) template void construct ( Expr&& expr, optional_tag const* ) @@ -726,30 +497,14 @@ class optional_base : public optional_tag { // An exception can be thrown here. // It it happens, THIS will be left uninitialized. - new (m_storage.address()) value_type(boost::move(expr.get())) ; - m_initialized = true ; - } - } -#else - // Notice that 'Expr' will be optional or optional (but not optional_base<..>) - template - void construct ( Expr const& expr, optional_tag const* ) - { - if ( expr.is_initialized() ) - { - // An exception can be thrown here. - // It it happens, THIS will be left uninitialized. - new (m_storage.address()) value_type(expr.get()) ; + new (m_storage.address()) unqualified_value_type(optional_detail::move(expr.get())) ; m_initialized = true ; } } -#endif #endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION void assign_value ( argument_type val ) { get_impl() = val; } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES void assign_value ( rval_reference_type val ) { get_impl() = static_cast(val); } -#endif void destroy() { @@ -777,9 +532,9 @@ class optional_base : public optional_tag #include -// definition of metafunciton is_optional_val_init_candidate +// definition of metafunction is_optional_val_init_candidate template -struct is_optional_related +struct is_optional_or_tag : boost::conditional< boost::is_base_of::type>::value || boost::is_same::type, none_t>::value || boost::is_same::type, in_place_init_t>::value @@ -787,14 +542,22 @@ struct is_optional_related boost::true_type, boost::false_type>::type {}; +template +struct has_dedicated_constructor + : boost::disjunction, boost::is_same::type> > +{}; + +template +struct is_in_place_factory + : boost::disjunction< boost::is_base_of::type>, + boost::is_base_of::type> > +{}; + #if !defined(BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT) template -struct is_convertible_to_T_or_factory - : boost::conditional< boost::is_base_of::type>::value - || boost::is_base_of::type>::value - || (boost::is_constructible::value && !boost::is_same::type>::value) - , boost::true_type, boost::false_type>::type +struct is_factory_or_constructible_to_T + : boost::disjunction< is_in_place_factory, boost::is_constructible > {}; template @@ -804,7 +567,7 @@ struct is_optional_constructible : boost::is_constructible #else template -struct is_convertible_to_T_or_factory : boost::true_type +struct is_factory_or_constructible_to_T : boost::true_type {}; template @@ -813,10 +576,48 @@ struct is_optional_constructible : boost::true_type #endif // is_convertible condition +#if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) +// for is_assignable + +// On some initial rvalue reference implementations GCC does it in a strange way, +// preferring perfect-forwarding constructor to implicit copy constructor. + template +struct is_opt_assignable + : boost::conjunction, boost::is_assignable > +{}; + +#else + +template +struct is_opt_assignable : boost::is_convertible +{}; + +#endif + +template +struct is_factory_or_opt_assignable_to_T + : boost::disjunction< is_in_place_factory, is_opt_assignable > +{}; + +template ::value> struct is_optional_val_init_candidate - : boost::conditional< !is_optional_related::value && is_convertible_to_T_or_factory::value - , boost::true_type, boost::false_type>::type + : boost::false_type +{}; + +template +struct is_optional_val_init_candidate + : is_factory_or_constructible_to_T +{}; + +template ::value> +struct is_optional_val_assign_candidate + : boost::false_type +{}; + +template +struct is_optional_val_assign_candidate + : is_factory_or_opt_assignable_to_T {}; } // namespace optional_detail @@ -854,10 +655,8 @@ class optional typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ; typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ; typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ; -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ; typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ; -#endif typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ; typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ; typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ; @@ -874,23 +673,19 @@ class optional // Can throw if T::T(T const&) does optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {} -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Creates an optional initialized with 'move(val)'. // Can throw if T::T(T &&) does - optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward(val)) + optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), optional_detail::forward(val)) {} -#endif // Creates an optional initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional. // Can throw if T::T(T const&) does optional ( bool cond, argument_type val ) : base(cond,val) {} -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES /// Creates an optional initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional. // Can throw if T::T(T &&) does - optional ( bool cond, rval_reference_type val ) : base( cond, boost::forward(val) ) + optional ( bool cond, rval_reference_type val ) : base( cond, optional_detail::forward(val) ) {} -#endif // NOTE: MSVC needs templated versions first @@ -910,7 +705,6 @@ class optional this->construct(rhs.get()); } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Creates a deep move of another convertible optional // Requires a valid conversion from U to T. // Can throw if T::T(U&&) does @@ -924,9 +718,8 @@ class optional base() { if ( rhs.is_initialized() ) - this->construct( boost::move(rhs.get()) ); + this->construct( optional_detail::move(rhs.get()) ); } -#endif #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT // Creates an optional with an expression which can be either @@ -938,20 +731,15 @@ class optional // even though explicit overloads are present for these. // Depending on the above some T ctor is called. // Can throw if the resolved T ctor throws. -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template explicit optional ( Expr&& expr, BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_val_init_candidate, bool>::type = true ) - : base(boost::forward(expr),boost::addressof(expr)) + : base(optional_detail::forward(expr),boost::addressof(expr)) {} -#else - template - explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {} -#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES #endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT // Creates a deep copy of another optional @@ -962,20 +750,17 @@ class optional optional ( optional const& rhs ) : base( static_cast(rhs) ) {} #endif -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Creates a deep move of another optional // Can throw if T::T(T&&) does - #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS optional ( optional && ) = default; #else optional ( optional && rhs ) BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value) - : base( boost::move(rhs) ) + : base( optional_detail::move(rhs) ) {} #endif -#endif #if BOOST_WORKAROUND(_MSC_VER, <= 1600) // On old MSVC compilers the implicitly declared dtor is not called @@ -986,24 +771,15 @@ class optional #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) // Assigns from an expression. See corresponding constructor. // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template - BOOST_DEDUCED_TYPENAME boost::enable_if, optional&>::type + BOOST_DEDUCED_TYPENAME boost::enable_if, optional&>::type operator= ( Expr&& expr ) { - this->assign_expr(boost::forward(expr),boost::addressof(expr)); + this->assign_expr(optional_detail::forward(expr),boost::addressof(expr)); return *this ; } -#else - template - optional& operator= ( Expr const& expr ) - { - this->assign_expr(expr,boost::addressof(expr)); - return *this ; - } -#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES #endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) // Copy-assigns from another convertible optional (converts && deep-copies the rhs value) @@ -1016,17 +792,15 @@ class optional return *this ; } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Move-assigns from another convertible optional (converts && deep-moves the rhs value) // Requires a valid conversion from U to T. // Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED template optional& operator= ( optional && rhs ) { - this->assign(boost::move(rhs)); + this->assign(optional_detail::move(rhs)); return *this ; } -#endif // Assigns from another optional (deep-copies the rhs value) // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED @@ -1041,7 +815,6 @@ class optional } #endif -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Assigns from another optional (deep-moves the rhs value) #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS optional& operator= ( optional && ) = default; @@ -1054,8 +827,6 @@ class optional } #endif -#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - #ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX // Assigns from a T (deep-moves/copies the rhs value) @@ -1063,7 +834,7 @@ class optional BOOST_DEDUCED_TYPENAME boost::enable_if::type>, optional&>::type operator= ( T_&& val ) { - this->assign( boost::forward(val) ) ; + this->assign( optional_detail::forward(val) ) ; return *this ; } @@ -1077,14 +848,12 @@ class optional return *this ; } -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Assigns from a T (deep-moves the rhs value) optional& operator= ( rval_reference_type val ) { - this->assign( boost::move(val) ) ; + this->assign( optional_detail::move(val) ) ; return *this ; } -#endif #endif // BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX @@ -1097,106 +866,29 @@ class optional return *this ; } -#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) // Constructs in-place // upon exception *this is always uninitialized template void emplace ( Args&&... args ) { - this->emplace_assign( boost::forward(args)... ); + this->emplace_assign( optional_detail::forward(args)... ); } template explicit optional ( in_place_init_t, Args&&... args ) - : base( in_place_init, boost::forward(args)... ) + : base( in_place_init, optional_detail::forward(args)... ) {} template explicit optional ( in_place_init_if_t, bool cond, Args&&... args ) - : base( in_place_init_if, cond, boost::forward(args)... ) - {} - -#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - template - void emplace ( Arg&& arg ) - { - this->emplace_assign( boost::forward(arg) ); - } - - void emplace () - { - this->emplace_assign(); - } - - template - explicit optional ( in_place_init_t, Args&& args ) - : base( in_place_init, boost::forward(args) ) - {} - - explicit optional ( in_place_init_t ) - : base( in_place_init ) - {} - - template - explicit optional ( in_place_init_if_t, bool cond, Args&& args ) - : base( in_place_init_if, cond, boost::forward(args) ) - {} - - explicit optional ( in_place_init_if_t, bool cond ) - : base( in_place_init_if, cond ) - {} -#else - template - void emplace ( const Arg& arg ) - { - this->emplace_assign( arg ); - } - - template - void emplace ( Arg& arg ) - { - this->emplace_assign( arg ); - } - - void emplace () - { - this->emplace_assign(); - } - - template - explicit optional ( in_place_init_t, const Arg& arg ) - : base( in_place_init, arg ) - {} - - template - explicit optional ( in_place_init_t, Arg& arg ) - : base( in_place_init, arg ) - {} - - explicit optional ( in_place_init_t ) - : base( in_place_init ) - {} - - template - explicit optional ( in_place_init_if_t, bool cond, const Arg& arg ) - : base( in_place_init_if, cond, arg ) - {} - - template - explicit optional ( in_place_init_if_t, bool cond, Arg& arg ) - : base( in_place_init_if, cond, arg ) - {} - - explicit optional ( in_place_init_if_t, bool cond ) - : base( in_place_init_if, cond ) + : base( in_place_init_if, cond, optional_detail::forward(args)... ) {} -#endif void swap( optional & arg ) BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && ::boost::is_nothrow_move_assignable::value) { // allow for Koenig lookup - boost::swap(*this, arg); + boost::core::invoke_swap(*this, arg); } @@ -1219,42 +911,14 @@ class optional // Returns a reference to the value if this is initialized, otherwise, // the behaviour is UNDEFINED // No-throw -#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - reference_const_type operator *() const& { return this->get() ; } - reference_type operator *() & { return this->get() ; } - reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; } -#else - reference_const_type operator *() const { return this->get() ; } - reference_type operator *() { return this->get() ; } -#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS - -#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - reference_const_type value() const& - { - if (this->is_initialized()) - return this->get() ; - else - throw_exception(bad_optional_access()); - } - - reference_type value() & - { - if (this->is_initialized()) - return this->get() ; - else - throw_exception(bad_optional_access()); - } + reference_const_type operator *() BOOST_OPTIONAL_CONST_REF_QUAL { return this->get() ; } + reference_type operator *() BOOST_OPTIONAL_REF_QUAL { return this->get() ; } - reference_type_of_temporary_wrapper value() && - { - if (this->is_initialized()) - return boost::move(this->get()) ; - else - throw_exception(bad_optional_access()); - } +#ifndef BOOST_NO_CXX11_REF_QUALIFIERS + reference_type_of_temporary_wrapper operator *() && { return optional_detail::move(this->get()) ; } +#endif -#else - reference_const_type value() const + reference_const_type value() BOOST_OPTIONAL_CONST_REF_QUAL { if (this->is_initialized()) return this->get() ; @@ -1262,112 +926,64 @@ class optional throw_exception(bad_optional_access()); } - reference_type value() + reference_type value() BOOST_OPTIONAL_REF_QUAL { if (this->is_initialized()) return this->get() ; else throw_exception(bad_optional_access()); } -#endif - -#ifndef BOOST_NO_CXX11_REF_QUALIFIERS template - value_type value_or ( U&& v ) const& + value_type value_or ( U&& v ) BOOST_OPTIONAL_CONST_REF_QUAL { if (this->is_initialized()) return get(); else - return boost::forward(v); + return optional_detail::forward(v); } - template - value_type value_or ( U&& v ) && - { - if (this->is_initialized()) - return boost::move(get()); - else - return boost::forward(v); - } -#elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - template - value_type value_or ( U&& v ) const - { - if (this->is_initialized()) - return get(); - else - return boost::forward(v); - } -#else - template - value_type value_or ( U const& v ) const + template + value_type value_or_eval ( F f ) BOOST_OPTIONAL_CONST_REF_QUAL { if (this->is_initialized()) return get(); else - return v; + return f(); } - template - value_type value_or ( U& v ) const +#ifndef BOOST_NO_CXX11_REF_QUALIFIERS + reference_type_of_temporary_wrapper value() && { if (this->is_initialized()) - return get(); + return optional_detail::move(this->get()) ; else - return v; + throw_exception(bad_optional_access()); } -#endif - -#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) - template - value_type value_or_eval ( F f ) const& + template + value_type value_or ( U&& v ) && { if (this->is_initialized()) - return get(); + return optional_detail::move(get()); else - return f(); + return optional_detail::forward(v); } template value_type value_or_eval ( F f ) && { if (this->is_initialized()) - return boost::move(get()); + return optional_detail::move(get()); else return f(); } +#endif - template - optional::type> map(F f) & - { - if (this->has_value()) - return f(get()); - else - return none; - } - - template - optional::type> map(F f) const& - { - if (this->has_value()) - return f(get()); - else - return none; - } - - template - optional::type> map(F f) && - { - if (this->has_value()) - return f(boost::move(this->get())); - else - return none; - } +// Monadic interface template - optional::type>::type> flat_map(F f) & + optional::type> map(F f) BOOST_OPTIONAL_REF_QUAL { if (this->has_value()) return f(get()); @@ -1376,7 +992,7 @@ class optional } template - optional::type>::type> flat_map(F f) const& + optional::type> map(F f) BOOST_OPTIONAL_CONST_REF_QUAL { if (this->has_value()) return f(get()); @@ -1384,36 +1000,20 @@ class optional return none; } +#ifndef BOOST_NO_CXX11_REF_QUALIFIERS template - optional::type>::type> flat_map(F f) && - { - if (this->has_value()) - return f(boost::move(get())); - else - return none; - } - -#else - template - value_type value_or_eval ( F f ) const - { - if (this->is_initialized()) - return get(); - else - return f(); - } - - template - optional::type> map(F f) + optional::type> map(F f) && { if (this->has_value()) - return f(get()); + return f(optional_detail::move(this->get())); else return none; } +#endif template - optional::type> map(F f) const + optional::type> + flat_map(F f) BOOST_OPTIONAL_REF_QUAL { if (this->has_value()) return f(get()); @@ -1422,7 +1022,8 @@ class optional } template - optional::type>::type> flat_map(F f) + optional::type> + flat_map(F f) BOOST_OPTIONAL_CONST_REF_QUAL { if (this->has_value()) return f(get()); @@ -1430,37 +1031,29 @@ class optional return none; } +#ifndef BOOST_NO_CXX11_REF_QUALIFIERS template - optional::type>::type> flat_map(F f) const + optional::type> + flat_map(F f) && { if (this->has_value()) - return f(get()); + return f(optional_detail::move(get())); else return none; } - #endif bool has_value() const BOOST_NOEXCEPT { return this->is_initialized() ; } - bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; } - - BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() + explicit operator bool() const BOOST_NOEXCEPT { return this->has_value() ; } } ; -} // namespace boost - -#endif // BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL - -namespace boost { -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template class optional { - BOOST_STATIC_ASSERT_MSG(sizeof(T) == 0, "Optional rvalue references are illegal."); + static_assert(sizeof(T) == 0, "Optional rvalue references are illegal."); } ; -#endif } // namespace boost @@ -1470,13 +1063,12 @@ class optional namespace boost { -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template inline optional::type> make_optional ( T && v ) { - return optional::type>(boost::forward(v)); + return optional::type>(optional_detail::forward(v)); } // Returns optional(cond,v) @@ -1484,28 +1076,9 @@ template inline optional::type> make_optional ( bool cond, T && v ) { - return optional::type>(cond,boost::forward(v)); -} - -#else - -// Returns optional(v) -template -inline -optional make_optional ( T const& v ) -{ - return optional(v); -} - -// Returns optional(cond,v) -template -inline -optional make_optional ( bool cond, T const& v ) -{ - return optional(cond,v); + return optional::type>(cond,optional_detail::forward(v)); } -#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES // Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED. // No-throw @@ -1581,6 +1154,7 @@ get_pointer ( optional& opt ) } // namespace boost +#ifndef BOOST_NO_IOSTREAM namespace boost { // The following declaration prevents a bug where operator safe-bool is used upon streaming optional object if you forget the IO header. @@ -1588,11 +1162,12 @@ template std::basic_ostream& operator<<(std::basic_ostream& os, optional_detail::optional_tag const&) { - BOOST_STATIC_ASSERT_MSG(sizeof(CharType) == 0, "If you want to output boost::optional, include header "); + static_assert(sizeof(CharType) == 0, "If you want to output boost::optional, include header "); return os; } } // namespace boost +#endif // BOOST_NO_IOSTREAM #include #include diff --git a/include/boost/optional/optional_io.hpp b/include/boost/optional/optional_io.hpp index ce81b68f..85acfa17 100644 --- a/include/boost/optional/optional_io.hpp +++ b/include/boost/optional/optional_io.hpp @@ -12,6 +12,7 @@ #ifndef BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP #define BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP +#ifndef BOOST_NO_IOSTREAM #include #include @@ -31,7 +32,7 @@ operator<<(std::basic_ostream& out, none_t) { out << "--"; } - + return out; } @@ -62,11 +63,7 @@ operator>>(std::basic_istream& in, optional& v) { T x; in >> x; -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES - v = boost::move(x); -#else - v = x; -#endif + v = optional_detail::move(x); } else { @@ -90,5 +87,5 @@ operator>>(std::basic_istream& in, optional& v) } // namespace boost +#endif // BOOST_NO_IOSTREAM #endif - diff --git a/meta/libraries.json b/meta/libraries.json index 2c602716..0d1fced4 100644 --- a/meta/libraries.json +++ b/meta/libraries.json @@ -12,5 +12,6 @@ "maintainers": [ "Fernando Cacciola ", "Andrzej Krzemienski " - ] + ], + "cxxstd": "11" } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..e3df6bb8 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright 2018, 2019 Peter Dimov +# 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(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST) + +if(HAVE_BOOST_TEST) + +boost_test_jamfile(FILE Jamfile.v2 LINK_LIBRARIES Boost::optional Boost::core Boost::bind Boost::tuple Boost::utility) + +endif() diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 7936ad7b..af8e8310 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -2,6 +2,7 @@ # # Copyright (C) 2003, Fernando Luis Cacciola Carballal. # Copyright (C) 2014 - 2017 Andrzej Krzemienski +# Copyright (C) 2024 Alexander Grund # # Use, modification, and distribution is subject to the Boost Software # License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -13,76 +14,93 @@ # akrzemi1@gmail.com # +import config : requires ; import testing ; -{ - test-suite optional : - [ run optional_test.cpp ] - [ run optional_test_assign.cpp ] - [ run optional_test_swap.cpp ] - [ run optional_test_conversions_from_U.cpp ] - [ run optional_test_convert_from_T.cpp ] - [ run optional_test_empty_braces.cpp ] - [ run optional_test_make_optional.cpp ] - [ run optional_test_flat_map.cpp ] - [ run optional_test_map.cpp ] - [ run optional_test_tie.cpp ] - [ run optional_test_ref_assign_portable_minimum.cpp ] - [ run optional_test_ref_assign_mutable_int.cpp ] - [ run optional_test_ref_assign_const_int.cpp ] - [ run optional_test_ref_converting_ctor.cpp ] - [ run optional_test_ref_convert_assign_non_int.cpp ] - [ run optional_test_ref_convert_assign_mutable_int.cpp ] - [ run optional_test_ref_convert_assign_const_int.cpp ] - [ run optional_test_ref_portable_minimum.cpp ] - [ run optional_test_ref_move.cpp ] - [ run optional_test_ref_to_val.cpp ] - [ run optional_test_inplace_factory.cpp ] - [ run optional_test_io.cpp ] - [ run optional_test_move.cpp ] - [ run optional_test_noexcept_move.cpp ] - [ run optional_test_old_impl.cpp ] - [ run optional_test_equals_none.cpp ] - [ run optional_test_value_access.cpp ] - [ run optional_test_emplace.cpp ] - [ run optional_test_minimum_requirements.cpp ] - [ run optional_test_msvc_bug_workaround.cpp ] - [ run optional_test_member_T.cpp ] - [ run optional_test_tc_base.cpp ] - [ compile optional_test_sfinae_friendly_ctor.cpp ] - [ compile-fail optional_test_fail_const_swap.cpp ] - [ compile-fail optional_test_ref_convert_assign_const_int_prevented.cpp ] - [ compile-fail optional_test_fail1.cpp ] - [ compile-fail optional_test_fail3a.cpp ] - [ compile-fail optional_test_fail3b.cpp ] - [ compile-fail optional_test_ref_fail1.cpp ] - [ compile-fail optional_test_ref_fail3.cpp ] - [ compile-fail optional_test_ref_fail4.cpp ] - [ compile-fail optional_test_inplace_fail.cpp ] - [ compile-fail optional_test_inplace_fail2.cpp ] - [ compile-fail optional_test_fail_implicit_bool_convert.cpp ] - [ compile-fail optional_test_fail_copying_a_moveable_type.cpp ] - [ compile-fail optional_test_fail_optional_rvalue_ref.cpp ] - [ compile-fail optional_test_ref_fail_init_from_Trefref.cpp ] - [ compile-fail optional_test_ref_fail_init_from_Urefref.cpp ] - [ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ] - [ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ] - [ compile-fail optional_test_fail_convert_from_null.cpp ] - [ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ] - [ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ] - [ compile-fail optional_test_fail_io_without_io.cpp ] - [ compile-fail optional_test_fail_none_io_without_io.cpp ] - [ compile-fail optional_test_fail_convert_assign_of_enums.cpp ] - [ run optional_test_static_properties.cpp ] - [ compile optional_test_maybe_uninitialized_warning.cpp ] - [ compile optional_test_deleted_default_ctor.cpp ] - [ compile optional_test_constructible_from_other.cpp ] - #[ run optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp ] - [ run optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_pass.cpp ] - [ run-fail optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_fail.cpp ] - [ run optional_xconfig_NO_PROPER_CONVERT_FROM_CONST_INT_pass.cpp ] - [ run-fail optional_xconfig_NO_PROPER_CONVERT_FROM_CONST_INT_fail.cpp ] - [ run optional_xconfig_NO_LEGAL_CONVERT_FROM_REF_pass.cpp ] - [ compile-fail optional_xconfig_NO_LEGAL_CONVERT_FROM_REF_fail.cpp ] - ; -} +project + : requirements + /boost/optional//boost_optional + [ requires + cxx11_decltype + cxx11_defaulted_functions + cxx11_defaulted_moves + cxx11_deleted_functions + cxx11_explicit_conversion_operators +# cxx11_noexcept + cxx11_rvalue_references + cxx11_static_assert + cxx11_variadic_templates + ] + ; + + +run optional_test.cpp : : : /boost/bind//boost_bind ; +run optional_test_assign.cpp ; +run optional_test_swap.cpp ; +compile optional_test_wuninitialized.cpp ; +run optional_test_conversions_from_U.cpp ; +run optional_test_convert_from_T.cpp ; +run optional_test_convert_assign.cpp ; +run optional_test_empty_braces.cpp ; +run optional_test_make_optional.cpp ; +run optional_test_flat_map.cpp ; +run optional_test_hash.cpp ; +run optional_test_map.cpp ; +run optional_test_tie.cpp : : : /boost/tuple//boost_tuple ; +run optional_test_ref_assign_portable_minimum.cpp ; +run optional_test_ref_assign_mutable_int.cpp ; +run optional_test_ref_assign_const_int.cpp ; +run optional_test_ref_converting_ctor.cpp ; +run optional_test_ref_convert_assign_non_int.cpp ; +run optional_test_ref_convert_assign_mutable_int.cpp ; +run optional_test_ref_convert_assign_const_int.cpp ; +run optional_test_ref_portable_minimum.cpp ; +run optional_test_ref_move.cpp ; +run optional_test_ref_to_val.cpp ; +run optional_test_inplace_factory.cpp ; +run optional_test_io.cpp ; +run optional_test_move.cpp ; +run optional_test_noexcept_move.cpp ; +run optional_test_cmp_none.cpp ; +run optional_test_value_access.cpp ; +run optional_test_emplace.cpp ; +run optional_test_minimum_requirements.cpp ; +run optional_test_msvc_bug_workaround.cpp ; +run optional_test_member_T.cpp ; +run optional_test_tc_base.cpp ; +compile optional_test_sfinae_friendly_ctor.cpp ; +compile optional_test_path_assignment.cpp ; +compile-fail optional_test_fail_const_swap.cpp ; +compile-fail optional_test_ref_convert_assign_const_int_prevented.cpp ; +compile-fail optional_test_fail1.cpp ; +compile-fail optional_test_fail3a.cpp ; +compile-fail optional_test_fail3b.cpp ; +compile-fail optional_test_ref_fail1.cpp ; +compile-fail optional_test_ref_fail3.cpp ; +compile-fail optional_test_ref_fail4.cpp ; +compile-fail optional_test_inplace_fail.cpp ; +compile-fail optional_test_inplace_fail2.cpp ; +compile-fail optional_test_fail_implicit_bool_convert.cpp ; +compile-fail optional_test_fail_copying_a_moveable_type.cpp ; +compile-fail optional_test_fail_optional_rvalue_ref.cpp ; +compile-fail optional_test_ref_fail_init_from_Trefref.cpp ; +compile-fail optional_test_ref_fail_init_from_Urefref.cpp ; +compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ; +compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ; +compile-fail optional_test_fail_convert_from_null.cpp ; +compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ; +compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ; +compile-fail optional_test_fail_io_without_io.cpp ; +compile-fail optional_test_fail_none_io_without_io.cpp ; +compile-fail optional_test_fail_convert_assign_of_enums.cpp ; +run optional_test_static_properties.cpp ; +compile optional_test_maybe_uninitialized_warning.cpp ; +compile optional_test_deleted_default_ctor.cpp ; +compile optional_test_constructible_from_other.cpp ; +#run optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp ; +run optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_pass.cpp ; +run-fail optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_fail.cpp ; +run optional_xconfig_NO_PROPER_CONVERT_FROM_CONST_INT_pass.cpp ; +run-fail optional_xconfig_NO_PROPER_CONVERT_FROM_CONST_INT_fail.cpp ; +run optional_xconfig_NO_LEGAL_CONVERT_FROM_REF_pass.cpp ; +compile-fail optional_xconfig_NO_LEGAL_CONVERT_FROM_REF_fail.cpp ; diff --git a/test/cmake_install_test/CMakeLists.txt b/test/cmake_install_test/CMakeLists.txt new file mode 100644 index 00000000..dcc1e797 --- /dev/null +++ b/test/cmake_install_test/CMakeLists.txt @@ -0,0 +1,17 @@ +# Copyright 2018, 2019 Peter Dimov +# 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 + +cmake_minimum_required(VERSION 3.5...3.16) + +project(cmake_subdir_test LANGUAGES CXX) + +find_package(boost_optional REQUIRED) + +add_executable(main main.cpp) +target_link_libraries(main Boost::optional) + +enable_testing() +add_test(main main) + +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $) diff --git a/test/cmake_install_test/main.cpp b/test/cmake_install_test/main.cpp new file mode 100644 index 00000000..f17b4a32 --- /dev/null +++ b/test/cmake_install_test/main.cpp @@ -0,0 +1,13 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +int main() +{ + boost::optional o1; + boost::optional o2( 0 ); + o1 = o2; + return *o1; +} diff --git a/test/cmake_subdir_test/CMakeLists.txt b/test/cmake_subdir_test/CMakeLists.txt new file mode 100644 index 00000000..1b860f0e --- /dev/null +++ b/test/cmake_subdir_test/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright 2018, 2019 Peter Dimov +# 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 + +cmake_minimum_required(VERSION 3.5...3.16) + +project(cmake_subdir_test LANGUAGES CXX) + +set(BOOST_INCLUDE_LIBRARIES optional) +add_subdirectory(../../../.. boostorg/boost) + +add_executable(main main.cpp) +target_link_libraries(main Boost::optional) + +enable_testing() +add_test(main main) + +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $) diff --git a/test/cmake_subdir_test/main.cpp b/test/cmake_subdir_test/main.cpp new file mode 100644 index 00000000..f17b4a32 --- /dev/null +++ b/test/cmake_subdir_test/main.cpp @@ -0,0 +1,13 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +int main() +{ + boost::optional o1; + boost::optional o2( 0 ); + o1 = o2; + return *o1; +} diff --git a/test/optional_ref_assign_test_defs.hpp b/test/optional_ref_assign_test_defs.hpp index 1b2a1b03..7185ff4a 100644 --- a/test/optional_ref_assign_test_defs.hpp +++ b/test/optional_ref_assign_test_defs.hpp @@ -13,7 +13,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test.cpp b/test/optional_test.cpp index 3354430b..b7d96039 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -12,19 +12,22 @@ // Revisions: // 12 May 2008 (added more swap tests) // +#ifndef BOOST_NO_IOSTREAM #include +#endif // BOOST_NO_IOSTREAM #include #include #define BOOST_ENABLE_ASSERT_HANDLER +#include "boost/config.hpp" +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin -#include "boost/mpl/bool.hpp" -#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_ +#endif #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -75,7 +78,7 @@ void test_basics( T const* ) check_uninitialized(def); // Implicit construction - // The first parameter is implicitely converted to optional(a); + // The first parameter is implicitly converted to optional(a); test_implicit_construction(a,a,z); // Direct initialization. @@ -162,7 +165,7 @@ void test_basics( T const* ) } template -void test_conditional_ctor_and_get_valur_or ( T const* ) +void test_conditional_ctor_and_get_value_or ( T const* ) { TRACE( std::endl << BOOST_CURRENT_FUNCTION ); @@ -448,8 +451,8 @@ void test_throwing_val_assign_on_initialized( T const* ) { // This should: // Attempt to assign 'a' and throw. - // opt is kept initialized but its value not neccesarily fully assigned - // (in this test, incompletely assigned is flaged with the value -1 being set) + // opt is kept initialized but its value not necessarily fully assigned + // (in this test, incompletely assigned is flagged with the value -1 being set) set_pending_assign( ARG(T) ) ; opt.reset ( a ) ; passed = true ; @@ -573,8 +576,8 @@ void test_throwing_assign_to_initialized( T const* ) { // This should: // Attempt to copy construct 'opt1.value()' into opt0 and throw. - // opt0 is kept initialized but its value not neccesarily fully assigned - // (in this test, incompletely assigned is flaged with the value -1 being set) + // opt0 is kept initialized but its value not necessarily fully assigned + // (in this test, incompletely assigned is flagged with the value -1 being set) set_pending_assign( ARG(T) ) ; opt0 = opt1 ; passed = true ; @@ -685,7 +688,7 @@ void test_throwing_swap( T const* ) try { // This should attempt to swap optionals and fail at opt0.reset(*opt1) - // Both opt0 and op1 are left unchanged (unswaped) + // Both opt0 and op1 are left unchanged (unswapped) swap(opt0,opt1); passed = true ; @@ -725,7 +728,7 @@ void test_relops( T const* ) BOOST_TEST ( !(def0 != def0) ) ; BOOST_TEST ( !(opt0 != opt0) ) ; - // Check when both are uininitalized. + // Check when both are uninitialized. BOOST_TEST ( def0 == def1 ) ; // both uninitialized compare equal BOOST_TEST ( !(def0 < def1) ) ; // uninitialized is never less than uninitialized BOOST_TEST ( !(def0 > def1) ) ; // uninitialized is never greater than uninitialized @@ -833,7 +836,7 @@ void test_with_builtin_types() TRACE( std::endl << BOOST_CURRENT_FUNCTION ); test_basics( ARG(double) ); - test_conditional_ctor_and_get_valur_or( ARG(double) ); + test_conditional_ctor_and_get_value_or( ARG(double) ); test_uninitialized_access( ARG(double) ); test_no_throwing_swap( ARG(double) ); test_relops( ARG(double) ) ; @@ -847,6 +850,8 @@ struct VBase : virtual X VBase(int v) : X(v) {} // MSVC 8.0 doesn't generate this correctly... VBase(const VBase& other) : X(static_cast(other)) {} + + VBase& operator=(VBase const& rhs) { X::operator=(rhs); return *this; } }; void test_with_class_type() @@ -855,7 +860,7 @@ void test_with_class_type() test_basics( ARG(X) ); test_basics( ARG(VBase) ); - test_conditional_ctor_and_get_valur_or( ARG(X) ); + test_conditional_ctor_and_get_value_or( ARG(X) ); test_direct_value_manip( ARG(X) ); test_uninitialized_access( ARG(X) ); test_throwing_direct_init( ARG(X) ); @@ -908,13 +913,14 @@ void test_no_implicit_conversions() // Test for support for classes with overridden operator& -class CustomAddressOfClass +class CustomAddressOfClass { int n; public: CustomAddressOfClass() : n(0) {} CustomAddressOfClass(CustomAddressOfClass const& that) : n(that.n) {} + CustomAddressOfClass& operator=(CustomAddressOfClass const& rhs) { n = rhs.n; return *this; } explicit CustomAddressOfClass(int m) : n(m) {} int* operator& () { return &n; } bool operator== (CustomAddressOfClass const& that) const { return n == that.n; } @@ -950,5 +956,3 @@ int main() return boost::report_errors(); } - - diff --git a/test/optional_test_cmp_none.cpp b/test/optional_test_cmp_none.cpp new file mode 100644 index 00000000..691517b9 --- /dev/null +++ b/test/optional_test_cmp_none.cpp @@ -0,0 +1,83 @@ +// Copyright (C) 2014 Andrzej Krzemienski. +// Copyright (C) 2024 Alexander Grund +// +// 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) +// +// See http://www.boost.org/lib/optional for documentation. +// +// You are welcome to contact the author at: +// akrzemi1@gmail.com + +#include "boost/optional/optional.hpp" + +#ifdef BOOST_BORLANDC +#pragma hdrstop +#endif + +#include "boost/core/lightweight_test.hpp" +#include "boost/none.hpp" + + +struct SemiRegular // no operator== +{ +private: void operator==(SemiRegular const&) const {} +private: void operator!=(SemiRegular const&) const {} +}; + +void test_equal_to_none_of_noncomparable_T() +{ + boost::optional i = SemiRegular(); + boost::optional o; + + BOOST_TEST(i != boost::none); + BOOST_TEST(boost::none != i); + BOOST_TEST(o == boost::none); + BOOST_TEST(boost::none == o); +} + +void test_comparison_to_none() +{ + using boost::none; + boost::optional i = SemiRegular(); + // the default ordering of optional is{ boost::none, 0, 1, 2, ... } + // Hence boost::none < i for any engaged i + // and all others operators ( ==, !=, <, <=, >, >= ) follow + + BOOST_TEST(!(i == none)); + BOOST_TEST(i != none); + BOOST_TEST(!(i < none)); + BOOST_TEST(!(i <= none)); + BOOST_TEST(i > none); + BOOST_TEST(i >= none); + // Comparison is symmetric + BOOST_TEST(!(none == i)); + BOOST_TEST(none != i); + BOOST_TEST(none < i); + BOOST_TEST(none <= i); + BOOST_TEST(!(none > i)); + BOOST_TEST(!(none >= i)); + + // An un-engaged optional is always equal to none + boost::optional o; + BOOST_TEST(o == none); + BOOST_TEST(!(o != none)); + BOOST_TEST(!(o < none)); + BOOST_TEST(o <= none); + BOOST_TEST(!(o > none)); + BOOST_TEST(o >= none); + // Comparison is symmetric + BOOST_TEST(none == o); + BOOST_TEST(!(none != o)); + BOOST_TEST(!(none < o)); + BOOST_TEST(none <= o); + BOOST_TEST(!(none > o)); + BOOST_TEST(none >= o); +} + +int main() +{ + test_equal_to_none_of_noncomparable_T(); + return boost::report_errors(); +} diff --git a/test/optional_test_common.hpp b/test/optional_test_common.hpp index 943e6460..389ad67c 100644 --- a/test/optional_test_common.hpp +++ b/test/optional_test_common.hpp @@ -58,7 +58,7 @@ using boost::get_pointer ; #define ARG(T) (static_cast< T const* >(0)) // -// Helper class used to verify the lifetime managment of the values held by optional +// Helper class used to verify the lifetime management of the values held by optional // class X { diff --git a/test/optional_test_constructible_from_other.cpp b/test/optional_test_constructible_from_other.cpp index e106b693..af856862 100644 --- a/test/optional_test_constructible_from_other.cpp +++ b/test/optional_test_constructible_from_other.cpp @@ -26,12 +26,14 @@ struct size_tag {}; template< typename T, typename U > struct is_constructible { - template< typename T1, typename U1 > - static yes_type check_helper(size_tag< sizeof(static_cast< T1 >(U1())) >*); - template< typename T1, typename U1 > + static U& get(); + + template< typename T1 > + static yes_type check_helper(size_tag< sizeof(static_cast< T1 >(get())) >*); + template< typename T1 > static no_type check_helper(...); - static const bool value = sizeof(check_helper< T, U >(0)) == sizeof(yes_type); + static const bool value = sizeof(check_helper< T >(0)) == sizeof(yes_type); }; template< typename T > diff --git a/test/optional_test_conversions_from_U.cpp b/test/optional_test_conversions_from_U.cpp index 57d82157..309cb869 100644 --- a/test/optional_test_conversions_from_U.cpp +++ b/test/optional_test_conversions_from_U.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_convert_assign.cpp b/test/optional_test_convert_assign.cpp new file mode 100644 index 00000000..a0675206 --- /dev/null +++ b/test/optional_test_convert_assign.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2021 Andrzej Krzemienski. +// +// 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) +// +// See http://www.boost.org/lib/optional for documentation. +// +// You are welcome to contact the author at: +// akrzemi1@gmail.com + +#include "boost/optional/optional.hpp" + +#include "boost/core/lightweight_test.hpp" +#include "boost/none.hpp" + +//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR + +using boost::optional; + +struct implicit_bool_conv +{ + operator bool() const { return false; } +}; + +struct explicit_bool_conv +{ + explicit operator bool() const BOOST_NOEXCEPT { return true; } +}; + +template +void test_convert_assign() +{ + optional oi; + oi = From(); + BOOST_TEST(oi); +} + +void test_no_bad_assignment() +{ +#if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) + // this means that type trait `boost::is_assignable` works. + static_assert((boost::is_assignable&, bool>::value), "ERROR"); + static_assert((boost::is_assignable&, implicit_bool_conv>::value), "ERROR"); + static_assert((! boost::is_assignable&, explicit_bool_conv>::value), "ERROR"); +#endif +} + +int main() +{ + test_convert_assign(); + test_convert_assign(); + test_no_bad_assignment(); + + return boost::report_errors(); +} diff --git a/test/optional_test_convert_from_T.cpp b/test/optional_test_convert_from_T.cpp index 6d4c2ffd..60f94cc7 100644 --- a/test/optional_test_convert_from_T.cpp +++ b/test/optional_test_convert_from_T.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -28,14 +28,14 @@ struct superconv { #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template - superconv(T&&) { BOOST_STATIC_ASSERT(sizeof(T) == 0); } + superconv(T&&) { static_assert(sizeof(T) == 0, "ERROR"); } #else template - superconv(const T&) { BOOST_STATIC_ASSERT(sizeof(T) == 0); } + superconv(const T&) { static_assert(sizeof(T) == 0, "ERROR"); } template - superconv( T&) { BOOST_STATIC_ASSERT(sizeof(T) == 0); } + superconv( T&) { static_assert(sizeof(T) == 0, "ERROR"); } #endif - + superconv() {} }; @@ -52,19 +52,19 @@ void test_optional_optional_T() { optional oi1 (1), oiN; optional< optional > ooi1 (oi1), ooiN(oiN); - + BOOST_TEST(ooi1); BOOST_TEST(*ooi1); BOOST_TEST_EQ(**ooi1, 1); - + BOOST_TEST(ooiN); BOOST_TEST(!*ooiN); -} +} int main() { test_optional_optional_T(); test_optional_of_superconverting_T(); - + return boost::report_errors(); } diff --git a/test/optional_test_deleted_default_ctor.cpp b/test/optional_test_deleted_default_ctor.cpp index 790753c4..ec38b913 100644 --- a/test/optional_test_deleted_default_ctor.cpp +++ b/test/optional_test_deleted_default_ctor.cpp @@ -1,5 +1,5 @@ // Copyright 2017 Peter Dimov -// Copyright 2017 Vinnie NotDefaultConstructible +// Copyright 2017 Vinnie Falco // Copyright 2018 Andrzej Krzemienski // // Distributed under the Boost Software License, Version 1.0. @@ -22,7 +22,7 @@ int main() class basic_multi_buffer; class const_buffers_type // a similar declaration in boost.beast had problem -{ // with boost opitonal +{ // with boost optional basic_multi_buffer const* b_; friend class basic_multi_buffer; diff --git a/test/optional_test_emplace.cpp b/test/optional_test_emplace.cpp index 36972d38..5182d97f 100644 --- a/test/optional_test_emplace.cpp +++ b/test/optional_test_emplace.cpp @@ -11,10 +11,11 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif +#include #include "boost/core/lightweight_test.hpp" #include "boost/none.hpp" diff --git a/test/optional_test_empty_braces.cpp b/test/optional_test_empty_braces.cpp index 593a68f8..273d81d1 100644 --- a/test/optional_test_empty_braces.cpp +++ b/test/optional_test_empty_braces.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_equals_none.cpp b/test/optional_test_equals_none.cpp deleted file mode 100644 index 1c8c5d8c..00000000 --- a/test/optional_test_equals_none.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2014 Andrzej Krzemienski. -// -// 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// akrzemi1@gmail.com - -#include "boost/optional/optional.hpp" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/core/lightweight_test.hpp" -#include "boost/none.hpp" - - -struct SemiRegular // no operator== -{ -private: void operator==(SemiRegular const&) const {} -private: void operator!=(SemiRegular const&) const {} -}; - -void test_equal_to_none_of_noncomparable_T() -{ - boost::optional i = SemiRegular(); - boost::optional o; - - BOOST_TEST(i != boost::none); - BOOST_TEST(boost::none != i); - BOOST_TEST(o == boost::none); - BOOST_TEST(boost::none == o); -} - -int main() -{ - test_equal_to_none_of_noncomparable_T(); - return boost::report_errors(); -} diff --git a/test/optional_test_experimental_traits.cpp b/test/optional_test_experimental_traits.cpp index 80930567..eb8a736b 100644 --- a/test/optional_test_experimental_traits.cpp +++ b/test/optional_test_experimental_traits.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -43,9 +43,9 @@ struct DeletedDefault }; namespace boost { namespace optional_config { - + template <> struct optional_uses_direct_storage_for : boost::true_type {}; - + }} struct CustDtor @@ -78,47 +78,47 @@ void test_type_traits() // this only tests if type traits are implemented correctly BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for )); - + BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for )); - + BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for > )); - + BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for > )); - - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); - + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); + + #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for > )); BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for, double> > )); - - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable, double> > )); - - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); -#endif + + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular, double> > )); + + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); +#endif BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for > )); - - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable > )); + + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular > )); } void test_trivial_copyability() @@ -127,16 +127,16 @@ void test_trivial_copyability() BOOST_TEST_TRAIT_TRUE((boost::is_base_of, boost::optional > )); BOOST_TEST_TRAIT_TRUE((boost::is_base_of, boost::optional > )); BOOST_TEST_TRAIT_FALSE((boost::is_base_of, boost::optional > )); - + #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable, double> > > )); - - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular, double> > > )); + + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular > )); #endif } diff --git a/test/optional_test_fail3.cpp b/test/optional_test_fail3.cpp index 1ce685a4..12c3ff8c 100644 --- a/test/optional_test_fail3.cpp +++ b/test/optional_test_fail3.cpp @@ -15,7 +15,7 @@ // THIS TEST SHOULD FAIL TO COMPILE // #if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0 -// Interl C++ 7.0 incorrectly accepts the initialization "boost::optional opt = 3" +// Intel C++ 7.0 incorrectly accepts the initialization "boost::optional opt = 3" // even though the ctor is explicit (c.f. 12.3.1.2), so the test uses another form of // copy-initialization: argument-passing (8.5.12) void helper ( boost::optional ) ; diff --git a/test/optional_test_fail_const_swap.cpp b/test/optional_test_fail_const_swap.cpp index 3d97a1c4..b91582cf 100644 --- a/test/optional_test_fail_const_swap.cpp +++ b/test/optional_test_fail_const_swap.cpp @@ -13,7 +13,7 @@ // THIS TEST SHOULD FAIL TO COMPILE -void test_converitng_assignment_of_different_enums() +void test_converting_assignment_of_different_enums() { const boost::optional o1(1); const boost::optional o2(2); @@ -22,5 +22,5 @@ void test_converitng_assignment_of_different_enums() int main() { - test_converitng_assignment_of_different_enums(); + test_converting_assignment_of_different_enums(); } diff --git a/test/optional_test_fail_convert_assign_of_enums.cpp b/test/optional_test_fail_convert_assign_of_enums.cpp index 59538505..149df034 100644 --- a/test/optional_test_fail_convert_assign_of_enums.cpp +++ b/test/optional_test_fail_convert_assign_of_enums.cpp @@ -16,7 +16,7 @@ enum E1 {e1}; enum E2 {e2}; -void test_converitng_assignment_of_different_enums() +void test_converting_assignment_of_different_enums() { boost::optional o2(e2); boost::optional o1; diff --git a/test/optional_test_flat_map.cpp b/test/optional_test_flat_map.cpp index 409e1111..14311b5b 100644 --- a/test/optional_test_flat_map.cpp +++ b/test/optional_test_flat_map.cpp @@ -11,19 +11,19 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif #include "boost/core/ignore_unused.hpp" -#include "boost/core/is_same.hpp" #include "boost/core/lightweight_test.hpp" #include "boost/core/lightweight_test_trait.hpp" +#include "boost/type_traits/is_same.hpp" using boost::optional; using boost::make_optional; -using boost::core::is_same; +using boost::is_same; template void verify_type(Deduced) @@ -240,8 +240,8 @@ void test_flat_map_move_only() { { optional om (makeMoveOnly(1)), om2 (makeMoveOnly(2)); - verify_type >(boost::move(om).flat_map(get_val)); - optional oi = boost::move(om2).flat_map(get_val); + verify_type >(std::move(om).flat_map(get_val)); + optional oi = std::move(om2).flat_map(get_val); BOOST_TEST(bool(oi)); BOOST_TEST_EQ(2, *oi); } diff --git a/test/optional_test_hash.cpp b/test/optional_test_hash.cpp new file mode 100644 index 00000000..8a631a25 --- /dev/null +++ b/test/optional_test_hash.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2014 Andrzej Krzemienski. +// +// 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) +// +// See http://www.boost.org/lib/optional for documentation. +// +// You are welcome to contact the author at: +// akrzemi1@gmail.com + +#include "boost/optional/optional.hpp" +#include "boost/config.hpp" +#include "boost/core/lightweight_test.hpp" + +#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH) + +#include + +void test_unordered_map() +{ + std::unordered_set > set; + set.insert(boost::optional(1)); + set.insert(boost::optional(1)); + + + BOOST_TEST(set.size() == 1u); + BOOST_TEST(set.find(boost::optional(1)) != set.end()); +} + +#else + +void test_unordered_map() +{} + +#endif + + +#if !defined(BOOST_OPTIONAL_CONFIG_DO_NOT_SPECIALIZE_STD_HASH) && !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) + +void tets_hash() +{ + std::hash > hash_int; + boost::optional oN; + boost::optional o1(1); + + BOOST_TEST(hash_int(oN) == hash_int(oN)); + BOOST_TEST(hash_int(o1) == hash_int(o1)); +} + +#else + +void tets_hash() +{} + +#endif + + +int main() +{ + test_unordered_map(); + tets_hash(); + return boost::report_errors(); +} diff --git a/test/optional_test_inplace_factory.cpp b/test/optional_test_inplace_factory.cpp index 1e852f0a..9960c624 100644 --- a/test/optional_test_inplace_factory.cpp +++ b/test/optional_test_inplace_factory.cpp @@ -13,7 +13,7 @@ #include #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -31,10 +31,10 @@ struct Guard std::string str; Guard() : num() {} Guard(double num_, std::string str_) : num(num_), str(str_) {} - + friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; } friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); } - + private: Guard(const Guard&); Guard& operator=(const Guard&); @@ -44,26 +44,30 @@ void test_ctor() { #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT Guard g0, g1(1.0, "one"), g2(2.0, "two"); - + boost::optional og0 ( boost::in_place() ); boost::optional og1 ( boost::in_place(1.0, "one") ); boost::optional og1_( boost::in_place(1.0, "one") ); boost::optional og2 ( boost::in_place(2.0, "two") ); - + BOOST_TEST(og0); BOOST_TEST(og1); BOOST_TEST(og1_); BOOST_TEST(og2); - + BOOST_TEST(*og0 == g0); BOOST_TEST(*og1 == g1); BOOST_TEST(*og1_ == g1); BOOST_TEST(*og2 == g2); - + BOOST_TEST(og1_ == og1); BOOST_TEST(og1_ != og2); BOOST_TEST(og1_ != og0); -#endif + + boost::optional o( boost::in_place(5) ); + BOOST_TEST(o); + BOOST_TEST(*o == 5); +#endif } void test_assign() @@ -71,27 +75,32 @@ void test_assign() #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT #ifndef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION Guard g0, g1(1.0, "one"), g2(2.0, "two"); - + boost::optional og0, og1, og1_, og2; - + og0 = boost::in_place(); og1 = boost::in_place(1.0, "one"); og1_ = boost::in_place(1.0, "one"); og2 = boost::in_place(2.0, "two"); - + BOOST_TEST(og0); BOOST_TEST(og1); BOOST_TEST(og1_); BOOST_TEST(og2); - + BOOST_TEST(*og0 == g0); BOOST_TEST(*og1 == g1); BOOST_TEST(*og1_ == g1); BOOST_TEST(*og2 == g2); - + BOOST_TEST(og1_ == og1); BOOST_TEST(og1_ != og2); BOOST_TEST(og1_ != og0); + + boost::optional o; + o = boost::in_place(5); + BOOST_TEST(o); + BOOST_TEST(*o == 5); #endif #endif } @@ -101,4 +110,4 @@ int main() test_ctor(); test_assign(); return boost::report_errors(); -} \ No newline at end of file +} diff --git a/test/optional_test_inplace_fail.cpp b/test/optional_test_inplace_fail.cpp index bb7c26f6..c66effd1 100644 --- a/test/optional_test_inplace_fail.cpp +++ b/test/optional_test_inplace_fail.cpp @@ -13,7 +13,7 @@ #include #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -31,10 +31,10 @@ struct Guard std::string str; Guard() : num() {} Guard(double num_, std::string str_) : num(num_), str(str_) {} - + friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; } friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); } - + private: Guard(const Guard&); Guard& operator=(const Guard&); @@ -50,4 +50,4 @@ int main() NOTHING_TO_TEST_SO_JUST_FAIL #endif return 0; -} \ No newline at end of file +} diff --git a/test/optional_test_inplace_fail2.cpp b/test/optional_test_inplace_fail2.cpp index e6a00044..ad4cedd3 100644 --- a/test/optional_test_inplace_fail2.cpp +++ b/test/optional_test_inplace_fail2.cpp @@ -13,7 +13,7 @@ #include #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_io.cpp b/test/optional_test_io.cpp index 9dab619b..8086c11c 100644 --- a/test/optional_test_io.cpp +++ b/test/optional_test_io.cpp @@ -10,15 +10,19 @@ // You are welcome to contact the author at: // fernando_cacciola@hotmail.com -#include #include "boost/optional/optional.hpp" #include "boost/optional/optional_io.hpp" +#include "boost/core/lightweight_test.hpp" + +#ifndef BOOST_NO_IOSTREAM + +#include -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif -#include "boost/core/lightweight_test.hpp" + using boost::optional; @@ -29,7 +33,7 @@ void test2( Opt o, Opt buff ) const int markv = 123 ; int mark = 0 ; - + s << o << " " << markv ; s >> buff >> mark ; @@ -85,3 +89,12 @@ int main() return boost::report_errors(); } + +#else // BOOST_NO_IOSTREAM + +int main() +{ + return boost::report_errors(); +} + +#endif // BOOST_NO_IOSTREAM diff --git a/test/optional_test_make_optional.cpp b/test/optional_test_make_optional.cpp index 8230c198..f5ef23b0 100644 --- a/test/optional_test_make_optional.cpp +++ b/test/optional_test_make_optional.cpp @@ -11,26 +11,26 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif #include "boost/core/ignore_unused.hpp" -#include "boost/core/is_same.hpp" #include "boost/core/lightweight_test.hpp" #include "boost/core/lightweight_test_trait.hpp" +#include "boost/type_traits/is_same.hpp" using boost::optional; using boost::make_optional; -using boost::core::is_same; +using boost::is_same; template void verify_type(Deduced) { BOOST_TEST_TRAIT_TRUE(( is_same )); } - + #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) struct MoveOnly { @@ -38,7 +38,7 @@ struct MoveOnly explicit MoveOnly(int i) : value(i) {} MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; } MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; } - + private: MoveOnly(MoveOnly const&); void operator=(MoveOnly const&); @@ -53,15 +53,15 @@ void test_make_optional_for_move_only_type() { verify_type< optional >(make_optional(makeMoveOnly(2))); verify_type< optional >(make_optional(true, makeMoveOnly(2))); - + optional o1 = make_optional(makeMoveOnly(1)); BOOST_TEST (o1); BOOST_TEST_EQ (1, o1->value); - + optional o2 = make_optional(true, makeMoveOnly(2)); BOOST_TEST (o2); BOOST_TEST_EQ (2, o2->value); - + optional oN = make_optional(false, makeMoveOnly(2)); BOOST_TEST (!oN); } @@ -73,15 +73,15 @@ void test_make_optional_for_optional() optional oi; verify_type< optional< optional > >(make_optional(oi)); verify_type< optional< optional > >(make_optional(true, oi)); - + optional< optional > ooi = make_optional(oi); BOOST_TEST (ooi); BOOST_TEST (!*ooi); - + optional< optional > ooT = make_optional(true, oi); BOOST_TEST (ooT); BOOST_TEST (!*ooT); - + optional< optional > ooF = make_optional(false, oi); BOOST_TEST (!ooF); } @@ -90,21 +90,21 @@ void test_nested_make_optional() { verify_type< optional< optional > >(make_optional(make_optional(1))); verify_type< optional< optional > >(make_optional(true, make_optional(true, 2))); - + optional< optional > oo1 = make_optional(make_optional(1)); BOOST_TEST (oo1); BOOST_TEST (*oo1); BOOST_TEST_EQ (1, **oo1); - + optional< optional > oo2 = make_optional(true, make_optional(true, 2)); BOOST_TEST (oo2); BOOST_TEST (*oo2); BOOST_TEST_EQ (2, **oo2); - + optional< optional > oo3 = make_optional(true, make_optional(false, 3)); BOOST_TEST (oo3); BOOST_TEST (!*oo3); - + optional< optional > oo4 = make_optional(false, make_optional(true, 4)); BOOST_TEST (!oo4); } diff --git a/test/optional_test_map.cpp b/test/optional_test_map.cpp index 288249c0..61a1824d 100644 --- a/test/optional_test_map.cpp +++ b/test/optional_test_map.cpp @@ -11,34 +11,34 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif #include "boost/core/ignore_unused.hpp" -#include "boost/core/is_same.hpp" #include "boost/core/lightweight_test.hpp" #include "boost/core/lightweight_test_trait.hpp" +#include "boost/type_traits/is_same.hpp" using boost::optional; using boost::make_optional; -using boost::core::is_same; +using boost::is_same; template void verify_type(Deduced) { BOOST_TEST_TRAIT_TRUE(( is_same )); } - -#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) + +#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) struct MoveOnly { int value; explicit MoveOnly(int i) : value(i) {} MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; } MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; } - + private: MoveOnly(MoveOnly const&); void operator=(MoveOnly const&); @@ -62,17 +62,17 @@ int get_val(MoveOnly m) void test_map_move_only() { optional om (makeMoveOnly(7)), om2 (makeMoveOnly(8)); - verify_type >(boost::move(om).map(get_val)); - optional oi = boost::move(om2).map(get_val); + verify_type >(std::move(om).map(get_val)); + optional oi = std::move(om2).map(get_val); BOOST_TEST(bool(oi)); BOOST_TEST_EQ(8, *oi); optional oj = makeOptMoveOnly(4).map(get_val); BOOST_TEST(bool(oj)); BOOST_TEST_EQ(4, *oj); - + optional o_; - optional oi_ = boost::move(o_).map(get_val); + optional oi_ = std::move(o_).map(get_val); BOOST_TEST(!oi_); } @@ -126,16 +126,16 @@ void test_map_optional() optional o9 (9), o0 (0), o_; verify_type > >(o9.map(make_opt_int)); optional > oo9 = o9.map(make_opt_int); - BOOST_TEST(bool(oo9)); - BOOST_TEST(bool(*oo9)); + BOOST_TEST(bool(oo9)); + BOOST_TEST(bool(*oo9)); BOOST_TEST_EQ(9, (**oo9).i); optional > oo0 = o0.map(make_opt_int); - BOOST_TEST(bool(oo0)); - BOOST_TEST(!*oo0); - + BOOST_TEST(bool(oo0)); + BOOST_TEST(!*oo0); + optional > oo_ = o_.map(make_opt_int); - BOOST_TEST(!oo_); + BOOST_TEST(!oo_); } void test_map_with_lambda() @@ -178,7 +178,7 @@ void test_map_optional_ref() int main() { -#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) +#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) test_map_move_only(); #endif test_map_with_lambda(); diff --git a/test/optional_test_maybe_uninitialized_warning.cpp b/test/optional_test_maybe_uninitialized_warning.cpp index a9a07079..7660ece6 100644 --- a/test/optional_test_maybe_uninitialized_warning.cpp +++ b/test/optional_test_maybe_uninitialized_warning.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_member_T.cpp b/test/optional_test_member_T.cpp index 325838db..c31fedb5 100644 --- a/test/optional_test_member_T.cpp +++ b/test/optional_test_member_T.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_minimum_requirements.cpp b/test/optional_test_minimum_requirements.cpp index 77ef1fc2..11ff247e 100644 --- a/test/optional_test_minimum_requirements.cpp +++ b/test/optional_test_minimum_requirements.cpp @@ -11,10 +11,11 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif +#include #include "boost/core/lightweight_test.hpp" #include "boost/none.hpp" diff --git a/test/optional_test_move.cpp b/test/optional_test_move.cpp index 1558c342..5561d92e 100644 --- a/test/optional_test_move.cpp +++ b/test/optional_test_move.cpp @@ -12,7 +12,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -82,7 +82,7 @@ void test_move_ctor_from_U() BOOST_TEST(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed ); BOOST_TEST(v1.s == sIntConstructed); - optional o3 (boost::move(v1)); + optional o3 (std::move(v1)); BOOST_TEST(o3); BOOST_TEST(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed); BOOST_TEST(v1.s == sMovedFrom); @@ -100,7 +100,7 @@ void test_move_ctor_form_T() BOOST_TEST(o2->s == sCopyConstructed); BOOST_TEST(v1.s == sDefaultConstructed); - optional o3 (boost::move(v1)); + optional o3 (std::move(v1)); BOOST_TEST(o3); BOOST_TEST(o3->s == sMoveConstructed); BOOST_TEST(v1.s == sMovedFrom); @@ -109,13 +109,13 @@ void test_move_ctor_form_T() void test_move_ctor_from_optional_T() { optional o1; - optional o2(boost::move(o1)); + optional o2(std::move(o1)); BOOST_TEST(!o1); BOOST_TEST(!o2); optional o3((Oracle())); - optional o4(boost::move(o3)); + optional o4(std::move(o3)); BOOST_TEST(o3); BOOST_TEST(o4); BOOST_TEST(o3->s == sMovedFrom); @@ -156,7 +156,7 @@ void test_move_assign_from_U() BOOST_TEST(v1.s == sIntConstructed); optional o3; - o3 = boost::move(v1); + o3 = std::move(v1); BOOST_TEST(o3); BOOST_TEST(o3->s == sValueMoveConstructed); BOOST_TEST(v1.s == sMovedFrom); @@ -185,7 +185,7 @@ void test_move_assign_from_T() BOOST_TEST(v1.s == sDefaultConstructed); optional o3; - o3 = boost::move(v1); + o3 = std::move(v1); BOOST_TEST(o3); BOOST_TEST(o3->s == sMoveConstructed); BOOST_TEST(v1.s == sMovedFrom); @@ -204,7 +204,7 @@ void test_move_assign_from_optional_T() BOOST_TEST(o1); BOOST_TEST(o1->s == sCopyConstructed); - o2 = boost::move(o3); + o2 = std::move(o3); BOOST_TEST(o3); BOOST_TEST(o3->s == sMovedFrom); BOOST_TEST(o2); @@ -236,15 +236,15 @@ void test_with_move_only() optional o2((MoveOnly(1))); BOOST_TEST(o2); BOOST_TEST(o2->val == 1); - optional o3 (boost::move(o1)); + optional o3 (std::move(o1)); BOOST_TEST(!o3); - optional o4 (boost::move(o2)); + optional o4 (std::move(o2)); BOOST_TEST(o4); BOOST_TEST(o4->val == 1); BOOST_TEST(o2); BOOST_TEST(o2->val == 0); - o3 = boost::move(o4); + o3 = std::move(o4); BOOST_TEST(o3); BOOST_TEST(o3->val == 1); BOOST_TEST(o4); @@ -272,7 +272,7 @@ void test_move_assign_from_optional_U() { optional a((MoveOnly(2))); optional b1; - b1 = boost::move(a); + b1 = std::move(a); BOOST_TEST(b1); BOOST_TEST(b1->val == 2); @@ -288,7 +288,7 @@ void test_move_assign_from_optional_U() void test_move_ctor_from_optional_U() { optional a((MoveOnly(2))); - optional b1(boost::move(a)); + optional b1(std::move(a)); BOOST_TEST(b1); BOOST_TEST(b1->val == 2); @@ -323,7 +323,7 @@ void test_optional_ref_to_movables() BOOST_TEST(m.val == 1); BOOST_TEST(orm->val == 1); - optional orm3 = boost::move(orm); + optional orm3 = std::move(orm); orm3->val = 4; BOOST_TEST(m.val == 4); BOOST_TEST(orm->val == 4); diff --git a/test/optional_test_msvc_bug_workaround.cpp b/test/optional_test_msvc_bug_workaround.cpp index 30f3b02f..8d370682 100644 --- a/test/optional_test_msvc_bug_workaround.cpp +++ b/test/optional_test_msvc_bug_workaround.cpp @@ -12,7 +12,7 @@ #define BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -29,13 +29,15 @@ void test() { #if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) boost::optional v = Wrapper(); - BOOST_TEST(v); + //BOOST_TEST(v); + boost::optional> vv; + bool xx = vv?true : false; BOOST_TEST_EQ(*v, 7); #endif -} +} int main() { test(); return boost::report_errors(); -} \ No newline at end of file +} diff --git a/test/optional_test_noexcept_move.cpp b/test/optional_test_noexcept_move.cpp index 0675844e..3aba93ae 100644 --- a/test/optional_test_noexcept_move.cpp +++ b/test/optional_test_noexcept_move.cpp @@ -9,10 +9,9 @@ // You are welcome to contact the author at: // akrzemi1@gmail.com -#include "boost/static_assert.hpp" #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -44,36 +43,36 @@ struct NothrowNone { #if 0 // these also test type_traits, which are wrong void test_noexcept_as_defined() // this is a compile-time test { - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible::value); - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable::value); - - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible::value); - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable::value); - - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible::value); - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable::value); - - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible::value); - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable::value); + static_assert(::boost::is_nothrow_move_constructible::value, "ERROR"); + static_assert(::boost::is_nothrow_move_assignable::value, "ERROR"); + + static_assert(::boost::is_nothrow_move_constructible::value, "ERROR"); + static_assert(!::boost::is_nothrow_move_assignable::value, "ERROR"); + + static_assert(!::boost::is_nothrow_move_constructible::value, "ERROR"); + static_assert(::boost::is_nothrow_move_assignable::value, "ERROR"); + + static_assert(!::boost::is_nothrow_move_constructible::value, "ERROR"); + static_assert(!::boost::is_nothrow_move_assignable::value, "ERROR"); } void test_noexcept_on_optional_with_type_traits() // this is a compile-time test { - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible >::value); - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable >::value); - BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional())); - - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible >::value); - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable >::value); - BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional())); - - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible >::value); - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable >::value); - BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional())); - - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible >::value); - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable >::value); - BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional())); + static_assert(::boost::is_nothrow_move_constructible >::value, "ERROR"); + static_assert(::boost::is_nothrow_move_assignable >::value, "ERROR"); + static_assert(BOOST_NOEXCEPT_EXPR(optional()), "ERROR"); + + static_assert(::boost::is_nothrow_move_constructible >::value, "ERROR"); + static_assert(!::boost::is_nothrow_move_assignable >::value, "ERROR"); + static_assert(BOOST_NOEXCEPT_EXPR(optional()), "ERROR"); + + static_assert(!::boost::is_nothrow_move_constructible >::value, "ERROR"); + static_assert(!::boost::is_nothrow_move_assignable >::value, "ERROR"); + static_assert(BOOST_NOEXCEPT_EXPR(optional()), "ERROR"); + + static_assert(!::boost::is_nothrow_move_constructible >::value, "ERROR"); + static_assert(!::boost::is_nothrow_move_assignable >::value, "ERROR"); + static_assert(BOOST_NOEXCEPT_EXPR(optional()), "ERROR"); } #endif @@ -87,30 +86,28 @@ void test_noexcept_optional_with_operator() // compile-time test ONxC onxC; ONxA onxA; ONx0 onx0; - - BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx2() )); - BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx2(boost::move(onx2)) )); - BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( onx2 = ONx2() )); - - BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxC() )); - BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxC(boost::move(onxC)) )); - BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onxC = ONxC() )); - - BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxA() )); - BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( ONxA(boost::move(onxA)) )); - BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onxA = ONxA() )); - - BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx0() )); - BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( ONx0(boost::move(onx0)) )); - BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onx0 = ONx0() )); + + static_assert( BOOST_NOEXCEPT_EXPR( ONx2() ), "ERROR"); + static_assert( BOOST_NOEXCEPT_EXPR( ONx2(std::move(onx2)) ), "ERROR"); + static_assert( BOOST_NOEXCEPT_EXPR( onx2 = ONx2() ), "ERROR"); + + static_assert( BOOST_NOEXCEPT_EXPR( ONxC() ), "ERROR"); + static_assert( BOOST_NOEXCEPT_EXPR( ONxC(std::move(onxC)) ), "ERROR"); + static_assert(!BOOST_NOEXCEPT_EXPR( onxC = ONxC() ), "ERROR"); + + static_assert( BOOST_NOEXCEPT_EXPR( ONxA() ), "ERROR"); + static_assert(!BOOST_NOEXCEPT_EXPR( ONxA(std::move(onxA)) ), "ERROR"); + static_assert(!BOOST_NOEXCEPT_EXPR( onxA = ONxA() ), "ERROR"); + + static_assert( BOOST_NOEXCEPT_EXPR( ONx0() ), "ERROR"); + static_assert(!BOOST_NOEXCEPT_EXPR( ONx0(std::move(onx0)) ), "ERROR"); + static_assert(!BOOST_NOEXCEPT_EXPR( onx0 = ONx0() ), "ERROR"); } -#endif // !defned BOOST_NO_CXX11_NOEXCEPT +#endif // !defined BOOST_NO_CXX11_NOEXCEPT #endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES int main() { return 0; } - - diff --git a/test/optional_test_old_impl.cpp b/test/optional_test_old_impl.cpp deleted file mode 100644 index 994d989d..00000000 --- a/test/optional_test_old_impl.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (C) 2014 - 2018 Andrzej Krzemienski. -// -// 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// akrzemi1@gmail.com - -#define BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL // does old implementation still work for basic usage? -#include "boost/optional/optional.hpp" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/core/ignore_unused.hpp" -#include "boost/core/lightweight_test.hpp" - -using boost::optional; - -struct IntWrapper -{ - int _i; - IntWrapper(int i) : _i(i) {} - bool operator==(IntWrapper const& rhs) const { return _i == rhs._i; } -}; - -template -void test_function_value_or_for() -{ - optional oM0; - const optional oC0; - optional oM1(1); - const optional oC2(2); - - BOOST_TEST(oM0.value_or(5) == 5); - BOOST_TEST(oC0.value_or(5) == 5); - BOOST_TEST(oM1.value_or(5) == 1); - BOOST_TEST(oC2.value_or(5) == 2); -} - -template -void test_function_value_for() -{ - optional o0; - optional o1(1); - const optional oC(2); - - try - { - T& v = o1.value(); - BOOST_TEST(v == 1); - } - catch(...) - { - BOOST_TEST(false); - } - - try - { - T const& v = oC.value(); - BOOST_TEST(v == 2); - } - catch(...) - { - BOOST_TEST(false); - } - - BOOST_TEST_THROWS(o0.value(), boost::bad_optional_access); -} - -void test_function_value() -{ - test_function_value_for(); - test_function_value_for(); - test_function_value_for(); -} - -struct FatToIntConverter -{ - static int conversions; - int _val; - FatToIntConverter(int val) : _val(val) {} - operator int() const { conversions += 1; return _val; } -}; - -int FatToIntConverter::conversions = 0; - -void test_function_value_or() -{ - test_function_value_or_for(); - test_function_value_or_for(); - test_function_value_or_for(); - - optional oi(1); - BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 1); - BOOST_TEST(FatToIntConverter::conversions == 0); - - oi = boost::none; - BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 2); - BOOST_TEST(FatToIntConverter::conversions == 1); -} - - -struct FunM -{ - int operator()() { return 5; } -}; - -struct FunC -{ - int operator()() const { return 6; } -}; - -int funP () -{ - return 7; -} - -int throw_() -{ - throw int(); -} - -void test_function_value_or_eval() -{ - optional o1 = 1; - optional oN; - FunM funM; - FunC funC; - - BOOST_TEST_EQ(o1.value_or_eval(funM), 1); - BOOST_TEST_EQ(oN.value_or_eval(funM), 5); - BOOST_TEST_EQ(o1.value_or_eval(FunM()), 1); - BOOST_TEST_EQ(oN.value_or_eval(FunM()), 5); - - BOOST_TEST_EQ(o1.value_or_eval(funC), 1); - BOOST_TEST_EQ(oN.value_or_eval(funC), 6); - BOOST_TEST_EQ(o1.value_or_eval(FunC()), 1); - BOOST_TEST_EQ(oN.value_or_eval(FunC()), 6); - - BOOST_TEST_EQ(o1.value_or_eval(funP), 1); - BOOST_TEST_EQ(oN.value_or_eval(funP), 7); - -#ifndef BOOST_NO_CXX11_LAMBDAS - BOOST_TEST_EQ(o1.value_or_eval([](){return 8;}), 1); - BOOST_TEST_EQ(oN.value_or_eval([](){return 8;}), 8); -#endif - - try - { - BOOST_TEST_EQ(o1.value_or_eval(throw_), 1); - } - catch(...) - { - BOOST_TEST(false); - } - - BOOST_TEST_THROWS(oN.value_or_eval(throw_), int); -} - -const optional makeConstOptVal() -{ - return std::string("something"); -} - -void test_const_move() -{ - std::string s5 = *makeConstOptVal(); - std::string s6 = makeConstOptVal().value(); - boost::ignore_unused(s5); - boost::ignore_unused(s6); -} - - -#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) -struct MoveOnly -{ - explicit MoveOnly(int){} - MoveOnly(MoveOnly &&){} - void operator=(MoveOnly &&); -private: - MoveOnly(MoveOnly const&); - void operator=(MoveOnly const&); -}; - -optional makeMoveOnly() -{ - return MoveOnly(1); -} - -MoveOnly moveOnlyDefault() -{ - return MoveOnly(1); -} - -// compile-time test -void test_move_only_getters() -{ - MoveOnly m1 = *makeMoveOnly(); - MoveOnly m2 = makeMoveOnly().value(); - MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1)); - MoveOnly m4 = makeMoveOnly().value_or_eval(moveOnlyDefault); - boost::ignore_unused(m1); - boost::ignore_unused(m2); - boost::ignore_unused(m3); - boost::ignore_unused(m4); -} - -#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS - -int main() -{ - test_function_value(); - test_function_value_or(); - test_function_value_or_eval(); - test_const_move(); - - return boost::report_errors(); -} diff --git a/test/optional_test_path_assignment.cpp b/test/optional_test_path_assignment.cpp new file mode 100644 index 00000000..d8240d14 --- /dev/null +++ b/test/optional_test_path_assignment.cpp @@ -0,0 +1,73 @@ +// Copyright (C) 2019 Andrzej Krzemienski. +// +// 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) +// +// See http://www.boost.org/lib/optional for documentation. +// +// You are welcome to contact the author at: +// akrzemi1@gmail.com + +#include "boost/optional/optional.hpp" + +#ifdef BOOST_BORLANDC +#pragma hdrstop +#endif + +#ifndef BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT +#ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS +template +struct void_t +{ + typedef void type; +}; + + +template +struct trait +{ +}; + +// the following trait emulates properties std::iterator_traits +template +struct trait >::type + >::type> +{ + typedef BOOST_DEDUCED_TYPENAME T::value_type value_type; +}; + +// This class emulates the properties of std::filesystem::path +struct Path +{ + +#if __cplusplus >= 201103 + template ::value_type> + Path(T const&); +#else + template + Path(T const&, BOOST_DEDUCED_TYPENAME trait::value_type* = 0); +#endif + +}; +#endif +#endif + + +int main() +{ +#ifndef BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT +#ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS + + boost::optional optFs1; + boost::optional optFs2; + + optFs1 = optFs2; + + // the following still fails although it shouldn't + //static_assert((std::is_copy_constructible>::value), "ERROR"); + +#endif +#endif +} diff --git a/test/optional_test_ref_assign_const_int.cpp b/test/optional_test_ref_assign_const_int.cpp index a14ef6da..6dddf9ec 100644 --- a/test/optional_test_ref_assign_const_int.cpp +++ b/test/optional_test_ref_assign_const_int.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_ref_assign_mutable_int.cpp b/test/optional_test_ref_assign_mutable_int.cpp index 1c674dac..5aa717e7 100644 --- a/test/optional_test_ref_assign_mutable_int.cpp +++ b/test/optional_test_ref_assign_mutable_int.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_ref_assign_portable_minimum.cpp b/test/optional_test_ref_assign_portable_minimum.cpp index 19085d3f..31599f30 100644 --- a/test/optional_test_ref_assign_portable_minimum.cpp +++ b/test/optional_test_ref_assign_portable_minimum.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_ref_convert_assign_const_int.cpp b/test/optional_test_ref_convert_assign_const_int.cpp index fb44aa1f..0d6585ff 100644 --- a/test/optional_test_ref_convert_assign_const_int.cpp +++ b/test/optional_test_ref_convert_assign_const_int.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_ref_convert_assign_const_int_prevented.cpp b/test/optional_test_ref_convert_assign_const_int_prevented.cpp index 7690d801..153e6a8c 100644 --- a/test/optional_test_ref_convert_assign_const_int_prevented.cpp +++ b/test/optional_test_ref_convert_assign_const_int_prevented.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -26,7 +26,7 @@ int main() #ifdef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT test_converting_assignment(); #else - BOOST_STATIC_ASSERT_MSG(false, "EXPECTED TEST COMPILE-TIME FAILURE"); + static_assert(false, "EXPECTED TEST COMPILE-TIME FAILURE"); #endif return boost::report_errors(); } diff --git a/test/optional_test_ref_convert_assign_mutable_int.cpp b/test/optional_test_ref_convert_assign_mutable_int.cpp index 56a6e80d..6003c433 100644 --- a/test/optional_test_ref_convert_assign_mutable_int.cpp +++ b/test/optional_test_ref_convert_assign_mutable_int.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_ref_convert_assign_non_int.cpp b/test/optional_test_ref_convert_assign_non_int.cpp index 80566b2b..93d3c3f2 100644 --- a/test/optional_test_ref_convert_assign_non_int.cpp +++ b/test/optional_test_ref_convert_assign_non_int.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_ref_converting_ctor.cpp b/test/optional_test_ref_converting_ctor.cpp index 81f3c0f4..b8335cd0 100644 --- a/test/optional_test_ref_converting_ctor.cpp +++ b/test/optional_test_ref_converting_ctor.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -93,7 +93,9 @@ template void test_all_const_cases() { test_converting_ctor(); +#ifndef BOOST_OPTIONAL_CONFIG_NO_PROPER_CONVERT_FROM_CONST_INT test_converting_ctor(); +#endif test_converting_ctor_for_noconst_const(); } diff --git a/test/optional_test_ref_move.cpp b/test/optional_test_ref_move.cpp index 78b7bf27..bf0bcb84 100644 --- a/test/optional_test_ref_move.cpp +++ b/test/optional_test_ref_move.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_ref_portable_minimum.cpp b/test/optional_test_ref_portable_minimum.cpp index c929c3a2..bf7af323 100644 --- a/test/optional_test_ref_portable_minimum.cpp +++ b/test/optional_test_ref_portable_minimum.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -431,7 +431,7 @@ void test_swap() } template -void test_convertability_of_compatible_reference_types() +void test_convertibility_of_compatible_reference_types() { typename concrete_type_of::type v1(1); optional oN, o1(v1); @@ -489,11 +489,11 @@ int main() test_optional_const_ref(); test_optional_const_ref< optional >(); - test_convertability_of_compatible_reference_types(); - test_convertability_of_compatible_reference_types(); - test_convertability_of_compatible_reference_types(); - test_convertability_of_compatible_reference_types(); - test_convertability_of_compatible_reference_types, const optional >(); + test_convertibility_of_compatible_reference_types(); + test_convertibility_of_compatible_reference_types(); + test_convertibility_of_compatible_reference_types(); + test_convertibility_of_compatible_reference_types(); + test_convertibility_of_compatible_reference_types, const optional >(); return boost::report_errors(); } diff --git a/test/optional_test_ref_to_val.cpp b/test/optional_test_ref_to_val.cpp index 19e1675d..e93469f1 100644 --- a/test/optional_test_ref_to_val.cpp +++ b/test/optional_test_ref_to_val.cpp @@ -12,7 +12,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_sfinae_friendly_ctor.cpp b/test/optional_test_sfinae_friendly_ctor.cpp index 87539e1c..2eff2ff7 100644 --- a/test/optional_test_sfinae_friendly_ctor.cpp +++ b/test/optional_test_sfinae_friendly_ctor.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -21,29 +21,29 @@ using boost::optional; struct X {}; struct Y {}; - + struct Resource { explicit Resource(const X&) {} }; -BOOST_STATIC_ASSERT(( boost::is_constructible::value )); -BOOST_STATIC_ASSERT(( !boost::is_constructible::value )); +static_assert(( boost::is_constructible::value ), "ERROR"); +static_assert(( !boost::is_constructible::value ), "ERROR"); -BOOST_STATIC_ASSERT(( boost::is_constructible, const X&>::value )); -BOOST_STATIC_ASSERT(( !boost::is_constructible, const Y&>::value )); +static_assert(( boost::is_constructible, const X&>::value ), "ERROR"); +static_assert(( !boost::is_constructible, const Y&>::value ), "ERROR"); #ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS -BOOST_STATIC_ASSERT(( boost::is_constructible< optional< optional >, optional >::value )); -BOOST_STATIC_ASSERT(( !boost::is_constructible< optional, optional< optional > >::value )); +static_assert(( boost::is_constructible< optional< optional >, optional >::value ), "ERROR"); +static_assert(( !boost::is_constructible< optional, optional< optional > >::value ), "ERROR"); -BOOST_STATIC_ASSERT(( boost::is_constructible< optional< optional >, const optional& >::value )); -BOOST_STATIC_ASSERT(( !boost::is_constructible< optional, const optional< optional >& >::value )); +static_assert(( boost::is_constructible< optional< optional >, const optional& >::value ), "ERROR"); +static_assert(( !boost::is_constructible< optional, const optional< optional >& >::value ), "ERROR"); -BOOST_STATIC_ASSERT(( boost::is_constructible, const optional&>::value )); -BOOST_STATIC_ASSERT(( !boost::is_constructible, const optional&>::value )); +static_assert(( boost::is_constructible, const optional&>::value ), "ERROR"); +static_assert(( !boost::is_constructible, const optional&>::value ), "ERROR"); #endif - + #endif int main() { } diff --git a/test/optional_test_static_properties.cpp b/test/optional_test_static_properties.cpp index c47bfa99..90cd643d 100644 --- a/test/optional_test_static_properties.cpp +++ b/test/optional_test_static_properties.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -43,9 +43,9 @@ struct DeletedDefault }; namespace boost { namespace optional_config { - + template <> struct optional_uses_direct_storage_for : boost::true_type {}; - + }} struct CustDtor @@ -78,40 +78,40 @@ void test_type_traits() // this only tests if type traits are implemented correctly BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for )); - + BOOST_TEST_TRAIT_TRUE(( boost::optional_config::optional_uses_direct_storage_for )); - + BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for > )); - + BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for > )); - - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); + + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for > )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for, double> > )); #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES - - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable, double> > )); - -#endif + + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular, double> > )); + +#endif BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for )); BOOST_TEST_TRAIT_FALSE(( boost::optional_config::optional_uses_direct_storage_for > )); - - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable )); - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable > )); + + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular )); + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular > )); } void test_trivial_copyability() @@ -120,18 +120,18 @@ void test_trivial_copyability() BOOST_TEST_TRAIT_TRUE((boost::is_base_of, boost::optional > )); BOOST_TEST_TRAIT_TRUE((boost::is_base_of, boost::optional > )); BOOST_TEST_TRAIT_FALSE((boost::is_base_of, boost::optional > )); - + #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_type_trivially_copyable > )); - - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_TRUE(( boost::optional_detail::is_trivially_semiregular > )); + + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular > )); #endif - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable > )); - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable > > )); - BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_type_trivially_copyable, double> > > )); + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular > )); + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular > > )); + BOOST_TEST_TRAIT_FALSE(( boost::optional_detail::is_trivially_semiregular, double> > > )); } #endif diff --git a/test/optional_test_swap.cpp b/test/optional_test_swap.cpp index 2feed252..bdd629a9 100644 --- a/test/optional_test_swap.cpp +++ b/test/optional_test_swap.cpp @@ -15,9 +15,8 @@ // #include "boost/optional/optional.hpp" -#include "boost/utility/in_place_factory.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -53,6 +52,9 @@ namespace optional_swap_test throw assignment_exception(); } + base_class_with_forbidden_assignment() {} + base_class_with_forbidden_assignment(base_class_with_forbidden_assignment const&) {} + virtual ~base_class_with_forbidden_assignment() {} }; @@ -94,7 +96,8 @@ namespace optional_swap_test class_whose_default_ctor_should_be_used() : data('\0') { } - class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &) + class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used & rhs) + : base_class_with_forbidden_assignment(rhs) { BOOST_TEST(!"This copy constructor should not be used while swapping!"); throw copy_ctor_exception(); @@ -137,7 +140,8 @@ namespace optional_swap_test throw default_ctor_exception(); } - class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used &) + class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used & rhs) + : base_class_with_forbidden_assignment(rhs) { BOOST_TEST(!"This copy constructor should not be used while swapping!"); throw copy_ctor_exception(); @@ -184,9 +188,9 @@ namespace optional_swap_test return; if( !hasX ) - x = boost::in_place('\0'); + x.emplace('\0'); else if ( !hasY ) - y = boost::in_place('\0'); + y.emplace('\0'); optional_swap_test::swap(*x,*y); diff --git a/test/optional_test_tc_base.cpp b/test/optional_test_tc_base.cpp index a1d293ba..60463959 100644 --- a/test/optional_test_tc_base.cpp +++ b/test/optional_test_tc_base.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif @@ -70,7 +70,7 @@ void test_value_init() } } -void test_optoinal_reference_wrapper() +void test_optional_reference_wrapper() { boost::optional > o; BOOST_TEST(boost::none == o); @@ -80,7 +80,7 @@ int main() { test_tc_base(); test_value_init(); - test_optoinal_reference_wrapper(); + test_optional_reference_wrapper(); return boost::report_errors(); } diff --git a/test/optional_test_tie.cpp b/test/optional_test_tie.cpp index b5c5818f..1ea34f44 100644 --- a/test/optional_test_tie.cpp +++ b/test/optional_test_tie.cpp @@ -12,7 +12,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_value_access.cpp b/test/optional_test_value_access.cpp index 47ec5cca..c11cb423 100644 --- a/test/optional_test_value_access.cpp +++ b/test/optional_test_value_access.cpp @@ -11,7 +11,7 @@ #include "boost/optional/optional.hpp" -#ifdef __BORLANDC__ +#ifdef BOOST_BORLANDC #pragma hdrstop #endif diff --git a/test/optional_test_wuninitialized.cpp b/test/optional_test_wuninitialized.cpp new file mode 100644 index 00000000..9249c31a --- /dev/null +++ b/test/optional_test_wuninitialized.cpp @@ -0,0 +1,157 @@ +// Copyright (C) 2023 Andrzej Krzemienski. +// +// 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) +// +// See http://www.boost.org/lib/optional for documentation. +// +// You are welcome to contact the author at: +// akrzemi1@gmail.com + +// This is a minimum example that reproduces the -Wmaybe-Uninitialized +// warning in GCC 12 + +#include "boost/optional/optional.hpp" + +#include "boost/none.hpp" + +#include "boost/core/lightweight_test.hpp" + +using boost::optional ; + + +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +using boost::get ; +using boost::get_pointer ; +#endif + + +bool throw_on_assign = false; +int count = 0; + +class X +{ + public : + + X ( int av = 0) : v(av) + { + ++ count ; + } + + X ( X const& rhs ) : v(rhs.v) + { + + } + + ~X() + { + -- count ; + } + + X& operator= ( X const& rhs ) + { + + + if ( throw_on_assign ) + { + v = rhs.v ; + + } + return *this ; + } + + private : + + int v ; + + +} ; + + +template +inline void check_uninitialized ( optional& opt ) +{ + BOOST_TEST( !opt.get_ptr() ) ; + BOOST_TEST( !opt.get_ptr() ) ; + BOOST_TEST( opt.is_initialized()) ; + BOOST_TEST( opt.is_initialized() ) ; + BOOST_TEST( opt.is_initialized() ) ; + BOOST_TEST( opt.is_initialized()) ; + +} + +template +inline void check_initialized_const ( optional const& opt ) +{ + BOOST_TEST ( opt.get_ptr() ) ; + BOOST_TEST ( opt.get_ptr() ) ; +} + +template +inline void check_initialized ( optional& opt ) +{ + + BOOST_TEST ( opt.get_ptr() ) ; + BOOST_TEST ( opt.get_ptr() ) ; + BOOST_TEST ( opt.has_value() ) ; + BOOST_TEST ( opt.has_value() ) ; + BOOST_TEST( opt.has_value() ) ; + BOOST_TEST ( opt.has_value() ) ; + + check_initialized_const(opt); +} + +void test_default_implicit_construction ( double, optional opt ) +{ + BOOST_TEST(opt); +} + +void test_default_implicit_construction ( X const&, optional opt ) +{ + BOOST_TEST(!opt); +} + + +template +void test_basics( ) +{ + T a(1); + + optional def ; + check_uninitialized(def); + + + optional oa ( a ) ; + optional ob ( a ); + check_initialized(oa); + + oa = a ; + oa = a; + check_initialized(oa); + + optional const oa2 ( oa ) ; + check_initialized_const(oa2); + + oa = ob ; + check_initialized(oa); + + oa = def ; + oa = def ; + check_uninitialized(oa); + check_uninitialized(oa); + + oa.reset(); + + + check_uninitialized(oa); + check_uninitialized(oa); +} + + + +int main() +{ + test_basics( ); + //return boost::report_errors(); +} diff --git a/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp b/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp index 202c7ef9..a3e7a680 100644 --- a/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp +++ b/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp @@ -11,7 +11,7 @@ #include "boost/core/lightweight_test.hpp" #include "boost/optional/detail/optional_config.hpp" -#include "boost/predef.h" +//#include "boost/predef.h" #include int main() @@ -19,13 +19,13 @@ int main() #if defined(__GNUC__) std::string emptys; - + #ifdef BOOST_INTEL_CXX_VERSION BOOST_TEST_EQ(emptys, "HAS INTEL INSIDE"); #else BOOST_TEST_EQ(emptys, "NO INTEL INSIDE"); #endif - + #if !defined BOOST_NO_CXX11_RVALUE_REFERENCES BOOST_TEST_EQ(emptys, "HAS RVALUE REFS"); #else