forked from boostorg/utility
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			boost-1.83
			...
			svn-branch
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | dbb99bf7df | 
							
								
								
									
										478
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										478
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,478 +0,0 @@ | ||||
| # Copyright 2021-2022 Andrey Semashev | ||||
| # | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| name: CI | ||||
|  | ||||
| on: | ||||
|   pull_request: | ||||
|   push: | ||||
|     branches: | ||||
|       - master | ||||
|       - develop | ||||
|       - feature/** | ||||
|  | ||||
| concurrency: | ||||
|   group: ${{format('{0}:{1}', github.repository, github.ref)}} | ||||
|   cancel-in-progress: true | ||||
|  | ||||
| env: | ||||
|   GIT_FETCH_JOBS: 8 | ||||
|   NET_RETRY_COUNT: 5 | ||||
|   DEFAULT_BUILD_VARIANT: debug,release | ||||
|  | ||||
| jobs: | ||||
|   posix: | ||||
|     defaults: | ||||
|       run: | ||||
|         shell: bash | ||||
|  | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         include: | ||||
|           # Linux, gcc | ||||
|           - toolset: gcc-4.4 | ||||
|             cxxstd: "98,0x" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:16.04 | ||||
|             install: | ||||
|               - g++-4.4 | ||||
|             sources: | ||||
|               - "ppa:ubuntu-toolchain-r/test" | ||||
|           - toolset: gcc-4.6 | ||||
|             cxxstd: "03,0x" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:16.04 | ||||
|             install: | ||||
|               - g++-4.6 | ||||
|             sources: | ||||
|               - "ppa:ubuntu-toolchain-r/test" | ||||
|           - toolset: gcc-4.7 | ||||
|             cxxstd: "03,11" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:16.04 | ||||
|             install: | ||||
|               - g++-4.7 | ||||
|           - toolset: gcc-4.8 | ||||
|             cxxstd: "03,11" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - g++-4.8 | ||||
|           - toolset: gcc-4.9 | ||||
|             cxxstd: "03,11" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:16.04 | ||||
|             install: | ||||
|               - g++-4.9 | ||||
|           - toolset: gcc-5 | ||||
|             cxxstd: "03,11,14,1z" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:16.04 | ||||
|             install: | ||||
|               - g++-5 | ||||
|           - toolset: gcc-6 | ||||
|             cxxstd: "03,11,14,1z" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - g++-6 | ||||
|           - toolset: gcc-7 | ||||
|             cxxstd: "03,11,14,17" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - g++-7 | ||||
|           - toolset: gcc-8 | ||||
|             cxxstd: "03,11,14,17,2a" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - g++-8 | ||||
|           - toolset: gcc-9 | ||||
|             cxxstd: "03,11,14,17,2a" | ||||
|             os: ubuntu-20.04 | ||||
|             install: | ||||
|               - g++-9 | ||||
|           - toolset: gcc-10 | ||||
|             cxxstd: "03,11,14,17,20" | ||||
|             os: ubuntu-20.04 | ||||
|             install: | ||||
|               - g++-10 | ||||
|           - toolset: gcc-11 | ||||
|             cxxstd: "03,11,14,17,20,23" | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - g++-11 | ||||
|           - toolset: gcc-12 | ||||
|             cxxstd: "03,11,14,17,20,23" | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - g++-12 | ||||
|           - name: UBSAN | ||||
|             toolset: gcc-11 | ||||
|             cxxstd: "03,11,14,17,20,23" | ||||
|             ubsan: 1 | ||||
|             build_variant: debug | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - g++-11 | ||||
|  | ||||
|           # Linux, clang | ||||
|           - toolset: clang | ||||
|             compiler: clang++-3.5 | ||||
|             cxxstd: "03,11" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:16.04 | ||||
|             install: | ||||
|               - clang-3.5 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-3.6 | ||||
|             cxxstd: "03,11,14" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:16.04 | ||||
|             install: | ||||
|               - clang-3.6 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-3.7 | ||||
|             cxxstd: "03,11,14" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:16.04 | ||||
|             install: | ||||
|               - clang-3.7 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-3.8 | ||||
|             cxxstd: "03,11,14" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:16.04 | ||||
|             install: | ||||
|               - clang-3.8 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-3.9 | ||||
|             cxxstd: "03,11,14" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - clang-3.9 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-4.0 | ||||
|             cxxstd: "03,11,14" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - clang-4.0 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-5.0 | ||||
|             cxxstd: "03,11,14,1z" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - clang-5.0 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-6.0 | ||||
|             cxxstd: "03,11,14,17" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - clang-6.0 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-7 | ||||
|             cxxstd: "03,11,14,17" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - clang-7 | ||||
|           # Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode | ||||
|           - toolset: clang | ||||
|             compiler: clang++-8 | ||||
|             cxxstd: "03,11,14,17,2a" | ||||
|             os: ubuntu-latest | ||||
|             container: ubuntu:18.04 | ||||
|             install: | ||||
|               - clang-8 | ||||
|               - g++-7 | ||||
|             gcc_toolchain: 7 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-9 | ||||
|             cxxstd: "03,11,14,17,2a" | ||||
|             os: ubuntu-20.04 | ||||
|             install: | ||||
|               - clang-9 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-10 | ||||
|             cxxstd: "03,11,14,17,20" | ||||
|             os: ubuntu-20.04 | ||||
|             install: | ||||
|               - clang-10 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-11 | ||||
|             cxxstd: "03,11,14,17,20" | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - clang-11 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-12 | ||||
|             cxxstd: "03,11,14,17,20,2b" | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - clang-12 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-13 | ||||
|             cxxstd: "03,11,14,17,20,2b" | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - clang-13 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-14 | ||||
|             cxxstd: "03,11,14,17,20,2b" | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - clang-14 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-15 | ||||
|             cxxstd: "03,11,14,17,20,2b" | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - clang-15 | ||||
|           - toolset: clang | ||||
|             compiler: clang++-16 | ||||
|             cxxstd: "03,11,14,17,20,2b" | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - clang-16 | ||||
|             sources: | ||||
|               - "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main" | ||||
|             source_keys: | ||||
|               - "https://apt.llvm.org/llvm-snapshot.gpg.key" | ||||
|           - toolset: clang | ||||
|             compiler: clang++-16 | ||||
|             cxxstd: "03,11,14,17,20,2b" | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - clang-16 | ||||
|               - libc++-16-dev | ||||
|               - libc++abi-16-dev | ||||
|             sources: | ||||
|               - "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-16 main" | ||||
|             source_keys: | ||||
|               - "https://apt.llvm.org/llvm-snapshot.gpg.key" | ||||
|             cxxflags: -stdlib=libc++ | ||||
|             linkflags: -stdlib=libc++ | ||||
|           - name: UBSAN | ||||
|             toolset: clang | ||||
|             compiler: clang++-15 | ||||
|             cxxstd: "03,11,14,17,20,2b" | ||||
|             cxxflags: -stdlib=libc++ | ||||
|             linkflags: -stdlib=libc++ | ||||
|             ubsan: 1 | ||||
|             build_variant: debug | ||||
|             os: ubuntu-22.04 | ||||
|             install: | ||||
|               - clang-15 | ||||
|               - libc++-15-dev | ||||
|               - libc++abi-15-dev | ||||
|  | ||||
|           - toolset: clang | ||||
|             cxxstd: "03,11,14,17,2a" | ||||
|             os: macos-11 | ||||
|  | ||||
|     timeout-minutes: 60 | ||||
|     runs-on: ${{matrix.os}} | ||||
|     container: ${{matrix.container}} | ||||
|  | ||||
|     steps: | ||||
|       - name: Setup environment | ||||
|         run: | | ||||
|             if [ -f "/etc/debian_version" ] | ||||
|             then | ||||
|                 echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV | ||||
|                 export DEBIAN_FRONTEND=noninteractive | ||||
|             fi | ||||
|             if [ -n "${{matrix.container}}" ] | ||||
|             then | ||||
|                 echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV | ||||
|                 if [ -f "/etc/debian_version" ] | ||||
|                 then | ||||
|                     apt-get -o Acquire::Retries=$NET_RETRY_COUNT update | ||||
|                     if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ] | ||||
|                     then | ||||
|                         PYTHON_PACKAGE="python-is-python3" | ||||
|                     else | ||||
|                         PYTHON_PACKAGE="python" | ||||
|                     fi | ||||
|                     apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ $PYTHON_PACKAGE python3 perl git cmake | ||||
|                 fi | ||||
|             fi | ||||
|             git config --global pack.threads 0 | ||||
|  | ||||
|       - uses: actions/checkout@v3 | ||||
|  | ||||
|       - name: Install packages | ||||
|         if: matrix.install | ||||
|         run: | | ||||
|             declare -a SOURCE_KEYS SOURCES | ||||
|             if [ -n "${{join(matrix.source_keys, ' ')}}" ] | ||||
|             then | ||||
|                 SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}") | ||||
|             fi | ||||
|             if [ -n "${{join(matrix.sources, ' ')}}" ] | ||||
|             then | ||||
|                 SOURCES=("${{join(matrix.sources, '" "')}}") | ||||
|             fi | ||||
|             for key in "${SOURCE_KEYS[@]}" | ||||
|             do | ||||
|                 for i in {1..$NET_RETRY_COUNT} | ||||
|                 do | ||||
|                     echo "Adding key: $key" | ||||
|                     wget -O - "$key" | sudo apt-key add - && break || sleep 2 | ||||
|                 done | ||||
|             done | ||||
|             if [ ${#SOURCES[@]} -gt 0 ] | ||||
|             then | ||||
|                 APT_ADD_REPO_COMMON_ARGS=("-y") | ||||
|                 APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')" | ||||
|                 if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ] | ||||
|                 then | ||||
|                     APT_ADD_REPO_COMMON_ARGS+=("-n") | ||||
|                 fi | ||||
|                 APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)" | ||||
|                 for source in "${SOURCES[@]}" | ||||
|                 do | ||||
|                     for i in {1..$NET_RETRY_COUNT} | ||||
|                     do | ||||
|                         APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}") | ||||
|                         if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ] | ||||
|                         then | ||||
|                             case "$source" in | ||||
|                             "ppa:"*) | ||||
|                                 APT_ADD_REPO_ARGS+=("-P") | ||||
|                                 ;; | ||||
|                             "deb "*) | ||||
|                                 APT_ADD_REPO_ARGS+=("-S") | ||||
|                                 ;; | ||||
|                             *) | ||||
|                                 APT_ADD_REPO_ARGS+=("-U") | ||||
|                                 ;; | ||||
|                             esac | ||||
|                         fi | ||||
|                         APT_ADD_REPO_ARGS+=("$source") | ||||
|                         echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}" | ||||
|                         sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2 | ||||
|                     done | ||||
|                 done | ||||
|             fi | ||||
|             sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update | ||||
|             sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}} | ||||
|  | ||||
|       - name: Setup GCC Toolchain | ||||
|         if: matrix.gcc_toolchain | ||||
|         run: | | ||||
|             GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain" | ||||
|             echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV | ||||
|             MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)" | ||||
|             mkdir -p "$GCC_TOOLCHAIN_ROOT" | ||||
|             ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include" | ||||
|             ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin" | ||||
|             mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET" | ||||
|             ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" | ||||
|  | ||||
|       - name: Setup Boost | ||||
|         run: | | ||||
|             echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY | ||||
|             LIBRARY=${GITHUB_REPOSITORY#*/} | ||||
|             echo LIBRARY: $LIBRARY | ||||
|             echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV | ||||
|             echo GITHUB_BASE_REF: $GITHUB_BASE_REF | ||||
|             echo GITHUB_REF: $GITHUB_REF | ||||
|             REF=${GITHUB_BASE_REF:-$GITHUB_REF} | ||||
|             REF=${REF#refs/heads/} | ||||
|             echo REF: $REF | ||||
|             BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true | ||||
|             echo BOOST_BRANCH: $BOOST_BRANCH | ||||
|             BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null) | ||||
|             echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV | ||||
|             echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV | ||||
|             DEPINST_ARGS=() | ||||
|             GIT_VERSION="$(git --version | sed -e 's/git version //')" | ||||
|             GIT_HAS_JOBS=1 | ||||
|             if [ -f "/etc/debian_version" ] | ||||
|             then | ||||
|                 if $(dpkg --compare-versions "$GIT_VERSION" lt 2.8.0) | ||||
|                 then | ||||
|                     GIT_HAS_JOBS=0 | ||||
|                 fi | ||||
|             else | ||||
|                 declare -a GIT_VER=(${GIT_VERSION//./ }) | ||||
|                 declare -a GIT_MIN_VER=(2 8 0) | ||||
|                 for ((i=0; i<${#GIT_VER[@]}; i++)) | ||||
|                 do | ||||
|                     if [ -z "${GIT_MIN_VER[i]}" ] | ||||
|                     then | ||||
|                         GIT_MIN_VER[i]=0 | ||||
|                     fi | ||||
|                     if [ "${GIT_VER[i]}" -lt "${GIT_MIN_VER[i]}" ] | ||||
|                     then | ||||
|                         GIT_HAS_JOBS=0 | ||||
|                         break | ||||
|                     fi | ||||
|                 done | ||||
|             fi | ||||
|             if [ "$GIT_HAS_JOBS" -ne 0 ] | ||||
|             then | ||||
|                 DEPINST_ARGS+=("--git_args" "--jobs $GIT_FETCH_JOBS") | ||||
|             fi | ||||
|             cd .. | ||||
|             git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root" | ||||
|             cd boost-root | ||||
|             mkdir -p libs/$LIBRARY | ||||
|             cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY | ||||
|             git submodule update --init tools/boostdep | ||||
|             DEPINST_ARGS+=("$LIBRARY") | ||||
|             python tools/boostdep/depinst/depinst.py "${DEPINST_ARGS[@]}" | ||||
|             if [ -z "${{matrix.cmake_tests}}" ] | ||||
|             then | ||||
|                 ./bootstrap.sh | ||||
|                 ./b2 headers | ||||
|                 if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ] | ||||
|                 then | ||||
|                     echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam | ||||
|                     if [ -n "$GCC_TOOLCHAIN_ROOT" ] | ||||
|                     then | ||||
|                         echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam | ||||
|                     fi | ||||
|                     echo " ;" >> ~/user-config.jam | ||||
|                 fi | ||||
|             fi | ||||
|  | ||||
|       - name: Run tests | ||||
|         if: matrix.cmake_tests == '' | ||||
|         run: | | ||||
|             cd ../boost-root | ||||
|             B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}") | ||||
|             if [ -n "${{matrix.build_variant}}" ] | ||||
|             then | ||||
|                 B2_ARGS+=("variant=${{matrix.build_variant}}") | ||||
|             else | ||||
|                 B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT") | ||||
|             fi | ||||
|             if [ -n "${{matrix.threading}}" ] | ||||
|             then | ||||
|                 B2_ARGS+=("threading=${{matrix.threading}}") | ||||
|             fi | ||||
|             if [ -n "${{matrix.ubsan}}" ] | ||||
|             then | ||||
|                 export UBSAN_OPTIONS="print_stacktrace=1" | ||||
|                 B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global") | ||||
|             fi | ||||
|             if [ -n "${{matrix.cxxflags}}" ] | ||||
|             then | ||||
|                 B2_ARGS+=("cxxflags=${{matrix.cxxflags}}") | ||||
|             fi | ||||
|             if [ -n "${{matrix.linkflags}}" ] | ||||
|             then | ||||
|                 B2_ARGS+=("linkflags=${{matrix.linkflags}}") | ||||
|             fi | ||||
|             B2_ARGS+=("libs/$LIBRARY/test") | ||||
|             ./b2 "${B2_ARGS[@]}" | ||||
| @@ -1,24 +0,0 @@ | ||||
| # Copyright 2018 Peter Dimov | ||||
| # Copyright 2018 Andrey Semashev | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| cmake_minimum_required(VERSION 3.5...3.20) | ||||
|  | ||||
| project(boost_utility VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) | ||||
|  | ||||
| add_library(boost_utility INTERFACE) | ||||
| add_library(Boost::utility ALIAS boost_utility) | ||||
|  | ||||
| target_include_directories(boost_utility INTERFACE include) | ||||
|  | ||||
| target_link_libraries(boost_utility | ||||
|     INTERFACE | ||||
|         Boost::config | ||||
|         Boost::core | ||||
|         Boost::io | ||||
|         Boost::preprocessor | ||||
|         Boost::static_assert | ||||
|         Boost::throw_exception | ||||
|         Boost::type_traits | ||||
| ) | ||||
| @@ -57,7 +57,10 @@ aliasing. | ||||
|   </TR> | ||||
|   <TR> | ||||
|     <TD VAlign=top>Validity Test</TD> | ||||
|     <TD VAlign=top> <tt>bool(t)</tt></TD> | ||||
|     <TD VAlign=top> <tt>t</tt><br> | ||||
|       <tt>t != 0</tt><br> | ||||
|       <tt>!!t</tt> | ||||
|      </TD> | ||||
|     <TD VAlign=top> bool </TD> | ||||
|     <TD VAlign=top>If the pointee is valid returns true.<br> | ||||
|       If the pointee is invalid returns false.</TD> | ||||
| @@ -65,7 +68,9 @@ aliasing. | ||||
|   </TR> | ||||
|   <TR> | ||||
|     <TD VAlign=top>Invalidity Test</TD> | ||||
|     <TD VAlign=top> <tt>!t</tt></TD> | ||||
|     <TD VAlign=top> <tt>t == 0</tt><br> | ||||
|                     <tt>!t</tt> | ||||
|     </TD> | ||||
|     <TD VAlign=top> bool </TD> | ||||
|     <TD VAlign=top>If the pointee is valid returns false.<br> | ||||
|       If the pointee is invalid returns true.</TD> | ||||
|   | ||||
							
								
								
									
										26
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,26 +0,0 @@ | ||||
| #  | ||||
|  | ||||
| Boost.Utility, part of collection of the [Boost C++ Libraries](https://github.com/boostorg), provides a number of smaller components, too small to be called libraries in their own right. See the documentation for the list of components. | ||||
|  | ||||
| ### Directories | ||||
|  | ||||
| * **doc** - Documentation sources | ||||
| * **include** - Interface headers of Boost.Utility | ||||
| * **test** - Boost.Utility unit tests | ||||
|  | ||||
| ### More information | ||||
|  | ||||
| * [Documentation](https://boost.org/libs/utility) | ||||
| * [Report bugs](https://github.com/boostorg/utility/issues/new). Be sure to mention Boost version, Boost.Utility component, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. | ||||
| * Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt). | ||||
|  | ||||
| ### Build status | ||||
|  | ||||
| Branch          | GitHub Actions | AppVeyor | Test Matrix | Dependencies | | ||||
| :-------------: | -------------- | -------- | ----------- | ------------ | | ||||
| [`master`](https://github.com/boostorg/utility/tree/master) | [](https://github.com/boostorg/utility/actions?query=branch%3Amaster) | [](https://ci.appveyor.com/project/Lastique/utility/branch/master) | [](http://www.boost.org/development/tests/master/developer/utility.html) | [](https://pdimov.github.io/boostdep-report/master/utility.html) | ||||
| [`develop`](https://github.com/boostorg/utility/tree/develop) | [](https://github.com/boostorg/utility/actions?query=branch%3Adevelop) | [](https://ci.appveyor.com/project/Lastique/utility/branch/develop) | [](http://www.boost.org/development/tests/develop/developer/utility.html) | [](https://pdimov.github.io/boostdep-report/develop/utility.html) | ||||
|  | ||||
| ### License | ||||
|  | ||||
| Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt). | ||||
							
								
								
									
										76
									
								
								addressof_fn_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								addressof_fn_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| #pragma warning(disable: 4710)  // function not inlined | ||||
| #pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| //  addressof_fn_test.cpp: addressof( f ) | ||||
| // | ||||
| //  Copyright (c) 2008, 2009 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 <boost/utility/addressof.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
|  | ||||
| void f0() | ||||
| { | ||||
| } | ||||
|  | ||||
| void f1(int) | ||||
| { | ||||
| } | ||||
|  | ||||
| void f2(int, int) | ||||
| { | ||||
| } | ||||
|  | ||||
| void f3(int, int, int) | ||||
| { | ||||
| } | ||||
|  | ||||
| void f4(int, int, int, int) | ||||
| { | ||||
| } | ||||
|  | ||||
| void f5(int, int, int, int, int) | ||||
| { | ||||
| } | ||||
|  | ||||
| void f6(int, int, int, int, int, int) | ||||
| { | ||||
| } | ||||
|  | ||||
| void f7(int, int, int, int, int, int, int) | ||||
| { | ||||
| } | ||||
|  | ||||
| void f8(int, int, int, int, int, int, int, int) | ||||
| { | ||||
| } | ||||
|  | ||||
| void f9(int, int, int, int, int, int, int, int, int) | ||||
| { | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     BOOST_TEST( boost::addressof( f0 ) == &f0 ); | ||||
|     BOOST_TEST( boost::addressof( f1 ) == &f1 ); | ||||
|     BOOST_TEST( boost::addressof( f2 ) == &f2 ); | ||||
|     BOOST_TEST( boost::addressof( f3 ) == &f3 ); | ||||
|     BOOST_TEST( boost::addressof( f4 ) == &f4 ); | ||||
|     BOOST_TEST( boost::addressof( f5 ) == &f5 ); | ||||
|     BOOST_TEST( boost::addressof( f6 ) == &f6 ); | ||||
|     BOOST_TEST( boost::addressof( f7 ) == &f7 ); | ||||
|     BOOST_TEST( boost::addressof( f8 ) == &f8 ); | ||||
|     BOOST_TEST( boost::addressof( f9 ) == &f9 ); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										94
									
								
								addressof_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								addressof_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| // Copyright (C) 2002 Brad King (brad.king@kitware.com)  | ||||
| //                    Douglas Gregor (gregod@cs.rpi.edu) | ||||
| // | ||||
| // 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) | ||||
|  | ||||
| // For more information, see http://www.boost.org | ||||
|  | ||||
|  | ||||
| #include <boost/utility/addressof.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) | ||||
| #pragma warning(push, 3) | ||||
| #endif | ||||
|  | ||||
| #include <iostream> | ||||
|  | ||||
| #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) | ||||
| #pragma warning(pop) | ||||
| #endif | ||||
|  | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| template<class T> void scalar_test( T * = 0 ) | ||||
| { | ||||
|     T* px = new T(); | ||||
|  | ||||
|     T& x = *px; | ||||
|     BOOST_TEST( boost::addressof(x) == px ); | ||||
|  | ||||
|     const T& cx = *px; | ||||
|     const T* pcx = boost::addressof(cx); | ||||
|     BOOST_TEST( pcx == px ); | ||||
|  | ||||
|     volatile T& vx = *px; | ||||
|     volatile T* pvx = boost::addressof(vx); | ||||
|     BOOST_TEST( pvx == px ); | ||||
|  | ||||
|     const volatile T& cvx = *px; | ||||
|     const volatile T* pcvx = boost::addressof(cvx); | ||||
|     BOOST_TEST( pcvx == px ); | ||||
|  | ||||
|     delete px; | ||||
| } | ||||
|  | ||||
| template<class T> void array_test( T * = 0 ) | ||||
| { | ||||
|     T nrg[3] = {1,2,3}; | ||||
|     T (*pnrg)[3] = &nrg; | ||||
|     BOOST_TEST( boost::addressof(nrg) == pnrg ); | ||||
|  | ||||
|     T const cnrg[3] = {1,2,3}; | ||||
|     T const (*pcnrg)[3] = &cnrg; | ||||
|     BOOST_TEST( boost::addressof(cnrg) == pcnrg ); | ||||
| } | ||||
|  | ||||
| struct addressable | ||||
| { | ||||
|     addressable( int = 0 ) | ||||
|     { | ||||
|     } | ||||
| }; | ||||
|  | ||||
| struct useless_type {}; | ||||
|  | ||||
| class nonaddressable { | ||||
| public: | ||||
|  | ||||
|     nonaddressable( int = 0 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     void dummy(); // Silence GCC warning: all member of class are private | ||||
|  | ||||
| private: | ||||
|  | ||||
|     useless_type operator&() const; | ||||
| }; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     scalar_test<char>(); | ||||
|     scalar_test<int>(); | ||||
|     scalar_test<addressable>(); | ||||
|     scalar_test<nonaddressable>(); | ||||
|  | ||||
|     array_test<char>(); | ||||
|     array_test<int>(); | ||||
|     array_test<addressable>(); | ||||
|     array_test<nonaddressable>(); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										95
									
								
								addressof_test2.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								addressof_test2.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| // Copyright (C) 2002 Brad King (brad.king@kitware.com)  | ||||
| //                    Douglas Gregor (gregod@cs.rpi.edu) | ||||
| // | ||||
| // Copyright 2009 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) | ||||
|  | ||||
| // For more information, see http://www.boost.org | ||||
|  | ||||
|  | ||||
| #include <boost/utility/addressof.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) | ||||
| #pragma warning(push, 3) | ||||
| #endif | ||||
|  | ||||
| #include <iostream> | ||||
|  | ||||
| #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) | ||||
| #pragma warning(pop) | ||||
| #endif | ||||
|  | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| template<class T> void scalar_test( T * = 0 ) | ||||
| { | ||||
|     T* px = new T(); | ||||
|  | ||||
|     T& x = *px; | ||||
|     BOOST_TEST( boost::addressof(x) == px ); | ||||
|  | ||||
|     const T& cx = *px; | ||||
|     const T* pcx = boost::addressof(cx); | ||||
|     BOOST_TEST( pcx == px ); | ||||
|  | ||||
|     volatile T& vx = *px; | ||||
|     volatile T* pvx = boost::addressof(vx); | ||||
|     BOOST_TEST( pvx == px ); | ||||
|  | ||||
|     const volatile T& cvx = *px; | ||||
|     const volatile T* pcvx = boost::addressof(cvx); | ||||
|     BOOST_TEST( pcvx == px ); | ||||
|  | ||||
|     delete px; | ||||
| } | ||||
|  | ||||
| template<class T> void array_test( T * = 0 ) | ||||
| { | ||||
|     T nrg[3] = {1,2,3}; | ||||
|     T (*pnrg)[3] = &nrg; | ||||
|     BOOST_TEST( boost::addressof(nrg) == pnrg ); | ||||
|  | ||||
|     T const cnrg[3] = {1,2,3}; | ||||
|     T const (*pcnrg)[3] = &cnrg; | ||||
|     BOOST_TEST( boost::addressof(cnrg) == pcnrg ); | ||||
| } | ||||
|  | ||||
| class convertible { | ||||
| public: | ||||
|  | ||||
|     convertible( int = 0 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     template<class U> operator U () const | ||||
|     { | ||||
|         return U(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| class convertible2 { | ||||
| public: | ||||
|  | ||||
|     convertible2( int = 0 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     operator convertible2* () const | ||||
|     { | ||||
|         return 0; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     scalar_test<convertible>(); | ||||
|     scalar_test<convertible2>(); | ||||
|  | ||||
|     array_test<convertible>(); | ||||
|     array_test<convertible2>(); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										91
									
								
								appveyor.yml
									
									
									
									
									
								
							
							
						
						
									
										91
									
								
								appveyor.yml
									
									
									
									
									
								
							| @@ -1,91 +0,0 @@ | ||||
| # Copyright 2016-2019 Peter Dimov | ||||
| # Copyright 2019, 2022 Andrey Semashev | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| version: 1.0.{build}-{branch} | ||||
|  | ||||
| shallow_clone: true | ||||
|  | ||||
| branches: | ||||
|   only: | ||||
|     - master | ||||
|     - develop | ||||
|     - /feature\/.*/ | ||||
|  | ||||
| environment: | ||||
|   matrix: | ||||
|     - TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0 | ||||
|       ADDRMD: 32 | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|     - TOOLSET: msvc-12.0,msvc-14.0 | ||||
|       ADDRMD: 32,64 | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|     - TOOLSET: msvc-14.1 | ||||
|       CXXSTD: 14,17,latest | ||||
|       ADDRMD: 32,64 | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 | ||||
|     - TOOLSET: msvc-14.2 | ||||
|       ADDRMD: 32,64 | ||||
|       CXXSTD: 14,17,20,latest | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|     - TOOLSET: msvc-14.3 | ||||
|       ADDRMD: 32,64 | ||||
|       CXXSTD: 14,17,20,latest | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 | ||||
|     - TOOLSET: clang-win | ||||
|       ADDRMD: 32 | ||||
|       CXXSTD: 14,17,latest | ||||
|       ENV_SCRIPT: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|     - TOOLSET: clang-win | ||||
|       ADDRMD: 64 | ||||
|       CXXSTD: 14,17,latest | ||||
|       ENV_SCRIPT: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 | ||||
|     - TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,1z | ||||
|       ADDPATH: C:\cygwin\bin; | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|     - TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,1z | ||||
|       ADDPATH: C:\cygwin64\bin; | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|     - TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,1z | ||||
|       ADDPATH: C:\mingw\bin; | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|     - TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,1z | ||||
|       ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin; | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|     - TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,17 | ||||
|       ADDPATH: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin; | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|     - TOOLSET: gcc | ||||
|       CXXSTD: 03,11,14,17,2a | ||||
|       ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin; | ||||
|       APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 | ||||
|  | ||||
| install: | ||||
|   - set GIT_FETCH_JOBS=8 | ||||
|   - set BOOST_BRANCH=develop | ||||
|   - if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master | ||||
|   - cd .. | ||||
|   - git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|   - cd boost-root | ||||
|   - git submodule update --init tools/boostdep | ||||
|   - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\utility | ||||
|   - python tools/boostdep/depinst/depinst.py %DEPINST_ARG_INCLUDE_EXAMPLES% --git_args "--jobs %GIT_FETCH_JOBS%" utility | ||||
|   - cmd /c bootstrap | ||||
|   - b2 headers | ||||
|  | ||||
| build: off | ||||
|  | ||||
| test_script: | ||||
|   - PATH=%ADDPATH%%PATH% | ||||
|   - if not "%ENV_SCRIPT%" == "" call "%ENV_SCRIPT%" | ||||
|   - if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% | ||||
|   - if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD% | ||||
|   - b2 -j %NUMBER_OF_PROCESSORS% libs/utility/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release | ||||
							
								
								
									
										115
									
								
								assert.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								assert.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | ||||
| <html> | ||||
| 	<head> | ||||
| 		<title>Boost: assert.hpp documentation</title> | ||||
| 		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||||
| 	</head> | ||||
| 	<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%"> | ||||
| 		<table border="0" width="100%"> | ||||
| 			<tr> | ||||
| 				<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A> | ||||
| 				</td> | ||||
| 				<td align="center"> | ||||
| 					<h1>assert.hpp</h1> | ||||
| 				</td> | ||||
| 			</tr> | ||||
| 			<tr> | ||||
| 				<td colspan="2" height="64"> </td> | ||||
| 			</tr> | ||||
| 		</table> | ||||
| 		<p> | ||||
| 			<a href="#BOOST_ASSERT">BOOST_ASSERT</a><br> | ||||
|             <a href="#BOOST_ASSERT_MSG">BOOST_ASSERT_MSG</a><br> | ||||
|             <a href="#BOOST_VERIFY">BOOST_VERIFY</a></p> | ||||
|              | ||||
| <h2><a name="BOOST_ASSERT">BOOST_ASSERT</a></h2> | ||||
| 		<p> | ||||
| 			The header <STRONG><boost/assert.hpp></STRONG> defines the macro <b>BOOST_ASSERT</b>,  | ||||
| 			which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG><cassert></STRONG>.  | ||||
| 			The macro is intended to be used in both Boost libraries and user  | ||||
|             code. | ||||
| 		</p> | ||||
| 		<P>By default, <tt>BOOST_ASSERT(expr)</tt> is equivalent to <tt>assert(expr)</tt>.</P> | ||||
| 		<P>If the macro <STRONG>BOOST_DISABLE_ASSERTS</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG> | ||||
| 			is included, <tt>BOOST_ASSERT(expr)</tt> is defined as <tt>((void)0)</tt>. This  | ||||
| 			allows users to selectively disable <STRONG>BOOST_ASSERT</STRONG> without  | ||||
| 			affecting the definition of the standard <STRONG>assert</STRONG>.</P> | ||||
| 		<P>If the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG> | ||||
| 			is included, <tt>BOOST_ASSERT(expr)</tt> evaluates <b>expr</b> and, if the  | ||||
| 			result is false, evaluates the expression</P> | ||||
| 		<blockquote> | ||||
| 		<P><tt>::boost::assertion_failed(#expr, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,  | ||||
| 				__FILE__, __LINE__)</tt></P> | ||||
| 		</blockquote> | ||||
| 		<P><STRONG>assertion_failed</STRONG> is declared in <STRONG><boost/assert.hpp></STRONG> | ||||
| 			as</P> | ||||
| 		<blockquote> | ||||
| 		<pre>namespace boost | ||||
| { | ||||
|   void assertion_failed(char const * expr, char const * function, char const * file, long line); | ||||
| } | ||||
| </pre> | ||||
| 		</blockquote> | ||||
| 		<p>but it is never defined. The user is expected to supply an appropriate  | ||||
| 			definition.</p> | ||||
| 		<P>As is the case with <STRONG><cassert></STRONG>, <STRONG><boost/assert.hpp></STRONG> | ||||
| 			can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT</STRONG> | ||||
| 			will be redefined each time as specified above.</P> | ||||
| 			 | ||||
| <h2><a name="BOOST_ASSERT_MSG">BOOST_ASSERT_MSG</a></h2> | ||||
| 		<p> | ||||
| 			The header <STRONG><boost/assert.hpp></STRONG> defines the macro <b>BOOST_ASSERT_MSG</b>,  | ||||
| 			which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG><cassert></STRONG>,  | ||||
|             but with an additional macro parameter supplying an error message. The macro is intended to be used in both Boost libraries  | ||||
|             and user code. | ||||
| 		</p> | ||||
| 		<P> <tt>BOOST_ASSERT_MSG(expr, msg)</tt> is equivalent to <code> | ||||
|         ((void)0)</code> if <b>BOOST_DISABLE_ASSERTS</b> or <b>NDEBUG</b> are  | ||||
|         defined or <code>expr</code> evaluates to <code>true</code>. If those  | ||||
|         macros and <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> are not  | ||||
|         defined, and <code>expr</code> evaluates to <code>false</code>, an error  | ||||
|         message that includes <tt>#expr</tt>, <tt>msg</tt>, <tt> <a href="current_function.html">BOOST_CURRENT_FUNCTION</a></tt>, <tt> | ||||
|         __FILE__</tt>, and <tt>__LINE__</tt> is sent to output stream <b> | ||||
|         BOOST_ASSERT_MSG_OSTREAM</b>  | ||||
|         and <code>std::abort()</code> is called.</P> | ||||
| 		<P> <b>BOOST_ASSERT_MSG_OSTREAM</b> defines the output stream. It defaults to <code>std::cerr</code>.  | ||||
|         Integrated development environments (IDE's) like Microsoft Visual Studio  | ||||
|         may produce easier to understand output if messages go to a different  | ||||
|         stream, such as <code>std::cout</code>. Users may define <b>BOOST_ASSERT_MSG_OSTREAM</b> before including <STRONG><boost/assert.hpp></STRONG>  | ||||
|         to specify a different output stream.  </P> | ||||
| 		<P>If the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG><boost/assert.hpp></STRONG> | ||||
| 			is included, instead of sending a error message to an output  | ||||
|         stream, this expression is evaluated</P> | ||||
| 		<blockquote> | ||||
| 		<P><tt>::boost::assertion_failed_msg(#expr, msg, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,  | ||||
| 				__FILE__, __LINE__)</tt></P> | ||||
| 		</blockquote> | ||||
| 		<P><STRONG>assertion_failed_msg</STRONG> is declared in <STRONG><boost/assert.hpp></STRONG> | ||||
| 			as</P> | ||||
| 		<blockquote> | ||||
| 		<pre>namespace boost | ||||
| { | ||||
|   void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); | ||||
| } | ||||
| </pre> | ||||
| 		</blockquote> | ||||
| 		<p>but it is never defined. The user is expected to supply an appropriate  | ||||
| 			definition.</p> | ||||
| 		<P>As is the case with <STRONG><cassert></STRONG>, <STRONG><boost/assert.hpp></STRONG> | ||||
| 			can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT_MSG</STRONG> | ||||
| 			will be redefined each time as specified above.</P> | ||||
| 			 | ||||
| <h2><a name="BOOST_VERIFY">BOOST_VERIFY</a></h2> | ||||
| 		<p><STRONG><boost/assert.hpp></STRONG> also defines the macro <STRONG>BOOST_VERIFY</STRONG>.  | ||||
| 			It has exactly the same behavior as <STRONG>BOOST_ASSERT</STRONG>, except that  | ||||
| 			the expression that is passed to <STRONG>BOOST_VERIFY</STRONG> is always  | ||||
| 			evaluated. This is useful when the asserted expression has desirable side  | ||||
| 			effects; it can also help suppress warnings about unused variables when the  | ||||
| 			only use of the variable is inside an assertion.</p> | ||||
| 		<p><br> | ||||
| 			<small>Copyright <20> 2002, 2007 by Peter Dimov.  Copyright <20> 2011  | ||||
|         by Beman Dawes. Distributed under the Boost Software  | ||||
| 				License, Version 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> | ||||
| 				or copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> | ||||
| 	</body> | ||||
| </html> | ||||
							
								
								
									
										153
									
								
								assert_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								assert_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | ||||
| // | ||||
| //  assert_test.cpp - a test for boost/assert.hpp | ||||
| // | ||||
| //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright (2) Beman Dawes 2011 | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| #include <boost/assert.hpp> | ||||
|  | ||||
| void test_default() | ||||
| { | ||||
|     int x = 1; | ||||
|  | ||||
|     BOOST_ASSERT(1); | ||||
|     BOOST_ASSERT(x); | ||||
|     BOOST_ASSERT(x == 1); | ||||
|     BOOST_ASSERT(&x); | ||||
|  | ||||
|     BOOST_ASSERT_MSG(1, "msg"); | ||||
|     BOOST_ASSERT_MSG(x, "msg"); | ||||
|     BOOST_ASSERT_MSG(x == 1, "msg"); | ||||
|     BOOST_ASSERT_MSG(&x, "msg"); | ||||
| } | ||||
|  | ||||
| #define BOOST_DISABLE_ASSERTS | ||||
| #include <boost/assert.hpp> | ||||
|  | ||||
| void test_disabled() | ||||
| { | ||||
|     int x = 1; | ||||
|  | ||||
|     BOOST_ASSERT(1); | ||||
|     BOOST_ASSERT(x); | ||||
|     BOOST_ASSERT(x == 1); | ||||
|     BOOST_ASSERT(&x); | ||||
|  | ||||
|     BOOST_ASSERT_MSG(1, "msg"); | ||||
|     BOOST_ASSERT_MSG(x, "msg"); | ||||
|     BOOST_ASSERT_MSG(x == 1, "msg"); | ||||
|     BOOST_ASSERT_MSG(&x, "msg"); | ||||
|  | ||||
|     BOOST_ASSERT(0); | ||||
|     BOOST_ASSERT(!x); | ||||
|     BOOST_ASSERT(x == 0); | ||||
|  | ||||
|     BOOST_ASSERT_MSG(0, "msg"); | ||||
|     BOOST_ASSERT_MSG(!x, "msg"); | ||||
|     BOOST_ASSERT_MSG(x == 0, "msg"); | ||||
|  | ||||
|     void * p = 0; | ||||
|  | ||||
|     BOOST_ASSERT(p); | ||||
|     BOOST_ASSERT_MSG(p, "msg"); | ||||
|  | ||||
|     // supress warnings | ||||
|     p = &x; | ||||
|     p = &p; | ||||
| } | ||||
|  | ||||
| #undef BOOST_DISABLE_ASSERTS | ||||
|  | ||||
| #define BOOST_ENABLE_ASSERT_HANDLER | ||||
| #include <boost/assert.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <cstdio> | ||||
|  | ||||
| int handler_invoked = 0; | ||||
| int msg_handler_invoked = 0; | ||||
|  | ||||
| void boost::assertion_failed(char const * expr, char const * function, char const * file, long line) | ||||
| { | ||||
| #if !defined(BOOST_NO_STDC_NAMESPACE) | ||||
|     using std::printf; | ||||
| #endif | ||||
|  | ||||
|     printf("Expression: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n", expr, function, file, line); | ||||
|     ++handler_invoked; | ||||
| } | ||||
|  | ||||
| void boost::assertion_failed_msg(char const * expr, char const * msg, char const * function, | ||||
|   char const * file, long line) | ||||
| { | ||||
| #if !defined(BOOST_NO_STDC_NAMESPACE) | ||||
|     using std::printf; | ||||
| #endif | ||||
|  | ||||
|     printf("Expression: %s Message: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n", | ||||
|       expr, msg, function, file, line); | ||||
|     ++msg_handler_invoked; | ||||
| } | ||||
|  | ||||
| struct X | ||||
| { | ||||
|     static void f() | ||||
|     { | ||||
|         BOOST_ASSERT(0); | ||||
|         BOOST_ASSERT_MSG(0, "msg f()"); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| void test_handler() | ||||
| { | ||||
|     int x = 1; | ||||
|  | ||||
|     BOOST_ASSERT(1); | ||||
|     BOOST_ASSERT(x); | ||||
|     BOOST_ASSERT(x == 1); | ||||
|     BOOST_ASSERT(&x); | ||||
|  | ||||
|     BOOST_ASSERT_MSG(1, "msg2"); | ||||
|     BOOST_ASSERT_MSG(x, "msg3"); | ||||
|     BOOST_ASSERT_MSG(x == 1, "msg4"); | ||||
|     BOOST_ASSERT_MSG(&x, "msg5"); | ||||
|  | ||||
|     BOOST_ASSERT(0); | ||||
|     BOOST_ASSERT(!x); | ||||
|     BOOST_ASSERT(x == 0); | ||||
|  | ||||
|     BOOST_ASSERT_MSG(0,"msg 0"); | ||||
|     BOOST_ASSERT_MSG(!x, "msg !x"); | ||||
|     BOOST_ASSERT_MSG(x == 0, "msg x == 0"); | ||||
|  | ||||
|     void * p = 0; | ||||
|  | ||||
|     BOOST_ASSERT(p); | ||||
|     BOOST_ASSERT_MSG(p, "msg p"); | ||||
|  | ||||
|     X::f(); | ||||
|  | ||||
|     BOOST_ASSERT(handler_invoked == 5); | ||||
|     BOOST_TEST(handler_invoked == 5); | ||||
|  | ||||
|     BOOST_ASSERT_MSG(msg_handler_invoked == 5, "msg_handler_invoked count is wrong"); | ||||
|     BOOST_TEST(msg_handler_invoked == 5); | ||||
| } | ||||
|  | ||||
| #undef BOOST_ENABLE_ASSERT_HANDLER | ||||
| #undef BOOST_ENABLE_ASSERT_MSG_HANDLER | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     test_default(); | ||||
|     test_disabled(); | ||||
|     test_handler(); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										398
									
								
								base_from_member.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										398
									
								
								base_from_member.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,398 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> | ||||
| <html> | ||||
| <head> | ||||
| <title>Boost: Base-from-Member Idiom Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="white" link="blue" text="black" vlink="purple" alink="red">  | ||||
| <h1><img src="../../boost.png" alt="C++ Boost" align="middle" | ||||
| width="277" height="86">Base-from-Member Idiom</h1> | ||||
|  | ||||
| <p>The class template <code>boost::base_from_member</code> provides | ||||
| a workaround for a class that needs to initialize a base class with a | ||||
| member.  The class template is in <cite><a | ||||
| href="../../boost/utility/base_from_member.hpp">boost/utility/base_from_member.hpp</a></cite> | ||||
| which is included in <i><a href="../../boost/utility.hpp">boost/utility.hpp</a></i>.</p> | ||||
|  | ||||
| <p>There is test/example code in <cite><a | ||||
| href="base_from_member_test.cpp">base_from_member_test.cpp</a></cite>.</p> | ||||
|  | ||||
| <h2><a name="contents">Contents</a></h2> | ||||
|  | ||||
| <ul> | ||||
| 	<li><a href="#contents">Contents</a></li> | ||||
| 	<li><a href="#rationale">Rationale</a></li> | ||||
| 	<li><a href="#synopsis">Synopsis</a></li> | ||||
| 	<li><a href="#usage">Usage</a></li> | ||||
| 	<li><a href="#example">Example</a></li> | ||||
| 	<li><a href="#credits">Credits</a> | ||||
| 		<ul> | ||||
| 			<li><a href="#contributors">Contributors</a></li> | ||||
| 		</ul></li> | ||||
| </ul> | ||||
|  | ||||
| <h2><a name="rationale">Rationale</a></h2> | ||||
|  | ||||
| <p>When developing a class, sometimes a base class needs to be | ||||
| initialized with a member of the current class.  As a naïve | ||||
| example:</p> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #include <streambuf>  <i>// for std::streambuf</i> | ||||
| #include <ostream>    <i>// for std::ostream</i> | ||||
|  | ||||
| class fdoutbuf | ||||
|     : public std::streambuf | ||||
| { | ||||
| public: | ||||
|     explicit fdoutbuf( int fd ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class fdostream | ||||
|     : public std::ostream | ||||
| { | ||||
| protected: | ||||
|     fdoutbuf buf; | ||||
| public: | ||||
|     explicit fdostream( int fd ) | ||||
|         : buf( fd ), std::ostream( &buf ) | ||||
|         {} | ||||
|     //... | ||||
| }; | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>This is undefined because C++'s initialization order mandates that | ||||
| the base class is initialized before the member it uses.  <a | ||||
| href="http://www.moocat.org">R. Samuel Klatchko</a> developed a way | ||||
| around this by using the initialization order in his favor.  Base | ||||
| classes are intialized in order of declaration, so moving the desired | ||||
| member to another base class, that is initialized before the desired | ||||
| base class, can ensure proper initialization.</p> | ||||
|  | ||||
| <p>A custom base class can be made for this idiom:</p> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #include <streambuf>  <i>// for std::streambuf</i> | ||||
| #include <ostream>    <i>// for std::ostream</i> | ||||
|  | ||||
| class fdoutbuf | ||||
|     : public std::streambuf | ||||
| { | ||||
| public: | ||||
|     explicit fdoutbuf( int fd ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| struct fdostream_pbase | ||||
| { | ||||
|     fdoutbuf sbuffer; | ||||
|  | ||||
|     explicit fdostream_pbase( int fd ) | ||||
|         : sbuffer( fd ) | ||||
|         {} | ||||
| }; | ||||
|  | ||||
| class fdostream | ||||
|     : private fdostream_pbase | ||||
|     , public std::ostream | ||||
| { | ||||
|     typedef fdostream_pbase  pbase_type; | ||||
|     typedef std::ostream     base_type; | ||||
|  | ||||
| public: | ||||
|     explicit fdostream( int fd ) | ||||
|         : pbase_type( fd ), base_type( &sbuffer ) | ||||
|         {} | ||||
|     //... | ||||
| }; | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>Other projects can use similar custom base classes.  The technique | ||||
| is basic enough to make a template, with a sample template class in | ||||
| this library.  The main template parameter is the type of the enclosed | ||||
| member.  The template class has several (explicit) constructor member | ||||
| templates, which implicitly type the constructor arguments and pass them | ||||
| to the member.  The template class uses implicit copy construction and | ||||
| assignment, cancelling them if the enclosed member is non-copyable.</p> | ||||
|  | ||||
| <p>Manually coding a base class may be better if the construction | ||||
| and/or copying needs are too complex for the supplied template class, | ||||
| or if the compiler is not advanced enough to use it.</p> | ||||
|  | ||||
| <p>Since base classes are unnamed, a class cannot have multiple (direct) | ||||
| base classes of the same type.  The supplied template class has an | ||||
| extra template parameter, an integer, that exists solely to provide type | ||||
| differentiation.  This parameter has a default value so a single use of a | ||||
| particular member type does not need to concern itself with the integer.</p> | ||||
|  | ||||
| <h2><a name="synopsis">Synopsis</a></h2> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #include <type_traits>  <i>// exposition only</i> | ||||
|  | ||||
| #ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY | ||||
| #define BOOST_BASE_FROM_MEMBER_MAX_ARITY  10 | ||||
| #endif | ||||
|  | ||||
| template < typename MemberType, int UniqueID = 0 > | ||||
| class boost::base_from_member | ||||
| { | ||||
| protected: | ||||
|     MemberType  member; | ||||
|  | ||||
| #if <i>C++2011 is in use</i> | ||||
|     template< typename ...T > | ||||
|     explicit constexpr   base_from_member( T&& ...x ) | ||||
|      noexcept( std::is_nothrow_constructible<MemberType, T...>::value ); | ||||
| #else | ||||
|     base_from_member(); | ||||
|  | ||||
|     template< typename T1 > | ||||
|     explicit  base_from_member( T1 x1 ); | ||||
|  | ||||
|     template< typename T1, typename T2 > | ||||
|     base_from_member( T1 x1, T2 x2 ); | ||||
|  | ||||
|     //... | ||||
|  | ||||
|     template< typename T1, typename T2, typename T3, typename T4, | ||||
|      typename T5, typename T6, typename T7, typename T8, typename T9, | ||||
|      typename T10 > | ||||
|     base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, | ||||
|      T8 x8, T9 x9, T10 x10 ); | ||||
| #endif | ||||
| }; | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>The class template has a first template parameter | ||||
| <var>MemberType</var> representing the type of the based-member. | ||||
| It has a last template parameter <var>UniqueID</var>, that is an | ||||
| <code>int</code>, to differentiate between multiple base classes that use | ||||
| the same based-member type.  The last template parameter has a default | ||||
| value of zero if it is omitted.  The class template has a protected | ||||
| data member called <var>member</var> that the derived class can use | ||||
| for later base classes (or itself).</p> | ||||
|  | ||||
| <p>If the appropriate features of C++2011 are present, there will be a single | ||||
| constructor template.  It implements "perfect forwarding" to the best | ||||
| constructor call of <code>member</code> (if any).  The constructor template is | ||||
| marked both <code>constexpr</code> and <code>explicit</code>.  The former will | ||||
| be ignored if the corresponding inner constructor call (of <code>member</code>) | ||||
| does not have the marker.  The latter binds the other way; always taking | ||||
| effect, even when the inner constructor call does not have the marker.  The | ||||
| constructor template propagates the <code>noexcept</code> status of the inner | ||||
| constructor call.  (The constructor template has a trailing parameter with a | ||||
| default value that disables the template when its signature is too close to the | ||||
| signatures of the automatically-defined non-template copy- and/or | ||||
| move-constructors of <code>base_from_member</code>.)</p> | ||||
|  | ||||
| <p>On earlier-standard compilers, there is a default constructor and several | ||||
| constructor member templates.  These constructor templates can take as many | ||||
| arguments (currently up to ten) as possible and pass them to a constructor of | ||||
| the data member.</p> | ||||
|  | ||||
| <p>Since C++ does not allow any way to explicitly state | ||||
| the template parameters of a templated constructor, make sure that | ||||
| the arguments are already close as possible to the actual type used in | ||||
| the data member's desired constructor.  Explicit conversions may be | ||||
| necessary.</p> | ||||
|  | ||||
| <p>The <var>BOOST_BASE_FROM_MEMBER_MAX_ARITY</var> macro constant specifies | ||||
| the maximum argument length for the constructor templates.  The constant | ||||
| may be overridden if more (or less) argument configurations are needed.  The | ||||
| constant may be read for code that is expandable like the class template and | ||||
| needs to maintain the same maximum size.  (Example code would be a class that | ||||
| uses this class template as a base class for a member with a flexible set of | ||||
| constructors.)  This constant is ignored when C++2011 features are present.</p> | ||||
|  | ||||
| <h2><a name="usage">Usage</a></h2> | ||||
|  | ||||
| <p>With the starting example, the <code>fdoutbuf</code> sub-object needs | ||||
| to be encapsulated in a base class that is inheirited before | ||||
| <code>std::ostream</code>.</p> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #include <boost/utility/base_from_member.hpp> | ||||
|  | ||||
| #include <streambuf>  <i>// for std::streambuf</i> | ||||
| #include <ostream>    <i>// for std::ostream</i> | ||||
|  | ||||
| class fdoutbuf | ||||
|     : public std::streambuf | ||||
| { | ||||
| public: | ||||
|     explicit fdoutbuf( int fd ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class fdostream | ||||
|     : private boost::base_from_member<fdoutbuf> | ||||
|     , public std::ostream | ||||
| { | ||||
|     // Helper typedef's | ||||
|     typedef boost::base_from_member<fdoutbuf>  pbase_type; | ||||
|     typedef std::ostream                        base_type; | ||||
|  | ||||
| public: | ||||
|     explicit fdostream( int fd ) | ||||
|         : pbase_type( fd ), base_type( &member ) | ||||
|         {} | ||||
|     //... | ||||
| }; | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>The base-from-member idiom is an implementation detail, so it | ||||
| should not be visible to the clients (or any derived classes) of | ||||
| <code>fdostream</code>.  Due to the initialization order, the | ||||
| <code>fdoutbuf</code> sub-object will get initialized before the | ||||
| <code>std::ostream</code> sub-object does, making the former | ||||
| sub-object safe to use in the latter sub-object's construction.  Since the | ||||
| <code>fdoutbuf</code> sub-object of the final type is the only sub-object | ||||
| with the name "member," that name can be used | ||||
| unqualified within the final class.</p> | ||||
|  | ||||
| <h2><a name="example">Example</a></h2> | ||||
|  | ||||
| <p>The base-from-member class templates should commonly involve | ||||
| only one base-from-member sub-object, usually for attaching a | ||||
| stream-buffer to an I/O stream.  The next example demonstrates how | ||||
| to use multiple base-from-member sub-objects and the resulting | ||||
| qualification issues.</p> | ||||
|  | ||||
| <blockquote><pre> | ||||
| #include <boost/utility/base_from_member.hpp> | ||||
|  | ||||
| #include <cstddef>  <i>// for NULL</i> | ||||
|  | ||||
| struct an_int | ||||
| { | ||||
|     int  y; | ||||
|  | ||||
|     an_int( float yf ); | ||||
| }; | ||||
|  | ||||
| class switcher | ||||
| { | ||||
| public: | ||||
|     switcher(); | ||||
|     switcher( double, int * ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class flow_regulator | ||||
| { | ||||
| public: | ||||
|     flow_regulator( switcher &, switcher & ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| template < unsigned Size > | ||||
| class fan | ||||
| { | ||||
| public: | ||||
|     explicit fan( switcher ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class system | ||||
|     : private boost::base_from_member<an_int> | ||||
|     , private boost::base_from_member<switcher> | ||||
|     , private boost::base_from_member<switcher, 1> | ||||
|     , private boost::base_from_member<switcher, 2> | ||||
|     , protected flow_regulator | ||||
|     , public fan<6> | ||||
| { | ||||
|     // Helper typedef's | ||||
|     typedef boost::base_from_member<an_int>       pbase0_type; | ||||
|     typedef boost::base_from_member<switcher>     pbase1_type; | ||||
|     typedef boost::base_from_member<switcher, 1>  pbase2_type; | ||||
|     typedef boost::base_from_member<switcher, 2>  pbase3_type; | ||||
|  | ||||
|     typedef flow_regulator  base1_type; | ||||
|     typedef fan<6>          base2_type; | ||||
|  | ||||
| public: | ||||
|     system( double x ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| system::system( double x ) | ||||
|     : pbase0_type( 0.2 ) | ||||
|     , pbase1_type() | ||||
|     , pbase2_type( -16, &this->pbase0_type::member ) | ||||
|     , pbase3_type( x, static_cast<int *>(NULL) ) | ||||
|     , base1_type( pbase3_type::member, pbase1_type::member ) | ||||
|     , base2_type( pbase2_type::member ) | ||||
| { | ||||
|     //... | ||||
| } | ||||
| </pre></blockquote> | ||||
|  | ||||
| <p>The final class has multiple sub-objects with the name | ||||
| "member," so any use of that name needs qualification by | ||||
| a name of the appropriate base type.  (Using <code>typedef</code>s | ||||
| ease mentioning the base types.)  However, the fix introduces a new | ||||
| problem when a pointer is needed.  Using the address operator with | ||||
| a sub-object qualified with its class's name results in a pointer-to-member | ||||
| (here, having a type of <code>an_int boost::base_from_member<an_int, | ||||
| 0> :: *</code>) instead of a pointer to the member (having a type of | ||||
| <code>an_int *</code>).  The new problem is fixed by qualifying the | ||||
| sub-object with "<code>this-></code>," and is needed just | ||||
| for pointers, and not for references or values.</p> | ||||
|  | ||||
| <p>There are some argument conversions in the initialization.  The | ||||
| constructor argument for <code>pbase0_type</code> is converted from | ||||
| <code>double</code> to <code>float</code>.  The first constructor | ||||
| argument for <code>pbase2_type</code> is converted from <code>int</code> | ||||
| to <code>double</code>.  The second constructor argument for | ||||
| <code>pbase3_type</code> is a special case of necessary conversion; all | ||||
| forms of the null-pointer literal in C++ (except <code>nullptr</code> from | ||||
| C++2011) also look like compile-time integral expressions, so C++ always | ||||
| interprets such code as an integer when it has overloads that can take either | ||||
| an integer or a pointer.  The last conversion is necessary for the compiler to | ||||
| call a constructor form with the exact pointer type used in | ||||
| <code>switcher</code>'s constructor.  (If C++2011's <code>nullptr</code> is | ||||
| used, it still needs a conversion if multiple pointer types can be accepted in | ||||
| a constructor call but <code>std::nullptr_t</code> cannot.)</p> | ||||
|  | ||||
| <h2><a name="credits">Credits</a></h2> | ||||
|  | ||||
| <h3><a name="contributors">Contributors</a></h3> | ||||
|  | ||||
| <dl> | ||||
| 	<dt><a href="http://www.boost.org/people/ed_brey.htm">Ed Brey</a> | ||||
| 	<dd>Suggested some interface changes. | ||||
|  | ||||
| 	<dt><a href="http://www.moocat.org">R. Samuel Klatchko</a> (<a | ||||
| 	href="mailto:rsk@moocat.org">rsk@moocat.org</a>, <a | ||||
| 	href="mailto:rsk@brightmail.com">rsk@brightmail.com</a>) | ||||
| 	<dd>Invented the idiom of how to use a class member for initializing | ||||
| 		a base class. | ||||
|  | ||||
| 	<dt><a href="http://www.boost.org/people/dietmar_kuehl.htm">Dietmar Kuehl</a> | ||||
| 	<dd>Popularized the base-from-member idiom in his | ||||
| 		<a href="http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/">IOStream | ||||
| 		example classes</a>. | ||||
|  | ||||
| 	<dt>Jonathan Turkanis | ||||
| 	<dd>Supplied an implementation of generating the constructor templates that | ||||
| 		can be controlled and automated with macros.  The implementation uses | ||||
| 		the <a href="../preprocessor/index.html">Preprocessor library</a>. | ||||
|  | ||||
| 	<dt><a href="http://www.boost.org/people/daryle_walker.html">Daryle Walker</a> | ||||
| 	<dd>Started the library.  Contributed the test file <cite><a | ||||
| 		href="base_from_member_test.cpp">base_from_member_test.cpp</a></cite>. | ||||
| </dl> | ||||
|  | ||||
| <hr> | ||||
|  | ||||
| <p>Revised: 16 February 2012</p> | ||||
|  | ||||
| <p>Copyright 2001, 2003, 2004, 2012 Daryle Walker.  Use, modification, and distribution | ||||
| are subject to the Boost Software License, Version 1.0.  (See accompanying | ||||
| file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at <<a | ||||
| href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p> | ||||
|  | ||||
| </body> | ||||
| </html> | ||||
| @@ -10,14 +10,15 @@ | ||||
| //  14 Jun 2003  Adjusted code for Boost.Test changes (Daryle Walker)
 | ||||
| //  29 Aug 2001  Initial Version (Daryle Walker)
 | ||||
| 
 | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
| #include <boost/test/minimal.hpp>  // for BOOST_CHECK, main
 | ||||
| 
 | ||||
| #include <boost/config.hpp>       // for BOOST_NO_MEMBER_TEMPLATES
 | ||||
| #include <boost/cstdlib.hpp>      // for boost::exit_success
 | ||||
| #include <boost/noncopyable.hpp>  // for boost::noncopyable
 | ||||
| 
 | ||||
| #include <boost/utility/base_from_member.hpp>  // for boost::base_from_member
 | ||||
| 
 | ||||
| #include <functional>  // for std::less
 | ||||
| #include <functional>  // for std::binary_function, std::less
 | ||||
| #include <iostream>    // for std::cout (std::ostream, std::endl indirectly)
 | ||||
| #include <set>         // for std::set
 | ||||
| #include <typeinfo>    // for std::type_info
 | ||||
| @@ -45,6 +46,7 @@ template < typename T > | ||||
| 
 | ||||
| // A custom comparison type is needed
 | ||||
| struct object_id_compare | ||||
|     : std::binary_function<object_id, object_id, bool> | ||||
| { | ||||
|     bool  operator ()( object_id const &a, object_id const &b ) const; | ||||
| 
 | ||||
| @@ -171,13 +173,13 @@ object_registrar  obj_reg; | ||||
| 
 | ||||
| // Main functionality
 | ||||
| int | ||||
| main() | ||||
| test_main( int , char * [] ) | ||||
| { | ||||
|     BOOST_TEST( obj_reg.db_.empty() ); | ||||
|     BOOST_TEST( obj_reg.defrauders_in_.empty() ); | ||||
|     BOOST_TEST( obj_reg.defrauders_out_.empty() ); | ||||
|     BOOST_TEST( obj_reg.overeager_.empty() ); | ||||
|     BOOST_TEST( obj_reg.overkilled_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.db_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.defrauders_in_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.defrauders_out_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.overeager_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.overkilled_.empty() ); | ||||
| 
 | ||||
|     // Make a separate block to examine pre- and post-effects
 | ||||
|     { | ||||
| @@ -185,20 +187,20 @@ main() | ||||
|         using std::endl; | ||||
| 
 | ||||
|         bad_class  bc; | ||||
|         BOOST_TEST( obj_reg.db_.size() == 3 ); | ||||
|         BOOST_TEST( obj_reg.defrauders_in_.size() == 1 ); | ||||
|         BOOST_CHECK( obj_reg.db_.size() == 3 ); | ||||
|         BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 ); | ||||
| 
 | ||||
|         good_class_1  gc1; | ||||
|         BOOST_TEST( obj_reg.db_.size() == 6 ); | ||||
|         BOOST_TEST( obj_reg.defrauders_in_.size() == 1 ); | ||||
|         BOOST_CHECK( obj_reg.db_.size() == 6 ); | ||||
|         BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 ); | ||||
| 
 | ||||
|         good_class_2  gc2; | ||||
|         BOOST_TEST( obj_reg.db_.size() == 11 ); | ||||
|         BOOST_TEST( obj_reg.defrauders_in_.size() == 1 ); | ||||
|         BOOST_CHECK( obj_reg.db_.size() == 11 ); | ||||
|         BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 ); | ||||
| 
 | ||||
|         BOOST_TEST( obj_reg.defrauders_out_.empty() ); | ||||
|         BOOST_TEST( obj_reg.overeager_.empty() ); | ||||
|         BOOST_TEST( obj_reg.overkilled_.empty() ); | ||||
|         BOOST_CHECK( obj_reg.defrauders_out_.empty() ); | ||||
|         BOOST_CHECK( obj_reg.overeager_.empty() ); | ||||
|         BOOST_CHECK( obj_reg.overkilled_.empty() ); | ||||
| 
 | ||||
|         // Getting the addresses of the objects ensure
 | ||||
|         // that they're used, and not optimized away.
 | ||||
| @@ -207,13 +209,13 @@ main() | ||||
|         cout << "Object 'gc2' is at " << &gc2 << '.' << endl; | ||||
|     } | ||||
| 
 | ||||
|     BOOST_TEST( obj_reg.db_.empty() ); | ||||
|     BOOST_TEST( obj_reg.defrauders_in_.size() == 1 ); | ||||
|     BOOST_TEST( obj_reg.defrauders_out_.size() == 1 ); | ||||
|     BOOST_TEST( obj_reg.overeager_.empty() ); | ||||
|     BOOST_TEST( obj_reg.overkilled_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.db_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 ); | ||||
|     BOOST_CHECK( obj_reg.defrauders_out_.size() == 1 ); | ||||
|     BOOST_CHECK( obj_reg.overeager_.empty() ); | ||||
|     BOOST_CHECK( obj_reg.overkilled_.empty() ); | ||||
| 
 | ||||
|     return boost::report_errors(); | ||||
|     return boost::exit_success; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										258
									
								
								binary_search_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								binary_search_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,258 @@ | ||||
| // (C) Copyright David Abrahams 2000. | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <memory> | ||||
| #include <climits> | ||||
| #include <iostream> | ||||
| #include <cassert> | ||||
| #include <stdlib.h> // for rand(). Would use cstdlib but VC6.4 doesn't put it in std:: | ||||
| #include <list> | ||||
| #include <algorithm> | ||||
| #include <boost/detail/binary_search.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <cstddef> | ||||
|  | ||||
| #if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) | ||||
| # define USE_SSTREAM | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_SSTREAM | ||||
| # include <sstream> | ||||
| #else | ||||
| # include <strstream> | ||||
| #endif | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| // In order to get ADL to find the comparison operators defined below, they have | ||||
| struct mystring : std::string | ||||
| { | ||||
|     typedef std::string base; | ||||
|      | ||||
|     mystring(std::string const& x) | ||||
|         : base(x) {} | ||||
| }; | ||||
|  | ||||
| typedef std::vector<mystring> string_vector; | ||||
|  | ||||
| const std::size_t sequence_length = 1000; | ||||
|  | ||||
| unsigned random_number() | ||||
| { | ||||
|     return static_cast<unsigned>(::rand()) % sequence_length; | ||||
| } | ||||
|  | ||||
| # ifndef USE_SSTREAM | ||||
| class unfreezer { | ||||
|  public: | ||||
|     unfreezer(std::ostrstream& s) : m_stream(s) {} | ||||
|     ~unfreezer() { m_stream.freeze(false); } | ||||
|  private: | ||||
|     std::ostrstream& m_stream; | ||||
| }; | ||||
| # endif | ||||
|  | ||||
| template <class T> | ||||
| void push_back_random_number_string(T& seq) | ||||
| { | ||||
|     unsigned value = random_number(); | ||||
| # if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) | ||||
|     std::ostringstream s; | ||||
|     s << value; | ||||
|     seq.push_back(s.str()); | ||||
| # else | ||||
|     std::ostrstream s; | ||||
|     auto unfreezer unfreeze(s); | ||||
|     s << value << char(0); | ||||
|     seq.push_back(std::string(s.str())); | ||||
| # endif | ||||
| } | ||||
|  | ||||
| inline unsigned to_int(unsigned x) { return x; } | ||||
| inline unsigned to_int(const std::string& x) { return atoi(x.c_str()); } | ||||
|  | ||||
| struct cmp | ||||
| { | ||||
|     template <class A1, class A2> | ||||
|     inline bool operator()(const A1& a1, const A2& a2) const | ||||
|     { | ||||
|         return to_int(a1) < to_int(a2); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| inline bool operator<(const mystring& x, const unsigned y) | ||||
| { | ||||
|     return to_int(x) < y; | ||||
| } | ||||
|  | ||||
| inline bool operator<(const unsigned y, const mystring& x) | ||||
| { | ||||
|     return y < to_int(x); | ||||
| } | ||||
|  | ||||
| template <class T> | ||||
| void sort_by_value(T& x); | ||||
|  | ||||
| template <class T> | ||||
| void sort_by_value_(T& v, long) | ||||
| { | ||||
|     std::sort(v.begin(), v.end(), cmp()); | ||||
| } | ||||
|  | ||||
| template <class T> | ||||
| void random_sorted_sequence(T& seq) | ||||
| { | ||||
|     seq.clear(); | ||||
|     for (std::size_t i = 0; i < sequence_length; ++i) | ||||
|     { | ||||
|         push_back_random_number_string(seq); | ||||
|     } | ||||
|     sort_by_value(seq); | ||||
| } | ||||
|  | ||||
| template <class T, class A> | ||||
| void sort_by_value_(std::list<T,A>& l, int) | ||||
| { | ||||
| # if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) && !defined(__SGI_STL_PORT) | ||||
| // VC6's standard lib doesn't have a template member function for list::sort() | ||||
|     std::vector<T> seq; | ||||
|     seq.reserve(sequence_length); | ||||
|     std::copy(l.begin(), l.end(), std::back_inserter(seq)); | ||||
|     sort_by_value(seq); | ||||
|     std::copy(seq.begin(), seq.end(), l.begin()); | ||||
| # else | ||||
|     l.sort(cmp()); | ||||
| # endif | ||||
| } | ||||
|  | ||||
| template <class T> | ||||
| void sort_by_value(T& x) | ||||
| { | ||||
|     (sort_by_value_)(x, 1); | ||||
| } | ||||
|  | ||||
| // A way to select the comparisons with/without a Compare parameter for testing. | ||||
| template <class Compare> struct searches | ||||
| { | ||||
|     template <class Iterator, class Key> | ||||
|     static Iterator lower_bound(Iterator start, Iterator finish, Key key, Compare cmp) | ||||
|         { return boost::detail::lower_bound(start, finish, key, cmp); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static Iterator upper_bound(Iterator start, Iterator finish, Key key, Compare cmp) | ||||
|         { return boost::detail::upper_bound(start, finish, key, cmp); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, Compare cmp) | ||||
|         { return boost::detail::equal_range(start, finish, key, cmp); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static bool binary_search(Iterator start, Iterator finish, Key key, Compare cmp) | ||||
|         { return boost::detail::binary_search(start, finish, key, cmp); } | ||||
| }; | ||||
|  | ||||
| struct no_compare {}; | ||||
|  | ||||
| template <> struct searches<no_compare> | ||||
| { | ||||
|     template <class Iterator, class Key> | ||||
|     static Iterator lower_bound(Iterator start, Iterator finish, Key key, no_compare) | ||||
|         { return boost::detail::lower_bound(start, finish, key); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static Iterator upper_bound(Iterator start, Iterator finish, Key key, no_compare) | ||||
|         { return boost::detail::upper_bound(start, finish, key); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, no_compare) | ||||
|         { return boost::detail::equal_range(start, finish, key); } | ||||
|  | ||||
|     template <class Iterator, class Key> | ||||
|     static bool binary_search(Iterator start, Iterator finish, Key key, no_compare) | ||||
|         { return boost::detail::binary_search(start, finish, key); } | ||||
| }; | ||||
|  | ||||
| template <class Sequence, class Compare> | ||||
| void test_loop(Sequence& x, Compare cmp, unsigned long test_count) | ||||
| { | ||||
|     typedef typename Sequence::const_iterator const_iterator; | ||||
|      | ||||
|     for (unsigned long i = 0; i < test_count; ++i) | ||||
|     { | ||||
|         random_sorted_sequence(x); | ||||
|         const const_iterator start = x.begin(); | ||||
|         const const_iterator finish = x.end(); | ||||
|          | ||||
|         unsigned key = random_number(); | ||||
|         const const_iterator l = searches<Compare>::lower_bound(start, finish, key, cmp); | ||||
|         const const_iterator u = searches<Compare>::upper_bound(start, finish, key, cmp); | ||||
|  | ||||
|         bool found_l = false; | ||||
|         bool found_u = false; | ||||
|         std::size_t index = 0; | ||||
|         std::size_t count = 0; | ||||
|         unsigned last_value = 0; | ||||
|         for (const_iterator p = start; p != finish; ++p) | ||||
|         { | ||||
|             if (p == l) | ||||
|                 found_l = true; | ||||
|              | ||||
|             if (p == u) | ||||
|             { | ||||
|                 assert(found_l); | ||||
|                 found_u = true; | ||||
|             } | ||||
|  | ||||
|             unsigned value = to_int(*p); | ||||
|             assert(value >= last_value); | ||||
|             last_value = value; | ||||
|              | ||||
|             if (!found_l) | ||||
|             { | ||||
|                 ++index; | ||||
|                 assert(to_int(*p) < key); | ||||
|             } | ||||
|             else if (!found_u) | ||||
|             { | ||||
|                 ++count; | ||||
|                 assert(to_int(*p) == key); | ||||
|             } | ||||
|             else | ||||
|                 assert(to_int(*p) > key); | ||||
|         } | ||||
|         assert(found_l || l == finish); | ||||
|         assert(found_u || u == finish); | ||||
|  | ||||
|         std::pair<const_iterator, const_iterator> | ||||
|             range = searches<Compare>::equal_range(start, finish, key, cmp); | ||||
|         assert(range.first == l); | ||||
|         assert(range.second == u); | ||||
|  | ||||
|         bool found = searches<Compare>::binary_search(start, finish, key, cmp); | ||||
|         assert(found == (u != l)); | ||||
|         std::cout << "found " << count << " copies of " << key << " at index " << index << "\n"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     string_vector x; | ||||
|     std::cout << "=== testing random-access iterators with <: ===\n"; | ||||
|     test_loop(x, no_compare(), 25); | ||||
|     std::cout << "=== testing random-access iterators with compare: ===\n"; | ||||
|     test_loop(x, cmp(), 25); | ||||
|      | ||||
|     std::list<mystring> y; | ||||
|     std::cout << "=== testing bidirectional iterators with <: ===\n"; | ||||
|     test_loop(y, no_compare(), 25); | ||||
|     std::cout << "=== testing bidirectional iterators with compare: ===\n"; | ||||
|     test_loop(y, cmp(), 25); | ||||
|     std::cerr << "******TEST PASSED******\n"; | ||||
|     return 0; | ||||
| } | ||||
| @@ -6,7 +6,7 @@ | ||||
|     http://www.boost.org/LICENSE_1_0.txt)
 | ||||
| ==============================================================================*/ | ||||
| 
 | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
| #include <boost/test/minimal.hpp> | ||||
| #include <boost/utility/binary.hpp> | ||||
| #include <algorithm> | ||||
| #include <cstddef> | ||||
| @@ -614,34 +614,34 @@ typedef char (&unsigned_long_int_id_type)[unsigned_long_int_id]; | ||||
| unsigned_int_id_type      binary_type_checker( unsigned int ); | ||||
| unsigned_long_int_id_type binary_type_checker( unsigned long int ); | ||||
| 
 | ||||
| int main() | ||||
| int test_main( int, char *[] ) | ||||
| { | ||||
|   BOOST_TEST( is_ascending_from_0_array( unsigned_ints_1_bit ) ); | ||||
|   BOOST_TEST( is_ascending_from_0_array( unsigned_ints_2_bits ) ); | ||||
|   BOOST_TEST( is_ascending_from_0_array( unsigned_ints_3_bits ) ); | ||||
|   BOOST_TEST( is_ascending_from_0_array( unsigned_ints_4_bits ) ); | ||||
|   BOOST_TEST( is_ascending_from_0_array( unsigned_ints_5_bits ) ); | ||||
|   BOOST_TEST( is_ascending_from_0_array( unsigned_ints_6_bits ) ); | ||||
|   BOOST_TEST( is_ascending_from_0_array( unsigned_ints_7_bits ) ); | ||||
|   BOOST_TEST( is_ascending_from_0_array( unsigned_ints_8_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_1_bit ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_2_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_3_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_4_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_5_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_6_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_7_bits ) ); | ||||
|   BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_8_bits ) ); | ||||
| 
 | ||||
|   BOOST_TEST( std::equal( &random_unsigned_ints_hex[0] | ||||
|   BOOST_CHECK( std::equal( &random_unsigned_ints_hex[0] | ||||
|                          , random_unsigned_ints_hex + num_random_test_values | ||||
|                          , &random_unsigned_ints_binary[0] | ||||
|                          ) | ||||
|              ); | ||||
| 
 | ||||
|   BOOST_TEST(    sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) ) | ||||
|   BOOST_CHECK(    sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) ) | ||||
|                == unsigned_int_id | ||||
|              ); | ||||
| 
 | ||||
|   BOOST_TEST(    sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) ) | ||||
|   BOOST_CHECK(    sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) ) | ||||
|                == unsigned_long_int_id | ||||
|              ); | ||||
| 
 | ||||
|   BOOST_TEST(    sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) ) | ||||
|   BOOST_CHECK(    sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) ) | ||||
|                == unsigned_long_int_id | ||||
|              ); | ||||
| 
 | ||||
|   return boost::report_errors(); | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										762
									
								
								call_traits.htm
									
									
									
									
									
								
							
							
						
						
									
										762
									
								
								call_traits.htm
									
									
									
									
									
								
							| @@ -1,19 +1,755 @@ | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|    <title>Boost.CallTraits</title> | ||||
|    <meta http-equiv="refresh" content="0; URL=./doc/html/utility/utilities/call_traits.html"> | ||||
| <meta http-equiv="Content-Type" | ||||
| content="text/html; charset=iso-8859-1"> | ||||
| <meta name="Template" | ||||
| content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot"> | ||||
| <meta name="GENERATOR" content="Microsoft FrontPage Express 2.0"> | ||||
| <title>Call Traits</title> | ||||
| </head> | ||||
| <body> | ||||
| Automatic redirection failed, please go to | ||||
| <a href="./doc/html/utility/utilities/call_traits.html">./doc/html/utility/utilities/call_traits.html</a> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" | ||||
| vlink="#800080"> | ||||
|  | ||||
| <h1><img src="../../boost.png" width="276" height="86">Header | ||||
| <<a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a>></h1> | ||||
|  | ||||
| <p>All of the contents of <boost/call_traits.hpp> are | ||||
| defined inside namespace boost.</p> | ||||
|  | ||||
| <p>The template class call_traits<T> encapsulates the | ||||
| "best" method to pass a parameter of some type T to or | ||||
| from a function, and consists of a collection of typedefs defined | ||||
| as in the table below. The purpose of call_traits is to ensure | ||||
| that problems like "<a href="#refs">references to references</a>" | ||||
| never occur, and that parameters are passed in the most efficient | ||||
| manner possible (see <a href="#examples">examples</a>). In each | ||||
| case if your existing practice is to use the type defined on the | ||||
| left, then replace it with the call_traits defined type on the | ||||
| right. </p> | ||||
|  | ||||
| <p>Note that for compilers that do not support either partial | ||||
| specialization or member templates, no benefit will occur from | ||||
| using call_traits: the call_traits defined types will always be | ||||
| the same as the existing practice in this case. In addition if | ||||
| only member templates and not partial template specialisation is | ||||
| support by the compiler (for example Visual C++ 6) then | ||||
| call_traits can not be used with array types (although it can be | ||||
| used to solve the reference to reference problem).</p> | ||||
|  | ||||
| <table border="0" cellpadding="7" cellspacing="1" width="797"> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#008080"><p | ||||
|         align="center">Existing practice</p> | ||||
|         </td> | ||||
|         <td valign="top" width="35%" bgcolor="#008080"><p | ||||
|         align="center">call_traits equivalent</p> | ||||
|         </td> | ||||
|         <td valign="top" width="32%" bgcolor="#008080"><p | ||||
|         align="center">Description</p> | ||||
|         </td> | ||||
|         <td valign="top" width="16%" bgcolor="#008080"><p | ||||
|         align="center">Notes</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%"><p align="center">T<br> | ||||
|         (return by value)</p> | ||||
|         </td> | ||||
|         <td valign="top" width="35%"><p align="center"><code>call_traits<T>::value_type</code></p> | ||||
|         </td> | ||||
|         <td valign="top" width="32%">Defines a type that | ||||
|         represents the "value" of type T. Use this for | ||||
|         functions that return by value, or possibly for stored | ||||
|         values of type T.</td> | ||||
|         <td valign="top" width="16%"><p align="center">2</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%"><p align="center">T&<br> | ||||
|         (return value)</p> | ||||
|         </td> | ||||
|         <td valign="top" width="35%"><p align="center"><code>call_traits<T>::reference</code></p> | ||||
|         </td> | ||||
|         <td valign="top" width="32%">Defines a type that | ||||
|         represents a reference to type T. Use for functions that | ||||
|         would normally return a T&.</td> | ||||
|         <td valign="top" width="16%"><p align="center">1</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%"><p align="center">const | ||||
|         T&<br> | ||||
|         (return value)</p> | ||||
|         </td> | ||||
|         <td valign="top" width="35%"><p align="center"><code>call_traits<T>::const_reference</code></p> | ||||
|         </td> | ||||
|         <td valign="top" width="32%">Defines a type that | ||||
|         represents a constant reference to type T. Use for | ||||
|         functions that would normally return a const T&.</td> | ||||
|         <td valign="top" width="16%"><p align="center">1</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%"><p align="center">const | ||||
|         T&<br> | ||||
|         (function parameter)</p> | ||||
|         </td> | ||||
|         <td valign="top" width="35%"><p align="center"><code>call_traits<T>::param_type</code></p> | ||||
|         </td> | ||||
|         <td valign="top" width="32%">Defines a type that | ||||
|         represents the "best" way to pass a parameter | ||||
|         of type T to a function.</td> | ||||
|         <td valign="top" width="16%"><p align="center">1,3</p> | ||||
|         </td> | ||||
|     </tr> | ||||
| </table> | ||||
|  | ||||
| <p>Notes:</p> | ||||
|  | ||||
| <ol> | ||||
|     <li>If T is already reference type, then call_traits is | ||||
|         defined such that <a href="#refs">references to | ||||
|         references</a> do not occur (requires partial | ||||
|         specialization).</li> | ||||
|     <li>If T is an array type, then call_traits defines <code>value_type</code> | ||||
|         as a "constant pointer to type" rather than an | ||||
|         "array of type" (requires partial | ||||
|         specialization). Note that if you are using value_type as | ||||
|         a stored value then this will result in storing a "constant | ||||
|         pointer to an array" rather than the array itself. | ||||
|         This may or may not be a good thing depending upon what | ||||
|         you actually need (in other words take care!).</li> | ||||
|     <li>If T is a small built in type or a pointer, then <code>param_type</code> | ||||
|         is defined as <code>T const</code>, instead of <code>T | ||||
|         const&</code>. This can improve the ability of the | ||||
|         compiler to optimize loops in the body of the function if | ||||
|         they depend upon the passed parameter, the semantics of | ||||
|         the passed parameter is otherwise unchanged (requires | ||||
|         partial specialization).</li> | ||||
| </ol> | ||||
|  | ||||
| <p> </p> | ||||
|  | ||||
| <h3>Copy constructibility</h3> | ||||
|  | ||||
| <p>The following table defines which call_traits types can always | ||||
| be copy-constructed from which other types, those entries marked | ||||
| with a '?' are true only if and only if T is copy constructible:</p> | ||||
|  | ||||
| <table border="0" cellpadding="7" cellspacing="1" width="766"> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%"> </td> | ||||
|         <td valign="top" colspan="5" width="85%" | ||||
|         bgcolor="#008080"><p align="center">To:</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#008080">From:</td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">T</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">value_type</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">reference</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">const_reference</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">param_type</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">T</td> | ||||
|         <td valign="top" width="17%"><p align="center">?</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">?</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td> | ||||
|         <td valign="top" width="17%"><p align="center">?</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">?</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">N</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">N</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td> | ||||
|         <td valign="top" width="17%"><p align="center">?</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">?</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td> | ||||
|         <td valign="top" width="17%"><p align="center">?</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">N</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">N</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td> | ||||
|         <td valign="top" width="17%"><p align="center">?</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">?</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">N</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">N</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|     </tr> | ||||
| </table> | ||||
|  | ||||
| <p> </p> | ||||
|  | ||||
| <p>If T is an assignable type the following assignments are | ||||
| possible:</p> | ||||
|  | ||||
| <table border="0" cellpadding="7" cellspacing="1" width="766"> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%"> </td> | ||||
|         <td valign="top" colspan="5" width="85%" | ||||
|         bgcolor="#008080"><p align="center">To:</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#008080">From:</td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">T</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">value_type</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">reference</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">const_reference</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">param_type</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">T</td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">Y</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">-</p> | ||||
|         </td> | ||||
|     </tr> | ||||
| </table> | ||||
|  | ||||
| <p> </p> | ||||
|  | ||||
| <h3><a name="examples"></a>Examples</h3> | ||||
|  | ||||
| <p>The following table shows the effect that call_traits has on | ||||
| various types, the table assumes that the compiler supports | ||||
| partial specialization: if it doesn't then all types behave in | ||||
| the same way as the entry for "myclass", and | ||||
| call_traits can not be used with reference or array types.</p> | ||||
|  | ||||
| <table border="0" cellpadding="7" cellspacing="1" width="766"> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%"> </td> | ||||
|         <td valign="top" colspan="5" width="85%" | ||||
|         bgcolor="#008080"><p align="center">Call_traits type:</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#008080"><p | ||||
|         align="center">Original type T</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">value_type</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">reference</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">const_reference</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">param_type</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">Applies to:</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">myclass</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">myclass</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">myclass&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const | ||||
|         myclass&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">myclass | ||||
|         const&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">All user | ||||
|         defined types.</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">int</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const | ||||
|         int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int const</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">All small | ||||
|         built-in types.</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">int*</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int*</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int*&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int*const&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int* const</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">All | ||||
|         pointer types.</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const | ||||
|         int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">All | ||||
|         reference types.</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">const int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const | ||||
|         int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const | ||||
|         int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const | ||||
|         int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const | ||||
|         int&</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">All | ||||
|         constant-references.</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">int[3]</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const int*</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">int(&)[3]</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const int(&)[3]</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const int* | ||||
|         const</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">All array | ||||
|         types.</p> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td valign="top" width="17%" bgcolor="#C0C0C0"><p | ||||
|         align="center">const int[3]</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const int*</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const int(&)[3]</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const int(&)[3]</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">const int* | ||||
|         const</p> | ||||
|         </td> | ||||
|         <td valign="top" width="17%"><p align="center">All | ||||
|         constant-array types.</p> | ||||
|         </td> | ||||
|     </tr> | ||||
| </table> | ||||
|  | ||||
| <p> </p> | ||||
|  | ||||
| <h4>Example 1:</h4> | ||||
|  | ||||
| <p>The following class is a trivial class that stores some type T | ||||
| by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a> | ||||
| file), the aim is to illustrate how each of the available | ||||
| call_traits typedefs may be used:</p> | ||||
|  | ||||
| <pre>template <class T> | ||||
| struct contained | ||||
| { | ||||
|    // define our typedefs first, arrays are stored by value | ||||
|    // so value_type is not the same as result_type: | ||||
|    typedef typename boost::call_traits<T>::param_type       param_type; | ||||
|    typedef typename boost::call_traits<T>::reference        reference; | ||||
|    typedef typename boost::call_traits<T>::const_reference  const_reference; | ||||
|    typedef T                                                value_type; | ||||
|    typedef typename boost::call_traits<T>::value_type       result_type; | ||||
|  | ||||
|    // stored value: | ||||
|    value_type v_; | ||||
|     | ||||
|    // constructors: | ||||
|    contained() {} | ||||
|    contained(param_type p) : v_(p){} | ||||
|    // return byval: | ||||
|    result_type value() { return v_; } | ||||
|    // return by_ref: | ||||
|    reference get() { return v_; } | ||||
|    const_reference const_get()const { return v_; } | ||||
|    // pass value: | ||||
|    void call(param_type p){} | ||||
|  | ||||
| };</pre> | ||||
|  | ||||
| <h4><a name="refs"></a>Example 2 (the reference to reference | ||||
| problem):</h4> | ||||
|  | ||||
| <p>Consider the definition of std::binder1st:</p> | ||||
|  | ||||
| <pre>template <class Operation>  | ||||
| class binder1st :  | ||||
|    public unary_function<typename Operation::second_argument_type, typename Operation::result_type>  | ||||
| {  | ||||
| protected:  | ||||
|    Operation op;  | ||||
|    typename Operation::first_argument_type value;  | ||||
| public:  | ||||
|    binder1st(const Operation& x, const typename Operation::first_argument_type& y);  | ||||
|    typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const;  | ||||
| }; </pre> | ||||
|  | ||||
| <p>Now consider what happens in the relatively common case that | ||||
| the functor takes its second argument as a reference, that | ||||
| implies that <code>Operation::second_argument_type</code> is a | ||||
| reference type, <code>operator()</code> will now end up taking a | ||||
| reference to a reference as an argument, and that is not | ||||
| currently legal. The solution here is to modify <code>operator()</code> | ||||
| to use call_traits:</p> | ||||
|  | ||||
| <pre>typename Operation::result_type operator()(typename call_traits<typename Operation::second_argument_type>::param_type x) const;</pre> | ||||
|  | ||||
| <p>Now in the case that <code>Operation::second_argument_type</code> | ||||
| is a reference type, the argument is passed as a reference, and | ||||
| the no "reference to reference" occurs.</p> | ||||
|  | ||||
| <h4><a name="ex3"></a>Example 3 (the make_pair problem):</h4> | ||||
|  | ||||
| <p>If we pass the name of an array as one (or both) arguments to <code>std::make_pair</code>, | ||||
| then template argument deduction deduces the passed parameter as | ||||
| "const reference to array of T", this also applies to | ||||
| string literals (which are really array literals). Consequently | ||||
| instead of returning a pair of pointers, it tries to return a | ||||
| pair of arrays, and since an array type is not copy-constructible | ||||
| the code fails to compile. One solution is to explicitly cast the | ||||
| arguments to make_pair to pointers, but call_traits provides a | ||||
| better (i.e. automatic) solution (and one that works safely even | ||||
| in generic code where the cast might do the wrong thing):</p> | ||||
|  | ||||
| <pre>template <class T1, class T2> | ||||
| std::pair< | ||||
|    typename boost::call_traits<T1>::value_type,  | ||||
|    typename boost::call_traits<T2>::value_type>  | ||||
|       make_pair(const T1& t1, const T2& t2) | ||||
| { | ||||
|    return std::pair< | ||||
|       typename boost::call_traits<T1>::value_type,  | ||||
|       typename boost::call_traits<T2>::value_type>(t1, t2); | ||||
| }</pre> | ||||
|  | ||||
| <p>Here, the deduced argument types will be automatically | ||||
| degraded to pointers if the deduced types are arrays, similar | ||||
| situations occur in the standard binders and adapters: in | ||||
| principle in any function that "wraps" a temporary | ||||
| whose type is deduced. Note that the function arguments to | ||||
| make_pair are not expressed in terms of call_traits: doing so | ||||
| would prevent template argument deduction from functioning.</p> | ||||
|  | ||||
| <h4><a name="ex4"></a>Example 4 (optimising fill):</h4> | ||||
|  | ||||
| <p>The call_traits template will "optimize" the passing | ||||
| of a small built-in type as a function parameter, this mainly has | ||||
| an effect when the parameter is used within a loop body. In the | ||||
| following example (see <a | ||||
| href="../type_traits/examples/fill_example.cpp">fill_example.cpp</a>), | ||||
| a version of std::fill is optimized in two ways: if the type | ||||
| passed is a single byte built-in type then std::memset is used to | ||||
| effect the fill, otherwise a conventional C++ implemention is | ||||
| used, but with the passed parameter "optimized" using | ||||
| call_traits:</p> | ||||
|  | ||||
| <pre>namespace detail{ | ||||
|  | ||||
| template <bool opt> | ||||
| struct filler | ||||
| { | ||||
|    template <typename I, typename T> | ||||
|    static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val) | ||||
|    { | ||||
|       while(first != last) | ||||
|       { | ||||
|          *first = val; | ||||
|          ++first; | ||||
|       } | ||||
|    } | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct filler<true> | ||||
| { | ||||
|    template <typename I, typename T> | ||||
|    static void do_fill(I first, I last, T val) | ||||
|    { | ||||
|       memset(first, val, last-first); | ||||
|    } | ||||
| }; | ||||
|  | ||||
| } | ||||
|  | ||||
| template <class I, class T> | ||||
| inline void fill(I first, I last, const T& val) | ||||
| { | ||||
|    enum{ can_opt = boost::is_pointer<I>::value | ||||
|                    && boost::is_arithmetic<T>::value | ||||
|                    && (sizeof(T) == 1) }; | ||||
|    typedef detail::filler<can_opt> filler_t; | ||||
|    filler_t::template do_fill<I,T>(first, last, val); | ||||
| }</pre> | ||||
|  | ||||
| <p>Footnote: the reason that this is "optimal" for | ||||
| small built-in types is that with the value passed as "T | ||||
| const" instead of "const T&" the compiler is | ||||
| able to tell both that the value is constant and that it is free | ||||
| of aliases. With this information the compiler is able to cache | ||||
| the passed value in a register, unroll the loop, or use | ||||
| explicitly parallel instructions: if any of these are supported. | ||||
| Exactly how much mileage you will get from this depends upon your | ||||
| compiler - we could really use some accurate benchmarking | ||||
| software as part of boost for cases like this.</p> | ||||
|  | ||||
| <p>Note that the function arguments to fill are not expressed in | ||||
| terms of call_traits: doing so would prevent template argument | ||||
| deduction from functioning. Instead fill acts as a "thin | ||||
| wrapper" that is there to perform template argument | ||||
| deduction, the compiler will optimise away the call to fill all | ||||
| together, replacing it with the call to filler<>::do_fill, | ||||
| which does use call_traits.</p> | ||||
|  | ||||
| <h3>Rationale</h3> | ||||
|  | ||||
| <p>The following notes are intended to briefly describe the | ||||
| rational behind choices made in call_traits.</p> | ||||
|  | ||||
| <p>All user-defined types follow "existing practice" | ||||
| and need no comment.</p> | ||||
|  | ||||
| <p>Small built-in types (what the standard calls fundamental | ||||
| types [3.9.1]) differ from existing practice only in the <i>param_type</i> | ||||
| typedef. In this case passing "T const" is compatible | ||||
| with existing practice, but may improve performance in some cases | ||||
| (see <a href="#ex4">Example 4</a>), in any case this should never | ||||
| be any worse than existing practice.</p> | ||||
|  | ||||
| <p>Pointers follow the same rational as small built-in types.</p> | ||||
|  | ||||
| <p>For reference types the rational follows <a href="#refs">Example | ||||
| 2</a> - references to references are not allowed, so the | ||||
| call_traits members must be defined such that these problems do | ||||
| not occur. There is a proposal to modify the language such that | ||||
| "a reference to a reference is a reference" (issue #106, | ||||
| submitted by Bjarne Stroustrup), call_traits<T>::value_type | ||||
| and call_traits<T>::param_type both provide the same effect | ||||
| as that proposal, without the need for a language change (in | ||||
| other words it's a workaround).</p> | ||||
|  | ||||
| <p>For array types, a function that takes an array as an argument | ||||
| will degrade the array type to a pointer type: this means that | ||||
| the type of the actual parameter is different from its declared | ||||
| type, something that can cause endless problems in template code | ||||
| that relies on the declared type of a parameter. For example:</p> | ||||
|  | ||||
| <pre>template <class T> | ||||
| struct A | ||||
| { | ||||
|    void foo(T t); | ||||
| };</pre> | ||||
|  | ||||
| <p><font face="Times New Roman">In this case if we instantiate | ||||
| A<int[2]> then the declared type of the parameter passed to | ||||
| member function foo is int[2], but it's actual type is const int*, | ||||
| if we try to use the type T within the function body, then there | ||||
| is a strong likelyhood that our code will not compile:</font></p> | ||||
|  | ||||
| <pre>template <class T> | ||||
| void A<T>::foo(T t) | ||||
| { | ||||
|    T dup(t); // doesn't compile for case that T is an array. | ||||
| }</pre> | ||||
|  | ||||
| <p>By using call_traits the degradation from array to pointer is | ||||
| explicit, and the type of the parameter is the same as it's | ||||
| declared type:</p> | ||||
|  | ||||
| <pre>template <class T> | ||||
| struct A | ||||
| { | ||||
|    void foo(typename call_traits<T>::value_type t); | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| void A<T>::foo(typename call_traits<T>::value_type t) | ||||
| { | ||||
|    typename call_traits<T>::value_type dup(t); // OK even if T is an array type. | ||||
| }</pre> | ||||
|  | ||||
| <p>For value_type (return by value), again only a pointer may be | ||||
| returned, not a copy of the whole array, and again call_traits | ||||
| makes the degradation explicit. The value_type member is useful | ||||
| whenever an array must be explicitly degraded to a pointer - <a | ||||
| href="#ex3">Example 3</a> provides the test case (Footnote: the | ||||
| array specialisation for call_traits is the least well understood | ||||
| of all the call_traits specialisations, if the given semantics | ||||
| cause specific problems for you, or don't solve a particular | ||||
| array-related problem, then I would be interested to hear about | ||||
| it. Most people though will probably never need to use this | ||||
| specialisation).</p> | ||||
|  | ||||
| <hr> | ||||
| <tt> | ||||
|    Boost.CallTraits<br> | ||||
|    <br> | ||||
|    Distributed under the Boost Software License, Version 1.0. | ||||
|    (See accompanying file LICENSE_1_0.txt or copy at | ||||
|    <a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>) <br> | ||||
|    <br> | ||||
| </tt> | ||||
|  | ||||
| <p>Revised 01 September 2000</p> | ||||
|  | ||||
|    <p> | ||||
|       Copyright 2000 Steve Cleary, Beman Dawes, Howard | ||||
|       Hinnant and John Maddock. <br/> | ||||
|       Use, modification and distribution are subject to the | ||||
|       Boost Software License, Version 1.0. | ||||
|       (See accompanying file LICENSE_1_0.txt | ||||
|       or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> | ||||
|          http://www.boost.org/LICENSE_1_0.txt | ||||
|       </a>). | ||||
|    </p> | ||||
| </body> | ||||
| </html> | ||||
|  | ||||
|   | ||||
| @@ -201,7 +201,7 @@ struct comparible_UDT | ||||
|       i_ = other.i_; | ||||
|       return *this; | ||||
|    } | ||||
|    bool operator == (const comparible_UDT& v) const { return v.i_ == i_; } | ||||
|    bool operator == (const comparible_UDT& v){ return v.i_ == i_; } | ||||
| }; | ||||
| 
 | ||||
| int main() | ||||
| @@ -376,7 +376,7 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>: | ||||
|    reference r = t; | ||||
|    const_reference cr = t; | ||||
|    reference r2 = r; | ||||
|    #ifndef BOOST_BORLANDC | ||||
|    #ifndef __BORLANDC__ | ||||
|    // C++ Builder buglet:
 | ||||
|    const_reference cr2 = r; | ||||
|    #endif | ||||
| @@ -393,7 +393,7 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>: | ||||
|    unused_variable(v3); | ||||
|    unused_variable(v4); | ||||
|    unused_variable(v5); | ||||
| #ifndef BOOST_BORLANDC | ||||
| #ifndef __BORLANDC__ | ||||
|    unused_variable(r2); | ||||
|    unused_variable(cr2); | ||||
| #endif | ||||
| @@ -1,19 +1,122 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | ||||
| <html> | ||||
| <head> | ||||
|     <title>Boost.Utility</title> | ||||
|     <meta http-equiv="refresh" content="0; URL=../core/doc/html/core/checked_delete.html"> | ||||
| </head> | ||||
| <body> | ||||
| Automatic redirection failed, please go to | ||||
| <a href="../core/doc/html/core/checked_delete.html">../core/doc/html/core/checked_delete.html</a> | ||||
| <hr> | ||||
| <tt> | ||||
|     Boost.Utility<br> | ||||
|     <br> | ||||
|     Distributed under the Boost Software License, Version 1.0. | ||||
|     (See accompanying file LICENSE_1_0.txt or copy at | ||||
|     <a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>) <br> | ||||
|     <br> | ||||
| </tt> | ||||
| </body> | ||||
| 	<head> | ||||
| 		<title>Boost: checked_delete.hpp documentation</title> | ||||
| 		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||||
| 	</head> | ||||
| 	<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%"> | ||||
| 		<table border="0" width="100%"> | ||||
| 			<tr> | ||||
| 				<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A> | ||||
| 				</td> | ||||
| 				<td align="center"> | ||||
| 					<h1>checked_delete.hpp</h1> | ||||
| 				</td> | ||||
| 			</tr> | ||||
| 			<tr> | ||||
| 				<td colspan="2" height="64"> </td> | ||||
| 			</tr> | ||||
| 		</table> | ||||
| 		<p> | ||||
| 			The header <STRONG><boost/checked_delete.hpp></STRONG> defines two  | ||||
| 			function templates, <STRONG>checked_delete</STRONG> and <STRONG>checked_array_delete</STRONG>,  | ||||
| 			and two class templates, <STRONG>checked_deleter</STRONG> and <STRONG>checked_array_deleter</STRONG>. | ||||
| 		</p> | ||||
| 		<P>The C++ Standard allows, in 5.3.5/5, pointers to incomplete class types to be  | ||||
| 			deleted with a <EM>delete-expression</EM>. When the class has a non-trivial  | ||||
| 			destructor, or a class-specific operator delete, the behavior is undefined.  | ||||
| 			Some compilers issue a warning when an incomplete type is deleted, but  | ||||
| 			unfortunately, not all do, and programmers sometimes ignore or disable  | ||||
| 			warnings.</P> | ||||
| 		<P>A particularly troublesome case is when a smart pointer's destructor, such as <STRONG> | ||||
| 				boost::scoped_ptr<T>::~scoped_ptr</STRONG>, is instantiated with an  | ||||
| 			incomplete type. This can often lead to silent, hard to track failures.</P> | ||||
| 		<P>The supplied function and class templates can be used to prevent these problems,  | ||||
| 			as they require a complete type, and cause a compilation error otherwise.</P> | ||||
| 		<h3><a name="Synopsis">Synopsis</a></h3> | ||||
| 		<pre> | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| template<class T> void checked_delete(T * p); | ||||
| template<class T> void checked_array_delete(T * p); | ||||
| template<class T> struct checked_deleter; | ||||
| template<class T> struct checked_array_deleter; | ||||
|  | ||||
| } | ||||
| </pre> | ||||
| 		<h3>checked_delete</h3> | ||||
| 		<h4><a name="checked_delete">template<class T> void checked_delete(T * p);</a></h4> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete p</tt> | ||||
| 				must be well-formed. | ||||
| 			</p> | ||||
| 			<p> | ||||
| 				<b>Effects:</b> <tt>delete p;</tt> | ||||
| 			</p> | ||||
| 		</blockquote> | ||||
| 		<h3>checked_array_delete</h3> | ||||
| 		<h4><a name="checked_array_delete">template<class T> void checked_array_delete(T  | ||||
| 				* p);</a></h4> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete [] p</tt> | ||||
| 				must be well-formed. | ||||
| 			</p> | ||||
| 			<p> | ||||
| 				<b>Effects:</b> <tt>delete [] p;</tt> | ||||
| 			</p> | ||||
| 		</blockquote> | ||||
| 		<h3>checked_deleter</h3> | ||||
| 		<pre> | ||||
| template<class T> struct checked_deleter | ||||
| { | ||||
|     typedef void result_type; | ||||
|     typedef T * argument_type; | ||||
|     void operator()(T * p) const; | ||||
| }; | ||||
| </pre> | ||||
| 		<h4>void checked_deleter<T>::operator()(T * p) const;</h4> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete p</tt> | ||||
| 				must be well-formed. | ||||
| 			</p> | ||||
| 			<p> | ||||
| 				<b>Effects:</b> <tt>delete p;</tt> | ||||
| 			</p> | ||||
| 		</blockquote> | ||||
| 		<h3>checked_array_deleter</h3> | ||||
| 		<pre> | ||||
| template<class T> struct checked_array_deleter | ||||
| { | ||||
|     typedef void result_type; | ||||
|     typedef T * argument_type; | ||||
|     void operator()(T * p) const; | ||||
| }; | ||||
| </pre> | ||||
| 		<h4>void checked_array_deleter<T>::operator()(T * p) const;</h4> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete [] p</tt> | ||||
| 				must be well-formed. | ||||
| 			</p> | ||||
| 			<p> | ||||
| 				<b>Effects:</b> <tt>delete [] p;</tt> | ||||
| 			</p> | ||||
| 		</blockquote> | ||||
| 		<h3><a name="Acknowledgements">Acknowledgements</a></h3> | ||||
| 		<p> | ||||
| 			The function templates <STRONG>checked_delete</STRONG> and <STRONG>checked_array_delete</STRONG> | ||||
| 			were originally part of <STRONG><boost/utility.hpp></STRONG>, and the  | ||||
| 			documentation acknowledged Beman Dawes, Dave Abrahams, Vladimir Prus, Rainer  | ||||
| 			Deyke, John Maddock, and others as contributors. | ||||
| 		</p> | ||||
| 		<p> | ||||
| 			<br> | ||||
| 			<small>Copyright <20> 2002 by Peter Dimov. Distributed under the Boost Software License, Version  | ||||
| 				1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or  | ||||
| 				copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> | ||||
| 	</body> | ||||
| </html> | ||||
|   | ||||
							
								
								
									
										28
									
								
								checked_delete_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								checked_delete_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| //  Boost checked_delete test program  ---------------------------------------// | ||||
|  | ||||
| //  Copyright Beman Dawes 2001.  Distributed under the Boost | ||||
| //  Software License, Version 1.0. (See accompanying file | ||||
| //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  See http://www.boost.org/libs/utility for documentation. | ||||
|  | ||||
| //  Revision History | ||||
| //  21 May 01  Initial version (Beman Dawes) | ||||
|  | ||||
| #include <boost/checked_delete.hpp>  // for checked_delete | ||||
|  | ||||
| //  This program demonstrates compiler errors when trying to delete an | ||||
| //  incomplete type. | ||||
|  | ||||
| namespace | ||||
| { | ||||
|     class Incomplete; | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     Incomplete * p = 0; | ||||
|     boost::checked_delete(p);          // should cause compile time error | ||||
|     boost::checked_array_delete(p);    // should cause compile time error | ||||
|     return 0; | ||||
| }   // main | ||||
| @@ -1,19 +1,76 @@ | ||||
| <html> | ||||
| <head> | ||||
|     <title>Boost.Utility</title> | ||||
|     <meta http-equiv="refresh" content="0; URL=./doc/html/utility/utilities/compressed_pair.html"> | ||||
| </head> | ||||
| <body> | ||||
| Automatic redirection failed, please go to | ||||
| <a href="./doc/html/utility/utilities/compressed_pair.html">./doc/html/utility/utilities/compressed_pair.html</a> | ||||
| <hr> | ||||
| <tt> | ||||
|     Boost.Utility<br> | ||||
|     <br> | ||||
|     Distributed under the Boost Software License, Version 1.0. | ||||
|     (See accompanying file LICENSE_1_0.txt or copy at | ||||
|     <a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>) <br> | ||||
|     <br> | ||||
| </tt> | ||||
| </body> | ||||
|    <head> | ||||
|       <title>Header </title> | ||||
|       <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||||
|       <meta name="Template" content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot"> | ||||
|       <meta name="GENERATOR" content="Microsoft FrontPage 5.0"> | ||||
|       <boostcompressed_pair.hpp> | ||||
|    </head> | ||||
|    <body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#800080"> | ||||
|       <h2><img src="../../boost.png" width="276" height="86">Header <<a href="../../boost/detail/compressed_pair.hpp">boost/compressed_pair.hpp</a>></h2> | ||||
|       <p>All of the contents of <boost/compressed_pair.hpp> are defined inside  | ||||
|          namespace boost.</p> | ||||
|       <p>The class compressed pair is very similar to std::pair, but if either of the  | ||||
|          template arguments are empty classes, then the "empty base-class optimisation"  | ||||
|          is applied to compress the size of the pair.</p> | ||||
|       <pre>template <class T1, class T2> | ||||
| class compressed_pair | ||||
| { | ||||
| public: | ||||
| 	typedef T1                                                 first_type; | ||||
| 	typedef T2                                                 second_type; | ||||
| 	typedef typename call_traits<first_type>::param_type       first_param_type; | ||||
| 	typedef typename call_traits<second_type>::param_type      second_param_type; | ||||
| 	typedef typename call_traits<first_type>::reference        first_reference; | ||||
| 	typedef typename call_traits<second_type>::reference       second_reference; | ||||
| 	typedef typename call_traits<first_type>::const_reference  first_const_reference; | ||||
| 	typedef typename call_traits<second_type>::const_reference second_const_reference; | ||||
|  | ||||
| 	         compressed_pair() : base() {} | ||||
| 	         compressed_pair(first_param_type x, second_param_type y); | ||||
| 	explicit compressed_pair(first_param_type x); | ||||
| 	explicit compressed_pair(second_param_type y); | ||||
|  | ||||
| 	compressed_pair& operator=(const compressed_pair&); | ||||
|  | ||||
| 	first_reference       first(); | ||||
| 	first_const_reference first() const; | ||||
|  | ||||
| 	second_reference       second(); | ||||
| 	second_const_reference second() const; | ||||
|  | ||||
| 	void swap(compressed_pair& y); | ||||
| };</pre> | ||||
|       <p>The two members of the pair can be accessed using the member functions first()  | ||||
|          and second(). Note that not all member functions can be instantiated for all  | ||||
|          template parameter types. In particular compressed_pair can be instantiated for  | ||||
|          reference and array types, however in these cases the range of constructors  | ||||
|          that can be used are limited. If types T1 and T2 are the same type, then there  | ||||
|          is only one version of the single-argument constructor, and this constructor  | ||||
|          initialises both values in the pair to the passed value.</p> | ||||
|       <P>Note that if either member is a POD type, then that member is not  | ||||
|          zero-initialized by the compressed_pair default constructor: it's up to you to  | ||||
|          supply an initial value for these types if you want them to have a default  | ||||
|          value.</P> | ||||
|       <p>Note that compressed_pair can not be instantiated if either of the template  | ||||
|          arguments is a union type, unless there is compiler support for  | ||||
|          boost::is_union, or if boost::is_union is specialised for the union type.</p> | ||||
|       <p>Finally, a word of caution for Visual C++ 6 users: if either argument is an  | ||||
|          empty type, then assigning to that member will produce memory corruption,  | ||||
|          unless the empty type has a "do nothing" assignment operator defined. This is  | ||||
|          due to a bug in the way VC6 generates implicit assignment operators.</p> | ||||
|       <h3>Acknowledgements</h3> | ||||
|       <p>Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and John  | ||||
|          Maddock.</p> | ||||
|       <p>Maintained by <a href="mailto:john@johnmaddock.co.uk">John Maddock</a>, the  | ||||
|          latest version of this file can be found at <a href="http://www.boost.org">www.boost.org</a>,  | ||||
|          and the boost discussion list at <a href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p> | ||||
|       <hr> | ||||
|       <p>Revised | ||||
|       <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->07 November 2007<!--webbot bot="Timestamp" endspan i-checksum="40338" --></p> | ||||
|       <p><EFBFBD> Copyright Beman Dawes, 2000.</p> | ||||
| <p>Distributed under the Boost Software License, Version 1.0. See | ||||
| <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p> | ||||
|  | ||||
|    </body> | ||||
| </html> | ||||
| @@ -14,7 +14,7 @@ | ||||
| #include <cassert> | ||||
| 
 | ||||
| #include <boost/compressed_pair.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
| #include <boost/test/test_tools.hpp> | ||||
| 
 | ||||
| using namespace boost; | ||||
| 
 | ||||
| @@ -79,47 +79,47 @@ void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type | ||||
|    // first param construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp2(p1); | ||||
|    cp2.second() = p2; | ||||
|    BOOST_TEST(cp2.first() == p1); | ||||
|    BOOST_TEST(cp2.second() == p2); | ||||
|    BOOST_CHECK(cp2.first() == p1); | ||||
|    BOOST_CHECK(cp2.second() == p2); | ||||
|    // second param construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp3(p2); | ||||
|    cp3.first() = p1; | ||||
|    BOOST_TEST(cp3.second() == p2); | ||||
|    BOOST_TEST(cp3.first() == p1); | ||||
|    BOOST_CHECK(cp3.second() == p2); | ||||
|    BOOST_CHECK(cp3.first() == p1); | ||||
|    // both param construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp4(p1, p2); | ||||
|    BOOST_TEST(cp4.first() == p1); | ||||
|    BOOST_TEST(cp4.second() == p2); | ||||
|    BOOST_CHECK(cp4.first() == p1); | ||||
|    BOOST_CHECK(cp4.second() == p2); | ||||
|    boost::compressed_pair<T1,T2> cp5(p3, p4); | ||||
|    BOOST_TEST(cp5.first() == p3); | ||||
|    BOOST_TEST(cp5.second() == p4); | ||||
|    BOOST_CHECK(cp5.first() == p3); | ||||
|    BOOST_CHECK(cp5.second() == p4); | ||||
|    // check const members:
 | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp4; | ||||
|    BOOST_TEST(cpr1.first() == p1); | ||||
|    BOOST_TEST(cpr1.second() == p2); | ||||
|    BOOST_CHECK(cpr1.first() == p1); | ||||
|    BOOST_CHECK(cpr1.second() == p2); | ||||
| 
 | ||||
|    // copy construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp6(cp4); | ||||
|    BOOST_TEST(cp6.first() == p1); | ||||
|    BOOST_TEST(cp6.second() == p2); | ||||
|    BOOST_CHECK(cp6.first() == p1); | ||||
|    BOOST_CHECK(cp6.second() == p2); | ||||
|    // assignment:
 | ||||
|    cp1 = cp4; | ||||
|    BOOST_TEST(cp1.first() == p1); | ||||
|    BOOST_TEST(cp1.second() == p2); | ||||
|    BOOST_CHECK(cp1.first() == p1); | ||||
|    BOOST_CHECK(cp1.second() == p2); | ||||
|    cp1 = cp5; | ||||
|    BOOST_TEST(cp1.first() == p3); | ||||
|    BOOST_TEST(cp1.second() == p4); | ||||
|    BOOST_CHECK(cp1.first() == p3); | ||||
|    BOOST_CHECK(cp1.second() == p4); | ||||
|    // swap:
 | ||||
|    cp4.swap(cp5); | ||||
|    BOOST_TEST(cp4.first() == p3); | ||||
|    BOOST_TEST(cp4.second() == p4); | ||||
|    BOOST_TEST(cp5.first() == p1); | ||||
|    BOOST_TEST(cp5.second() == p2); | ||||
|    BOOST_CHECK(cp4.first() == p3); | ||||
|    BOOST_CHECK(cp4.second() == p4); | ||||
|    BOOST_CHECK(cp5.first() == p1); | ||||
|    BOOST_CHECK(cp5.second() == p2); | ||||
|    swap(cp4,cp5); | ||||
|    BOOST_TEST(cp4.first() == p1); | ||||
|    BOOST_TEST(cp4.second() == p2); | ||||
|    BOOST_TEST(cp5.first() == p3); | ||||
|    BOOST_TEST(cp5.second() == p4); | ||||
|    BOOST_CHECK(cp4.first() == p1); | ||||
|    BOOST_CHECK(cp4.second() == p2); | ||||
|    BOOST_CHECK(cp5.first() == p3); | ||||
|    BOOST_CHECK(cp5.second() == p4); | ||||
| } | ||||
| 
 | ||||
| //
 | ||||
| @@ -148,20 +148,20 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_ | ||||
| #endif | ||||
|    // both param construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp4(p1, p2); | ||||
|    BOOST_TEST(cp4.first() == p1); | ||||
|    BOOST_TEST(cp4.second() == p2); | ||||
|    BOOST_CHECK(cp4.first() == p1); | ||||
|    BOOST_CHECK(cp4.second() == p2); | ||||
|    boost::compressed_pair<T1,T2> cp5(p3, p4); | ||||
|    BOOST_TEST(cp5.first() == p3); | ||||
|    BOOST_TEST(cp5.second() == p4); | ||||
|    BOOST_CHECK(cp5.first() == p3); | ||||
|    BOOST_CHECK(cp5.second() == p4); | ||||
|    // check const members:
 | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp4; | ||||
|    BOOST_TEST(cpr1.first() == p1); | ||||
|    BOOST_TEST(cpr1.second() == p2); | ||||
|    BOOST_CHECK(cpr1.first() == p1); | ||||
|    BOOST_CHECK(cpr1.second() == p2); | ||||
| 
 | ||||
|    // copy construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp6(cp4); | ||||
|    BOOST_TEST(cp6.first() == p1); | ||||
|    BOOST_TEST(cp6.second() == p2); | ||||
|    BOOST_CHECK(cp6.first() == p1); | ||||
|    BOOST_CHECK(cp6.second() == p2); | ||||
|    // assignment:
 | ||||
|    // VC6 bug:
 | ||||
|    // When second() is an empty class, VC6 performs the
 | ||||
| @@ -174,8 +174,8 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_ | ||||
|    // settings - some generate the problem others do not.
 | ||||
|    cp4.first() = p3; | ||||
|    cp4.second() = p4; | ||||
|    BOOST_TEST(cp4.first() == p3); | ||||
|    BOOST_TEST(cp4.second() == p4); | ||||
|    BOOST_CHECK(cp4.first() == p3); | ||||
|    BOOST_CHECK(cp4.second() == p4); | ||||
| } | ||||
| //
 | ||||
| // supplimentary tests for case where first arg only is a reference type:
 | ||||
| @@ -199,8 +199,8 @@ void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second | ||||
|    // first param construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp2(p1); | ||||
|    cp2.second() = p2; | ||||
|    BOOST_TEST(cp2.first() == p1); | ||||
|    BOOST_TEST(cp2.second() == p2); | ||||
|    BOOST_CHECK(cp2.first() == p1); | ||||
|    BOOST_CHECK(cp2.second() == p2); | ||||
| #endif | ||||
| } | ||||
| //
 | ||||
| @@ -225,8 +225,8 @@ void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second | ||||
|    // second param construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp3(p2); | ||||
|    cp3.first() = p1; | ||||
|    BOOST_TEST(cp3.second() == p2); | ||||
|    BOOST_TEST(cp3.first() == p1); | ||||
|    BOOST_CHECK(cp3.second() == p2); | ||||
|    BOOST_CHECK(cp3.first() == p1); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| @@ -253,14 +253,14 @@ void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_par | ||||
|    // second param construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp3(p2); | ||||
|    cp3.first()[0] = p1[0]; | ||||
|    BOOST_TEST(cp3.second() == p2); | ||||
|    BOOST_TEST(cp3.first()[0] == p1[0]); | ||||
|    BOOST_CHECK(cp3.second() == p2); | ||||
|    BOOST_CHECK(cp3.first()[0] == p1[0]); | ||||
|    // check const members:
 | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp3; | ||||
|    BOOST_TEST(cpr1.first()[0] == p1[0]); | ||||
|    BOOST_TEST(cpr1.second() == p2); | ||||
|    BOOST_CHECK(cpr1.first()[0] == p1[0]); | ||||
|    BOOST_CHECK(cpr1.second() == p2); | ||||
| 
 | ||||
|    BOOST_TEST(sizeof(T1) == sizeof(cp1.first())); | ||||
|    BOOST_CHECK(sizeof(T1) == sizeof(cp1.first())); | ||||
| } | ||||
| 
 | ||||
| template <class T1, class T2> | ||||
| @@ -283,14 +283,14 @@ void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_par | ||||
|    // first param construct:
 | ||||
|    boost::compressed_pair<T1,T2> cp2(p1); | ||||
|    cp2.second()[0] = p2[0]; | ||||
|    BOOST_TEST(cp2.first() == p1); | ||||
|    BOOST_TEST(cp2.second()[0] == p2[0]); | ||||
|    BOOST_CHECK(cp2.first() == p1); | ||||
|    BOOST_CHECK(cp2.second()[0] == p2[0]); | ||||
|    // check const members:
 | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp2; | ||||
|    BOOST_TEST(cpr1.first() == p1); | ||||
|    BOOST_TEST(cpr1.second()[0] == p2[0]); | ||||
|    BOOST_CHECK(cpr1.first() == p1); | ||||
|    BOOST_CHECK(cpr1.second()[0] == p2[0]); | ||||
| 
 | ||||
|    BOOST_TEST(sizeof(T2) == sizeof(cp1.second())); | ||||
|    BOOST_CHECK(sizeof(T2) == sizeof(cp1.second())); | ||||
| } | ||||
| 
 | ||||
| template <class T1, class T2> | ||||
| @@ -312,18 +312,18 @@ void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_para | ||||
|    boost::compressed_pair<T1,T2> cp1; | ||||
|    cp1.first()[0] = p1[0]; | ||||
|    cp1.second()[0] = p2[0]; | ||||
|    BOOST_TEST(cp1.first()[0] == p1[0]); | ||||
|    BOOST_TEST(cp1.second()[0] == p2[0]); | ||||
|    BOOST_CHECK(cp1.first()[0] == p1[0]); | ||||
|    BOOST_CHECK(cp1.second()[0] == p2[0]); | ||||
|    // check const members:
 | ||||
|    const boost::compressed_pair<T1,T2>& cpr1 = cp1; | ||||
|    BOOST_TEST(cpr1.first()[0] == p1[0]); | ||||
|    BOOST_TEST(cpr1.second()[0] == p2[0]); | ||||
|    BOOST_CHECK(cpr1.first()[0] == p1[0]); | ||||
|    BOOST_CHECK(cpr1.second()[0] == p2[0]); | ||||
| 
 | ||||
|    BOOST_TEST(sizeof(T1) == sizeof(cp1.first())); | ||||
|    BOOST_TEST(sizeof(T2) == sizeof(cp1.second())); | ||||
|    BOOST_CHECK(sizeof(T1) == sizeof(cp1.first())); | ||||
|    BOOST_CHECK(sizeof(T2) == sizeof(cp1.second())); | ||||
| } | ||||
| 
 | ||||
| int main() | ||||
| int test_main(int, char *[]) | ||||
| { | ||||
|    // declare some variables to pass to the tester:
 | ||||
|    non_empty1 ne1(2); | ||||
| @@ -383,5 +383,13 @@ int main() | ||||
|    compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4); | ||||
|    // T1 == T2, both non-empty
 | ||||
|    compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2); | ||||
|    return boost::report_errors(); | ||||
|    return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| unsigned int expected_failures = 0; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										36
									
								
								current_function.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								current_function.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> | ||||
| <html> | ||||
| 	<head> | ||||
| 		<title>Boost: current_function.hpp documentation</title> | ||||
| 		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||||
| 	</head> | ||||
| 	<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%"> | ||||
| 		<table border="0" width="100%"> | ||||
| 			<tr> | ||||
| 				<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A> | ||||
| 				</td> | ||||
| 				<td align="center"> | ||||
| 					<h1>current_function.hpp</h1> | ||||
| 				</td> | ||||
| 			</tr> | ||||
| 			<tr> | ||||
| 				<td colspan="2" height="64"> </td> | ||||
| 			</tr> | ||||
| 		</table> | ||||
| 		<p> | ||||
| 			The header <STRONG><boost/current_function.hpp></STRONG> defines a single  | ||||
| 			macro, <STRONG>BOOST_CURRENT_FUNCTION</STRONG>,<STRONG> </STRONG>similar to the  | ||||
| 			C99 predefined identifier <STRONG>__func__</STRONG>. | ||||
| 		</p> | ||||
| 		<P><STRONG>BOOST_CURRENT_FUNCTION</STRONG> expands to a string literal containing  | ||||
| 			the (fully qualified, if possible) name of the enclosing function. If there is  | ||||
| 			no enclosing function, the behavior is undefined.</P> | ||||
| 		<p>Some compilers do not provide a way to obtain the name of the current enclosing  | ||||
| 			function. On such compilers, the string literal has an unspecified value.</p> | ||||
| 		<p> | ||||
| 			<br> | ||||
| 			<small>Copyright <20> 2002 by Peter Dimov. Distributed under the Boost Software License, Version  | ||||
| 				1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or  | ||||
| 				copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> | ||||
| 	</body> | ||||
| </html> | ||||
							
								
								
									
										40
									
								
								current_function_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								current_function_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #pragma warning(disable: 4786)  // identifier truncated in debug info | ||||
| #pragma warning(disable: 4710)  // function not inlined | ||||
| #pragma warning(disable: 4711)  // function selected for automatic inline expansion | ||||
| #pragma warning(disable: 4514)  // unreferenced inline removed | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  current_function_test.cpp - a test for boost/current_function.hpp | ||||
| // | ||||
| //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
|  | ||||
| #include <boost/current_function.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <cstdio> | ||||
|  | ||||
| void message(char const * file, long line, char const * func, char const * msg) | ||||
| { | ||||
| #if !defined(BOOST_NO_STDC_NAMESPACE) | ||||
|     using std::printf; | ||||
| #endif | ||||
|  | ||||
|     printf("%s(%ld): %s in function '%s'\n", file, line, msg, func); | ||||
| } | ||||
|  | ||||
| #define MESSAGE(msg) message(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, msg) | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     MESSAGE("assertion failed"); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										4
									
								
								doc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								doc/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +0,0 @@ | ||||
| html | ||||
| xml | ||||
| temp | ||||
| out.txt | ||||
| @@ -1,81 +0,0 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2012 Marshall Clow | ||||
|  / Copyright (c) 2021, Alan Freitas | ||||
|  / 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) | ||||
|  /] | ||||
|  | ||||
| [/===============] | ||||
| [#sec:BOOST_BINARY] | ||||
| [section Binary Integer Literals] | ||||
| [/===============] | ||||
|  | ||||
| [section Introduction] | ||||
|  | ||||
| The macro `BOOST_BINARY` is used for the representation of binary | ||||
| literals. It takes as an argument a binary number arranged as an | ||||
| arbitrary amount of 1s and 0s in groupings of length 1 to 8, with | ||||
| groups separated by spaces. The macro serves as a replacement for | ||||
| [@https://en.cppreference.com/w/cpp/language/integer_literal binary integer literals], | ||||
| adopted in C++14. | ||||
|  | ||||
| The type of the literal yielded is determined by the same rules as | ||||
| those of [@https://en.cppreference.com/w/cpp/language/integer_literal hex and octal literals]. | ||||
| By implementation, this macro expands directly to an octal literal during preprocessing, so | ||||
| there is no overhead at runtime and the result is usable in any place that an octal literal | ||||
| would be. | ||||
|  | ||||
| In order to directly support binary literals with suffixes, | ||||
| additional macros of the form `BOOST_BINARY_XXX` are also | ||||
| provided, where `XXX` is a standard integer suffix in all capital | ||||
| letters. | ||||
|  | ||||
| In addition, LL and ULL suffixes may be used for representing | ||||
| `long long` and `unsigned long long` types in compilers which provide | ||||
| them as an extension. | ||||
|  | ||||
| The `BOOST_BINARY` family of macros resides in the header | ||||
| [@../../../../boost/utility/binary.hpp <boost/utility/binary.hpp>]. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [section Example] | ||||
|  | ||||
| ``` | ||||
| void foo( int ); | ||||
|  | ||||
| void foo( unsigned long ); | ||||
|  | ||||
| void bar() | ||||
| { | ||||
|   int value1 = BOOST_BINARY( 100 111000 01 1 110 ); | ||||
|  | ||||
|   unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned long | ||||
|  | ||||
|   long long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported | ||||
|  | ||||
|   __assert__(    BOOST_BINARY( 10010 ) | ||||
|           &  BOOST_BINARY( 11000 ) | ||||
|           == BOOST_BINARY( 10000 ) | ||||
|         ); | ||||
|  | ||||
|   foo( BOOST_BINARY( 1010 ) ); // calls the first foo | ||||
|  | ||||
|   foo( BOOST_BINARY_LU( 1010 ) ); // calls the second foo | ||||
| } | ||||
| ``` | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [xinclude tmp/boost_binary_reference.xml] | ||||
| [/===============] | ||||
|  | ||||
|  | ||||
| [section Acknowledgments] | ||||
|  | ||||
| Contributed by Matt Calabrese. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [endsect] | ||||
							
								
								
									
										483
									
								
								doc/Jamfile.v2
									
									
									
									
									
								
							
							
						
						
									
										483
									
								
								doc/Jamfile.v2
									
									
									
									
									
								
							| @@ -1,413 +1,100 @@ | ||||
|  | ||||
| # Copyright John Maddock 2005. Use, modification, and distribution are | ||||
| # 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) | ||||
|  | ||||
| import project ; | ||||
| import doxygen ; | ||||
| import quickbook ; | ||||
| project : requirements | ||||
|         # Path for links to Boost: | ||||
|         <xsl:param>boost.root=../../../.. | ||||
|  | ||||
| project boost/libs/utility/doc ; | ||||
|         # Some general style settings: | ||||
|         <xsl:param>table.footnote.number.format=1 | ||||
|         <xsl:param>footnote.number.format=1 | ||||
|  | ||||
|         # HTML options first: | ||||
|         # Use graphics not text for navigation: | ||||
|         <xsl:param>navig.graphics=1 | ||||
|        # PDF Options: | ||||
|         # TOC Generation: this is needed for FOP-0.9 and later: | ||||
|         <xsl:param>fop1.extensions=0 | ||||
|         <xsl:param>xep.extensions=1 | ||||
|         # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9! | ||||
|         <xsl:param>fop.extensions=0 | ||||
|         # No indent on body text: | ||||
|         <xsl:param>body.start.indent=0pt | ||||
|         # Margin size: | ||||
|         <xsl:param>page.margin.inner=0.5in | ||||
|         # Margin size: | ||||
|         <xsl:param>page.margin.outer=0.5in | ||||
|         # Paper type = A4 | ||||
|         <xsl:param>paper.type=A4 | ||||
|         # Yes, we want graphics for admonishments: | ||||
|         <xsl:param>admon.graphics=1 | ||||
|         # Set this one for PDF generation *only*: | ||||
|         # default pnd graphics are awful in PDF form, | ||||
|         # better use SVG's instead: | ||||
|         <format>pdf:<xsl:param>admon.graphics.extension=".svg" | ||||
|         <format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/ | ||||
|         <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/utility/doc/html | ||||
| ; | ||||
|  | ||||
| using quickbook ; | ||||
|  | ||||
| path-constant INCLUDES : ../../.. ; | ||||
| path-constant boost-images : ../../../doc/src/images ; | ||||
|  | ||||
| # Generate XML doxygen reference for base_from_member component in base_from_member_reference.xml | ||||
| doxygen base_from_member_reference | ||||
|   : | ||||
|     $(INCLUDES)/boost/utility/base_from_member.hpp | ||||
|   : | ||||
|     <location>tmp | ||||
|     <doxygen:param>ENABLE_PREPROCESSING=YES | ||||
|     <doxygen:param>EXPAND_ONLY_PREDEF=YES | ||||
|     <doxygen:param>EXTRACT_ALL=NO | ||||
|     <doxygen:param>EXTRACT_PRIVATE=NO | ||||
|     <doxygen:param>HIDE_UNDOC_MEMBERS=YES | ||||
|     <doxygen:param>MACRO_EXPANSION=YES | ||||
|     <doxygen:param>"PREDEFINED= \\ | ||||
|                     BOOST_UTILITY_DOCS \\ | ||||
|                     BOOST_SYMBOL_VISIBLE= \\ | ||||
|                     BOOST_FORCEINLINE=inline \\ | ||||
|                     BOOST_GPU_ENABLED= \\ | ||||
|                     BOOST_STATIC_ASSERT(x)= \\ | ||||
|                     BOOST_STATIC_ASSERT_MSG(x,y)= \\ | ||||
|                     BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\ | ||||
|                     BOOST_RV_REF(x)=\"x&&\" \\ | ||||
|                     BOOST_NESTED_TEMPLATE=template \\ | ||||
|                     BOOST_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CXX14_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_OPERATORS_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CONSTEXPR_OR_CONST=constexpr \\ | ||||
|                     BOOST_NOEXCEPT=noexcept \\ | ||||
|                     BOOST_NOEXCEPT_IF(x)=noexcept(x) \\ | ||||
|                     BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\ | ||||
|                     BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\ | ||||
|                     BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\ | ||||
|                     BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\ | ||||
|                     BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\ | ||||
|                     BOOST_REF_CONST=const" | ||||
|     <doxygen:param>"EXCLUDE_SYMBOLS= \\ | ||||
|                     detail \\ | ||||
|                     F \\ | ||||
|                     result_of_has_result_type_impl \\ | ||||
|                     conditional \\ | ||||
|                     boost::operators_impl" | ||||
|     <xsl:param>"boost.doxygen.reftitle=Reference" | ||||
|     <xsl:param>"boost.doxygen.refid=base_from_member.reference" | ||||
|   ; | ||||
|  | ||||
| # Generate XML doxygen reference for boost_binary component in boost_binary_reference.xml | ||||
| doxygen boost_binary_reference | ||||
|   : | ||||
|     $(INCLUDES)/boost/utility/binary.hpp | ||||
|   : | ||||
|     <location>tmp | ||||
|     <doxygen:param>ENABLE_PREPROCESSING=YES | ||||
|     <doxygen:param>EXPAND_ONLY_PREDEF=YES | ||||
|     <doxygen:param>EXTRACT_ALL=NO | ||||
|     <doxygen:param>EXTRACT_PRIVATE=NO | ||||
|     <doxygen:param>HIDE_UNDOC_MEMBERS=YES | ||||
|     <doxygen:param>MACRO_EXPANSION=YES | ||||
|     <doxygen:param>"PREDEFINED= \\ | ||||
|                     BOOST_UTILITY_DOCS \\ | ||||
|                     BOOST_SYMBOL_VISIBLE= \\ | ||||
|                     BOOST_FORCEINLINE=inline \\ | ||||
|                     BOOST_GPU_ENABLED= \\ | ||||
|                     BOOST_STATIC_ASSERT(x)= \\ | ||||
|                     BOOST_STATIC_ASSERT_MSG(x,y)= \\ | ||||
|                     BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\ | ||||
|                     BOOST_RV_REF(x)=\"x&&\" \\ | ||||
|                     BOOST_NESTED_TEMPLATE=template \\ | ||||
|                     BOOST_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CXX14_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_OPERATORS_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CONSTEXPR_OR_CONST=constexpr \\ | ||||
|                     BOOST_NOEXCEPT=noexcept \\ | ||||
|                     BOOST_NOEXCEPT_IF(x)=noexcept(x) \\ | ||||
|                     BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\ | ||||
|                     BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\ | ||||
|                     BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\ | ||||
|                     BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\ | ||||
|                     BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\ | ||||
|                     BOOST_REF_CONST=const" | ||||
|     <doxygen:param>"EXCLUDE_SYMBOLS= \\ | ||||
|                     detail \\ | ||||
|                     F \\ | ||||
|                     result_of_has_result_type_impl \\ | ||||
|                     conditional \\ | ||||
|                     boost::operators_impl" | ||||
|     <xsl:param>"boost.doxygen.reftitle=Reference" | ||||
|     <xsl:param>"boost.doxygen.refid=boost_binary.reference" | ||||
|   ; | ||||
|  | ||||
| # Generate XML doxygen reference for call_traits component in call_traits_reference.xml | ||||
| doxygen call_traits_reference | ||||
|   : | ||||
|     $(INCLUDES)/boost/call_traits.hpp | ||||
|     $(INCLUDES)/boost/detail/call_traits.hpp | ||||
|   : | ||||
|     <location>tmp | ||||
|     <doxygen:param>ENABLE_PREPROCESSING=YES | ||||
|     <doxygen:param>EXPAND_ONLY_PREDEF=YES | ||||
|     <doxygen:param>EXTRACT_ALL=NO | ||||
|     <doxygen:param>EXTRACT_PRIVATE=NO | ||||
|     <doxygen:param>HIDE_UNDOC_MEMBERS=YES | ||||
|     <doxygen:param>MACRO_EXPANSION=YES | ||||
|     <doxygen:param>"PREDEFINED= \\ | ||||
|                     BOOST_UTILITY_DOCS \\ | ||||
|                     BOOST_SYMBOL_VISIBLE= \\ | ||||
|                     BOOST_FORCEINLINE=inline \\ | ||||
|                     BOOST_GPU_ENABLED= \\ | ||||
|                     BOOST_STATIC_ASSERT(x)= \\ | ||||
|                     BOOST_STATIC_ASSERT_MSG(x,y)= \\ | ||||
|                     BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\ | ||||
|                     BOOST_RV_REF(x)=\"x&&\" \\ | ||||
|                     BOOST_NESTED_TEMPLATE=template \\ | ||||
|                     BOOST_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CXX14_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_OPERATORS_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CONSTEXPR_OR_CONST=constexpr \\ | ||||
|                     BOOST_NOEXCEPT=noexcept \\ | ||||
|                     BOOST_NOEXCEPT_IF(x)=noexcept(x) \\ | ||||
|                     BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\ | ||||
|                     BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\ | ||||
|                     BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\ | ||||
|                     BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\ | ||||
|                     BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\ | ||||
|                     BOOST_REF_CONST=const" | ||||
|     <doxygen:param>"EXCLUDE_SYMBOLS= \\ | ||||
|                     detail \\ | ||||
|                     F \\ | ||||
|                     result_of_has_result_type_impl \\ | ||||
|                     conditional \\ | ||||
|                     boost::operators_impl" | ||||
|     <xsl:param>"boost.doxygen.reftitle=Reference" | ||||
|     <xsl:param>"boost.doxygen.refid=call_traits.reference" | ||||
|   ; | ||||
|  | ||||
| # Generate XML doxygen reference for compressed_pair component in compressed_pair_reference.xml | ||||
| doxygen compressed_pair_reference | ||||
|   : | ||||
|     $(INCLUDES)/boost/compressed_pair.hpp | ||||
|     $(INCLUDES)/boost/detail/compressed_pair.hpp | ||||
|   : | ||||
|     <location>tmp | ||||
|     <doxygen:param>ENABLE_PREPROCESSING=YES | ||||
|     <doxygen:param>EXPAND_ONLY_PREDEF=YES | ||||
|     <doxygen:param>EXTRACT_ALL=NO | ||||
|     <doxygen:param>EXTRACT_PRIVATE=NO | ||||
|     <doxygen:param>HIDE_UNDOC_MEMBERS=YES | ||||
|     <doxygen:param>MACRO_EXPANSION=YES | ||||
|     <doxygen:param>"PREDEFINED= \\ | ||||
|                     BOOST_UTILITY_DOCS \\ | ||||
|                     BOOST_SYMBOL_VISIBLE= \\ | ||||
|                     BOOST_FORCEINLINE=inline \\ | ||||
|                     BOOST_GPU_ENABLED= \\ | ||||
|                     BOOST_STATIC_ASSERT(x)= \\ | ||||
|                     BOOST_STATIC_ASSERT_MSG(x,y)= \\ | ||||
|                     BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\ | ||||
|                     BOOST_RV_REF(x)=\"x&&\" \\ | ||||
|                     BOOST_NESTED_TEMPLATE=template \\ | ||||
|                     BOOST_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CXX14_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_OPERATORS_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CONSTEXPR_OR_CONST=constexpr \\ | ||||
|                     BOOST_NOEXCEPT=noexcept \\ | ||||
|                     BOOST_NOEXCEPT_IF(x)=noexcept(x) \\ | ||||
|                     BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\ | ||||
|                     BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\ | ||||
|                     BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\ | ||||
|                     BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\ | ||||
|                     BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\ | ||||
|                     BOOST_REF_CONST=const" | ||||
|     <doxygen:param>"EXCLUDE_SYMBOLS= \\ | ||||
|                     detail \\ | ||||
|                     F \\ | ||||
|                     result_of_has_result_type_impl \\ | ||||
|                     conditional \\ | ||||
|                     boost::operators_impl" | ||||
|     <xsl:param>"boost.doxygen.reftitle=Reference" | ||||
|     <xsl:param>"boost.doxygen.refid=compressed_pair.reference" | ||||
|   ; | ||||
|  | ||||
| # Generate XML doxygen reference for in_place_factory component in in_place_factory_reference.xml | ||||
| doxygen in_place_factory_reference | ||||
|   : | ||||
|     $(INCLUDES)/boost/utility/in_place_factory.hpp | ||||
|     $(INCLUDES)/boost/utility/typed_in_place_factory.hpp | ||||
|   : | ||||
|     <location>tmp | ||||
|     <doxygen:param>ENABLE_PREPROCESSING=YES | ||||
|     <doxygen:param>EXPAND_ONLY_PREDEF=YES | ||||
|     <doxygen:param>EXTRACT_ALL=NO | ||||
|     <doxygen:param>EXTRACT_PRIVATE=NO | ||||
|     <doxygen:param>HIDE_UNDOC_MEMBERS=YES | ||||
|     <doxygen:param>MACRO_EXPANSION=YES | ||||
|     <doxygen:param>"PREDEFINED= \\ | ||||
|                     BOOST_UTILITY_DOCS \\ | ||||
|                     BOOST_SYMBOL_VISIBLE= \\ | ||||
|                     BOOST_FORCEINLINE=inline \\ | ||||
|                     BOOST_GPU_ENABLED= \\ | ||||
|                     BOOST_STATIC_ASSERT(x)= \\ | ||||
|                     BOOST_STATIC_ASSERT_MSG(x,y)= \\ | ||||
|                     BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\ | ||||
|                     BOOST_RV_REF(x)=\"x&&\" \\ | ||||
|                     BOOST_NESTED_TEMPLATE=template \\ | ||||
|                     BOOST_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CXX14_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_OPERATORS_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CONSTEXPR_OR_CONST=constexpr \\ | ||||
|                     BOOST_NOEXCEPT=noexcept \\ | ||||
|                     BOOST_NOEXCEPT_IF(x)=noexcept(x) \\ | ||||
|                     BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\ | ||||
|                     BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\ | ||||
|                     BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\ | ||||
|                     BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\ | ||||
|                     BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\ | ||||
|                     BOOST_REF_CONST=const" | ||||
|     <doxygen:param>"EXCLUDE_SYMBOLS= \\ | ||||
|                     detail \\ | ||||
|                     F \\ | ||||
|                     result_of_has_result_type_impl \\ | ||||
|                     conditional \\ | ||||
|                     boost::operators_impl" | ||||
|     <xsl:param>"boost.doxygen.reftitle=Reference" | ||||
|     <xsl:param>"boost.doxygen.refid=in_place_factory.reference" | ||||
|   ; | ||||
|  | ||||
| # Generate XML doxygen reference for operators component in operators_reference.xml | ||||
| # we skip operators_reference because operators.hpp is not adapted for doxygen | ||||
|  | ||||
| # Generate XML doxygen reference for result_of component in result_of_reference.xml | ||||
| doxygen result_of_reference | ||||
|   : | ||||
|     $(INCLUDES)/boost/utility/result_of.hpp | ||||
|   : | ||||
|     <location>tmp | ||||
|     <doxygen:param>ENABLE_PREPROCESSING=YES | ||||
|     <doxygen:param>EXPAND_ONLY_PREDEF=YES | ||||
|     <doxygen:param>EXTRACT_ALL=NO | ||||
|     <doxygen:param>EXTRACT_PRIVATE=NO | ||||
|     <doxygen:param>HIDE_UNDOC_MEMBERS=YES | ||||
|     <doxygen:param>MACRO_EXPANSION=YES | ||||
|     <doxygen:param>"PREDEFINED= \\ | ||||
|                     BOOST_UTILITY_DOCS \\ | ||||
|                     BOOST_SYMBOL_VISIBLE= \\ | ||||
|                     BOOST_FORCEINLINE=inline \\ | ||||
|                     BOOST_GPU_ENABLED= \\ | ||||
|                     BOOST_STATIC_ASSERT(x)= \\ | ||||
|                     BOOST_STATIC_ASSERT_MSG(x,y)= \\ | ||||
|                     BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\ | ||||
|                     BOOST_RV_REF(x)=\"x&&\" \\ | ||||
|                     BOOST_NESTED_TEMPLATE=template \\ | ||||
|                     BOOST_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CXX14_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_OPERATORS_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CONSTEXPR_OR_CONST=constexpr \\ | ||||
|                     BOOST_NOEXCEPT=noexcept \\ | ||||
|                     BOOST_NOEXCEPT_IF(x)=noexcept(x) \\ | ||||
|                     BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\ | ||||
|                     BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\ | ||||
|                     BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\ | ||||
|                     BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\ | ||||
|                     BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\ | ||||
|                     BOOST_REF_CONST=const" | ||||
|     <doxygen:param>"EXCLUDE_SYMBOLS= \\ | ||||
|                     detail \\ | ||||
|                     F \\ | ||||
|                     result_of_has_result_type_impl \\ | ||||
|                     conditional \\ | ||||
|                     boost::operators_impl" | ||||
|     <xsl:param>"boost.doxygen.reftitle=Reference" | ||||
|     <xsl:param>"boost.doxygen.refid=result_of.reference" | ||||
|   ; | ||||
|  | ||||
| # Generate XML doxygen reference for string_view component in string_view_reference.xml | ||||
| doxygen string_view_reference | ||||
|   : | ||||
|     $(INCLUDES)/boost/utility/string_view.hpp | ||||
|   : | ||||
|     <location>tmp | ||||
|     <doxygen:param>ENABLE_PREPROCESSING=YES | ||||
|     <doxygen:param>EXPAND_ONLY_PREDEF=YES | ||||
|     <doxygen:param>EXTRACT_ALL=NO | ||||
|     <doxygen:param>EXTRACT_PRIVATE=NO | ||||
|     <doxygen:param>HIDE_UNDOC_MEMBERS=YES | ||||
|     <doxygen:param>MACRO_EXPANSION=YES | ||||
|     <doxygen:param>"PREDEFINED= \\ | ||||
|                     BOOST_UTILITY_DOCS \\ | ||||
|                     BOOST_SYMBOL_VISIBLE= \\ | ||||
|                     BOOST_FORCEINLINE=inline \\ | ||||
|                     BOOST_GPU_ENABLED= \\ | ||||
|                     BOOST_STATIC_ASSERT(x)= \\ | ||||
|                     BOOST_STATIC_ASSERT_MSG(x,y)= \\ | ||||
|                     BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\ | ||||
|                     BOOST_RV_REF(x)=\"x&&\" \\ | ||||
|                     BOOST_NESTED_TEMPLATE=template \\ | ||||
|                     BOOST_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CXX14_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_OPERATORS_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CONSTEXPR_OR_CONST=constexpr \\ | ||||
|                     BOOST_NOEXCEPT=noexcept \\ | ||||
|                     BOOST_NOEXCEPT_IF(x)=noexcept(x) \\ | ||||
|                     BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\ | ||||
|                     BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\ | ||||
|                     BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\ | ||||
|                     BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\ | ||||
|                     BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\ | ||||
|                     BOOST_REF_CONST=const" | ||||
|     <doxygen:param>"EXCLUDE_SYMBOLS= \\ | ||||
|                     detail \\ | ||||
|                     F \\ | ||||
|                     result_of_has_result_type_impl \\ | ||||
|                     conditional \\ | ||||
|                     boost::operators_impl" | ||||
|     <xsl:param>"boost.doxygen.reftitle=Reference" | ||||
|     <xsl:param>"boost.doxygen.refid=string_view.reference" | ||||
|   ; | ||||
|  | ||||
| # Generate XML doxygen reference for value_init component in value_init_reference.xml | ||||
| doxygen value_init_reference | ||||
|   : | ||||
|     $(INCLUDES)/boost/utility/value_init.hpp | ||||
|   : | ||||
|     <location>tmp | ||||
|     <doxygen:param>ENABLE_PREPROCESSING=YES | ||||
|     <doxygen:param>EXPAND_ONLY_PREDEF=YES | ||||
|     <doxygen:param>EXTRACT_ALL=NO | ||||
|     <doxygen:param>EXTRACT_PRIVATE=NO | ||||
|     <doxygen:param>HIDE_UNDOC_MEMBERS=YES | ||||
|     <doxygen:param>MACRO_EXPANSION=YES | ||||
|     <doxygen:param>"PREDEFINED= \\ | ||||
|                     BOOST_UTILITY_DOCS \\ | ||||
|                     BOOST_SYMBOL_VISIBLE= \\ | ||||
|                     BOOST_FORCEINLINE=inline \\ | ||||
|                     BOOST_GPU_ENABLED= \\ | ||||
|                     BOOST_STATIC_ASSERT(x)= \\ | ||||
|                     BOOST_STATIC_ASSERT_MSG(x,y)= \\ | ||||
|                     BOOST_STATIC_CONSTANT(x,y)=\"static constexpr x y\" \\ | ||||
|                     BOOST_RV_REF(x)=\"x&&\" \\ | ||||
|                     BOOST_NESTED_TEMPLATE=template \\ | ||||
|                     BOOST_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CXX14_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_OPERATORS_CONSTEXPR=constexpr \\ | ||||
|                     BOOST_CONSTEXPR_OR_CONST=constexpr \\ | ||||
|                     BOOST_NOEXCEPT=noexcept \\ | ||||
|                     BOOST_NOEXCEPT_IF(x)=noexcept(x) \\ | ||||
|                     BOOST_NOEXCEPT_OR_NOTHROW=noexcept \\ | ||||
|                     BOOST_COPY_ASSIGN_REF(x)=\"x const&\" \\ | ||||
|                     BOOST_DEFAULTED_FUNCTION(x,y)=\"x = default;\" \\ | ||||
|                     BOOST_DELETED_FUNCTION(x)=\"x = delete;\" \\ | ||||
|                     BOOST_EXPLICIT_OPERATOR_BOOL()=\"explicit operator bool() const;\" \\ | ||||
|                     BOOST_REF_CONST=const" | ||||
|     <doxygen:param>"EXCLUDE_SYMBOLS= \\ | ||||
|                     detail \\ | ||||
|                     F \\ | ||||
|                     result_of_has_result_type_impl \\ | ||||
|                     conditional \\ | ||||
|                     boost::operators_impl" | ||||
|     <xsl:param>"boost.doxygen.reftitle=Reference" | ||||
|     <xsl:param>"boost.doxygen.refid=value_init.reference" | ||||
|   ; | ||||
|  | ||||
| # Generate main.xml boostbook documentation from main.qbk quickbook documentation | ||||
| xml main : main.qbk ; | ||||
|  | ||||
| # Generate ./html documentation from main.xml boostbook documentation | ||||
| # Each doxygen reference in quickbook files with [xinclude tmp/<component>_reference.xml] becomes: | ||||
| # <xi:include href="../../../../libs/utility/doc/tmp/<component>_reference.xml"/> | ||||
| # in boostbook. | ||||
| # All of these <xi:include> commands give the reference the id "utility.reference" | ||||
| boostbook standalone_main | ||||
| xml declval : declval.qbk ; | ||||
| boostbook standalone_declval | ||||
|     : | ||||
|         main | ||||
|         declval | ||||
|     : | ||||
|         <dependency>base_from_member_reference | ||||
|         <dependency>boost_binary_reference | ||||
|         <dependency>call_traits_reference | ||||
|         <dependency>compressed_pair_reference | ||||
|         <dependency>in_place_factory_reference | ||||
|         <dependency>result_of_reference | ||||
|         <dependency>string_view_reference | ||||
|         <dependency>value_init_reference | ||||
|         # File name of HTML output: | ||||
|         # <xsl:param>root.filename=main | ||||
|         <xsl:param>boost.root=../../../.. | ||||
|         <format>pdf:<xsl:param>"boost.url.prefix=http://www.boost.org/doc/libs/release/libs/utility/doc/html" | ||||
|         # How far down we chunk nested sections: no more than two so utility component pages include their reference | ||||
|         <xsl:param>chunk.section.depth=2 # 8 | ||||
|         <xsl:param>root.filename=declval | ||||
|         # How far down we chunk nested sections, basically all of them: | ||||
|         <xsl:param>chunk.section.depth=0 | ||||
|         # Don't put the first section on the same page as the TOC: | ||||
|         <xsl:param>chunk.first.sections=1 # 1 | ||||
|         # How far down sections get TOC: 2 so we show each Utility component in main page but no more than that | ||||
|         <xsl:param>toc.section.depth=2 # 2 | ||||
|         # Max depth in each TOC: 2 so we show each Utility component in main page but no more than that | ||||
|         <xsl:param>toc.max.depth=2 # 2 | ||||
|         # How far down we go with TOC's in main page: 2 so each Utility component page has 1 level TOC | ||||
|         <xsl:param>generate.section.toc.level=2 # 2 | ||||
|         <xsl:param>chunk.first.sections=0 | ||||
|         # How far down sections get TOC's | ||||
|         <xsl:param>toc.section.depth=1 | ||||
|         # Max depth in each TOC: | ||||
|         <xsl:param>toc.max.depth=1 | ||||
|         # How far down we go with TOC's | ||||
|         <xsl:param>generate.section.toc.level=1 | ||||
|      ; | ||||
|  | ||||
| ############################################################################### | ||||
| alias boostdoc ; | ||||
| explicit boostdoc ; | ||||
| xml string_ref : string_ref.qbk ; | ||||
| boostbook standalone_string_ref | ||||
|     : | ||||
|         string_ref | ||||
|     : | ||||
|         # File name of HTML output: | ||||
|         <xsl:param>root.filename=string_ref | ||||
|         # How far down we chunk nested sections, basically all of them: | ||||
|         <xsl:param>chunk.section.depth=0 | ||||
|         # Don't put the first section on the same page as the TOC: | ||||
|         <xsl:param>chunk.first.sections=0 | ||||
|         # How far down sections get TOC's | ||||
|         <xsl:param>toc.section.depth=1 | ||||
|         # Max depth in each TOC: | ||||
|         <xsl:param>toc.max.depth=1 | ||||
|         # How far down we go with TOC's | ||||
|         <xsl:param>generate.section.toc.level=1 | ||||
|      ; | ||||
|  | ||||
| alias boostrelease : standalone_main ; | ||||
| explicit boostrelease ; | ||||
| xml explicit_operator_bool : explicit_operator_bool.qbk ; | ||||
| boostbook standalone_explicit_operator_bool | ||||
|     : | ||||
|         explicit_operator_bool | ||||
|     : | ||||
|         # File name of HTML output: | ||||
|         <xsl:param>root.filename=explicit_operator_bool | ||||
|         # How far down we chunk nested sections, basically all of them: | ||||
|         <xsl:param>chunk.section.depth=0 | ||||
|         # Don't put the first section on the same page as the TOC: | ||||
|         <xsl:param>chunk.first.sections=0 | ||||
|         # How far down sections get TOC's | ||||
|         <xsl:param>toc.section.depth=1 | ||||
|         # Max depth in each TOC: | ||||
|         <xsl:param>toc.max.depth=1 | ||||
|         # How far down we go with TOC's | ||||
|         <xsl:param>generate.section.toc.level=1 | ||||
|      ; | ||||
|   | ||||
| @@ -1,376 +0,0 @@ | ||||
| [/ | ||||
|   Copyright 2001, 2003, 2004, 2012 Daryle Walker. | ||||
|   Copyright (c) 2021, Alan Freitas | ||||
|  | ||||
|   Distributed under the Boost Software License, Version 1.0. | ||||
|  | ||||
|   See accompanying file LICENSE_1_0.txt | ||||
|   or copy at http://boost.org/LICENSE_1_0.txt | ||||
| ] | ||||
|  | ||||
| [section:base_from_member Base from Member] | ||||
| [block'''<?dbhtml stop-chunking?>'''] | ||||
|  | ||||
| [section Introduction] | ||||
|  | ||||
| The class templates __base_from_member__ support the base-from-member idiom. | ||||
| When developing a class, sometimes a base class needs to be initialized | ||||
| with a member of the current class. As a na\u00EFve example: | ||||
|  | ||||
| ``` | ||||
| #include <streambuf>  /* for std::streambuf */ | ||||
| #include <ostream>    /* for std::ostream */ | ||||
|  | ||||
| class fdoutbuf | ||||
|   : public __std_streambuf__ | ||||
| { | ||||
| public: | ||||
|     explicit fdoutbuf( int fd ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class fdostream | ||||
|   : public __std_ostream__ | ||||
| { | ||||
| protected: | ||||
|     fdoutbuf buf; | ||||
| public: | ||||
|     explicit fdostream( int fd ) | ||||
|       : buf( fd ), __std_ostream__( &buf ) {} | ||||
|     //... | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| This is undefined because C++'s initialization order mandates that the base | ||||
| class is initialized before the member it uses. [@http://www.moocat.org R. | ||||
| Samuel Klatchko] developed a way around this by using the initialization | ||||
| order in his favor. Base classes are initialized in order of declaration, so | ||||
| moving the desired member to another base class, that is initialized before | ||||
| the desired base class, can ensure proper initialization. | ||||
|  | ||||
| A custom base class can be made for this idiom: | ||||
|  | ||||
|     #include <streambuf>  /* for std::streambuf */ | ||||
|     #include <ostream>    /* for std::ostream */ | ||||
|  | ||||
|     class fdoutbuf | ||||
|       : public __std_streambuf__ | ||||
|     { | ||||
|     public: | ||||
|         explicit fdoutbuf( int fd ); | ||||
|         //... | ||||
|     }; | ||||
|  | ||||
|     struct fdostream_pbase | ||||
|     { | ||||
|         fdoutbuf sbuffer; | ||||
|  | ||||
|         explicit fdostream_pbase( int fd ) | ||||
|           : sbuffer( fd ) {} | ||||
|     }; | ||||
|  | ||||
|     class fdostream | ||||
|       : private fdostream_pbase | ||||
|       , public __std_ostream__ | ||||
|     { | ||||
|         typedef fdostream_pbase  pbase_type; | ||||
|         typedef __std_ostream__     base_type; | ||||
|  | ||||
|     public: | ||||
|         explicit fdostream( int fd ) | ||||
|           : pbase_type( fd ), base_type( &sbuffer ) {} | ||||
|         //... | ||||
|     }; | ||||
|  | ||||
| Other projects can use similar custom base classes. The technique is basic | ||||
| enough to make a template, with a sample template class in this library. | ||||
| The main template parameter is the type of the enclosed member. The | ||||
| template class has several (explicit) constructor member templates, which | ||||
| implicitly type the constructor arguments and pass them to the member. The | ||||
| template class uses implicit copy construction and assignment, cancelling | ||||
| them if the enclosed member is non-copyable. | ||||
|  | ||||
| Manually coding a base class may be better if the construction and/or | ||||
| copying needs are too complex for the supplied template class, or if the | ||||
| compiler is not advanced enough to use it. | ||||
|  | ||||
| Since base classes are unnamed, a class cannot have multiple (direct) base | ||||
| classes of the same type. The supplied template class has an extra template | ||||
| parameter, an integer, that exists solely to provide type differentiation. | ||||
| This parameter has a default value so a single use of a particular member | ||||
| type does not need to concern itself with the integer. | ||||
|  | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [section Synopsis] | ||||
|  | ||||
|     #include <type_traits>  /* exposition only */ | ||||
|  | ||||
|     #ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY | ||||
|     #define BOOST_BASE_FROM_MEMBER_MAX_ARITY  10 | ||||
|     #endif | ||||
|  | ||||
|     template < typename MemberType, int UniqueID = 0 > | ||||
|     class __base_from_member__ | ||||
|     { | ||||
|     protected: | ||||
|         MemberType  member; | ||||
|  | ||||
|     #if ``['C++11 is in use]`` | ||||
|         template< typename ...T > | ||||
|         explicit constexpr __base_from_member__( T&& ...x ) | ||||
|          noexcept( __std_is_nothrow_constructible__<MemberType, T...>::value ); | ||||
|     #else | ||||
|         __base_from_member__(); | ||||
|  | ||||
|         template< typename T1 > | ||||
|         explicit  __base_from_member__( T1 x1 ); | ||||
|  | ||||
|         template< typename T1, typename T2 > | ||||
|         __base_from_member__( T1 x1, T2 x2 ); | ||||
|  | ||||
|         //... | ||||
|  | ||||
|         template< typename T1, typename T2, typename T3, typename T4, | ||||
|          typename T5, typename T6, typename T7, typename T8, typename T9, | ||||
|          typename T10 > | ||||
|         __base_from_member__( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, | ||||
|          T8 x8, T9 x9, T10 x10 ); | ||||
|     #endif | ||||
|     }; | ||||
|  | ||||
|     template < typename MemberType, int UniqueID > | ||||
|     class __base_from_member__<MemberType&, UniqueID> | ||||
|     { | ||||
|     protected: | ||||
|         MemberType& member; | ||||
|  | ||||
|         explicit constexpr __base_from_member__( MemberType& x ) | ||||
|             noexcept; | ||||
|     }; | ||||
|  | ||||
| The class template has a first template parameter `MemberType` representing | ||||
| the type of the based-member. It has a last template parameter `UniqueID`, | ||||
| that is an `int`, to differentiate between multiple base classes that use | ||||
| the same based-member type. The last template parameter has a default value | ||||
| of zero if it is omitted. The class template has a protected data member | ||||
| called `member` that the derived class can use for later base classes or | ||||
| itself. | ||||
|  | ||||
| If the appropriate features of C++11 are present, there will be a single | ||||
| constructor template. It implements ['perfect forwarding] to the best | ||||
| constructor call of `member` if any. The constructor template is marked | ||||
| both `constexpr` and `explicit`. The former will be ignored if the | ||||
| corresponding inner constructor call of `member` does not have the marker. | ||||
| The latter binds the other way; always taking effect, even when the inner | ||||
| constructor call does not have the marker. The constructor template | ||||
| propagates the `noexcept` status of the inner constructor call. The | ||||
| constructor template has a trailing parameter with a default value that | ||||
| disables the template when its signature is too close to the signatures of | ||||
| the automatically-defined non-template copy- and/or move-constructors of | ||||
| __base_from_member__. | ||||
|  | ||||
| On earlier-standard compilers, there is a default constructor and several | ||||
| constructor member templates. These constructor templates can take as many | ||||
| arguments (currently up to ten) as possible and pass them to a constructor | ||||
| of the data member. | ||||
|  | ||||
| A specialization for member references offers a single constructor taking | ||||
| a `MemberType&`, which is the only way to initialize a reference. | ||||
|  | ||||
| Since C++ does not allow any way to explicitly state the template parameters | ||||
| of a templated constructor, make sure that the arguments are already close | ||||
| as possible to the actual type used in the data member's desired constructor. | ||||
| Explicit conversions may be necessary. | ||||
|  | ||||
| The `BOOST_BASE_FROM_MEMBER_MAX_ARITY` macro constant specifies the maximum | ||||
| argument length for the constructor templates. The constant may be overridden | ||||
| if more (or less) argument configurations are needed. The constant may be | ||||
| read for code that is expandable like the class template and needs to | ||||
| maintain the same maximum size. (Example code would be a class that uses | ||||
| this class template as a base class for a member with a flexible set of | ||||
| constructors.) This constant is ignored when C++11 features are present. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [section Basic Usage] | ||||
|  | ||||
| With the starting example, the `fdoutbuf` sub-object needs to be | ||||
| encapsulated in a base class that is inherited before `__std_ostream__`. | ||||
|  | ||||
| ``` | ||||
| #include <boost/utility/base_from_member.hpp> | ||||
|  | ||||
| #include <streambuf>  // for std::streambuf | ||||
| #include <ostream>    // for __std_ostream__ | ||||
|  | ||||
| class fdoutbuf | ||||
|   : public __std_streambuf__ | ||||
| { | ||||
| public: | ||||
|     explicit fdoutbuf( int fd ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class fdostream | ||||
|   : private __boost_base_from_member__<fdoutbuf> | ||||
|   , public __std_ostream__ | ||||
| { | ||||
|     // Helper typedef's | ||||
|     typedef __boost_base_from_member__<fdoutbuf>  pbase_type; | ||||
|     typedef __std_ostream__                        base_type; | ||||
|  | ||||
| public: | ||||
|     explicit fdostream( int fd ) | ||||
|       : pbase_type( fd ), base_type( &member ){} | ||||
|     //... | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| The base-from-member idiom is an implementation detail, so it should not | ||||
| be visible to the clients (or any derived classes) of `fdostream`. Due to | ||||
| the initialization order, the `fdoutbuf` sub-object will get initialized | ||||
| before the `__std_ostream__` sub-object does, making the former sub-object | ||||
| safe to use in the latter sub-object's construction. Since the `fdoutbuf` | ||||
| sub-object of the final type is the only sub-object with the name `member` | ||||
| that name can be used unqualified within the final class. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [section Multiple Sub-Objects] | ||||
|  | ||||
| The base-from-member class templates should commonly involve only one | ||||
| base-from-member sub-object, usually for attaching a stream-buffer to an | ||||
| I/O stream. The next example demonstrates how to use multiple | ||||
| base-from-member sub-objects and the resulting qualification issues. | ||||
|  | ||||
| ``` | ||||
| #include <boost/utility/base_from_member.hpp> | ||||
|  | ||||
| #include <cstddef>  /* for NULL */ | ||||
|  | ||||
| struct an_int | ||||
| { | ||||
|     int  y; | ||||
|  | ||||
|     an_int( float yf ); | ||||
| }; | ||||
|  | ||||
| class switcher | ||||
| { | ||||
| public: | ||||
|     switcher(); | ||||
|     switcher( double, int * ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class flow_regulator | ||||
| { | ||||
| public: | ||||
|     flow_regulator( switcher &, switcher & ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| template < unsigned Size > | ||||
| class fan | ||||
| { | ||||
| public: | ||||
|     explicit fan( switcher ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| class system | ||||
|   : private __boost_base_from_member__<an_int> | ||||
|   , private __boost_base_from_member__<switcher> | ||||
|   , private __boost_base_from_member__<switcher, 1> | ||||
|   , private __boost_base_from_member__<switcher, 2> | ||||
|   , protected flow_regulator | ||||
|   , public fan<6> | ||||
| { | ||||
|     // Helper typedef's | ||||
|     typedef __boost_base_from_member__<an_int>       pbase0_type; | ||||
|     typedef __boost_base_from_member__<switcher>     pbase1_type; | ||||
|     typedef __boost_base_from_member__<switcher, 1>  pbase2_type; | ||||
|     typedef __boost_base_from_member__<switcher, 2>  pbase3_type; | ||||
|  | ||||
|     typedef flow_regulator  base1_type; | ||||
|     typedef fan<6>          base2_type; | ||||
|  | ||||
| public: | ||||
|     system( double x ); | ||||
|     //... | ||||
| }; | ||||
|  | ||||
| system::system( double x ) | ||||
|   : pbase0_type( 0.2 ) | ||||
|   , pbase1_type() | ||||
|   , pbase2_type( -16, &this->pbase0_type::member.y ) | ||||
|   , pbase3_type( x, static_cast<int *>(NULL) ) | ||||
|   , base1_type( pbase3_type::member, pbase1_type::member ) | ||||
|   , base2_type( pbase2_type::member ) | ||||
| { | ||||
|     //... | ||||
| } | ||||
| ``` | ||||
|  | ||||
| The final class has multiple sub-objects with the name `member`, so any | ||||
| use of that name needs qualification by a name of the appropriate base | ||||
| type. Using `typedef`s ease mentioning the base types. | ||||
|  | ||||
| However, the fix introduces a new problem when a pointer is needed. Using the | ||||
| address operator with a sub-object qualified with its class's name results in a | ||||
| pointer-to-member (here, having a type of `an_int __boost_base_from_member__<an_int, 0>::*`) | ||||
| instead of a pointer to the member (having a type of `an_int*`). | ||||
| The new problem is fixed by qualifying the sub-object with `this->` and is needed | ||||
| just for pointers, and not for references or values. | ||||
|  | ||||
| There are some argument conversions in the initialization. The constructor | ||||
| argument for `pbase0_type` is converted from `double` to `float`. The first | ||||
| constructor argument for `pbase2_type` is converted from `int` to `double`. | ||||
|  | ||||
| The second constructor argument for `pbase3_type` is a special case of | ||||
| necessary conversion; all forms of the null-pointer literal in C++ (except | ||||
| `nullptr` from C++11) also look like compile-time integral expressions, so | ||||
| C++ always interprets such code as an integer when it has overloads that can | ||||
| take either an integer or a pointer. | ||||
|  | ||||
| The last conversion is necessary for the compiler to call a constructor form | ||||
| with the exact pointer type used in `switcher`'s constructor. (If C++11's | ||||
| __nullptr__ is used, it still needs a conversion if multiple pointer types can | ||||
| be accepted in a constructor call but `__std_nullptr_t__` cannot.) | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [xinclude tmp/base_from_member_reference.xml] | ||||
| [/===============] | ||||
|  | ||||
| [section Acknowledgments] | ||||
|  | ||||
| Author: Walker, Daryle | ||||
|  | ||||
| Copyright 2001, 2003, 2004, 2012 Daryle Walker | ||||
|  | ||||
| * [@http://www.boost.org/people/ed_brey.htm Ed Brey] suggested some interface | ||||
|   changes. | ||||
|  | ||||
| * [@http://www.moocat.org R. Samuel Klatchko] ([@mailto:rsk@moocat.org | ||||
|   rsk@moocat.org], [@mailto:rsk@brightmail.com rsk@brightmail.com]) invented | ||||
|   the idiom of how to use a class member for initializing a base class. | ||||
|  | ||||
| * [@http://www.boost.org/people/dietmar_kuehl.htm Dietmar Kuehl] popularized the | ||||
|   base-from-member idiom in his [@http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/ | ||||
|   IOStream example classes]. | ||||
|  | ||||
| * Jonathan Turkanis supplied an implementation of generating the constructor | ||||
|   templates that can be controlled and automated with macros. The | ||||
|   implementation uses the [@boost:/libs/preprocessor/index.html Preprocessor library]. | ||||
|  | ||||
| * [@http://www.boost.org/people/daryle_walker.html">Daryle Walker] started the | ||||
|   library. Contributed the test file [@../../../test/base_from_member_test.cpp | ||||
|   base_from_member_test.cpp]. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [endsect] | ||||
| @@ -1,443 +0,0 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2012 Marshall Clow | ||||
|  / Copyright (c) 2021, Alan Freitas | ||||
|  / | ||||
|  / 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 Call Traits] | ||||
| [/===============] | ||||
|  | ||||
| [section Introduction] | ||||
|  | ||||
| All of the contents of [@../../../../boost/call_traits.hpp `<boost/call_traits.hpp>`] are | ||||
| defined inside `namespace boost`. | ||||
|  | ||||
| The template class __call_traits_T__ encapsulates the | ||||
| "best" method to pass a parameter of some type `T` to or | ||||
| from a function, and consists of a collection of `typedef`s defined | ||||
| as in the table below. The purpose of __call_traits__ is to ensure | ||||
| that problems like [link sec:refs "references to references"] | ||||
| never occur, and that parameters are passed in the most efficient | ||||
| manner possible, as in the [link sec:examples examples]. In each | ||||
| case, if your existing practice is to use the type defined on the | ||||
| left, then replace it with the __call_traits__ defined type on the | ||||
| right. | ||||
|  | ||||
| Note that for compilers that do not support either partial | ||||
| specialization or member templates, no benefit will occur from | ||||
| using __call_traits__: the __call_traits__ defined types will always be | ||||
| the same as the existing practice in this case. In addition if | ||||
| only member templates and not partial template specialisation is | ||||
| support by the compiler (for example Visual C++ 6) then | ||||
| __call_traits__ cannot be used with array types, although it can still be | ||||
| used to solve the reference to reference problem. | ||||
|  | ||||
| [table __call_traits__ types | ||||
|     [[Existing practice] [__call_traits__ equivalent] [Description] [Notes]] | ||||
|     [ | ||||
|         [`T` | ||||
|  | ||||
|           (return by value) | ||||
|         ] | ||||
|         [ | ||||
|             __call_traits_T__`::value_type` | ||||
|         ] | ||||
|         [ | ||||
|             Defines a type that represents the "value" of type `T`. | ||||
|  | ||||
|             Use this for functions that return by value, or possibly for stored values of type `T`. | ||||
|         ] | ||||
|         [2] | ||||
|     ] | ||||
|     [ | ||||
|         [`T&` | ||||
|  | ||||
|           (return value) | ||||
|         ] | ||||
|         [ | ||||
|             __call_traits_T__`::reference` | ||||
|         ] | ||||
|         [ | ||||
|             Defines a type that represents a reference to type `T`. | ||||
|  | ||||
|             Use for functions that would normally return a `T&`. | ||||
|         ] | ||||
|         [1] | ||||
|     ] | ||||
|     [ | ||||
|         [`const T&` | ||||
|  | ||||
|           (return value) | ||||
|         ] | ||||
|         [ | ||||
|             __call_traits_T__`::const_reference` | ||||
|         ] | ||||
|         [ | ||||
|             Defines a type that represents a constant reference to type `T`. | ||||
|  | ||||
|             Use for functions that would normally return a `const T&`. | ||||
|         ] | ||||
|         [1] | ||||
|     ] | ||||
|     [ | ||||
|         [`const T&` | ||||
|  | ||||
|           (function parameter) | ||||
|         ] | ||||
|         [ | ||||
|             __call_traits_T__`::param_type` | ||||
|         ] | ||||
|         [ | ||||
|             Defines a type that represents the "best" way to pass a parameter of type `T` to a function. | ||||
|         ] | ||||
|         [1,3] | ||||
|     ] | ||||
| ] | ||||
|  | ||||
| Notes: | ||||
|  | ||||
| # If `T` is already reference type, then __call_traits__ is | ||||
|         defined such that [link sec:refs "references to references"] | ||||
|         do not occur (requires partial specialization). | ||||
| # If `T` is an array type, then __call_traits__ defines `value_type` | ||||
|         as a "constant pointer to type" rather than an | ||||
|         "array of type" (requires partial specialization). | ||||
|         Note that if you are using `value_type` as a stored value | ||||
|         then this will result in storing a "constant pointer to | ||||
|         an array" rather than the array itself. This may or may | ||||
|         not be a good thing depending upon what you actually | ||||
|         need (in other words take care!). | ||||
| # If `T` is a small built in type or a pointer, then `param_type` | ||||
|         is defined as `T const`, instead of `T const&`. This can | ||||
|         improve the ability of the compiler to optimize loops in | ||||
|         the body of the function if they depend upon the passed | ||||
|         parameter, the semantics of the passed parameter is | ||||
|         otherwise unchanged (requires partial specialization). | ||||
|  | ||||
|  | ||||
| [endsect] | ||||
| [section Copy constructibility] | ||||
|  | ||||
| The following table defines which __call_traits__ types can always | ||||
| be copy-constructed from which other types: | ||||
|  | ||||
| [table Which __call_traits__ types can always be copy-constructed from which other types | ||||
|     [[]          [To `T`] [To `value_type`] [To `reference`] [To `const_reference`] [To `param_type`]] | ||||
|     [[From `T`]    [iff `T` is copy constructible] [iff `T` is copy constructible] [Yes] [Yes] [Yes]] | ||||
|     [[From `value_type`]    [iff `T` is copy constructible] [iff `T` is copy constructible] [No] [No] [Yes]] | ||||
|     [[From `reference`]    [iff `T` is copy constructible] [iff `T` is copy constructible] [Yes] [Yes] [Yes]] | ||||
|     [[From `const_reference`]    [iff `T` is copy constructible] [No] [No] [Yes] [Yes]] | ||||
|     [[From `param_type`]    [iff `T` is copy constructible] [iff `T` is copy constructible] [No] [No] [Yes]] | ||||
| ] | ||||
|  | ||||
| If `T` is an assignable type the following assignments are possible: | ||||
|  | ||||
| [table Which __call_traits__ types are assignable from which other types | ||||
|     [[]          [To `T`] [To `value_type`] [To `reference`] [To `const_reference`] [To `param_type`]] | ||||
|     [[From `T`]    [Yes] [Yes] [-] [-] [-]] | ||||
|     [[From `value_type`]    [Yes] [Yes] [-] [-] [-]] | ||||
|     [[From `reference`]    [Yes] [Yes] [-] [-] [-]] | ||||
|     [[From `const_reference`]    [Yes] [Yes] [-] [-] [-]] | ||||
|     [[From `param_type`]    [Yes] [Yes] [-] [-] [-]] | ||||
| ] | ||||
| [endsect] | ||||
|  | ||||
| [#sec:examples] | ||||
| [section Examples] | ||||
|  | ||||
| The following table shows the effect that __call_traits__ has on | ||||
| various types. | ||||
|  | ||||
| [table Examples of __call_traits__ types | ||||
|     [[]          [__call_traits__::`value_type`] [__call_traits__::`reference`] [__call_traits__::`const_reference`] [__call_traits__::`param_type`] [Applies to:]] | ||||
|     [[From `my_class`]    [`my_class`] [`my_class&`] [`const my_class&`] [`my_class const&`] [All user-defined types]] | ||||
|     [[From `int`]    [`int`] [`int&`] [`const int&`] [`int const`] [All small built-in types]] | ||||
|     [[From `int*`]    [`int*`] [`int*&`] [`int* const &`] [`int* const`] [All pointer types]] | ||||
|     [[From `int&`]    [`int&`] [`int&`] [`const int&`] [`int&`] [All reference types]] | ||||
|     [[From `const int&`]    [`const int&`] [`const int&`] [`const int&`] [`const int&`] [All constant reference types]] | ||||
|     [[From `int[3]`]    [`const int*`] [`int(&)[3]`] [`const int(&)[3]`] [`const int* const`] [All array types]] | ||||
|     [[From `const int[3]`]    [`const int*`] [`const int(&)[3]`] [`const int(&)[3]`] [`const int* const`] [All constant array types]] | ||||
| ] | ||||
|  | ||||
| The table assumes the compiler supports partial | ||||
| specialization: if it does not then all types behave in | ||||
| the same way as the entry for "`my_class`", and | ||||
| __call_traits__ can not be used with reference or array types. | ||||
|  | ||||
| [section Example 1:] | ||||
|  | ||||
| The following class is a trivial class that stores some type `T` | ||||
| by value (see the [@../../../test/call_traits_test.cpp `call_traits_test.cpp`] | ||||
| file). The aim is to illustrate how each of the available | ||||
| __call_traits__ `typedef`s may be used: | ||||
|  | ||||
| ``` | ||||
| template <class T> | ||||
| struct contained | ||||
| { | ||||
|    // define our typedefs first, arrays are stored by value | ||||
|    // so value_type is not the same as result_type: | ||||
|    typedef typename __boost_call_traits__<T>::param_type       param_type; | ||||
|    typedef typename __boost_call_traits__<T>::reference        reference; | ||||
|    typedef typename __boost_call_traits__<T>::const_reference  const_reference; | ||||
|    typedef T                                                value_type; | ||||
|    typedef typename __boost_call_traits__<T>::value_type       result_type; | ||||
|  | ||||
|    // stored value: | ||||
|    value_type v_; | ||||
|  | ||||
|    // constructors: | ||||
|    contained() {} | ||||
|    contained(param_type p) : v_(p){} | ||||
|    // return byval: | ||||
|    result_type value() { return v_; } | ||||
|    // return by_ref: | ||||
|    reference get() { return v_; } | ||||
|    const_reference const_get()const { return v_; } | ||||
|    // pass value: | ||||
|    void call(param_type p){} | ||||
|  | ||||
| }; | ||||
| ``` | ||||
| [endsect] | ||||
|  | ||||
| [#sec:refs] | ||||
| [section Example 2 (the reference to reference problem):] | ||||
|  | ||||
| Consider the definition of __std_binder1st__: | ||||
|  | ||||
| ``` | ||||
| template <class Operation> | ||||
| class binder1st : | ||||
|    public __std_unary_function__<typename Operation::second_argument_type, typename Operation::result_type> | ||||
| { | ||||
| protected: | ||||
|    Operation op; | ||||
|    typename Operation::first_argument_type value; | ||||
| public: | ||||
|    binder1st(const Operation& x, const typename Operation::first_argument_type& y); | ||||
|    typename Operation::result_type operator()(const typename Operation::second_argument_type& x) const; | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| Now consider what happens in the relatively common case that | ||||
| the functor takes its second argument as a reference, that | ||||
| implies that `Operation::second_argument_type` is a | ||||
| reference type, `operator()` will now end up taking a | ||||
| reference to a reference as an argument, and that is not | ||||
| currently legal. The solution here is to modify `operator()` | ||||
| to use __call_traits__: | ||||
|  | ||||
| ``` | ||||
| typename Operation::result_type operator()(typename __call_traits__<typename Operation::second_argument_type>::param_type x) const; | ||||
| ``` | ||||
|  | ||||
| Now in the case that `Operation::second_argument_type` | ||||
| is a reference type, the argument is passed as a reference, and | ||||
| the no "reference to reference" occurs. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [#sec:example3] | ||||
| [section Example 3 (the `make_pair` problem):] | ||||
|  | ||||
| If we pass the name of an array as one (or both) arguments to `__std_make_pair__`, | ||||
| then template argument deduction deduces the passed parameter as | ||||
| "const reference to array of `T`", this also applies to | ||||
| string literals (which are really array literals). Consequently | ||||
| instead of returning a pair of pointers, it tries to return a | ||||
| pair of arrays, and since an array type is not copy-constructible | ||||
| the code fails to compile. One solution is to explicitly cast the | ||||
| arguments to __std_make_pair__ to pointers, but __call_traits__ provides a | ||||
| better automatic solution that works safely even in generic code where the | ||||
| cast might do the wrong thing: | ||||
|  | ||||
| ``` | ||||
| template <class T1, class T2> | ||||
| __std_pair__< | ||||
|    typename __boost_call_traits__<T1>::value_type, | ||||
|    typename __boost_call_traits__<T2>::value_type> | ||||
|       make_pair(const T1& t1, const T2& t2) | ||||
| { | ||||
|    return __std_pair__< | ||||
|       typename __boost_call_traits__<T1>::value_type, | ||||
|       typename __boost_call_traits__<T2>::value_type>(t1, t2); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Here, the deduced argument types will be automatically | ||||
| degraded to pointers if the deduced types are arrays, similar | ||||
| situations occur in the standard binders and adapters: in | ||||
| principle in any function that "wraps" a temporary | ||||
| whose type is deduced. Note that the function arguments to | ||||
| __std_make_pair__ are not expressed in terms of __call_traits__: doing so | ||||
| would prevent template argument deduction from functioning. | ||||
| [endsect] | ||||
|  | ||||
| [#sec:example4] | ||||
| [section Example 4 (optimising fill):] | ||||
|  | ||||
| The __call_traits__ template will "optimize" the passing | ||||
| of a small built-in type as a function parameter. This mainly has | ||||
| an effect when the parameter is used within a loop body. | ||||
|  | ||||
| In the following example (see [@boost:/libs/type_traits/examples/fill_example.cpp `fill_example.cpp`]), | ||||
| a version of __std_fill__ is optimized in two ways: if the type | ||||
| passed is a single byte built-in type then __std_memset__ is used to | ||||
| effect the fill, otherwise a conventional C++ implementation is | ||||
| used, but with the passed parameter "optimized" using | ||||
| __call_traits__: | ||||
|  | ||||
| ``` | ||||
| template <bool opt> | ||||
| struct filler | ||||
| { | ||||
|    template <typename I, typename T> | ||||
|    static void do_fill(I first, I last, typename __boost_call_traits__<T>::param_type val) | ||||
|    { | ||||
|       while(first != last) | ||||
|       { | ||||
|          *first = val; | ||||
|          ++first; | ||||
|       } | ||||
|    } | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct filler<true> | ||||
| { | ||||
|    template <typename I, typename T> | ||||
|    static void do_fill(I first, I last, T val) | ||||
|    { | ||||
|       __std_memset__(first, val, last-first); | ||||
|    } | ||||
| }; | ||||
|  | ||||
| template <class I, class T> | ||||
| inline void fill(I first, I last, const T& val) | ||||
| { | ||||
|    enum { can_opt = boost::is_pointer<I>::value | ||||
|                    && boost::is_arithmetic<T>::value | ||||
|                    && (sizeof(T) == 1) }; | ||||
|    typedef filler<can_opt> filler_t; | ||||
|    filler_t::template do_fill<I,T>(first, last, val); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| The reason that this is "optimal" for small built-in types is that | ||||
| with the value passed as `T const` instead of `const T&` the compiler is | ||||
| able to tell both that the value is constant and that it is free | ||||
| of aliases. With this information the compiler is able to cache | ||||
| the passed value in a register, unroll the loop, or use | ||||
| explicitly parallel instructions: if any of these are supported. | ||||
| Exactly how much mileage you will get from this depends upon your | ||||
| compiler - we could really use some accurate benchmarking | ||||
| software as part of boost for cases like this. | ||||
|  | ||||
| Note that the function arguments to fill are not expressed in | ||||
| terms of __call_traits__: doing so would prevent template argument | ||||
| deduction from functioning. Instead fill acts as a "thin | ||||
| wrapper" that is there to perform template argument | ||||
| deduction, the compiler will optimise away the call to fill all | ||||
| together, replacing it with the call to `filler<>::do_fill`, | ||||
| which does use __call_traits__. | ||||
|  | ||||
| [endsect] | ||||
| [endsect] | ||||
|  | ||||
| [section Rationale] | ||||
|  | ||||
| The following notes are intended to briefly describe the | ||||
| rationale behind choices made in __call_traits__. | ||||
|  | ||||
| All user-defined types follow "existing practice" and need no comment. | ||||
|  | ||||
| Small built-in types, what the standard calls [@https://en.cppreference.com/w/cpp/language/types fundamental | ||||
| types], differ from existing practice only in the `param_type` | ||||
| `typedef`. In this case passing `T const` is compatible | ||||
| with existing practice, but may improve performance in some cases | ||||
| (see [link sec:example4 Example 4]). In any case this should never | ||||
| be any worse than existing practice. | ||||
|  | ||||
| Pointers follow the same rationale as small built-in types. | ||||
|  | ||||
| For reference types the rationale follows [link sec:refs Example 2] | ||||
| - references to references are not allowed, so the __call_traits__ | ||||
| members must be defined such that these problems do | ||||
| not occur. There is a proposal to modify the language such that | ||||
| "a reference to a reference is a reference" (issue #106, | ||||
| submitted by Bjarne Stroustrup). __call_traits_T__`::value_type` | ||||
| and __call_traits_T__`::param_type` both provide the same effect | ||||
| as that proposal, without the need for a language change. In | ||||
| other words, it's a workaround. | ||||
|  | ||||
| For array types, a function that takes an array as an argument | ||||
| will degrade the array type to a pointer type: this means that | ||||
| the type of the actual parameter is different from its declared | ||||
| type, something that can cause endless problems in template code | ||||
| that relies on the declared type of a parameter. | ||||
|  | ||||
| For example: | ||||
|  | ||||
| ``` | ||||
| template <class T> | ||||
| struct A | ||||
| { | ||||
|    void foo(T t); | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| In this case if we instantiate `A<int[2]>` then the declared type of | ||||
| the parameter passed to member function `foo` is `int[2]`, but its | ||||
| actual type is `const int*`. If we try to use the type `T` within the | ||||
| function body, then there is a strong likelihood that our code will not compile: | ||||
|  | ||||
| ``` | ||||
| template <class T> | ||||
| void A<T>::foo(T t) | ||||
| { | ||||
|    T dup(t); // doesn't compile for case that T is an array. | ||||
| } | ||||
| ``` | ||||
|  | ||||
| By using __call_traits__ the degradation from array to pointer is | ||||
| explicit, and the type of the parameter is the same as it's | ||||
| declared type: | ||||
|  | ||||
| ``` | ||||
| template <class T> | ||||
| struct A | ||||
| { | ||||
|    void foo(typename __call_traits__<T>::value_type t); | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| void A<T>::foo(typename __call_traits__<T>::value_type t) | ||||
| { | ||||
|    typename __call_traits__<T>::value_type dup(t); // OK even if T is an array type. | ||||
| } | ||||
| ``` | ||||
|  | ||||
| For `value_type` (return by value), again only a pointer may be | ||||
| returned, not a copy of the whole array, and again __call_traits__ | ||||
| makes the degradation explicit. The `value_type` member is useful | ||||
| whenever an array must be explicitly degraded to a pointer - | ||||
| [link sec:example3 Example 3] provides the test case. | ||||
|  | ||||
| Footnote: the array specialisation for __call_traits__ is the least | ||||
| well understood of all the __call_traits__ specialisations. If the given | ||||
| semantics cause specific problems for you, or does not solve a particular | ||||
| array-related problem, then I would be interested to hear about | ||||
| it. Most people though will probably never need to use this | ||||
| specialisation. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [xinclude tmp/call_traits_reference.xml] | ||||
| [/===============] | ||||
|  | ||||
| [endsect] | ||||
| @@ -1,98 +0,0 @@ | ||||
| [/ | ||||
|   Copyright 2000 Beman Dawes & John Maddock. | ||||
|   Copyright (c) 2021, Alan Freitas | ||||
|  | ||||
|   Distributed under the Boost Software License, Version 1.0. | ||||
|  | ||||
|   See accompanying file LICENSE_1_0.txt | ||||
|   or copy at http://boost.org/LICENSE_1_0.txt | ||||
| ] | ||||
|  | ||||
| [section Compressed Pair] | ||||
|  | ||||
| [section Introduction] | ||||
|  | ||||
| All of the contents of [@../../../../boost/compressed_pair.hpp `<boost/compressed_pair.hpp>`] are defined inside | ||||
| `namespace boost`. | ||||
|  | ||||
| The class __compressed_pair__ is very similar to __std_pair__. However, if either of | ||||
| the template arguments are empty classes, then the | ||||
| [@https://en.cppreference.com/w/cpp/language/ebo ['empty base-class optimisation]] | ||||
| is applied to compress the size of the pair. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [section Synopsis] | ||||
|  | ||||
| ```cpp | ||||
| template <class T1, class T2> | ||||
| class __compressed_pair__ | ||||
| { | ||||
| public: | ||||
|     typedef T1                                                 first_type; | ||||
|     typedef T2                                                 second_type; | ||||
|     typedef typename __call_traits__<first_type>::param_type       first_param_type; | ||||
|     typedef typename __call_traits__<second_type>::param_type      second_param_type; | ||||
|     typedef typename __call_traits__<first_type>::reference        first_reference; | ||||
|     typedef typename __call_traits__<second_type>::reference       second_reference; | ||||
|     typedef typename __call_traits__<first_type>::const_reference  first_const_reference; | ||||
|     typedef typename __call_traits__<second_type>::const_reference second_const_reference; | ||||
|  | ||||
|              compressed_pair() : base() {} | ||||
|              compressed_pair(first_param_type x, second_param_type y); | ||||
|     explicit compressed_pair(first_param_type x); | ||||
|     explicit compressed_pair(second_param_type y); | ||||
|  | ||||
|     compressed_pair& operator=(const compressed_pair&); | ||||
|  | ||||
|     first_reference       first(); | ||||
|     first_const_reference first() const; | ||||
|  | ||||
|     second_reference       second(); | ||||
|     second_const_reference second() const; | ||||
|  | ||||
|     void swap(compressed_pair& y); | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| The two members of the pair can be accessed using the member functions | ||||
| `first()` and `second()`. Note that not all member functions can be | ||||
| instantiated for all template parameter types. In particular | ||||
| __compressed_pair__ can be instantiated for reference and array types, | ||||
| however in these cases the range of constructors that can be used is | ||||
| limited. If types `T1` and `T2` are the same type, then there is only | ||||
| one version of the single-argument constructor, and this constructor | ||||
| initialises both values in the pair to the passed value. | ||||
|  | ||||
| Note that if either member is a [@https://en.cppreference.com/w/cpp/named_req/PODType POD] | ||||
| type, then that member is not zero-initialized by the __compressed_pair__ default constructor: | ||||
| it is up to you to supply an initial value for these types if you want them to have | ||||
| a default value. | ||||
|  | ||||
| Note that __compressed_pair__ can not be instantiated if either of the | ||||
| template arguments is a union type, unless there is compiler support for | ||||
| [@boost:/libs/type_traits/index.html `boost::is_union`], or | ||||
| if [@boost:/libs/type_traits/index.html `boost::is_union`] is | ||||
| specialised for the union type. | ||||
|  | ||||
| Finally, a word of caution for Visual C++ 6 users: if either argument is an | ||||
| empty type, then assigning to that member will produce memory corruption, | ||||
| unless the empty type has a "do nothing" assignment operator defined. This | ||||
| is due to a bug in the way VC6 generates implicit assignment operators. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [xinclude tmp/compressed_pair_reference.xml] | ||||
| [/===============] | ||||
|  | ||||
| [section Acknowledgments] | ||||
|  | ||||
| Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and | ||||
| John Maddock. | ||||
|  | ||||
| Maintained by [@mailto:john@johnmaddock.co.uk John Maddock]. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [endsect] | ||||
							
								
								
									
										115
									
								
								doc/declval.qbk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								doc/declval.qbk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2008 Howard Hinnant | ||||
|  / Copyright (c) 2009-20012 Vicente J. Botet Escriba | ||||
|  / | ||||
|  / 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) | ||||
|  /] | ||||
|  | ||||
| [article Declval | ||||
|     [quickbook 1.5] | ||||
|     [authors [Hinnant, Howard]] | ||||
|     [authors [Botet Escriba, Vicente J.]] | ||||
|     [copyright 2008 Howard Hinnant] | ||||
|     [copyright 2009-2012 Vicente J. Botet Escriba] | ||||
|     [license | ||||
|         Distributed under the Boost Software License, Version 1.0. | ||||
|         (See accompanying file LICENSE_1_0.txt or copy at | ||||
|         [@http://www.boost.org/LICENSE_1_0.txt]) | ||||
|     ] | ||||
| ] | ||||
|  | ||||
| [/===============] | ||||
| [section Overview] | ||||
| [/===============] | ||||
|  | ||||
| The motivation for `declval` was introduced in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value N2958:  | ||||
| Moving Swap Forward]. Here follows a rewording of this chapter. | ||||
|  | ||||
| With the provision of decltype, late-specified return types, and default template-arguments for function templates a  | ||||
| new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale.  | ||||
| Using this technique, it is sometimes necessary to obtain an object of a known type in a non-using context, e.g. given the declaration  | ||||
|  | ||||
|   template<class T> | ||||
|   T&& declval(); // not used | ||||
|    | ||||
| as part of the function template declaration  | ||||
|  | ||||
|   template<class To, class From> | ||||
|   decltype(static_cast<To>(declval<From>())) convert(From&&); | ||||
|    | ||||
| or as part of a class template definition  | ||||
|  | ||||
|   template<class> class result_of; | ||||
|  | ||||
|   template<class Fn, class... ArgTypes> | ||||
|   struct result_of<Fn(ArgTypes...)>  | ||||
|   { | ||||
|     typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) type; | ||||
|   }; | ||||
|    | ||||
| The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function.  | ||||
| The name is supposed to direct the reader's attention to the fact that the expression `declval<T>()` is an lvalue if and only if  | ||||
| T is an lvalue-reference, otherwise an rvalue. To extend the domain of this function we can do a bit better by changing its declaration to  | ||||
|  | ||||
|   template<class T> | ||||
|   typename std::add_rvalue_reference<T>::type declval(); // not used | ||||
|    | ||||
| which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()`  | ||||
| already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C++0x standard.  | ||||
|  | ||||
| The provision of a new library component that allows the production of values in unevaluated expressions is considered  | ||||
| important to realize constrained templates in C++0x where concepts are not available.  | ||||
| This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer.  | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
| [/=================] | ||||
| [section:reference Reference ] | ||||
| [/=================] | ||||
|  | ||||
| `#include <boost/utility/declval.hpp>` | ||||
|  | ||||
|     namespace boost { | ||||
|  | ||||
|         template <typename T> | ||||
|         typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand | ||||
|  | ||||
|     }  // namespace boost | ||||
|  | ||||
|  | ||||
| The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands. | ||||
|  | ||||
|         template <typename T> | ||||
|         typename add_rvalue_reference<T>::type declval(); | ||||
|  | ||||
| [*Remarks:] If this function is used, the program is ill-formed. | ||||
|  | ||||
| [*Remarks:] The template parameter T of declval may be an incomplete type. | ||||
|  | ||||
| [*Example:] | ||||
|  | ||||
|     template <class To, class From> | ||||
|     decltype(static_cast<To>(declval<From>())) convert(From&&); | ||||
|  | ||||
| Declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To.  | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [section History] | ||||
| [/===============] | ||||
|  | ||||
| [heading boost 1.50] | ||||
|  | ||||
| Fixes: | ||||
|  | ||||
| * [@http://svn.boost.org/trac/boost/ticket/6570 #6570] Adding noexcept to boost::declval. | ||||
|  	 | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										68
									
								
								doc/explicit_operator_bool.qbk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								doc/explicit_operator_bool.qbk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2013 Andrey Semashev | ||||
|  / | ||||
|  / Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|  / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  /] | ||||
|  | ||||
| [article BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL | ||||
|     [quickbook 1.5] | ||||
|     [authors [Semashev, Andrey]] | ||||
|     [copyright 2013 Andrey Semashev] | ||||
|     [license | ||||
|         Distributed under the Boost Software License, Version 1.0. | ||||
|         (See accompanying file LICENSE_1_0.txt or copy at | ||||
|         [@http://www.boost.org/LICENSE_1_0.txt]) | ||||
|     ] | ||||
| ] | ||||
|  | ||||
| [/===============] | ||||
| [section Overview] | ||||
| [/===============] | ||||
|  | ||||
| `BOOST_EXPLICIT_OPERATOR_BOOL()` and `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` are compatibility helper macros that expand to an explicit conversion operator to `bool`. For compilers not supporting explicit conversion operators introduced in C++11 the macros expand to a conversion operator that implements the [@http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool safe bool idiom]. In case if the compiler is not able to handle safe bool idiom well the macros expand to a regular conversion operator to `bool`. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
| [/===============] | ||||
| [section Examples] | ||||
| [/===============] | ||||
|  | ||||
| Both macros are intended to be placed within a user's class definition. The generated conversion operators will be implemented in terms of `operator!()` that should be defined by user in this class. In case of `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` the generated conversion operator will be declared `constexpr` which requires the corresponding `operator!()` to also be `constexpr`. | ||||
|  | ||||
|     template< typename T > | ||||
|     class my_ptr | ||||
|     { | ||||
|         T* m_p; | ||||
|  | ||||
|     public: | ||||
|         BOOST_EXPLICIT_OPERATOR_BOOL() | ||||
|  | ||||
|         bool operator!() const | ||||
|         { | ||||
|             return !m_p; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| Now `my_ptr` can be used in conditional expressions, similarly to a regular pointer: | ||||
|  | ||||
|     my_ptr< int > p; | ||||
|     if (p) | ||||
|         std::cout << "true" << std::endl; | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [section History] | ||||
| [/===============] | ||||
|  | ||||
| [heading boost 1.55] | ||||
|  | ||||
| * The macro was extracted from Boost.Log. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										176
									
								
								doc/html/declval.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								doc/html/declval.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | ||||
| <html> | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> | ||||
| <title>Declval</title> | ||||
| <link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css"> | ||||
| <meta name="generator" content="DocBook XSL Stylesheets V1.76.0"> | ||||
| <link rel="home" href="declval.html" title="Declval"> | ||||
| </head> | ||||
| <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> | ||||
| <table cellpadding="2" width="100%"><tr> | ||||
| <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td> | ||||
| <td align="center"><a href="../../../../index.html">Home</a></td> | ||||
| <td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td> | ||||
| <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> | ||||
| <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> | ||||
| <td align="center"><a href="../../../../more/index.htm">More</a></td> | ||||
| </tr></table> | ||||
| <hr> | ||||
| <div class="spirit-nav"></div> | ||||
| <div class="article"> | ||||
| <div class="titlepage"> | ||||
| <div> | ||||
| <div><h2 class="title"> | ||||
| <a name="declval"></a>Declval</h2></div> | ||||
| <div><div class="authorgroup"> | ||||
| <div class="author"><h3 class="author"> | ||||
| <span class="firstname">Howard</span> <span class="surname">Hinnant</span> | ||||
| </h3></div> | ||||
| <div class="author"><h3 class="author"> | ||||
| <span class="firstname">Vicente J.</span> <span class="surname">Botet Escriba</span> | ||||
| </h3></div> | ||||
| </div></div> | ||||
| <div><p class="copyright">Copyright © 2008 Howard Hinnant</p></div> | ||||
| <div><p class="copyright">Copyright © 2009 -2012 Vicente J. Botet Escriba</p></div> | ||||
| <div><div class="legalnotice"> | ||||
| <a name="idp13456288"></a><p> | ||||
|         Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|         file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) | ||||
|       </p> | ||||
| </div></div> | ||||
| </div> | ||||
| <hr> | ||||
| </div> | ||||
| <div class="toc"> | ||||
| <p><b>Table of Contents</b></p> | ||||
| <dl> | ||||
| <dt><span class="section"><a href="declval.html#declval.overview">Overview</a></span></dt> | ||||
| <dt><span class="section"><a href="declval.html#declval.reference">Reference </a></span></dt> | ||||
| <dt><span class="section"><a href="declval.html#declval.history">History</a></span></dt> | ||||
| </dl> | ||||
| </div> | ||||
| <div class="section declval_overview"> | ||||
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> | ||||
| <a name="declval.overview"></a><a class="link" href="declval.html#declval.overview" title="Overview">Overview</a> | ||||
| </h2></div></div></div> | ||||
| <p> | ||||
|       The motivation for <code class="computeroutput"><span class="identifier">declval</span></code> | ||||
|       was introduced in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value" target="_top">N2958: | ||||
|       Moving Swap Forward</a>. Here follows a rewording of this chapter. | ||||
|     </p> | ||||
| <p> | ||||
|       With the provision of decltype, late-specified return types, and default template-arguments | ||||
|       for function templates a new generation of SFINAE patterns will emerge to at | ||||
|       least partially compensate the lack of concepts on the C++0x timescale. Using | ||||
|       this technique, it is sometimes necessary to obtain an object of a known type | ||||
|       in a non-using context, e.g. given the declaration | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> | ||||
| <span class="identifier">T</span><span class="special">&&</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">// not used | ||||
| </span></pre> | ||||
| <p> | ||||
|       as part of the function template declaration | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">To</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">From</span><span class="special">></span> | ||||
| <span class="identifier">decltype</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">To</span><span class="special">>(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">From</span><span class="special">>()))</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">From</span><span class="special">&&);</span> | ||||
| </pre> | ||||
| <p> | ||||
|       or as part of a class template definition | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">></span> <span class="keyword">class</span> <span class="identifier">result_of</span><span class="special">;</span> | ||||
|  | ||||
| <span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">ArgTypes</span><span class="special">></span> | ||||
| <span class="keyword">struct</span> <span class="identifier">result_of</span><span class="special"><</span><span class="identifier">Fn</span><span class="special">(</span><span class="identifier">ArgTypes</span><span class="special">...)></span>  | ||||
| <span class="special">{</span> | ||||
|   <span class="keyword">typedef</span> <span class="identifier">decltype</span><span class="special">(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">Fn</span><span class="special">>()(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">ArgTypes</span><span class="special">>()...))</span> <span class="identifier">type</span><span class="special">;</span> | ||||
| <span class="special">};</span> | ||||
| </pre> | ||||
| <p> | ||||
|       The role of the function template declval() is a transformation of a type T | ||||
|       into a value without using or evaluating this function. The name is supposed | ||||
|       to direct the reader's attention to the fact that the expression <code class="computeroutput"><span class="identifier">declval</span><span class="special"><</span><span class="identifier">T</span><span class="special">>()</span></code> is | ||||
|       an lvalue if and only if T is an lvalue-reference, otherwise an rvalue. To | ||||
|       extend the domain of this function we can do a bit better by changing its declaration | ||||
|       to | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> | ||||
| <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">add_rvalue_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">// not used | ||||
| </span></pre> | ||||
| <p> | ||||
|       which ensures that we can also use cv void as template parameter. The careful | ||||
|       reader might have noticed that <code class="computeroutput"><span class="identifier">declval</span><span class="special">()</span></code> already exists under the name create() as | ||||
|       part of the definition of the semantics of the type trait is_convertible in | ||||
|       the C++0x standard. | ||||
|     </p> | ||||
| <p> | ||||
|       The provision of a new library component that allows the production of values | ||||
|       in unevaluated expressions is considered important to realize constrained templates | ||||
|       in C++0x where concepts are not available. This extremely light-weight function | ||||
|       is expected to be part of the daily tool-box of the C++0x programmer. | ||||
|     </p> | ||||
| </div> | ||||
| <div class="section declval_reference"> | ||||
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> | ||||
| <a name="declval.reference"></a><a class="link" href="declval.html#declval.reference" title="Reference">Reference </a> | ||||
| </h2></div></div></div> | ||||
| <p> | ||||
|       <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">declval</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code> | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> | ||||
|  | ||||
|     <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> | ||||
|     <span class="keyword">typename</span> <span class="identifier">add_rvalue_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">()</span> <span class="identifier">noexcept</span><span class="special">;</span> <span class="comment">// as unevaluated operand | ||||
| </span> | ||||
| <span class="special">}</span>  <span class="comment">// namespace boost | ||||
| </span></pre> | ||||
| <p> | ||||
|       The library provides the function template declval to simplify the definition | ||||
|       of expressions which occur as unevaluated operands. | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> | ||||
| <span class="keyword">typename</span> <span class="identifier">add_rvalue_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">();</span> | ||||
| </pre> | ||||
| <p> | ||||
|       <span class="bold"><strong>Remarks:</strong></span> If this function is used, the program | ||||
|       is ill-formed. | ||||
|     </p> | ||||
| <p> | ||||
|       <span class="bold"><strong>Remarks:</strong></span> The template parameter T of declval | ||||
|       may be an incomplete type. | ||||
|     </p> | ||||
| <p> | ||||
|       <span class="bold"><strong>Example:</strong></span> | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">To</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">From</span><span class="special">></span> | ||||
| <span class="identifier">decltype</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">To</span><span class="special">>(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">From</span><span class="special">>()))</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">From</span><span class="special">&&);</span> | ||||
| </pre> | ||||
| <p> | ||||
|       Declares a function template convert which only participates in overloading | ||||
|       if the type From can be explicitly converted to type To. | ||||
|     </p> | ||||
| </div> | ||||
| <div class="section declval_history"> | ||||
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> | ||||
| <a name="declval.history"></a><a class="link" href="declval.html#declval.history" title="History">History</a> | ||||
| </h2></div></div></div> | ||||
| <a name="declval.history.boost_1_50"></a><h4> | ||||
| <a name="idp13559952"></a> | ||||
|       <a class="link" href="declval.html#declval.history.boost_1_50">boost 1.50</a> | ||||
|     </h4> | ||||
| <p> | ||||
|       New Features: | ||||
|     </p> | ||||
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> | ||||
|           <a href="http://svn.boost.org/trac/boost/ticket/6570" target="_top">#6570</a> | ||||
|           Adding noexcept to boost::declval. | ||||
|         </li></ul></div> | ||||
| </div> | ||||
| </div> | ||||
| <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> | ||||
| <td align="left"><p><small>Last revised: March 25, 2012 at 18:26:23 GMT</small></p></td> | ||||
| <td align="right"><div class="copyright-footer"></div></td> | ||||
| </tr></table> | ||||
| <hr> | ||||
| <div class="spirit-nav"></div> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										280
									
								
								doc/html/string_ref.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								doc/html/string_ref.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,280 @@ | ||||
| <html> | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> | ||||
| <title>String_Ref</title> | ||||
| <link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css"> | ||||
| <meta name="generator" content="DocBook XSL Stylesheets V1.75.2"> | ||||
| <link rel="home" href="string_ref.html" title="String_Ref"> | ||||
| </head> | ||||
| <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> | ||||
| <table cellpadding="2" width="100%"><tr> | ||||
| <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td> | ||||
| <td align="center"><a href="../../../../index.html">Home</a></td> | ||||
| <td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td> | ||||
| <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> | ||||
| <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> | ||||
| <td align="center"><a href="../../../../more/index.htm">More</a></td> | ||||
| </tr></table> | ||||
| <hr> | ||||
| <div class="spirit-nav"></div> | ||||
| <div class="article"> | ||||
| <div class="titlepage"> | ||||
| <div> | ||||
| <div><h2 class="title"> | ||||
| <a name="string_ref"></a>String_Ref</h2></div> | ||||
| <div><div class="authorgroup"><div class="author"><h3 class="author"> | ||||
| <span class="firstname">Marshall</span> <span class="surname">Clow</span> | ||||
| </h3></div></div></div> | ||||
| <div><p class="copyright">Copyright © 2012 Marshall Clow</p></div> | ||||
| <div><div class="legalnotice"> | ||||
| <a name="string_ref.legal"></a><p> | ||||
|         Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|         file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) | ||||
|       </p> | ||||
| </div></div> | ||||
| </div> | ||||
| <hr> | ||||
| </div> | ||||
| <div class="toc"> | ||||
| <p><b>Table of Contents</b></p> | ||||
| <dl> | ||||
| <dt><span class="section"><a href="string_ref.html#string_ref.overview">Overview</a></span></dt> | ||||
| <dt><span class="section"><a href="string_ref.html#string_ref.examples">Examples</a></span></dt> | ||||
| <dt><span class="section"><a href="string_ref.html#string_ref.reference">Reference </a></span></dt> | ||||
| <dt><span class="section"><a href="string_ref.html#string_ref.history">History</a></span></dt> | ||||
| </dl> | ||||
| </div> | ||||
| <div class="section string_ref_overview"> | ||||
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> | ||||
| <a name="string_ref.overview"></a><a class="link" href="string_ref.html#string_ref.overview" title="Overview">Overview</a> | ||||
| </h2></div></div></div> | ||||
| <p> | ||||
|       Boost.StringRef is an implementation of Jeffrey Yaskin's <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html" target="_top">N3442: | ||||
|       string_ref: a non-owning reference to a string</a>. | ||||
|     </p> | ||||
| <p> | ||||
|       When you are parsing/processing strings from some external source, frequently | ||||
|       you want to pass a piece of text to a procedure for specialized processing. | ||||
|       The canonical way to do this is as a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, | ||||
|       but that has certain drawbacks: | ||||
|     </p> | ||||
| <p> | ||||
|       1) If you are processing a buffer of text (say a HTTP response or the contents | ||||
|       of a file), then you have to create the string from the text you want to pass, | ||||
|       which involves memory allocation and copying of data. | ||||
|     </p> | ||||
| <p> | ||||
|       2) if a routine receives a constant <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> | ||||
|       and wants to pass a portion of that string to another routine, then it must | ||||
|       create a new string of that substring. | ||||
|     </p> | ||||
| <p> | ||||
|       3) A routine receives a constant <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> | ||||
|       and wants to return a portion of the string, then it must create a new string | ||||
|       to return. | ||||
|     </p> | ||||
| <p> | ||||
|       <code class="computeroutput"><span class="identifier">string_ref</span></code> is designed to solve | ||||
|       these efficiency problems. A <code class="computeroutput"><span class="identifier">string_ref</span></code> | ||||
|       is a read-only reference to a contiguous sequence of characters, and provides | ||||
|       much of the functionality of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>. | ||||
|       A <code class="computeroutput"><span class="identifier">string_ref</span></code> is cheap to create, | ||||
|       copy and pass by value, because it does not actually own the storage that it | ||||
|       points to. | ||||
|     </p> | ||||
| <p> | ||||
|       A <code class="computeroutput"><span class="identifier">string_ref</span></code> is implemented | ||||
|       as a small struct that contains a pointer to the start of the character data | ||||
|       and a count. A <code class="computeroutput"><span class="identifier">string_ref</span></code> is | ||||
|       cheap to create and cheap to copy. | ||||
|     </p> | ||||
| <p> | ||||
|       <code class="computeroutput"><span class="identifier">string_ref</span></code> acts as a container; | ||||
|       it includes all the methods that you would expect in a container, including | ||||
|       iteration support, <code class="computeroutput"><span class="keyword">operator</span> <span class="special">[]</span></code>, | ||||
|       <code class="computeroutput"><span class="identifier">at</span></code> and <code class="computeroutput"><span class="identifier">size</span></code>. | ||||
|       It can be used with any of the iterator-based algorithms in the STL - as long | ||||
|       as you don't need to change the underlying data (<code class="computeroutput"><span class="identifier">sort</span></code> | ||||
|       and <code class="computeroutput"><span class="identifier">remove</span></code>, for example, will | ||||
|       not work) | ||||
|     </p> | ||||
| <p> | ||||
|       Besides generic container functionality, <code class="computeroutput"><span class="identifier">string_ref</span></code> | ||||
|       provides a subset of the interface of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>. | ||||
|       This makes it easy to replace parameters of type <code class="computeroutput"><span class="keyword">const</span> | ||||
|       <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&</span></code> | ||||
|       with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span></code>. Like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, | ||||
|       <code class="computeroutput"><span class="identifier">string_ref</span></code> has a static member | ||||
|       variable named <code class="computeroutput"><span class="identifier">npos</span></code> to denote | ||||
|       the result of failed searches, and to mean "the end". | ||||
|     </p> | ||||
| <p> | ||||
|       Because a <code class="computeroutput"><span class="identifier">string_ref</span></code> does not | ||||
|       own the data that it "points to", it introduces lifetime issues into | ||||
|       code that uses it. The programmer must ensure that the data that a <code class="computeroutput"><span class="identifier">string_ref</span></code> refers to exists as long as the | ||||
|       <code class="computeroutput"><span class="identifier">string_ref</span></code> does. | ||||
|     </p> | ||||
| </div> | ||||
| <div class="section string_ref_examples"> | ||||
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> | ||||
| <a name="string_ref.examples"></a><a class="link" href="string_ref.html#string_ref.examples" title="Examples">Examples</a> | ||||
| </h2></div></div></div> | ||||
| <p> | ||||
|       Integrating <code class="computeroutput"><span class="identifier">string_ref</span></code> into | ||||
|       your code is fairly simple. Wherever you pass a <code class="computeroutput"><span class="keyword">const</span> | ||||
|       <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&</span></code> | ||||
|       or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> as a parameter, that's a candidate | ||||
|       for passing a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span></code>. | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&</span><span class="identifier">bar</span> <span class="special">)</span> <span class="special">{</span> | ||||
|     <span class="keyword">return</span> <span class="identifier">bar</span><span class="special">.</span><span class="identifier">substr</span> <span class="special">(</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span> <span class="special">);</span> | ||||
|     <span class="special">}</span> | ||||
|  | ||||
| <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="string">"ABCDEFG"</span> <span class="special">).</span><span class="identifier">front</span><span class="special">()</span> <span class="special">==</span> <span class="string">"C"</span> <span class="special">)</span> <span class="special">{</span> <span class="comment">/* do something */</span> <span class="special">}</span> | ||||
| </pre> | ||||
| <p> | ||||
|       Let's figure out what happens in this (contrived) example. | ||||
|     </p> | ||||
| <p> | ||||
|       First, a temporary string is created from the string literal <code class="computeroutput"><span class="string">"ABCDEFG"</span></code>, and it is passed (by reference) | ||||
|       to the routine <code class="computeroutput"><span class="identifier">extract_part</span></code>. | ||||
|       Then a second string is created in the call <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">substr</span></code> | ||||
|       and returned to <code class="computeroutput"><span class="identifier">extract_part</span></code> | ||||
|       (this copy may be elided by RVO). Then <code class="computeroutput"><span class="identifier">extract_part</span></code> | ||||
|       returns that string back to the caller (again this copy may be elided). The | ||||
|       first temporary string is deallocated, and <code class="computeroutput"><span class="identifier">front</span></code> | ||||
|       is called on the second string, and then it is deallocated as well. | ||||
|     </p> | ||||
| <p> | ||||
|       Two <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>s are created, and two copy operations. | ||||
|       That's (potentially) four memory allocations and deallocations, and the associated | ||||
|       copying of data. | ||||
|     </p> | ||||
| <p> | ||||
|       Now let's look at the same code with <code class="computeroutput"><span class="identifier">string_ref</span></code>: | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span> <span class="identifier">bar</span> <span class="special">)</span> <span class="special">{</span> | ||||
|     <span class="keyword">return</span> <span class="identifier">bar</span><span class="special">.</span><span class="identifier">substr</span> <span class="special">(</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span> <span class="special">);</span> | ||||
|     <span class="special">}</span> | ||||
|  | ||||
| <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="string">"ABCDEFG"</span> <span class="special">).</span><span class="identifier">front</span><span class="special">()</span> <span class="special">==</span> <span class="string">"C"</span> <span class="special">)</span> <span class="special">{</span> <span class="comment">/* do something */</span> <span class="special">}</span> | ||||
| </pre> | ||||
| <p> | ||||
|       No memory allocations. No copying of character data. No changes to the code | ||||
|       other than the types. There are two <code class="computeroutput"><span class="identifier">string_ref</span></code>s | ||||
|       created, and two <code class="computeroutput"><span class="identifier">string_ref</span></code>s | ||||
|       copied, but those are cheap operations. | ||||
|     </p> | ||||
| </div> | ||||
| <div class="section string_ref_reference"> | ||||
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> | ||||
| <a name="string_ref.reference"></a><a class="link" href="string_ref.html#string_ref.reference" title="Reference">Reference </a> | ||||
| </h2></div></div></div> | ||||
| <p> | ||||
|       The header file "string_ref.hpp" defines a template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">basic_string_ref</span></code>, | ||||
|       and four specializations - for <code class="computeroutput"><span class="keyword">char</span></code> | ||||
|       / <code class="computeroutput"><span class="keyword">wchar_t</span></code> / <code class="computeroutput"><span class="identifier">char16_t</span></code> | ||||
|       / <code class="computeroutput"><span class="identifier">char32_t</span></code> . | ||||
|     </p> | ||||
| <p> | ||||
|       <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">string_ref</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code> | ||||
|     </p> | ||||
| <p> | ||||
|       Construction and copying: | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span> <span class="special">();</span>    <span class="comment">// Constructs an empty string_ref</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// Constructs from a NULL-terminated string</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">str</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">len</span><span class="special">);</span> <span class="comment">// Constructs from a pointer, length pair</span> | ||||
| <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Allocator</span><span class="special">></span> | ||||
| <span class="identifier">basic_string_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special"><</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">>&</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// Constructs from a std::string</span> | ||||
| <span class="identifier">basic_string_ref</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">basic_string_ref</span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">);</span> | ||||
| <span class="identifier">basic_string_ref</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">basic_string_ref</span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">);</span> | ||||
| </pre> | ||||
| <p> | ||||
|       <code class="computeroutput"><span class="identifier">string_ref</span></code> does not define | ||||
|       a move constructor nor a move-assignment operator because copying a <code class="computeroutput"><span class="identifier">string_ref</span></code> is just a cheap as moving one. | ||||
|     </p> | ||||
| <p> | ||||
|       Basic container-like functions: | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">size</span><span class="special">()</span>     <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">length</span><span class="special">()</span>   <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">max_size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">bool</span> <span class="identifier">empty</span><span class="special">()</span>         <span class="keyword">const</span> <span class="special">;</span> | ||||
|  | ||||
| <span class="comment">// All iterators are const_iterators</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span>  <span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span> <span class="identifier">cbegin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span>    <span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span>   <span class="identifier">cend</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">const_reverse_iterator</span>         <span class="identifier">rbegin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">const_reverse_iterator</span>        <span class="identifier">crbegin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">const_reverse_iterator</span>           <span class="identifier">rend</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">const_reverse_iterator</span>          <span class="identifier">crend</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| </pre> | ||||
| <p> | ||||
|       Access to the individual elements (all of which are const): | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">size_type</span> <span class="identifier">pos</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&</span> <span class="identifier">at</span><span class="special">(</span><span class="identifier">size_t</span> <span class="identifier">pos</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&</span> <span class="identifier">front</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&</span> <span class="identifier">back</span><span class="special">()</span>  <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">data</span><span class="special">()</span>  <span class="keyword">const</span> <span class="special">;</span> | ||||
| </pre> | ||||
| <p> | ||||
|       Modifying the <code class="computeroutput"><span class="identifier">string_ref</span></code> (but | ||||
|       not the underlying data): | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">clear</span><span class="special">();</span> | ||||
| <span class="keyword">void</span> <span class="identifier">remove_prefix</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">);</span> | ||||
| <span class="keyword">void</span> <span class="identifier">remove_suffix</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">);</span> | ||||
| </pre> | ||||
| <p> | ||||
|       Searching: | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="identifier">size_type</span> <span class="identifier">find</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">find</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">rfind</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">rfind</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">find_first_of</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">find_last_of</span> <span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
|  | ||||
| <span class="identifier">size_type</span> <span class="identifier">find_first_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">find_last_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">find_first_not_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">find_first_not_of</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">find_last_not_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="identifier">size_type</span> <span class="identifier">find_last_not_of</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| </pre> | ||||
| <p> | ||||
|       String-like operations: | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span> <span class="identifier">substr</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">pos</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">=</span><span class="identifier">npos</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> <span class="comment">// Creates a new string_ref</span> | ||||
| <span class="keyword">bool</span> <span class="identifier">starts_with</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="keyword">bool</span> <span class="identifier">starts_with</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="keyword">bool</span> <span class="identifier">ends_with</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| <span class="keyword">bool</span> <span class="identifier">ends_with</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> | ||||
| </pre> | ||||
| </div> | ||||
| <div class="section string_ref_history"> | ||||
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> | ||||
| <a name="string_ref.history"></a><a class="link" href="string_ref.html#string_ref.history" title="History">History</a> | ||||
| </h2></div></div></div> | ||||
| <h4> | ||||
| <a name="string_ref.history.h0"></a> | ||||
|       <span><a name="string_ref.history.boost_1_53"></a></span><a class="link" href="string_ref.html#string_ref.history.boost_1_53">boost | ||||
|       1.53</a> | ||||
|     </h4> | ||||
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> | ||||
|           Introduced | ||||
|         </li></ul></div> | ||||
| </div> | ||||
| </div> | ||||
| <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> | ||||
| <td align="left"><p><small>Last revised: January 14, 2013 at 16:24:14 GMT</small></p></td> | ||||
| <td align="right"><div class="copyright-footer"></div></td> | ||||
| </tr></table> | ||||
| <hr> | ||||
| <div class="spirit-nav"></div> | ||||
| </body> | ||||
| </html> | ||||
| @@ -1,308 +0,0 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2012 Marshall Clow | ||||
|  / Copyright (c) 2021, Alan Freitas | ||||
|  / | ||||
|  / 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) | ||||
|  /] | ||||
|  | ||||
| [/===============] | ||||
| [#sec:in_place_factory] | ||||
| [section In-place Factory] | ||||
| [/===============] | ||||
|  | ||||
| [section Introduction] | ||||
|  | ||||
| Suppose we have a class | ||||
|  | ||||
| ``` | ||||
| struct X | ||||
| { | ||||
|   X ( int, __std_string__ ) ; | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| And a container for it which supports an empty state. That is, a container which can contain zero objects: | ||||
|  | ||||
| ``` | ||||
| struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|   ~C() { delete contained_ ; } | ||||
|   X* contained_ ; | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| A container designed to support an empty state typically does not require the contained type to be | ||||
| __DefaultConstructible__, but it typically requires it to be __CopyConstructible__ as a mechanism to | ||||
| initialize the object to store: | ||||
|  | ||||
| ``` | ||||
| struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|    C ( X const& v ) : contained_ ( new X(v) ) {} | ||||
|   ~C() { delete contained_ ; } | ||||
|   X* contained_ ; | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| There is a subtle problem with this: since the mechanism used to initialize the stored object is copy construction, | ||||
| there must exist a previously constructed source object to copy from. This object is likely to be temporary and serve | ||||
| no purpose besides being the source: | ||||
|  | ||||
| ``` | ||||
| void foo() | ||||
| { | ||||
|   // Temporary object created. | ||||
|   C c( 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 supplies the arguments for the `X` constructor | ||||
| directly to the container: | ||||
|  | ||||
| ``` | ||||
| struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|    C ( X const& v ) : contained_ ( new X(v) ) {} | ||||
|    C ( int a0, __std_string__ a1 ) : contained_ ( new X(a0,a1) ) {} | ||||
|   ~C() { delete contained_ ; } | ||||
|   X* contained_ ; | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| ``` | ||||
| void foo() | ||||
| { | ||||
|   // Wrapped object constructed in-place | ||||
|   // No temporary created. | ||||
|   C c(123,"hello"); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Clearly, this solution does not scale well since the container must duplicate all the constructor overloads | ||||
| from the contained type, or at least all those which are to be supported directly in the container. | ||||
|  | ||||
| [endsect] | ||||
| [section Framework] | ||||
|  | ||||
| This library proposes a framework to allow some containers to directly construct contained objects in-place without requiring | ||||
| the entire set of constructor overloads from the contained type. It also allows the container to remove the __CopyConstructible__ | ||||
| requirement from the contained type since objects can be directly constructed in-place without need of a copy. | ||||
|  | ||||
| The only requirement on the container is that it must provide proper storage. That is, the container should be | ||||
| correctly aligned and sized. Naturally, the container will typically support uninitialized storage to avoid the | ||||
| in-place construction to override a fully-constructed object, as this would defeat the purpose of in-place construction. | ||||
|  | ||||
| For this purpose, the framework provides two concepts called: InPlaceFactories and TypedInPlaceFactories. | ||||
| Helpers to declare these classes are declared in [@../../../../boost/utility/in_place_factory.hpp `<boost/utility/in_place_factory.hpp>`] | ||||
| and [@../../../../boost/utility/typed_in_place_factory.hpp `<boost/utility/typed_in_place_factory.hpp>`]. | ||||
|  | ||||
| Essentially, these classes hold a sequence of actual parameters and a method to construct an object in place using these parameters. | ||||
| Each member of the family differs only in the number and type of the parameter list. The first family | ||||
| takes the type of the object to construct directly in method provided for that | ||||
| purpose, whereas the second family incorporates that type in the factory class | ||||
| itself. From the container point of view, using the framework amounts to calling the | ||||
| factory's method to contruct the object in place. From the user point of view, it amounts to creating | ||||
| the right factory object to hold the parameters and pass it to the container. | ||||
|  | ||||
| The following simplified example shows the basic idea. A complete example follows the formal specification of the framework: | ||||
|  | ||||
| ``` | ||||
| struct C | ||||
| { | ||||
|    template <class InPlaceFactory> | ||||
|    C ( InPlaceFactory const& aFactory ) | ||||
|     : | ||||
|     contained_ ( uninitialized_storage() ) | ||||
|    { | ||||
|      aFactory.template apply<X>(contained_); | ||||
|    } | ||||
|  | ||||
|   ~C() | ||||
|   { | ||||
|     contained_ -> X::~X(); | ||||
|     delete[] contained_ ; | ||||
|   } | ||||
|  | ||||
|   char* uninitialized_storage() { return new char[sizeof(X)] ; } | ||||
|  | ||||
|   char* contained_ ; | ||||
| }; | ||||
|  | ||||
| void foo() | ||||
| { | ||||
|   C c( in_place(123,"hello") ) ; | ||||
| } | ||||
|  | ||||
| ``` | ||||
|  | ||||
| [endsect] | ||||
| [section Specification] | ||||
|  | ||||
| The following is the first member of the family of `InPlaceFactory` classes, along with its corresponding helper template function. | ||||
| The rest of the family varies only in the number and type of template and constructor parameters. | ||||
|  | ||||
|  | ||||
| ``` | ||||
| namespace boost { | ||||
|  | ||||
| struct __in_place_factory_base__ {}; | ||||
|  | ||||
| template<class A0> | ||||
| class in_place_factory : public __in_place_factory_base__ | ||||
| { | ||||
|   public: | ||||
|     in_place_factory ( A0 const& a0 ) : m_a0(a0) {} | ||||
|  | ||||
|     template< class T > | ||||
|     void apply ( void* address ) const | ||||
|     { | ||||
|       new (address) T(m_a0); | ||||
|     } | ||||
|  | ||||
|   private: | ||||
|       A0 const& m_a0 ; | ||||
| }; | ||||
|  | ||||
| template<class A0> | ||||
| in_place_factory<A0> in_place ( A0 const& a0 ) | ||||
| { | ||||
|   return in_place_factory<A0>(a0); | ||||
| } | ||||
|  | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Similarly, the following is the first member of the family of `typed_in_place_factory` classes, along with its corresponding | ||||
| helper template function. The rest of the family varies only in the number and type of template and constructor parameters. | ||||
|  | ||||
| ``` | ||||
| namespace boost { | ||||
|  | ||||
| struct __typed_in_place_factory_base__ {}; | ||||
|  | ||||
| template<class T, class A0> | ||||
| class typed_in_place_factory : public __typed_in_place_factory_base__ | ||||
| { | ||||
|   public: | ||||
|     typed_in_place_factory ( A0 const& a0 ) : m_a0(a0) {} | ||||
|  | ||||
|     void apply ( void* address ) const | ||||
|     { | ||||
|       new (address) T(m_a0); | ||||
|     } | ||||
|  | ||||
|   private: | ||||
|     A0 const& m_a0 ; | ||||
| }; | ||||
|  | ||||
| template<class T, class A0> | ||||
| typed_in_place_factory<A0> in_place ( A0 const& a0 ) | ||||
| { | ||||
|   return typed_in_place_factory<T,A0>(a0); | ||||
| } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| As you can see, the `in_place_factory` and `typed_in_place_factory` template classes vary only in the way they specify | ||||
| the target type: in the first family, the type is given as a template argument to the apply member function while in the | ||||
| second it is given directly as part of the factory class. | ||||
|  | ||||
| When the container holds a unique non-polymorphic type, such as the case of [@boost:/libs/optional/index.html Boost.Optional], | ||||
| it knows the exact dynamic-type of the contained object and can pass it to the `apply()` method of a non-typed factory. | ||||
| In this case, end users can use an `in_place_factory` instance which can be constructed without the type of the object to construct. | ||||
|  | ||||
| However, if the container holds heterogeneous or polymorphic objects, such as the case of [@boost:/libs/variant/index.html Boost.Variant], | ||||
| the dynamic-type of the object to be constructed must be known by the factory. In this case, end users must use a `typed_in_place_factory` | ||||
| instead. | ||||
|  | ||||
| [endsect] | ||||
| [section Container-side Usage] | ||||
|  | ||||
| As shown in the introductory simplified example, the container class must contain methods that accept an instance of | ||||
| these factories and pass the object's storage to the factory's apply method. | ||||
|  | ||||
| However, the type of the factory class cannot be completely specified in the container class because that would | ||||
| defeat the whole purpose of the factories which is to allow the container to accept a variadic argument list | ||||
| for the constructor of its contained object. | ||||
|  | ||||
| The correct function overload must be based on the only distinctive and common | ||||
| characteristic of all the classes in each family: the base class. | ||||
|  | ||||
| Depending on the container class, you can use `enable_if` to generate the right overload, or use the following | ||||
| dispatch technique, which is used in the [@boost:/libs/optional/index.html Boost.Optional] class: | ||||
|  | ||||
|  | ||||
| ``` | ||||
| struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|    C ( X const& v ) : contained_ ( new X(v) ) {} | ||||
|  | ||||
|    template <class Expr> | ||||
|    C ( Expr const& expr ) | ||||
|     : | ||||
|     contained_ ( uninitialized_storage() ) | ||||
|    { | ||||
|     construct(expr,&expr); | ||||
|    } | ||||
|  | ||||
|   ~C() { delete contained_ ; } | ||||
|  | ||||
|   template<class InPlaceFactory> | ||||
|   void construct ( InPlaceFactory const& aFactory, boost::__in_place_factory_base__* ) | ||||
|   { | ||||
|     aFactory.template apply<X>(contained_); | ||||
|   } | ||||
|  | ||||
|   template<class TypedInPlaceFactory> | ||||
|   void construct ( TypedInPlaceFactory const& aFactory, boost::__typed_in_place_factory_base__* ) | ||||
|   { | ||||
|     aFactory.apply(contained_); | ||||
|   } | ||||
|  | ||||
|   X* uninitialized_storage() { return static_cast<X*>(new char[sizeof(X)]) ; } | ||||
|  | ||||
|   X* contained_ ; | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| [endsect] | ||||
| [section User-side Usage] | ||||
|  | ||||
| End users pass to the container an instance of a factory object holding the actual parameters needed to construct the | ||||
| contained object directly within the container. For this, the helper template function `in_place` is used. | ||||
|  | ||||
| The call `in_place(a0,a1,a2,...,an)` constructs a (non-typed) `in_place_factory` instance with the given argument list. | ||||
|  | ||||
| The call `in_place<T>(a0,a1,a2,...,an)` constructs a `typed_in_place_factory` instance with the given argument list for the | ||||
| type `T`. | ||||
|  | ||||
| ``` | ||||
| void foo() | ||||
| { | ||||
|   C a( in_place(123, "hello") ) ;    // in_place_factory passed | ||||
|   C b( in_place<X>(456, "world") ) ; // typed_in_place_factory passed | ||||
| } | ||||
|  | ||||
| ``` | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [#boost.typed_in_place_factory_base] | ||||
| [xinclude tmp/in_place_factory_reference.xml] | ||||
| [/===============] | ||||
|  | ||||
| [section Acknowledgments] | ||||
|  | ||||
| Copyright Fernando Luis Cacciola Carballal, 2004 | ||||
|  | ||||
| [endsect] | ||||
| [endsect] | ||||
							
								
								
									
										
											BIN
										
									
								
								doc/logo.png
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doc/logo.png
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 10 KiB | 
							
								
								
									
										539
									
								
								doc/logo.svg
									
									
									
									
									
								
							
							
						
						
									
										539
									
								
								doc/logo.svg
									
									
									
									
									
								
							| @@ -1,539 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:xlink="http://www.w3.org/1999/xlink" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="744.09448819" | ||||
|    height="1052.3622047" | ||||
|    id="svg6858" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.48.4 r9939" | ||||
|    sodipodi:docname="utility.svg"> | ||||
|   <defs | ||||
|      id="defs6860"> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient4453-7-8-6-7-3-5" | ||||
|        id="linearGradient10687-2-5" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        x1="753.02301" | ||||
|        y1="3132.0801" | ||||
|        x2="1146.25" | ||||
|        y2="3132.0801" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient4453-7-8-6-7-3-5"> | ||||
|       <stop | ||||
|          style="stop-color:#aac4dd;stop-opacity:1;" | ||||
|          offset="0" | ||||
|          id="stop4455-61-8-7-1-2-8" /> | ||||
|       <stop | ||||
|          style="stop-color:#c2dbe9;stop-opacity:1;" | ||||
|          offset="1" | ||||
|          id="stop4457-4-1-9-1-12-1" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient4453-7-8-6-7-3-5" | ||||
|        id="linearGradient10685-2-2" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        x1="753.02301" | ||||
|        y1="3132.0801" | ||||
|        x2="1146.25" | ||||
|        y2="3132.0801" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient6749"> | ||||
|       <stop | ||||
|          style="stop-color:#aac4dd;stop-opacity:1;" | ||||
|          offset="0" | ||||
|          id="stop6751" /> | ||||
|       <stop | ||||
|          style="stop-color:#c2dbe9;stop-opacity:1;" | ||||
|          offset="1" | ||||
|          id="stop6753" /> | ||||
|     </linearGradient> | ||||
|     <clipPath | ||||
|        clipPathUnits="userSpaceOnUse" | ||||
|        id="clipPath3387-3-6-4-2-8-4"> | ||||
|       <path | ||||
|          inkscape:connector-curvature="0" | ||||
|          d="m 862.109,3289.75 -109.086,-190.45 69.122,-124.42 164.511,-0.47 c 0,0 111.044,188.28 116.564,197.63 7.66,0 43.03,0 43.03,0 l -67.03,117.71 -217.111,0 z" | ||||
|          id="path3389-2-0-7-7-8-9" /> | ||||
|     </clipPath> | ||||
|     <linearGradient | ||||
|        y2="3132.0801" | ||||
|        x2="1146.25" | ||||
|        y1="3132.0801" | ||||
|        x1="753.02301" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        id="linearGradient4492-8-8" | ||||
|        xlink:href="#linearGradient4453-7-8-6-7-3-5" | ||||
|        inkscape:collect="always" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient6758"> | ||||
|       <stop | ||||
|          style="stop-color:#aac4dd;stop-opacity:1;" | ||||
|          offset="0" | ||||
|          id="stop6760" /> | ||||
|       <stop | ||||
|          style="stop-color:#c2dbe9;stop-opacity:1;" | ||||
|          offset="1" | ||||
|          id="stop6762" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient4453-7-8-6-7-3-5" | ||||
|        id="linearGradient10691-7-8" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        x1="1026.6899" | ||||
|        y1="2937.73" | ||||
|        x2="1463.14" | ||||
|        y2="2937.73" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient6765"> | ||||
|       <stop | ||||
|          style="stop-color:#aac4dd;stop-opacity:1;" | ||||
|          offset="0" | ||||
|          id="stop6767" /> | ||||
|       <stop | ||||
|          style="stop-color:#c2dbe9;stop-opacity:1;" | ||||
|          offset="1" | ||||
|          id="stop6769" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient4453-7-8-6-7-3-5" | ||||
|        id="linearGradient10689-4-2" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        x1="1026.6899" | ||||
|        y1="2937.73" | ||||
|        x2="1463.14" | ||||
|        y2="2937.73" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient6772"> | ||||
|       <stop | ||||
|          style="stop-color:#aac4dd;stop-opacity:1;" | ||||
|          offset="0" | ||||
|          id="stop6774" /> | ||||
|       <stop | ||||
|          style="stop-color:#c2dbe9;stop-opacity:1;" | ||||
|          offset="1" | ||||
|          id="stop6776" /> | ||||
|     </linearGradient> | ||||
|     <clipPath | ||||
|        clipPathUnits="userSpaceOnUse" | ||||
|        id="clipPath3369-1-5-6-1-0-7"> | ||||
|       <path | ||||
|          inkscape:connector-curvature="0" | ||||
|          d="m 1131.64,3128.5 -104.95,-181.12 116.38,-200.42 208.05,0.94 112.02,191.63 -112.08,188.97 -219.42,0 z" | ||||
|          id="path3371-89-4-1-6-0-1" /> | ||||
|     </clipPath> | ||||
|     <linearGradient | ||||
|        y2="2937.73" | ||||
|        x2="1463.14" | ||||
|        y1="2937.73" | ||||
|        x1="1026.6899" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        id="linearGradient4498-5-7" | ||||
|        xlink:href="#linearGradient4453-7-8-6-7-3-5" | ||||
|        inkscape:collect="always" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient6781"> | ||||
|       <stop | ||||
|          style="stop-color:#aac4dd;stop-opacity:1;" | ||||
|          offset="0" | ||||
|          id="stop6783" /> | ||||
|       <stop | ||||
|          style="stop-color:#c2dbe9;stop-opacity:1;" | ||||
|          offset="1" | ||||
|          id="stop6785" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient4459-1-2-8-9-9-5" | ||||
|        id="linearGradient10695-9-9" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        x1="646.55499" | ||||
|        y1="2736.25" | ||||
|        x2="1088.27" | ||||
|        y2="2736.25" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient4459-1-2-8-9-9-5"> | ||||
|       <stop | ||||
|          id="stop4461-2-1-5-2-5-0" | ||||
|          offset="0" | ||||
|          style="stop-color:#839bc2;stop-opacity:1;" /> | ||||
|       <stop | ||||
|          id="stop4463-3-2-8-7-30-3" | ||||
|          offset="1" | ||||
|          style="stop-color:#9fb6d4;stop-opacity:1;" /> | ||||
|     </linearGradient> | ||||
|     <linearGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#linearGradient4459-1-2-8-9-9-5" | ||||
|        id="linearGradient10693-9-4" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        x1="646.55499" | ||||
|        y1="2736.25" | ||||
|        x2="1088.27" | ||||
|        y2="2736.25" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient6792"> | ||||
|       <stop | ||||
|          id="stop6794" | ||||
|          offset="0" | ||||
|          style="stop-color:#839bc2;stop-opacity:1;" /> | ||||
|       <stop | ||||
|          id="stop6796" | ||||
|          offset="1" | ||||
|          style="stop-color:#9fb6d4;stop-opacity:1;" /> | ||||
|     </linearGradient> | ||||
|     <clipPath | ||||
|        clipPathUnits="userSpaceOnUse" | ||||
|        id="clipPath3351-4-7-3-5-95-0"> | ||||
|       <path | ||||
|          inkscape:connector-curvature="0" | ||||
|          d="m 757.242,2926.25 -110.687,-189.11 110.656,-190.89 219.437,0 111.622,189.1 -111.59,190.9 -219.438,0 z" | ||||
|          id="path3353-1-9-3-4-1-1" /> | ||||
|     </clipPath> | ||||
|     <linearGradient | ||||
|        y2="2736.25" | ||||
|        x2="1088.27" | ||||
|        y1="2736.25" | ||||
|        x1="646.55499" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        id="linearGradient4510-1-5" | ||||
|        xlink:href="#linearGradient4459-1-2-8-9-9-5" | ||||
|        inkscape:collect="always" /> | ||||
|     <linearGradient | ||||
|        id="linearGradient6801"> | ||||
|       <stop | ||||
|          id="stop6803" | ||||
|          offset="0" | ||||
|          style="stop-color:#839bc2;stop-opacity:1;" /> | ||||
|       <stop | ||||
|          id="stop6805" | ||||
|          offset="1" | ||||
|          style="stop-color:#9fb6d4;stop-opacity:1;" /> | ||||
|     </linearGradient> | ||||
|     <radialGradient | ||||
|        inkscape:collect="always" | ||||
|        xlink:href="#radialGradient3327-8-4-8-0-2-4" | ||||
|        id="radialGradient10699-1-3" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        cx="997.46997" | ||||
|        cy="2896.25" | ||||
|        fx="997.46997" | ||||
|        fy="2896.25" | ||||
|        r="583.73999" /> | ||||
|     <radialGradient | ||||
|        fx="0" | ||||
|        fy="0" | ||||
|        cx="0" | ||||
|        cy="0" | ||||
|        r="1" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(58.375,0,0,-58.375,99.75,289.625)" | ||||
|        spreadMethod="pad" | ||||
|        id="radialGradient3327-8-4-8-0-2-4"> | ||||
|       <stop | ||||
|          style="stop-opacity:1;stop-color:#aeaeb3" | ||||
|          offset="0" | ||||
|          id="stop3329-7-0-1-0-33-2" /> | ||||
|       <stop | ||||
|          style="stop-opacity:1;stop-color:#ffffff" | ||||
|          offset="0.949438" | ||||
|          id="stop3331-4-3-0-0-97-3" /> | ||||
|       <stop | ||||
|          style="stop-opacity:1;stop-color:#ffffff" | ||||
|          offset="1" | ||||
|          id="stop3333-2-4-9-7-2-2" /> | ||||
|     </radialGradient> | ||||
|     <radialGradient | ||||
|        r="583.73999" | ||||
|        fy="2896.25" | ||||
|        fx="997.46997" | ||||
|        cy="2896.25" | ||||
|        cx="997.46997" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        id="radialGradient13050" | ||||
|        xlink:href="#radialGradient3327-8-4-8-0-2-4" | ||||
|        inkscape:collect="always" /> | ||||
|     <radialGradient | ||||
|        fx="0" | ||||
|        fy="0" | ||||
|        cx="0" | ||||
|        cy="0" | ||||
|        r="1" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(58.375,0,0,-58.375,99.75,289.625)" | ||||
|        spreadMethod="pad" | ||||
|        id="radialGradient6813"> | ||||
|       <stop | ||||
|          style="stop-opacity:1;stop-color:#aeaeb3" | ||||
|          offset="0" | ||||
|          id="stop6815" /> | ||||
|       <stop | ||||
|          style="stop-opacity:1;stop-color:#ffffff" | ||||
|          offset="0.949438" | ||||
|          id="stop6817" /> | ||||
|       <stop | ||||
|          style="stop-opacity:1;stop-color:#ffffff" | ||||
|          offset="1" | ||||
|          id="stop6819" /> | ||||
|     </radialGradient> | ||||
|     <clipPath | ||||
|        clipPathUnits="userSpaceOnUse" | ||||
|        id="clipPath3323-7-2-4-5-3-4"> | ||||
|       <path | ||||
|          inkscape:connector-curvature="0" | ||||
|          d="m 997.469,2312.51 c -322.379,0 -583.739,261.36 -583.739,583.74 0,322.38 261.36,583.74 583.739,583.74 322.381,0 583.741,-261.36 583.741,-583.74 0,-322.38 -261.36,-583.74 -583.741,-583.74" | ||||
|          id="path3325-9-2-9-5-04-9" /> | ||||
|     </clipPath> | ||||
|     <radialGradient | ||||
|        r="583.73999" | ||||
|        fy="2896.25" | ||||
|        fx="997.46997" | ||||
|        cy="2896.25" | ||||
|        cx="997.46997" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        id="radialGradient4516-8-2" | ||||
|        xlink:href="#radialGradient3327-8-4-8-0-2-4" | ||||
|        inkscape:collect="always" /> | ||||
|     <radialGradient | ||||
|        fx="0" | ||||
|        fy="0" | ||||
|        cx="0" | ||||
|        cy="0" | ||||
|        r="1" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        gradientTransform="matrix(58.375,0,0,-58.375,99.75,289.625)" | ||||
|        spreadMethod="pad" | ||||
|        id="radialGradient6824"> | ||||
|       <stop | ||||
|          style="stop-opacity:1;stop-color:#aeaeb3" | ||||
|          offset="0" | ||||
|          id="stop6826" /> | ||||
|       <stop | ||||
|          style="stop-opacity:1;stop-color:#ffffff" | ||||
|          offset="0.949438" | ||||
|          id="stop6828" /> | ||||
|       <stop | ||||
|          style="stop-opacity:1;stop-color:#ffffff" | ||||
|          offset="1" | ||||
|          id="stop6830" /> | ||||
|     </radialGradient> | ||||
|     <radialGradient | ||||
|        r="583.73999" | ||||
|        fy="2896.25" | ||||
|        fx="997.46997" | ||||
|        cy="2896.25" | ||||
|        cx="997.46997" | ||||
|        gradientUnits="userSpaceOnUse" | ||||
|        id="radialGradient6856" | ||||
|        xlink:href="#radialGradient3327-8-4-8-0-2-4" | ||||
|        inkscape:collect="always" /> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0.0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1.4" | ||||
|      inkscape:cx="234.05635" | ||||
|      inkscape:cy="581.46313" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      inkscape:window-width="1680" | ||||
|      inkscape:window-height="982" | ||||
|      inkscape:window-x="-8" | ||||
|      inkscape:window-y="-8" | ||||
|      inkscape:window-maximized="1"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid3066" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata6863"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title /> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1"> | ||||
|     <g | ||||
|        id="g3319-1-2-5-1-4-4" | ||||
|        transform="matrix(0.10419818,0,0,-0.10419818,137.10955,897.00327)" | ||||
|        style="fill:url(#radialGradient10699-1-3);fill-opacity:1" | ||||
|        inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png" | ||||
|        inkscape:export-xdpi="63.625523" | ||||
|        inkscape:export-ydpi="63.625523"> | ||||
|       <g | ||||
|          clip-path="url(#clipPath3323-7-2-4-5-3-4)" | ||||
|          id="g3321-9-2-7-4-3-9" | ||||
|          style="fill:url(#radialGradient6856);fill-opacity:1"> | ||||
|         <path | ||||
|            id="path3335-8-7-3-8-92-0" | ||||
|            style="fill:url(#radialGradient4516-8-2);fill-opacity:1;fill-rule:nonzero;stroke:none" | ||||
|            d="m 997.469,2312.51 c -322.379,0 -583.739,261.36 -583.739,583.74 0,322.38 261.36,583.74 583.739,583.74 322.381,0 583.741,-261.36 583.741,-583.74 0,-322.38 -261.36,-583.74 -583.741,-583.74" | ||||
|            inkscape:connector-curvature="0" /> | ||||
|       </g> | ||||
|     </g> | ||||
|     <g | ||||
|        id="g3347-6-8-3-7-4-4" | ||||
|        transform="matrix(0.125,0,0,-0.125,112.08304,959.82207)" | ||||
|        style="fill:url(#linearGradient10695-9-9);fill-opacity:1" | ||||
|        inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png" | ||||
|        inkscape:export-xdpi="63.625523" | ||||
|        inkscape:export-ydpi="63.625523"> | ||||
|       <g | ||||
|          clip-path="url(#clipPath3351-4-7-3-5-95-0)" | ||||
|          id="g3349-5-5-4-7-9-4" | ||||
|          style="fill:url(#linearGradient10693-9-4);fill-opacity:1"> | ||||
|         <path | ||||
|            id="path3361-0-8-2-9-0-9" | ||||
|            style="fill:url(#linearGradient4510-1-5);fill-opacity:1;fill-rule:nonzero;stroke:none" | ||||
|            d="m 757.242,2926.25 -110.687,-189.11 110.656,-190.89 219.437,0 111.622,189.1 -111.59,190.9 -219.438,0" | ||||
|            inkscape:connector-curvature="0" /> | ||||
|       </g> | ||||
|     </g> | ||||
|     <path | ||||
|        id="path3363-6-9-0-1-5-8" | ||||
|        style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" | ||||
|        d="m 194.34816,617.68335 13.106,-22.3925 25.99649,0 13.21487,22.60874 -13.21487,22.39125 -25.99649,0 -13.106,-22.60749 z m 40.53761,-24.8925 -28.86524,0 -0.72412,1.23749 -13.106,22.39251 -0.73575,1.25625 0.73087,1.26 13.106,22.60744 0.72263,1.24634 28.86374,0 0.72512,-1.22884 13.215,-22.39119 0.74625,-1.265 -0.74,-1.26751 -13.21537,-22.60875 -0.72313,-1.23874" | ||||
|        inkscape:connector-curvature="0" | ||||
|        inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png" | ||||
|        inkscape:export-xdpi="63.625523" | ||||
|        inkscape:export-ydpi="63.625523" /> | ||||
|     <g | ||||
|        id="g3365-0-4-1-9-7-5" | ||||
|        transform="matrix(0.125,0,0,-0.125,112.08304,959.82207)" | ||||
|        style="fill:url(#linearGradient10691-7-8);fill-opacity:1" | ||||
|        inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png" | ||||
|        inkscape:export-xdpi="63.625523" | ||||
|        inkscape:export-ydpi="63.625523"> | ||||
|       <g | ||||
|          clip-path="url(#clipPath3369-1-5-6-1-0-7)" | ||||
|          id="g3367-2-4-2-8-4-3" | ||||
|          style="fill:url(#linearGradient10689-4-2);fill-opacity:1"> | ||||
|         <path | ||||
|            id="path3379-4-6-7-6-7-2" | ||||
|            style="fill:url(#linearGradient4498-5-7);fill-opacity:1;fill-rule:nonzero;stroke:none" | ||||
|            d="m 1131.64,3128.5 -104.95,-181.12 116.38,-200.42 208.05,0.94 112.02,191.63 -112.08,188.97 -219.42,0" | ||||
|            inkscape:connector-curvature="0" /> | ||||
|       </g> | ||||
|     </g> | ||||
|     <path | ||||
|        id="path3381-6-8-0-0-66-3" | ||||
|        style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" | ||||
|        d="m 241.86427,591.39959 12.3925,-21.38999 25.99625,0 13.27125,22.37625 -13.27125,22.7025 -24.56875,0.11 -13.82,-23.79876 z m 39.8125,-23.88999 -28.86125,0 -0.7225,1.24625 -12.3925,21.39 -0.72625,1.255 0.7275,1.25374 13.82,23.79876 0.7275,1.25125 1.44625,-0.006 24.56875,-0.11 1.4275,-0.006 0.72,-1.2325 13.27125,-22.7025 0.7425,-1.27 -0.75125,-1.26625 -13.27125,-22.37625 -0.72625,-1.225" | ||||
|        inkscape:connector-curvature="0" | ||||
|        inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png" | ||||
|        inkscape:export-xdpi="63.625523" | ||||
|        inkscape:export-ydpi="63.625523" /> | ||||
|     <g | ||||
|        id="g3383-5-5-2-2-3-0" | ||||
|        transform="matrix(0.125,0,0,-0.125,112.08304,959.82207)" | ||||
|        style="fill:url(#linearGradient10687-2-5);fill-opacity:1" | ||||
|        inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png" | ||||
|        inkscape:export-xdpi="63.625523" | ||||
|        inkscape:export-ydpi="63.625523"> | ||||
|       <g | ||||
|          clip-path="url(#clipPath3387-3-6-4-2-8-4)" | ||||
|          id="g3385-0-6-4-8-0-1" | ||||
|          style="fill:url(#linearGradient10685-2-2);fill-opacity:1"> | ||||
|         <path | ||||
|            id="path3397-9-6-1-6-9-7" | ||||
|            style="fill:url(#linearGradient4492-8-8);fill-opacity:1;fill-rule:nonzero;stroke:none" | ||||
|            d="m 862.109,3289.75 -109.086,-190.45 69.122,-124.42 164.511,-0.47 c 0,0 111.044,188.28 116.564,197.63 7.66,0 43.03,0 43.03,0 l -67.03,117.71 -217.111,0" | ||||
|            inkscape:connector-curvature="0" /> | ||||
|       </g> | ||||
|     </g> | ||||
|     <path | ||||
|        id="path3399-6-7-3-2-0-1" | ||||
|        style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" | ||||
|        d="m 207.64603,572.41959 12.92424,-22.56624 25.68775,0 6.95625,12.21375 -3.94375,0 -14.56837,24.7025 -19.11525,-0.055 -7.94087,-14.295 z m 40.06574,-25.06624 -28.59012,0 -0.71975,1.2575 -12.92537,22.56625 -0.70112,1.22375 0.68512,1.23249 7.94137,14.295 0.71087,1.2825 1.46638,0.004 19.11525,0.055 1.43212,0.004 0.729,-1.23375 13.84375,-23.47249 6.81625,0 -2.12875,-3.7375 -6.95625,-12.21375 -0.71875,-1.2625" | ||||
|        inkscape:connector-curvature="0" | ||||
|        inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png" | ||||
|        inkscape:export-xdpi="63.625523" | ||||
|        inkscape:export-ydpi="63.625523" /> | ||||
|     <g | ||||
|        transform="matrix(1.25,0,0,-1.25,105.02062,972.84257)" | ||||
|        id="g3465-0-8-9" | ||||
|        inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png" | ||||
|        inkscape:export-xdpi="63.625523" | ||||
|        inkscape:export-ydpi="63.625523"> | ||||
|       <text | ||||
|          id="text3467-9-0-8" | ||||
|          transform="matrix(1,0,-0.17627963,-1,0,0)" | ||||
|          x="116.98372" | ||||
|          y="-267.77499" | ||||
|          style="font-size:11.81779194px"> | ||||
|         <tspan | ||||
|            sodipodi:role="line" | ||||
|            style="font-size:46.39999771px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#49608a;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Denmark;-inkscape-font-specification:Denmark" | ||||
|            x="116.98372" | ||||
|            y="-267.77499" | ||||
|            id="tspan13239">UTILITY</tspan> | ||||
|         <tspan | ||||
|            sodipodi:role="line" | ||||
|            style="font-size:46.39999771px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#49608a;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Denmark;-inkscape-font-specification:Denmark" | ||||
|            x="116.98372" | ||||
|            y="-209.77499" | ||||
|            id="tspan11278-3" /> | ||||
|       </text> | ||||
|       <text | ||||
|          id="text3471-0-51-2" | ||||
|          transform="matrix(0.99235617,0,-0.17763746,-1.0077027,0,0)" | ||||
|          style="font-size:38.40000153px" | ||||
|          x="112.74373" | ||||
|          y="-306.75479"> | ||||
|         <tspan | ||||
|            id="tspan3473-6-0-9" | ||||
|            sodipodi:role="line" | ||||
|            style="font-size:38.40000153px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#49608a;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Denmark;-inkscape-font-specification:Denmark" | ||||
|            x="112.74373" | ||||
|            y="-306.75479">boost</tspan> | ||||
|       </text> | ||||
|     </g> | ||||
|     <path | ||||
|        style="fill:#ffffff;fill-opacity:1;stroke:none" | ||||
|        d="m 201.43967,613.81579 4.64114,4.2175 3.3738,-3.71306 -0.92817,-0.84354 1.68708,-1.85636 20.53445,20.81026 4.2175,-4.64111 -22.22144,-18.95384 c 0,0 1.69594,-1.83698 2.53062,-2.78454 2.53905,-2.76559 5.98925,-4.72587 5.98925,-4.72587 0,0 -6.03647,0.58224 -8.76507,2.21476 -0.84428,0.92751 -6.75676,7.40649 -6.75676,7.40649 l -0.92819,-0.84355 -3.37382,3.71308" | ||||
|        id="path13283" | ||||
|        inkscape:connector-curvature="0" | ||||
|        sodipodi:nodetypes="cccccccccccccc" /> | ||||
|     <g | ||||
|        id="g3086" | ||||
|        transform="matrix(0.99872217,-0.05053738,0.05053738,0.99872217,-31.539183,11.181538)"> | ||||
|       <path | ||||
|          sodipodi:nodetypes="ccccccccc" | ||||
|          inkscape:connector-curvature="0" | ||||
|          id="path13243" | ||||
|          d="m 227.74101,611.16418 -15.09943,12.783 2.55659,3.01989 15.09944,-12.78302 c 3.56324,2.16769 7.58975,-1.2411 7.0464,-5.96538 l -4.02652,3.40879 -2.55659,-3.01989 4.02652,-3.40879 c -3.56324,-2.16769 -8.59639,2.0933 -7.04641,5.9654 z" | ||||
|          style="fill:#ffffff;fill-opacity:1;stroke:none" /> | ||||
|       <path | ||||
|          sodipodi:nodetypes="ccccccccc" | ||||
|          inkscape:connector-curvature="0" | ||||
|          id="path13243-1" | ||||
|          d="m 215.25729,626.9851 15.08951,-12.7947 -2.55893,-3.01791 -15.08952,12.79471 c -3.56492,-2.16491 -7.58878,1.24699 -7.04177,5.97085 l 4.02388,-3.41192 2.55892,3.01791 -4.02387,3.41192 c 3.56491,2.16492 8.59476,-2.09997 7.04178,-5.97086 z" | ||||
|          style="fill:#ffffff;fill-opacity:1;stroke:none" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| Before Width: | Height: | Size: 20 KiB | 
							
								
								
									
										234
									
								
								doc/main.qbk
									
									
									
									
									
								
							
							
						
						
									
										234
									
								
								doc/main.qbk
									
									
									
									
									
								
							| @@ -1,234 +0,0 @@ | ||||
| [/ | ||||
|     Copyright (c) 2021, Alan Freitas | ||||
|  | ||||
|     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) | ||||
|  | ||||
|     Official repository: https://github.com/boostorg/utility | ||||
| ] | ||||
|  | ||||
| [/############################################# | ||||
|                   DOCUMENT INFO | ||||
| ###############################################] | ||||
|  | ||||
| [library Boost.Utility | ||||
|     [id utility] | ||||
|     [quickbook 1.6] | ||||
|     [copyright 2001 Beman Dawes] | ||||
|     [purpose Utility Library] | ||||
|     [license | ||||
|         Distributed under the Boost Software License, Version 1.0. | ||||
|         (See accompanying file LICENSE_1_0.txt or copy at | ||||
|         [@http://www.boost.org/LICENSE_1_0.txt]) | ||||
|     ] | ||||
|     [authors [Dawes, Beman]] | ||||
|     [category template] | ||||
|     [category generic] | ||||
| ] | ||||
|  | ||||
| [template mdash[]'''—'''] | ||||
| [template ndash[]'''–'''] | ||||
| [template sect[]'''§'''] | ||||
| [template hellip[]'''…'''] | ||||
|  | ||||
| [template indexterm1[term1]'''<indexterm><primary>'''[term1]'''</primary></indexterm>'''] | ||||
| [template indexterm2[term1 term2]'''<indexterm><primary>'''[term1]'''</primary><secondary>'''[term2]'''</secondary></indexterm>'''] | ||||
|  | ||||
| [template include_file[path][^<'''<ulink url="https://github.com/boostorg/utility/blob/master/include/'''[path]'''">'''[path]'''</ulink>'''>]] | ||||
| [template issue[n]'''<ulink url="https://github.com/boostorg/utility/issues/'''[n]'''">#'''[n]'''</ulink>'''] | ||||
|  | ||||
| [/ Named Requirements ] | ||||
|  | ||||
| [def __Handler__                ['Handler]] | ||||
| [def __Allocator__              [@https://en.cppreference.com/w/cpp/named_req/Allocator ['Allocator]]] | ||||
| [def __CopyAssignable__         [@https://en.cppreference.com/w/cpp/named_req/CopyAssignable ['CopyAssignable]]] | ||||
| [def __CopyConstructible__      [@https://en.cppreference.com/w/cpp/named_req/CopyConstructible ['CopyConstructible]]] | ||||
| [def __Copyable__               [@https://en.cppreference.com/w/cpp/concepts/copyable ['Copyable]]] | ||||
| [def __DefaultConstructible__   [@https://en.cppreference.com/w/cpp/named_req/DefaultConstructible ['DefaultConstructible]]] | ||||
| [def __Hash__                   [@https://en.cppreference.com/w/cpp/named_req/Hash ['Hash]]] | ||||
| [def __InputIterator__          [@https://en.cppreference.com/w/cpp/named_req/InputIterator ['InputIterator]]] | ||||
| [def __MoveAssignable__         [@https://en.cppreference.com/w/cpp/named_req/MoveAssignable ['MoveAssignable]]] | ||||
| [def __MoveConstructible__      [@https://en.cppreference.com/w/cpp/named_req/MoveConstructible ['MoveConstructible]]] | ||||
| [def __RandomAccessIterator__   [@https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator ['RandomAccessIterator]]] | ||||
| [def __Regular__                [@https://en.cppreference.com/w/cpp/concepts/regular ['Regular]]] | ||||
| [def __Swappable__              [@https://en.cppreference.com/w/cpp/named_req/Swappable ['Swappable]]] | ||||
|  | ||||
| [/ Boost types ] | ||||
| [/ (Macros are defined here because these macros are often referenced in other components) ] | ||||
| [/ (operators macros link to the a table of operators because there's no doxygen reference for the operators) ] | ||||
|  | ||||
| [def __BOOST_BINARY__ [link sec:BOOST_BINARY `BOOST_BINARY`]] | ||||
| [def __in_place_factory__ [link sec:in_place_factory `in_place_factory`]] | ||||
|  | ||||
| [def __boost_base_from_member__ [link boost.base_from_member `boost::base_from_member`]] | ||||
| [def __boost_call_traits__ [link boost.call_traits `boost::call_traits`]] | ||||
| [def __boost_result_of__ [link boost.result_of `boost::result_of`]] | ||||
| [def __boost_tr1_result_of__ [link boost.tr1_result_of `boost::tr1_result_of`]] | ||||
| [def __boost_string_view__ [link boost.basic_string_view `boost::string_view`]] | ||||
| [def __boost_basic_string_view__ [link boost.basic_string_view `boost::basic_string_view`]] | ||||
|  | ||||
| [def __additive1__ [link sec:arithmetic `additive1`]] | ||||
| [def __additive2__ [link sec:arithmetic `additive2`]] | ||||
| [def __arithmetic1__ [link sec:arithmetic `arithmetic1`]] | ||||
| [def __arithmetic2__ [link sec:arithmetic `arithmetic2`]] | ||||
| [def __base_from_member__ [link boost.base_from_member `base_from_member`]] | ||||
| [def __basic_string_ref__ [link boost.basic_string_view `basic_string_ref`]] | ||||
| [def __basic_string_view__ [link boost.basic_string_view `basic_string_view`]] | ||||
| [def __bidirectional_iteratable__ [link sec:arithmetic `bidirectional_iteratable`]] | ||||
| [def __bidirectional_iterator_helper__ [link sec:arithmetic `bidirectional_iterator_helper`]] | ||||
| [def __bitwise1__ [link sec:arithmetic `bitwise1`]] | ||||
| [def __bitwise2__ [link sec:arithmetic `bitwise2`]] | ||||
| [def __call_traits__ [link boost.call_traits `call_traits`]] | ||||
| [def __call_traits_T__ [link boost.call_traits `call_traits<T>`]] | ||||
| [def __call_traits_lt__T___ [link boost.call_traits `call_traits<T&>`]] | ||||
| [def __call_traits_lt__T_lb_N_rb__gt___ [link boost.call_traits `call_traits< T[N]>`]] | ||||
| [def __call_traits_lt__const_T_lb_N_rb__gt___ [link boost.call_traits `call_traits< const T[N]>`]] | ||||
| [def __compressed_pair__ [link boost.compressed_pair `compressed_pair`]] | ||||
| [def __decrementable__ [link sec:arithmetic `decrementable`]] | ||||
| [def __dereferenceable__ [link sec:arithmetic `dereferenceable`]] | ||||
| [def __equal_pointees__ [link sec:arithmetic `equal_pointees`]] | ||||
| [def __equal_pointees_t__ [link sec:arithmetic `equal_pointees_t`]] | ||||
| [def __equality_comparable1__ [link sec:arithmetic `equality_comparable1`]] | ||||
| [def __equality_comparable2__ [link sec:arithmetic `equality_comparable2`]] | ||||
| [def __equivalent1__ [link sec:arithmetic `equivalent1`]] | ||||
| [def __equivalent2__ [link sec:arithmetic `equivalent2`]] | ||||
| [def __euclidean_ring_operators1__ [link sec:arithmetic `euclidean_ring_operators1`]] | ||||
| [def __euclidean_ring_operators2__ [link sec:arithmetic `euclidean_ring_operators2`]] | ||||
| [def __field_operators1__ [link sec:arithmetic `field_operators1`]] | ||||
| [def __field_operators2__ [link sec:arithmetic `field_operators2`]] | ||||
| [def __forward_iteratable__ [link sec:arithmetic `forward_iteratable`]] | ||||
| [def __forward_iterator_helper__ [link sec:arithmetic `forward_iterator_helper`]] | ||||
| [def __get__ [link boost.get `get`]] | ||||
| [def __hash_range__ [link boost.hash_range `hash_range`]] | ||||
| [def __hash_value__ [link boost.hash_value `hash_value`]] | ||||
| [def __in_place_factory_base__ [link boost.in_place_factory_base `in_place_factory_base`]] | ||||
| [def __incrementable__ [link sec:arithmetic `incrementable`]] | ||||
| [def __indexable__ [link sec:arithmetic `indexable`]] | ||||
| [def __initialized__ [link boost.initialized `initialized`]] | ||||
| [def __initialized_value__ [link boost.initialized_value `initialized_value`]] | ||||
| [def __initialized_value_t__ [link boost.initialized_value_t `initialized_value_t`]] | ||||
| [def __input_iteratable__ [link sec:arithmetic `input_iteratable`]] | ||||
| [def __input_iterator_helper__ [link sec:arithmetic `input_iterator_helper`]] | ||||
| [def __integer_arithmetic1__ [link sec:arithmetic `integer_arithmetic1`]] | ||||
| [def __integer_arithmetic2__ [link sec:arithmetic `integer_arithmetic2`]] | ||||
| [def __integer_multiplicative1__ [link sec:arithmetic `integer_multiplicative1`]] | ||||
| [def __integer_multiplicative2__ [link sec:arithmetic `integer_multiplicative2`]] | ||||
| [def __is_chained_base__ [link sec:arithmetic `is_chained_base`]] | ||||
| [def __less_pointees__ [link boost.less_pointees `less_pointees`]] | ||||
| [def __less_pointees_t__ [link boost.less_pointees_t `less_pointees_t`]] | ||||
| [def __less_than_comparable1__ [link sec:arithmetic `less_than_comparable1`]] | ||||
| [def __less_than_comparable2__ [link sec:arithmetic `less_than_comparable2`]] | ||||
| [def __multiplicative1__ [link sec:arithmetic `multiplicative1`]] | ||||
| [def __multiplicative2__ [link sec:arithmetic `multiplicative2`]] | ||||
| [def __operator_eq__eq__ [link sec:arithmetic `operator==`]] | ||||
| [def __operator_gt__ [link sec:arithmetic `operator_gt_`]] | ||||
| [def __operator_gt__eq__ [link sec:arithmetic `operator>`]] | ||||
| [def __operator_lt__ [link sec:arithmetic `operator<`]] | ||||
| [def __operator_lt__eq__ [link sec:arithmetic `operator<=`]] | ||||
| [def __operator_lt__lt__ [link sec:arithmetic `operator<<`]] | ||||
| [def __operator_not__eq__ [link sec:arithmetic `operator!=`]] | ||||
| [def __operators2__ [link sec:arithmetic `operators2`]] | ||||
| [def __operators__ [link sec:arithmetic `operators`]] | ||||
| [def __operators_lt_T__ [link sec:arithmetic `operators<T,T>`]] | ||||
| [def __ordered_euclidean_ring_operators1__ [link sec:arithmetic `ordered_euclidean_ring_operators1`]] | ||||
| [def __ordered_euclidean_ring_operators2__ [link sec:arithmetic `ordered_euclidean_ring_operators2`]] | ||||
| [def __ordered_euclidian_ring_operators1__ [link sec:arithmetic `ordered_euclidian_ring_operators1`]] | ||||
| [def __ordered_euclidian_ring_operators2__ [link sec:arithmetic `ordered_euclidian_ring_operators2`]] | ||||
| [def __ordered_field_operators1__ [link sec:arithmetic `ordered_field_operators1`]] | ||||
| [def __ordered_field_operators2__ [link sec:arithmetic `ordered_field_operators2`]] | ||||
| [def __ordered_ring_operators1__ [link sec:arithmetic `ordered_ring_operators1`]] | ||||
| [def __ordered_ring_operators2__ [link sec:arithmetic `ordered_ring_operators2`]] | ||||
| [def __output_iteratable__ [link sec:arithmetic `output_iteratable`]] | ||||
| [def __output_iterator_helper__ [link sec:arithmetic `output_iterator_helper`]] | ||||
| [def __partially_ordered1__ [link sec:arithmetic `partially_ordered1`]] | ||||
| [def __partially_ordered2__ [link sec:arithmetic `partially_ordered2`]] | ||||
| [def __random_access_iteratable__ [link sec:arithmetic `random_access_iteratable`]] | ||||
| [def __random_access_iterator_helper__ [link sec:arithmetic `random_access_iterator_helper`]] | ||||
| [def __result_of__ [link boost.result_of `result_of`]] | ||||
| [def __ring_operators1__ [link sec:arithmetic `ring_operators1`]] | ||||
| [def __ring_operators2__ [link sec:arithmetic `ring_operators2`]] | ||||
| [def __shiftable1__ [link sec:arithmetic `shiftable1`]] | ||||
| [def __shiftable2__ [link sec:arithmetic `shiftable2`]] | ||||
| [def __string_ref__ [link boost.basic_string_view `string_ref`]] | ||||
| [def __string_view__ [link boost.basic_string_view `string_view`]] | ||||
| [def __swap__ [link sec:arithmetic `swap`]] | ||||
| [def __totally_ordered1__ [link sec:arithmetic `totally_ordered1`]] | ||||
| [def __totally_ordered2__ [link sec:arithmetic `totally_ordered2`]] | ||||
| [def __tr1_result_of__ [link boost.tr1_result_of `tr1_result_of`]] | ||||
| [def __typed_in_place_factory_base__ [link boost.typed_in_place_factory_base `typed_in_place_factory_base`]] | ||||
| [def __u16string_ref__ [link boost.basic_string_view `u16string_ref`]] | ||||
| [def __u16string_view__ [link boost.basic_string_view `u16string_view`]] | ||||
| [def __u32string_ref__ [link boost.basic_string_view `u32string_ref`]] | ||||
| [def __u32string_view__ [link boost.basic_string_view `u32string_view`]] | ||||
| [def __unit_steppable__ [link sec:arithmetic `unit_steppable`]] | ||||
| [def __value_initialized__ [link boost.value_initialized `value_initialized`]] | ||||
| [def __wstring_ref__ [link boost.basic_string_view `wstring_ref`]] | ||||
| [def __wstring_view__ [link boost.basic_string_view `wstring_view`]] | ||||
|  | ||||
| [/ std:: types ] | ||||
|  | ||||
| [def __assert__       [@https://en.cppreference.com/w/cpp/error/assert `assert`]] | ||||
| [def __decltype__       [@https://en.cppreference.com/w/cpp/language/decltype `decltype`]] | ||||
| [def __initializer_list__       [@https://en.cppreference.com/w/cpp/utility/initializer_list `std::initializer_list`]] | ||||
| [def __nullptr__       [@https://en.cppreference.com/w/cpp/language/nullptr `nullptr`]] | ||||
| [def __std_addressof__              [@https://en.cppreference.com/w/cpp/memory/addressof `std::addressof`]] | ||||
| [def __std_array__              [@https://en.cppreference.com/w/cpp/container/array `std::array`]] | ||||
| [def __std_basic_string__             [@https://en.cppreference.com/w/cpp/string/basic_string `std::basic_string`]] | ||||
| [def __std_basic_string_view__                   [@https://en.cppreference.com/w/cpp/string/basic_string_view `std::basic_string_view`]] | ||||
| [def __std_binder1st__                [@https://en.cppreference.com/w/cpp/utility/functional/binder12 `std::binder1st`]] | ||||
| [def __std_complex__            [@https://en.cppreference.com/w/cpp/numeric/complex `std::complex`]] | ||||
| [def __std_declval__            [@https://en.cppreference.com/w/cpp/utility/declval `std::declval`]] | ||||
| [def __std_enable_if__            [@https://en.cppreference.com/w/cpp/types/enable_if `std::enable_if`]] | ||||
| [def __std_enable_if_t__            [@https://en.cppreference.com/w/cpp/types/enable_if `std::enable_if_t`]] | ||||
| [def __std_fill__                     [@https://en.cppreference.com/w/cpp/algorithm/fill `std::fill`]] | ||||
| [def __std_hash__               [@https://en.cppreference.com/w/cpp/utility/hash `std::hash`]] | ||||
| [def __std_initializer_list__       [@https://en.cppreference.com/w/cpp/utility/initializer_list `std::initializer_list`]] | ||||
| [def __std_is_nothrow_constructible__ [@https://en.cppreference.com/w/cpp/types/is_constructible `std::is_nothrow_constructible`]] | ||||
| [def __std_make_pair__                [@https://en.cppreference.com/w/cpp/utility/pair/make_pair `std::make_pair`]] | ||||
| [def __std_memory_resource__    [@https://en.cppreference.com/w/cpp/memory/memory_resource `std::pmr::memory_resource`]] | ||||
| [def __std_memset__                   [@https://en.cppreference.com/w/cpp/string/byte/memset `std::memset`]] | ||||
| [def __std_next__                   [@https://en.cppreference.com/w/cpp/iterator/next `std::next`]] | ||||
| [def __std_nullptr_t__                [@https://en.cppreference.com/w/cpp/types/nullptr_t `std::nullptr_t`]] | ||||
| [def __std_ostream__                  [@https://en.cppreference.com/w/cpp/io/basic_ostream `std::ostream`]] | ||||
| [def __std_ostream__            [@https://en.cppreference.com/w/cpp/io/basic_ostream `__std_ostream__`]] | ||||
| [def __std_pair__                     [@https://en.cppreference.com/w/cpp/utility/pair `std::pair`]] | ||||
| [def __std_polymorphic_allocator__ [@https://en.cppreference.com/w/cpp/memory/polymorphic_allocator `std::pmr::polymorphic_allocator`]] | ||||
| [def __std_prev__                   [@https://en.cppreference.com/w/cpp/iterator/prev `std::prev`]] | ||||
| [def __std_ptrdiff_t__                [@https://en.cppreference.com/w/cpp/types/ptrdiff_t `std::ptrdiff_t`]] | ||||
| [def __std_remove__                [@https://en.cppreference.com/w/cpp/algorithm/remove `std::remove`]] | ||||
| [def __std_result_of__                [@https://en.cppreference.com/w/cpp/types/result_of `std::result_of`]] | ||||
| [def __std_sort__          [@https://en.cppreference.com/w/cpp/algorithm/sort `std::sort`]] | ||||
| [def __std_streambuf__          [@https://en.cppreference.com/w/cpp/header/streambuf `std::streambuf`]] | ||||
| [def __std_string__                   [@https://en.cppreference.com/w/cpp/string/basic_string `std::string`]] | ||||
| [def __std_string_view__                   [@https://en.cppreference.com/w/cpp/string/basic_string_view `std::string_view`]] | ||||
| [def __std_unary_function__      [@https://en.cppreference.com/w/cpp/utility/functional/unary_function `std::unary_function`]] | ||||
| [def __std_unordered_map__      [@https://en.cppreference.com/w/cpp/container/unordered_map `std::unordered_map`]] | ||||
| [def __std_uses_allocator__     [@https://en.cppreference.com/w/cpp/memory/uses_allocator `std::uses_allocator`]] | ||||
| [def __std_vector__             [@https://en.cppreference.com/w/cpp/container/vector `std::vector`]] | ||||
|  | ||||
| [/ Dingbats ] | ||||
|  | ||||
| [def __good__ [role green \u2714]] | ||||
| [def __bad__  [role red   \u2718]] | ||||
|  | ||||
| [/-----------------------------------------------------------------------------] | ||||
|  | ||||
| [include overview.qbk] | ||||
|  | ||||
| [include utilities.qbk] | ||||
|  | ||||
| [include other.qbk] | ||||
|  | ||||
| [#sec:reference] | ||||
| [section:ref Quick Reference] | ||||
|  | ||||
| [/ Reference table ] | ||||
| [xinclude quickref.xml] | ||||
|  | ||||
| [/ Generated reference files ] | ||||
| [/ [include reference.qbk] ] | ||||
|  | ||||
| [/ Generated index ] | ||||
| [/ [xinclude index.xml] ] | ||||
|  | ||||
| [endsect] | ||||
							
								
								
									
										2008
									
								
								doc/operators.qbk
									
									
									
									
									
								
							
							
						
						
									
										2008
									
								
								doc/operators.qbk
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,29 +0,0 @@ | ||||
| [/ | ||||
|     Copyright (c) 2021 Alan de Freitas (alandefreitas@gmail.com) | ||||
|  | ||||
|     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) | ||||
|  | ||||
|     Official repository: https://github.com/boostorg/utility | ||||
| ] | ||||
|  | ||||
| [section:utilities More Utilities] | ||||
|  | ||||
| Some utilities have been moved from Boost.Utilities to more appropriate Boost libraries: | ||||
|  | ||||
| # Moved to [@boost:/libs/core/index.html Boost.Core] | ||||
|     # [@boost:/libs/core/doc/html/core/addressof.html addressof] | ||||
|     # [@boost:/libs/core/doc/html/core/checked_delete.html checked_delete] | ||||
|     # [@boost:/libs/core/doc/html/core/enable_if.html enable_if] | ||||
|     # [@boost:/libs/core/doc/html/core/noncopyable.html noncopyable] | ||||
| # Moved to [@boost:/libs/type_traits/index.html Boost.TypeTraits] | ||||
|     # [@boost:/libs/type_traits/doc/html/boost_typetraits/reference/declval.html declval] | ||||
| # Moved to [@boost:/libs/iterator/index.html Boost.Iterator] | ||||
|     # [@boost:/libs/iterator/doc/generator_iterator.htm generator iterator adaptors] | ||||
|     # [@boost:/libs/iterator/doc/html/iterator/algorithms/next_prior.html next/prior] | ||||
| # Moved to [@boost:/libs/io/index.html Boost.IO] | ||||
|     # [@boost:/libs/io/doc/html/io.html ostream_string] | ||||
| # Moved to [@boost:/libs/throw_exception/index.html Boost.ThrowException] | ||||
|     # [@boost:/libs/throw_exception/doc/html/throw_exception.html#using_boost_throw_exception throw_exception] | ||||
|  | ||||
| [endsect] | ||||
| @@ -1,46 +0,0 @@ | ||||
| [/ | ||||
|     Copyright (c) 2021 Alan de Freitas (alandefreitas@gmail.com) | ||||
|  | ||||
|     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) | ||||
|  | ||||
|     Official repository: https://github.com/boostorg/utility | ||||
| ] | ||||
|  | ||||
| [section Overview] | ||||
| [block'''<?dbhtml stop-chunking?>'''] | ||||
|  | ||||
| Boost.Utility is a collection of small, useful, and general-purpose components for language support. | ||||
|  | ||||
| Over time, | ||||
|  | ||||
| * several components have been moved to more appropriate Boost libraries and | ||||
| * many of these components had variants accepted into the C++ standard | ||||
|  | ||||
| When the component has moved to another Boost library, Boost.Utility headers still lead to the appropriate headers | ||||
| in other libraries. | ||||
|  | ||||
| [table:id Components | ||||
|     [[Boost.Utility] [Moved to Boost] [C++ Standard variant]] | ||||
|     [[[@boost:/libs/core/doc/html/core/addressof.html `addressof`]] [[@boost:/libs/core/index.html Boost.Core]] [C++11 __std_addressof__]] | ||||
|     [[__base_from_member__]      [] []] | ||||
|     [[__BOOST_BINARY__] [] [C++14 [@https://en.cppreference.com/w/cpp/language/integer_literal Binary integer literal]]] | ||||
|     [[__call_traits__]      [] []] | ||||
|     [[[@boost:/libs/core/doc/html/core/checked_delete.html `checked_delete`]] [[@boost:/libs/core/index.html Boost.Core]] []] | ||||
|     [[__compressed_pair__]      [] []] | ||||
|     [[[@boost:/libs/type_traits/doc/html/boost_typetraits/reference/declval.html `declval`]] [[@boost:/libs/type_traits/index.html Boost.TypeTraits]] [C++11 __std_declval__]] | ||||
|     [[[@boost:/libs/core/doc/html/core/enable_if.html `enable_if`]] [[@boost:/libs/core/index.html Boost.Core]] [C++11 __std_enable_if__]] | ||||
|     [[[@boost:/libs/iterator/doc/generator_iterator.htm generator iterator adaptors]] [[@boost:/libs/iterator/index.html Boost.Iterator]] []] | ||||
|     [[__in_place_factory__]      [] []] | ||||
|     [[[@boost:/libs/iterator/index.html `iterator_adaptors`]]      [[@boost:/libs/iterator/index.html Boost.Iterator]] []] | ||||
|     [[[@boost:/libs/iterator/doc/html/iterator/algorithms/next_prior.html `next` / `prior`]] [[@boost:/libs/iterator/index.html Boost.Iterator]] [C++11 __std_next__ / __std_prev__]] | ||||
|     [[[@boost:/libs/core/doc/html/core/noncopyable.html `noncopyable`]] [[@boost:/libs/core/index.html Boost.Core]] []] | ||||
|     [[[link sec:operators `operators`]]      [] []] | ||||
|     [[[@boost:/libs/io/doc/html/io.html `ostream_string`]] [[@boost:/libs/io/index.html Boost.IO]] []] | ||||
|     [[__result_of__]      [] [C++11 __std_result_of__]] | ||||
|     [[__string_view__]      [] [C++17 __std_string_view__]] | ||||
|     [[[@boost:/libs/throw_exception/doc/html/throw_exception.html#using_boost_throw_exception `throw_exception`]] [[@boost:/libs/throw_exception/index.html Boost.ThrowException]] []] | ||||
|     [[[link sec:value_init `value_init`]]      [] [C++11 [@https://en.cppreference.com/w/cpp/language/list_initialization List initialization]]] | ||||
| ] | ||||
|  | ||||
| [endsect] | ||||
							
								
								
									
										497
									
								
								doc/quickref.xml
									
									
									
									
									
								
							
							
						
						
									
										497
									
								
								doc/quickref.xml
									
									
									
									
									
								
							| @@ -1,497 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "../../../tools/boostbook/dtd/boostbook.dtd"> | ||||
|  | ||||
| <!-- | ||||
|     Copyright (c) 2021, Alan Freitas | ||||
|  | ||||
|     Distributed under the Boost Software License, Version 1.0. | ||||
|  | ||||
|     See accompanying file LICENSE_1_0.txt | ||||
|     or copy at http://boost.org/LICENSE_1_0.txt | ||||
| --> | ||||
|  | ||||
| <!-- See also https://tdg.docbook.org/tdg/5.1/ --> | ||||
|  | ||||
| <!-- Doxygen reference --> | ||||
| <informaltable frame="all"> | ||||
|     <tgroup cols="4"> | ||||
|         <colspec colname="a"/> | ||||
|         <colspec colname="b"/> | ||||
|         <colspec colname="c"/> | ||||
|         <colspec colname="d"/> | ||||
|  | ||||
|         <thead> | ||||
|             <row> | ||||
|                 <entry valign="center" namest="a" nameend="a"> | ||||
|                     <bridgehead renderas="sect2">Base from Member</bridgehead> | ||||
|                 </entry> | ||||
|                 <entry valign="center" namest="b" nameend="b"> | ||||
|                     <bridgehead renderas="sect2">Call Traits</bridgehead> | ||||
|                 </entry> | ||||
|                 <entry valign="center" namest="c" nameend="c"> | ||||
|                     <bridgehead renderas="sect2">Compressed Pair</bridgehead> | ||||
|                 </entry> | ||||
|                 <entry valign="center" namest="d" nameend="d"> | ||||
|                     <bridgehead renderas="sect2">In-place Factory</bridgehead> | ||||
|                 </entry> | ||||
|             </row> | ||||
|         </thead> | ||||
|         <tbody> | ||||
|             <row> | ||||
|                 <!-- base_from_member --> | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Classes</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="boost.base_from_member">base_from_member</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <!-- call_traits --> | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Type Traits</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="boost.call_traits">call_traits</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.call_traits">call_traits<T&></link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.call_traits">call_traits<T[N]> | ||||
|                             </link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.call_traits">call_traits<const | ||||
|                                 T[N]> | ||||
|                             </link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <!-- compressed_pair --> | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Classes</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="boost.compressed_pair">compressed_pair</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|  | ||||
|                     <bridgehead renderas="sect3">Functions</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="header.boost.detail.compressed_pair_hpp">swap</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <!-- in_place_factory --> | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Classes</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="boost.in_place_factory_base">in_place_factory_base</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.typed_in_place_factory_base">typed_in_place_factory_base | ||||
|                             </link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|             </row> | ||||
|         </tbody> | ||||
|     </tgroup> | ||||
|  | ||||
|     <tgroup cols="5"> | ||||
|         <colspec colname="a"/> | ||||
|         <colspec colname="b"/> | ||||
|         <colspec colname="c"/> | ||||
|         <colspec colname="d"/> | ||||
|         <colspec colname="e"/> | ||||
|  | ||||
|         <thead> | ||||
|             <row> | ||||
|                 <entry valign="center" namest="a" nameend="e"> | ||||
|                     <bridgehead renderas="sect2">Operators</bridgehead> | ||||
|                 </entry> | ||||
|             </row> | ||||
|         </thead> | ||||
|  | ||||
|         <tbody> | ||||
|             <row> | ||||
|                 <entry valign="top"> | ||||
|                     <!-- 13 classes per cell --> | ||||
|                     <bridgehead renderas="sect3">Classes (1 of 5)</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">additive1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">additive2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">arithmetic1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">arithmetic2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">bidirectional_iteratable</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic"> | ||||
|                                 bidirectional_iterator_helper | ||||
|                             </link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">bitwise1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">bitwise2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">decrementable</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">dereferenceable</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">equality_comparable1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">equality_comparable2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">equivalent1</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Classes (2 of 5)</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">equivalent2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">euclidean_ring_operators1 | ||||
|                             </link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">euclidean_ring_operators2 | ||||
|                             </link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">field_operators1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">field_operators2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">forward_iteratable</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">forward_iterator_helper</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">incrementable</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">indexable</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">input_iteratable</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">input_iterator_helper</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">integer_arithmetic1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">integer_arithmetic2</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Classes (3 of 5)</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">integer_multiplicative1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">integer_multiplicative2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">is_chained_base</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">less_than_comparable1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">less_than_comparable2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">multiplicative1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">multiplicative2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">operators</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">operators2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">operators<T,T></link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic"> | ||||
|                                 ordered_euclidean_ring_operators1 | ||||
|                             </link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic"> | ||||
|                                 ordered_euclidean_ring_operators2 | ||||
|                             </link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic"> | ||||
|                                 ordered_euclidian_ring_operators1 | ||||
|                             </link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Classes (4 of 5)</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic"> | ||||
|                                 ordered_euclidian_ring_operators2 | ||||
|                             </link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">ordered_field_operators1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">ordered_field_operators2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">ordered_ring_operators1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">ordered_ring_operators2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">output_iteratable</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">output_iterator_helper</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">partially_ordered1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">partially_ordered2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">random_access_iteratable</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic"> | ||||
|                                 random_access_iterator_helper | ||||
|                             </link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">ring_operators1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">ring_operators2</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Classes (5 of 5)</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">shiftable1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">shiftable2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">totally_ordered1</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">totally_ordered2</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">unit_steppable</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                     <bridgehead renderas="sect3">Type Traits</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="sec:arithmetic">is_chained_base</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|             </row> | ||||
|         </tbody> | ||||
|     </tgroup> | ||||
|  | ||||
|     <tgroup cols="5"> | ||||
|         <colspec colname="a"/> | ||||
|         <colspec colname="b"/> | ||||
|         <colspec colname="c"/> | ||||
|         <colspec colname="d"/> | ||||
|         <colspec colname="e"/> | ||||
|  | ||||
|         <thead> | ||||
|             <row> | ||||
|                 <entry valign="center" namest="a" nameend="a"> | ||||
|                     <bridgehead renderas="sect2">Result of</bridgehead> | ||||
|                 </entry> | ||||
|                 <entry valign="center" namest="b" nameend="d"> | ||||
|                     <bridgehead renderas="sect2">String View</bridgehead> | ||||
|                 </entry> | ||||
|                 <entry valign="center" namest="e" nameend="e"> | ||||
|                     <bridgehead renderas="sect2">Value Init</bridgehead> | ||||
|                 </entry> | ||||
|             </row> | ||||
|         </thead> | ||||
|  | ||||
|         <tbody> | ||||
|             <row> | ||||
|                 <!-- result_of --> | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Type Traits</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="boost.result_of">result_of</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.tr1_result_of">tr1_result_of</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <!-- string_view --> | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Aliases</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">string_view</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">u16string_ref</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">u16string_view</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">u32string_ref</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">u32string_view</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">wstring_ref</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">wstring_view</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">string_ref</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Classes</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">basic_string_ref</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.basic_string_view">basic_string_view</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                     <bridgehead renderas="sect3">Functions</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="boost.hash_range">hash_range</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="boost.hash_value">hash_value</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <entry valign="top"> | ||||
|                     <bridgehead renderas="sect3">Operators</bridgehead> | ||||
|                     <simplelist type="vert" columns="1"> | ||||
|                         <member> | ||||
|                             <link linkend="header.boost.utility.string_view_hpp">operator==</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="header.boost.utility.string_view_hpp">operator!=</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="header.boost.utility.string_view_hpp">operator<</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="header.boost.utility.string_view_hpp">operator<=</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="header.boost.utility.string_view_hpp">operator></link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="header.boost.utility.string_view_hpp">operator>=</link> | ||||
|                         </member> | ||||
|                         <member> | ||||
|                             <link linkend="header.boost.utility.string_view_hpp">operator<<</link> | ||||
|                         </member> | ||||
|                     </simplelist> | ||||
|                 </entry> | ||||
|  | ||||
|                 <!-- value_init --> | ||||
|                 <entry valign="top"> | ||||
|                         <bridgehead renderas="sect3">Classes</bridgehead> | ||||
|                         <simplelist type="vert" columns="1"> | ||||
|                             <member> | ||||
|                                 <link linkend="boost.initialized">initialized</link> | ||||
|                             </member> | ||||
|                             <member> | ||||
|                                 <link linkend="boost.initialized_value_t">initialized_value_t</link> | ||||
|                             </member> | ||||
|                             <member> | ||||
|                                 <link linkend="boost.value_initialized">value_initialized</link> | ||||
|                             </member> | ||||
|                         </simplelist> | ||||
|                         <bridgehead renderas="sect3">Functions</bridgehead> | ||||
|                         <simplelist type="vert" columns="1"> | ||||
|                             <member> | ||||
|                                 <link linkend="header.boost.utility.value_init_hpp">get</link> | ||||
|                             </member> | ||||
|                             <member> | ||||
|                                 <link linkend="header.boost.utility.value_init_hpp">swap</link> | ||||
|                             </member> | ||||
|                         </simplelist> | ||||
|                         <bridgehead renderas="sect3">Constants</bridgehead> | ||||
|                         <simplelist type="vert" columns="1"> | ||||
|                             <member> | ||||
|                                 <link linkend="boost.initialized_value">initialized_value</link> | ||||
|                             </member> | ||||
|                         </simplelist> | ||||
|                 </entry> | ||||
|             </row> | ||||
|         </tbody> | ||||
|     </tgroup> | ||||
| </informaltable> | ||||
| @@ -1,421 +0,0 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2012 Marshall Clow | ||||
|  / Copyright (c) 2021, Alan Freitas | ||||
|  / | ||||
|  / 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 Result of] | ||||
| [/===============] | ||||
|  | ||||
| [section Introduction] | ||||
|  | ||||
| The class template __result_of__ helps determine the type of a | ||||
| call expression. For example, given an lvalue `f` of type `F` | ||||
| and lvalues `t1`,`t2`, ..., `tN` of types `T1`, `T2`, ..., `TN`, | ||||
| respectively, the type __result_of__`<F(T1, T2, ..., TN)>::type` defines | ||||
| the result type of the expression `f(t1, t2, ...,tN)`. | ||||
|  | ||||
| This implementation permits the type `F` to be a function pointer, | ||||
| function reference, member function pointer, or class type. By default, | ||||
| N may be any value between 0 and 16. To change the upper limit, define | ||||
| the macro `BOOST_RESULT_OF_NUM_ARGS` to the maximum value for N. Class | ||||
| template __result_of__ resides in the header | ||||
| [@../../../../boost/utility/result_of.hpp `<boost/utility/result_of.hpp>`]. | ||||
|  | ||||
| If your compiler's support for __decltype__ is adequate, __result_of__ | ||||
| automatically uses it to deduce the type of the call expression, in | ||||
| which case __result_of__`<F(T1, T2, ..., TN)>::type` names the type | ||||
| __decltype__`(boost::declval<F>()(boost::declval<T1>(), | ||||
| boost::declval<T2>(), ..., boost::declval<TN>()))`, as in the | ||||
| following example. | ||||
|  | ||||
| ``` | ||||
| struct functor { | ||||
|     template<class T> | ||||
|     T operator()(T x) | ||||
|     { | ||||
|         return x; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| typedef __boost_result_of__<functor(int)>::type type; // type is int | ||||
| ``` | ||||
|  | ||||
| You can test whether __result_of__ is using __decltype__ by checking if | ||||
| the macro `BOOST_RESULT_OF_USE_DECLTYPE` is defined after | ||||
| including `result_of.hpp`. You can also force __result_of__ to use | ||||
| __decltype__ by defining `BOOST_RESULT_OF_USE_DECLTYPE` prior | ||||
| to including `result_of.hpp`. | ||||
|  | ||||
| If __decltype__ is not used, then automatic result type deduction of function | ||||
| objects is not possible. Instead, __result_of__ uses the following protocol | ||||
| to allow the programmer to specify a type. When `F` is a class type with a | ||||
| member type `result_type`, `result_of<F(T1, T2, ..., TN)>::type` is | ||||
| `F::result_type`. When `F` does not contain `result_type`, | ||||
| `result_of<F(T1, T2, ..., TN)>::type` is | ||||
| `F::result<F(T1, T2, ..., TN)>::type` when | ||||
| `N > 0` or `void` when `N = 0`. | ||||
|  | ||||
| Note that it is the responsibility of the programmer to ensure that | ||||
| function objects accurately advertise their result | ||||
| type via this protocol, as in the following example. | ||||
|  | ||||
| ``` | ||||
| struct functor { | ||||
|     template <class> struct result; | ||||
|  | ||||
|     template<class F, class T> | ||||
|     struct result<F(T)> { | ||||
|         typedef T type; | ||||
|     }; | ||||
|  | ||||
|     template<class T> | ||||
|     T operator()(T x) | ||||
|     { | ||||
|         return x; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| typedef __boost_result_of__<functor(int)>::type type; // type is int | ||||
| ``` | ||||
|  | ||||
| Since __decltype__ is a language feature standardized in C++11, if you are | ||||
| writing a function object to be used with __result_of__, for maximum | ||||
| portability, you might consider following the above protocol | ||||
| even if your compiler has proper __decltype__ support. | ||||
|  | ||||
| If you wish to continue to use the protocol on compilers that | ||||
| support __decltype__, there are two options: | ||||
|  | ||||
| * You can use __boost_tr1_result_of__, which is also defined in | ||||
| [@../../../boost/utility/result_of.hpp `<boost/utility/result_of.hpp>`]. | ||||
|  | ||||
| * Alternatively, you can define the macro `BOOST_RESULT_OF_USE_TR1`, | ||||
| which causes __result_of__ to use the protocol described above instead | ||||
| of __decltype__. If you choose to follow the protocol, take care to | ||||
| ensure that the `result_type` and `result<>` members accurately | ||||
| represent the return type of `operator()` given a call expression. | ||||
|  | ||||
| Additionally, __boost_result_of__ provides a third mode of operation, | ||||
| which some users may find convenient. When | ||||
| `BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK` is defined, | ||||
| __boost_result_of__ behaves as follows. If the function object has a member | ||||
| type `result_type` or member template `result<>`, then __boost_result_of__ | ||||
| will use the TR1 protocol. | ||||
|  | ||||
| Otherwise, __boost_result_of__ will use __decltype__. Using TR1 with | ||||
| a __decltype__ fallback may workaround certain problems at the cost of portability. | ||||
| For example: | ||||
|  | ||||
| * Deficient compiler: If your code requires __boost_result_of__ to work | ||||
| with incomplete return types but your compiler's __decltype__ implementation | ||||
| does not support incomplete return types, then you can use the TR1 protocol | ||||
| as a workaround. Support for incomplete return types was added late in the | ||||
| C++11 standardization process | ||||
| (see [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf N3276]) | ||||
| and is not implemented by some compilers. | ||||
|  | ||||
| * Deficient legacy code: If your existing TR1 function object advertises a different type than | ||||
| the actual result type deduced by __decltype__, then using TR1 with a __decltype__ fallback | ||||
| will allow you to work with both your existing TR1 function objects and new C++11 | ||||
| function object. This situation could occur if your legacy function objects | ||||
| misused the TR1 protocol. See the documentation on known [link sec:result_of_tr1_diff differences] | ||||
| between __boost_result_of__ and TR1. | ||||
|  | ||||
| * [#BOOST_NO_RESULT_OF] This implementation of __result_of__ requires class template | ||||
| partial specialization, the ability to parse function types properly, and support | ||||
| for SFINAE. If __result_of__ is not supported by your compiler, including the header | ||||
| [@../../../boost/utility/result_of.hpp `<boost/utility/result_of.hpp>`] will define | ||||
| the macro `BOOST_NO_RESULT_OF`. | ||||
|  | ||||
| For additional information about __result_of__, see the C++ Library | ||||
| Technical Report, [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf N1836], | ||||
| or, for motivation and design rationale, the __result_of__ | ||||
| [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html proposal]. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [#sec:result_of_guidelines] | ||||
| [section Usage guidelines for __boost_result_of__] | ||||
|  | ||||
| The following are general suggestions about when and how to use __boost_result_of__. | ||||
|  | ||||
| # If you are targeting C++11 and are not concerned about portability to | ||||
| non-compliant compilers or previous versions of the standard, then use | ||||
| `__std_result_of__`. If `__std_result_of__` meets your needs, then | ||||
| there's no reason to stop using it. | ||||
|  | ||||
| # If you are targeting C++11 but may port your code to legacy compilers | ||||
| at some time in the future, then use __boost_result_of__ with __decltype__. | ||||
| When __decltype__ is used __boost_result_of__ and `__std_result_of__` are usually | ||||
| interchangeable. See the documentation on known [link sec:result_of_cxx11_diff differences] | ||||
| between __boost_result_of__ and C++11 __std_result_of__. | ||||
|  | ||||
| # If compiler portability is required, use __boost_result_of__ with the TR1 protocol | ||||
|  | ||||
| Regardless of how you configure __boost_result_of__, it is | ||||
| important to bear in mind that the return type of a | ||||
| function may change depending on its arguments, and | ||||
| additionally, the return type of a member function may | ||||
| change depending on the cv-qualification of the | ||||
| object. __boost_result_of__ must be passed | ||||
| the appropriately cv-qualified types in order to | ||||
| deduce the corresponding return type. | ||||
|  | ||||
| For example: | ||||
|  | ||||
| ``` | ||||
| struct functor { | ||||
|     int& operator()(int); | ||||
|     int const& operator()(int) const; | ||||
|  | ||||
|     float& operator()(float&); | ||||
|     float const& operator()(float const&); | ||||
| }; | ||||
|  | ||||
| typedef __boost_result_of__< | ||||
|     functor(int) | ||||
| >::type type1; // type1 is int & | ||||
|  | ||||
| typedef __boost_result_of__< | ||||
|     const functor(int) | ||||
| >::type type2; // type2 is int const & | ||||
|  | ||||
| typedef __boost_result_of__< | ||||
|     functor(float&) | ||||
| >::type type3; // type3 is float & | ||||
|  | ||||
| typedef __boost_result_of__< | ||||
|     functor(float const&) | ||||
| >::type type4; // type4 is float const & | ||||
| ``` | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [#sec:result_of_tr1_protocol_guidelines] | ||||
| [section Usage guidelines for the TR1 result_of protocol] | ||||
|  | ||||
| On compliant C++11 compilers, __boost_result_of__ can | ||||
| use __decltype__ to deduce the type of any | ||||
| call expression, including calls to function | ||||
| objects. However, on pre-C++11 compilers or on | ||||
| compilers without adequate decltype support, | ||||
| additional scaffolding is needed from function | ||||
| objects as described above. The following are | ||||
| suggestions about how to use the TR1 protocol. | ||||
|  | ||||
| * When the return type does not depend on the | ||||
| argument types or the cv-qualification of the | ||||
| function object, simply | ||||
| define `result_type`. There is no need | ||||
| to use the `result` template unless the | ||||
| return type varies.</li> | ||||
|  | ||||
| * Use the protocol specified type when defining | ||||
| function prototypes. This can help ensure the | ||||
| actual return type does not get out of sync with | ||||
| the protocol specification. For example: | ||||
|  | ||||
| ``` | ||||
| struct functor { | ||||
|     typedef int result_type; | ||||
|     result_type operator()(int); | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| * Always specify the `result` specialization near the corresponding | ||||
| `operator()` overload. This can make it easier to keep the specializations | ||||
| in sync with the overloads. For example: | ||||
|  | ||||
| ``` | ||||
| struct functor { | ||||
|     template<class> struct result; | ||||
|  | ||||
|     template<class F> | ||||
|     struct result<F(int)> { | ||||
|         typedef int& type; | ||||
|     }; | ||||
|     result<functor(int)>::type operator()(int); | ||||
|  | ||||
|     template<class F> | ||||
|     struct result<const F(int)> { | ||||
|         typedef int const& type; | ||||
|     }; | ||||
|     result<const functor(int)>::type operator()(int) const; | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| * Use type transformations to simplify | ||||
| the `result` template specialization. For | ||||
| example, the following uses [@../type_traits/doc/html/index.html Boost.TypeTraits] | ||||
| to specialize the `result` template for | ||||
| a single `operator()` that can be called on | ||||
| both a const and non-const function object with | ||||
| either an lvalue or rvalue argument. | ||||
|  | ||||
| ``` | ||||
| struct functor { | ||||
|     template<class> struct result; | ||||
|  | ||||
|     template<class F, class T> | ||||
|     struct result<F(T)> | ||||
|         : boost::remove_cv< | ||||
|               typename boost::remove_reference<T>::type | ||||
|           > | ||||
|     {}; | ||||
|  | ||||
|     template<class T> | ||||
|     T operator()(T const& x) const; | ||||
| }; | ||||
| ``` | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [#sec:result_of_tr1_diff] | ||||
| [section Known differences between __boost_result_of__ and __boost_tr1_result_of__] | ||||
|  | ||||
| When using __decltype__, __boost_result_of__ ignores the TR1 protocol and instead deduces the | ||||
| return type of function objects directly via __decltype__. In most situations, users | ||||
| will not notice a difference, so long as they use the protocol correctly. The following are situations in | ||||
| which the type deduced by __boost_result_of__ is known to differ depending on whether | ||||
| __decltype__ or the TR1 protocol is used. | ||||
|  | ||||
| TR1 protocol misusage: When using the TR1 protocol, __boost_result_of__ cannot | ||||
| detect whether the actual type of a call to a function object is the same as the | ||||
| type specified by the protocol, which allows for the possibility of inadvertent | ||||
| mismatches between the specified type and the actual type. When using __decltype__, | ||||
| these subtle bugs may result in compilation errors. For example: | ||||
|  | ||||
| ``` | ||||
| struct functor { | ||||
|    typedef short result_type; | ||||
|    int operator()(short); | ||||
| }; | ||||
|  | ||||
| #ifdef BOOST_RESULT_OF_USE_DECLTYPE | ||||
|  | ||||
| BOOST_STATIC_ASSERT(( | ||||
|    boost::is_same<__boost_result_of__<functor(short)>::type, int>::value | ||||
| )); | ||||
|  | ||||
| #else | ||||
|  | ||||
| BOOST_STATIC_ASSERT(( | ||||
|    boost::is_same<__boost_result_of__<functor(short)>::type, short>::value | ||||
| )); | ||||
|  | ||||
| #endif | ||||
| ``` | ||||
|  | ||||
| Note that the user can force __boost_result_of__ to use the TR1 | ||||
| protocol even on platforms that support __decltype__ by | ||||
| defining `BOOST_RESULT_OF_USE_TR1`. | ||||
|  | ||||
| Nullary function objects: When using the TR1 protocol, __boost_result_of__ | ||||
| cannot always deduce the type of calls to nullary function objects, in which case the | ||||
| type defaults to void. When using __decltype__, __boost_result_of__ always gives the | ||||
| actual type of the call expression. For example: | ||||
|  | ||||
| ``` | ||||
| struct functor { | ||||
|    template<class> struct result { | ||||
|        typedef int type; | ||||
|    }; | ||||
|    int operator()(); | ||||
| }; | ||||
|  | ||||
| #ifdef BOOST_RESULT_OF_USE_DECLTYPE | ||||
|  | ||||
| BOOST_STATIC_ASSERT(( | ||||
|    boost::is_same<__boost_result_of__<functor()>::type, int>::value | ||||
| )); | ||||
|  | ||||
| #else | ||||
|  | ||||
| BOOST_STATIC_ASSERT(( | ||||
|    boost::is_same<__boost_result_of__<functor()>::type, void>::value | ||||
| )); | ||||
|  | ||||
| #endif | ||||
| ``` | ||||
|  | ||||
| Note that there are some workarounds for the nullary function problem. | ||||
| So long as the return type does not vary, `result_type` can always be used to | ||||
| specify the return type regardless of arity. If the return type does vary, | ||||
| then the user can specialize __boost_result_of__ itself for nullary calls. | ||||
|  | ||||
| Non-class prvalues and cv-qualification: When using the TR1 protocol, __boost_result_of__ will | ||||
| report the cv-qualified type specified by `result_type` or the `result` template regardless of | ||||
| the actual cv-qualification of the call expression. When using __decltype__, __boost_result_of__ | ||||
| will report the actual type of the call expression, which is not cv-qualified when the expression | ||||
| is a non-class prvalue. For example: | ||||
|  | ||||
| ``` | ||||
| struct functor { | ||||
|    template<class> struct result; | ||||
|    template<class F, class T> struct result<F(const T)> { | ||||
|        typedef const T type; | ||||
|    }; | ||||
|  | ||||
|    const short operator()(const short); | ||||
|    int const & operator()(int const &); | ||||
| }; | ||||
|  | ||||
| // Non-prvalue call expressions work the same with or without decltype. | ||||
|  | ||||
| BOOST_STATIC_ASSERT(( | ||||
|    boost::is_same< | ||||
|        __boost_result_of__<functor(int const &)>::type, | ||||
|        int const & | ||||
| ::value | ||||
| )); | ||||
|  | ||||
| // Non-class prvalue call expressions are not actually cv-qualified, | ||||
| // but only the decltype-based result_of reports this accurately. | ||||
|  | ||||
| #ifdef BOOST_RESULT_OF_USE_DECLTYPE | ||||
|  | ||||
| BOOST_STATIC_ASSERT(( | ||||
|    boost::is_same< | ||||
|        __boost_result_of__<functor(const short)>::type, | ||||
|        short | ||||
| ::value | ||||
| )); | ||||
|  | ||||
| #else | ||||
|  | ||||
| BOOST_STATIC_ASSERT(( | ||||
|    boost::is_same< | ||||
|        __boost_result_of__<functor(const short)>::type, | ||||
|        const short | ||||
| ::value | ||||
| )); | ||||
|  | ||||
| #endif | ||||
| ``` | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [#sec:result_of_cxx11_diff] | ||||
| [section Known differences between __boost_result_of__ and C++11 result_of] | ||||
|  | ||||
| When using __decltype__, __boost_result_of__ implements most of the C++11 __std_result_of__ | ||||
| specification. One known exception is that __boost_result_of__ does not implement the | ||||
| requirements regarding pointers to member data. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [xinclude tmp/result_of_reference.xml] | ||||
| [/===============] | ||||
|  | ||||
| [section Acknowledgments] | ||||
|  | ||||
| Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [endsect] | ||||
							
								
								
									
										167
									
								
								doc/string_ref.qbk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								doc/string_ref.qbk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2012 Marshall Clow | ||||
|  / | ||||
|  / 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) | ||||
|  /] | ||||
|  | ||||
| [article String_Ref | ||||
|     [quickbook 1.5] | ||||
|     [authors [Clow, Marshall]] | ||||
|     [copyright 2012 Marshall Clow] | ||||
|     [license | ||||
|         Distributed under the Boost Software License, Version 1.0. | ||||
|         (See accompanying file LICENSE_1_0.txt or copy at | ||||
|         [@http://www.boost.org/LICENSE_1_0.txt]) | ||||
|     ] | ||||
| ] | ||||
|  | ||||
| [/===============] | ||||
| [section Overview] | ||||
| [/===============] | ||||
|  | ||||
| Boost.StringRef is an implementation of Jeffrey Yaskin's [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html N3442: | ||||
| string_ref: a non-owning reference to a string].  | ||||
|  | ||||
| When you are parsing/processing strings from some external source, frequently you want to pass a piece of text to a procedure for specialized processing. The canonical way to do this is as a `std::string`, but that has certain drawbacks: | ||||
|  | ||||
| 1) If you are processing a buffer of text (say a HTTP response or the contents of a file), then you have to create the string from the text you want to pass, which involves memory allocation and copying of data. | ||||
|  | ||||
| 2) if a routine receives a constant `std::string` and wants to pass a portion of that string to another routine, then it must create a new string of that substring. | ||||
|  | ||||
| 3) A routine receives a constant `std::string` and wants to return a portion of the string, then it must create a new string to return. | ||||
|  | ||||
| `string_ref` is designed to solve these efficiency problems. A `string_ref` is a read-only reference to a contiguous sequence of characters, and provides much of the functionality of `std::string`. A `string_ref` is cheap to create, copy and pass by value, because it does not actually own the storage that it points to.  | ||||
|  | ||||
| A `string_ref` is implemented as a small struct that contains a pointer to the start of the character data and a count. A `string_ref` is cheap to create and cheap to copy. | ||||
|  | ||||
| `string_ref` acts as a container; it includes all the methods that you would expect in a container, including iteration support, `operator []`, `at` and `size`. It can be used with any of the iterator-based algorithms in the STL - as long as you don't need to change the underlying data (`sort` and `remove`, for example, will not work) | ||||
|  | ||||
| Besides generic container functionality, `string_ref` provides a subset of the interface of `std::string`. This makes it easy to replace parameters of type `const std::string &` with `boost::string_ref`. Like `std::string`, `string_ref` has a static member variable named `npos` to denote the result of failed searches, and to mean "the end". | ||||
|  | ||||
| Because a `string_ref` does not own the data that it "points to", it introduces lifetime issues into code that uses it. The programmer must ensure that the data that a `string_ref` refers to exists as long as the `string_ref` does. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
| [/===============] | ||||
| [section Examples] | ||||
| [/===============] | ||||
|  | ||||
| Integrating `string_ref` into your code is fairly simple. Wherever you pass a `const std::string &` or `std::string` as a parameter, that's a candidate for passing a `boost::string_ref`. | ||||
|  | ||||
|     std::string extract_part ( const std::string &bar ) { | ||||
|         return bar.substr ( 2, 3 ); | ||||
|         } | ||||
|          | ||||
|     if ( extract_part ( "ABCDEFG" ).front() == 'C' ) { /* do something */ } | ||||
|      | ||||
| Let's figure out what happens in this (contrived) example. | ||||
|  | ||||
| First, a temporary string is created from the string literal `"ABCDEFG"`, and it is passed (by reference) to the routine `extract_part`. Then a second string is created in the call `std::string::substr` and returned to `extract_part` (this copy may be elided by RVO). Then `extract_part` returns that string back to the caller (again this copy may be elided). The first temporary string is deallocated, and `front` is called on the second string, and then it is deallocated as well. | ||||
|  | ||||
| Two `std::string`s are created, and two copy operations. That's (potentially) four memory allocations and deallocations, and the associated copying of data. | ||||
|  | ||||
| Now let's look at the same code with `string_ref`: | ||||
|  | ||||
|     boost::string_ref extract_part ( boost::string_ref bar ) { | ||||
|         return bar.substr ( 2, 3 ); | ||||
|         } | ||||
|          | ||||
|     if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } | ||||
|  | ||||
| No memory allocations. No copying of character data. No changes to the code other than the types. There are two `string_ref`s created, and two `string_ref`s copied, but those are cheap operations. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
| [/=================] | ||||
| [section:reference Reference ] | ||||
| [/=================] | ||||
|  | ||||
| The header file "string_ref.hpp" defines a template `boost::basic_string_ref`, and four specializations - for `char` / `wchar_t` / `char16_t` / `char32_t` . | ||||
|  | ||||
| `#include <boost/utility/string_ref.hpp>` | ||||
|  | ||||
| Construction and copying: | ||||
|  | ||||
|     BOOST_CONSTEXPR basic_string_ref ();    // Constructs an empty string_ref | ||||
|     BOOST_CONSTEXPR basic_string_ref(const charT* str); // Constructs from a NULL-terminated string | ||||
|     BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len); // Constructs from a pointer, length pair | ||||
|     template<typename Allocator> | ||||
|     basic_string_ref(const std::basic_string<charT, traits, Allocator>& str); // Constructs from a std::string | ||||
|     basic_string_ref (const basic_string_ref &rhs); | ||||
|     basic_string_ref& operator=(const basic_string_ref &rhs); | ||||
|  | ||||
| `string_ref` does not define a move constructor nor a move-assignment operator because copying a `string_ref` is just a cheap as moving one. | ||||
|  | ||||
| Basic container-like functions: | ||||
|  | ||||
|     BOOST_CONSTEXPR size_type size()     const ; | ||||
|     BOOST_CONSTEXPR size_type length()   const ; | ||||
|     BOOST_CONSTEXPR size_type max_size() const ; | ||||
|     BOOST_CONSTEXPR bool empty()         const ; | ||||
|      | ||||
|     // All iterators are const_iterators | ||||
|     BOOST_CONSTEXPR const_iterator  begin() const ; | ||||
|     BOOST_CONSTEXPR const_iterator cbegin() const ; | ||||
|     BOOST_CONSTEXPR const_iterator    end() const ; | ||||
|     BOOST_CONSTEXPR const_iterator   cend() const ; | ||||
|     const_reverse_iterator         rbegin() const ; | ||||
|     const_reverse_iterator        crbegin() const ; | ||||
|     const_reverse_iterator           rend() const ; | ||||
|     const_reverse_iterator          crend() const ; | ||||
|  | ||||
| Access to the individual elements (all of which are const): | ||||
|  | ||||
|     BOOST_CONSTEXPR const charT& operator[](size_type pos) const ; | ||||
|     const charT& at(size_t pos) const ; | ||||
|     BOOST_CONSTEXPR const charT& front() const ; | ||||
|     BOOST_CONSTEXPR const charT& back()  const ; | ||||
|     BOOST_CONSTEXPR const charT* data()  const ; | ||||
|  | ||||
| Modifying the `string_ref` (but not the underlying data): | ||||
|  | ||||
|     void clear(); | ||||
|     void remove_prefix(size_type n); | ||||
|     void remove_suffix(size_type n); | ||||
|  | ||||
| Searching: | ||||
|  | ||||
|     size_type find(basic_string_ref s) const ; | ||||
|     size_type find(charT c) const ; | ||||
|     size_type rfind(basic_string_ref s) const ; | ||||
|     size_type rfind(charT c) const ; | ||||
|     size_type find_first_of(charT c) const ; | ||||
|     size_type find_last_of (charT c) const ; | ||||
|          | ||||
|     size_type find_first_of(basic_string_ref s) const ; | ||||
|     size_type find_last_of(basic_string_ref s) const ; | ||||
|     size_type find_first_not_of(basic_string_ref s) const ; | ||||
|     size_type find_first_not_of(charT c) const ; | ||||
|     size_type find_last_not_of(basic_string_ref s) const ; | ||||
|     size_type find_last_not_of(charT c) const ; | ||||
|  | ||||
| String-like operations: | ||||
|  | ||||
|     BOOST_CONSTEXPR basic_string_ref substr(size_type pos, size_type n=npos) const ; // Creates a new string_ref | ||||
|     bool starts_with(charT c) const ; | ||||
|     bool starts_with(basic_string_ref x) const ; | ||||
|     bool ends_with(charT c) const ; | ||||
|     bool ends_with(basic_string_ref x) const ; | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [section History] | ||||
| [/===============] | ||||
|  | ||||
| [heading boost 1.53] | ||||
| * Introduced | ||||
|      | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -1,209 +0,0 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2012 Marshall Clow | ||||
|  / Copyright (c) 2021, Alan Freitas | ||||
|  / | ||||
|  / 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 String View] | ||||
| [/===============] | ||||
|  | ||||
| [section Introduction] | ||||
|  | ||||
| The class __boost_string_view__ and other classes derived from __basic_string_view__ represent references to strings or substrings. When you are parsing/processing strings from some external source, frequently you want to pass a piece of text to a procedure for specialized processing. Before __std_string_view__, the canonical way to do this used to be a __std_string__, but that has certain drawbacks: | ||||
|  | ||||
| 1) If you are processing a buffer of text (say a HTTP response or the contents of a file), then you have to create the string from the text you want to pass, which involves memory allocation and copying of data. | ||||
|  | ||||
| 2) If a routine receives a constant __std_string__ and wants to pass a portion of that string to another routine, then it must create a new string of that substring. | ||||
|  | ||||
| 3) If a routine receives a constant __std_string__ and wants to return a portion of the string, then it must create a new string to return. | ||||
|  | ||||
| __boost_string_view__ is designed to solve these efficiency problems. A __boost_string_view__ is a read-only reference to a contiguous sequence of characters, and provides much of the functionality of __std_string__. A __boost_string_view__ is cheap to create, copy and pass by value, because it does not actually own the storage that it points to. | ||||
|  | ||||
| A __boost_string_view__ is implemented as a small struct that contains a pointer to the start of the character `data` and a `count`. A __boost_string_view__ is cheap to create and cheap to copy. | ||||
|  | ||||
| __boost_string_view__ acts as a container; it includes all the methods that you would expect in a container, including iteration support, `operator[]`, `at` and `size`. It can be used with any of the iterator-based algorithms in the STL - as long as you do not need to change the underlying data. For example, __std_sort__ and __std_remove__ will not work. | ||||
|  | ||||
| Besides generic container functionality, __boost_string_view__ provides a subset of the interface of __std_string__. This makes it easy to replace parameters of type `const __std_string__ &` with __boost_string_view__. Like __std_string__, __boost_string_view__ has a static member variable named `npos` to denote the result of failed searches, and to mean "the end". | ||||
|  | ||||
| [caution Because a __boost_string_view__ does not own the data that it refers to, it introduces lifetime issues into code that uses it. The programmer must ensure that the data that a __string_view__ refers to exists as long as the __string_view__ does.] | ||||
|  | ||||
| [note | ||||
|  | ||||
| Boost.Utility also includes the class __string_ref__: | ||||
|  | ||||
| - __string_ref__ is the initial implementation of Jeffrey Yaskin's [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html N3442: | ||||
| string_ref: a non-owning reference to a string]. | ||||
|  | ||||
| - __string_view__ is an updated implementation to reflect the Library Fundamentals TS [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html N4480: \[string.view\]]. | ||||
|  | ||||
| Please prefer __string_view__ / __basic_string_view__ over __string_ref__ / __basic_string_ref__: | ||||
|  | ||||
| - The __basic_string_view__ class better matches __std_basic_string_view__. | ||||
|  | ||||
| - __basic_string_view__ has WAY more constexpr support. | ||||
|  | ||||
| - Code that uses __basic_string_ref__ should continue to work. | ||||
|  | ||||
| - Not much code depends on __basic_string_ref__ anymore. | ||||
|  | ||||
|  | ||||
| ] | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [section Examples] | ||||
| [/===============] | ||||
|  | ||||
| Integrating __string_view__ into your code is fairly simple. Wherever you pass a `const __std_string__ &` or __std_string__ as a parameter, that's a candidate for passing a __boost_string_view__. | ||||
|  | ||||
| ``` | ||||
| __std_string__ extract_part ( const __std_string__ &bar ) { | ||||
|     return bar.substr ( 2, 3 ); | ||||
| } | ||||
|  | ||||
| if ( extract_part ( "ABCDEFG" ).front() == 'C' ) { /* do something */ } | ||||
| ``` | ||||
|  | ||||
| Let's figure out what happens in this contrived example. | ||||
|  | ||||
| * First, a temporary string is created from the string literal `"ABCDEFG"`, and it is passed (by reference) to the routine `extract_part`. | ||||
| * Then a second string is created in the call `__std_string__::substr` and returned to `extract_part` (this copy may be elided by RVO). | ||||
| * Then `extract_part` returns that string back to the caller (again this copy may be elided). | ||||
| * The first temporary string is deallocated, and `front` is called on the second string, and then it is deallocated as well. | ||||
|  | ||||
| Two __std_string__ s are created, and two copy operations. That is potentially four memory allocations and deallocations, and the associated copying of data. | ||||
|  | ||||
| Now let's look at the same code with __string_view__: | ||||
|  | ||||
| ``` | ||||
| __boost_string_view__ extract_part ( __boost_string_view__ bar ) { | ||||
|     return bar.substr ( 2, 3 ); | ||||
| } | ||||
|  | ||||
| if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } | ||||
| ``` | ||||
|  | ||||
| No memory allocations. No copying of character data. No changes to the code other than the types. There are two __string_view__ s created, and two __string_view__ s copied, but those are cheap operations. | ||||
| [endsect] | ||||
|  | ||||
| [/=================] | ||||
| [section:reference Synopsis] | ||||
| [/=================] | ||||
|  | ||||
| The header file [@../../../../boost/utility/string_view.hpp `<boost/utility/string_view.hpp>`] defines a template __boost_basic_string_view__, and four specializations __string_view__, __wstring_view__, __u16string_view__, __u32string_view__ - for `char` / `wchar_t` / `char16_t` / `char32_t`. | ||||
|  | ||||
| `#include <boost/utility/string_view.hpp>` | ||||
|  | ||||
| Construction and copying: | ||||
|  | ||||
| ``` | ||||
| constexpr basic_string_view ();    // Constructs an empty string_view | ||||
| constexpr basic_string_view(const charT* str); // Constructs from a NULL-terminated string | ||||
| constexpr basic_string_view(const charT* str, size_type len); // Constructs from a pointer, length pair | ||||
| template<typename Allocator> | ||||
| basic_string_view(const __std_basic_string__<charT, traits, Allocator>& str); // Constructs from a std::string | ||||
| basic_string_view (const basic_string_view &rhs); | ||||
| basic_string_view& operator=(const basic_string_view &rhs); | ||||
| ``` | ||||
|  | ||||
| __string_view__ does not define a move constructor nor a move-assignment operator because copying a __string_view__ is just a cheap as moving one. | ||||
|  | ||||
| Basic container-like functions: | ||||
|  | ||||
| ``` | ||||
| constexpr size_type size()     const ; | ||||
| constexpr size_type length()   const ; | ||||
| constexpr size_type max_size() const ; | ||||
| constexpr bool empty()         const ; | ||||
|  | ||||
| // All iterators are const_iterators | ||||
| constexpr const_iterator  begin() const ; | ||||
| constexpr const_iterator cbegin() const ; | ||||
| constexpr const_iterator    end() const ; | ||||
| constexpr const_iterator   cend() const ; | ||||
| const_reverse_iterator         rbegin() const ; | ||||
| const_reverse_iterator        crbegin() const ; | ||||
| const_reverse_iterator           rend() const ; | ||||
| const_reverse_iterator          crend() const ; | ||||
| ``` | ||||
|  | ||||
| Access to the individual elements (all of which are const): | ||||
|  | ||||
| ``` | ||||
| constexpr const charT& operator[](size_type pos) const ; | ||||
| const charT& at(size_t pos) const ; | ||||
| constexpr const charT& front() const ; | ||||
| constexpr const charT& back()  const ; | ||||
| constexpr const charT* data()  const ; | ||||
| ``` | ||||
|  | ||||
| Modifying the __string_view__ (but not the underlying data): | ||||
|  | ||||
| ``` | ||||
| void clear(); | ||||
| void remove_prefix(size_type n); | ||||
| void remove_suffix(size_type n); | ||||
| ``` | ||||
|  | ||||
| Searching: | ||||
|  | ||||
| ``` | ||||
| size_type find(basic_string_view s) const ; | ||||
| size_type find(charT c) const ; | ||||
| size_type rfind(basic_string_view s) const ; | ||||
| size_type rfind(charT c) const ; | ||||
| size_type find_first_of(charT c) const ; | ||||
| size_type find_last_of (charT c) const ; | ||||
|  | ||||
| size_type find_first_of(basic_string_view s) const ; | ||||
| size_type find_last_of(basic_string_view s) const ; | ||||
| size_type find_first_not_of(basic_string_view s) const ; | ||||
| size_type find_first_not_of(charT c) const ; | ||||
| size_type find_last_not_of(basic_string_view s) const ; | ||||
| size_type find_last_not_of(charT c) const ; | ||||
| ``` | ||||
|  | ||||
| String-like operations: | ||||
|  | ||||
| ``` | ||||
| constexpr basic_string_view substr(size_type pos, size_type n=npos) const ; // Creates a new string_view | ||||
| bool starts_with(charT c) const ; | ||||
| bool starts_with(basic_string_view x) const ; | ||||
| bool ends_with(charT c) const ; | ||||
| bool ends_with(basic_string_view x) const ; | ||||
| ``` | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
| [/===============] | ||||
| [section History] | ||||
| [/===============] | ||||
|  | ||||
| [h5 boost 1.71] | ||||
| * Glen Fernandes updated the implementation of the stream insertion operator to | ||||
| write directly to the `basic_streambuf` and refactored that functionality into | ||||
| a common utility. | ||||
|  | ||||
| [h5 boost 1.53] | ||||
| * Introduced | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [xinclude tmp/string_view_reference.xml] | ||||
| [/===============] | ||||
|  | ||||
| [/===============] | ||||
| [section Acknowledgments] | ||||
| [/===============] | ||||
|  | ||||
| Author: Clow, Marshall | ||||
|  | ||||
| Copyright 2012 Marshall Clow | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [endsect] | ||||
							
								
								
									
										2
									
								
								doc/tmp/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								doc/tmp/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +0,0 @@ | ||||
| *.qbk | ||||
| *.xml | ||||
| @@ -1,32 +0,0 @@ | ||||
| [/ | ||||
|     Copyright (c) 2021 Alan de Freitas (alandefreitas@gmail.com) | ||||
|  | ||||
|     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) | ||||
|  | ||||
|     Official repository: https://github.com/boostorg/utility | ||||
| ] | ||||
|  | ||||
| [section:utilities Utilities] | ||||
|  | ||||
| The entire contents of Boost.Utility are in `namespace boost`. | ||||
|  | ||||
| [warning | ||||
|  | ||||
| Direct use of the header [@../../../../boost/utility.hpp `<boost/utility.hpp>`] is discouraged and it will be deprecated. | ||||
|  | ||||
| Please include the headers relative to individual components instead. | ||||
|  | ||||
| ] | ||||
|  | ||||
| [include base_from_member.qbk] | ||||
| [include BOOST_BINARY.qbk] | ||||
| [include call_traits.qbk] | ||||
| [include compressed_pair.qbk] | ||||
| [include in_place_factory.qbk] | ||||
| [include operators.qbk] | ||||
| [include result_of.qbk] | ||||
| [include string_view.qbk] | ||||
| [include value_init.qbk] | ||||
|  | ||||
| [endsect] | ||||
| @@ -1,584 +0,0 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2012 Marshall Clow | ||||
|  / Copyright (c) 2021, Alan Freitas | ||||
|  / | ||||
|  / 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) | ||||
|  /] | ||||
|  | ||||
| [/===============] | ||||
| [#sec:value_init] | ||||
| [section Value Init] | ||||
|  | ||||
| [/===============] | ||||
|  | ||||
| [section Introduction] | ||||
|  | ||||
| Constructing and initializing objects in a generic way is difficult in | ||||
| C++. The problem is that there are several different rules that apply | ||||
| for initialization. Depending on the type, the value of a newly constructed | ||||
| object can be zero-initialized (logically 0), default-constructed (using | ||||
| the default constructor), or indeterminate. When writing generic code, | ||||
| this problem must be addressed. The template __value_initialized__ provides | ||||
| a solution with consistent syntax for value initialization of scalar, | ||||
| union and class types. Moreover, __value_initialized__ offers a workaround to various | ||||
| compiler issues regarding value-initialization. | ||||
|  | ||||
| Furthermore, a `const` object __initialized_value__ is provided, | ||||
| to avoid repeating the type name when retrieving the value from a | ||||
| `__value_initialized__<T>` object. | ||||
|  | ||||
| There are various ways to initialize a variable, in C++. The following | ||||
| declarations all ['may] have a local variable initialized to its default | ||||
| value: | ||||
|  | ||||
| ``` | ||||
| T1 var1; | ||||
| T2 var2 = 0; | ||||
| T3 var3 = {}; | ||||
| T4 var4 = T4(); | ||||
| ``` | ||||
|  | ||||
| Unfortunately, whether or not any of those declarations correctly | ||||
| initialize the variable very much depends on its type. The first | ||||
| declaration is valid for any __DefaultConstructible__ type by definition. | ||||
|  | ||||
| However, it does not always do an initialization. It correctly initializes | ||||
| the variable when it's an instance of a class, and the author of the class | ||||
| has provided a proper default constructor. On the other hand, the value of | ||||
| `var1` is ['indeterminate] when its type is an arithmetic type, like `int`, | ||||
| `float`, or `char`. | ||||
|  | ||||
| An arithmetic variable is of course initialized properly by the second declaration, | ||||
| `T2 var2 = 0`. But this initialization form will not usually work for a | ||||
| class type, unless the class was especially written to support being | ||||
| initialized that way. | ||||
|  | ||||
| The third form, `T3 var3 = {}`, initializes an aggregate, typically a "C-style" | ||||
| `struct` or a "C-style" array. However, at the time this library was developed, | ||||
| the syntax did not allow for a class that has an explicitly declared constructor. | ||||
|  | ||||
| The fourth form is the most generic form of them, as it can be used to initialize | ||||
| arithmetic types, class types, aggregates, pointers, and other types. | ||||
| The declaration,  `T4 var4 = T4()`, should be read as follows: First a temporary | ||||
| object is created, by `T4()`. This object is [link sec:valueinit value-initialized]. | ||||
| Next the temporary object is copied to the named variable, `var4`. Afterwards, | ||||
| the temporary is destroyed. While the copying and the destruction are likely to | ||||
| be optimized away, C++ still requires the type `T4` to be __CopyConstructible__. | ||||
| So `T4` needs to be ['both] __DefaultConstructible__ ['and] __CopyConstructible__. | ||||
|  | ||||
| A class may not be CopyConstructible, for example because it may have a | ||||
| private and undefined copy constructor, or because it may be derived from | ||||
| `boost::noncopyable`. Scott Meyers \[[link sec:references 2]\] explains why a | ||||
| class would be defined like that. | ||||
|  | ||||
| There is another, less obvious disadvantage to the fourth form, `T4 var4 = T4()`: | ||||
| It suffers from various [link sec:compiler_issues compiler issues], causing | ||||
| a variable to be left uninitialized in some compiler specific cases. | ||||
|  | ||||
| The template __value_initialized__ offers a generic way to initialize | ||||
| an object, like `T4 var4 = T4()`, but without requiring its type | ||||
| to be __CopyConstructible__. And it offers a workaround to those compiler issues | ||||
| regarding value-initialization as well. It allows getting an initialized | ||||
| variable of any type; it ['only] requires the type to be __DefaultConstructible__. | ||||
| A properly ['value-initialized] object of type `T` is constructed by the following | ||||
| declaration: | ||||
|  | ||||
| ``` | ||||
| value_initialized<T> var; | ||||
| ``` | ||||
|  | ||||
| The template __initialized__ offers both value-initialization and direct-initialization. | ||||
| It is especially useful as a data member type, allowing the very same object | ||||
| to be either direct-initialized or value-initialized. | ||||
|  | ||||
| The `const` object __initialized_value__ allows value-initializing a variable as follows: | ||||
|  | ||||
| ``` | ||||
| T var = initialized_value; | ||||
| ``` | ||||
|  | ||||
| This form of initialization is semantically equivalent to `T4 var4 = T4()`, | ||||
| but robust against the aforementioned compiler issues. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [#sec:details] | ||||
| [section Details] | ||||
|  | ||||
| The C++ standard \[[link sec:references 3]\] contains the definitions | ||||
| of `zero-initialization` and `default-initialization`. Informally, zero-initialization | ||||
| means that the object is given the initial value `0` converted to the type and | ||||
| default-initialization means that [@https://en.cppreference.com/w/cpp/named_req/PODType POD] \[[link sec:references 4]\] types are zero-initialized, | ||||
| while non-POD class types are initialized with their corresponding default constructors. | ||||
|  | ||||
| A ['declaration] can contain an ['initializer], which specifies the | ||||
| object's initial value. The initializer can be just '()', which states that | ||||
| the object shall be value-initialized (but see below). However, if a ['declaration] | ||||
| has no ['initializer] and it is of a non-`const`, non-`static` POD type, the | ||||
| initial value is indeterminate: (see [sect]8.5, \[dcl.init\], for the | ||||
| accurate definitions). | ||||
|  | ||||
| ``` | ||||
| int x; // no initializer. x value is indeterminate. | ||||
| __std_string__ s; // no initializer, s is default-constructed. | ||||
|  | ||||
| int y = int(); | ||||
| // y is initialized using copy-initialization | ||||
| // but the temporary uses an empty set of parentheses as the initializer, | ||||
| // so it is default-constructed. | ||||
| // A default constructed POD type is zero-initialized, | ||||
| // therefore, y == 0. | ||||
|  | ||||
| void foo ( __std_string__ ) ; | ||||
| foo ( __std_string__() ) ; | ||||
| // the temporary string is default constructed | ||||
| // as indicated by the initializer () | ||||
| ``` | ||||
|  | ||||
| [#sec:valueinit] | ||||
| [h5 value-initialization] | ||||
|  | ||||
| The first [@http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html Technical | ||||
| Corrigendum for the C++ Standard] (TC1), whose draft was released to the public in | ||||
| November 2001, introduced [@http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#178 Core | ||||
| Issue 178], among many other issues. | ||||
|  | ||||
| That issue introduced the new concept of `value-initialization`, and also fixed the | ||||
| wording for zero-initialization. Informally, value-initialization is similar to | ||||
| default-initialization with the exception that in some cases non-static data members | ||||
| and base class sub-objects are also value-initialized. | ||||
|  | ||||
| The difference is that an object that is value-initialized will not have, or at least | ||||
| is less likely to have, indeterminate values for data members and base class sub-objects; | ||||
| unlike the case of an object default constructed (see Core Issue 178 for a | ||||
| normative description). | ||||
|  | ||||
| In order to specify value-initialization of an object we need to use the | ||||
| empty-set initializer: `()`. | ||||
|  | ||||
| As before, a declaration with no initializer specifies default-initialization, | ||||
| and a declaration with a non-empty initializer specifies copy (`=xxx`) or | ||||
| direct (`xxx`) initialization. | ||||
|  | ||||
| ``` | ||||
| template<class T> void eat(T); | ||||
|  | ||||
| int x ; // indeterminate initial value. | ||||
|  | ||||
| __std_string__ s; // default-initialized. | ||||
|  | ||||
| eat ( int() ) ; // value-initialized | ||||
|  | ||||
| eat ( __std_string__() ) ; // value-initialized | ||||
| ``` | ||||
|  | ||||
| [#sec:valueinitsyn] | ||||
| [h5 value-initialization syntax] | ||||
|  | ||||
| Value initialization is specified using `()`. However, the empty set of | ||||
| parentheses is not permitted by the syntax of initializers because it is | ||||
| parsed as the declaration of a function taking no arguments: | ||||
|  | ||||
| ``` | ||||
| int x() ; // declares function int(*)() | ||||
| ``` | ||||
|  | ||||
| Thus, the empty `()` must be put in some other initialization context. | ||||
|  | ||||
| One alternative is to use copy-initialization syntax: | ||||
|  | ||||
| ``` | ||||
| int x = int(); | ||||
| ``` | ||||
|  | ||||
| This works perfectly fine for POD types. But for non-POD class types, | ||||
| copy-initialization searches for a suitable constructor, which could be, | ||||
| for instance, the copy-constructor. It also searches for a suitable conversion | ||||
| sequence but this does not apply in this context. | ||||
|  | ||||
| For an arbitrary unknown type, using this syntax may not have the | ||||
| value-initialization effect intended because we don't know if a copy | ||||
| from a default constructed object is exactly the same as a default | ||||
| constructed object, and the compiler is allowed, in | ||||
| some cases, but never required to, optimize the copy away. | ||||
|  | ||||
| One possible generic solution is to use value-initialization of a non static | ||||
| data member: | ||||
|  | ||||
| ``` | ||||
| template<class T> | ||||
| struct W | ||||
| { | ||||
|     // value-initialization of 'data' here. | ||||
|     W() : data() {} | ||||
|  | ||||
|     T data; | ||||
| }; | ||||
|  | ||||
| W<int> w; | ||||
| // w.data is value-initialized for any type. | ||||
| ``` | ||||
|  | ||||
| This is the solution as it was supplied by earlier versions of the | ||||
| `__value_initialized__<T>` template class. Unfortunately this approach | ||||
| suffered from various compiler issues. | ||||
|  | ||||
| [#sec:compiler_issues] | ||||
| [h5 Compiler issues] | ||||
|  | ||||
| Various compilers have not yet fully implemented value-initialization. | ||||
| So when an object should be ['value-initialized] according to the C++ Standard, | ||||
| it ['may] in practice still be left uninitialized, because of those | ||||
| compiler issues. It is hard to make a general statement on what those issues | ||||
| are like, because they depend on the compiler you are using, its version number, | ||||
| and the type of object you would like to have value-initialized. | ||||
|  | ||||
| All compilers we have tested so far support value-initialization for arithmetic types properly. | ||||
| However, various compilers may leave some types of ['aggregates] uninitialized, when they | ||||
| should be value-initialized. Value-initialization of objects of a pointer-to-member type may also | ||||
| go wrong on various compilers. | ||||
|  | ||||
| At the moment of writing, May 2010, the following reported issues regarding | ||||
| value-initialization are still there in current compiler releases: | ||||
|  | ||||
|  | ||||
|  | ||||
| * [@https://connect.microsoft.com/VisualStudio/feedback/details/100744 Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression]: Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005. | ||||
| * [@http://connect.microsoft.com/VisualStudio/feedback/details/484295 Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor] Reported by Sylvester Hesp, 2009. | ||||
| * [@https://connect.microsoft.com/VisualStudio/feedback/details/499606 Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization] Reported by Alex Vakulenko, 2009 | ||||
| * [@http://qc.embarcadero.com/wc/qcmain.aspx?d=83751 Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized] Reported by Niels Dekker (LKEB), 2010. | ||||
| * [@http://qc.embarcadero.com/wc/qcmain.aspx?d=83851 Embarcadero/C++Builder Report 83851, Value-initialized temporary triggers internal backend error C1798] Reported by Niels Dekker, 2010. | ||||
| * [@http://qc.embarcadero.com/wc/qcmain.aspx?d=84279 Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"] Reported by Niels Dekker, 2010 | ||||
| * Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate. Reported to Steve Clamage by Niels Dekker, 2010. | ||||
| * IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate. Reported to Michael Wong by Niels Dekker, 2010. | ||||
| * Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error on Intel 11.1. Reported by John Maddock, 2010. | ||||
|  | ||||
| Note that all known GCC issues regarding value-initialization are fixed with GCC version 4.4, including | ||||
| [@http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 GCC Bug 30111]. Clang also has completely implemented | ||||
| value-initialization, as far as we know, now that [@http://llvm.org/bugs/show_bug.cgi?id=7139 Clang Bug 7139] | ||||
| is fixed. | ||||
|  | ||||
| New versions of __value_initialized__ (Boost release version 1.35 or higher) offer a workaround to these | ||||
| issues: __value_initialized__ may now clear its internal data, prior to constructing the object that it | ||||
| contains. It will do so for those compilers that need to have such a workaround, based on the | ||||
| [@boost:/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_defects | ||||
| compiler defect macro] `BOOST_NO_COMPLETE_VALUE_INITIALIZATION`. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [#sec:types] | ||||
| [section Types and objects] | ||||
|  | ||||
| [#sec:val_init] | ||||
| [section `template class value_initialized<T>`] | ||||
|  | ||||
| ``` | ||||
| namespace boost { | ||||
|  | ||||
| template<class T> | ||||
| class __value_initialized__ | ||||
| { | ||||
|  | ||||
|   public : | ||||
|  | ||||
|     __value_initialized__() : x() {} | ||||
|  | ||||
|     operator T const &() const { return x ; } | ||||
|  | ||||
|     operator T&() { return x ; } | ||||
|  | ||||
|     T const &data() const { return x ; } | ||||
|  | ||||
|     T& data() { return x ; } | ||||
|  | ||||
|     void swap( __value_initialized__& ); | ||||
|  | ||||
|   private : | ||||
|  | ||||
|     [unspecified] x ; | ||||
|  | ||||
| } ; | ||||
|  | ||||
| template<class T> | ||||
|  | ||||
| T const& get ( __value_initialized__<T> const& x ) | ||||
| { | ||||
|   return x.data(); | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| T& get ( __value_initialized__<T>& x ) | ||||
| { | ||||
|   return x.data(); | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| void swap ( __value_initialized__<T>& lhs, __value_initialized__<T>& rhs ) | ||||
| { | ||||
|   lhs.swap(rhs); | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
| ``` | ||||
|  | ||||
| An object of this template class is a `T`-wrapper convertible to `'T&'` whose | ||||
| wrapped object (data member of type `T`) is [link sec:valueinit value-initialized] upon default-initialization | ||||
| of this wrapper class: | ||||
|  | ||||
| ``` | ||||
| int zero = 0; | ||||
| __value_initialized__<int> x; | ||||
| assert( x == zero ) ; | ||||
|  | ||||
| __std_string__ def; | ||||
| __value_initialized__< __std_string__ > y; | ||||
| assert( y == def ) ; | ||||
| ``` | ||||
|  | ||||
| The purpose of this wrapper is to provide a consistent syntax for value initialization | ||||
| of scalar, union and class types (POD and non-POD) since the correct syntax for value | ||||
| initialization varies (see [link sec:valueinitsyn value-initialization syntax]). | ||||
|  | ||||
| The wrapped object can be accessed either through the conversion operator | ||||
| `T&`, the member function `data()`, or the non-member function `get()`: | ||||
|  | ||||
| ``` | ||||
| void watch(int); | ||||
|  | ||||
| __value_initialized__<int> x; | ||||
|  | ||||
| watch(x) ; // operator T& used. | ||||
| watch(x.data()); | ||||
| watch( get(x) ) // function get() used | ||||
| ``` | ||||
|  | ||||
| Both `const` and non-`const` objects can be wrapped. Mutable objects can be | ||||
| modified directly from within the wrapper but constant objects cannot: | ||||
|  | ||||
| When `T` is a __Swappable__ type, `__value_initialized__<T>` | ||||
| is swappable as well, by calling its `swap` member function | ||||
| as well as by calling `boost::swap`. | ||||
|  | ||||
| ``` | ||||
| __value_initialized__<int> x; | ||||
| static_cast<int&>(x) = 1 ; // OK | ||||
| get(x) = 1 ; // OK | ||||
|  | ||||
| __value_initialized__<int const> y ; | ||||
| static_cast<int&>(y) = 1 ; // ERROR: cannot cast to int& | ||||
| static_cast<int const&>(y) = 1 ; // ERROR: cannot modify a const value | ||||
| get(y) = 1 ; // ERROR: cannot modify a const value | ||||
| ``` | ||||
|  | ||||
| [warning | ||||
|  | ||||
| The __value_initialized__ implementation of Boost version 1.40.0 and older | ||||
| allowed ['non-const] access to the wrapped object, from a constant wrapper, | ||||
| both by its conversion operator and its `data()` member function. | ||||
|  | ||||
| For example: | ||||
|  | ||||
| ``` | ||||
| __value_initialized__<int> const x_c; | ||||
| int& xr = x_c ; // OK, conversion to int& available even though x_c is itself const. | ||||
| xr = 2 ; | ||||
| ``` | ||||
|  | ||||
| The reason for this obscure behavior was that some compilers did not accept the following valid code: | ||||
|  | ||||
| ``` | ||||
| struct X | ||||
| { | ||||
|   operator int&() ; | ||||
|     operator int const&() const ; | ||||
|   }; | ||||
|   X x ; | ||||
|   (x == 1) ; // ERROR HERE! | ||||
| ``` | ||||
|  | ||||
| The current version of __value_initialized__ no longer has this obscure behavior. | ||||
| As compilers nowadays widely support overloading the conversion operator by having a `const` | ||||
| and a `non-const` version, we have decided to fix the issue accordingly. So the current version | ||||
| supports the idea of logical constness. | ||||
|  | ||||
| ] | ||||
|  | ||||
| [h5 Recommended practice: The non-member get() idiom] | ||||
|  | ||||
| The obscure behavior of being able to modify a non-`const` | ||||
| wrapped object from within a constant wrapper (as was supported by previous | ||||
| versions of __value_initialized__) can be avoided if access to the wrapped object | ||||
| is always performed with the `get()` idiom: | ||||
|  | ||||
| ``` | ||||
| value_initialized<int> x; | ||||
| get(x) = 1; // OK | ||||
| value_initialized<int const> cx; | ||||
| get(x) = 1; // ERROR: Cannot modify a const object | ||||
|  | ||||
| value_initialized<int> const x_c; | ||||
| get(x_c) = 1; // ERROR: Cannot modify a const object | ||||
|  | ||||
| value_initialized<int const> const cx_c; | ||||
| get(cx_c) = 1; // ERROR: Cannot modify a const object | ||||
| ``` | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [#sec:initialized] | ||||
| [section `template class initialized<T>`] | ||||
|  | ||||
|  | ||||
| ``` | ||||
| namespace boost { | ||||
|  | ||||
| template<class T> | ||||
| class __initialized__ | ||||
| { | ||||
|  | ||||
|   public : | ||||
|  | ||||
|     __initialized__() : x() {} | ||||
|  | ||||
|     explicit __initialized__(T const & arg) : x(arg) {} | ||||
|  | ||||
|     operator T const &() const; | ||||
|  | ||||
|     operator T&(); | ||||
|  | ||||
|     T const &data() const; | ||||
|  | ||||
|     T& data(); | ||||
|  | ||||
|     void swap( __initialized__& ); | ||||
|  | ||||
|   private : | ||||
|  | ||||
|     [unspecified] x ; | ||||
|  | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| T const& get ( __initialized__<T> const& x ); | ||||
|  | ||||
| template<class T> | ||||
| T& get ( __initialized__<T>& x ); | ||||
|  | ||||
| template<class T> | ||||
| void swap ( __initialized__<T>& lhs, __initialized__<T>& rhs ); | ||||
|  | ||||
| } // namespace boost | ||||
| ``` | ||||
|  | ||||
| The template class `boost::__initialized__<T>` supports both value-initialization | ||||
| and direct-initialization, so its interface is a superset of the interface | ||||
| of `__value_initialized__<T>`: Its default-constructor value-initializes the | ||||
| wrapped object just like the default-constructor of `__value_initialized__<T>`, | ||||
| but `boost::__initialized__<T>` also offers an extra `explicit` | ||||
| constructor, which direct-initializes the wrapped object by the specified value. | ||||
|  | ||||
| `__initialized__<T>` is especially useful when the wrapped | ||||
| object must be either value-initialized or direct-initialized, depending on | ||||
| runtime conditions. For example, `__initialized__<T>` could | ||||
| hold the value of a data member that may be value-initialized by some | ||||
| constructors, and direct-initialized by others. | ||||
|  | ||||
| On the other hand, if it is known beforehand that the | ||||
| object must ['always] be value-initialized, `__value_initialized__<T>` | ||||
| may be preferable. And if the object must always be | ||||
| direct-initialized, none of the two wrappers really needs to be used. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [#sec:initialized_value] | ||||
| [section `initialized_value`] | ||||
|  | ||||
| ``` | ||||
| namespace boost { | ||||
| class __initialized_value_t__ | ||||
| { | ||||
|   public : | ||||
|     template <class T> operator T() const ; | ||||
| }; | ||||
|  | ||||
| __initialized_value_t__ const initialized_value = {} ; | ||||
|  | ||||
| } // namespace boost | ||||
| ``` | ||||
|  | ||||
| __initialized_value__ provides a convenient way to get | ||||
| an initialized value: its conversion operator provides an appropriate | ||||
| ['value-initialized] object for any __CopyConstructible__ type. | ||||
|  | ||||
| Suppose you need to have an initialized variable of type `T`. | ||||
| You could do it as follows: | ||||
|  | ||||
| ``` | ||||
| T var = T(); | ||||
| ``` | ||||
|  | ||||
| But as mentioned before, this form suffers from various compiler issues. | ||||
| The template __value_initialized__ offers a workaround: | ||||
|  | ||||
| ``` | ||||
| T var = get( __value_initialized__<T>() ); | ||||
| ``` | ||||
|  | ||||
| Unfortunately both forms repeat the type name, which | ||||
| is rather short now (`T`), but could of course be | ||||
| more like `Namespace::Template<Arg>::Type`. | ||||
|  | ||||
| Instead, one could use __initialized_value__ as follows: | ||||
|  | ||||
| ``` | ||||
| T var = __initialized_value__; | ||||
| ``` | ||||
|  | ||||
| [endsect] | ||||
| [endsect] | ||||
|  | ||||
| [#sec:references] | ||||
| [section References] | ||||
|  | ||||
| # Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote various papers, | ||||
| proposing to extend the support for brace-enclosed ['initializer lists] | ||||
| in C++. This [@https://en.cppreference.com/w/cpp/language/list_initialization feature] has | ||||
| now been available since C++11. This would allow a variable `var` of any __DefaultConstructible__ type | ||||
| `T` to be ['value-initialized] by doing `T var = {}`. The papers are listed at Bjarne's web page, | ||||
| [@http://www.research.att.com/~bs/WG21.html My C++ Standards committee papers]. | ||||
|  | ||||
| # Scott Meyers, Effective C++, Third Edition, item 6, ['Explicitly disallow the use of | ||||
| compiler-generated functions you do not want], [@http://www.aristeia.com/books.html Scott Meyers: Books and CDs] | ||||
|  | ||||
| # The C++ Standard, Second edition (2003), ISO/IEC 14882:2003 | ||||
|  | ||||
| # POD stands for [@https://en.cppreference.com/w/cpp/named_req/PODType "Plain Old Data"] | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [/===============] | ||||
| [xinclude tmp/value_init_reference.xml] | ||||
| [/===============] | ||||
|  | ||||
| [#sec:acknowledgements] | ||||
| [section Acknowledgements] | ||||
|  | ||||
| __value_initialized__ was developed by Fernando Cacciola, with help and suggestions | ||||
| from David Abrahams and Darin Adler. | ||||
|  | ||||
| Special thanks to Bjorn Karlsson who carefully edited and completed this documentation. | ||||
|  | ||||
| __value_initialized__ was reimplemented by Fernando Cacciola and Niels Dekker | ||||
| for Boost release version 1.35 (2008), offering a workaround to various compiler issues. | ||||
|  | ||||
| `boost::__initialized__` was very much inspired by feedback from Edward Diener and Jeffrey Hellrung. | ||||
|  | ||||
| __initialized_value__ was written by Niels Dekker, and added to Boost release version 1.36 (2008). | ||||
|  | ||||
| Developed by [@mailto:fernando_cacciola@hotmail.com Fernando Cacciola]. The latest version of | ||||
| this file can be found at [@http://www.boost.org www.boost.org]. | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
| [endsect] | ||||
							
								
								
									
										483
									
								
								enable_if.html
									
									
									
									
									
								
							
							
						
						
									
										483
									
								
								enable_if.html
									
									
									
									
									
								
							| @@ -1,19 +1,464 @@ | ||||
| <html> | ||||
| <head> | ||||
|     <title>Boost.EnableIf</title> | ||||
|     <meta http-equiv="refresh" content="0; URL=../core/doc/html/core/enable_if.html"> | ||||
| </head> | ||||
| <body> | ||||
| Automatic redirection failed, please go to | ||||
| <a href="../core/doc/html/core/enable_if.html">../core/doc/html/core/enable_if.html</a> | ||||
| <hr> | ||||
| <tt> | ||||
|     Boost.EnableIf<br> | ||||
|     <br> | ||||
|     Distributed under the Boost Software License, Version 1.0. | ||||
|     (See accompanying file LICENSE_1_0.txt or copy at | ||||
|     <a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>) <br> | ||||
|     <br> | ||||
| </tt> | ||||
| </body> | ||||
| </html> | ||||
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | ||||
|             "http://www.w3.org/TR/REC-html40/loose.dtd"> | ||||
| <HTML> | ||||
| <HEAD><TITLE>enable_if</TITLE> | ||||
|  | ||||
| <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||
| <META name="GENERATOR" content="Microsoft FrontPage 5.0"> | ||||
| </HEAD> | ||||
| <BODY > | ||||
| <!--HEVEA command line is: hevea -nosymb -noiso -pedantic -v enable_if_docs_for_boost.tex --> | ||||
| <!--HTMLHEAD--> | ||||
| <!--ENDHTML--> | ||||
| <!--PREFIX <ARG ></ARG>--> | ||||
| <!--CUT DEF section 1 --> | ||||
| <BR> | ||||
| <BR> | ||||
|  | ||||
|  | ||||
| <h1> | ||||
| <img border="0" src="../../boost.png" align="center" width="277" height="86">enable_if</h1> | ||||
| <BR> | ||||
| <BR> | ||||
| Copyright 2003 Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine.<BR> | ||||
| Copyright 2011 Matt Calabrese.<BR> | ||||
| <BR> | ||||
| <!--TOC section Introduction--> | ||||
|  | ||||
| <H2><A NAME="htoc1">1</A>  Introduction</H2><!--SEC END --> | ||||
|  | ||||
| <A NAME="introduction"></A> | ||||
| The <TT>enable_if</TT> family of templates is a set of tools to allow a function template or a class template specialization  | ||||
| to include or exclude itself from a set of matching functions or specializations | ||||
| based on properties of its template arguments.  | ||||
| For example, one can define function templates that | ||||
| are only enabled for, and thus only match, an arbitrary set of types | ||||
| defined by a traits class. The <TT>enable_if</TT> templates can also be | ||||
| applied to enable class template specializations. Applications of | ||||
| <TT>enable_if</TT> are discussed in length | ||||
| in [<A HREF="#jarvi:03:cuj_arbitrary_overloading"><CITE>1</CITE></A>] and [<A HREF="#jarvi:03:c++typeclasses"><CITE>2</CITE></A>].<BR> | ||||
| <BR> | ||||
| <!--TOC subsection Synopsis--> | ||||
|  | ||||
| <H3><A NAME="htoc2">1.1</A>  Synopsis</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:synopsis"></A> | ||||
| <PRE>namespace boost { | ||||
|   template <class Cond, class T = void> struct enable_if; | ||||
|   template <class Cond, class T = void> struct disable_if; | ||||
|   template <class Cond, class T> struct lazy_enable_if; | ||||
|   template <class Cond, class T> struct lazy_disable_if; | ||||
|  | ||||
|   template <bool B, class T = void> struct enable_if_c; | ||||
|   template <bool B, class T = void> struct disable_if_c; | ||||
|   template <bool B, class T> struct lazy_enable_if_c; | ||||
|   template <bool B, class T> struct lazy_disable_if_c; | ||||
| } | ||||
| </PRE> | ||||
| <!--TOC subsection Background--> | ||||
|  | ||||
| <H3><A NAME="htoc3">1.2</A>  Background</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:background"></A> | ||||
| Sensible operation of template function overloading in C++ relies | ||||
| on the <EM>SFINAE</EM> (substitution-failure-is-not-an-error) | ||||
| principle [<A HREF="#vandevoorde2002:templates"><CITE>3</CITE></A>]: if an invalid argument | ||||
| or return type is formed during the instantiation of a function | ||||
| template, the instantiation is removed from the overload resolution | ||||
| set instead of causing a compilation error. The following example,  | ||||
| taken from [<A HREF="#jarvi:03:cuj_arbitrary_overloading"><CITE>1</CITE></A>], | ||||
| demonstrates why this is important: | ||||
| <PRE>int negate(int i) { return -i; } | ||||
|  | ||||
| template <class F> | ||||
| typename F::result_type negate(const F& f) { return -f(); } | ||||
|  | ||||
| </PRE> | ||||
| Suppose the compiler encounters the call <TT>negate(1)</TT>. The first | ||||
| definition is obviously a better match, but the compiler must | ||||
| nevertheless consider (and instantiate the prototypes) of both | ||||
| definitions to find this out. Instantiating the latter definition with | ||||
| <TT>F</TT> as <TT>int</TT> would result in: | ||||
| <PRE>int::result_type negate(const int&); | ||||
|  | ||||
| </PRE> | ||||
| where the return type is invalid. If this were an error, adding an unrelated function template  | ||||
| (that was never called) could break otherwise valid code. | ||||
| Due to the SFINAE principle the above example is not, however, erroneous.  | ||||
| The latter definition of <TT>negate</TT> is simply removed from the overload resolution set.<BR> | ||||
| <BR> | ||||
| The <TT>enable_if</TT> templates are tools for controlled creation of the SFINAE | ||||
| conditions.<BR> | ||||
| <BR> | ||||
| <!--TOC section The <TT>enable_if</TT> templates--> | ||||
|  | ||||
| <H2><A NAME="htoc4">2</A>  The <TT>enable_if</TT> templates</H2><!--SEC END --> | ||||
|  | ||||
| <A NAME="enable_if"></A> | ||||
| The names of the <TT>enable_if</TT> templates have three parts: an optional <TT>lazy_</TT> tag,  | ||||
| either <TT>enable_if</TT> or <TT>disable_if</TT>, and an optional <TT>_c</TT> tag. | ||||
| All eight combinations of these parts are supported. | ||||
| The meaning of the <TT>lazy_</TT> tag is described in Section <A HREF="#sec:enable_if_lazy">3.3</A>. | ||||
| The second part of the name indicates whether a true condition argument should  | ||||
| enable or disable the current overload. | ||||
| The third part of the name indicates whether the condition argument is a <TT>bool</TT> value  | ||||
| (<TT>_c</TT> suffix), or a type containing a static <TT>bool</TT> constant named <TT>value</TT> (no suffix). | ||||
| The latter version interoperates with Boost.MPL. <BR> | ||||
| <BR> | ||||
| The definitions of <TT>enable_if_c</TT> and <TT>enable_if</TT> are as follows (we use <TT>enable_if</TT> templates  | ||||
| unqualified but they are in the <TT>boost</TT> namespace). | ||||
| <PRE>template <bool B, class T = void> | ||||
| struct enable_if_c { | ||||
|   typedef T type; | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| struct enable_if_c<false, T> {}; | ||||
|  | ||||
| template <class Cond, class T = void> | ||||
| struct enable_if : public enable_if_c<Cond::value, T> {}; | ||||
|  | ||||
| </PRE> | ||||
| An instantiation of the <TT>enable_if_c</TT> template with the parameter | ||||
| <TT>B</TT> as <TT>true</TT> contains a member type <TT>type</TT>, defined | ||||
| to be <TT>T</TT>. If <TT>B</TT> is | ||||
| <TT>false</TT>, no such member is defined. Thus  | ||||
| <TT>enable_if_c<B, T>::type</TT> is either a valid or an invalid type | ||||
| expression, depending on the value of <TT>B</TT>. | ||||
| When valid, <TT>enable_if_c<B, T>::type</TT> equals <TT>T</TT>. | ||||
| The <TT>enable_if_c</TT> template can thus be used for controlling when functions are considered for | ||||
| overload resolution and when they are not.  | ||||
| For example, the following function is defined for all arithmetic types (according to the | ||||
| classification of the <A HREF="../type_traits/index.html">Boost type_traits library</A>): | ||||
| <PRE>template <class T> | ||||
| typename enable_if_c<boost::is_arithmetic<T>::value, T>::type  | ||||
| foo(T t) { return t; } | ||||
|  | ||||
| </PRE> | ||||
| The <TT>disable_if_c</TT> template is provided as well, and has the | ||||
| same functionality as <TT>enable_if_c</TT> except for the negated condition. The following | ||||
| function is enabled for all non-arithmetic types. | ||||
| <PRE>template <class T> | ||||
| typename disable_if_c<boost::is_arithmetic<T>::value, T>::type  | ||||
| bar(T t) { return t; } | ||||
|  | ||||
| </PRE> | ||||
| For easier syntax in some cases and interoperation with Boost.MPL we provide versions of | ||||
| the <TT>enable_if</TT> templates taking any type with a <TT>bool</TT> member constant named  | ||||
| <TT>value</TT> as the condition argument. | ||||
| The MPL <TT>bool_</TT>, <TT>and_</TT>, <TT>or_</TT>, and <TT>not_</TT> templates are likely to be  | ||||
| useful for creating such types. Also, the traits classes in the Boost.Type_traits library  | ||||
| follow this convention.  | ||||
| For example, the above example function <TT>foo</TT> can be alternatively written as: | ||||
| <PRE>template <class T> | ||||
| typename enable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t) { return t; } | ||||
|  | ||||
| </PRE> | ||||
|  | ||||
| <!--TOC section Using <TT>enable_if</TT>--> | ||||
|  | ||||
| <H2><A NAME="htoc5">3</A>  Using <TT>enable_if</TT></H2><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:using_enable_if"></A> | ||||
| The <TT>enable_if</TT> templates are defined in | ||||
| <TT>boost/utility/enable_if.hpp</TT>, which is included by <TT>boost/utility.hpp</TT>.<BR> | ||||
| <BR> | ||||
| With respect to function templates, <TT>enable_if</TT> can be used in multiple different ways: | ||||
|  | ||||
| <UL> | ||||
| <LI>As the return type of an instantiatied function | ||||
| <LI>As an extra parameter of an instantiated function | ||||
| <LI>As an extra template parameter (useful only in a compiler that supports C++0x default | ||||
| arguments for function template parameters, see <A href="#sec:enable_if_0x">Enabling function | ||||
| templates in C++0x</a> for details) | ||||
| </UL> | ||||
|  | ||||
| In the previous section, the return type form of <TT>enable_if</TT> was shown. As an example | ||||
| of using the form of <TT>enable_if</TT> that works via an extra function parameter, the | ||||
| <TT>foo</TT> function in the previous section could also be written | ||||
| as: | ||||
| <PRE>template <class T> | ||||
| T foo(T t, typename enable_if<boost::is_arithmetic<T> >::type* dummy = 0);  | ||||
|  | ||||
| </PRE>Hence, an extra parameter of type <TT>void*</TT> is added, but it is given  | ||||
| a default value to keep the parameter hidden from client code. | ||||
| Note that the second template argument was not given to <TT>enable_if</TT>, as the default  | ||||
| <TT>void</TT> gives the desired behavior.<BR> | ||||
| <BR> | ||||
| Which way to write the enabler is largely a matter of taste, but for certain functions, only a | ||||
| subset of the options is possible: | ||||
| <UL><LI> | ||||
| Many operators have a fixed number of arguments, thus <TT>enable_if</TT> must be used either in the | ||||
| return type or in an extra template parameter. | ||||
| <LI>Functions that have a variadic parameter list must use either the return type form or an extra | ||||
| template parameter. | ||||
| <LI>Constructors do not have a return type so you must use either an extra function parameter or an | ||||
| extra template parameter. | ||||
| <LI>Constructors that have a variadic parameter list must an extra template parameter. | ||||
| <LI>Conversion operators can only be written with an extra template parameter. | ||||
| </UL> | ||||
| <!--TOC subsection Enabling function templates in C++0x--> | ||||
|  | ||||
| <A NAME="sec:enable_if_0x"></A> | ||||
| <H3><A NAME="htoc7">3.1</A>  Enabling function templates in C++0x</H3><!--SEC END --> | ||||
|  | ||||
| In a compiler which supports C++0x default arguments for function template parameters, you can | ||||
| enable and disable function templates by adding an additional template parameter. This approach | ||||
| works in all situations where you would use either the return type form of <TT>enable_if</TT> or | ||||
| the function parameter form, including operators, constructors, variadic function templates, and | ||||
| even overloaded conversion operations. | ||||
|  | ||||
| As an example: | ||||
|  | ||||
| <PRE>#include <boost/type_traits/is_arithmetic.hpp> | ||||
| #include <boost/type_traits/is_pointer.hpp> | ||||
| #include <boost/utility/enable_if.hpp> | ||||
|  | ||||
| class test | ||||
| { | ||||
| public: | ||||
|   // A constructor that works for any argument list of size 10 | ||||
|   template< class... T | ||||
|           , typename boost::enable_if_c< sizeof...( T ) == 10, int >::type = 0 | ||||
|           > | ||||
|   test( T&&... ); | ||||
|  | ||||
|   // A conversion operation that can convert to any arithmetic type | ||||
|   template< class T | ||||
|           , typename boost::enable_if< boost::is_arithmetic< T >, int >::type = 0 | ||||
|           > | ||||
|   operator T() const; | ||||
|  | ||||
|   // A conversion operation that can convert to any pointer type | ||||
|   template< class T | ||||
|           , typename boost::enable_if< boost::is_pointer< T >, int >::type = 0 | ||||
|           > | ||||
|   operator T() const; | ||||
| }; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   // Works | ||||
|   test test_( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ); | ||||
|  | ||||
|   // Fails as expected | ||||
|   test fail_construction( 1, 2, 3, 4, 5 ); | ||||
|  | ||||
|   // Works by calling the conversion operator enabled for arithmetic types | ||||
|   int arithmetic_object = test_; | ||||
|  | ||||
|   // Works by calling the conversion operator enabled for pointer types | ||||
|   int* pointer_object = test_; | ||||
|  | ||||
|   // Fails as expected | ||||
|   struct {} fail_conversion = test_; | ||||
| } | ||||
|  | ||||
| </PRE> | ||||
|  | ||||
| <!--TOC subsection Enabling template class specializations--> | ||||
|  | ||||
| <H3><A NAME="htoc7">3.2</A>  Enabling template class specializations</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:enable_if_classes"></A> | ||||
| Class template specializations can be enabled or disabled with <TT>enable_if</TT>. | ||||
| One extra template parameter needs to be added for the enabler expressions. | ||||
| This parameter has the default value <TT>void</TT>. | ||||
| For example: | ||||
| <PRE>template <class T, class Enable = void>  | ||||
| class A { ... }; | ||||
|  | ||||
| template <class T> | ||||
| class A<T, typename enable_if<is_integral<T> >::type> { ... }; | ||||
|  | ||||
| template <class T> | ||||
| class A<T, typename enable_if<is_float<T> >::type> { ... }; | ||||
|  | ||||
| </PRE>Instantiating <TT>A</TT> with any integral type matches the first specialization, | ||||
| whereas any floating point type matches the second one. All other types | ||||
| match the primary template. | ||||
| The condition can be any compile-time boolean expression that depends on the  | ||||
| template arguments of the class. | ||||
| Note that again, the second argument to <TT>enable_if</TT> is not needed; the default (<TT>void</TT>)  | ||||
| is the correct value.<BR> | ||||
| <BR> | ||||
| <!--TOC subsection Overlapping enabler conditions--> | ||||
|  | ||||
| <H3><A NAME="htoc8">3.3</A>  Overlapping enabler conditions</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:overlapping_conditions"></A> | ||||
| Once the compiler has examined the enabling conditions and included the | ||||
| function into the overload resolution set, normal C++ overload resolution  | ||||
| rules are used to select the best matching function. | ||||
| In particular, there is no ordering between enabling conditions. | ||||
| Function templates with enabling conditions that are not mutually exclusive can  | ||||
| lead to ambiguities. For example: | ||||
| <PRE>template <class T> | ||||
| typename enable_if<boost::is_integral<T>, void>::type  | ||||
| foo(T t) {} | ||||
|  | ||||
| template <class T> | ||||
| typename enable_if<boost::is_arithmetic<T>, void>::type  | ||||
| foo(T t) {} | ||||
|  | ||||
| </PRE> | ||||
| All integral types are also arithmetic. Therefore, say, for the call <TT>foo(1)</TT>, | ||||
| both conditions are true and both functions are thus in the overload resolution set. | ||||
| They are both equally good matches and thus ambiguous. | ||||
| Of course, more than one enabling condition can be simultaneously true as long as  | ||||
| other arguments disambiguate the functions.<BR> | ||||
| <BR> | ||||
| The above discussion applies to using <TT>enable_if</TT> in class template | ||||
| partial specializations as well.<BR> | ||||
| <BR> | ||||
| <!--TOC subsection Lazy <TT>enable_if</TT>--> | ||||
|  | ||||
| <H3><A NAME="htoc9">3.4</A>  Lazy <TT>enable_if</TT></H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:enable_if_lazy"></A> | ||||
| In some cases it is necessary to avoid instantiating part of a | ||||
| function signature unless an enabling condition is true. For example: | ||||
| <PRE>template <class T, class U> class mult_traits; | ||||
|  | ||||
| template <class T, class U> | ||||
| typename enable_if<is_multipliable<T, U>, typename mult_traits<T, U>::type>::type | ||||
| operator*(const T& t, const U& u) { ... } | ||||
|  | ||||
| </PRE>Assume the class template <TT>mult_traits</TT> is a traits class defining  | ||||
| the resulting type of a multiplication operator. The <TT>is_multipliable</TT> traits | ||||
| class specifies for which types to enable the operator. Whenever | ||||
| <TT>is_multipliable<A, B>::value</TT> is <TT>true</TT> for some types <TT>A</TT> and <TT>B</TT>, | ||||
| then <TT>mult_traits<A, B>::type</TT> is defined.<BR> | ||||
| <BR> | ||||
| Now, trying to invoke (some other overload) of <TT>operator*</TT> with, say, operand types <TT>C</TT> and <TT>D</TT>  | ||||
| for which <TT>is_multipliable<C, D>::value</TT> is <TT>false</TT>  | ||||
| and <TT>mult_traits<C, D>::type</TT> is not defined is an error on some compilers.  | ||||
| The SFINAE principle is not applied because | ||||
| the invalid type occurs as an argument to another template. The <TT>lazy_enable_if</TT>  | ||||
| and <TT>lazy_disable_if</TT> templates (and their <TT>_c</TT> versions) can be used in such | ||||
| situations: | ||||
| <PRE>template<class T, class U> | ||||
| typename lazy_enable_if<is_multipliable<T, U>, mult_traits<T, U> >::type | ||||
| operator*(const T& t, const U& u) { ... } | ||||
|  | ||||
| </PRE>The second argument of <TT>lazy_enable_if</TT> must be a class type | ||||
| that defines a nested type named <TT>type</TT> whenever the first | ||||
| parameter (the condition) is true.<BR> | ||||
| <BR> | ||||
| <!--TOC paragraph Note--> | ||||
|  | ||||
| <H5>Note</H5><!--SEC END --> | ||||
|  | ||||
| Referring to one member type or static constant in a traits class | ||||
| causes all of the members (type and static constant) of that | ||||
| specialization to be instantiated. Therefore, if your traits classes | ||||
| can sometimes contain invalid types, you should use two distinct | ||||
| templates for describing the conditions and the type mappings. In the | ||||
| above example, <TT>is_multipliable<T, U>::value</TT> defines when | ||||
| <TT>mult_traits<T, U>::type</TT> is valid.<BR> | ||||
| <BR> | ||||
| <!--TOC subsection Compiler workarounds--> | ||||
|  | ||||
| <H3><A NAME="htoc10">3.5</A>  Compiler workarounds</H3><!--SEC END --> | ||||
|  | ||||
| <A NAME="sec:workarounds"></A> | ||||
| Some compilers flag functions as ambiguous if the only distinguishing factor is a different  | ||||
| condition in an enabler (even though the functions could never be ambiguous). For example, | ||||
| some compilers (e.g. GCC 3.2) diagnose the following two functions as ambiguous: | ||||
| <PRE>template <class T> | ||||
| typename enable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t); | ||||
|  | ||||
| template <class T> | ||||
| typename disable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t); | ||||
|  | ||||
| </PRE>Two workarounds can be applied: | ||||
| <UL><LI> | ||||
| Use an extra dummy parameter which disambiguates the functions. Use a default value for | ||||
| it to hide the parameter from the caller. For example: | ||||
| <PRE>template <int> struct dummy { dummy(int) {} }; | ||||
|  | ||||
| template <class T> | ||||
| typename enable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t, dummy<0> = 0); | ||||
|  | ||||
| template <class T> | ||||
| typename disable_if<boost::is_arithmetic<T>, T>::type  | ||||
| foo(T t, dummy<1> = 0); | ||||
| </PRE><BR> | ||||
| <BR> | ||||
| <LI>Define the functions in different namespaces and bring them into a common | ||||
| namespace with <TT>using</TT> declarations: | ||||
| <PRE>namespace A { | ||||
|   template <class T> | ||||
|   typename enable_if<boost::is_arithmetic<T>, T>::type  | ||||
|   foo(T t); | ||||
| } | ||||
|  | ||||
| namespace B { | ||||
|   template <class T> | ||||
|   typename disable_if<boost::is_arithmetic<T>, T>::type  | ||||
|   foo(T t); | ||||
| } | ||||
|  | ||||
| using A::foo; | ||||
| using B::foo; | ||||
|  | ||||
| </PRE> | ||||
| Note that the second workaround above cannot be used for member | ||||
| templates. On the other hand, operators do not accept extra arguments, | ||||
| which makes the first workaround unusable. As the net effect, | ||||
| neither of the workarounds are of assistance for templated operators that | ||||
| need to be defined as member functions (assignment and | ||||
| subscript operators). | ||||
| </UL> | ||||
| <!--TOC section Acknowledgements--> | ||||
|  | ||||
| <H2><A NAME="htoc10">4</A>  Acknowledgements</H2><!--SEC END --> | ||||
|  | ||||
| We are grateful to Howard Hinnant, Jason Shirk, Paul Mensonides, and Richard | ||||
| Smith whose findings have influenced the library.<BR> | ||||
| <BR> | ||||
| <!--TOC section References--> | ||||
|  | ||||
| <H2>References</H2><!--SEC END --> | ||||
| <DL COMPACT=compact><DT><A NAME="jarvi:03:cuj_arbitrary_overloading"><FONT COLOR=purple>[1]</FONT></A><DD> | ||||
| Jaakko Järvi, Jeremiah Willcock, Howard Hinnant, and Andrew Lumsdaine. | ||||
| Function overloading based on arbitrary properties of types. | ||||
| <EM>C/C++ Users Journal</EM>, 21(6):25--32, June 2003.<BR> | ||||
| <BR> | ||||
| <DT><A NAME="jarvi:03:c++typeclasses"><FONT COLOR=purple>[2]</FONT></A><DD> | ||||
| Jaakko Järvi, Jeremiah Willcock, and Andrew Lumsdaine. | ||||
| Concept-controlled polymorphism. | ||||
| In Frank Pfennig and Yannis Smaragdakis, editors, <EM>Generative | ||||
|  Programming and Component Engineering</EM>, volume 2830 of <EM>LNCS</EM>, pages | ||||
|  228--244. Springer Verlag, September 2003.<BR> | ||||
| <BR> | ||||
| <DT><A NAME="vandevoorde2002:templates"><FONT COLOR=purple>[3]</FONT></A><DD> | ||||
| David Vandevoorde and Nicolai M. Josuttis. | ||||
| <EM>C++ Templates: The Complete Guide</EM>. | ||||
| Addison-Wesley, 2002.</DL> | ||||
|  | ||||
| <hr/> | ||||
|    <p>Copyright Jaakko Järvi<sup>*</sup>, Jeremiah Willcock<sup>*</sup>, Andrew Lumsdaine<sup>*</sup>, Matt Calabrese<BR> | ||||
| <EM>{jajarvi|jewillco|lums}@osl.iu.edu, rivorus@gmail.com</EM><BR> | ||||
| <sup>*</sup>Indiana University<BR> | ||||
| Open Systems Lab<br/> | ||||
| Use, modification and distribution are subject to the | ||||
| Boost Software License, Version 1.0. | ||||
| (See accompanying file LICENSE_1_0.txt | ||||
| or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> | ||||
|    http://www.boost.org/LICENSE_1_0.txt | ||||
| </a>). | ||||
| </p> | ||||
| <!--HTMLFOOT--> | ||||
| <!--ENDHTML--> | ||||
| <!--FOOTER--> | ||||
| <HR SIZE=2> | ||||
| <BLOCKQUOTE><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by | ||||
| </EM><A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html"><EM>H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A</EM></A><EM>. | ||||
| </EM></BLOCKQUOTE> | ||||
| </BODY> | ||||
| </HTML> | ||||
|   | ||||
							
								
								
									
										23
									
								
								enable_if/test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								enable_if/test/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| # Copyright David Abrahams 2003. | ||||
| # Distributed under the Boost Software License, Version 1.0.  | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at  | ||||
| # http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| # For more information, see http://www.boost.org/ | ||||
|  | ||||
| project | ||||
|     : requirements <library>/boost/test//boost_test_exec_monitor | ||||
|     ; | ||||
|  | ||||
| test-suite utility/enable_if | ||||
|         : | ||||
|         [ run constructors.cpp ] | ||||
|         [ run dummy_arg_disambiguation.cpp ] | ||||
|         [ run lazy.cpp ] | ||||
|         [ run lazy_test.cpp ] | ||||
|         [ run member_templates.cpp ] | ||||
|         [ run namespace_disambiguation.cpp ] | ||||
|         [ run no_disambiguation.cpp ] | ||||
|         [ run partial_specializations.cpp ] | ||||
|     ; | ||||
|  | ||||
							
								
								
									
										62
									
								
								enable_if/test/constructors.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								enable_if/test/constructors.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) The Trustees of Indiana University. | ||||
|  | ||||
| // Use, modification, and distribution is subject to the Boost Software | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits.hpp> | ||||
|  | ||||
| using boost::enable_if; | ||||
| using boost::disable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| struct container { | ||||
|   bool my_value; | ||||
|  | ||||
|   template <class T> | ||||
|   container(const T&, const typename enable_if<is_arithmetic<T>, T>::type * = 0): | ||||
|   my_value(true) {} | ||||
|  | ||||
|   template <class T> | ||||
|   container(const T&, const typename disable_if<is_arithmetic<T>, T>::type * = 0): | ||||
|   my_value(false) {} | ||||
| }; | ||||
|  | ||||
| // example from Howard Hinnant (tests enable_if template members of a templated class) | ||||
| template <class charT> | ||||
| struct xstring | ||||
| { | ||||
|   template <class It> | ||||
|   xstring(It begin, It end, typename  | ||||
|           disable_if<is_arithmetic<It> >::type* = 0) | ||||
|     : data(end-begin) {} | ||||
|    | ||||
|   int data; | ||||
| }; | ||||
|  | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(container(1).my_value); | ||||
|   BOOST_CHECK(container(1.0).my_value); | ||||
|  | ||||
|   BOOST_CHECK(!container("1").my_value);   | ||||
|   BOOST_CHECK(!container(static_cast<void*>(0)).my_value);   | ||||
|  | ||||
|   char sa[] = "123456"; | ||||
|   BOOST_CHECK(xstring<char>(sa, sa+6).data == 6); | ||||
|  | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										46
									
								
								enable_if/test/dummy_arg_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								enable_if/test/dummy_arg_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) The Trustees of Indiana University. | ||||
|  | ||||
| // Use, modification, and distribution is subject to the Boost Software | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::enable_if; | ||||
| using boost::disable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| template <int N> struct dummy { | ||||
|   dummy(int) {}; | ||||
| }; | ||||
|  | ||||
| template<class T> | ||||
| typename enable_if<is_arithmetic<T>, bool>::type | ||||
| arithmetic_object(T t, dummy<0> = 0) { return true; } | ||||
|  | ||||
| template<class T> | ||||
| typename disable_if<is_arithmetic<T>, bool>::type | ||||
| arithmetic_object(T t, dummy<1> = 0) { return false; } | ||||
|  | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(arithmetic_object(1)); | ||||
|   BOOST_CHECK(arithmetic_object(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!arithmetic_object("1"));   | ||||
|   BOOST_CHECK(!arithmetic_object(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										82
									
								
								enable_if/test/lazy.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								enable_if/test/lazy.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) The Trustees of Indiana University. | ||||
|  | ||||
| // Use, modification, and distribution is subject to the Boost Software | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_same.hpp> | ||||
|  | ||||
| using boost::enable_if_c; | ||||
| using boost::lazy_enable_if_c; | ||||
|  | ||||
| // This class provides a reduced example of a traits class for | ||||
| // computing the result of multiplying two types.  The member typedef | ||||
| // 'type' in this traits class defines the return type of this | ||||
| // operator.  The return type member is invalid unless both arguments | ||||
| // for mult_traits are values that mult_traits expects (ints in this | ||||
| // case).  This kind of situation may arise if a traits class only | ||||
| // makes sense for some set of types, not all C++ types. | ||||
|  | ||||
| template <class T> struct is_int { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = (boost::is_same<T, int>::value)); | ||||
| }; | ||||
|  | ||||
| template <class T, class U> | ||||
| struct mult_traits { | ||||
|   typedef typename T::does_not_exist type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct mult_traits<int, int> { | ||||
|   typedef int type; | ||||
| }; | ||||
|  | ||||
|  | ||||
| // Next, a forwarding function mult() is defined.  It is enabled only | ||||
| // when both arguments are of type int.  The first version, using | ||||
| // non-lazy enable_if_c does not work. | ||||
|  | ||||
| #if 0 | ||||
| template <class T, class U> | ||||
| typename enable_if_c< | ||||
|   is_int<T>::value && is_int<U>::value, | ||||
|   typename mult_traits<T, U>::type | ||||
| >::type | ||||
| mult(const T& x, const U& y) {return x * y;} | ||||
| #endif | ||||
|  | ||||
| // A correct version uses lazy_enable_if_c. | ||||
| // This template removes compiler errors from invalid code used as an | ||||
| // argument to enable_if_c. | ||||
|  | ||||
| #if 1 | ||||
| template <class T, class U> | ||||
| typename lazy_enable_if_c< | ||||
|   is_int<T>::value & is_int<U>::value, | ||||
|   mult_traits<T, U>  | ||||
| >::type | ||||
| mult(const T& x, const U& y) {return x * y;} | ||||
| #endif | ||||
|  | ||||
| double mult(int i, double d) { return (double)i * d; } | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|  | ||||
|  | ||||
|   BOOST_CHECK(mult(1, 2) == 2); | ||||
|  | ||||
|   BOOST_CHECK(mult(1, 3.0) == 3.0); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										100
									
								
								enable_if/test/lazy_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								enable_if/test/lazy_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) The Trustees of Indiana University. | ||||
|  | ||||
| // Use, modification, and distribution is subject to the Boost Software | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| // Testing all variations of lazy_enable_if. | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
| #include <boost/mpl/not.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_same.hpp> | ||||
|  | ||||
| using boost::lazy_enable_if; | ||||
| using boost::lazy_disable_if; | ||||
|  | ||||
| using boost::lazy_enable_if_c; | ||||
| using boost::lazy_disable_if_c; | ||||
|  | ||||
|  | ||||
| template <class T> | ||||
| struct is_int_or_double { | ||||
|   BOOST_STATIC_CONSTANT(bool,  | ||||
|     value = (boost::is_same<T, int>::value ||  | ||||
|              boost::is_same<T, double>::value)); | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| struct some_traits { | ||||
|   typedef typename T::does_not_exist type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct some_traits<int> { | ||||
|   typedef bool type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct some_traits<double> { | ||||
|   typedef bool type; | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| struct make_bool { | ||||
|   typedef bool type; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct make_bool<int> {}; | ||||
|  | ||||
| template <> | ||||
| struct make_bool<double> {}; | ||||
|  | ||||
| namespace A { | ||||
|  | ||||
|   template<class T> | ||||
|   typename lazy_enable_if<is_int_or_double<T>, some_traits<T> >::type | ||||
|   foo(T t) { return true; } | ||||
|  | ||||
|   template<class T> | ||||
|   typename lazy_enable_if_c<is_int_or_double<T>::value, some_traits<T> >::type | ||||
|   foo2(T t) { return true; } | ||||
| } | ||||
|  | ||||
| namespace B { | ||||
|   template<class T> | ||||
|   typename lazy_disable_if<is_int_or_double<T>, make_bool<T> >::type | ||||
|   foo(T t) { return false; } | ||||
|  | ||||
|   template<class T> | ||||
|   typename lazy_disable_if_c<is_int_or_double<T>::value, make_bool<T> >::type | ||||
|   foo2(T t) { return false; } | ||||
| } | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   using namespace A; | ||||
|   using namespace B; | ||||
|   BOOST_CHECK(foo(1)); | ||||
|   BOOST_CHECK(foo(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!foo("1"));   | ||||
|   BOOST_CHECK(!foo(static_cast<void*>(0)));   | ||||
|  | ||||
|   BOOST_CHECK(foo2(1)); | ||||
|   BOOST_CHECK(foo2(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!foo2("1"));   | ||||
|   BOOST_CHECK(!foo2(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										43
									
								
								enable_if/test/member_templates.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								enable_if/test/member_templates.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) The Trustees of Indiana University. | ||||
|  | ||||
| // Use, modification, and distribution is subject to the Boost Software | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::enable_if; | ||||
| using boost::disable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| struct container { | ||||
|   template <class T> | ||||
|   typename enable_if<is_arithmetic<T>, bool>::type | ||||
|   arithmetic_object(const T&, const int* /* disambiguate */ = 0) {return true;} | ||||
|  | ||||
|   template <class T> | ||||
|   typename disable_if<is_arithmetic<T>, bool>::type | ||||
|   arithmetic_object(const T&) {return false;} | ||||
| }; | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(container().arithmetic_object(1)); | ||||
|   BOOST_CHECK(container().arithmetic_object(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!container().arithmetic_object("1"));   | ||||
|   BOOST_CHECK(!container().arithmetic_object(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										47
									
								
								enable_if/test/namespace_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								enable_if/test/namespace_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) The Trustees of Indiana University. | ||||
|  | ||||
| // Use, modification, and distribution is subject to the Boost Software | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
| #include <boost/mpl/not.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::enable_if; | ||||
| using boost::mpl::not_; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| namespace A { | ||||
|   template<class T> | ||||
|   typename enable_if<is_arithmetic<T>, bool>::type | ||||
|   arithmetic_object(T t) { return true; } | ||||
| } | ||||
|  | ||||
| namespace B { | ||||
|   template<class T> | ||||
|   typename enable_if<not_<is_arithmetic<T> >, bool>::type | ||||
|   arithmetic_object(T t) { return false; } | ||||
| } | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   using namespace A; | ||||
|   using namespace B; | ||||
|   BOOST_CHECK(arithmetic_object(1)); | ||||
|   BOOST_CHECK(arithmetic_object(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!arithmetic_object("1"));   | ||||
|   BOOST_CHECK(!arithmetic_object(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										43
									
								
								enable_if/test/no_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								enable_if/test/no_disambiguation.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) The Trustees of Indiana University. | ||||
|  | ||||
| // Use, modification, and distribution is subject to the Boost Software | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
| #include <boost/mpl/not.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::mpl::not_; | ||||
| using boost::enable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| template<class T> | ||||
| typename enable_if<is_arithmetic<T>, bool>::type | ||||
| arithmetic_object(T t) { return true; } | ||||
|  | ||||
| template<class T> | ||||
| typename enable_if<not_<is_arithmetic<T> >, bool>::type | ||||
| arithmetic_object(T t) { return false; } | ||||
|  | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(arithmetic_object(1)); | ||||
|   BOOST_CHECK(arithmetic_object(1.0)); | ||||
|  | ||||
|   BOOST_CHECK(!arithmetic_object("1"));   | ||||
|   BOOST_CHECK(!arithmetic_object(static_cast<void*>(0)));   | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										67
									
								
								enable_if/test/partial_specializations.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								enable_if/test/partial_specializations.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) The Trustees of Indiana University. | ||||
|  | ||||
| // Use, modification, and distribution is subject to the Boost Software | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
| #include <boost/test/minimal.hpp> | ||||
|  | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/type_traits/is_arithmetic.hpp> | ||||
|  | ||||
| using boost::enable_if_c; | ||||
| using boost::disable_if_c; | ||||
| using boost::enable_if; | ||||
| using boost::disable_if; | ||||
| using boost::is_arithmetic; | ||||
|  | ||||
| template <class T, class Enable = void> | ||||
| struct tester; | ||||
|  | ||||
| template <class T> | ||||
| struct tester<T, typename enable_if_c<is_arithmetic<T>::value>::type> { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = true); | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| struct tester<T, typename disable_if_c<is_arithmetic<T>::value>::type> { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = false); | ||||
| }; | ||||
|  | ||||
| template <class T, class Enable = void> | ||||
| struct tester2; | ||||
|  | ||||
| template <class T> | ||||
| struct tester2<T, typename enable_if<is_arithmetic<T> >::type> { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = true); | ||||
| }; | ||||
|  | ||||
| template <class T> | ||||
| struct tester2<T, typename disable_if<is_arithmetic<T> >::type> { | ||||
|   BOOST_STATIC_CONSTANT(bool, value = false); | ||||
| }; | ||||
|  | ||||
| int test_main(int, char*[]) | ||||
| { | ||||
|   | ||||
|   BOOST_CHECK(tester<int>::value); | ||||
|   BOOST_CHECK(tester<double>::value); | ||||
|  | ||||
|   BOOST_CHECK(!tester<char*>::value); | ||||
|   BOOST_CHECK(!tester<void*>::value); | ||||
|  | ||||
|   BOOST_CHECK(tester2<int>::value); | ||||
|   BOOST_CHECK(tester2<double>::value); | ||||
|  | ||||
|   BOOST_CHECK(!tester2<char*>::value); | ||||
|   BOOST_CHECK(!tester2<void*>::value); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										163
									
								
								generator_iterator.htm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								generator_iterator.htm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | ||||
|  | ||||
| <html> | ||||
| <head> | ||||
|   <meta http-equiv="Content-Language" content="en-us"> | ||||
|   <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> | ||||
|  | ||||
|   <title>Generator Iterator Adaptor Documentation</title> | ||||
| </head> | ||||
|  | ||||
| <body bgcolor="#FFFFFF" text="#000000"> | ||||
|   <img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle" | ||||
|   width="277" height="86"> | ||||
|  | ||||
|   <h1>Generator Iterator Adaptor</h1> | ||||
|  | ||||
|   <p>Defined in header <a href= | ||||
|   "../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a></p> | ||||
|  | ||||
|   <p>The generator iterator adaptor makes it easier to create custom input | ||||
|   iterators from 0-ary functions and function objects. The adaptor takes a | ||||
|   <a href="http://www.sgi.com/tech/stl/Generator.html">Generator</a> and | ||||
|   creates a model of <a href= | ||||
|   "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>. Each | ||||
|   increment retrieves an item from the generator and makes it available to be | ||||
|   retrieved by dereferencing. The motivation for this iterator is that some | ||||
|   concepts can be more naturally expressed as a generator, while most STL | ||||
|   algorithms expect an iterator. An example is the <a href= | ||||
|   "../random/index.html">Random Number</a> library.</p> | ||||
|  | ||||
|   <h2>Synopsis</h2> | ||||
|  | ||||
|   <blockquote> | ||||
|     <pre> | ||||
| namespace boost { | ||||
|   template <class Generator> | ||||
|   class generator_iterator_policies; | ||||
|  | ||||
|   template <class Generator> | ||||
|   class generator_iterator_generator; | ||||
|  | ||||
|   template <class Generator> | ||||
|   typename generator_iterator_generator<Generator>::type | ||||
|   make_generator_iterator(Generator & gen); | ||||
| } | ||||
| </pre> | ||||
|   </blockquote> | ||||
|   <hr> | ||||
|  | ||||
|   <h2>The Generator Iterator Generator Class</h2> | ||||
|  | ||||
|   <p>The class generator_iterator_generator is a helper class whose purpose | ||||
|   is to construct a generator iterator type. The template parameter for this | ||||
|   class is the Generator function object type that is being wrapped. The | ||||
|   generator iterator adaptor only holds a reference (or pointer) to the | ||||
|   function object, therefore the function object must outlive the generator | ||||
|   iterator adaptor constructed from it.</p> | ||||
|   <pre> | ||||
| template <class Generator> | ||||
| class generator_iterator_generator | ||||
| { | ||||
| public: | ||||
|   typedef <i>unspecified</i> type; // the resulting generator iterator type  | ||||
| } | ||||
| </pre> | ||||
|  | ||||
|   <h3>Template Parameters</h3> | ||||
|  | ||||
|   <table border summary=""> | ||||
|     <tr> | ||||
|       <th>Parameter</th> | ||||
|  | ||||
|       <th>Description</th> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|       <td><tt><a href= | ||||
|       "http://www.sgi.com/tech/stl/Generator.html">Generator</a></tt></td> | ||||
|  | ||||
|       <td>The generator (0-ary function object) type being wrapped. The | ||||
|       return type of the function must be defined as | ||||
|       <tt>Generator::result_type</tt>. The function object must be a model of | ||||
|       <a href= | ||||
|       "http://www.sgi.com/tech/stl/Generator.html">Generator</a>.</td> | ||||
|     </tr> | ||||
|   </table> | ||||
|  | ||||
|   <h3>Concept Model</h3> | ||||
|  | ||||
|   <p>The generator iterator class is a model of <a href= | ||||
|   "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.</p> | ||||
|  | ||||
|   <h3>Members</h3> | ||||
|  | ||||
|   <p>The generator iterator implements the member functions and operators | ||||
|   required of the <a href= | ||||
|   "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a> | ||||
|   concept.<br></p> | ||||
|   <hr> | ||||
|  | ||||
|   <h2><a name="make_generator_iterator" id="make_generator_iterator">The | ||||
|   Generator Iterator Object Generator</a></h2> | ||||
|  | ||||
|   <p>The <tt>make_generator_iterator()</tt> function provides a convenient | ||||
|   way to create generator iterator objects. The function saves the user the | ||||
|   trouble of explicitly writing out the iterator types.</p> | ||||
|  | ||||
|   <blockquote> | ||||
|     <pre> | ||||
| template <class Generator> | ||||
| typename generator_iterator_generator<Generator>::type | ||||
| make_generator_iterator(Generator & gen); | ||||
| </pre> | ||||
|   </blockquote> | ||||
|   <hr> | ||||
|  | ||||
|   <h3>Example</h3> | ||||
|  | ||||
|   <p>The following program shows how <code>generator_iterator</code> | ||||
|   transforms a generator into an input iterator.</p> | ||||
|  | ||||
|   <blockquote> | ||||
|     <pre> | ||||
| #include <iostream> | ||||
| #include <boost/generator_iterator.hpp> | ||||
|  | ||||
| class my_generator | ||||
| { | ||||
| public: | ||||
|   typedef int result_type; | ||||
|   my_generator() : state(0) { } | ||||
|   int operator()() { return ++state; } | ||||
| private: | ||||
|   int state; | ||||
| }; | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   my_generator gen; | ||||
|   boost::generator_iterator_generator<my_generator>::type it = boost::make_generator_iterator(gen); | ||||
|   for(int i = 0; i < 10; ++i, ++it) | ||||
|     std::cout << *it << std::endl; | ||||
| } | ||||
| </pre> | ||||
|   </blockquote> | ||||
|   <hr> | ||||
|  | ||||
|   <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= | ||||
|   "../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional" | ||||
|   height="31" width="88"></a></p> | ||||
|  | ||||
|   <p>Revised  | ||||
|   <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p> | ||||
|  | ||||
|   <p><i>Copyright © 2001 <a href= | ||||
|   "http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a></i></p> | ||||
|  | ||||
|   <p><i>Distributed under the Boost Software License, Version 1.0. (See | ||||
|   accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or | ||||
|   copy at <a href= | ||||
|   "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p> | ||||
| </body> | ||||
| </html> | ||||
| @@ -6,7 +6,7 @@ | ||||
|   <body> | ||||
|     Automatic redirection failed, click this  | ||||
|     <a href="doc/html/index.html">link</a>  <hr> | ||||
|     <p>Copyright © Lorenzo Caminiti, 2009-2012</p> | ||||
|     <p><EFBFBD> Copyright Lorenzo Caminiti, 2009-2012</p> | ||||
|     <p>Distributed under the Boost Software License, Version 1.0 (see  | ||||
|     accompanying file <a href="../../../LICENSE_1_0.txt"> | ||||
|     LICENSE_1_0.txt</a> or a copy at | ||||
|   | ||||
| @@ -1,19 +1,296 @@ | ||||
| <html> | ||||
| <head> | ||||
|     <title>Boost.InPlaceFactory</title> | ||||
|     <meta http-equiv="refresh" content="0; URL=./doc/html/utility/utilities/in_place_factory.html"> | ||||
| </head> | ||||
| <body> | ||||
| Automatic redirection failed, please go to | ||||
| <a href="./doc/html/utility/utilities/in_place_factory.html">./doc/html/utility/utilities/in_place_factory.html</a> | ||||
| <!DOCTYPE HTML PUBLIC "-//SoftQuad Software//DTD HoTMetaL PRO 5.0::19981217::extensions to HTML 4.0//EN" "hmpro5.dtd"> | ||||
|  | ||||
| <HTML> | ||||
|  | ||||
| <HEAD> | ||||
| <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252"> | ||||
| <TITLE>In_place_factory Documentation</TITLE> | ||||
| </HEAD> | ||||
|  | ||||
| <BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080"> | ||||
| <H2 align="left"><IMG SRC="../../boost.png" WIDTH="276" HEIGHT="86"></H2> | ||||
|  | ||||
| <blockquote> | ||||
|   <blockquote> | ||||
|     <blockquote> | ||||
|       <blockquote> | ||||
|         <blockquote> | ||||
|           <blockquote> | ||||
| <H2 align="left">Header <<A | ||||
| HREF="../../boost/utility/in_place_factory.hpp">boost/utility/in_place_factory.hpp</A>> </H2> | ||||
|  | ||||
| <H2 align="left">Header <<A | ||||
| HREF="../../boost/utility/typed_in_place_factory.hpp">boost/utility/typed_in_place_factory.hpp</A>> </H2> | ||||
|  | ||||
|           </blockquote> | ||||
|         </blockquote> | ||||
|       </blockquote> | ||||
|     </blockquote> | ||||
|   </blockquote> | ||||
| </blockquote> | ||||
| <p> </p> | ||||
|  | ||||
| <H2>Contents</H2> | ||||
| <DL CLASS="page-index"> | ||||
|   <DT><A HREF="#mot">Motivation</A></DT> | ||||
|   <DT><A HREF="#framework">Framework</A></DT> | ||||
|   <DT><A HREF="#specification">Specification</A></DT> | ||||
|   <DT><A HREF="#container-usage">Container-side Usage</A></DT> | ||||
|   <DT><A HREF="#user-usage">User-side Usage</A></DT> | ||||
| </DL> | ||||
|  | ||||
| <HR> | ||||
|  | ||||
| <H2><A NAME="mot"></A>Motivation</H2> | ||||
|  | ||||
| <p>Suppose we have a class</p> | ||||
| <pre>struct X | ||||
| { | ||||
|   X ( int, std::string ) ; | ||||
| } ;</pre> | ||||
| <p>And a container for it which supports an empty state (that is, which can contain zero objects):</p> | ||||
| <pre>struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|   ~C() { delete contained_ ; } | ||||
|   X* contained_ ; | ||||
| } ;</pre> | ||||
| <p>A container designed to support an empty state typically doesn't require the contained type to be DefaultConstructible, | ||||
| but it typically requires it to be CopyConstructible as a mechanism to | ||||
| initialize the object to store:</p> | ||||
| <pre>struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|    C ( X const& v ) : contained_ ( new X(v) ) {} | ||||
|   ~C() { delete contained_ ; } | ||||
|   X* contained_ ; | ||||
| } ;</pre> | ||||
| <p>There is a subtle problem with this: since the mechanism used to initialize the stored object is copy construction, | ||||
| there must exist a previously constructed source object to copy from. This | ||||
| object is likely to be temporary and serve no purpose besides being the source</p> | ||||
| <pre>void foo() | ||||
| { | ||||
|   // Temporary object created. | ||||
|   C c( X(123,"hello") ) ; | ||||
| } | ||||
| </pre> | ||||
| <p>A solution to this problem is to support direct construction of the contained | ||||
| object right in the container's storage.<br> | ||||
| In this scheme, the user supplies the arguments for the X constructor | ||||
| directly to the container:</p> | ||||
| <pre>struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|    C ( X const& v ) : contained_ ( new X(v) ) {} | ||||
|    C ( int a0, std::string a1 ) : contained_ ( new X(a0,a1) ) {} | ||||
|   ~C() { delete contained_ ; } | ||||
|   X* contained_ ; | ||||
| } ;</pre> | ||||
| <pre>void foo() | ||||
| { | ||||
|   // Wrapped object constructed in-place | ||||
|   // No temporary created. | ||||
|   C c(123,"hello") ; | ||||
| } | ||||
| </pre> | ||||
| <p>Clearly, this solution doesn't scale well since the container must duplicate all the constructor overloads from the contained type | ||||
| (at least all those which are to be supported directly in the container).</p> | ||||
|  | ||||
| <H2><A NAME="framework"></A>Framework</H2> | ||||
| <p> | ||||
| This library proposes a framework to allow some containers to directly contruct contained objects in-place without requiring | ||||
| the entire set of constructor overloads from the contained type. It also allows the container to remove the CopyConstuctible | ||||
| requirement from the contained type since objects can be directly constructed in-place without need of a copy.<br> | ||||
| The only requirement on the container is that it must provide proper storage (that is, correctly aligned and sized). | ||||
| Naturally, the container will typically support uninitialized storage to avoid the in-place construction to override | ||||
| a fully-constructed object (as this would defeat the purpose of in-place construction) | ||||
| </p> | ||||
| <p>For this purpose, the framework provides two families of classes collectively called: InPlaceFactories and TypedInPlaceFactories.<br> | ||||
| Essentially, these classes hold a sequence of actual parameters and a method to contruct an object in place using these parameters. | ||||
| Each member of the family differs only in the number (and type) of the parameter list. The first family | ||||
| takes the type of the object to construct directly in method provided for that | ||||
| purpose, whereas the second family incorporates that type in the factory class | ||||
| itself..</p> | ||||
| <p>From the container POV, using the framework amounts to calling the factory's method to contruct the object in place. | ||||
| From the user POV, it amounts to creating the right factory object to hold the parameters and pass it to the container.<br> | ||||
| The following simplified example shows the basic idea. A complete example follows the formal specification of the framework:</p> | ||||
| <pre>struct C | ||||
| { | ||||
|    template<class InPlaceFactory> | ||||
|    C ( InPlaceFactory const& aFactory ) | ||||
|     : | ||||
|     contained_ ( uninitialized_storage() ) | ||||
|    { | ||||
|      aFactory.template apply<X>(contained_); | ||||
|    } | ||||
|  | ||||
|   ~C()  | ||||
|   {  | ||||
|     contained_ -> X::~X(); | ||||
|     delete[] contained_ ;  | ||||
|   } | ||||
|  | ||||
|   char* uninitialized_storage() { return new char[sizeof(X)] ; } | ||||
|  | ||||
|   char* contained_ ; | ||||
| } ; | ||||
|  | ||||
| void foo() | ||||
| { | ||||
|   C c( in_place(123,"hello") ) ; | ||||
| } | ||||
| </pre> | ||||
|  | ||||
| <HR> | ||||
|  | ||||
| <H2><A NAME="specification">Specification</A></H2> | ||||
|  | ||||
| <p>The following is the first member of the family of 'in_place_factory' classes, along with its corresponding helper template function. | ||||
| The rest of the family varies only in the number and type of template (and constructor) parameters.</p> | ||||
| <PRE>namespace boost { | ||||
|  | ||||
| struct in_place_factory_base {} ; | ||||
|  | ||||
| template<class A0> | ||||
| class in_place_factory : public in_place_factory_base | ||||
| { | ||||
|   public:</PRE> | ||||
|  | ||||
| <PRE>    in_place_factory ( A0 const& a0 ) : m_a0(a0) {} | ||||
|  | ||||
|     template< class T > | ||||
|     void apply ( void* address ) const | ||||
|     { | ||||
|       new (address) T(m_a0); | ||||
|     } | ||||
|  | ||||
|   private:</PRE> | ||||
|  | ||||
| <PRE>    A0 const& m_a0 ; | ||||
| } ; | ||||
|  | ||||
| template<class A0> | ||||
| in_place_factory<A0> in_place ( A0 const& a0 ) | ||||
| { | ||||
|   return in_place_factory<A0>(a0); | ||||
| } | ||||
| </PRE> | ||||
|  | ||||
| <p>Similarly, the following is the first member of the family of 'typed_in_place_factory' classes, along with its corresponding | ||||
| helper template function. The rest of the family varies only in the number and type of template (and constructor) parameters.</p> | ||||
| <PRE>namespace boost { | ||||
|  | ||||
| struct typed_in_place_factory_base {} ; | ||||
|  | ||||
| template<class T, class A0> | ||||
| class typed_in_place_factory : public typed_in_place_factory_base | ||||
| { | ||||
|   public:</PRE> | ||||
|  | ||||
| <PRE>    typed_in_place_factory ( A0 const& a0 ) : m_a0(a0) {} | ||||
|  | ||||
|     void apply ( void* address ) const | ||||
|     { | ||||
|       new (address) T(m_a0); | ||||
|     } | ||||
|  | ||||
|   private:</PRE> | ||||
|  | ||||
| <PRE>    A0 const& m_a0 ; | ||||
| } ; | ||||
|  | ||||
| template<class T, class A0> | ||||
| typed_in_place_factory<A0> in_place ( A0 const& a0 ) | ||||
| { | ||||
|   return typed_in_place_factory<T,A0>(a0); | ||||
| }</PRE> | ||||
|  | ||||
| <PRE>} | ||||
| </PRE> | ||||
|  | ||||
| <p>As you can see, the 'in_place_factory' and 'typed_in_place_factory' template classes varies only in the way they specify | ||||
| the target type: in the first family, the type is given as a template argument to the apply member function while in the | ||||
| second it is given directly as part of the factory class.<br> | ||||
| When the container holds a unique non-polymorphic type (such as the case of Boost.Optional), it knows the exact dynamic-type | ||||
| of the contained object and can pass it to the apply() method of a (non-typed) factory. | ||||
| In this case, end users can use an 'in_place_factory' instance which can be constructed without the type of the object to construct.<br> | ||||
| However, if the container holds heterogeneous or polymorphic objects (such as the case of Boost.Variant), the dynamic-type | ||||
| of the object to be constructed must be known by the factory itslef. In this case, end users must use a 'typed_in_place_factory' | ||||
| instead.</p> | ||||
|  | ||||
| <HR> | ||||
|  | ||||
| <h2><A NAME="container-usage">Container-side Usage</a></h2> | ||||
|  | ||||
| <p>As shown in the introductory simplified example, the container class must | ||||
| contain methods that accept an instance of | ||||
| these factories and pass the object's storage to the factory's apply method.<br> | ||||
| However, the type of the factory class cannot be completly specified in the container class because that would | ||||
| defeat the whole purpose of the factories which is to allow the container to accept a variadic argument list | ||||
| for the constructor of its contained object.<br> | ||||
| The correct function overload must be based on the only distinctive and common | ||||
| characteristic of all the classes in each family, the base class.<br> | ||||
| Depending on the container class, you can use 'enable_if' to generate the right overload, or use the following | ||||
| dispatch technique (used in the Boost.Optional class): | ||||
| </p> | ||||
| <pre>struct C | ||||
| { | ||||
|    C() : contained_(0) {} | ||||
|    C ( X const& v ) : contained_ ( new X(v) ) {} | ||||
|  | ||||
|    template<class Expr> | ||||
|    C ( Expr const& expr ) | ||||
|     : | ||||
|     contained_ ( uninitialized_storage() ) | ||||
|    { | ||||
|     construct(expr,&expr) | ||||
|    } | ||||
|  | ||||
|   ~C() { delete contained_ ; } | ||||
|  | ||||
|   template<class InPlaceFactory> | ||||
|   void construct ( InPlaceFactory const& aFactory, boost::in_place_factory_base* ) | ||||
|   { | ||||
|     aFactory.template apply<X>(contained_); | ||||
|   } | ||||
|  | ||||
|   template<class TypedInPlaceFactory> | ||||
|   void construct ( TypedInPlaceFactory const& aFactory, boost::typed_in_place_factory_base* ) | ||||
|   { | ||||
|     aFactory.apply(contained_); | ||||
|   } | ||||
|  | ||||
|   X* uninitialized_storage() { return static_cast<X*>(new char[sizeof(X)]) ; } | ||||
|  | ||||
|   X* contained_ ; | ||||
| } ; | ||||
| </pre> | ||||
|  | ||||
| <hr> | ||||
| <tt> | ||||
|     Boost.InPlaceFactory<br> | ||||
|     <br> | ||||
|     Distributed under the Boost Software License, Version 1.0. | ||||
|     (See accompanying file LICENSE_1_0.txt or copy at | ||||
|     <a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>) <br> | ||||
|     <br> | ||||
| </tt> | ||||
| </body> | ||||
| </html> | ||||
|  | ||||
| <h2><A NAME="user-usage">User-side Usage</a></h2> | ||||
|  | ||||
| <p>End users pass to the container an instance of a factory object holding the actual parameters needed to construct the | ||||
| contained object directly within the container. For this, the helper template function 'in_place' is used.<br> | ||||
| The call 'in_place(a0,a1,a2,...,an)' constructs a (non-typed) 'in_place_factory' instance with the given argument list.<br> | ||||
| The call 'in_place<T>(a0,a1,a2,...,an)' constructs a 'typed_in_place_factory' instance with the given argument list for the | ||||
| type 'T'.</p> | ||||
| <pre>void foo() | ||||
| { | ||||
|   C a( in_place(123,"hello") ) ;    // in_place_factory passed | ||||
|   C b( in_place<X>(456,"world") ) ; // typed_in_place_factory passed | ||||
| } | ||||
| </pre> | ||||
|  | ||||
| <P>Revised September 17, 2004</P> | ||||
| <p><EFBFBD> Copyright Fernando Luis Cacciola Carballal, 2004</p> | ||||
| <p> Use, modification, and distribution are subject to the Boost Software | ||||
| License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt"> | ||||
| LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> | ||||
| www.boost.org/LICENSE_1_0.txt</a>)</p> | ||||
| <P>Developed by <A HREF="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</A>, | ||||
| the latest version of this file can be found at <A | ||||
| HREF="http://www.boost.org">www.boost.org</A>, and the boost | ||||
| <A HREF="http://www.boost.org/more/mailing_lists.htm#main">discussion lists</A></P> | ||||
| </BODY> | ||||
| </HTML> | ||||
|   | ||||
							
								
								
									
										141
									
								
								include/boost/assert.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								include/boost/assert.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | ||||
| // | ||||
| //  boost/assert.hpp - BOOST_ASSERT(expr) | ||||
| //                     BOOST_ASSERT_MSG(expr, msg) | ||||
| //                     BOOST_VERIFY(expr) | ||||
| // | ||||
| //  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright (c) 2007 Peter Dimov | ||||
| //  Copyright (c) Beman Dawes 2011 | ||||
| // | ||||
| // 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) | ||||
| // | ||||
| //  Note: There are no include guards. This is intentional. | ||||
| // | ||||
| //  See http://www.boost.org/libs/utility/assert.html for documentation. | ||||
| // | ||||
|  | ||||
| // | ||||
| // Stop inspect complaining about use of 'assert': | ||||
| // | ||||
| // boostinspect:naassert_macro | ||||
| // | ||||
|  | ||||
| //--------------------------------------------------------------------------------------// | ||||
| //                                     BOOST_ASSERT                                     // | ||||
| //--------------------------------------------------------------------------------------// | ||||
|  | ||||
| #undef BOOST_ASSERT | ||||
|  | ||||
| #if defined(BOOST_DISABLE_ASSERTS) | ||||
|  | ||||
| # define BOOST_ASSERT(expr) ((void)0) | ||||
|  | ||||
| #elif defined(BOOST_ENABLE_ASSERT_HANDLER) | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/current_function.hpp> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|   void assertion_failed(char const * expr, | ||||
|                         char const * function, char const * file, long line); // user defined | ||||
| } // namespace boost | ||||
|  | ||||
| #define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr)) \ | ||||
|   ? ((void)0) \ | ||||
|   : ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) | ||||
|  | ||||
| #else | ||||
| # include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same | ||||
| # define BOOST_ASSERT(expr) assert(expr) | ||||
| #endif | ||||
|  | ||||
| //--------------------------------------------------------------------------------------// | ||||
| //                                   BOOST_ASSERT_MSG                                   // | ||||
| //--------------------------------------------------------------------------------------// | ||||
|  | ||||
| # undef BOOST_ASSERT_MSG | ||||
|  | ||||
| #if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG) | ||||
|  | ||||
|   #define BOOST_ASSERT_MSG(expr, msg) ((void)0) | ||||
|  | ||||
| #elif defined(BOOST_ENABLE_ASSERT_HANDLER) | ||||
|  | ||||
|   #include <boost/config.hpp> | ||||
|   #include <boost/current_function.hpp> | ||||
|  | ||||
|   namespace boost | ||||
|   { | ||||
|     void assertion_failed_msg(char const * expr, char const * msg, | ||||
|                               char const * function, char const * file, long line); // user defined | ||||
|   } // namespace boost | ||||
|  | ||||
|   #define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \ | ||||
|     ? ((void)0) \ | ||||
|     : ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) | ||||
|  | ||||
| #else | ||||
|   #ifndef BOOST_ASSERT_HPP | ||||
|     #define BOOST_ASSERT_HPP | ||||
|     #include <cstdlib> | ||||
|     #include <iostream> | ||||
|     #include <boost/config.hpp> | ||||
|     #include <boost/current_function.hpp> | ||||
|  | ||||
|     //  IDE's like Visual Studio perform better if output goes to std::cout or | ||||
|     //  some other stream, so allow user to configure output stream: | ||||
|     #ifndef BOOST_ASSERT_MSG_OSTREAM | ||||
|     # define BOOST_ASSERT_MSG_OSTREAM std::cerr | ||||
|     #endif | ||||
|  | ||||
|     namespace boost | ||||
|     { | ||||
|       namespace assertion | ||||
|       { | ||||
|         namespace detail | ||||
|         { | ||||
|           // Note: The template is needed to make the function non-inline and avoid linking errors | ||||
|           template< typename CharT > | ||||
|           BOOST_NOINLINE void assertion_failed_msg(CharT const * expr, char const * msg, char const * function, | ||||
|             char const * file, long line) | ||||
|           { | ||||
|             BOOST_ASSERT_MSG_OSTREAM | ||||
|               << "***** Internal Program Error - assertion (" << expr << ") failed in " | ||||
|               << function << ":\n" | ||||
|               << file << '(' << line << "): " << msg << std::endl; | ||||
| #ifdef UNDER_CE | ||||
|             // The Windows CE CRT library does not have abort() so use exit(-1) instead. | ||||
|             std::exit(-1); | ||||
| #else | ||||
|             std::abort(); | ||||
| #endif | ||||
|           } | ||||
|         } // detail | ||||
|       } // assertion | ||||
|     } // detail | ||||
|   #endif | ||||
|  | ||||
|   #define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \ | ||||
|     ? ((void)0) \ | ||||
|     : ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \ | ||||
|           BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) | ||||
| #endif | ||||
|  | ||||
| //--------------------------------------------------------------------------------------// | ||||
| //                                     BOOST_VERIFY                                     // | ||||
| //--------------------------------------------------------------------------------------// | ||||
|  | ||||
| #undef BOOST_VERIFY | ||||
|  | ||||
| #if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) | ||||
|  | ||||
| # define BOOST_VERIFY(expr) ((void)(expr)) | ||||
|  | ||||
| #else | ||||
|  | ||||
| # define BOOST_VERIFY(expr) BOOST_ASSERT(expr) | ||||
|  | ||||
| #endif | ||||
| @@ -5,7 +5,7 @@ | ||||
| // | ||||
| //  See http://www.boost.org/libs/utility for most recent version including documentation. | ||||
|  | ||||
| //  See boost/detail/call_traits.hpp | ||||
| //  See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp | ||||
| //  for full copyright notices. | ||||
|  | ||||
| #ifndef BOOST_CALL_TRAITS_HPP | ||||
| @@ -15,6 +15,10 @@ | ||||
| #include <boost/config.hpp> | ||||
| #endif | ||||
|  | ||||
| #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
| #include <boost/detail/ob_call_traits.hpp> | ||||
| #else | ||||
| #include <boost/detail/call_traits.hpp> | ||||
| #endif | ||||
|  | ||||
| #endif // BOOST_CALL_TRAITS_HPP | ||||
|   | ||||
							
								
								
									
										69
									
								
								include/boost/checked_delete.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								include/boost/checked_delete.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED | ||||
| #define BOOST_CHECKED_DELETE_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  boost/checked_delete.hpp | ||||
| // | ||||
| //  Copyright (c) 2002, 2003 Peter Dimov | ||||
| //  Copyright (c) 2003 Daniel Frey | ||||
| //  Copyright (c) 2003 Howard Hinnant | ||||
| // | ||||
| //  Distributed under the Boost Software License, Version 1.0. (See | ||||
| //  accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
| //  See http://www.boost.org/libs/utility/checked_delete.html for documentation. | ||||
| // | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| // verify that types are complete for increased safety | ||||
|  | ||||
| template<class T> inline void checked_delete(T * x) | ||||
| { | ||||
|     // intentionally complex - simplification causes regressions | ||||
|     typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; | ||||
|     (void) sizeof(type_must_be_complete); | ||||
|     delete x; | ||||
| } | ||||
|  | ||||
| template<class T> inline void checked_array_delete(T * x) | ||||
| { | ||||
|     typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; | ||||
|     (void) sizeof(type_must_be_complete); | ||||
|     delete [] x; | ||||
| } | ||||
|  | ||||
| template<class T> struct checked_deleter | ||||
| { | ||||
|     typedef void result_type; | ||||
|     typedef T * argument_type; | ||||
|  | ||||
|     void operator()(T * x) const | ||||
|     { | ||||
|         // boost:: disables ADL | ||||
|         boost::checked_delete(x); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template<class T> struct checked_array_deleter | ||||
| { | ||||
|     typedef void result_type; | ||||
|     typedef T * argument_type; | ||||
|  | ||||
|     void operator()(T * x) const | ||||
|     { | ||||
|         boost::checked_array_delete(x); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED | ||||
| @@ -5,7 +5,7 @@ | ||||
| // | ||||
| //  See http://www.boost.org/libs/utility for most recent version including documentation. | ||||
|  | ||||
| //  See boost/detail/compressed_pair.hpp | ||||
| //  See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp | ||||
| //  for full copyright notices. | ||||
|  | ||||
| #ifndef BOOST_COMPRESSED_PAIR_HPP | ||||
| @@ -15,6 +15,10 @@ | ||||
| #include <boost/config.hpp> | ||||
| #endif | ||||
|  | ||||
| #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
| #include <boost/detail/ob_compressed_pair.hpp> | ||||
| #else | ||||
| #include <boost/detail/compressed_pair.hpp> | ||||
| #endif | ||||
|  | ||||
| #endif // BOOST_COMPRESSED_PAIR_HPP | ||||
|   | ||||
							
								
								
									
										68
									
								
								include/boost/current_function.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								include/boost/current_function.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED | ||||
| #define BOOST_CURRENT_FUNCTION_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  boost/current_function.hpp - BOOST_CURRENT_FUNCTION | ||||
| // | ||||
| //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| // | ||||
| // 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) | ||||
| // | ||||
| //  http://www.boost.org/libs/utility/current_function.html | ||||
| // | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void current_function_helper() | ||||
| { | ||||
|  | ||||
| #if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) | ||||
|  | ||||
| # define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ | ||||
|  | ||||
| #elif defined(__DMC__) && (__DMC__ >= 0x810) | ||||
|  | ||||
| # define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ | ||||
|  | ||||
| #elif defined(__FUNCSIG__) | ||||
|  | ||||
| # define BOOST_CURRENT_FUNCTION __FUNCSIG__ | ||||
|  | ||||
| #elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) | ||||
|  | ||||
| # define BOOST_CURRENT_FUNCTION __FUNCTION__ | ||||
|  | ||||
| #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) | ||||
|  | ||||
| # define BOOST_CURRENT_FUNCTION __FUNC__ | ||||
|  | ||||
| #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) | ||||
|  | ||||
| # define BOOST_CURRENT_FUNCTION __func__ | ||||
|  | ||||
| #else | ||||
|  | ||||
| # define BOOST_CURRENT_FUNCTION "(unknown)" | ||||
|  | ||||
| #endif | ||||
|  | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED | ||||
|  | ||||
| @@ -100,7 +100,7 @@ struct call_traits<T&> | ||||
|    typedef T& param_type;  // hh removed const | ||||
| }; | ||||
|  | ||||
| #if BOOST_WORKAROUND( BOOST_BORLANDC,  < 0x5A0 ) | ||||
| #if BOOST_WORKAROUND( __BORLANDC__,  < 0x5A0 ) | ||||
| // these are illegal specialisations; cv-qualifies applied to | ||||
| // references have no effect according to [8.3.2p1], | ||||
| // C++ Builder requires them though as it treats cv-qualified | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| //  See http://www.boost.org/libs/utility for most recent version including documentation. | ||||
|  | ||||
| // compressed_pair: pair that "compresses" empty members | ||||
| // (see libs/utility/doc/html/compressed_pair.html) | ||||
| // (see libs/utility/compressed_pair.htm) | ||||
| // | ||||
| // JM changes 25 Jan 2004: | ||||
| // For the case where T1 == T2 and both are empty, then first() and second() | ||||
| @@ -24,7 +24,6 @@ | ||||
|  | ||||
| #include <boost/type_traits/remove_cv.hpp> | ||||
| #include <boost/type_traits/is_empty.hpp> | ||||
| #include <boost/type_traits/is_final.hpp> | ||||
| #include <boost/type_traits/is_same.hpp> | ||||
| #include <boost/call_traits.hpp> | ||||
|  | ||||
| @@ -43,14 +42,6 @@ class compressed_pair; | ||||
|  | ||||
| namespace details | ||||
| { | ||||
|    template<class T, bool E = boost::is_final<T>::value> | ||||
|    struct compressed_pair_empty | ||||
|       : ::boost::false_type { }; | ||||
|  | ||||
|    template<class T> | ||||
|    struct compressed_pair_empty<T, false> | ||||
|       : ::boost::is_empty<T> { }; | ||||
|  | ||||
|    // JM altered 26 Jan 2000: | ||||
|    template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty> | ||||
|    struct compressed_pair_switch; | ||||
| @@ -347,15 +338,13 @@ namespace details | ||||
|  | ||||
| template <class T1, class T2> | ||||
| class compressed_pair | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
|     : private ::boost::details::compressed_pair_imp<T1, T2, | ||||
|    : private ::boost::details::compressed_pair_imp<T1, T2, | ||||
|              ::boost::details::compressed_pair_switch< | ||||
|                     T1, | ||||
|                     T2, | ||||
|                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value, | ||||
|                     ::boost::details::compressed_pair_empty<T1>::value, | ||||
|                     ::boost::details::compressed_pair_empty<T2>::value>::value> | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|                     ::boost::is_empty<T1>::value, | ||||
|                     ::boost::is_empty<T2>::value>::value> | ||||
| { | ||||
| private: | ||||
|    typedef details::compressed_pair_imp<T1, T2, | ||||
| @@ -363,8 +352,8 @@ private: | ||||
|                     T1, | ||||
|                     T2, | ||||
|                     ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value, | ||||
|                     ::boost::details::compressed_pair_empty<T1>::value, | ||||
|                     ::boost::details::compressed_pair_empty<T2>::value>::value> base; | ||||
|                     ::boost::is_empty<T1>::value, | ||||
|                     ::boost::is_empty<T2>::value>::value> base; | ||||
| public: | ||||
|    typedef T1                                                 first_type; | ||||
|    typedef T2                                                 second_type; | ||||
| @@ -394,15 +383,13 @@ public: | ||||
| // | ||||
| template <class T> | ||||
| class compressed_pair<T, T> | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
|    : private details::compressed_pair_imp<T, T, | ||||
|              ::boost::details::compressed_pair_switch< | ||||
|                     T, | ||||
|                     T, | ||||
|                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value, | ||||
|                     ::boost::details::compressed_pair_empty<T>::value, | ||||
|                     ::boost::details::compressed_pair_empty<T>::value>::value> | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|                     ::boost::is_empty<T>::value, | ||||
|                     ::boost::is_empty<T>::value>::value> | ||||
| { | ||||
| private: | ||||
|    typedef details::compressed_pair_imp<T, T, | ||||
| @@ -410,8 +397,8 @@ private: | ||||
|                     T, | ||||
|                     T, | ||||
|                     ::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value, | ||||
|                     ::boost::details::compressed_pair_empty<T>::value, | ||||
|                     ::boost::details::compressed_pair_empty<T>::value>::value> base; | ||||
|                     ::boost::is_empty<T>::value, | ||||
|                     ::boost::is_empty<T>::value>::value> base; | ||||
| public: | ||||
|    typedef T                                                  first_type; | ||||
|    typedef T                                                  second_type; | ||||
|   | ||||
							
								
								
									
										168
									
								
								include/boost/detail/ob_call_traits.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								include/boost/detail/ob_call_traits.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,168 @@ | ||||
| //  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. | ||||
| //  Use, modification and distribution are 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/utility for most recent version including documentation. | ||||
| // | ||||
| //  Crippled version for crippled compilers: | ||||
| //  see libs/utility/call_traits.htm | ||||
| // | ||||
|  | ||||
| /* Release notes: | ||||
|    01st October 2000: | ||||
|       Fixed call_traits on VC6, using "poor man's partial specialisation", | ||||
|       using ideas taken from "Generative programming" by Krzysztof Czarnecki  | ||||
|       & Ulrich Eisenecker. | ||||
| */ | ||||
|  | ||||
| #ifndef BOOST_OB_CALL_TRAITS_HPP | ||||
| #define BOOST_OB_CALL_TRAITS_HPP | ||||
|  | ||||
| #ifndef BOOST_CONFIG_HPP | ||||
| #include <boost/config.hpp> | ||||
| #endif | ||||
|  | ||||
| #ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP | ||||
| #include <boost/type_traits/arithmetic_traits.hpp> | ||||
| #endif | ||||
| #ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP | ||||
| #include <boost/type_traits/composite_traits.hpp> | ||||
| #endif | ||||
|  | ||||
| namespace boost{ | ||||
|  | ||||
| #ifdef BOOST_MSVC6_MEMBER_TEMPLATES | ||||
| // | ||||
| // use member templates to emulate | ||||
| // partial specialisation: | ||||
| // | ||||
| namespace detail{ | ||||
|  | ||||
| template <class T> | ||||
| struct standard_call_traits | ||||
| { | ||||
|    typedef T value_type; | ||||
|    typedef T& reference; | ||||
|    typedef const T& const_reference; | ||||
|    typedef const T& param_type; | ||||
| }; | ||||
| template <class T> | ||||
| struct simple_call_traits | ||||
| { | ||||
|    typedef T value_type; | ||||
|    typedef T& reference; | ||||
|    typedef const T& const_reference; | ||||
|    typedef const T param_type; | ||||
| }; | ||||
| template <class T> | ||||
| struct reference_call_traits | ||||
| { | ||||
|    typedef T value_type; | ||||
|    typedef T reference; | ||||
|    typedef T const_reference; | ||||
|    typedef T param_type; | ||||
| }; | ||||
|  | ||||
| template <bool pointer, bool arithmetic, bool reference> | ||||
| struct call_traits_chooser | ||||
| { | ||||
|    template <class T> | ||||
|    struct rebind | ||||
|    { | ||||
|       typedef standard_call_traits<T> type; | ||||
|    }; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct call_traits_chooser<true, false, false> | ||||
| { | ||||
|    template <class T> | ||||
|    struct rebind | ||||
|    { | ||||
|       typedef simple_call_traits<T> type; | ||||
|    }; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct call_traits_chooser<false, false, true> | ||||
| { | ||||
|    template <class T> | ||||
|    struct rebind | ||||
|    { | ||||
|       typedef reference_call_traits<T> type; | ||||
|    }; | ||||
| }; | ||||
|  | ||||
| template <bool size_is_small>  | ||||
| struct call_traits_sizeof_chooser2 | ||||
| { | ||||
|    template <class T> | ||||
|    struct small_rebind | ||||
|    { | ||||
|       typedef simple_call_traits<T> small_type; | ||||
|    }; | ||||
| }; | ||||
|  | ||||
| template<>  | ||||
| struct call_traits_sizeof_chooser2<false> | ||||
| { | ||||
|    template <class T> | ||||
|    struct small_rebind | ||||
|    { | ||||
|       typedef standard_call_traits<T> small_type; | ||||
|    }; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct call_traits_chooser<false, true, false> | ||||
| { | ||||
|    template <class T> | ||||
|    struct rebind | ||||
|    { | ||||
|       enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) }; | ||||
|       typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser; | ||||
|       typedef typename chooser::template small_rebind<T> bound_type; | ||||
|       typedef typename bound_type::small_type type; | ||||
|    }; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
| template <typename T> | ||||
| struct call_traits | ||||
| { | ||||
| private: | ||||
|     typedef detail::call_traits_chooser< | ||||
|          ::boost::is_pointer<T>::value, | ||||
|          ::boost::is_arithmetic<T>::value,  | ||||
|          ::boost::is_reference<T>::value | ||||
|       > chooser; | ||||
|    typedef typename chooser::template rebind<T> bound_type; | ||||
|    typedef typename bound_type::type call_traits_type; | ||||
| public: | ||||
|    typedef typename call_traits_type::value_type       value_type; | ||||
|    typedef typename call_traits_type::reference        reference; | ||||
|    typedef typename call_traits_type::const_reference  const_reference; | ||||
|    typedef typename call_traits_type::param_type       param_type; | ||||
| }; | ||||
|  | ||||
| #else | ||||
| // | ||||
| // sorry call_traits is completely non-functional | ||||
| // blame your broken compiler: | ||||
| // | ||||
|  | ||||
| template <typename T> | ||||
| struct call_traits | ||||
| { | ||||
|    typedef T value_type; | ||||
|    typedef T& reference; | ||||
|    typedef const T& const_reference; | ||||
|    typedef const T& param_type; | ||||
| }; | ||||
|  | ||||
| #endif // member templates | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif // BOOST_OB_CALL_TRAITS_HPP | ||||
| @@ -20,11 +20,10 @@ | ||||
|       - John Maddock Jan 2000. | ||||
| */ | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
|  | ||||
| #ifndef BOOST_OB_COMPRESSED_PAIR_HPP | ||||
| #define BOOST_OB_COMPRESSED_PAIR_HPP | ||||
|  | ||||
|  | ||||
| #include <algorithm> | ||||
| #ifndef BOOST_OBJECT_TYPE_TRAITS_HPP | ||||
| #include <boost/type_traits/object_traits.hpp> | ||||
| @@ -168,6 +167,17 @@ public: | ||||
|    compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x) | ||||
|       : T2(x.second()), _first(x.first()) {} | ||||
|  | ||||
| #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 | ||||
|   // Total weirdness. If the assignment to _first is moved after | ||||
|   // the call to the inherited operator=, then this breaks graph/test/graph.cpp | ||||
|   // by way of iterator_adaptor. | ||||
|   compressed_pair_1& operator=(const compressed_pair_1& x) { | ||||
|     _first = x._first; | ||||
|     T2::operator=(x); | ||||
|     return *this; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|    first_reference       first()       { return _first; } | ||||
|    first_const_reference first() const { return _first; } | ||||
|  | ||||
| @@ -495,4 +505,6 @@ inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y) | ||||
| } // boost | ||||
|  | ||||
| #endif // BOOST_OB_COMPRESSED_PAIR_HPP | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										80
									
								
								include/boost/generator_iterator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								include/boost/generator_iterator.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| // (C) Copyright Jens Maurer 2001. | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
| // Revision History: | ||||
|  | ||||
| // 15 Nov 2001   Jens Maurer | ||||
| //      created. | ||||
|  | ||||
| //  See http://www.boost.org/libs/utility/iterator_adaptors.htm for documentation. | ||||
|  | ||||
| #ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP | ||||
| #define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP | ||||
|  | ||||
| #include <boost/iterator/iterator_facade.hpp> | ||||
| #include <boost/ref.hpp> | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| template<class Generator> | ||||
| class generator_iterator | ||||
|   : public iterator_facade< | ||||
|         generator_iterator<Generator> | ||||
|       , typename Generator::result_type | ||||
|       , single_pass_traversal_tag | ||||
|       , typename Generator::result_type const& | ||||
|     > | ||||
| { | ||||
|     typedef iterator_facade< | ||||
|         generator_iterator<Generator> | ||||
|       , typename Generator::result_type | ||||
|       , single_pass_traversal_tag | ||||
|       , typename Generator::result_type const& | ||||
|     > super_t; | ||||
|      | ||||
|  public: | ||||
|     generator_iterator() {} | ||||
|     generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {} | ||||
|  | ||||
|     void increment() | ||||
|     { | ||||
|         m_value = (*m_g)(); | ||||
|     } | ||||
|  | ||||
|     const typename Generator::result_type& | ||||
|     dereference() const | ||||
|     { | ||||
|         return m_value; | ||||
|     } | ||||
|  | ||||
|     bool equal(generator_iterator const& y) const | ||||
|     { | ||||
|         return this->m_g == y.m_g && this->m_value == y.m_value; | ||||
|     } | ||||
|  | ||||
|  private: | ||||
|     Generator* m_g; | ||||
|     typename Generator::result_type m_value; | ||||
| }; | ||||
|  | ||||
| template<class Generator> | ||||
| struct generator_iterator_generator | ||||
| { | ||||
|   typedef generator_iterator<Generator> type; | ||||
| }; | ||||
|  | ||||
| template <class Generator> | ||||
| inline generator_iterator<Generator> | ||||
| make_generator_iterator(Generator & gen) | ||||
| { | ||||
|   typedef generator_iterator<Generator> result_t; | ||||
|   return result_t(&gen); | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
|  | ||||
| #endif // BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP | ||||
|  | ||||
							
								
								
									
										51
									
								
								include/boost/next_prior.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								include/boost/next_prior.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| //  Boost next_prior.hpp header file  ---------------------------------------// | ||||
|  | ||||
| //  (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. Distributed under the Boost | ||||
| //  Software License, Version 1.0. (See accompanying file | ||||
| //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  See http://www.boost.org/libs/utility for documentation. | ||||
|  | ||||
| //  Revision History | ||||
| //  13 Dec 2003  Added next(x, n) and prior(x, n) (Daniel Walker) | ||||
|  | ||||
| #ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED | ||||
| #define BOOST_NEXT_PRIOR_HPP_INCLUDED | ||||
|  | ||||
| #include <iterator> | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| //  Helper functions for classes like bidirectional iterators not supporting | ||||
| //  operator+ and operator- | ||||
| // | ||||
| //  Usage: | ||||
| //    const std::list<T>::iterator p = get_some_iterator(); | ||||
| //    const std::list<T>::iterator prev = boost::prior(p); | ||||
| //    const std::list<T>::iterator next = boost::next(prev, 2); | ||||
|  | ||||
| //  Contributed by Dave Abrahams | ||||
|  | ||||
| template <class T> | ||||
| inline T next(T x) { return ++x; } | ||||
|  | ||||
| template <class T, class Distance> | ||||
| inline T next(T x, Distance n) | ||||
| { | ||||
|     std::advance(x, n); | ||||
|     return x; | ||||
| } | ||||
|  | ||||
| template <class T> | ||||
| inline T prior(T x) { return --x; } | ||||
|  | ||||
| template <class T, class Distance> | ||||
| inline T prior(T x, Distance n) | ||||
| { | ||||
|     std::advance(x, -n); | ||||
|     return x; | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // BOOST_NEXT_PRIOR_HPP_INCLUDED | ||||
							
								
								
									
										48
									
								
								include/boost/noncopyable.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								include/boost/noncopyable.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| //  Boost noncopyable.hpp header file  --------------------------------------// | ||||
|  | ||||
| //  (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost | ||||
| //  Software License, Version 1.0. (See accompanying file | ||||
| //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  See http://www.boost.org/libs/utility for documentation. | ||||
|  | ||||
| #ifndef BOOST_NONCOPYABLE_HPP_INCLUDED | ||||
| #define BOOST_NONCOPYABLE_HPP_INCLUDED | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| //  Private copy constructor and copy assignment ensure classes derived from | ||||
| //  class noncopyable cannot be copied. | ||||
|  | ||||
| //  Contributed by Dave Abrahams | ||||
|  | ||||
| namespace noncopyable_  // protection from unintended ADL | ||||
| { | ||||
|   class noncopyable | ||||
|   { | ||||
|    protected: | ||||
| #ifndef BOOST_NO_DEFAULTED_FUNCTIONS | ||||
|     BOOST_CONSTEXPR noncopyable() = default; | ||||
|     ~noncopyable() = default; | ||||
| #else | ||||
|     noncopyable() {} | ||||
|       ~noncopyable() {} | ||||
| #endif | ||||
| #ifndef BOOST_NO_DELETED_FUNCTIONS | ||||
|         noncopyable( const noncopyable& ) = delete; | ||||
|         noncopyable& operator=( const noncopyable& ) = delete; | ||||
| #else | ||||
|     private:  // emphasize the following members are private | ||||
|       noncopyable( const noncopyable& ); | ||||
|       noncopyable& operator=( const noncopyable& ); | ||||
| #endif | ||||
|   }; | ||||
| } | ||||
|  | ||||
| typedef noncopyable_::noncopyable noncopyable; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // BOOST_NONCOPYABLE_HPP_INCLUDED | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,951 +0,0 @@ | ||||
| //  Boost operators.hpp header file  ----------------------------------------// | ||||
|  | ||||
| //  (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001. | ||||
| //  Distributed under the Boost Software License, Version 1.0. (See | ||||
| //  accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  See http://www.boost.org/libs/utility/operators.htm for documentation. | ||||
|  | ||||
| //  Revision History | ||||
| //  22 Feb 16 Preserve old work-arounds. (Daniel Frey) | ||||
| //  16 Dec 10 Limit warning suppression for 4284 to older versions of VC++ | ||||
| //            (Matthew Bradbury, fixes #4432) | ||||
| //  07 Aug 08 Added "euclidean" spelling. (Daniel Frey) | ||||
| //  03 Apr 08 Make sure "convertible to bool" is sufficient | ||||
| //            for T::operator<, etc. (Daniel Frey) | ||||
| //  24 May 07 Changed empty_base to depend on T, see | ||||
| //            http://svn.boost.org/trac/boost/ticket/979 | ||||
| //  21 Oct 02 Modified implementation of operators to allow compilers with a | ||||
| //            correct named return value optimization (NRVO) to produce optimal | ||||
| //            code.  (Daniel Frey) | ||||
| //  02 Dec 01 Bug fixed in random_access_iteratable.  (Helmut Zeisel) | ||||
| //  28 Sep 01 Factored out iterator operator groups.  (Daryle Walker) | ||||
| //  27 Aug 01 'left' form for non commutative operators added; | ||||
| //            additional classes for groups of related operators added; | ||||
| //            workaround for empty base class optimization | ||||
| //            bug of GCC 3.0 (Helmut Zeisel) | ||||
| //  25 Jun 01 output_iterator_helper changes: removed default template  | ||||
| //            parameters, added support for self-proxying, additional  | ||||
| //            documentation and tests (Aleksey Gurtovoy) | ||||
| //  29 May 01 Added operator classes for << and >>.  Added input and output | ||||
| //            iterator helper classes.  Added classes to connect equality and | ||||
| //            relational operators.  Added classes for groups of related | ||||
| //            operators.  Reimplemented example operator and iterator helper | ||||
| //            classes in terms of the new groups.  (Daryle Walker, with help | ||||
| //            from Alexy Gurtovoy) | ||||
| //  11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly | ||||
| //            supplied arguments from actually being used (Dave Abrahams) | ||||
| //  04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and | ||||
| //            refactoring of compiler workarounds, additional documentation | ||||
| //            (Alexy Gurtovoy and Mark Rodgers with some help and prompting from | ||||
| //            Dave Abrahams)  | ||||
| //  28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and | ||||
| //            Jeremy Siek (Dave Abrahams) | ||||
| //  20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5 | ||||
| //            (Mark Rodgers) | ||||
| //  20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy) | ||||
| //  10 Jun 00 Support for the base class chaining technique was added | ||||
| //            (Aleksey Gurtovoy). See documentation and the comments below  | ||||
| //            for the details.  | ||||
| //  12 Dec 99 Initial version with iterator operators (Jeremy Siek) | ||||
| //  18 Nov 99 Change name "divideable" to "dividable", remove unnecessary | ||||
| //            specializations of dividable, subtractable, modable (Ed Brey)  | ||||
| //  17 Nov 99 Add comments (Beman Dawes) | ||||
| //            Remove unnecessary specialization of operators<> (Ed Brey) | ||||
| //  15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two | ||||
| //            operators.(Beman Dawes) | ||||
| //  12 Nov 99 Add operators templates (Ed Brey) | ||||
| //  11 Nov 99 Add single template parameter version for compilers without | ||||
| //            partial specialization (Beman Dawes) | ||||
| //  10 Nov 99 Initial version | ||||
|  | ||||
| // 10 Jun 00: | ||||
| // An additional optional template parameter was added to most of  | ||||
| // operator templates to support the base class chaining technique (see  | ||||
| // documentation for the details). Unfortunately, a straightforward | ||||
| // implementation of this change would have broken compatibility with the | ||||
| // previous version of the library by making it impossible to use the same | ||||
| // template name (e.g. 'addable') for both the 1- and 2-argument versions of | ||||
| // an operator template. This implementation solves the backward-compatibility | ||||
| // issue at the cost of some simplicity. | ||||
| // | ||||
| // One of the complications is an existence of special auxiliary class template | ||||
| // 'is_chained_base<>' (see 'detail' namespace below), which is used | ||||
| // to determine whether its template parameter is a library's operator template | ||||
| // or not. You have to specialize 'is_chained_base<>' for each new  | ||||
| // operator template you add to the library. | ||||
| // | ||||
| // However, most of the non-trivial implementation details are hidden behind  | ||||
| // several local macros defined below, and as soon as you understand them, | ||||
| // you understand the whole library implementation.  | ||||
|  | ||||
| #ifndef BOOST_OPERATORS_V1_HPP | ||||
| #define BOOST_OPERATORS_V1_HPP | ||||
|  | ||||
| #include <cstddef> | ||||
| #include <iterator> | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
|  | ||||
| #if defined(__sgi) && !defined(__GNUC__) | ||||
| #   pragma set woff 1234 | ||||
| #endif | ||||
|  | ||||
| #if BOOST_WORKAROUND(BOOST_MSVC, < 1600) | ||||
| #   pragma warning( disable : 4284 ) // complaint about return type of  | ||||
| #endif                               // operator-> not begin a UDT | ||||
|  | ||||
| namespace boost { | ||||
| namespace detail { | ||||
|  | ||||
| template <typename T> class empty_base {}; | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| // In this section we supply the xxxx1 and xxxx2 forms of the operator | ||||
| // templates, which are explicitly targeted at the 1-type-argument and | ||||
| // 2-type-argument operator forms, respectively. Some compilers get confused | ||||
| // when inline friend functions are overloaded in namespaces other than the | ||||
| // global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of | ||||
| // these templates must go in the global namespace. | ||||
|  | ||||
| #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE | ||||
| namespace boost | ||||
| { | ||||
| #endif | ||||
|  | ||||
| //  Basic operator classes (contributed by Dave Abrahams) ------------------// | ||||
|  | ||||
| //  Note that friend functions defined in a class are implicitly inline. | ||||
| //  See the C++ std, 11.4 [class.friend] paragraph 5 | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct less_than_comparable2 : B | ||||
| { | ||||
|      friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); } | ||||
|      friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); } | ||||
|      friend bool operator>(const U& x, const T& y)  { return y < x; } | ||||
|      friend bool operator<(const U& x, const T& y)  { return y > x; } | ||||
|      friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); } | ||||
|      friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); } | ||||
| }; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct less_than_comparable1 : B | ||||
| { | ||||
|      friend bool operator>(const T& x, const T& y)  { return y < x; } | ||||
|      friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); } | ||||
|      friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); } | ||||
| }; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct equality_comparable2 : B | ||||
| { | ||||
|      friend bool operator==(const U& y, const T& x) { return x == y; } | ||||
|      friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); } | ||||
|      friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); } | ||||
| }; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct equality_comparable1 : B | ||||
| { | ||||
|      friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); } | ||||
| }; | ||||
|  | ||||
| // A macro which produces "name_2left" from "name". | ||||
| #define BOOST_OPERATOR2_LEFT(name) name##2##_##left | ||||
|  | ||||
| //  NRVO-friendly implementation (contributed by Daniel Frey) ---------------// | ||||
|  | ||||
| #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) | ||||
|  | ||||
| // This is the optimal implementation for ISO/ANSI C++, | ||||
| // but it requires the compiler to implement the NRVO. | ||||
| // If the compiler has no NRVO, this is the best symmetric | ||||
| // implementation available. | ||||
|  | ||||
| #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                         \ | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> >        \ | ||||
| struct NAME##2 : B                                                            \ | ||||
| {                                                                             \ | ||||
|   friend T operator OP( const T& lhs, const U& rhs )                          \ | ||||
|     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \ | ||||
|   friend T operator OP( const U& lhs, const T& rhs )                          \ | ||||
|     { T nrv( rhs ); nrv OP##= lhs; return nrv; }                              \ | ||||
| };                                                                            \ | ||||
|                                                                               \ | ||||
| template <class T, class B = ::boost::detail::empty_base<T> >                 \ | ||||
| struct NAME##1 : B                                                            \ | ||||
| {                                                                             \ | ||||
|   friend T operator OP( const T& lhs, const T& rhs )                          \ | ||||
|     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \ | ||||
| }; | ||||
|  | ||||
| #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \ | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> >  \ | ||||
| struct NAME##2 : B                                                      \ | ||||
| {                                                                       \ | ||||
|   friend T operator OP( const T& lhs, const U& rhs )                    \ | ||||
|     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \ | ||||
| };                                                                      \ | ||||
|                                                                         \ | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> >  \ | ||||
| struct BOOST_OPERATOR2_LEFT(NAME) : B                                   \ | ||||
| {                                                                       \ | ||||
|   friend T operator OP( const U& lhs, const T& rhs )                    \ | ||||
|     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \ | ||||
| };                                                                      \ | ||||
|                                                                         \ | ||||
| template <class T, class B = ::boost::detail::empty_base<T> >           \ | ||||
| struct NAME##1 : B                                                      \ | ||||
| {                                                                       \ | ||||
|   friend T operator OP( const T& lhs, const T& rhs )                    \ | ||||
|     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                        \ | ||||
| }; | ||||
|  | ||||
| #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) | ||||
|  | ||||
| // For compilers without NRVO the following code is optimal, but not | ||||
| // symmetric!  Note that the implementation of | ||||
| // BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide | ||||
| // optimization opportunities to the compiler :) | ||||
|  | ||||
| #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP )                   \ | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> >  \ | ||||
| struct NAME##2 : B                                                      \ | ||||
| {                                                                       \ | ||||
|   friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ | ||||
|   friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \ | ||||
| };                                                                      \ | ||||
|                                                                         \ | ||||
| template <class T, class B = ::boost::detail::empty_base<T> >           \ | ||||
| struct NAME##1 : B                                                      \ | ||||
| {                                                                       \ | ||||
|   friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ | ||||
| }; | ||||
|  | ||||
| #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP )               \ | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> >  \ | ||||
| struct NAME##2 : B                                                      \ | ||||
| {                                                                       \ | ||||
|   friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ | ||||
| };                                                                      \ | ||||
|                                                                         \ | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> >  \ | ||||
| struct BOOST_OPERATOR2_LEFT(NAME) : B                                   \ | ||||
| {                                                                       \ | ||||
|   friend T operator OP( const U& lhs, const T& rhs )                    \ | ||||
|     { return T( lhs ) OP##= rhs; }                                      \ | ||||
| };                                                                      \ | ||||
|                                                                         \ | ||||
| template <class T, class B = ::boost::detail::empty_base<T> >           \ | ||||
| struct NAME##1 : B                                                      \ | ||||
| {                                                                       \ | ||||
|   friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ | ||||
| }; | ||||
|  | ||||
| #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) | ||||
|  | ||||
| BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * ) | ||||
| BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + ) | ||||
| BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - ) | ||||
| BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / ) | ||||
| BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % ) | ||||
| BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ ) | ||||
| BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & ) | ||||
| BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | ) | ||||
|  | ||||
| #undef BOOST_BINARY_OPERATOR_COMMUTATIVE | ||||
| #undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE | ||||
| #undef BOOST_OPERATOR2_LEFT | ||||
|  | ||||
| //  incrementable and decrementable contributed by Jeremy Siek | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct incrementable : B | ||||
| { | ||||
|   friend T operator++(T& x, int) | ||||
|   { | ||||
|     incrementable_type nrv(x); | ||||
|     ++x; | ||||
|     return nrv; | ||||
|   } | ||||
| private: // The use of this typedef works around a Borland bug | ||||
|   typedef T incrementable_type; | ||||
| }; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct decrementable : B | ||||
| { | ||||
|   friend T operator--(T& x, int) | ||||
|   { | ||||
|     decrementable_type nrv(x); | ||||
|     --x; | ||||
|     return nrv; | ||||
|   } | ||||
| private: // The use of this typedef works around a Borland bug | ||||
|   typedef T decrementable_type; | ||||
| }; | ||||
|  | ||||
| //  Iterator operator classes (contributed by Jeremy Siek) ------------------// | ||||
|  | ||||
| template <class T, class P, class B = ::boost::detail::empty_base<T> > | ||||
| struct dereferenceable : B | ||||
| { | ||||
|   P operator->() const | ||||
|   {  | ||||
|     return &*static_cast<const T&>(*this);  | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <class T, class I, class R, class B = ::boost::detail::empty_base<T> > | ||||
| struct indexable : B | ||||
| { | ||||
|   R operator[](I n) const | ||||
|   { | ||||
|     return *(static_cast<const T&>(*this) + n); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| //  More operator classes (contributed by Daryle Walker) --------------------// | ||||
| //  (NRVO-friendly implementation contributed by Daniel Frey) ---------------// | ||||
|  | ||||
| #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) | ||||
|  | ||||
| #define BOOST_BINARY_OPERATOR( NAME, OP )                                     \ | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> >        \ | ||||
| struct NAME##2 : B                                                            \ | ||||
| {                                                                             \ | ||||
|   friend T operator OP( const T& lhs, const U& rhs )                          \ | ||||
|     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \ | ||||
| };                                                                            \ | ||||
|                                                                               \ | ||||
| template <class T, class B = ::boost::detail::empty_base<T> >                 \ | ||||
| struct NAME##1 : B                                                            \ | ||||
| {                                                                             \ | ||||
|   friend T operator OP( const T& lhs, const T& rhs )                          \ | ||||
|     { T nrv( lhs ); nrv OP##= rhs; return nrv; }                              \ | ||||
| }; | ||||
|  | ||||
| #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) | ||||
|  | ||||
| #define BOOST_BINARY_OPERATOR( NAME, OP )                                     \ | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> >        \ | ||||
| struct NAME##2 : B                                                            \ | ||||
| {                                                                             \ | ||||
|   friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; }       \ | ||||
| };                                                                            \ | ||||
|                                                                               \ | ||||
| template <class T, class B = ::boost::detail::empty_base<T> >                 \ | ||||
| struct NAME##1 : B                                                            \ | ||||
| {                                                                             \ | ||||
|   friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; }       \ | ||||
| }; | ||||
|  | ||||
| #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) | ||||
|  | ||||
| BOOST_BINARY_OPERATOR( left_shiftable, << ) | ||||
| BOOST_BINARY_OPERATOR( right_shiftable, >> ) | ||||
|  | ||||
| #undef BOOST_BINARY_OPERATOR | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct equivalent2 : B | ||||
| { | ||||
|   friend bool operator==(const T& x, const U& y) | ||||
|   { | ||||
|     return !static_cast<bool>(x < y) && !static_cast<bool>(x > y); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct equivalent1 : B | ||||
| { | ||||
|   friend bool operator==(const T&x, const T&y) | ||||
|   { | ||||
|     return !static_cast<bool>(x < y) && !static_cast<bool>(y < x); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct partially_ordered2 : B | ||||
| { | ||||
|   friend bool operator<=(const T& x, const U& y) | ||||
|     { return static_cast<bool>(x < y) || static_cast<bool>(x == y); } | ||||
|   friend bool operator>=(const T& x, const U& y) | ||||
|     { return static_cast<bool>(x > y) || static_cast<bool>(x == y); } | ||||
|   friend bool operator>(const U& x, const T& y) | ||||
|     { return y < x; } | ||||
|   friend bool operator<(const U& x, const T& y) | ||||
|     { return y > x; } | ||||
|   friend bool operator<=(const U& x, const T& y) | ||||
|     { return static_cast<bool>(y > x) || static_cast<bool>(y == x); } | ||||
|   friend bool operator>=(const U& x, const T& y) | ||||
|     { return static_cast<bool>(y < x) || static_cast<bool>(y == x); } | ||||
| }; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct partially_ordered1 : B | ||||
| { | ||||
|   friend bool operator>(const T& x, const T& y) | ||||
|     { return y < x; } | ||||
|   friend bool operator<=(const T& x, const T& y) | ||||
|     { return static_cast<bool>(x < y) || static_cast<bool>(x == y); } | ||||
|   friend bool operator>=(const T& x, const T& y) | ||||
|     { return static_cast<bool>(y < x) || static_cast<bool>(x == y); } | ||||
| }; | ||||
|  | ||||
| //  Combined operator classes (contributed by Daryle Walker) ----------------// | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct totally_ordered2 | ||||
|     : less_than_comparable2<T, U | ||||
|     , equality_comparable2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct totally_ordered1 | ||||
|     : less_than_comparable1<T | ||||
|     , equality_comparable1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct additive2 | ||||
|     : addable2<T, U | ||||
|     , subtractable2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct additive1 | ||||
|     : addable1<T | ||||
|     , subtractable1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct multiplicative2 | ||||
|     : multipliable2<T, U | ||||
|     , dividable2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct multiplicative1 | ||||
|     : multipliable1<T | ||||
|     , dividable1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct integer_multiplicative2 | ||||
|     : multiplicative2<T, U | ||||
|     , modable2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct integer_multiplicative1 | ||||
|     : multiplicative1<T | ||||
|     , modable1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct arithmetic2 | ||||
|     : additive2<T, U | ||||
|     , multiplicative2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct arithmetic1 | ||||
|     : additive1<T | ||||
|     , multiplicative1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct integer_arithmetic2 | ||||
|     : additive2<T, U | ||||
|     , integer_multiplicative2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct integer_arithmetic1 | ||||
|     : additive1<T | ||||
|     , integer_multiplicative1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct bitwise2 | ||||
|     : xorable2<T, U | ||||
|     , andable2<T, U | ||||
|     , orable2<T, U, B | ||||
|       > > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct bitwise1 | ||||
|     : xorable1<T | ||||
|     , andable1<T | ||||
|     , orable1<T, B | ||||
|       > > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct unit_steppable | ||||
|     : incrementable<T | ||||
|     , decrementable<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct shiftable2 | ||||
|     : left_shiftable2<T, U | ||||
|     , right_shiftable2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct shiftable1 | ||||
|     : left_shiftable1<T | ||||
|     , right_shiftable1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct ring_operators2 | ||||
|     : additive2<T, U | ||||
|     , subtractable2_left<T, U | ||||
|     , multipliable2<T, U, B | ||||
|       > > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct ring_operators1 | ||||
|     : additive1<T | ||||
|     , multipliable1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct ordered_ring_operators2 | ||||
|     : ring_operators2<T, U | ||||
|     , totally_ordered2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct ordered_ring_operators1 | ||||
|     : ring_operators1<T | ||||
|     , totally_ordered1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct field_operators2 | ||||
|     : ring_operators2<T, U | ||||
|     , dividable2<T, U | ||||
|     , dividable2_left<T, U, B | ||||
|       > > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct field_operators1 | ||||
|     : ring_operators1<T | ||||
|     , dividable1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct ordered_field_operators2 | ||||
|     : field_operators2<T, U | ||||
|     , totally_ordered2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct ordered_field_operators1 | ||||
|     : field_operators1<T | ||||
|     , totally_ordered1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct euclidian_ring_operators2 | ||||
|     : ring_operators2<T, U | ||||
|     , dividable2<T, U | ||||
|     , dividable2_left<T, U | ||||
|     , modable2<T, U | ||||
|     , modable2_left<T, U, B | ||||
|       > > > > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct euclidian_ring_operators1 | ||||
|     : ring_operators1<T | ||||
|     , dividable1<T | ||||
|     , modable1<T, B | ||||
|       > > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct ordered_euclidian_ring_operators2 | ||||
|     : totally_ordered2<T, U | ||||
|     , euclidian_ring_operators2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct ordered_euclidian_ring_operators1 | ||||
|     : totally_ordered1<T | ||||
|     , euclidian_ring_operators1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct euclidean_ring_operators2 | ||||
|     : ring_operators2<T, U | ||||
|     , dividable2<T, U | ||||
|     , dividable2_left<T, U | ||||
|     , modable2<T, U | ||||
|     , modable2_left<T, U, B | ||||
|       > > > > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct euclidean_ring_operators1 | ||||
|     : ring_operators1<T | ||||
|     , dividable1<T | ||||
|     , modable1<T, B | ||||
|       > > > {}; | ||||
|  | ||||
| template <class T, class U, class B = ::boost::detail::empty_base<T> > | ||||
| struct ordered_euclidean_ring_operators2 | ||||
|     : totally_ordered2<T, U | ||||
|     , euclidean_ring_operators2<T, U, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct ordered_euclidean_ring_operators1 | ||||
|     : totally_ordered1<T | ||||
|     , euclidean_ring_operators1<T, B | ||||
|       > > {}; | ||||
|  | ||||
| template <class T, class P, class B = ::boost::detail::empty_base<T> > | ||||
| struct input_iteratable | ||||
|     : equality_comparable1<T | ||||
|     , incrementable<T | ||||
|     , dereferenceable<T, P, B | ||||
|       > > > {}; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| struct output_iteratable | ||||
|     : incrementable<T, B | ||||
|       > {}; | ||||
|  | ||||
| template <class T, class P, class B = ::boost::detail::empty_base<T> > | ||||
| struct forward_iteratable | ||||
|     : input_iteratable<T, P, B | ||||
|       > {}; | ||||
|  | ||||
| template <class T, class P, class B = ::boost::detail::empty_base<T> > | ||||
| struct bidirectional_iteratable | ||||
|     : forward_iteratable<T, P | ||||
|     , decrementable<T, B | ||||
|       > > {}; | ||||
|  | ||||
| //  To avoid repeated derivation from equality_comparable, | ||||
| //  which is an indirect base class of bidirectional_iterable, | ||||
| //  random_access_iteratable must not be derived from totally_ordered1 | ||||
| //  but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001) | ||||
| template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> > | ||||
| struct random_access_iteratable | ||||
|     : bidirectional_iteratable<T, P | ||||
|     , less_than_comparable1<T | ||||
|     , additive2<T, D | ||||
|     , indexable<T, D, R, B | ||||
|       > > > > {}; | ||||
|  | ||||
| #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE | ||||
| } // namespace boost | ||||
| #endif // BOOST_NO_OPERATORS_IN_NAMESPACE | ||||
|  | ||||
|  | ||||
| // BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 - | ||||
| // | ||||
| // When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an | ||||
| // operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used | ||||
| // for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for | ||||
| // two-argument forms. Note that these macros expect to be invoked from within | ||||
| // boost. | ||||
|  | ||||
| #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE | ||||
|  | ||||
|   // The template is already in boost so we have nothing to do. | ||||
| # define BOOST_IMPORT_TEMPLATE4(template_name) | ||||
| # define BOOST_IMPORT_TEMPLATE3(template_name) | ||||
| # define BOOST_IMPORT_TEMPLATE2(template_name) | ||||
| # define BOOST_IMPORT_TEMPLATE1(template_name) | ||||
|  | ||||
| #else // BOOST_NO_OPERATORS_IN_NAMESPACE | ||||
|  | ||||
| #  ifndef BOOST_NO_USING_TEMPLATE | ||||
|  | ||||
|      // Bring the names in with a using-declaration | ||||
|      // to avoid stressing the compiler. | ||||
| #    define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name; | ||||
| #    define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name; | ||||
| #    define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name; | ||||
| #    define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name; | ||||
|  | ||||
| #  else | ||||
|  | ||||
|      // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration | ||||
|      // from working, we are forced to use inheritance for that compiler. | ||||
| #    define BOOST_IMPORT_TEMPLATE4(template_name)                                             \ | ||||
|      template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \ | ||||
|      struct template_name : ::template_name<T, U, V, W, B> {}; | ||||
|  | ||||
| #    define BOOST_IMPORT_TEMPLATE3(template_name)                                    \ | ||||
|      template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \ | ||||
|      struct template_name : ::template_name<T, U, V, B> {}; | ||||
|  | ||||
| #    define BOOST_IMPORT_TEMPLATE2(template_name)                           \ | ||||
|      template <class T, class U, class B = ::boost::detail::empty_base<T> > \ | ||||
|      struct template_name : ::template_name<T, U, B> {}; | ||||
|  | ||||
| #    define BOOST_IMPORT_TEMPLATE1(template_name)                  \ | ||||
|      template <class T, class B = ::boost::detail::empty_base<T> > \ | ||||
|      struct template_name : ::template_name<T, B> {}; | ||||
|  | ||||
| #  endif // BOOST_NO_USING_TEMPLATE | ||||
|  | ||||
| #endif // BOOST_NO_OPERATORS_IN_NAMESPACE | ||||
|  | ||||
| // | ||||
| // Here's where we put it all together, defining the xxxx forms of the templates | ||||
| // in namespace boost. We also define specializations of is_chained_base<> for | ||||
| // the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as | ||||
| // necessary. | ||||
| // | ||||
|  | ||||
| // is_chained_base<> - a traits class used to distinguish whether an operator | ||||
| // template argument is being used for base class chaining, or is specifying a | ||||
| // 2nd argument type. | ||||
|  | ||||
| namespace boost { | ||||
| // A type parameter is used instead of a plain bool because Borland's compiler | ||||
| // didn't cope well with the more obvious non-type template parameter. | ||||
| namespace detail { | ||||
|   struct true_t {}; | ||||
|   struct false_t {}; | ||||
| } // namespace detail | ||||
|  | ||||
| // Unspecialized version assumes that most types are not being used for base | ||||
| // class chaining. We specialize for the operator templates defined in this | ||||
| // library. | ||||
| template<class T> struct is_chained_base { | ||||
|   typedef ::boost::detail::false_t value; | ||||
| }; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| // Import a 4-type-argument operator template into boost (if necessary) and | ||||
| // provide a specialization of 'is_chained_base<>' for it. | ||||
| # define BOOST_OPERATOR_TEMPLATE4(template_name4)                     \ | ||||
|   BOOST_IMPORT_TEMPLATE4(template_name4)                              \ | ||||
|   template<class T, class U, class V, class W, class B>               \ | ||||
|   struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > {  \ | ||||
|     typedef ::boost::detail::true_t value;                            \ | ||||
|   }; | ||||
|  | ||||
| // Import a 3-type-argument operator template into boost (if necessary) and | ||||
| // provide a specialization of 'is_chained_base<>' for it. | ||||
| # define BOOST_OPERATOR_TEMPLATE3(template_name3)                     \ | ||||
|   BOOST_IMPORT_TEMPLATE3(template_name3)                              \ | ||||
|   template<class T, class U, class V, class B>                        \ | ||||
|   struct is_chained_base< ::boost::template_name3<T, U, V, B> > {     \ | ||||
|     typedef ::boost::detail::true_t value;                            \ | ||||
|   }; | ||||
|  | ||||
| // Import a 2-type-argument operator template into boost (if necessary) and | ||||
| // provide a specialization of 'is_chained_base<>' for it. | ||||
| # define BOOST_OPERATOR_TEMPLATE2(template_name2)                  \ | ||||
|   BOOST_IMPORT_TEMPLATE2(template_name2)                           \ | ||||
|   template<class T, class U, class B>                              \ | ||||
|   struct is_chained_base< ::boost::template_name2<T, U, B> > {     \ | ||||
|     typedef ::boost::detail::true_t value;                         \ | ||||
|   }; | ||||
|  | ||||
| // Import a 1-type-argument operator template into boost (if necessary) and | ||||
| // provide a specialization of 'is_chained_base<>' for it. | ||||
| # define BOOST_OPERATOR_TEMPLATE1(template_name1)                  \ | ||||
|   BOOST_IMPORT_TEMPLATE1(template_name1)                           \ | ||||
|   template<class T, class B>                                       \ | ||||
|   struct is_chained_base< ::boost::template_name1<T, B> > {        \ | ||||
|     typedef ::boost::detail::true_t value;                         \ | ||||
|   }; | ||||
|  | ||||
| // BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it | ||||
| // can be used for specifying both 1-argument and 2-argument forms. Requires the | ||||
| // existence of two previously defined class templates named '<template_name>1' | ||||
| // and '<template_name>2' which must implement the corresponding 1- and 2- | ||||
| // argument forms. | ||||
| // | ||||
| // The template type parameter O == is_chained_base<U>::value is used to | ||||
| // distinguish whether the 2nd argument to <template_name> is being used for | ||||
| // base class chaining from another boost operator template or is describing a | ||||
| // 2nd operand type. O == true_t only when U is actually an another operator | ||||
| // template from the library. Partial specialization is used to select an | ||||
| // implementation in terms of either '<template_name>1' or '<template_name>2'. | ||||
| // | ||||
|  | ||||
| # define BOOST_OPERATOR_TEMPLATE(template_name)                    \ | ||||
| template <class T                                                  \ | ||||
|          ,class U = T                                              \ | ||||
|          ,class B = ::boost::detail::empty_base<T>                 \ | ||||
|          ,class O = typename is_chained_base<U>::value             \ | ||||
|          >                                                         \ | ||||
| struct template_name : template_name##2<T, U, B> {};               \ | ||||
|                                                                    \ | ||||
| template<class T, class U, class B>                                \ | ||||
| struct template_name<T, U, B, ::boost::detail::true_t>             \ | ||||
|   : template_name##1<T, U> {};                                     \ | ||||
|                                                                    \ | ||||
| template <class T, class B>                                        \ | ||||
| struct template_name<T, T, B, ::boost::detail::false_t>            \ | ||||
|   : template_name##1<T, B> {};                                     \ | ||||
|                                                                    \ | ||||
| template<class T, class U, class B, class O>                       \ | ||||
| struct is_chained_base< ::boost::template_name<T, U, B, O> > {     \ | ||||
|   typedef ::boost::detail::true_t value;                           \ | ||||
| };                                                                 \ | ||||
|                                                                    \ | ||||
| BOOST_OPERATOR_TEMPLATE2(template_name##2)                         \ | ||||
| BOOST_OPERATOR_TEMPLATE1(template_name##1) | ||||
|  | ||||
|  | ||||
|  | ||||
| namespace boost { | ||||
|      | ||||
| BOOST_OPERATOR_TEMPLATE(less_than_comparable) | ||||
| BOOST_OPERATOR_TEMPLATE(equality_comparable) | ||||
| BOOST_OPERATOR_TEMPLATE(multipliable) | ||||
| BOOST_OPERATOR_TEMPLATE(addable) | ||||
| BOOST_OPERATOR_TEMPLATE(subtractable) | ||||
| BOOST_OPERATOR_TEMPLATE2(subtractable2_left) | ||||
| BOOST_OPERATOR_TEMPLATE(dividable) | ||||
| BOOST_OPERATOR_TEMPLATE2(dividable2_left) | ||||
| BOOST_OPERATOR_TEMPLATE(modable) | ||||
| BOOST_OPERATOR_TEMPLATE2(modable2_left) | ||||
| BOOST_OPERATOR_TEMPLATE(xorable) | ||||
| BOOST_OPERATOR_TEMPLATE(andable) | ||||
| BOOST_OPERATOR_TEMPLATE(orable) | ||||
|  | ||||
| BOOST_OPERATOR_TEMPLATE1(incrementable) | ||||
| BOOST_OPERATOR_TEMPLATE1(decrementable) | ||||
|  | ||||
| BOOST_OPERATOR_TEMPLATE2(dereferenceable) | ||||
| BOOST_OPERATOR_TEMPLATE3(indexable) | ||||
|  | ||||
| BOOST_OPERATOR_TEMPLATE(left_shiftable) | ||||
| BOOST_OPERATOR_TEMPLATE(right_shiftable) | ||||
| BOOST_OPERATOR_TEMPLATE(equivalent) | ||||
| BOOST_OPERATOR_TEMPLATE(partially_ordered) | ||||
|  | ||||
| BOOST_OPERATOR_TEMPLATE(totally_ordered) | ||||
| BOOST_OPERATOR_TEMPLATE(additive) | ||||
| BOOST_OPERATOR_TEMPLATE(multiplicative) | ||||
| BOOST_OPERATOR_TEMPLATE(integer_multiplicative) | ||||
| BOOST_OPERATOR_TEMPLATE(arithmetic) | ||||
| BOOST_OPERATOR_TEMPLATE(integer_arithmetic) | ||||
| BOOST_OPERATOR_TEMPLATE(bitwise) | ||||
| BOOST_OPERATOR_TEMPLATE1(unit_steppable) | ||||
| BOOST_OPERATOR_TEMPLATE(shiftable) | ||||
| BOOST_OPERATOR_TEMPLATE(ring_operators) | ||||
| BOOST_OPERATOR_TEMPLATE(ordered_ring_operators) | ||||
| BOOST_OPERATOR_TEMPLATE(field_operators) | ||||
| BOOST_OPERATOR_TEMPLATE(ordered_field_operators) | ||||
| BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators) | ||||
| BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators) | ||||
| BOOST_OPERATOR_TEMPLATE(euclidean_ring_operators) | ||||
| BOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators) | ||||
| BOOST_OPERATOR_TEMPLATE2(input_iteratable) | ||||
| BOOST_OPERATOR_TEMPLATE1(output_iteratable) | ||||
| BOOST_OPERATOR_TEMPLATE2(forward_iteratable) | ||||
| BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable) | ||||
| BOOST_OPERATOR_TEMPLATE4(random_access_iteratable) | ||||
|  | ||||
| #undef BOOST_OPERATOR_TEMPLATE | ||||
| #undef BOOST_OPERATOR_TEMPLATE4 | ||||
| #undef BOOST_OPERATOR_TEMPLATE3 | ||||
| #undef BOOST_OPERATOR_TEMPLATE2 | ||||
| #undef BOOST_OPERATOR_TEMPLATE1 | ||||
| #undef BOOST_IMPORT_TEMPLATE1 | ||||
| #undef BOOST_IMPORT_TEMPLATE2 | ||||
| #undef BOOST_IMPORT_TEMPLATE3 | ||||
| #undef BOOST_IMPORT_TEMPLATE4 | ||||
|  | ||||
| // The following 'operators' classes can only be used portably if the derived class | ||||
| // declares ALL of the required member operators. | ||||
| template <class T, class U> | ||||
| struct operators2 | ||||
|     : totally_ordered2<T,U | ||||
|     , integer_arithmetic2<T,U | ||||
|     , bitwise2<T,U | ||||
|       > > > {}; | ||||
|  | ||||
| template <class T, class U = T> | ||||
| struct operators : operators2<T, U> {}; | ||||
|  | ||||
| template <class T> struct operators<T, T> | ||||
|     : totally_ordered<T | ||||
|     , integer_arithmetic<T | ||||
|     , bitwise<T | ||||
|     , unit_steppable<T | ||||
|       > > > > {}; | ||||
|  | ||||
| //  Iterator helper classes (contributed by Jeremy Siek) -------------------// | ||||
| //  (Input and output iterator helpers contributed by Daryle Walker) -------// | ||||
| //  (Changed to use combined operator classes by Daryle Walker) ------------// | ||||
| template <class T, | ||||
|           class V, | ||||
|           class D = std::ptrdiff_t, | ||||
|           class P = V const *, | ||||
|           class R = V const &> | ||||
| struct input_iterator_helper | ||||
|   : input_iteratable<T, P | ||||
|   , std::iterator<std::input_iterator_tag, V, D, P, R | ||||
|     > > {}; | ||||
|  | ||||
| template<class T> | ||||
| struct output_iterator_helper | ||||
|   : output_iteratable<T | ||||
|   , std::iterator<std::output_iterator_tag, void, void, void, void | ||||
|   > > | ||||
| { | ||||
|   T& operator*()  { return static_cast<T&>(*this); } | ||||
|   T& operator++() { return static_cast<T&>(*this); } | ||||
| }; | ||||
|  | ||||
| template <class T, | ||||
|           class V, | ||||
|           class D = std::ptrdiff_t, | ||||
|           class P = V*, | ||||
|           class R = V&> | ||||
| struct forward_iterator_helper | ||||
|   : forward_iteratable<T, P | ||||
|   , std::iterator<std::forward_iterator_tag, V, D, P, R | ||||
|     > > {}; | ||||
|  | ||||
| template <class T, | ||||
|           class V, | ||||
|           class D = std::ptrdiff_t, | ||||
|           class P = V*, | ||||
|           class R = V&> | ||||
| struct bidirectional_iterator_helper | ||||
|   : bidirectional_iteratable<T, P | ||||
|   , std::iterator<std::bidirectional_iterator_tag, V, D, P, R | ||||
|     > > {}; | ||||
|  | ||||
| template <class T, | ||||
|           class V,  | ||||
|           class D = std::ptrdiff_t, | ||||
|           class P = V*, | ||||
|           class R = V&> | ||||
| struct random_access_iterator_helper | ||||
|   : random_access_iteratable<T, P, D, R | ||||
|   , std::iterator<std::random_access_iterator_tag, V, D, P, R | ||||
|     > > | ||||
| { | ||||
|   friend D requires_difference_operator(const T& x, const T& y) { | ||||
|     return x - y; | ||||
|   } | ||||
| }; // random_access_iterator_helper | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #if defined(__sgi) && !defined(__GNUC__) | ||||
| #pragma reset woff 1234 | ||||
| #endif | ||||
|  | ||||
| #endif // BOOST_OPERATORS_V1_HPP | ||||
							
								
								
									
										189
									
								
								include/boost/ref.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								include/boost/ref.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | ||||
| #ifndef BOOST_REF_HPP_INCLUDED | ||||
| #define BOOST_REF_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/utility/addressof.hpp> | ||||
| #include <boost/mpl/bool.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
|  | ||||
| // | ||||
| //  ref.hpp - ref/cref, useful helper functions | ||||
| // | ||||
| //  Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) | ||||
| //  Copyright (C) 2001, 2002 Peter Dimov | ||||
| //  Copyright (C) 2002 David Abrahams | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
| // | ||||
| //  See http://www.boost.org/libs/bind/ref.html for documentation. | ||||
| // | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| template<class T> class reference_wrapper | ||||
| {  | ||||
| public: | ||||
|     typedef T type; | ||||
|  | ||||
| #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) | ||||
|  | ||||
|     explicit reference_wrapper(T& t): t_(&t) {} | ||||
|  | ||||
| #else | ||||
|  | ||||
|     explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} | ||||
|  | ||||
| #endif | ||||
|  | ||||
|     operator T& () const { return *t_; } | ||||
|  | ||||
|     T& get() const { return *t_; } | ||||
|  | ||||
|     T* get_pointer() const { return t_; } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     T* t_; | ||||
| }; | ||||
|  | ||||
| # if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) | ||||
| #  define BOOST_REF_CONST | ||||
| # else | ||||
| #  define BOOST_REF_CONST const | ||||
| # endif | ||||
|  | ||||
| template<class T> inline reference_wrapper<T> BOOST_REF_CONST ref(T & t) | ||||
| {  | ||||
|     return reference_wrapper<T>(t); | ||||
| } | ||||
|  | ||||
| template<class T> inline reference_wrapper<T const> BOOST_REF_CONST cref(T const & t) | ||||
| { | ||||
|     return reference_wrapper<T const>(t); | ||||
| } | ||||
|  | ||||
| # undef BOOST_REF_CONST | ||||
|  | ||||
| # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|  | ||||
| template<typename T> | ||||
| class is_reference_wrapper | ||||
|     : public mpl::false_ | ||||
| { | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| class unwrap_reference | ||||
| { | ||||
|  public: | ||||
|     typedef T type; | ||||
| }; | ||||
|  | ||||
| #  define AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(X) \ | ||||
| template<typename T> \ | ||||
| class is_reference_wrapper< X > \ | ||||
|     : public mpl::true_ \ | ||||
| { \ | ||||
| }; \ | ||||
| \ | ||||
| template<typename T> \ | ||||
| class unwrap_reference< X > \ | ||||
| { \ | ||||
|  public: \ | ||||
|     typedef T type; \ | ||||
| }; \ | ||||
| /**/ | ||||
|  | ||||
| AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T>) | ||||
| #if !defined(BOOST_NO_CV_SPECIALIZATIONS) | ||||
| AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const) | ||||
| AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> volatile) | ||||
| AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const volatile) | ||||
| #endif | ||||
|  | ||||
| #  undef AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF | ||||
|  | ||||
| # else // no partial specialization | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #include <boost/type.hpp> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|   typedef char (&yes_reference_wrapper_t)[1]; | ||||
|   typedef char (&no_reference_wrapper_t)[2]; | ||||
|        | ||||
|   no_reference_wrapper_t is_reference_wrapper_test(...); | ||||
|  | ||||
|   template<typename T> | ||||
|   yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper<T> >); | ||||
|  | ||||
|   template<bool wrapped> | ||||
|   struct reference_unwrapper | ||||
|   { | ||||
|       template <class T> | ||||
|       struct apply | ||||
|       { | ||||
|           typedef T type; | ||||
|       }; | ||||
|   }; | ||||
|  | ||||
|   template<> | ||||
|   struct reference_unwrapper<true> | ||||
|   { | ||||
|       template <class T> | ||||
|       struct apply | ||||
|       { | ||||
|           typedef typename T::type type; | ||||
|       }; | ||||
|   }; | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| class is_reference_wrapper | ||||
| { | ||||
|  public: | ||||
|     BOOST_STATIC_CONSTANT( | ||||
|         bool, value = ( | ||||
|              sizeof(detail::is_reference_wrapper_test(type<T>())) | ||||
|             == sizeof(detail::yes_reference_wrapper_t))); | ||||
|      | ||||
|     typedef ::boost::mpl::bool_<value> type; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| class unwrap_reference | ||||
|     : public detail::reference_unwrapper< | ||||
|         is_reference_wrapper<T>::value | ||||
|       >::template apply<T> | ||||
| {}; | ||||
|  | ||||
| # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION | ||||
|  | ||||
| template <class T> inline typename unwrap_reference<T>::type& | ||||
| unwrap_ref(T& t) | ||||
| { | ||||
|     return t; | ||||
| } | ||||
|  | ||||
| template<class T> inline T* get_pointer( reference_wrapper<T> const & r ) | ||||
| { | ||||
|     return r.get_pointer(); | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_REF_HPP_INCLUDED | ||||
							
								
								
									
										12
									
								
								include/boost/swap.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								include/boost/swap.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| // Copyright (C) 2007 Joseph Gauterin | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| #ifndef BOOST_SWAP_HPP | ||||
| #define BOOST_SWAP_HPP | ||||
|  | ||||
| #include "boost/utility/swap.hpp" | ||||
|  | ||||
| #endif | ||||
| @@ -9,16 +9,13 @@ | ||||
| #ifndef BOOST_UTILITY_HPP | ||||
| #define BOOST_UTILITY_HPP | ||||
|  | ||||
| // Use of this header is discouraged and it will be deprecated. | ||||
| // Please include one or more of the headers below instead. | ||||
|  | ||||
| #include <boost/utility/addressof.hpp> | ||||
| #include <boost/utility/base_from_member.hpp> | ||||
| #include <boost/utility/binary.hpp> | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/utility/identity_type.hpp> | ||||
|  | ||||
| #include <boost/core/addressof.hpp> | ||||
| #include <boost/core/enable_if.hpp> | ||||
| #include <boost/core/checked_delete.hpp> | ||||
| #include <boost/core/noncopyable.hpp> | ||||
| #include <boost/checked_delete.hpp> | ||||
| #include <boost/next_prior.hpp> | ||||
| #include <boost/noncopyable.hpp> | ||||
|  | ||||
| #endif  // BOOST_UTILITY_HPP | ||||
|   | ||||
							
								
								
									
										102
									
								
								include/boost/utility/addressof.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								include/boost/utility/addressof.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| // Copyright (C) 2002 Brad King (brad.king@kitware.com) | ||||
| //                    Douglas Gregor (gregod@cs.rpi.edu) | ||||
| // | ||||
| // Copyright (C) 2002, 2008 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) | ||||
|  | ||||
| // For more information, see http://www.boost.org | ||||
|  | ||||
| #ifndef BOOST_UTILITY_ADDRESSOF_HPP | ||||
| # define BOOST_UTILITY_ADDRESSOF_HPP | ||||
|  | ||||
| # include <boost/config.hpp> | ||||
| # include <boost/detail/workaround.hpp> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| template<class T> struct addr_impl_ref | ||||
| { | ||||
|     T & v_; | ||||
|  | ||||
|     inline addr_impl_ref( T & v ): v_( v ) {} | ||||
|     inline operator T& () const { return v_; } | ||||
|  | ||||
| private: | ||||
|     addr_impl_ref & operator=(const addr_impl_ref &); | ||||
| }; | ||||
|  | ||||
| template<class T> struct addressof_impl | ||||
| { | ||||
|     static inline T * f( T & v, long ) | ||||
|     { | ||||
|         return reinterpret_cast<T*>( | ||||
|             &const_cast<char&>(reinterpret_cast<const volatile char &>(v))); | ||||
|     } | ||||
|  | ||||
|     static inline T * f( T * v, int ) | ||||
|     { | ||||
|         return v; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| template<class T> T * addressof( T & v ) | ||||
| { | ||||
| #if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || defined( __SUNPRO_CC ) | ||||
|  | ||||
|     return boost::detail::addressof_impl<T>::f( v, 0 ); | ||||
|  | ||||
| #else | ||||
|  | ||||
|     return boost::detail::addressof_impl<T>::f( boost::detail::addr_impl_ref<T>( v ), 0 ); | ||||
|  | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #if defined( __SUNPRO_CC ) && BOOST_WORKAROUND( __SUNPRO_CC, BOOST_TESTED_AT( 0x590 ) ) | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| template<class T> struct addressof_addp | ||||
| { | ||||
|     typedef T * type; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| template< class T, std::size_t N > | ||||
| typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] ) | ||||
| { | ||||
|     return &t; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // Borland doesn't like casting an array reference to a char reference | ||||
| // but these overloads work around the problem. | ||||
| #if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) | ||||
| template<typename T,std::size_t N> | ||||
| T (*addressof(T (&t)[N]))[N] | ||||
| { | ||||
|    return reinterpret_cast<T(*)[N]>(&t); | ||||
| } | ||||
|  | ||||
| template<typename T,std::size_t N> | ||||
| const T (*addressof(const T (&t)[N]))[N] | ||||
| { | ||||
|    return reinterpret_cast<const T(*)[N]>(&t); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // BOOST_UTILITY_ADDRESSOF_HPP | ||||
| @@ -47,14 +47,13 @@ | ||||
| //         {} | ||||
| // This macro should only persist within this file. | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
| #define BOOST_PRIVATE_CTR_DEF( z, n, data )                   \ | ||||
|     template < BOOST_PP_ENUM_PARAMS(n, typename T) >          \ | ||||
|     base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) )  \ | ||||
|         : member( BOOST_PP_ENUM_PARAMS(n, x) )                \ | ||||
|         {}                                                    \ | ||||
| #define BOOST_PRIVATE_CTR_DEF( z, n, data )                            \ | ||||
|     template < BOOST_PP_ENUM_PARAMS(n, typename T) >                   \ | ||||
|     explicit base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) )  \ | ||||
|         : member( BOOST_PP_ENUM_PARAMS(n, x) )                         \ | ||||
|         {}                                                             \ | ||||
|     /**/ | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|  | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| @@ -143,26 +142,12 @@ protected: | ||||
|         : member() | ||||
|         {} | ||||
|  | ||||
|     template < typename T0 > explicit base_from_member( T0 x0 ) : member( x0 ) {} | ||||
|     BOOST_PP_REPEAT_FROM_TO( 2, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY), | ||||
|     BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY), | ||||
|      BOOST_PRIVATE_CTR_DEF, _ ) | ||||
| #endif | ||||
|  | ||||
| };  // boost::base_from_member | ||||
|  | ||||
| template < typename MemberType, int UniqueID > | ||||
| class base_from_member<MemberType&, UniqueID> | ||||
| { | ||||
| protected: | ||||
|     MemberType& member; | ||||
|  | ||||
|     explicit BOOST_CONSTEXPR base_from_member( MemberType& x ) | ||||
|         BOOST_NOEXCEPT | ||||
|         : member( x ) | ||||
|         {} | ||||
|  | ||||
| };  // boost::base_from_member | ||||
|  | ||||
| }  // namespace boost | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -68,7 +68,6 @@ | ||||
|   ( (0) BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings )  \ | ||||
|   )  | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
| #define BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings )  \ | ||||
|   BOOST_PP_SEQ_TRANSFORM                                                       \ | ||||
|   ( BOOST_DETAIL_TRIPLE_TO_OCTAL_OPERATION                                     \ | ||||
| @@ -705,5 +704,5 @@ | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111101 (1)(1)(1)(1)(1)(1)(0)(1),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111110 (1)(1)(1)(1)(1)(1)(1)(0),  | ||||
| #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111111 (1)(1)(1)(1)(1)(1)(1)(1),  | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -33,12 +33,8 @@ bool equal_pointees ( OptionalPointee const& x, OptionalPointee const& y ) | ||||
| } | ||||
|  | ||||
| template<class OptionalPointee> | ||||
| struct equal_pointees_t | ||||
| struct equal_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool> | ||||
| { | ||||
|   typedef bool result_type; | ||||
|   typedef OptionalPointee first_argument_type; | ||||
|   typedef OptionalPointee second_argument_type; | ||||
|  | ||||
|   bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const | ||||
|     { return equal_pointees(x,y) ; } | ||||
| } ; | ||||
| @@ -60,12 +56,8 @@ bool less_pointees ( OptionalPointee const& x, OptionalPointee const& y ) | ||||
| } | ||||
|  | ||||
| template<class OptionalPointee> | ||||
| struct less_pointees_t | ||||
| struct less_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool> | ||||
| { | ||||
|   typedef bool result_type; | ||||
|   typedef OptionalPointee first_argument_type; | ||||
|   typedef OptionalPointee second_argument_type; | ||||
|  | ||||
|   bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const | ||||
|     { return less_pointees(x,y) ; } | ||||
| } ; | ||||
|   | ||||
							
								
								
									
										44
									
								
								include/boost/utility/declval.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								include/boost/utility/declval.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| //  declval.hpp  -------------------------------------------------------------// | ||||
|  | ||||
| //  Copyright 2010 Vicente J. Botet Escriba | ||||
|  | ||||
| //  Distributed under the Boost Software License, Version 1.0. | ||||
| //  See http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DECLVAL_HPP | ||||
| #define BOOST_UTILITY_DECLVAL_HPP | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| //----------------------------------------------------------------------------// | ||||
|  | ||||
| #include <boost/type_traits/add_rvalue_reference.hpp> | ||||
|  | ||||
| //----------------------------------------------------------------------------// | ||||
| //                                                                            // | ||||
| //                           C++03 implementation of                          // | ||||
| //                   20.2.4 Function template declval [declval]               // | ||||
| //                          Written by Vicente J. Botet Escriba               // | ||||
| //                                                                            // | ||||
| // 1 The library provides the function template declval to simplify the | ||||
| // definition of expressions which occur as unevaluated operands. | ||||
| // 2 Remarks: If this function is used, the program is ill-formed. | ||||
| // 3 Remarks: The template parameter T of declval may be an incomplete type. | ||||
| // [ Example: | ||||
| // | ||||
| // template <class To, class From> | ||||
| // decltype(static_cast<To>(declval<From>())) convert(From&&); | ||||
| // | ||||
| // declares a function template convert which only participates in overloading | ||||
| // if the type From can be explicitly converted to type To. For another example | ||||
| // see class template common_type (20.9.7.6). -end example ] | ||||
| //----------------------------------------------------------------------------// | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
|     template <typename T> | ||||
|     typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand | ||||
|  | ||||
| }  // namespace boost | ||||
|  | ||||
| #endif  // BOOST_UTILITY_DECLVAL_HPP | ||||
| @@ -1,58 +0,0 @@ | ||||
| #ifndef BOOST_UTILITY_DETAIL_MINSTD_RAND_HPP_INCLUDED | ||||
| #define BOOST_UTILITY_DETAIL_MINSTD_RAND_HPP_INCLUDED | ||||
|  | ||||
| // Copyright 2017 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 | ||||
| // | ||||
| // An implementation of minstd_rand that does not require | ||||
| // the Random library | ||||
|  | ||||
| #include <boost/cstdint.hpp> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class minstd_rand | ||||
| { | ||||
| private: | ||||
|  | ||||
|     boost::uint_least32_t x_; | ||||
|  | ||||
|     enum { a = 48271, m = 2147483647 }; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     minstd_rand(): x_( 1 ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     explicit minstd_rand( boost::uint_least32_t x ): x_( x % m ) | ||||
|     { | ||||
|         if( x_ == 0 ) | ||||
|         { | ||||
|             x_ = 1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     boost::uint_least32_t operator()() | ||||
|     { | ||||
|         boost::uint_least64_t y = x_; | ||||
|  | ||||
|         y = ( a * y ) % m; | ||||
|  | ||||
|         x_ = static_cast<boost::uint_least32_t>( y ); | ||||
|  | ||||
|         return x_; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_UTILITY_DETAIL_MINSTD_RAND_HPP_INCLUDED | ||||
| @@ -22,19 +22,19 @@ | ||||
| # define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T) | ||||
| #endif | ||||
|  | ||||
| #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | ||||
| template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)> | ||||
|     : conditional< | ||||
|         is_pointer<F>::value || is_member_function_pointer<F>::value | ||||
|     : mpl::if_< | ||||
|           mpl::or_< is_pointer<F>, is_member_function_pointer<F> > | ||||
|         , boost::detail::tr1_result_of_impl< | ||||
|             typename remove_cv<F>::type, | ||||
|             typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS), | ||||
|             (boost::detail::result_of_has_result_type<F>::value)> | ||||
|             (boost::detail::has_result_type<F>::value)> | ||||
|         , boost::detail::tr1_result_of_impl< | ||||
|             F, | ||||
|             F(BOOST_RESULT_OF_ARGS), | ||||
|             (boost::detail::result_of_has_result_type<F>::value)> >::type { }; | ||||
|             (boost::detail::has_result_type<F>::value)> >::type { }; | ||||
| #endif | ||||
|  | ||||
| #ifdef BOOST_RESULT_OF_USE_DECLTYPE | ||||
| @@ -46,7 +46,7 @@ struct result_of<F(BOOST_RESULT_OF_ARGS)> | ||||
| #ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK | ||||
| template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of<F(BOOST_RESULT_OF_ARGS)> | ||||
|     : conditional<detail::result_of_has_result_type<F>::value || detail::result_of_has_result<F>::value, | ||||
|     : mpl::if_<mpl::or_<detail::has_result_type<F>, detail::has_result<F> >, | ||||
|                tr1_result_of<F(BOOST_RESULT_OF_ARGS)>, | ||||
|                detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> >::type { }; | ||||
| #endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK | ||||
| @@ -57,8 +57,8 @@ namespace detail { | ||||
|  | ||||
| template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))> | ||||
|     : conditional< | ||||
|           is_member_function_pointer<F>::value | ||||
|     : mpl::if_< | ||||
|           is_member_function_pointer<F> | ||||
|         , detail::tr1_result_of_impl< | ||||
|             typename remove_cv<F>::type, | ||||
|             typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false | ||||
| @@ -82,22 +82,25 @@ struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<R(BOOST_PP_ | ||||
| }; | ||||
|  | ||||
| template<typename F> | ||||
| struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION()) | ||||
|   : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F> | ||||
| {}; | ||||
| struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION()); | ||||
|  | ||||
| template<typename F> | ||||
| struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F *> | ||||
|   : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F> | ||||
| {}; | ||||
|  | ||||
| template<typename F> | ||||
| struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F &> | ||||
|   : BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F> | ||||
| {}; | ||||
|  | ||||
| template<typename F> | ||||
| struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION()) | ||||
|   : conditional< | ||||
|         is_class<typename remove_reference<F>::type>::value, | ||||
|   : mpl::eval_if< | ||||
|         is_class<typename remove_reference<F>::type>, | ||||
|         result_of_wrap_callable_class<F>, | ||||
|         type_identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<typename remove_reference<F>::type>::type> > | ||||
|     >::type | ||||
|         mpl::identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<F>::type> > | ||||
|     > | ||||
| {}; | ||||
|  | ||||
| template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)> | ||||
| @@ -108,7 +111,7 @@ struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) { | ||||
|             (boost::declval<wrapper_t>()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)), result_of_weird_type()) | ||||
|         )) | ||||
|     ); | ||||
|     typedef integral_constant<bool, value> type; | ||||
|     typedef mpl::bool_<value> type; | ||||
| }; | ||||
|  | ||||
| template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| @@ -151,7 +154,7 @@ struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), | ||||
|  | ||||
| #else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) | ||||
|  | ||||
| #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | ||||
| template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of<F(BOOST_RESULT_OF_ARGS)> | ||||
|     : tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { }; | ||||
| @@ -177,7 +180,7 @@ struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), F | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | ||||
| template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct tr1_result_of_impl<R (T0::*) | ||||
|                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), | ||||
|   | ||||
| @@ -1,190 +0,0 @@ | ||||
| // Boost result_of library | ||||
|  | ||||
| //  Copyright Douglas Gregor 2004. Use, modification and | ||||
| //  distribution is subject to the Boost Software License, Version | ||||
| //  1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  Copyright Daniel Walker, Eric Niebler, Michel Morin 2008-2012. | ||||
| //  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) | ||||
|  | ||||
| // For more information, see http://www.boost.org/libs/utility | ||||
|  | ||||
| #ifndef BOOST_RESULT_OF_HPP | ||||
| # error Boost result_of - do not include this file! | ||||
| #endif | ||||
|  | ||||
| template<typename F, typename... Args> | ||||
| struct tr1_result_of<F(Args...)> | ||||
|     : conditional< | ||||
|         is_pointer<F>::value || is_member_function_pointer<F>::value | ||||
|         , boost::detail::tr1_result_of_impl< | ||||
|             typename remove_cv<F>::type, | ||||
|             typename remove_cv<F>::type(Args...), | ||||
|             (boost::detail::result_of_has_result_type<F>::value)> | ||||
|         , boost::detail::tr1_result_of_impl< | ||||
|             F, | ||||
|             F(Args...), | ||||
|             (boost::detail::result_of_has_result_type<F>::value)> >::type { }; | ||||
|  | ||||
| #ifdef BOOST_RESULT_OF_USE_DECLTYPE | ||||
| template<typename F, typename... Args> | ||||
| struct result_of<F(Args...)> | ||||
|     : detail::cpp0x_result_of<F(Args...)> { }; | ||||
| #endif // BOOST_RESULT_OF_USE_DECLTYPE | ||||
|  | ||||
| #ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK | ||||
| template<typename F, typename... Args> | ||||
| struct result_of<F(Args...)> | ||||
|     : conditional<detail::result_of_has_result_type<F>::value || detail::result_of_has_result<F>::value, | ||||
|                tr1_result_of<F(Args...)>, | ||||
|                detail::cpp0x_result_of<F(Args...)> >::type { }; | ||||
| #endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK | ||||
|  | ||||
| #if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) | ||||
|  | ||||
| namespace detail { | ||||
|  | ||||
| template<typename F, typename... Args> | ||||
| struct cpp0x_result_of<F(Args...)> | ||||
|     : conditional< | ||||
|           is_member_function_pointer<F>::value | ||||
|         , detail::tr1_result_of_impl< | ||||
|             typename remove_cv<F>::type, | ||||
|             typename remove_cv<F>::type(Args...), false | ||||
|           > | ||||
|         , detail::cpp0x_result_of_impl< | ||||
|               F(Args...) | ||||
|           > | ||||
|       >::type | ||||
| {}; | ||||
|  | ||||
| #ifdef BOOST_NO_SFINAE_EXPR | ||||
|  | ||||
| template<typename F> | ||||
| struct result_of_callable_fun_2; | ||||
|  | ||||
| template<typename R, typename... Args> | ||||
| struct result_of_callable_fun_2<R(Args...)> { | ||||
|     R operator()(Args...) const; | ||||
|     typedef result_of_private_type const &(*pfn_t)(...); | ||||
|     operator pfn_t() const volatile; | ||||
| }; | ||||
|  | ||||
| template<typename F> | ||||
| struct result_of_callable_fun | ||||
|   : result_of_callable_fun_2<F> | ||||
| {}; | ||||
|  | ||||
| template<typename F> | ||||
| struct result_of_callable_fun<F *> | ||||
|   : result_of_callable_fun_2<F> | ||||
| {}; | ||||
|  | ||||
| template<typename F> | ||||
| struct result_of_select_call_wrapper_type | ||||
|   : conditional< | ||||
|         is_class<typename remove_reference<F>::type>::value, | ||||
|         result_of_wrap_callable_class<F>, | ||||
|         type_identity<result_of_callable_fun<typename remove_cv<typename remove_reference<F>::type>::type> > | ||||
|     >::type | ||||
| {}; | ||||
|  | ||||
| template<typename F, typename... Args> | ||||
| struct result_of_is_callable { | ||||
|     typedef typename result_of_select_call_wrapper_type<F>::type wrapper_t; | ||||
|     static const bool value = ( | ||||
|         sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_type( | ||||
|             (boost::declval<wrapper_t>()(boost::declval<Args>()...), result_of_weird_type()) | ||||
|         )) | ||||
|     ); | ||||
|     typedef integral_constant<bool, value> type; | ||||
| }; | ||||
|  | ||||
| template<typename F, typename... Args> | ||||
| struct cpp0x_result_of_impl<F(Args...), true> | ||||
|     : lazy_enable_if< | ||||
|           result_of_is_callable<F, Args...> | ||||
|         , cpp0x_result_of_impl<F(Args...), false> | ||||
|       > | ||||
| {}; | ||||
|  | ||||
| template<typename F, typename... Args> | ||||
| struct cpp0x_result_of_impl<F(Args...), false> | ||||
| { | ||||
|   typedef decltype( | ||||
|     boost::declval<F>()( | ||||
|       boost::declval<Args>()... | ||||
|     ) | ||||
|   ) type; | ||||
| }; | ||||
|  | ||||
| #else // BOOST_NO_SFINAE_EXPR | ||||
|  | ||||
| template<typename F, typename... Args> | ||||
| struct cpp0x_result_of_impl<F(Args...), | ||||
|                             typename result_of_always_void<decltype( | ||||
|                                 boost::declval<F>()( | ||||
|                                     boost::declval<Args>()... | ||||
|                                 ) | ||||
|                             )>::type> { | ||||
|   typedef decltype( | ||||
|     boost::declval<F>()( | ||||
|       boost::declval<Args>()... | ||||
|     ) | ||||
|   ) type; | ||||
| }; | ||||
|  | ||||
| #endif // BOOST_NO_SFINAE_EXPR | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| #else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) | ||||
|  | ||||
| template<typename F, typename... Args> | ||||
| struct result_of<F(Args...)> | ||||
|     : tr1_result_of<F(Args...)> { }; | ||||
|  | ||||
| #endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) | ||||
|  | ||||
| namespace detail { | ||||
|  | ||||
| template<typename R, typename FArgs, typename... Args> | ||||
| struct tr1_result_of_impl<R (*)(Args...), FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| template<typename R, typename FArgs, typename... Args> | ||||
| struct tr1_result_of_impl<R (&)(Args...), FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| template<typename R, typename FArgs, typename C, typename... Args> | ||||
| struct tr1_result_of_impl<R (C::*)(Args...), FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| template<typename R, typename FArgs, typename C, typename... Args> | ||||
| struct tr1_result_of_impl<R (C::*)(Args...) const, FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| template<typename R, typename FArgs, typename C, typename... Args> | ||||
| struct tr1_result_of_impl<R (C::*)(Args...) volatile, FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| template<typename R, typename FArgs, typename C, typename... Args> | ||||
| struct tr1_result_of_impl<R (C::*)(Args...) const volatile, FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| } | ||||
							
								
								
									
										43
									
								
								include/boost/utility/empty_deleter.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								include/boost/utility/empty_deleter.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /* | ||||
|  *          Copyright Andrey Semashev 2007 - 2013. | ||||
|  * Distributed under the Boost Software License, Version 1.0. | ||||
|  *    (See accompanying file LICENSE_1_0.txt or copy at | ||||
|  *          http://www.boost.org/LICENSE_1_0.txt) | ||||
|  */ | ||||
| /*! | ||||
|  * \file   empty_deleter.hpp | ||||
|  * \author Andrey Semashev | ||||
|  * \date   22.04.2007 | ||||
|  * | ||||
|  * This header contains an \c empty_deleter implementation. This is an empty | ||||
|  * function object that receives a pointer and does nothing with it. | ||||
|  * Such empty deletion strategy may be convenient, for example, when | ||||
|  * constructing <tt>shared_ptr</tt>s that point to some object that should not be | ||||
|  * deleted (i.e. a variable on the stack or some global singleton, like <tt>std::cout</tt>). | ||||
|  */ | ||||
|  | ||||
| #ifndef BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_ | ||||
| #define BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_ | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #ifdef BOOST_HAS_PRAGMA_ONCE | ||||
| #pragma once | ||||
| #endif | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| //! A function object that does nothing and can be used as an empty deleter for \c shared_ptr | ||||
| struct empty_deleter | ||||
| { | ||||
|     //! Function object result type | ||||
|     typedef void result_type; | ||||
|     /*! | ||||
|      * Does nothing | ||||
|      */ | ||||
|     void operator() (const volatile void*) const BOOST_NOEXCEPT {} | ||||
| }; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_ | ||||
							
								
								
									
										119
									
								
								include/boost/utility/enable_if.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								include/boost/utility/enable_if.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| // Boost enable_if library | ||||
|  | ||||
| // Copyright 2003 (c) The Trustees of Indiana University. | ||||
|  | ||||
| // Use, modification, and distribution is subject to the Boost Software | ||||
| // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| // http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) | ||||
| //             Jeremiah Willcock (jewillco at osl.iu.edu) | ||||
| //             Andrew Lumsdaine (lums at osl.iu.edu) | ||||
|  | ||||
|  | ||||
| #ifndef BOOST_UTILITY_ENABLE_IF_HPP | ||||
| #define BOOST_UTILITY_ENABLE_IF_HPP | ||||
|  | ||||
| #include "boost/config.hpp" | ||||
|  | ||||
| // Even the definition of enable_if causes problems on some compilers, | ||||
| // so it's macroed out for all compilers that do not support SFINAE | ||||
|  | ||||
| #ifndef BOOST_NO_SFINAE | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|   | ||||
|   template <bool B, class T = void> | ||||
|   struct enable_if_c { | ||||
|     typedef T type; | ||||
|   }; | ||||
|  | ||||
|   template <class T> | ||||
|   struct enable_if_c<false, T> {}; | ||||
|  | ||||
|   template <class Cond, class T = void>  | ||||
|   struct enable_if : public enable_if_c<Cond::value, T> {}; | ||||
|  | ||||
|   template <bool B, class T> | ||||
|   struct lazy_enable_if_c { | ||||
|     typedef typename T::type type; | ||||
|   }; | ||||
|  | ||||
|   template <class T> | ||||
|   struct lazy_enable_if_c<false, T> {}; | ||||
|  | ||||
|   template <class Cond, class T>  | ||||
|   struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {}; | ||||
|  | ||||
|  | ||||
|   template <bool B, class T = void> | ||||
|   struct disable_if_c { | ||||
|     typedef T type; | ||||
|   }; | ||||
|  | ||||
|   template <class T> | ||||
|   struct disable_if_c<true, T> {}; | ||||
|  | ||||
|   template <class Cond, class T = void>  | ||||
|   struct disable_if : public disable_if_c<Cond::value, T> {}; | ||||
|  | ||||
|   template <bool B, class T> | ||||
|   struct lazy_disable_if_c { | ||||
|     typedef typename T::type type; | ||||
|   }; | ||||
|  | ||||
|   template <class T> | ||||
|   struct lazy_disable_if_c<true, T> {}; | ||||
|  | ||||
|   template <class Cond, class T>  | ||||
|   struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {}; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #else | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
|   namespace detail { typedef void enable_if_default_T; } | ||||
|  | ||||
|   template <typename T> | ||||
|   struct enable_if_does_not_work_on_this_compiler; | ||||
|  | ||||
|   template <bool B, class T = detail::enable_if_default_T> | ||||
|   struct enable_if_c : enable_if_does_not_work_on_this_compiler<T> | ||||
|   { }; | ||||
|  | ||||
|   template <bool B, class T = detail::enable_if_default_T>  | ||||
|   struct disable_if_c : enable_if_does_not_work_on_this_compiler<T> | ||||
|   { }; | ||||
|  | ||||
|   template <bool B, class T = detail::enable_if_default_T>  | ||||
|   struct lazy_enable_if_c : enable_if_does_not_work_on_this_compiler<T> | ||||
|   { }; | ||||
|  | ||||
|   template <bool B, class T = detail::enable_if_default_T>  | ||||
|   struct lazy_disable_if_c : enable_if_does_not_work_on_this_compiler<T> | ||||
|   { }; | ||||
|  | ||||
|   template <class Cond, class T = detail::enable_if_default_T>  | ||||
|   struct enable_if : enable_if_does_not_work_on_this_compiler<T> | ||||
|   { }; | ||||
|  | ||||
|   template <class Cond, class T = detail::enable_if_default_T>  | ||||
|   struct disable_if : enable_if_does_not_work_on_this_compiler<T> | ||||
|   { }; | ||||
|  | ||||
|   template <class Cond, class T = detail::enable_if_default_T>  | ||||
|   struct lazy_enable_if : enable_if_does_not_work_on_this_compiler<T> | ||||
|   { }; | ||||
|  | ||||
|   template <class Cond, class T = detail::enable_if_default_T>  | ||||
|   struct lazy_disable_if : enable_if_does_not_work_on_this_compiler<T> | ||||
|   { }; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // BOOST_NO_SFINAE | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										128
									
								
								include/boost/utility/explicit_operator_bool.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								include/boost/utility/explicit_operator_bool.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| /* | ||||
|  *          Copyright Andrey Semashev 2007 - 2013. | ||||
|  * Distributed under the Boost Software License, Version 1.0. | ||||
|  *    (See accompanying file LICENSE_1_0.txt or copy at | ||||
|  *          http://www.boost.org/LICENSE_1_0.txt) | ||||
|  */ | ||||
| /*! | ||||
|  * \file   explicit_operator_bool.hpp | ||||
|  * \author Andrey Semashev | ||||
|  * \date   08.03.2009 | ||||
|  * | ||||
|  * This header defines a compatibility macro that implements an unspecified | ||||
|  * \c bool operator idiom, which is superseded with explicit conversion operators in | ||||
|  * C++11. | ||||
|  */ | ||||
|  | ||||
| #ifndef BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_ | ||||
| #define BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_ | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #ifdef BOOST_HAS_PRAGMA_ONCE | ||||
| #pragma once | ||||
| #endif | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) | ||||
|  | ||||
| /*! | ||||
|  * \brief The macro defines an explicit operator of conversion to \c bool | ||||
|  * | ||||
|  * The macro should be used inside the definition of a class that has to | ||||
|  * support the conversion. The class should also implement <tt>operator!</tt>, | ||||
|  * in terms of which the conversion operator will be implemented. | ||||
|  */ | ||||
| #define BOOST_EXPLICIT_OPERATOR_BOOL()\ | ||||
|     BOOST_FORCEINLINE explicit operator bool () const\ | ||||
|     {\ | ||||
|         return !this->operator! ();\ | ||||
|     } | ||||
|  | ||||
| /*! | ||||
|  * \brief The macro defines a constexpr explicit operator of conversion to \c bool | ||||
|  * | ||||
|  * The macro should be used inside the definition of a class that has to | ||||
|  * support the conversion. The class should also implement <tt>operator!</tt>, | ||||
|  * in terms of which the conversion operator will be implemented. | ||||
|  */ | ||||
| #define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\ | ||||
|     BOOST_FORCEINLINE BOOST_CONSTEXPR explicit operator bool () const\ | ||||
|     {\ | ||||
|         return !this->operator! ();\ | ||||
|     } | ||||
|  | ||||
| #else // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) | ||||
|  | ||||
| #if (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG) | ||||
| // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it | ||||
| #define BOOST_NO_UNSPECIFIED_BOOL | ||||
| #endif // (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG) | ||||
|  | ||||
| #if !defined(BOOST_NO_UNSPECIFIED_BOOL) | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| namespace detail { | ||||
|  | ||||
| #if !defined(_MSC_VER) && !defined(__IBMCPP__) | ||||
|  | ||||
|     struct unspecified_bool | ||||
|     { | ||||
|         // NOTE TO THE USER: If you see this in error messages then you tried | ||||
|         // to apply an unsupported operator on the object that supports | ||||
|         // explicit conversion to bool. | ||||
|         struct OPERATORS_NOT_ALLOWED; | ||||
|         static void true_value(OPERATORS_NOT_ALLOWED*) {} | ||||
|     }; | ||||
|     typedef void (*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*); | ||||
|  | ||||
| #else | ||||
|  | ||||
|     // MSVC and VACPP are too eager to convert pointer to function to void* even though they shouldn't | ||||
|     struct unspecified_bool | ||||
|     { | ||||
|         // NOTE TO THE USER: If you see this in error messages then you tried | ||||
|         // to apply an unsupported operator on the object that supports | ||||
|         // explicit conversion to bool. | ||||
|         struct OPERATORS_NOT_ALLOWED; | ||||
|         void true_value(OPERATORS_NOT_ALLOWED*) {} | ||||
|     }; | ||||
|     typedef void (unspecified_bool::*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #define BOOST_EXPLICIT_OPERATOR_BOOL()\ | ||||
|     BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const\ | ||||
|     {\ | ||||
|         return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\ | ||||
|     } | ||||
|  | ||||
| #define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\ | ||||
|     BOOST_FORCEINLINE BOOST_CONSTEXPR operator boost::detail::unspecified_bool_type () const\ | ||||
|     {\ | ||||
|         return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\ | ||||
|     } | ||||
|  | ||||
| #else // !defined(BOOST_NO_UNSPECIFIED_BOOL) | ||||
|  | ||||
| #define BOOST_EXPLICIT_OPERATOR_BOOL()\ | ||||
|     BOOST_FORCEINLINE operator bool () const\ | ||||
|     {\ | ||||
|         return !this->operator! ();\ | ||||
|     } | ||||
|  | ||||
| #define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\ | ||||
|     BOOST_FORCEINLINE BOOST_CONSTEXPR operator bool () const\ | ||||
|     {\ | ||||
|         return !this->operator! ();\ | ||||
|     } | ||||
|  | ||||
| #endif // !defined(BOOST_NO_UNSPECIFIED_BOOL) | ||||
|  | ||||
| #endif // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) | ||||
|  | ||||
| #endif // BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_ | ||||
| @@ -19,21 +19,15 @@ namespace boost { | ||||
|  | ||||
| class in_place_factory_base {} ; | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
| #define  BOOST_PP_ITERATION_LIMITS (0, BOOST_MAX_INPLACE_FACTORY_ARITY) | ||||
| #define  BOOST_PP_FILENAME_1 <boost/utility/in_place_factory.hpp> | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|  | ||||
| #include BOOST_PP_ITERATE() | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #include <boost/utility/detail/in_place_factory_suffix.hpp> | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
| #define BOOST_UTILITY_INPLACE_FACTORY_04APR2007_HPP | ||||
| #endif | ||||
|  | ||||
| #else | ||||
| #define N BOOST_PP_ITERATION() | ||||
|  | ||||
| @@ -54,13 +48,15 @@ public: | ||||
|   {} | ||||
|  | ||||
|   template<class T> | ||||
|   void* apply(void* address) const | ||||
|   void* apply(void* address | ||||
|       BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const | ||||
|   { | ||||
|     return new(address) T( BOOST_PP_ENUM_PARAMS(N, m_a) ); | ||||
|   } | ||||
|  | ||||
|   template<class T> | ||||
|   void* apply(void* address, std::size_t n) const | ||||
|   void* apply(void* address, std::size_t n | ||||
|       BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const | ||||
|   { | ||||
|     for(char* next = address = this->BOOST_NESTED_TEMPLATE apply<T>(address); | ||||
|         !! --n;) | ||||
|   | ||||
| @@ -10,37 +10,31 @@ | ||||
| #define BOOST_RESULT_OF_HPP | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/preprocessor/cat.hpp> | ||||
| #include <boost/preprocessor/iteration/iterate.hpp> | ||||
| #include <boost/preprocessor/repetition/enum_params.hpp> | ||||
| #include <boost/preprocessor/repetition/enum_trailing_params.hpp> | ||||
| #include <boost/preprocessor/repetition/enum_binary_params.hpp> | ||||
| #include <boost/preprocessor/repetition/enum_shifted_params.hpp> | ||||
| #include <boost/preprocessor/facilities/intercept.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <boost/mpl/has_xxx.hpp> | ||||
| #include <boost/mpl/if.hpp> | ||||
| #include <boost/mpl/eval_if.hpp> | ||||
| #include <boost/mpl/bool.hpp> | ||||
| #include <boost/mpl/identity.hpp> | ||||
| #include <boost/mpl/or.hpp> | ||||
| #include <boost/type_traits/is_class.hpp> | ||||
| #include <boost/type_traits/is_pointer.hpp> | ||||
| #include <boost/type_traits/is_member_function_pointer.hpp> | ||||
| #include <boost/type_traits/remove_cv.hpp> | ||||
| #include <boost/type_traits/remove_reference.hpp> | ||||
| #include <boost/type_traits/declval.hpp> | ||||
| #include <boost/type_traits/conditional.hpp> | ||||
| #include <boost/type_traits/type_identity.hpp> | ||||
| #include <boost/type_traits/integral_constant.hpp> | ||||
| #include <boost/core/enable_if.hpp> | ||||
| #include <boost/utility/declval.hpp> | ||||
| #include <boost/utility/enable_if.hpp> | ||||
|  | ||||
| #ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES | ||||
| #  undef BOOST_RESULT_OF_NO_VARIADIC_TEMPLATES | ||||
| #  define BOOST_RESULT_OF_NO_VARIADIC_TEMPLATES | ||||
| #endif | ||||
| #ifdef BOOST_RESULT_OF_NO_VARIADIC_TEMPLATES | ||||
| #  include <boost/preprocessor/cat.hpp> | ||||
| #  include <boost/preprocessor/iteration/iterate.hpp> | ||||
| #  include <boost/preprocessor/repetition/enum_params.hpp> | ||||
| #  include <boost/preprocessor/repetition/enum_trailing_params.hpp> | ||||
| #  include <boost/preprocessor/repetition/enum_binary_params.hpp> | ||||
| #  include <boost/preprocessor/repetition/enum_shifted_params.hpp> | ||||
| #  include <boost/preprocessor/facilities/intercept.hpp> | ||||
| #endif | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
| #ifndef BOOST_RESULT_OF_NUM_ARGS | ||||
| #  define BOOST_RESULT_OF_NUM_ARGS 16 | ||||
| #endif | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|  | ||||
| // Use the decltype-based version of result_of by default if the compiler | ||||
| // supports N3276 <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf>. | ||||
| @@ -53,7 +47,10 @@ | ||||
|   BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time. | ||||
| #endif | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
| #if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) | ||||
| #  error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined. | ||||
| #endif | ||||
|  | ||||
| #ifndef BOOST_RESULT_OF_USE_TR1 | ||||
| #  ifndef BOOST_RESULT_OF_USE_DECLTYPE | ||||
| #    ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK | ||||
| @@ -65,51 +62,18 @@ | ||||
| #    endif | ||||
| #  endif | ||||
| #endif | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| template<typename F> struct result_of; | ||||
| template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of | ||||
|  | ||||
| #if !defined(BOOST_NO_SFINAE) | ||||
| #if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) | ||||
| namespace detail { | ||||
|  | ||||
| typedef char result_of_yes_type;      // sizeof(result_of_yes_type) == 1 | ||||
| typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type)  == 2 | ||||
| BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) | ||||
|  | ||||
| template<class T> struct result_of_has_type {}; | ||||
|  | ||||
| template<class T> struct result_of_has_result_type_impl | ||||
| { | ||||
|     template<class U> static result_of_yes_type f( result_of_has_type<typename U::result_type>* ); | ||||
|     template<class U> static result_of_no_type f( ... ); | ||||
|  | ||||
|     typedef boost::integral_constant<bool, sizeof(f<T>(0)) == sizeof(result_of_yes_type)> type; | ||||
| }; | ||||
|  | ||||
| template<class T> struct result_of_has_result_type: result_of_has_result_type_impl<T>::type | ||||
| { | ||||
| }; | ||||
|  | ||||
| // Work around a nvcc bug by only defining has_result when it's needed. | ||||
| #ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK | ||||
|  | ||||
| template<template<class> class C> struct result_of_has_template {}; | ||||
|  | ||||
| template<class T> struct result_of_has_result_impl | ||||
| { | ||||
|     template<class U> static result_of_yes_type f( result_of_has_template<U::template result>* ); | ||||
|     template<class U> static result_of_no_type f( ... ); | ||||
|  | ||||
|     typedef boost::integral_constant<bool, sizeof(f<T>(0)) == sizeof(result_of_yes_type)> type; | ||||
| }; | ||||
|  | ||||
| template<class T> struct result_of_has_result: result_of_has_result_impl<T>::type | ||||
| { | ||||
| }; | ||||
|  | ||||
| #endif | ||||
| BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result) | ||||
|  | ||||
| template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl; | ||||
|  | ||||
| @@ -119,8 +83,8 @@ template<typename F> struct cpp0x_result_of; | ||||
|  | ||||
| // There doesn't seem to be any other way to turn this off such that the presence of | ||||
| // the user-defined operator,() below doesn't cause spurious warning all over the place, | ||||
| // so unconditionally and globally turn it off. (https://svn.boost.org/trac10/ticket/7663) | ||||
| #ifdef BOOST_MSVC | ||||
| // so unconditionally turn it off. | ||||
| #if BOOST_MSVC | ||||
| #  pragma warning(disable: 4913) // user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used | ||||
| #endif | ||||
|  | ||||
| @@ -130,23 +94,19 @@ struct result_of_weird_type { | ||||
|   friend result_of_private_type operator,(result_of_private_type, result_of_weird_type); | ||||
| }; | ||||
|  | ||||
| typedef char result_of_yes_type;      // sizeof(result_of_yes_type) == 1 | ||||
| typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type)  == 2 | ||||
|  | ||||
| template<typename T> | ||||
| result_of_no_type result_of_is_private_type(T const &); | ||||
| result_of_yes_type result_of_is_private_type(result_of_private_type); | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| #  pragma warning(push) | ||||
| #  pragma warning(disable: 4512) // assignment operator could not be generated. | ||||
| #endif | ||||
| template<typename C> | ||||
| struct result_of_callable_class : C { | ||||
|     result_of_callable_class(); | ||||
|     typedef result_of_private_type const &(*pfn_t)(...); | ||||
|     operator pfn_t() const volatile; | ||||
| }; | ||||
| #ifdef BOOST_MSVC | ||||
| #  pragma warning(pop) | ||||
| #endif | ||||
|  | ||||
| template<typename C> | ||||
| struct result_of_wrap_callable_class { | ||||
| @@ -217,10 +177,10 @@ struct tr1_result_of_impl<F, FArgs, true> | ||||
| }; | ||||
|  | ||||
| template<typename FArgs> | ||||
| struct is_function_with_no_args : false_type {}; | ||||
| struct is_function_with_no_args : mpl::false_ {}; | ||||
|  | ||||
| template<typename F> | ||||
| struct is_function_with_no_args<F(void)> : true_type {}; | ||||
| struct is_function_with_no_args<F(void)> : mpl::true_ {}; | ||||
|  | ||||
| template<typename F, typename FArgs> | ||||
| struct result_of_nested_result : F::template result<FArgs> | ||||
| @@ -228,24 +188,15 @@ struct result_of_nested_result : F::template result<FArgs> | ||||
|  | ||||
| template<typename F, typename FArgs> | ||||
| struct tr1_result_of_impl<F, FArgs, false> | ||||
|   : conditional<is_function_with_no_args<FArgs>::value, | ||||
|   : mpl::if_<is_function_with_no_args<FArgs>, | ||||
|              result_of_void_impl<F>, | ||||
|              result_of_nested_result<F, FArgs> >::type | ||||
| {}; | ||||
|  | ||||
| } // end namespace detail | ||||
|  | ||||
| #ifndef BOOST_RESULT_OF_NO_VARIADIC_TEMPLATES | ||||
| #  include <boost/utility/detail/result_of_variadic.hpp> | ||||
| #else | ||||
| #  define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>)) | ||||
| #  include BOOST_PP_ITERATE() | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| // inform dependency trackers, as they can't see through macro includes | ||||
| #include <boost/utility/detail/result_of_iterate.hpp> | ||||
| #endif | ||||
| #define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>)) | ||||
| #include BOOST_PP_ITERATE() | ||||
|  | ||||
| #else | ||||
| #  define BOOST_NO_RESULT_OF 1 | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| /* | ||||
|    Copyright (c) Marshall Clow 2012-2015. | ||||
|    Copyright (c) Glen Joseph Fernandes 2019 (glenjofe@gmail.com) | ||||
|    Copyright (c) Marshall Clow 2012-2012. | ||||
|  | ||||
|    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) | ||||
| @@ -18,7 +17,6 @@ | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <boost/io/ostream_put.hpp> | ||||
| #include <boost/utility/string_ref_fwd.hpp> | ||||
| #include <boost/throw_exception.hpp> | ||||
|  | ||||
| @@ -29,11 +27,6 @@ | ||||
| #include <string> | ||||
| #include <iosfwd> | ||||
|  | ||||
| #if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406) | ||||
| // GCC 4.6 cannot handle a defaulted function with noexcept specifier | ||||
| #define BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS | ||||
| #endif | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
|     namespace detail { | ||||
| @@ -64,55 +57,37 @@ namespace boost { | ||||
|         static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1); | ||||
|  | ||||
|         // construct/copy | ||||
|         BOOST_CONSTEXPR basic_string_ref () BOOST_NOEXCEPT | ||||
|         BOOST_CONSTEXPR basic_string_ref () | ||||
|             : ptr_(NULL), len_(0) {} | ||||
|  | ||||
|         // by defaulting these functions, basic_string_ref becomes | ||||
|         //  trivially copy/move constructible. | ||||
|         BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs) BOOST_NOEXCEPT | ||||
| #ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS | ||||
|             = default; | ||||
| #else | ||||
|         BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs) | ||||
|             : ptr_(rhs.ptr_), len_(rhs.len_) {} | ||||
| #endif | ||||
|  | ||||
|         basic_string_ref& operator=(const basic_string_ref &rhs) BOOST_NOEXCEPT | ||||
| #ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS | ||||
|             = default; | ||||
| #else | ||||
|             { | ||||
|         basic_string_ref& operator=(const basic_string_ref &rhs) { | ||||
|             ptr_ = rhs.ptr_; | ||||
|             len_ = rhs.len_; | ||||
|             return *this; | ||||
|             } | ||||
| #endif | ||||
|  | ||||
|         basic_string_ref(const charT* str) BOOST_NOEXCEPT | ||||
|         basic_string_ref(const charT* str) | ||||
|             : ptr_(str), len_(traits::length(str)) {} | ||||
|  | ||||
|         template<typename Allocator> | ||||
|         basic_string_ref(const std::basic_string<charT, traits, Allocator>& str) | ||||
|             : ptr_(str.data()), len_(str.length()) {} | ||||
|  | ||||
| // #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) | ||||
| //         // Constructing a string_ref from a temporary string is a bad idea | ||||
| //         template<typename Allocator> | ||||
| //         basic_string_ref(      std::basic_string<charT, traits, Allocator>&&) | ||||
| //             = delete; | ||||
| // #endif | ||||
|  | ||||
|         BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) BOOST_NOEXCEPT | ||||
|         BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) | ||||
|             : ptr_(str), len_(len) {} | ||||
|  | ||||
| #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS | ||||
|         template<typename Allocator> | ||||
|         explicit operator std::basic_string<charT, traits, Allocator>() const { | ||||
|             return std::basic_string<charT, traits, Allocator> ( begin(), end()); | ||||
|             return std::basic_string<charT, traits, Allocator> ( ptr_, len_ ); | ||||
|             } | ||||
| #endif | ||||
|  | ||||
|         std::basic_string<charT, traits> to_string () const { | ||||
|             return std::basic_string<charT, traits> ( begin(), end()); | ||||
|             return std::basic_string<charT, traits> ( ptr_, len_ ); | ||||
|             } | ||||
|  | ||||
|         // iterators | ||||
| @@ -128,13 +103,13 @@ namespace boost { | ||||
|         // capacity | ||||
|         BOOST_CONSTEXPR size_type size()     const { return len_; } | ||||
|         BOOST_CONSTEXPR size_type length()   const { return len_; } | ||||
|         BOOST_CONSTEXPR size_type max_size() const { return ~static_cast<size_type>(0) / (sizeof(value_type) * 2u); } | ||||
|         BOOST_CONSTEXPR size_type max_size() const { return len_; } | ||||
|         BOOST_CONSTEXPR bool empty()         const { return len_ == 0; } | ||||
|  | ||||
|         // element access | ||||
|         BOOST_CONSTEXPR const charT& operator[](size_type pos) const { return ptr_[pos]; } | ||||
|  | ||||
|         const charT& at(size_type pos) const { | ||||
|         const charT& at(size_t pos) const { | ||||
|             if ( pos >= len_ ) | ||||
|                 BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_ref::at" ) ); | ||||
|             return ptr_[pos]; | ||||
| @@ -161,14 +136,12 @@ namespace boost { | ||||
|  | ||||
|  | ||||
|         // basic_string_ref string operations | ||||
|         basic_string_ref substr() const { | ||||
|             return basic_string_ref(data(), size()); | ||||
|             } | ||||
|  | ||||
|         basic_string_ref substr(size_type pos, size_type n=npos) const { | ||||
|             if ( pos > size()) | ||||
|                 BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) ); | ||||
|             return basic_string_ref(data() + pos, (std::min)(size() - pos, n)); | ||||
|             if ( n == npos || pos + n > size()) | ||||
|                 n = size () - pos; | ||||
|             return basic_string_ref ( data() + pos, n ); | ||||
|             } | ||||
|  | ||||
|         int compare(basic_string_ref x) const { | ||||
| @@ -187,7 +160,6 @@ namespace boost { | ||||
|             } | ||||
|  | ||||
|         size_type find(basic_string_ref s) const { | ||||
|             if (s.empty()) return 0; | ||||
|             const_iterator iter = std::search ( this->cbegin (), this->cend (), | ||||
|                                                 s.cbegin (), s.cend (), traits::eq ); | ||||
|             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); | ||||
| @@ -200,16 +172,15 @@ namespace boost { | ||||
|             } | ||||
|  | ||||
|         size_type rfind(basic_string_ref s) const { | ||||
|             if (s.empty()) return 0; | ||||
|             const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (), | ||||
|                                                 s.crbegin (), s.crend (), traits::eq ); | ||||
|             return iter == this->crend () ? npos : (std::distance(iter, this->crend()) - s.size()); | ||||
|             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); | ||||
|             } | ||||
|  | ||||
|         size_type rfind(charT c) const { | ||||
|             const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (), | ||||
|                                     detail::string_ref_traits_eq<charT, traits> ( c )); | ||||
|             return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter)); | ||||
|             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); | ||||
|             } | ||||
|  | ||||
|         size_type find_first_of(charT c) const { return  find (c); } | ||||
| @@ -224,7 +195,7 @@ namespace boost { | ||||
|         size_type find_last_of(basic_string_ref s) const { | ||||
|             const_reverse_iterator iter = std::find_first_of | ||||
|                 ( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq ); | ||||
|             return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter)); | ||||
|             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter); | ||||
|             } | ||||
|  | ||||
|         size_type find_first_not_of(basic_string_ref s) const { | ||||
| @@ -241,17 +212,21 @@ namespace boost { | ||||
|  | ||||
|         size_type find_last_not_of(basic_string_ref s) const { | ||||
|             const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s ); | ||||
|             return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter)); | ||||
|             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); | ||||
|             } | ||||
|  | ||||
|         size_type find_last_not_of(charT c) const { | ||||
|             for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter ) | ||||
|                 if ( !traits::eq ( c, *iter )) | ||||
|                     return this->size() - 1 - std::distance(this->crbegin(), iter); | ||||
|                     return reverse_distance ( this->crbegin (), iter ); | ||||
|             return npos; | ||||
|             } | ||||
|  | ||||
|     private: | ||||
|         template <typename r_iter> | ||||
|         size_type reverse_distance ( r_iter first, r_iter last ) const { | ||||
|             return len_ - 1 - std::distance ( first, last ); | ||||
|             } | ||||
|  | ||||
|         template <typename Iterator> | ||||
|         Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const { | ||||
| @@ -427,11 +402,52 @@ namespace boost { | ||||
|         return basic_string_ref<charT, traits>(x) >= y; | ||||
|         } | ||||
|  | ||||
|     namespace detail { | ||||
|  | ||||
|         template<class charT, class traits> | ||||
|         inline void insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) { | ||||
|             enum { chunk_size = 8 }; | ||||
|             charT fill_chars[chunk_size]; | ||||
|             std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill()); | ||||
|             for (; n >= chunk_size && os.good(); n -= chunk_size) | ||||
|                 os.write(fill_chars, static_cast< std::size_t >(chunk_size)); | ||||
|             if (n > 0 && os.good()) | ||||
|                 os.write(fill_chars, n); | ||||
|             } | ||||
|  | ||||
|         template<class charT, class traits> | ||||
|         void insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) { | ||||
|             const std::size_t size = str.size(); | ||||
|             const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size; | ||||
|             const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left; | ||||
|             if (!align_left) { | ||||
|                 detail::insert_fill_chars(os, alignment_size); | ||||
|                 if (os.good()) | ||||
|                     os.write(str.data(), size); | ||||
|                 } | ||||
|             else { | ||||
|                 os.write(str.data(), size); | ||||
|                 if (os.good()) | ||||
|                     detail::insert_fill_chars(os, alignment_size); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } // namespace detail | ||||
|  | ||||
|     // Inserter | ||||
|     template<class charT, class traits> | ||||
|     inline std::basic_ostream<charT, traits>& | ||||
|     operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) { | ||||
|         return boost::io::ostream_put(os, str.data(), str.size()); | ||||
|         if (os.good()) { | ||||
|             const std::size_t size = str.size(); | ||||
|             const std::size_t w = static_cast< std::size_t >(os.width()); | ||||
|             if (w <= size) | ||||
|                 os.write(str.data(), size); | ||||
|             else | ||||
|                 detail::insert_aligned(os, str); | ||||
|             os.width(0); | ||||
|             } | ||||
|         return os; | ||||
|         } | ||||
|  | ||||
| #if 0 | ||||
|   | ||||
| @@ -1,694 +0,0 @@ | ||||
| /* | ||||
|    Copyright (c) Marshall Clow 2012-2015. | ||||
|    Copyright (c) Beman Dawes 2015 | ||||
|    Copyright (c) Glen Joseph Fernandes 2019 (glenjofe@gmail.com) | ||||
|  | ||||
|    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) | ||||
|  | ||||
|     For more information, see http://www.boost.org | ||||
|  | ||||
|     Based on the StringRef implementation in LLVM (http://llvm.org) and | ||||
|     N3422 by Jeffrey Yasskin | ||||
|         http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html | ||||
|     Updated July 2015 to reflect the Library Fundamentals TS | ||||
|         http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html | ||||
| */ | ||||
|  | ||||
| #ifndef BOOST_STRING_VIEW_HPP | ||||
| #define BOOST_STRING_VIEW_HPP | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <boost/io/ostream_put.hpp> | ||||
| #include <boost/utility/string_view_fwd.hpp> | ||||
| #include <boost/throw_exception.hpp> | ||||
| #include <boost/assert.hpp> | ||||
|  | ||||
| #include <cstddef> | ||||
| #include <stdexcept> | ||||
| #include <algorithm> | ||||
| #include <iterator> | ||||
| #include <string> | ||||
| #include <cstring> | ||||
| #include <iosfwd> | ||||
|  | ||||
| #if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406) | ||||
| // GCC 4.6 cannot handle a defaulted function with noexcept specifier | ||||
| #define BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS | ||||
| #endif | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
|     namespace detail { | ||||
|     //  A helper functor because sometimes we don't have lambdas | ||||
|         template <typename charT, typename traits> | ||||
|         class string_view_traits_eq { | ||||
|         public: | ||||
|             string_view_traits_eq ( charT ch ) : ch_(ch) {} | ||||
|             bool operator()( charT val ) const { return traits::eq (ch_, val); } | ||||
|             charT ch_; | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits>  // traits defaulted in string_view_fwd.hpp | ||||
|     class basic_string_view { | ||||
|     public: | ||||
|       // types | ||||
|       typedef traits                                traits_type; | ||||
|       typedef charT                                 value_type; | ||||
|       typedef charT*                                pointer; | ||||
|       typedef const charT*                          const_pointer; | ||||
|       typedef charT&                                reference; | ||||
|       typedef const charT&                          const_reference; | ||||
|       typedef const_pointer                         const_iterator; // impl-defined | ||||
|       typedef const_iterator                        iterator; | ||||
|       typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | ||||
|       typedef const_reverse_iterator                reverse_iterator; | ||||
|       typedef std::size_t                           size_type; | ||||
|       typedef std::ptrdiff_t                        difference_type; | ||||
|       static BOOST_CONSTEXPR_OR_CONST size_type     npos = size_type(-1); | ||||
|  | ||||
|       // construct/copy | ||||
|       BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT | ||||
|         : ptr_(NULL), len_(0) {} | ||||
|  | ||||
|       // by defaulting these functions, basic_string_ref becomes | ||||
|       //  trivially copy/move constructible. | ||||
|       BOOST_CONSTEXPR basic_string_view(const basic_string_view &rhs) BOOST_NOEXCEPT | ||||
| #ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS | ||||
|         = default; | ||||
| #else | ||||
|         : ptr_(rhs.ptr_), len_(rhs.len_) {} | ||||
| #endif | ||||
|  | ||||
|       basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT | ||||
| #ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS | ||||
|             = default; | ||||
| #else | ||||
|         { | ||||
|         ptr_ = rhs.ptr_; | ||||
|         len_ = rhs.len_; | ||||
|         return *this; | ||||
|         } | ||||
| #endif | ||||
|  | ||||
|       template<typename Allocator> | ||||
|         basic_string_view(const std::basic_string<charT, traits, Allocator>& str) BOOST_NOEXCEPT | ||||
|           : ptr_(str.data()), len_(str.length()) {} | ||||
|  | ||||
| // #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) | ||||
| //       // Constructing a string_view from a temporary string is a bad idea | ||||
| //       template<typename Allocator> | ||||
| //         basic_string_view(      std::basic_string<charT, traits, Allocator>&&) | ||||
| //           = delete; | ||||
| // #endif | ||||
|  | ||||
|       BOOST_CONSTEXPR basic_string_view(const charT* str) | ||||
|         : ptr_(str), len_(traits::length(str)) {} | ||||
|  | ||||
|       BOOST_CONSTEXPR basic_string_view(const charT* str, size_type len) | ||||
|         : ptr_(str), len_(len) {} | ||||
|  | ||||
|         // iterators | ||||
|         BOOST_CONSTEXPR const_iterator   begin() const BOOST_NOEXCEPT { return ptr_; } | ||||
|         BOOST_CONSTEXPR const_iterator  cbegin() const BOOST_NOEXCEPT { return ptr_; } | ||||
|         BOOST_CONSTEXPR const_iterator     end() const BOOST_NOEXCEPT { return ptr_ + len_; } | ||||
|         BOOST_CONSTEXPR const_iterator    cend() const BOOST_NOEXCEPT { return ptr_ + len_; } | ||||
|                 const_reverse_iterator  rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } | ||||
|                 const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } | ||||
|                 const_reverse_iterator    rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } | ||||
|                 const_reverse_iterator   crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } | ||||
|  | ||||
|         // capacity | ||||
|         BOOST_CONSTEXPR size_type size()     const BOOST_NOEXCEPT { return len_; } | ||||
|         BOOST_CONSTEXPR size_type length()   const BOOST_NOEXCEPT { return len_; } | ||||
|         BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return ~static_cast<size_type>(0) / (sizeof(value_type) * 2u); } | ||||
|         BOOST_CONSTEXPR bool empty()         const BOOST_NOEXCEPT { return len_ == 0; } | ||||
|  | ||||
|         // element access | ||||
|         BOOST_CONSTEXPR const_reference operator[](size_type pos) const BOOST_NOEXCEPT { return ptr_[pos]; } | ||||
|  | ||||
|         BOOST_CONSTEXPR const_reference at(size_type pos) const { | ||||
|             return pos >= len_ ? BOOST_THROW_EXCEPTION(std::out_of_range("boost::string_view::at")), ptr_[0] : ptr_[pos]; | ||||
|             } | ||||
|  | ||||
|         BOOST_CONSTEXPR const_reference front() const                { return ptr_[0]; } | ||||
|         BOOST_CONSTEXPR const_reference back()  const                { return ptr_[len_-1]; } | ||||
|         BOOST_CONSTEXPR const_pointer data()    const BOOST_NOEXCEPT { return ptr_; } | ||||
|  | ||||
|         // modifiers | ||||
|         void clear() BOOST_NOEXCEPT { len_ = 0; }          // Boost extension | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n) { | ||||
|             BOOST_ASSERT(n <= size()); | ||||
|             // This check is deprecated and is left for backward compatibility. It will be removed in the future. | ||||
|             if ( n > len_ ) | ||||
|                 n = len_; | ||||
|             ptr_ += n; | ||||
|             len_ -= n; | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR void remove_suffix(size_type n) { | ||||
|             BOOST_ASSERT(n <= size()); | ||||
|             // This check is deprecated and is left for backward compatibility. It will be removed in the future. | ||||
|             if ( n > len_ ) | ||||
|                 n = len_; | ||||
|             len_ -= n; | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR void swap(basic_string_view& s) BOOST_NOEXCEPT { | ||||
|             std::swap(ptr_, s.ptr_); | ||||
|             std::swap(len_, s.len_); | ||||
|             } | ||||
|  | ||||
|         // basic_string_view string operations | ||||
| #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS | ||||
|         template<typename Allocator> | ||||
|         explicit operator std::basic_string<charT, traits, Allocator>() const { | ||||
|             return std::basic_string<charT, traits, Allocator>(begin(), end()); | ||||
|             } | ||||
| #endif | ||||
|  | ||||
| #ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS | ||||
|         template<typename Allocator = std::allocator<charT> > | ||||
|         std::basic_string<charT, traits, Allocator> to_string(const Allocator& a = Allocator()) const { | ||||
|             return std::basic_string<charT, traits, Allocator>(begin(), end(), a); | ||||
|             } | ||||
| #else | ||||
|         std::basic_string<charT, traits> to_string() const { | ||||
|             return std::basic_string<charT, traits>(begin(), end()); | ||||
|             } | ||||
|  | ||||
|         template<typename Allocator> | ||||
|         std::basic_string<charT, traits, Allocator> to_string(const Allocator& a) const { | ||||
|             return std::basic_string<charT, traits, Allocator>(begin(), end(), a); | ||||
|             } | ||||
| #endif | ||||
|  | ||||
|         size_type copy(charT* s, size_type n, size_type pos=0) const { | ||||
|             if (pos > size()) | ||||
|                 BOOST_THROW_EXCEPTION(std::out_of_range("string_view::copy" )); | ||||
|             size_type rlen = (std::min)(n, len_ - pos); | ||||
|             traits_type::copy(s, data() + pos, rlen); | ||||
|             return rlen; | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR basic_string_view substr() const { | ||||
|             return basic_string_view(data(), size()); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const { | ||||
|             if ( pos > size()) | ||||
|                 BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) ); | ||||
|             return basic_string_view(data() + pos, (std::min)(size() - pos, n)); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(basic_string_view x) const BOOST_NOEXCEPT { | ||||
|             const int cmp = traits::compare(ptr_, x.ptr_, (std::min)(len_, x.len_)); | ||||
|             return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view x) | ||||
|           const { | ||||
|             return substr(pos1, n1).compare(x); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, | ||||
|           basic_string_view x, size_type pos2, size_type n2) const { | ||||
|             return substr(pos1, n1).compare(x.substr(pos2, n2)); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(const charT* x) const { | ||||
|             return compare(basic_string_view(x)); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, const charT* x) const { | ||||
|             return substr(pos1, n1).compare(basic_string_view(x)); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, | ||||
|           const charT* x, size_type n2) const { | ||||
|             return substr(pos1, n1).compare(basic_string_view(x, n2)); | ||||
|             } | ||||
|  | ||||
|         //  Searches | ||||
|         BOOST_CONSTEXPR bool starts_with(charT c) const BOOST_NOEXCEPT {              // Boost extension | ||||
|             return !empty() && traits::eq(c, front()); | ||||
|             } | ||||
|  | ||||
|         BOOST_CONSTEXPR bool starts_with(basic_string_view x) const BOOST_NOEXCEPT {  // Boost extension | ||||
|             return len_ >= x.len_ && traits::compare(ptr_, x.ptr_, x.len_) == 0; | ||||
|             } | ||||
|  | ||||
|         BOOST_CONSTEXPR bool ends_with(charT c) const BOOST_NOEXCEPT {                // Boost extension | ||||
|             return !empty() && traits::eq(c, back()); | ||||
|             } | ||||
|  | ||||
|         BOOST_CONSTEXPR bool ends_with(basic_string_view x) const BOOST_NOEXCEPT {    // Boost extension | ||||
|             return len_ >= x.len_ && | ||||
|                traits::compare(ptr_ + len_ - x.len_, x.ptr_, x.len_) == 0; | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR bool contains(basic_string_view s) const BOOST_NOEXCEPT { | ||||
|             return find(s) != npos; | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR bool contains(charT c) const BOOST_NOEXCEPT { | ||||
|             return find(c) != npos; | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR bool contains(const charT* s) const BOOST_NOEXCEPT { | ||||
|             return find(s) != npos; | ||||
|             } | ||||
|  | ||||
|         //  find | ||||
|         BOOST_CXX14_CONSTEXPR size_type find(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT { | ||||
|             if (pos > size()) | ||||
|               return npos; | ||||
|             if (s.empty()) | ||||
|               return pos; | ||||
|             if (s.size() > size() - pos) | ||||
|                 return npos; | ||||
|             const charT* cur = ptr_ + pos; | ||||
|             const charT* last = cend() - s.size() + 1; | ||||
|             for (; cur != last ; ++cur) { | ||||
|                 cur = traits::find(cur, last - cur, s[0]); | ||||
|                 if (!cur) | ||||
|                     return npos; | ||||
|                 if (traits::compare(cur, s.cbegin(), s.size()) == 0) | ||||
|                     return cur - ptr_; | ||||
|             } | ||||
|             return npos; | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT { | ||||
|             if (pos > size()) | ||||
|               return npos; | ||||
|             const charT* ret_ptr = traits::find(ptr_ + pos, len_ - pos, c); | ||||
|             if (ret_ptr) | ||||
|               return ret_ptr - ptr_; | ||||
|             return npos; | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return find(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT | ||||
|             { return find(basic_string_view(s), pos); } | ||||
|  | ||||
|         //  rfind | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT { | ||||
|             if (len_ < s.len_) | ||||
|               return npos; | ||||
|             if (pos > len_ - s.len_) | ||||
|               pos = len_ - s.len_; | ||||
|             if (s.len_ == 0u)     // an empty string is always found | ||||
|               return pos; | ||||
|             for (const charT* cur = ptr_ + pos; ; --cur) { | ||||
|                 if (traits::compare(cur, s.ptr_, s.len_) == 0) | ||||
|                   return cur - ptr_; | ||||
|                 if (cur == ptr_) | ||||
|                   return npos; | ||||
|                 }; | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return rfind(basic_string_view(&c, 1), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return rfind(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return rfind(basic_string_view(s), pos); } | ||||
|  | ||||
|         //  find_first_of | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT { | ||||
|             if (pos >= len_ || s.len_ == 0) | ||||
|               return npos; | ||||
|             const_iterator iter = std::find_first_of | ||||
|                 (this->cbegin () + pos, this->cend (), s.cbegin (), s.cend (), traits::eq); | ||||
|             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT | ||||
|             { return find(c, pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return find_first_of(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT | ||||
|             { return find_first_of(basic_string_view(s), pos); } | ||||
|  | ||||
|         //  find_last_of | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT { | ||||
|             if (s.len_ == 0u) | ||||
|               return npos; | ||||
|             if (pos >= len_) | ||||
|               pos = 0; | ||||
|             else | ||||
|               pos = len_ - (pos+1); | ||||
|             const_reverse_iterator iter = std::find_first_of | ||||
|                 ( this->crbegin () + pos, this->crend (), s.cbegin (), s.cend (), traits::eq ); | ||||
|             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter); | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return find_last_of(basic_string_view(&c, 1), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return find_last_of(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return find_last_of(basic_string_view(s), pos); } | ||||
|  | ||||
|         //  find_first_not_of | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT { | ||||
|             if (pos >= len_) | ||||
|               return npos; | ||||
|             if (s.len_ == 0) | ||||
|               return pos; | ||||
|             const_iterator iter = find_not_of ( this->cbegin () + pos, this->cend (), s ); | ||||
|             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT | ||||
|             { return find_first_not_of(basic_string_view(&c, 1), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return find_first_not_of(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT | ||||
|             { return find_first_not_of(basic_string_view(s), pos); } | ||||
|  | ||||
|         //  find_last_not_of | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT { | ||||
|             if (pos >= len_) | ||||
|               pos = len_ - 1; | ||||
|             if (s.len_ == 0u) | ||||
|               return pos; | ||||
|             pos = len_ - (pos+1); | ||||
|             const_reverse_iterator iter = find_not_of ( this->crbegin () + pos, this->crend (), s ); | ||||
|             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return find_last_not_of(basic_string_view(&c, 1), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return find_last_not_of(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return find_last_not_of(basic_string_view(s), pos); } | ||||
|  | ||||
|     private: | ||||
|         template <typename r_iter> | ||||
|         size_type reverse_distance(r_iter first, r_iter last) const BOOST_NOEXCEPT { | ||||
|         // Portability note here: std::distance is not NOEXCEPT, but calling it with a string_view::reverse_iterator will not throw. | ||||
|             return len_ - 1 - std::distance ( first, last ); | ||||
|             } | ||||
|  | ||||
|         template <typename Iterator> | ||||
|         Iterator find_not_of(Iterator first, Iterator last, basic_string_view s) const BOOST_NOEXCEPT { | ||||
|             for (; first != last ; ++first) | ||||
|                 if ( 0 == traits::find(s.ptr_, s.len_, *first)) | ||||
|                     return first; | ||||
|             return last; | ||||
|             } | ||||
|  | ||||
|         const charT *ptr_; | ||||
|         std::size_t len_; | ||||
|         }; | ||||
|  | ||||
|  | ||||
| //  Comparison operators | ||||
| //  Equality | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         if (x.size () != y.size ()) return false; | ||||
|         return x.compare(y) == 0; | ||||
|         } | ||||
|  | ||||
| //  Inequality | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         if ( x.size () != y.size ()) return true; | ||||
|         return x.compare(y) != 0; | ||||
|         } | ||||
|  | ||||
| //  Less than | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x, | ||||
|                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return x.compare(y) < 0; | ||||
|         } | ||||
|  | ||||
| //  Greater than | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x, | ||||
|                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return x.compare(y) > 0; | ||||
|         } | ||||
|  | ||||
| //  Less than or equal to | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return x.compare(y) <= 0; | ||||
|         } | ||||
|  | ||||
| //  Greater than or equal to | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return x.compare(y) >= 0; | ||||
|         } | ||||
|  | ||||
| // "sufficient additional overloads of comparison functions" | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x, | ||||
|                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x == basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) == y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x, | ||||
|                                               const charT * y) BOOST_NOEXCEPT { | ||||
|         return x == basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(const charT * x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) == y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x, | ||||
|                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x != basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) != y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x, | ||||
|                            const charT * y) BOOST_NOEXCEPT { | ||||
|         return x != basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(const charT * x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) != y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x, | ||||
|                     const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x < basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                 basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) < y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x, | ||||
|                           const charT * y) BOOST_NOEXCEPT { | ||||
|         return x < basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(const charT * x, | ||||
|                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) < y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x, | ||||
|                     const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x > basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                 basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) > y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x, | ||||
|                           const charT * y) BOOST_NOEXCEPT { | ||||
|         return x > basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(const charT * x, | ||||
|                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) > y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x, | ||||
|                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x <= basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) <= y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x, | ||||
|                            const charT * y) BOOST_NOEXCEPT { | ||||
|         return x <= basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(const charT * x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) <= y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x, | ||||
|                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x >= basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) >= y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x, | ||||
|                            const charT * y) BOOST_NOEXCEPT { | ||||
|         return x >= basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(const charT * x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) >= y; | ||||
|         } | ||||
|  | ||||
|     // Inserter | ||||
|     template<class charT, class traits> | ||||
|     inline std::basic_ostream<charT, traits>& | ||||
|     operator<<(std::basic_ostream<charT, traits>& os, | ||||
|       const basic_string_view<charT,traits>& str) { | ||||
|         return boost::io::ostream_put(os, str.data(), str.size()); | ||||
|         } | ||||
|  | ||||
| #if 0 | ||||
|     // numeric conversions | ||||
|     // | ||||
|     //  These are short-term implementations. | ||||
|     //  In a production environment, I would rather avoid the copying. | ||||
|     // | ||||
|     inline int stoi (string_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stoi ( std::string(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline long stol (string_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stol ( std::string(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline unsigned long stoul (string_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stoul ( std::string(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline long long stoll (string_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stoll ( std::string(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline unsigned long long stoull (string_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stoull ( std::string(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline float stof (string_view str, size_t* idx=0) { | ||||
|         return std::stof ( std::string(str), idx ); | ||||
|         } | ||||
|  | ||||
|     inline double stod (string_view str, size_t* idx=0) { | ||||
|         return std::stod ( std::string(str), idx ); | ||||
|         } | ||||
|  | ||||
|     inline long double stold (string_view str, size_t* idx=0)  { | ||||
|         return std::stold ( std::string(str), idx ); | ||||
|         } | ||||
|  | ||||
|     inline int  stoi (wstring_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stoi ( std::wstring(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline long stol (wstring_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stol ( std::wstring(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline unsigned long stoul (wstring_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stoul ( std::wstring(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline long long stoll (wstring_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stoll ( std::wstring(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline unsigned long long stoull (wstring_view str, size_t* idx=0, int base=10) { | ||||
|         return std::stoull ( std::wstring(str), idx, base ); | ||||
|         } | ||||
|  | ||||
|     inline float  stof (wstring_view str, size_t* idx=0) { | ||||
|         return std::stof ( std::wstring(str), idx ); | ||||
|         } | ||||
|  | ||||
|     inline double stod (wstring_view str, size_t* idx=0) { | ||||
|         return std::stod ( std::wstring(str), idx ); | ||||
|         } | ||||
|  | ||||
|     inline long double stold (wstring_view str, size_t* idx=0) { | ||||
|         return std::stold ( std::wstring(str), idx ); | ||||
|         } | ||||
| #endif | ||||
|  | ||||
|     // Forward declaration of Boost.ContainerHash function | ||||
|     template <class It> std::size_t hash_range(It, It); | ||||
|  | ||||
|     template <class charT, class traits> | ||||
|     std::size_t hash_value(basic_string_view<charT, traits> s) { | ||||
|         return boost::hash_range(s.begin(), s.end()); | ||||
|         } | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| namespace std { | ||||
|     // Hashing | ||||
|     template<> struct hash<boost::string_view>; | ||||
|     template<> struct hash<boost::u16string_view>; | ||||
|     template<> struct hash<boost::u32string_view>; | ||||
|     template<> struct hash<boost::wstring_view>; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
| @@ -1,39 +0,0 @@ | ||||
| /* | ||||
|    Copyright (c) Marshall Clow 2012-2012. | ||||
|  | ||||
|    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) | ||||
|  | ||||
|     For more information, see http://www.boost.org | ||||
|  | ||||
|     Based on the StringRef implementation in LLVM (http://llvm.org) and | ||||
|     N3422 by Jeffrey Yasskin | ||||
|         http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html | ||||
|     Updated July 2015 to reflect the Library Fundamentals TS | ||||
|         http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html | ||||
|  | ||||
| */ | ||||
|  | ||||
| #ifndef BOOST_STRING_VIEW_FWD_HPP | ||||
| #define BOOST_STRING_VIEW_FWD_HPP | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <string> | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
|     template<typename charT, typename traits = std::char_traits<charT> > class basic_string_view; | ||||
|     typedef basic_string_view<char,     std::char_traits<char> >        string_view; | ||||
|     typedef basic_string_view<wchar_t,  std::char_traits<wchar_t> >    wstring_view; | ||||
|  | ||||
| #ifndef BOOST_NO_CXX11_CHAR16_T | ||||
|     typedef basic_string_view<char16_t, std::char_traits<char16_t> > u16string_view; | ||||
| #endif | ||||
|  | ||||
| #ifndef BOOST_NO_CXX11_CHAR32_T | ||||
|     typedef basic_string_view<char32_t, std::char_traits<char32_t> > u32string_view; | ||||
| #endif | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										55
									
								
								include/boost/utility/swap.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								include/boost/utility/swap.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| // Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker | ||||
| // | ||||
| // 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) | ||||
| // For more information, see http://www.boost.org | ||||
|  | ||||
|  | ||||
| #ifndef BOOST_UTILITY_SWAP_HPP | ||||
| #define BOOST_UTILITY_SWAP_HPP | ||||
|  | ||||
| // Note: the implementation of this utility contains various workarounds: | ||||
| // - swap_impl is put outside the boost namespace, to avoid infinite | ||||
| // recursion (causing stack overflow) when swapping objects of a primitive | ||||
| // type. | ||||
| // - swap_impl has a using-directive, rather than a using-declaration, | ||||
| // because some compilers (including MSVC 7.1, Borland 5.9.3, and | ||||
| // Intel 8.1) don't do argument-dependent lookup when it has a | ||||
| // using-declaration instead. | ||||
| // - boost::swap has two template arguments, instead of one, to | ||||
| // avoid ambiguity when swapping objects of a Boost type that does | ||||
| // not have its own boost::swap overload. | ||||
|  | ||||
| #include <algorithm> //for std::swap | ||||
| #include <cstddef> //for std::size_t | ||||
|  | ||||
| namespace boost_swap_impl | ||||
| { | ||||
|   template<class T> | ||||
|   void swap_impl(T& left, T& right) | ||||
|   { | ||||
|     using namespace std;//use std::swap if argument dependent lookup fails | ||||
|     swap(left,right); | ||||
|   } | ||||
|  | ||||
|   template<class T, std::size_t N> | ||||
|   void swap_impl(T (& left)[N], T (& right)[N]) | ||||
|   { | ||||
|     for (std::size_t i = 0; i < N; ++i) | ||||
|     { | ||||
|       ::boost_swap_impl::swap_impl(left[i], right[i]); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|   template<class T1, class T2> | ||||
|   void swap(T1& left, T2& right) | ||||
|   { | ||||
|     ::boost_swap_impl::swap_impl(left, right); | ||||
|   } | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -19,20 +19,15 @@ namespace boost { | ||||
|  | ||||
| class typed_in_place_factory_base {} ; | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
| #define  BOOST_PP_ITERATION_LIMITS (0, BOOST_MAX_INPLACE_FACTORY_ARITY) | ||||
| #define  BOOST_PP_FILENAME_1 <boost/utility/typed_in_place_factory.hpp> | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|  | ||||
| #include BOOST_PP_ITERATE() | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #include <boost/utility/detail/in_place_factory_suffix.hpp> | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
| #define BOOST_UTILITY_TYPED_INPLACE_FACTORY_04APR2007_HPP | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|  | ||||
| #else  | ||||
| #define N BOOST_PP_ITERATION() | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| // (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal. | ||||
| // Copyright 2020 Peter Dimov | ||||
| // | ||||
| // Distributed under the Boost Software License, Version 1.0. (See | ||||
| // accompanying file LICENSE_1_0.txt or copy at | ||||
| @@ -22,13 +21,19 @@ | ||||
| // issues, by clearing the bytes of T, before constructing the T object it | ||||
| // contains. More details on these issues are at libs/utility/value_init.htm | ||||
|  | ||||
| #include <boost/aligned_storage.hpp> | ||||
| #include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION. | ||||
| #include <boost/core/swap.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <boost/static_assert.hpp> | ||||
| #include <boost/type_traits/cv_traits.hpp> | ||||
| #include <boost/type_traits/alignment_of.hpp> | ||||
| #include <boost/swap.hpp> | ||||
| #include <cstring> | ||||
| #include <cstddef> | ||||
| #include <new> | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| #pragma warning(push) | ||||
| #if _MSC_VER >= 1310 | ||||
| // It is safe to ignore the following warning from MSVC 7.1 or higher: | ||||
| // "warning C4351: new behavior: elements of array will be default initialized" | ||||
| #pragma warning(disable: 4351) | ||||
| @@ -36,8 +41,7 @@ | ||||
| // a const type: "warning C4512: assignment operator could not be generated". | ||||
| #pragma warning(disable: 4512) | ||||
| #endif | ||||
|  | ||||
| #ifndef BOOST_UTILITY_DOCS | ||||
| #endif | ||||
|  | ||||
| #ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION | ||||
|   // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED  | ||||
| @@ -56,100 +60,116 @@ | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| #endif // BOOST_UTILITY_DOCS | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| namespace detail { | ||||
|  | ||||
|   struct zero_init | ||||
|   { | ||||
|     zero_init() | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     zero_init( void * p, std::size_t n ) | ||||
|     { | ||||
|       std::memset( p, 0, n ); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| template<class T> | ||||
| class initialized | ||||
| #if BOOST_DETAIL_VALUE_INIT_WORKAROUND | ||||
|   : detail::zero_init | ||||
| #endif | ||||
| { | ||||
|   private: | ||||
|   private : | ||||
|     struct wrapper | ||||
|     { | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) | ||||
|       typename | ||||
| #endif  | ||||
|       remove_const<T>::type data; | ||||
|  | ||||
|     T data_; | ||||
|       wrapper() | ||||
|       : | ||||
|       data() | ||||
|       { | ||||
|       } | ||||
|  | ||||
|       wrapper(T const & arg) | ||||
|       : | ||||
|       data(arg) | ||||
|       { | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|     mutable | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) | ||||
|       typename | ||||
| #endif  | ||||
|       aligned_storage<sizeof(wrapper), alignment_of<wrapper>::value>::type x; | ||||
|  | ||||
|     wrapper * wrapper_address() const | ||||
|     { | ||||
|       return static_cast<wrapper *>( static_cast<void*>(&x)); | ||||
|     } | ||||
|  | ||||
|   public : | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     initialized(): | ||||
|     initialized() | ||||
|     { | ||||
| #if BOOST_DETAIL_VALUE_INIT_WORKAROUND | ||||
|       zero_init( &const_cast< char& >( reinterpret_cast<char const volatile&>( data_ ) ), sizeof( data_ ) ), | ||||
|       std::memset(&x, 0, sizeof(x)); | ||||
| #endif | ||||
|       data_() | ||||
|     { | ||||
|       new (wrapper_address()) wrapper(); | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     explicit initialized(T const & arg): data_( arg ) | ||||
|     initialized(initialized const & arg) | ||||
|     { | ||||
|       new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address()))); | ||||
|     } | ||||
|  | ||||
|     explicit initialized(T const & arg) | ||||
|     { | ||||
|       new (wrapper_address()) wrapper(arg); | ||||
|     } | ||||
|  | ||||
|     initialized & operator=(initialized const & arg) | ||||
|     { | ||||
|       // Assignment is only allowed when T is non-const. | ||||
|       BOOST_STATIC_ASSERT( ! is_const<T>::value ); | ||||
|       *wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address())); | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     ~initialized() | ||||
|     { | ||||
|       wrapper_address()->wrapper::~wrapper(); | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     T const & data() const | ||||
|     { | ||||
|       return data_; | ||||
|       return wrapper_address()->data; | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     T& data() | ||||
|     { | ||||
|       return data_; | ||||
|       return wrapper_address()->data; | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     void swap(initialized & arg) | ||||
|     { | ||||
|       ::boost::swap( this->data(), arg.data() ); | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     operator T const &() const | ||||
|     { | ||||
|       return data_; | ||||
|       return wrapper_address()->data; | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     operator T&() | ||||
|     { | ||||
|       return data_; | ||||
|       return wrapper_address()->data; | ||||
|     } | ||||
|  | ||||
| } ; | ||||
|  | ||||
| template<class T> | ||||
| BOOST_GPU_ENABLED | ||||
| T const& get ( initialized<T> const& x ) | ||||
| { | ||||
|   return x.data() ; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| BOOST_GPU_ENABLED | ||||
| T& get ( initialized<T>& x ) | ||||
| { | ||||
|   return x.data() ; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| BOOST_GPU_ENABLED | ||||
| void swap ( initialized<T> & lhs, initialized<T> & rhs ) | ||||
| { | ||||
|   lhs.swap(rhs) ; | ||||
| @@ -165,37 +185,31 @@ class value_initialized | ||||
|  | ||||
|   public : | ||||
|      | ||||
|     BOOST_GPU_ENABLED | ||||
|     value_initialized() | ||||
|     : | ||||
|     m_data() | ||||
|     { } | ||||
|      | ||||
|     BOOST_GPU_ENABLED | ||||
|     T const & data() const | ||||
|     { | ||||
|       return m_data.data(); | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     T& data() | ||||
|     { | ||||
|       return m_data.data(); | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     void swap(value_initialized & arg) | ||||
|     { | ||||
|       m_data.swap(arg.m_data); | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     operator T const &() const | ||||
|     { | ||||
|       return m_data; | ||||
|     } | ||||
|  | ||||
|     BOOST_GPU_ENABLED | ||||
|     operator T&() | ||||
|     { | ||||
|       return m_data; | ||||
| @@ -204,21 +218,18 @@ class value_initialized | ||||
|  | ||||
|  | ||||
| template<class T> | ||||
| BOOST_GPU_ENABLED | ||||
| T const& get ( value_initialized<T> const& x ) | ||||
| { | ||||
|   return x.data() ; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| BOOST_GPU_ENABLED | ||||
| T& get ( value_initialized<T>& x ) | ||||
| { | ||||
|   return x.data() ; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| BOOST_GPU_ENABLED | ||||
| void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs ) | ||||
| { | ||||
|   lhs.swap(rhs) ; | ||||
| @@ -229,7 +240,7 @@ class initialized_value_t | ||||
| { | ||||
|   public : | ||||
|      | ||||
|     template <class T> BOOST_GPU_ENABLED operator T() const | ||||
|     template <class T> operator T() const | ||||
|     { | ||||
|       return initialized<T>().data(); | ||||
|     } | ||||
|   | ||||
							
								
								
									
										67
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								index.html
									
									
									
									
									
								
							| @@ -1,19 +1,52 @@ | ||||
| <html> | ||||
| <head> | ||||
|     <title>Boost.Utility</title> | ||||
|     <meta http-equiv="refresh" content="0; URL=./doc/html/index.html"> | ||||
| </head> | ||||
| <body> | ||||
| Automatic redirection failed, please go to | ||||
| <a href="./doc/html/index.html">./doc/html/index.html</a> | ||||
| <hr> | ||||
| <tt> | ||||
|     Boost.Utility<br> | ||||
|     <br> | ||||
|     Distributed under the Boost Software License, Version 1.0. | ||||
|     (See accompanying file LICENSE_1_0.txt or copy at | ||||
|     <a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>) <br> | ||||
|     <br> | ||||
| </tt> | ||||
| </body> | ||||
| 	<head> | ||||
| 		<meta http-equiv="Content-Language" content="en-us"> | ||||
| 		<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> | ||||
| 		<meta name="ProgId" content="FrontPage.Editor.Document"> | ||||
| 		<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | ||||
| 		<title>Boost Utility Library</title> | ||||
| 	</head> | ||||
| 	<body bgcolor="#FFFFFF"> | ||||
| 		<h1><IMG SRC="../../boost.png" WIDTH="276" HEIGHT="86" align="center">Boost  | ||||
| 			Utility Library</h1> | ||||
| 		<p>The Boost Utility Library isn't really a single library at all. It is just a  | ||||
| 			collection for components too small to be called libraries in their own right.</p> | ||||
| 		<p>But that doesn't mean there isn't useful stuff here. Take a look:</p> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<a href="utility.htm#addressof">addressof</a><br> | ||||
| 				<a href="assert.html">assert</a><br> | ||||
| 				<a href="base_from_member.html">base_from_member</a><br> | ||||
| 				<a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a><br> | ||||
| 				<a href="call_traits.htm">call_traits</a><br> | ||||
| 				<a href="checked_delete.html">checked_delete</a><br> | ||||
| 				<a href="compressed_pair.htm">compressed_pair</a><br> | ||||
| 				<a href="current_function.html">current_function</a><br> | ||||
| 				<a href="doc/html/declval.html">declval</a><br> | ||||
| 				<a href="enable_if.html">enable_if</a><br> | ||||
| 				<a href="in_place_factories.html">in_place_factory</a><br> | ||||
| 				<a href="iterator_adaptors.htm">iterator_adaptors</a><br> | ||||
| 				<a href="generator_iterator.htm">generator iterator adaptors</a><br> | ||||
| 				<a href="utility.htm#functions_next_prior">next/prior</a><br> | ||||
| 				<a href="utility.htm#Class_noncopyable">noncopyable</a><br> | ||||
| 				<a href="operators.htm">operators</a><br> | ||||
| 				<a href="utility.htm#result_of">result_of</a><br> | ||||
| 				<a href="swap.html">swap</a><br> | ||||
| 				<a href="throw_exception.html">throw_exception</a><br> | ||||
| 				<a href="utility.htm">utility</a><br> | ||||
|             <a href="doc/html/string_ref.html">string_ref</a><br> | ||||
|             <a href="value_init.htm">value_init</a> | ||||
|             <a href="doc/html/explicit_operator_bool.html">BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL</a><br> | ||||
|          </p> | ||||
| 		</blockquote> | ||||
| 		<hr> | ||||
| 		<p>© Copyright Beman Dawes, 2001</p> | ||||
|         <p>Distributed under the Boost Software License, Version 1.0. (See  | ||||
|         accompanying file <a href="../../LICENSE_1_0.txt"> | ||||
|         LICENSE_1_0.txt</a> or copy at | ||||
|         <a href="http://www.boost.org/LICENSE_1_0.txt"> | ||||
|         www.boost.org/LICENSE_1_0.txt</a>)</p> | ||||
| 		<p>Revised  | ||||
| 			<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p> | ||||
| 		</body> | ||||
| </html> | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // 2 May 2010 (Created) Niels Dekker
 | ||||
| 
 | ||||
| #include <boost/utility/value_init.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
| 
 | ||||
| #include <string> | ||||
| 
 | ||||
| @@ -1,19 +1,11 @@ | ||||
| <!-- Copyright David Abrahams 2004. 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) --> | ||||
| <html> | ||||
| <head> | ||||
|     <title>Boost.Iterator</title> | ||||
|     <meta http-equiv="refresh" content="0; URL=../iterator/doc/index.html"> | ||||
| <meta http-equiv="refresh" content="0; URL=../iterator/doc/index.html"> | ||||
| </head> | ||||
| <body> | ||||
| Automatic redirection failed, please go to | ||||
| <a href="../iterator/doc/index.html">../iterator/doc/index.html</a> | ||||
| <hr> | ||||
| <tt> | ||||
|     Boost.Iterator<br> | ||||
|     <br> | ||||
|     Distributed under the Boost Software License, Version 1.0. | ||||
|     (See accompanying file LICENSE_1_0.txt or copy at | ||||
|     <a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>) <br> | ||||
|     <br> | ||||
| </tt> | ||||
| This documentation moved to <a href="../iterator/doc/index.html">../iterator/doc/index.html</a>. | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user