1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-14 18:17:59 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

View File

View File

@@ -0,0 +1,64 @@
# Copyright 2018 Peter Dimov
# Copyright 2019 Glen Fernandes
# Distributed under the Boost Software License, Version 1.0.
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0
ADDRMD: 32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-10.0
ADDRMD: 32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-11.0
ADDRMD: 32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-12.0
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
ADDRMD: 32,64
CXXSTD: 14,17
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
ADDRMD: 32,64
CXXSTD: 14,17
install:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% https://github.com/boostorg/boost.git boost
- cd boost
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\functional\
- python tools/boostdep/depinst/depinst.py -I forward/test -I factory/test -I overloaded_function/test functional
- cmd /c bootstrap
- b2 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- cd libs\functional
- ..\..\b2 test toolset=%TOOLSET% %CXXSTD% %ADDRMD%
- ..\..\b2 forward/test toolset=%TOOLSET% %CXXSTD% %ADDRMD%
- ..\..\b2 factory/test toolset=%TOOLSET% %CXXSTD% %ADDRMD%
- ..\..\b2 overloaded_function/test toolset=%TOOLSET% %CXXSTD% %ADDRMD%

View File

@@ -0,0 +1,96 @@
* text=auto !eol svneol=native#text/plain
*.gitattributes text svneol=native#text/plain
# Scriptish formats
*.bat text svneol=native#text/plain
*.bsh text svneol=native#text/x-beanshell
*.cgi text svneol=native#text/plain
*.cmd text svneol=native#text/plain
*.js text svneol=native#text/javascript
*.php text svneol=native#text/x-php
*.pl text svneol=native#text/x-perl
*.pm text svneol=native#text/x-perl
*.py text svneol=native#text/x-python
*.sh eol=lf svneol=LF#text/x-sh
configure eol=lf svneol=LF#text/x-sh
# Image formats
*.bmp binary svneol=unset#image/bmp
*.gif binary svneol=unset#image/gif
*.ico binary svneol=unset#image/ico
*.jpeg binary svneol=unset#image/jpeg
*.jpg binary svneol=unset#image/jpeg
*.png binary svneol=unset#image/png
*.tif binary svneol=unset#image/tiff
*.tiff binary svneol=unset#image/tiff
*.svg text svneol=native#image/svg%2Bxml
# Data formats
*.pdf binary svneol=unset#application/pdf
*.avi binary svneol=unset#video/avi
*.doc binary svneol=unset#application/msword
*.dsp text svneol=crlf#text/plain
*.dsw text svneol=crlf#text/plain
*.eps binary svneol=unset#application/postscript
*.gz binary svneol=unset#application/gzip
*.mov binary svneol=unset#video/quicktime
*.mp3 binary svneol=unset#audio/mpeg
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
*.ps binary svneol=unset#application/postscript
*.psd binary svneol=unset#application/photoshop
*.rdf binary svneol=unset#text/rdf
*.rss text svneol=unset#text/xml
*.rtf binary svneol=unset#text/rtf
*.sln text svneol=native#text/plain
*.swf binary svneol=unset#application/x-shockwave-flash
*.tgz binary svneol=unset#application/gzip
*.vcproj text svneol=native#text/xml
*.vcxproj text svneol=native#text/xml
*.vsprops text svneol=native#text/xml
*.wav binary svneol=unset#audio/wav
*.xls binary svneol=unset#application/vnd.ms-excel
*.zip binary svneol=unset#application/zip
# Text formats
.htaccess text svneol=native#text/plain
*.bbk text svneol=native#text/xml
*.cmake text svneol=native#text/plain
*.css text svneol=native#text/css
*.dtd text svneol=native#text/xml
*.htm text svneol=native#text/html
*.html text svneol=native#text/html
*.ini text svneol=native#text/plain
*.log text svneol=native#text/plain
*.mak text svneol=native#text/plain
*.qbk text svneol=native#text/plain
*.rst text svneol=native#text/plain
*.sql text svneol=native#text/x-sql
*.txt text svneol=native#text/plain
*.xhtml text svneol=native#text/xhtml%2Bxml
*.xml text svneol=native#text/xml
*.xsd text svneol=native#text/xml
*.xsl text svneol=native#text/xml
*.xslt text svneol=native#text/xml
*.xul text svneol=native#text/xul
*.yml text svneol=native#text/plain
boost-no-inspect text svneol=native#text/plain
CHANGES text svneol=native#text/plain
COPYING text svneol=native#text/plain
INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamroot text svneol=native#text/plain
Jamfile.v2 text svneol=native#text/plain
Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain
README text svneol=native#text/plain
TODO text svneol=native#text/plain
# Code formats
*.c text svneol=native#text/plain
*.cpp text svneol=native#text/plain
*.h text svneol=native#text/plain
*.hpp text svneol=native#text/plain
*.ipp text svneol=native#text/plain
*.tpp text svneol=native#text/plain
*.jam text svneol=native#text/plain
*.java text svneol=native#text/plain

View File

@@ -0,0 +1,530 @@
name: GitHub Actions CI
on:
pull_request:
push:
branches:
- master
- develop
- githubactions*
- feature/**
- fix/**
- pr/**
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- name: "TOOLSET=gcc COMPILER=g++ CXXSTD=03,11 Job 0"
buildtype: "boost"
packages: ""
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:16.04"
cxx: "g++"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++"
cxxstd: "03,11"
- name: "TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x Job 1"
buildtype: "boost"
packages: "g++-4.4"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "g++"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-4.4"
cxxstd: "98,0x"
- name: "TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x Job 2"
buildtype: "boost"
packages: "g++-4.6"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:16.04"
cxx: "g++"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-4.6"
cxxstd: "03,0x"
- name: "TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11 Job 3"
buildtype: "boost"
packages: "g++-4.7"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "g++-4.7"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-4.7"
cxxstd: "03,11"
- name: "TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11 Job 4"
buildtype: "boost"
packages: "g++-4.8"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "g++-4.8"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-4.8"
cxxstd: "03,11"
- name: "TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11 Job 5"
buildtype: "boost"
packages: "g++-4.9"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:16.04"
cxx: "g++-4.9"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-4.9"
cxxstd: "03,11"
- name: "TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z Job 6"
buildtype: "boost"
packages: "g++-5"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:16.04"
cxx: "g++-5"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-5"
cxxstd: "03,11,14,1z"
- name: "TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z Job 7"
buildtype: "boost"
packages: "g++-6"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "g++-6"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-6"
cxxstd: "03,11,14,1z"
- name: "TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 Job 8"
buildtype: "boost"
packages: "g++-7"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:16.04"
cxx: "g++-7"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-7"
cxxstd: "03,11,14,17"
- name: "TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17 Job 9"
buildtype: "boost"
packages: "g++-8"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:16.04"
cxx: "g++-8"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-8"
cxxstd: "03,11,14,17,2a"
- name: "TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17 Job 10"
buildtype: "boost"
packages: "g++-9"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:16.04"
cxx: "g++-9"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "gcc"
compiler: "g++-9"
cxxstd: "03,11,14,17,2a"
- name: "TOOLSET=clang COMPILER=clang++ CXXSTD=03,11 Job 11"
buildtype: "boost"
packages: ""
packages_to_remove: ""
os: "ubuntu-18.04"
cxx: "clang++"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "clang"
compiler: "clang++"
cxxstd: "03,11"
- name: "TOOLSET=clang COMPILER=/usr/bin/clang++ CXXST Job 12"
buildtype: "boost"
packages: "clang-3.3"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "/usr/bin/clang++"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "clang"
compiler: "/usr/bin/clang++"
cxxstd: "03,11"
- name: "TOOLSET=clang COMPILER=/usr/bin/clang++ CXXST Job 13"
buildtype: "boost"
packages: "clang-3.4"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "/usr/bin/clang++"
sources: ""
llvm_os: ""
llvm_ver: ""
toolset: "clang"
compiler: "/usr/bin/clang++"
cxxstd: "03,11"
- name: "TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03, Job 14"
buildtype: "boost"
packages: "clang-3.5 libstdc++-4.9-dev"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "clang++-3.5"
sources: ""
llvm_os: "precise"
llvm_ver: "3.5"
toolset: "clang"
compiler: "clang++-3.5"
cxxstd: "03,11,14"
- name: "TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03, Job 15"
buildtype: "boost"
packages: "clang-3.6"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "clang++-3.6"
sources: ""
llvm_os: "precise"
llvm_ver: "3.6"
toolset: "clang"
compiler: "clang++-3.6"
cxxstd: "03,11,14"
- name: "TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03, Job 16"
buildtype: "boost"
packages: "clang-3.7"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "clang++-3.7"
sources: ""
llvm_os: "precise"
llvm_ver: "3.7"
toolset: "clang"
compiler: "clang++-3.7"
cxxstd: "03,11,14"
- name: "TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03, Job 17"
buildtype: "boost"
packages: "clang-3.8 libstdc++-4.9-dev"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "clang++-3.8"
sources: ""
llvm_os: "precise"
llvm_ver: "3.8"
toolset: "clang"
compiler: "clang++-3.8"
cxxstd: "03,11,14"
- name: "TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03, Job 18"
buildtype: "boost"
packages: "clang-3.9 libstdc++-4.9-dev"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "clang++-3.9"
sources: ""
llvm_os: "precise"
llvm_ver: "3.9"
toolset: "clang"
compiler: "clang++-3.9"
cxxstd: "03,11,14"
- name: "TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03, Job 19"
buildtype: "boost"
packages: "clang-4.0"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "clang++-4.0"
sources: ""
llvm_os: "trusty"
llvm_ver: "4.0"
toolset: "clang"
compiler: "clang++-4.0"
cxxstd: "03,11,14"
- name: "TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03, Job 20"
buildtype: "boost"
packages: "clang-5.0"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "clang++-5.0"
sources: ""
llvm_os: "trusty"
llvm_ver: "5.0"
toolset: "clang"
compiler: "clang++-5.0"
cxxstd: "03,11,14,1z"
- name: "TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03, Job 21"
buildtype: "boost"
packages: "clang-6.0"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:14.04"
cxx: "clang++-6.0"
sources: ""
llvm_os: "trusty"
llvm_ver: "6.0"
toolset: "clang"
compiler: "clang++-6.0"
cxxstd: "03,11,14,17,2a"
- name: "TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11 Job 22"
buildtype: "boost"
packages: "clang-7"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:16.04"
cxx: "clang++-7"
sources: ""
llvm_os: "xenial"
llvm_ver: "7"
toolset: "clang"
compiler: "clang++-7"
cxxstd: "03,11,14,17,2a"
- name: "TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11 Job 23"
buildtype: "boost"
packages: "clang-8"
packages_to_remove: ""
os: "ubuntu-20.04"
container: "ubuntu:16.04"
cxx: "clang++-8"
sources: ""
llvm_os: "xenial"
llvm_ver: "8"
toolset: "clang"
compiler: "clang++-8"
cxxstd: "03,11,14,17,2a"
- name: "TOOLSET=clang COMPILER=clang++-libc++ CXXSTD= Job 24"
buildtype: "boost"
packages: " libc++-9-dev libc++abi-9-dev"
packages_to_remove: "libc++-dev libc++abi-dev"
os: "ubuntu-18.04"
cxx: "clang++-libc++"
sources: ""
llvm_os: "xenial"
llvm_ver: "9"
toolset: "clang"
compiler: "clang++-libc++"
cxxstd: "03,11,14,1z"
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
steps:
- name: Check if running in container
if: matrix.container != ''
run: echo "GHA_CONTAINER=${{ matrix.container }}" >> $GITHUB_ENV
- name: If running in container, upgrade packages
if: matrix.container != ''
run: |
apt-get -o Acquire::Retries=3 update && DEBIAN_FRONTEND=noninteractive apt-get -y install tzdata && apt-get -o Acquire::Retries=3 install -y sudo software-properties-common wget curl apt-transport-https make apt-file sudo unzip libssl-dev build-essential autotools-dev autoconf automake g++ libc++-helpers python ruby cpio gcc-multilib g++-multilib pkgconf python3 ccache libpython-dev
sudo apt-add-repository ppa:git-core/ppa
sudo apt-get -o Acquire::Retries=3 update && apt-get -o Acquire::Retries=3 -y install git
python_version=$(python3 -c 'import sys; print("{0.major}.{0.minor}".format(sys.version_info))')
sudo wget https://bootstrap.pypa.io/pip/$python_version/get-pip.py
sudo python3 get-pip.py
sudo /usr/local/bin/pip install cmake
- uses: actions/checkout@v2
- name: linux
shell: bash
env:
CXX: ${{ matrix.cxx }}
SOURCES: ${{ matrix.sources }}
LLVM_OS: ${{ matrix.llvm_os }}
LLVM_VER: ${{ matrix.llvm_ver }}
PACKAGES: ${{ matrix.packages }}
PACKAGES_TO_REMOVE: ${{ matrix.packages_to_remove }}
JOB_BUILDTYPE: ${{ matrix.buildtype }}
TOOLSET: ${{ matrix.toolset }}
COMPILER: ${{ matrix.compiler }}
CXXSTD: ${{ matrix.cxxstd }}
TRAVIS_BRANCH: ${{ github.base_ref }}
TRAVIS_OS_NAME: "linux"
run: |
echo '==================================> SETUP'
echo '==================================> PACKAGES'
set -e
if [ -n "$PACKAGES_TO_REMOVE" ]; then sudo apt-get purge -y $PACKAGES_TO_REMOVE; fi
echo ">>>>> APT: REPO.."
for i in {1..3}; do sudo -E apt-add-repository -y "ppa:ubuntu-toolchain-r/test" && break || sleep 2; done
if test -n "${LLVM_OS}" ; then
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
if test -n "${LLVM_VER}" ; then
sudo -E apt-add-repository "deb http://apt.llvm.org/${LLVM_OS}/ llvm-toolchain-${LLVM_OS}-${LLVM_VER} main"
else
# Snapshot (i.e. trunk) build of clang
sudo -E apt-add-repository "deb http://apt.llvm.org/${LLVM_OS}/ llvm-toolchain-${LLVM_OS} main"
fi
fi
echo ">>>>> APT: UPDATE.."
sudo -E apt-get -o Acquire::Retries=3 update
if test -n "${SOURCES}" ; then
echo ">>>>> APT: INSTALL SOURCES.."
for SOURCE in $SOURCES; do
sudo -E apt-add-repository ppa:$SOURCE
done
fi
echo ">>>>> APT: INSTALL ${PACKAGES}.."
sudo -E DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::Retries=3 -y --no-install-suggests --no-install-recommends install ${PACKAGES}
echo '==================================> INSTALL AND COMPILE'
set -e
export TRAVIS_BUILD_DIR=$(pwd)
export TRAVIS_BRANCH=${TRAVIS_BRANCH:-$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')}
export VCS_COMMIT_ID=$GITHUB_SHA
export GIT_COMMIT=$GITHUB_SHA
export REPO_NAME=$(basename $GITHUB_REPOSITORY)
export USER=$(whoami)
export CC=${CC:-gcc}
export PATH=~/.local/bin:/usr/local/bin:$PATH
if [ "$JOB_BUILDTYPE" == "boost" ]; then
echo '==================================> INSTALL'
BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
cd ..
git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost
cd boost
git submodule update --init tools/build
git submodule update --init libs/config
git submodule update --init tools/boostdep
mkdir -p libs/functional
cp -r $TRAVIS_BUILD_DIR/* libs/functional
python tools/boostdep/depinst/depinst.py -I forward/test -I factory/test -I overloaded_function/test functional
./bootstrap.sh
./b2 headers
echo '==================================> SCRIPT'
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
cd libs/functional
../../b2 -j 3 test toolset=$TOOLSET cxxstd=$CXXSTD
../../b2 -j 3 forward/test toolset=$TOOLSET cxxstd=$CXXSTD
../../b2 -j 3 factory/test toolset=$TOOLSET cxxstd=$CXXSTD
../../b2 -j 3 overloaded_function/test toolset=$TOOLSET cxxstd=$CXXSTD
fi
osx:
strategy:
fail-fast: false
matrix:
include:
- name: "TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,1 Job 25"
buildtype: "boost"
packages: ""
os: "macos-10.15"
cxx: "clang++"
sources: ""
llvm_os: ""
llvm_ver: ""
xcode_version: 11.7
toolset: "clang"
compiler: "clang++"
cxxstd: "03,11,14,1z"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Set DEVELOPER_DIR
if: matrix.xcode_version != ''
run: echo "DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode_version }}.app/Contents/Developer" >> $GITHUB_ENV
- name: Test DEVELOPER_DIR
run: echo $DEVELOPER_DIR
- name: "osx"
shell: bash
env:
CXX: ${{ matrix.cxx }}
SOURCES: ${{ matrix.sources }}
LLVM_OS: ${{ matrix.llvm_os }}
LLVM_VER: ${{ matrix.llvm_ver }}
PACKAGES: ${{ matrix.packages }}
JOB_BUILDTYPE: ${{ matrix.buildtype }}
TOOLSET: ${{ matrix.toolset }}
COMPILER: ${{ matrix.compiler }}
CXXSTD: ${{ matrix.cxxstd }}
TRAVIS_BRANCH: ${{ github.base_ref }}
TRAVIS_OS_NAME: "osx"
run: |
echo '==================================> SETUP'
set -e
sudo mv /Library/Developer/CommandLineTools /Library/Developer/CommandLineTools.bck
echo '==================================> PACKAGES'
echo '==================================> INSTALL AND COMPILE'
set -e
export TRAVIS_BUILD_DIR=$(pwd)
export TRAVIS_BRANCH=${TRAVIS_BRANCH:-$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')}
export VCS_COMMIT_ID=$GITHUB_SHA
export GIT_COMMIT=$GITHUB_SHA
export REPO_NAME=$(basename $GITHUB_REPOSITORY)
export USER=$(whoami)
export CC=${CC:-gcc}
export PATH=~/.local/bin:/usr/local/bin:$PATH
if [ "$JOB_BUILDTYPE" == "boost" ]; then
echo '==================================> INSTALL'
BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
cd ..
git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost
cd boost
git submodule update --init tools/build
git submodule update --init libs/config
git submodule update --init tools/boostdep
mkdir -p libs/functional
cp -r $TRAVIS_BUILD_DIR/* libs/functional
python tools/boostdep/depinst/depinst.py -I forward/test -I factory/test -I overloaded_function/test functional
./bootstrap.sh
./b2 headers
echo '==================================> SCRIPT'
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
cd libs/functional
../../b2 -j 3 test toolset=$TOOLSET cxxstd=$CXXSTD
../../b2 -j 3 forward/test toolset=$TOOLSET cxxstd=$CXXSTD
../../b2 -j 3 factory/test toolset=$TOOLSET cxxstd=$CXXSTD
../../b2 -j 3 overloaded_function/test toolset=$TOOLSET cxxstd=$CXXSTD
fi

View File

@@ -0,0 +1,303 @@
# Copyright 2016 Daniel James
# Copyright 2018 Peter Dimov
# Copyright 2019 Glen Fernandes
# Distributed under the Boost Software License, Version 1.0.
language: cpp
sudo: false
dist: trusty
python: "2.7"
branches:
only:
- master
- develop
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
- os: linux
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.3
- os: linux
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.4
- os: linux
compiler: clang++-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.5
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- os: linux
compiler: clang++-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- os: linux
compiler: clang++-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- os: linux
compiler: clang++-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- os: linux
compiler: clang++-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
- os: linux
compiler: clang++-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-7
- os: linux
compiler: clang++-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-8
- os: linux
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
- cd ..
- git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost
- cd boost
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- mkdir -p libs/functional
- cp -r $TRAVIS_BUILD_DIR/* libs/functional
- python tools/boostdep/depinst/depinst.py -I forward/test -I factory/test -I overloaded_function/test functional
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- cd libs/functional
- ../../b2 -j 3 test toolset=$TOOLSET cxxstd=$CXXSTD
- ../../b2 -j 3 forward/test toolset=$TOOLSET cxxstd=$CXXSTD
- ../../b2 -j 3 factory/test toolset=$TOOLSET cxxstd=$CXXSTD
- ../../b2 -j 3 overloaded_function/test toolset=$TOOLSET cxxstd=$CXXSTD
notifications:
email:
on_success: always

View File

@@ -0,0 +1,33 @@
# Generated by `boostdep --cmake functional`
# Copyright 2020 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
project(boost_functional VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_functional INTERFACE)
add_library(Boost::functional ALIAS boost_functional)
target_include_directories(boost_functional INTERFACE include)
target_link_libraries(boost_functional
INTERFACE
Boost::config
Boost::core
Boost::function
Boost::function_types
Boost::mpl
Boost::preprocessor
Boost::type_traits
Boost::typeof
Boost::utility
)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()

View File

@@ -0,0 +1,161 @@
<!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>Boost Function Object Adapter Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2" summary="">
<tr>
<td bgcolor="#FFFFFF"><img src="../../boost.png" alt=
"boost.png (6897 bytes)" width="277" height="86"></td>
<td><a href="../../index.htm"><font face="Arial" color=
"#FFFFFF"><big>Home</big></font></a></td>
<td><a href="../libraries.htm"><font face="Arial" color=
"#FFFFFF"><big>Libraries</big></font></a></td>
<td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color=
"#FFFFFF"><big>People</big></font></a></td>
<td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color=
"#FFFFFF"><big>FAQ</big></font></a></td>
<td><a href="../../more/index.htm"><font face="Arial" color=
"#FFFFFF"><big>More</big></font></a></td>
</tr>
</table>
<h1>Binders</h1>
<p>The header <a href="../../boost/functional.hpp">functional.hpp</a>
provides enhanced versions of both the binder function object adapters from
the C++ Standard Library (&sect;20.3.6):</p>
<ul>
<li><tt>binder1st</tt></li>
<li><tt>binder2nd</tt></li>
</ul>
<p>As well as the corresponding helper functions</p>
<ul>
<li><tt>bind1st</tt></li>
<li><tt>bind2nd</tt></li>
</ul>
<p>The key benefit of these adapters over those in the Standard Library is
they avoid the problem of <a href="#refref">references to
references.</a></p>
<h3>Usage</h3>
<p>Usage is identical to the standard binders. For example,</p>
<blockquote>
<pre>
class Foo {
public:
void bar(std::ostream &amp;);
// ...
};
// ...
std::vector&lt;Foo&gt; c;
// ...
std::for_each(c.begin(), c.end(),
boost::bind2nd(boost::mem_fun_ref(&amp;Foo::bar), std::cout));
</pre>
</blockquote>
<h3 id="refref">References to References</h3>
<p>Consider the usage example above</p>
<blockquote>
<pre>
class Foo {
public:
void bar(<strong>std::ostream &amp;</strong>);
// ...
};
// ...
std::for_each(c.begin(), c.end(),
boost::bind2nd(boost::mem_fun_ref(&amp;Foo::bar), std::cout));
</pre>
</blockquote>
<p>If this had been written using <tt>std::bind2nd</tt> and
<tt>std::mem_fun_ref</tt>, it would be unlikely to compile.</p>
<p>The problem arises because <tt>bar</tt> takes a reference argument. The
Standard defines <tt>std::mem_fun_ref</tt> such that it creates a function
object whose <tt>second_argument_type</tt> will be
<tt>std::ostream&amp;</tt>.</p>
<p>The call to <tt>bind2nd</tt> creates a <tt>binder2nd</tt> which the
Standard defines as follows:</p>
<blockquote>
<pre>
template &lt;class Operation&gt;
class binder2nd
: public unary_function&lt;typename Operation::first_argument_type,
typename Operation::result_type&gt; {
...
public:
binder2nd(const Operation&amp; x,
<strong>const typename Operation::second_argument_type&amp; y</strong>);
...
</pre>
</blockquote>
<p>Since our operation's <tt>second_argument_type</tt> is
<tt>std::ostream&amp;</tt>, the type of <tt>y</tt> in the constructor would
be <tt>std::ostream&amp;&amp;</tt>. Since you cannot have a reference to a
reference, at this point we should get a compilation error because
references to references are illegal in C++ (but see <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#106">C++
Standard core language active issues list</a>).</p>
<p>The binders in this library avoid this problem by using the Boost
<tt><a href="../utility/call_traits.htm">call_traits</a></tt>
templates.</p>
<p>Our constructor is declared</p>
<blockquote>
<pre>
binder2nd(const Operation&amp; x,
<strong>typename call_traits&lt;
typename binary_traits&lt;Operation&gt;::second_argument_type
&gt;::param_type y</strong>)
</pre>
</blockquote>
<p>As a result, <tt>y</tt> has a type of <tt>std::ostream&amp;</tt>, and
our example compiles.</p>
<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 -->02
December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
<p><i>Copyright &copy; 2000 Cadenza New Zealand Ltd.</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>

View File

@@ -0,0 +1,14 @@
# Copyright (c) 2016 Rene Rivera
#
# 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)
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease
: ../factory/doc//standalone
../forward/doc//standalone
../overloaded_function/doc//doc ;
explicit boostrelease ;

View File

@@ -0,0 +1,20 @@
# (C) Copyright Tobias Schwinger
#
# Use modification and distribution are subject to the boost Software License,
# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
using quickbook ;
xml factory : factory.qbk ;
boostbook standalone : factory
:
<xsl:param>boost.root=../../../../..
<xsl:param>boost.libraries=../../../../libraries.htm
<xsl:param>chunk.section.depth=0
<xsl:param>chunk.first.sections=0
<xsl:param>generate.section.toc.level=2
<xsl:param>toc.max.depth=1
;

View File

@@ -0,0 +1,432 @@
[/
Copyright 2007,2008 Tobias Schwinger
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[library Boost.Functional/Factory
[quickbook 1.5]
[version 1.0]
[authors [Schwinger, Tobias], [Fernandes, Glen]]
[copyright 2007 2008 Tobias Schwinger]
[copyright 2019 Glen Joseph Fernandes]
[license Distributed under the Boost Software License, Version 1.0.]
[purpose Function object templates for object creation.]
[category higher-order]
[category generic]]
[def __boost__bind__
[@http://www.boost.org/libs/bind/bind.html `boost::bind`]]
[def __boost__forward_adapter__
[@http://www.boost.org/libs/functional/forward/doc/index.html
`boost::forward_adapter`]]
[def __boost_function__
[@http://www.boost.org/doc/html/function.html Boost.Function]]
[def __smart_pointer__
[@http://www.boost.org/libs/smart_ptr/index.html Smart Pointer]]
[def __smart_pointers__
[@http://www.boost.org/libs/smart_ptr/index.html Smart Pointers]]
[def __boost__shared_ptr__
[@http://www.boost.org/libs/smart_ptr/shared_ptr.htm `boost::shared_ptr`]]
[def __allocator__ [@https://www.boost.org/sgi/stl/Allocators.html Allocator]]
[def __std_allocators__
[@https://www.boost.org/sgi/stl/Allocators.html Allocators]]
[def __boost__factory__ `boost::factory`]
[def __boost__value_factory__ `boost::value_factory`]
[def __value_factory__ `value_factory`]
[section Brief Description]
The template __boost__factory__ lets you encapsulate a `new` expression as a
function object, __boost__value_factory__ encapsulates a constructor invocation
without `new`.
```
__boost__factory__<T*>()(arg1,arg2,arg3)
// same as new T(arg1,arg2,arg3)
__boost__value_factory__<T>()(arg1,arg2,arg3)
// same as T(arg1,arg2,arg3)
```
Before C++11 the arguments to the function objects have to be LValues. A
factory that also accepts RValues can be composed using the
__boost__forward_adapter__ or __boost__bind__. In C++11 or higher the
arguments can be LValues or RValues.
[endsect]
[section Background]
In traditional Object Oriented Programming a Factory is an object implementing
an interface of one or more methods that construct objects conforming to known
interfaces.
```
// assuming a_concrete_class and another_concrete_class are derived
// from an_abstract_class
struct a_factory {
virtual an_abstract_class* create() const = 0;
virtual ~a_factory() { }
};
struct a_concrete_factory
: a_factory {
an_abstract_class* create() const {
return new a_concrete_class();
}
};
struct another_concrete_factory
: a_factory {
an_abstract_class* create() const {
return new another_concrete_class();
}
};
// [...]
int main()
{
boost::ptr_map<std::string, a_factory> factories;
// [...]
factories.insert("a_name",
std::unique_ptr<a_factory>(new a_concrete_factory));
factories.insert("another_name",
std::unique_ptr<a_factory>(new another_concrete_factory));
// [...]
std::unique_ptr<an_abstract_class> x(factories.at(some_name).create());
// [...]
}
```
This approach has several drawbacks. The most obvious one is that there is lots
of boilerplate code. In other words there is too much code to express a rather
simple intention. We could use templates to get rid of some of it but the
approach remains inflexible:
* We may want a factory that takes some arguments that are forwarded to the
constructor,
* we will probably want to use smart pointers,
* we may want several member functions to create different kinds of objects,
* we might not necessarily need a polymorphic base class for the objects,
* as we will see, we do not need a factory base class at all,
* we might want to just call the constructor - without `new` to create an
object on the stack, and
* finally we might want to use customized memory management.
Experience has shown that using function objects and generic Boost components
for their composition, Design Patterns that describe callback mechanisms
(typically requiring a high percentage of boilerplate code with pure Object
Oriented methodology) become implementable with just few code lines and without
extra classes.
Factories are callback mechanisms for constructors, so we provide two class
templates, __boost__value_factory__ and __boost__factory__, that encapsulate
object construction via direct application of the constructor and the `new`
operator, respectively.
We let the function objects forward their arguments to the construction
expressions they encapsulate. Over this __boost__factory__ optionally allows
the use of smart pointers and __std_allocators__.
Compile-time polymorphism can be used where appropriate,
```
template<class T>
void do_something()
{
// [...]
T x = T(a, b);
// for conceptually similar objects x we neither need virtual
// functions nor a common base class in this context.
// [...]
}
```
Now, to allow inhomogeneous signatures for the constructors of the types passed
in for `T` we can use __value_factory__ and __boost__bind__ to normalize
between them.
```
template<class ValueFactory>
void do_something(ValueFactory make_obj = ValueFactory())
{
// [...]
typename ValueFactory::result_type x = make_obj(a, b);
// for conceptually similar objects x we neither need virtual
// functions nor a common base class in this context.
// [...]
}
int main()
{
// [...]
do_something(boost::value_factory<X>());
do_something(boost::bind(boost::value_factory<Y>(), _1, 5, _2));
// construct X(a, b) and Y(a, 5, b), respectively.
// [...]
}
```
Maybe we want our objects to outlive the function's scope, in this case we have
to use dynamic allocation;
```
template<class Factory>
whatever do_something(Factory new_obj = Factory())
{
typename Factory::result_type ptr = new_obj(a, b);
// again, no common base class or virtual functions needed,
// we could enforce a polymorphic base by writing e.g.
// boost::shared_ptr<base>
// instead of
// typename Factory::result_type
// above.
// Note that we are also free to have the type erasure happen
// somewhere else (e.g. in the constructor of this function's
// result type).
// [...]
}
// [... call do_something like above but with boost::factory instead
// of boost::value_factory]
```
Although we might have created polymorphic objects in the previous example, we
have used compile time polymorphism for the factory. If we want to erase the
type of the factory and thus allow polymorphism at run time, we can use
__boost_function__ to do so. The first example can be rewritten as follows.
```
typedef boost::function<an_abstract_class*()> a_factory;
// [...]
int main()
{
std::map<std::string, a_factory> factories;
// [...]
factories["a_name"] = boost::factory<a_concrete_class*>();
factories["another_name"] = boost::factory<another_concrete_class*>();
// [...]
}
```
Of course we can just as easy create factories that take arguments and/or
return __smart_pointers__.
[endsect]
[section:reference Reference]
[section value_factory]
[heading Description]
Function object template that invokes the constructor of the type `T`.
[heading Header]
```
#include <boost/functional/value_factory.hpp>
```
[heading Synopsis]
```
namespace boost {
template<class T>
class value_factory;
} // boost
```
[variablelist Notation
[[`T`][an arbitrary type with at least one public constructor]]
[[`a0`...`aN`][argument values to a constructor of `T`]]
[[`F`][the type `value_factory<F>`]]
[[`f`][an instance object of `F`]]]
[heading Expression Semantics]
[table
[[Expression][Semantics]]
[[`F()`][creates an object of type `F`.]]
[[`F(f)`][creates an object of type `F`.]]
[[`f(a0`...`aN)`][returns `T(a0`...`aN)`.]]
[[`F::result_type`][is the type `T`.]]]
[heading Limits]
Before C++11, the maximum number of arguments supported is 10. Since C++11 an
arbitrary number of arguments is supported.
[endsect]
[section factory]
[heading Description]
Function object template that dynamically constructs a pointee object for the
type of pointer given as template argument. Smart pointers may be used for the
template argument, given that `pointer_traits<Pointer>::element_type` yields
the pointee type.
If an __allocator__ is given, it is used for memory allocation and the
placement form of the `new` operator is used to construct the object. A
function object that calls the destructor and deallocates the memory with a
copy of the Allocator is used for the second constructor argument of `Pointer`
(thus it must be a __smart_pointer__ that provides a suitable constructor,
such as __boost__shared_ptr__).
If a third template argument is `factory_passes_alloc_to_smart_pointer`, the
allocator itself is used for the third constructor argument of `Pointer`
(__boost__shared_ptr__ then uses the allocator to manage the memory of its
separately allocated reference counter).
[heading Header]
```
#include <boost/functional/factory.hpp>
```
[heading Synopsis]
```
namespace boost {
enum factory_alloc_propagation {
factory_alloc_for_pointee_and_deleter,
factory_passes_alloc_to_smart_pointer
};
template<class Pointer,
class Allocator = void,
factory_alloc_propagation Policy = factory_alloc_for_pointee_and_deleter>
class factory;
} // boost
```
[variablelist Notation
[[`T`][an arbitrary type with at least one public constructor]]
[[`P`][pointer or smart pointer to `T`]]
[[`a0`...`aN`][argument values to a constructor of `T`]]
[[`F`][the type `factory<P>`]]
[[`f`][an instance object of `F`]]]
[heading Expression Semantics]
[table
[[Expression][Semantics]]
[[`F()`][creates an object of type `F`.]]
[[`F(f)`][creates an object of type `F`.]]
[[`f(a0`...`aN)`]
[dynamically creates an object of type `T` using `a0`...`aN` as arguments for
the constructor invocation.]]
[[`F::result_type`][is the type `P` with top-level cv-qualifiers removed.]]]
[heading Limits]
Before C++11, the maximum number of arguments supported is 10. Since C++11 an
arbitrary number of arguments is supported.
[endsect]
[endsect]
[section Changes]
[heading Boost 1.72.0]
Glen Fernandes rewrote the implementations of `factory` and `value_factory` to
provide the following features:
* Support r-value arguments when available
* Support arbitrary number of arguments via variadic templates when available
* Support allocators that are final
* Support allocators that use fancy pointers
* Support for disabled exceptions (`BOOST_NO_EXCEPTIONS`)
* Improved compilation times
The following features have been removed:
* Increasing limits for C++03 compilers through
`BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY`
* Using `boost::none_t` in place of `void` through
`BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T`
[heading Boost 1.58.0]
In order to remove the dependency on Boost.Optional, the default parameter for
allocators has been changed from `boost::none_t` to `void`. If you have code
that has stopped working because it uses `boost::none_t`, a quick fix is to
define `BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T`, which will restore support,
but this will be removed in a future release. It should be be relatively easy
to fix this properly.
[endsect]
[section Acknowledgements]
Tobias Schwinger for creating this library.
Eric Niebler requested a function to invoke a type's constructor (with the
arguments supplied as a Tuple) as a Fusion feature. These Factory utilities are
a factored-out generalization of this idea.
Dave Abrahams suggested Smart Pointer support for exception safety, providing
useful hints for the implementation.
Joel de Guzman's documentation style was copied from Fusion.
Peter Dimov for sharing his insights on language details and their evolution.
[endsect]
[section References]
# [@http://en.wikipedia.org/wiki/Design_Patterns Design Patterns],
Gamma et al. - Addison Wesley Publishing, 1995
# [@https://boost.org/sgi/stl/ Standard Template Library Programmer's Guide],
Hewlett-Packard Company, 1994
# [@http://www.boost.org/libs/bind/bind.html Boost.Bind],
Peter Dimov, 2001-2005
# [@http://www.boost.org/doc/html/function.html Boost.Function],
Douglas Gregor, 2001-2004
[endsect]

View File

@@ -0,0 +1,16 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<!-- Copyright (C) 2002 Douglas Gregor <doug.gregor -at- 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) -->
<title>Redirect to generated documentation</title>
<meta http-equiv="refresh" content="0; URL=http://www.boost.org/doc/libs/master/libs/functional/factory/doc/html/">
</head>
<body>
Automatic redirection failed, please go to
<a href="http://www.boost.org/doc/libs/master/libs/functional/factory/doc/html/">http://www.boost.org/doc/libs/master/libs/functional/factory/doc/html/</a>
</body>
</html>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatic redirection failed, click this
<a href="doc/html/index.html">link</a> &nbsp;<hr>
<p><EFBFBD> Copyright Tobias Schwinger, 2009</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>
</body>
</html>

View File

@@ -0,0 +1,20 @@
# Copyright 2007,2008 Tobias Schwinger
#
# Copyright 2019 Glen Joseph Fernandes
# (glenjofe@gmail.com)
#
# Distributed under the Boost Software License, Version 1.0.
# (http://www.boost.org/LICENSE_1_0.txt)
import testing ;
run value_factory.cpp ;
run value_factory_args.cpp ;
run value_factory_move.cpp ;
run factory.cpp ;
run factory_args.cpp ;
run factory_move.cpp ;
run factory_with_allocator.cpp ;
run factory_with_std_allocator.cpp ;
run factory_allocator_throws.cpp ;
run factory_default_allocator.cpp : : : <exception-handling>off ;

View File

@@ -0,0 +1,87 @@
/*
Copyright 2007 Tobias Schwinger
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/scoped_ptr.hpp>
class sum {
public:
explicit sum(int i0 = 0, int i1 = 0, int i2 = 0, int i3 = 0,
int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0,
int i8 = 0, int i9 = 0)
: value_(i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9) { }
int get() const {
return value_;
}
private:
int value_;
};
int main()
{
boost::factory<sum*> x;
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int h = 8;
int i = 9;
int j = 10;
{
boost::scoped_ptr<sum> s(x());
BOOST_TEST(s->get() == 0);
}
{
boost::scoped_ptr<sum> s(x(a));
BOOST_TEST(s->get() == 1);
}
{
boost::scoped_ptr<sum> s(x(a, b));
BOOST_TEST(s->get() == 3);
}
{
boost::scoped_ptr<sum> s(x(a, b, c));
BOOST_TEST(s->get() == 6);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d));
BOOST_TEST(s->get() == 10);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e));
BOOST_TEST(s->get() == 15);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f));
BOOST_TEST(s->get() == 21);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f, g));
BOOST_TEST(s->get() == 28);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f, g, h));
BOOST_TEST(s->get() == 36);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f, g, h, i));
BOOST_TEST(s->get() == 45);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f, g, h, i, j));
BOOST_TEST(s->get() == 55);
}
return boost::report_errors();
}

View File

@@ -0,0 +1,85 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
struct type {
explicit type(bool b) {
if (b) {
throw true;
}
}
};
template<class T>
class creator {
public:
static int count;
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
++count;
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
--count;
::operator delete(ptr);
}
};
template<class T>
int creator<T>::count = 0;
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
int main()
{
bool b = true;
try {
boost::shared_ptr<type> s(boost::factory<boost::shared_ptr<type>,
creator<void>,
boost::factory_alloc_for_pointee_and_deleter>()(b));
} catch (...) {
BOOST_TEST(creator<type>::count == 0);
}
try {
boost::shared_ptr<type> s(boost::factory<boost::shared_ptr<type>,
creator<void>,
boost::factory_passes_alloc_to_smart_pointer>()(b));
} catch (...) {
BOOST_TEST(creator<type>::count == 0);
}
return boost::report_errors();
}

View File

@@ -0,0 +1,42 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/scoped_ptr.hpp>
class sum {
public:
explicit sum(int a = 0, int b = 0, int c = 0, int d = 0,
int e = 0, int f = 0, int g = 0, int h = 0,
int i = 0, int j = 0, int k = 0, int l = 0)
: value_(a + b + c + d + e + f + g + h + i + j + k + l) { }
int get() const {
return value_;
}
private:
int value_;
};
int main()
{
boost::scoped_ptr<sum> s(boost::factory<sum*>()(1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12));
BOOST_TEST(s->get() == 78);
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,56 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/factory.hpp>
#include <boost/core/default_allocator.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/config.hpp>
#include <exception>
#if defined(BOOST_NO_EXCEPTIONS)
namespace boost {
BOOST_NORETURN void throw_exception(const std::exception&)
{
std::terminate();
}
}
#endif
class sum {
public:
sum(int a, int b)
: value_(a + b) { }
int get() const {
return value_;
}
private:
int value_;
};
int main()
{
int a = 1;
int b = 2;
{
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
boost::default_allocator<void>,
boost::factory_alloc_for_pointee_and_deleter>()(a, b));
BOOST_TEST(s->get() == 3);
}
{
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
boost::default_allocator<void>,
boost::factory_passes_alloc_to_smart_pointer>()(a, b));
BOOST_TEST(s->get() == 3);
}
return boost::report_errors();
}

View File

@@ -0,0 +1,55 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/scoped_ptr.hpp>
class arg {
public:
explicit arg(int n)
: value_(n) { }
arg(arg&& a)
: value_(a.value_) { }
int get() const {
return value_;
}
private:
int value_;
};
class sum {
public:
explicit sum(arg&& a1, arg&& a2)
: value_(a1.get() + a2.get()) { }
int get() const {
return value_;
}
private:
int value_;
};
int main()
{
boost::scoped_ptr<sum> s(boost::factory<sum*>()(arg(1), arg(2)));
BOOST_TEST(s->get() == 3);
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,95 @@
/*
Copyright 2007 Tobias Schwinger
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
class sum {
public:
sum(int a, int b)
: value_(a + b) { }
int get() const {
return value_;
}
private:
int value_;
};
template<class T>
class creator {
public:
static int count;
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
++count;
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
--count;
::operator delete(ptr);
}
};
template<class T>
int creator<T>::count = 0;
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
int main()
{
int a = 1;
int b = 2;
{
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
creator<void>,
boost::factory_alloc_for_pointee_and_deleter>()(a, b));
BOOST_TEST(creator<sum>::count == 1);
BOOST_TEST(s->get() == 3);
}
BOOST_TEST(creator<sum>::count == 0);
{
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
creator<void>,
boost::factory_passes_alloc_to_smart_pointer>()(a, b));
BOOST_TEST(creator<sum>::count == 1);
BOOST_TEST(s->get() == 3);
}
BOOST_TEST(creator<sum>::count == 0);
return boost::report_errors();
}

View File

@@ -0,0 +1,46 @@
/*
Copyright 2007 Tobias Schwinger
Copyright 2017 Daniel James
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <memory>
class sum {
public:
sum(int a, int b)
: value_(a + b) { }
int get() const {
return value_;
}
private:
int value_;
};
int main()
{
int a = 1;
int b = 2;
{
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
std::allocator<char>,
boost::factory_alloc_for_pointee_and_deleter>()(a, b));
BOOST_TEST(s->get() == 3);
}
{
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
std::allocator<char>,
boost::factory_passes_alloc_to_smart_pointer>()(a, b));
BOOST_TEST(s->get() == 3);
}
return boost::report_errors();
}

View File

@@ -0,0 +1,86 @@
/*
Copyright 2007 Tobias Schwinger
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/value_factory.hpp>
#include <boost/core/lightweight_test.hpp>
class sum {
public:
explicit sum(int i0 = 0, int i1 = 0, int i2 = 0, int i3 = 0,
int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0,
int i8 = 0, int i9 = 0)
: value_(i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9) { }
int get() const {
return value_;
}
private:
int value_;
};
int main()
{
boost::value_factory<sum> x;
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int h = 8;
int i = 9;
int j = 10;
{
sum s(x());
BOOST_TEST(s.get() == 0);
}
{
sum s(x(a));
BOOST_TEST(s.get() == 1);
}
{
sum s(x(a, b));
BOOST_TEST(s.get() == 3);
}
{
sum s(x(a, b, c));
BOOST_TEST(s.get() == 6);
}
{
sum s(x(a, b, c, d));
BOOST_TEST(s.get() == 10);
}
{
sum s(x(a, b, c, d, e));
BOOST_TEST(s.get() == 15);
}
{
sum s(x(a, b, c, d, e, f));
BOOST_TEST(s.get() == 21);
}
{
sum s(x(a, b, c, d, e, f, g));
BOOST_TEST(s.get() == 28);
}
{
sum s(x(a, b, c, d, e, f, g, h));
BOOST_TEST(s.get() == 36);
}
{
sum s(x(a, b, c, d, e, f, g, h, i));
BOOST_TEST(s.get() == 45);
}
{
sum s(x(a, b, c, d, e, f, g, h, i, j));
BOOST_TEST(s.get() == 55);
}
return boost::report_errors();
}

View File

@@ -0,0 +1,40 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/functional/value_factory.hpp>
#include <boost/core/lightweight_test.hpp>
class sum {
public:
explicit sum(int a = 0, int b = 0, int c = 0, int d = 0,
int e = 0, int f = 0, int g = 0, int h = 0,
int i = 0, int j = 0, int k = 0, int l = 0)
: value_(a + b + c + d + e + f + g + h + i + j + k + l) { }
int get() const {
return value_;
}
private:
int value_;
};
int main()
{
sum s(boost::value_factory<sum>()(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
BOOST_TEST(s.get() == 78);
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,54 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/functional/value_factory.hpp>
#include <boost/core/lightweight_test.hpp>
class arg {
public:
explicit arg(int n)
: value_(n) { }
arg(arg&& a)
: value_(a.value_) { }
int get() const {
return value_;
}
private:
int value_;
};
class sum {
public:
explicit sum(arg&& a1, arg&& a2)
: value_(a1.get() + a2.get()) { }
int get() const {
return value_;
}
private:
int value_;
};
int main()
{
sum s(boost::value_factory<sum>()(arg(1), arg(2)));
BOOST_TEST(s.get() == 3);
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,19 @@
# (C) Copyright Tobias Schwinger
#
# Use modification and distribution are subject to the boost Software License,
# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
using quickbook ;
xml forward : forward.qbk ;
boostbook standalone : forward
:
<xsl:param>boost.root=../../../../..
<xsl:param>boost.libraries=../../../../libraries.htm
<xsl:param>chunk.section.depth=0
<xsl:param>chunk.first.sections=0
<xsl:param>generate.section.toc.level=2
<xsl:param>toc.max.depth=1
;

View File

@@ -0,0 +1,316 @@
[library Boost.Functional/Forward
[quickbook 1.3]
[version 1.0]
[authors [Schwinger, Tobias]]
[copyright 2007 2008 Tobias Schwinger]
[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])
]
[purpose Function object adapters for generic argument forwarding.]
[category higher-order]
[category generic]
[last-revision $Date: 2008/11/01 19:58:50 $]
]
[def __unspecified__ /unspecified/]
[def __boost_ref__ [@http://www.boost.org/doc/html/ref.html Boost.Ref]]
[def __boost_result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf]]
[def __boost__result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of `boost::result_of`]]
[def __the_forwarding_problem__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem]]
[def __boost_fusion__ [@http://www.boost.org/libs/fusion/doc/html/index.html Boost.Fusion]]
[section Brief Description]
`boost::forward_adapter` provides a reusable adapter template for function
objects. It forwards RValues as references to const, while leaving LValues
as-is.
struct g // function object that only accept LValues
{
template< typename T0, typename T1, typename T2 >
void operator()(T0 & t0, T1 & t1, T2 & t2) const;
typedef void result_type;
};
// Adapted version also accepts RValues and forwards
// them as references to const, LValues as-is
typedef boost::forward_adapter<g> f;
Another adapter, `boost::lighweight_forward_adapter` allows forwarding with
some help from the user accepting and unwrapping reference wrappers (see
__boost_ref__) for reference arguments, const qualifying all other arguments.
The target functions must be compatible with __boost_result_of__, and so are
the adapters.
[endsect]
[section Background]
Let's suppose we have some function `f` that we can call like this:
f(123,a_variable);
Now we want to write another, generic function `g` that can be called the
same way and returns some object that calls `f` with the same arguments.
f(123,a_variable) == g(f,123,a_variable).call_f()
[heading Why would we want to do it, anyway?]
Maybe we want to run `f` several times. Or maybe we want to run it within
another thread. Maybe we just want to encapsulate the call expression for now,
and then use it with other code that allows to compose more complex expressions
in order to decompose it with C++ templates and have the compiler generate some
machinery that eventually calls `f` at runtime (in other words; apply a
technique that is commonly referred to as Expression Templates).
[heading Now, how do we do it?]
The bad news is: It's impossible.
That is so because there is a slight difference between a variable and an
expression that evaluates to its value: Given
int y;
int const z = 0;
and
template< typename T > void func1(T & x);
we can call
func1(y); // x is a reference to a non-const object
func1(z); // x is a reference to a const object
where
func1(1); // fails to compile.
This way we can safely have `func1` store its reference argument and the
compiler keeps us from storing a reference to an object with temporary lifetime.
It is important to realize that non-constness and whether an object binds to a
non-const reference parameter are two different properties. The latter is the
distinction between LValues and RValues. The names stem from the left hand side
and the right hand side of assignment expressions, thus LValues are typically
the ones you can assign to, and RValues the temporary results from the right
hand side expression.
y = 1+2; // a is LValue, 1+2 is the expression producing the RValue,
// 1+2 = a; // usually makes no sense.
func1(y); // works, because y is an LValue
// func1(1+2); // fails to compile, because we only got an RValue.
If we add const qualification on the parameter, our function also accepts
RValues:
template< typename T > void func2(T const & x);
// [...] function scope:
func2(1); // x is a reference to a const temporary, object,
func2(y); // x is a reference to a const object, while y is not const, and
func2(z); // x is a reference to a const object, just like z.
In all cases, the argument `x` in `func2` is a const-qualified LValue.
We can use function overloading to identify non-const LValues:
template< typename T > void func3(T const & x); // #1
template< typename T > void func3(T & x); // #2
// [...] function scope:
func3(1); // x is a reference to a const, temporary object in #1,
func3(y); // x is a reference to a non-const object in #2, and
func3(z); // x is a reference to a const object in #1.
Note that all arguments `x` in the overloaded function `func3` are LValues.
In fact, there is no way to transport RValues into a function as-is in C++98.
Also note that we can't distinguish between what used to be a const qualified
LValue and an RValue.
That's as close as we can get to a generic forwarding function `g` as
described above by the means of C++ 98. See __the_forwarding_problem__ for a
very detailed discussion including solutions that require language changes.
Now, for actually implementing it, we need 2^N overloads for N parameters
(each with and without const qualifier) for each number of arguments
(that is 2^(Nmax+1) - 2^Nmin). Right, that means the compile-time complexity
is O(2^N), however the factor is low so it works quite well for a reasonable
number (< 10) of arguments.
[endsect]
[section:reference Reference]
[section forward_adapter]
[heading Description]
Function object adapter template whose instances are callable with LValue and
RValue arguments. RValue arguments are forwarded as reference-to-const typed
LValues.
An arity can be given as second, numeric non-type template argument to restrict
forwarding to a specific arity.
If a third, numeric non-type template argument is present, the second and third
template argument are treated as minimum and maximum arity, respectively.
Specifying an arity can be helpful to improve the readability of diagnostic
messages and compile time performance.
__boost_result_of__ can be used to determine the result types of specific call
expressions.
[heading Header]
#include <boost/functional/forward_adapter.hpp>
[heading Synopsis]
namespace boost
{
template< class Function,
int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ >
class forward_adapter;
}
[variablelist Notation
[[`F`] [a possibly const qualified function object type or reference type thereof]]
[[`f`] [an object convertible to `F`]]
[[`FA`] [the type `forward_adapter<F>`]]
[[`fa`] [an instance object of `FA`, initialized with `f`]]
[[`a0`...`aN`] [arguments to `fa`]]
]
The result type of a target function invocation must be
__boost__result_of__<F*(TA0 [const]&...TAN [const]&])>::type
where `TA0`...`TAN` denote the argument types of `a0`...`aN`.
[heading Expression Semantics]
[table
[[Expression] [Semantics]]
[[`FA(f)`] [creates an adapter, initializes the target function with `f`.]]
[[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]]
[[`fa(a0`...`aN)`] [calls `f` with with arguments `a0`...`aN`.]]
]
[heading Limits]
The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set the
maximum call arity. It defaults to 6.
[heading Complexity]
Preprocessing time: O(2^N), where N is the arity limit.
Compile time: O(2^N), where N depends on the arity range.
Run time: O(0) if the compiler inlines, O(1) otherwise.
[endsect]
[section lightweight_forward_adapter]
[heading Description]
Function object adapter template whose instances are callable with LValue and
RValue arguments. All arguments are forwarded as reference-to-const typed
LValues, except for reference wrappers which are unwrapped and may yield
non-const LValues.
An arity can be given as second, numeric non-type template argument to restrict
forwarding to a specific arity.
If a third, numeric non-type template argument is present, the second and third
template argument are treated as minimum and maximum arity, respectively.
Specifying an arity can be helpful to improve the readability of diagnostic
messages and compile time performance.
__boost_result_of__ can be used to determine the result types of specific call
expressions.
[heading Header]
#include <boost/functional/lightweight_forward_adapter.hpp>
[heading Synopsis]
namespace boost
{
template< class Function,
int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ >
struct lightweight_forward_adapter;
}
[variablelist Notation
[[`F`] [a possibly const qualified function object type or reference type thereof]]
[[`f`] [an object convertible to `F`]]
[[`FA`] [the type `lightweight_forward_adapter<F>`]]
[[`fa`] [an instance of `FA`, initialized with `f`]]
[[`a0`...`aN`] [arguments to `fa`]]
]
The result type of a target function invocation must be
__boost__result_of__<F*(TA0 [const]&...TAN [const]&])>::type
where `TA0`...`TAN` denote the argument types of `a0`...`aN`.
[heading Expression Semantics]
[table
[[Expression] [Semantics]]
[[`FA(f)`] [creates an adapter, initializes the target function with `f`.]]
[[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]]
[[`fa(a0`...`aN)`] [calls `f` with with const arguments `a0`...`aN`. If `aI` is a
reference wrapper it is unwrapped.]]
]
[heading Limits]
The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined
to set the maximum call arity. It defaults to 10.
[heading Complexity]
Preprocessing time: O(N), where N is the arity limit.
Compile time: O(N), where N is the effective arity of a call.
Run time: O(0) if the compiler inlines, O(1) otherwise.
[endsect]
[endsect]
[section Acknowledgements]
As these utilities are factored out of the __boost_fusion__ functional module,
I want to thank Dan Marsden and Joel de Guzman for letting me participate in the
development of that great library in the first place.
Further, I want to credit the authors of the references below, for their
in-depth investigation of the problem and the solution implemented here.
Last but not least I want to thank Vesa Karnoven and Paul Mensonides for the
Boost Preprocessor library. Without it, I would have ended up with an external
code generator for this one.
[endsect]
[section References]
# [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem],
Peter Dimov, Howard E. Hinnant, David Abrahams, 2002
# [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf],
Douglas Gregor, 2004
# [@http://www.boost.org/doc/html/ref.html Boost.Ref],
Jaakko Jarvi, Peter Dimov, Douglas Gregor, David Abrahams, 1999-2002
[endsect]

View File

@@ -0,0 +1,16 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<!-- Copyright (C) 2002 Douglas Gregor <doug.gregor -at- 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) -->
<title>Redirect to generated documentation</title>
<meta http-equiv="refresh" content="0; URL=http://www.boost.org/doc/libs/master/libs/functional/forward/doc/html/">
</head>
<body>
Automatic redirection failed, please go to
<a href="http://www.boost.org/doc/libs/master/libs/functional/forward/doc/html/">http://www.boost.org/doc/libs/master/libs/functional/forward/doc/html/</a>
</body>
</html>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatic redirection failed, click this
<a href="doc/html/index.html">link</a> &nbsp;<hr>
<p><EFBFBD> Copyright Tobias Schwinger, 2009</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>
</body>
</html>

View File

@@ -0,0 +1,17 @@
# (C) Copyright Tobias Schwinger
#
# Use modification and distribution are subject to the boost Software License,
# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
import testing ;
project forward-tests
;
test-suite functional/forward
:
[ run forward_adapter.cpp ]
[ run lightweight_forward_adapter.cpp ]
;

View File

@@ -0,0 +1,135 @@
/*=============================================================================
Copyright (c) 2007 Tobias Schwinger
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).
==============================================================================*/
#include <boost/config.hpp>
#ifdef BOOST_MSVC
# pragma warning(disable: 4244) // no conversion warnings, please
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/functional/forward_adapter.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/blank.hpp>
#include <boost/noncopyable.hpp>
#include <memory>
template <class Base = boost::blank>
class test_func : public Base
{
int val;
public:
test_func(int v) : val(v) { }
template<class B>
test_func(test_func<B> const & that)
: val(that.val)
{ }
template<class B> friend class test_func;
int operator()(int & l, int const & r) const
{
return l=r+val;
}
long operator()(int & l, int const & r)
{
return -(l=r+val);
}
char operator()(int& l, int& r)
{
return l=r+val;
}
template <typename Sig>
struct result
{
typedef void type;
};
// ensure result_of argument types are what's expected
// note: this is *not* how client code should look like
template <class Self>
struct result< Self const(int&,int const&) > { typedef int type; };
template <class Self>
struct result< Self(int&,int const&) > { typedef long type; };
template <class Self>
struct result< Self(int&,int&) > { typedef char type; };
};
enum { int_, long_, char_ };
int type_of(int) { return int_; }
int type_of(long) { return long_; }
int type_of(char) { return char_; }
int main()
{
{
using boost::is_same;
using boost::result_of;
typedef boost::forward_adapter< test_func<> > f;
// lvalue,rvalue
BOOST_TEST(( is_same<
result_of< f(int&, int) >::type, long >::value ));
BOOST_TEST(( is_same<
result_of< f const (int&, int) >::type, int >::value ));
// lvalue,const lvalue
BOOST_TEST(( is_same<
result_of< f(int&, int const &) >::type, long >::value ));
BOOST_TEST(( is_same<
result_of< f const (int&, int const &) >::type, int >::value ));
// lvalue,lvalue
BOOST_TEST(( is_same<
result_of< f(int&, int&) >::type, char >::value ));
// result_of works differently for C++11 here, so compare
// with using it against test_func.
BOOST_TEST(( is_same<
result_of< f const (int&, int&) >::type,
result_of< test_func<> const (int&, int&)>::type >::value ));
}
{
using boost::noncopyable;
using boost::forward_adapter;
int x = 0;
test_func<noncopyable> f(7);
forward_adapter< test_func<> > func(f);
forward_adapter< test_func<noncopyable> & > func_ref(f);
forward_adapter< test_func<noncopyable> & > const func_ref_c(f);
forward_adapter< test_func<> const > func_c(f);
forward_adapter< test_func<> > const func_c2(f);
forward_adapter< test_func<noncopyable> const & > func_c_ref(f);
BOOST_TEST( type_of( func(x,1) ) == long_ );
BOOST_TEST( type_of( func_ref(x,1) ) == long_ );
BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ );
BOOST_TEST( type_of( func_c(x,1) ) == int_ );
BOOST_TEST( type_of( func_c2(x,1) ) == int_ );
BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ );
BOOST_TEST( type_of( func(x,x) ) == char_ );
BOOST_TEST( func(x,1) == -8 );
BOOST_TEST( func_ref(x,1) == -8 );
BOOST_TEST( func_ref_c(x,1) == -8 );
BOOST_TEST( func_c(x,1) == 8 );
BOOST_TEST( func_c2(x,1) == 8 );
BOOST_TEST( func_c_ref(x,1) == 8 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,135 @@
/*=============================================================================
Copyright (c) 2007 Tobias Schwinger
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).
==============================================================================*/
#include <boost/config.hpp>
#ifdef BOOST_MSVC
# pragma warning(disable: 4244) // no conversion warnings, please
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/functional/lightweight_forward_adapter.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/blank.hpp>
#include <boost/noncopyable.hpp>
#include <memory>
template <class Base = boost::blank>
class test_func : public Base
{
int val;
public:
test_func(int v) : val(v) { }
template<class B>
test_func(test_func<B> const & that)
: val(that.val)
{ }
template<class B> friend class test_func;
int operator()(int & l, int const & r) const
{
return l=r+val;
}
long operator()(int & l, int const & r)
{
return -(l=r+val);
}
char operator()(int & l, int & r)
{
return l=r+val;
}
template <typename Sig>
struct result
{
typedef void type;
};
// ensure result_of argument types are what's expected
// note: this is *not* how client code should look like
template <class Self>
struct result< Self const(int&,int const&) > { typedef int type; };
template <class Self>
struct result< Self(int&,int const&) > { typedef long type; };
template <class Self>
struct result< Self(int&,int&) > { typedef char type; };
};
enum { int_, long_, char_ };
int type_of(int) { return int_; }
int type_of(long) { return long_; }
int type_of(char) { return char_; }
int main()
{
{
using boost::is_same;
using boost::result_of;
typedef boost::lightweight_forward_adapter< test_func<> > f;
typedef boost::reference_wrapper<int> ref;
typedef boost::reference_wrapper<int const> cref;
// lvalue,rvalue
BOOST_TEST(( is_same<
result_of< f(ref, int) >::type, long >::value ));
BOOST_TEST(( is_same<
result_of< f const (ref, int) >::type, int >::value ));
// lvalue,const lvalue
BOOST_TEST(( is_same<
result_of< f(ref, cref) >::type, long >::value ));
BOOST_TEST(( is_same<
result_of< f const (ref, cref) >::type, int >::value ));
// lvalue,lvalue
BOOST_TEST(( is_same<
result_of< f(ref, ref) >::type, char >::value ));
// result_of works differently for C++11 here, so compare
// with using it against test_func.
BOOST_TEST(( is_same<
result_of< f const (ref, ref) >::type,
result_of< test_func<> const (int&, int&) >::type >::value ));
}
{
using boost::noncopyable;
using boost::lightweight_forward_adapter;
int v = 0; boost::reference_wrapper<int> x(v);
test_func<noncopyable> f(7);
lightweight_forward_adapter< test_func<> > func(f);
lightweight_forward_adapter< test_func<noncopyable> & > func_ref(f);
lightweight_forward_adapter< test_func<noncopyable> & > const func_ref_c(f);
lightweight_forward_adapter< test_func<> const > func_c(f);
lightweight_forward_adapter< test_func<> > const func_c2(f);
lightweight_forward_adapter< test_func<noncopyable> const & > func_c_ref(f);
BOOST_TEST( type_of( func(x,1) ) == long_ );
BOOST_TEST( type_of( func_ref(x,1) ) == long_ );
BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ );
BOOST_TEST( type_of( func_c(x,1) ) == int_ );
BOOST_TEST( type_of( func_c2(x,1) ) == int_ );
BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ );
BOOST_TEST( type_of( func(x,x) ) == char_ );
BOOST_TEST( func(x,1) == -8 );
BOOST_TEST( func_ref(x,1) == -8 );
BOOST_TEST( func_ref_c(x,1) == -8 );
BOOST_TEST( func_c(x,1) == 8 );
BOOST_TEST( func_c2(x,1) == 8 );
BOOST_TEST( func_c_ref(x,1) == 8 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,233 @@
<!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>Boost Function Object Adapter Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2" summary="">
<tr>
<td bgcolor="#FFFFFF"><img src="../../boost.png" alt=
"boost.png (6897 bytes)" width="277" height="86"></td>
<td><a href="../../index.htm"><font face="Arial" color=
"#FFFFFF"><big>Home</big></font></a></td>
<td><a href="../libraries.htm"><font face="Arial" color=
"#FFFFFF"><big>Libraries</big></font></a></td>
<td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color=
"#FFFFFF"><big>People</big></font></a></td>
<td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color=
"#FFFFFF"><big>FAQ</big></font></a></td>
<td><a href="../../more/index.htm"><font face="Arial" color=
"#FFFFFF"><big>More</big></font></a></td>
</tr>
</table>
<h1>Function Object Traits</h1>
<p>The header <a href="../../boost/functional.hpp">functional.hpp</a>
provides two traits class templates for functions and function objects:</p>
<table border="1" summary="">
<tr>
<th>Type</th>
<th>Contents</th>
<th>Description</th>
</tr>
<tr>
<td valign="top" rowspan="4">
<tt>template&nbsp;&lt;typename&nbsp;T&gt;<br>
struct&nbsp;unary_traits</tt></td>
<td valign="top"><tt>function_type</tt></td>
<td valign="top">The type of the function or function object itself
(i.e., <tt>T</tt>).</td>
</tr>
<tr>
<td valign="top"><tt>param_type</tt></td>
<td valign="top">The type that should be used to pass the function or
function object as a parameter.</td>
</tr>
<tr>
<td valign="top"><tt>result_type</tt></td>
<td valign="top">The type returned by the function or function
object.</td>
</tr>
<tr>
<td valign="top"><tt>argument_type</tt></td>
<td valign="top">The type of the argument to the function or function
object.</td>
</tr>
<tr>
<td valign="top" rowspan="5">
<tt>template&nbsp;&lt;typename&nbsp;T&gt;<br>
struct&nbsp;binary_traits</tt></td>
<td valign="top"><tt>function_type</tt></td>
<td valign="top">The type of the function or function object itself
(i.e., <tt>T</tt>).</td>
</tr>
<tr>
<td valign="top"><tt>param_type</tt></td>
<td valign="top">The type that should be used to pass the function or
function object as a parameter.</td>
</tr>
<tr>
<td valign="top"><tt>result_type</tt></td>
<td valign="top">The type returned by the function or function
object.</td>
</tr>
<tr>
<td valign="top"><tt>first_argument_type</tt></td>
<td valign="top">The type of the first argument to the function or
function object.</td>
</tr>
<tr>
<td valign="top"><tt>second_argument_type</tt></td>
<td valign="top">The type of the second argument to the function or
function object.</td>
</tr>
</table>
<h3>Usage</h3>
<p><tt>unary_traits</tt> should be instantiated with either a function
taking a single parameter, or an adaptable unary function object (i.e., a
class derived from <tt>std::unary_function</tt> or one which provides the
same typedefs). (See &sect;20.3.1 in the C++ Standard.)</p>
<p><tt>binary_traits</tt> should be instantiated with either a function
taking two parameters, or an adaptable binary function object (i.e., a
class derived from <tt>std::binary_function</tt> or one which provides the
same typedefs). (See &sect;20.3.1 in the C++ Standard.)</p>
<p>The most common usage of these templates is in function object adapters,
thus allowing them to adapt plain functions as well as function objects.
You can do this by wherever you would normally write, for example,</p>
<blockquote>
<pre>
typename Operation::argument_type
</pre>
</blockquote>
<p>simply writing</p>
<blockquote>
<pre>
typename boost::unary_traits&lt;Operation&gt;::argument_type
</pre>
</blockquote>
<p>instead.</p>
<h3>Additional Types Defined</h3>
<p>In addition to the standard result and argument typedefs, these traits
templates define two additional types.</p>
<h4><tt>function_type</tt></h4>
<p>This is the type of the function or function object, and can be used in
declarations such as</p>
<blockquote>
<pre>
template &lt;class Predicate&gt;
class unary_negate : // ...
{
// ...
private:
<strong>typename unary_traits&lt;Predicate&gt;::function_type</strong> pred;
};
</pre>
</blockquote>
<p>If this typedef were not provided, it would not be possible to declare
<tt>pred</tt> in a way that would allow <tt>unary_negate</tt> to be
instantiated with a function type (see the C++ Standard &sect;14.3.1
&para;3).</p>
<h4><tt>param_type</tt></h4>
<p>This is a type suitable for passing the function or function object as a
parameter to another function. For example,</p>
<blockquote>
<pre>
template &lt;class Predicate&gt;
class unary_negate : // ...
{
public:
explicit unary_negate(<strong>typename unary_traits&lt;Predicate&gt;::param_type</strong> x)
:
pred(x)
{}
// ...
};
</pre>
</blockquote>
<p>Function objects are passed by reference to const; function pointers are
passed by value.</p>
<h3>Limitations</h3>
<p>This library uses these traits within all function object adapters,
theoretically rendering <tt>ptr_fun</tt> obsolete. However, third party
adapters probably won't take advantage of this mechanism, and so
<tt>ptr_fun</tt> may still be required. Accordingly, this library also
provides <a href="ptr_fun.html">improved versions of the standard function
pointer adapters</a>.</p>
<p>These traits templates will also not work with compilers that fail to
support partial specialisation of templates. With these compilers, the
traits templates can only be instantiated with adaptable function objects,
thus requiring <tt>ptr_fun</tt> to be used, even with the function object
adapters in this library.</p>
<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 -->02
December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
<p><i>Copyright &copy; 2000 Cadenza New Zealand Ltd.</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>

View File

@@ -0,0 +1,16 @@
<!--
Copyright 2005-2007 Daniel James.
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>
<meta http-equiv="refresh" content="0; URL=../../../doc/html/hash.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="../../../doc/html/hash.html">../../../doc/html/hash.html</a>
</body>
</html>

View File

@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Boost Function Object Adapter Library</title>
</head>
<body>
<h1>Identity</h1>
<p>The header <a href="../../boost/functional/identity.hpp">
&lt;boost/functional/identity.hpp&gt;</a> provides the function object
<code>boost::identity</code> whose <code>operator()</code> returns its
argument. It is an implementation of C++20's <code>std::identity</code>
that supports C++03 and above.</p>
<h2>Example</h2>
<p>It is commonly used as the default projection in constrained algorithms.</p>
<pre>
<code>template&lt;class Range, class Projection = boost::identity&gt;
void print(Range&& range, Projection projection = {});</code>
</pre>
<h2>Reference</h2>
<pre>
<code>namespace boost {
struct identity {
using is_transparent = <em>unspecified</em>;
template&lt;class T&gt;
T&amp;&amp; operator()(T&amp;&amp; value) const noexcept;
};
} // boost</code>
</pre>
<h3>Operators</h3>
<dl>
<dt><code>template&lt;class T&gt;
T&amp;&amp; operator()(T&amp;&amp; value) const noexcept;</code></dt>
<dd>Returns <code>std::forward&lt;T&gt;(value)</code></dd>
</dl>
<hr>
<p>Copyright 2021 Glen Joseph Fernandes.</p>
<p>Distributed under the
<a href="http://www.boost.org/LICENSE_1_0.txt">Boost Software License,
Version 1.0</a>.</p>
</body>
</html>

View File

@@ -0,0 +1,581 @@
// ------------------------------------------------------------------------------
// Copyright (c) 2000 Cadenza New Zealand Ltd
// Distributed under the Boost Software License, Version 1.0. (See accompany-
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// ------------------------------------------------------------------------------
// Boost functional.hpp header file
// See http://www.boost.org/libs/functional for documentation.
// ------------------------------------------------------------------------------
// $Id$
// ------------------------------------------------------------------------------
#ifndef BOOST_FUNCTIONAL_HPP
#define BOOST_FUNCTIONAL_HPP
#include <boost/config.hpp>
#include <boost/call_traits.hpp>
#include <functional>
namespace boost
{
namespace functional
{
namespace detail {
#if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC
// std::unary_function and std::binary_function were both removed
// in C++17.
template <typename Arg1, typename Result>
struct unary_function
{
typedef Arg1 argument_type;
typedef Result result_type;
};
template <typename Arg1, typename Arg2, typename Result>
struct binary_function
{
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
#else
// Use the standard objects when we have them.
using std::unary_function;
using std::binary_function;
#endif
}
}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// --------------------------------------------------------------------------
// The following traits classes allow us to avoid the need for ptr_fun
// because the types of arguments and the result of a function can be
// deduced.
//
// In addition to the standard types defined in unary_function and
// binary_function, we add
//
// - function_type, the type of the function or function object itself.
//
// - param_type, the type that should be used for passing the function or
// function object as an argument.
// --------------------------------------------------------------------------
namespace detail
{
template <class Operation>
struct unary_traits_imp;
template <class Operation>
struct unary_traits_imp<Operation*>
{
typedef Operation function_type;
typedef const function_type & param_type;
typedef typename Operation::result_type result_type;
typedef typename Operation::argument_type argument_type;
};
template <class R, class A>
struct unary_traits_imp<R(*)(A)>
{
typedef R (*function_type)(A);
typedef R (*param_type)(A);
typedef R result_type;
typedef A argument_type;
};
template <class Operation>
struct binary_traits_imp;
template <class Operation>
struct binary_traits_imp<Operation*>
{
typedef Operation function_type;
typedef const function_type & param_type;
typedef typename Operation::result_type result_type;
typedef typename Operation::first_argument_type first_argument_type;
typedef typename Operation::second_argument_type second_argument_type;
};
template <class R, class A1, class A2>
struct binary_traits_imp<R(*)(A1,A2)>
{
typedef R (*function_type)(A1,A2);
typedef R (*param_type)(A1,A2);
typedef R result_type;
typedef A1 first_argument_type;
typedef A2 second_argument_type;
};
} // namespace detail
template <class Operation>
struct unary_traits
{
typedef typename detail::unary_traits_imp<Operation*>::function_type function_type;
typedef typename detail::unary_traits_imp<Operation*>::param_type param_type;
typedef typename detail::unary_traits_imp<Operation*>::result_type result_type;
typedef typename detail::unary_traits_imp<Operation*>::argument_type argument_type;
};
template <class R, class A>
struct unary_traits<R(*)(A)>
{
typedef R (*function_type)(A);
typedef R (*param_type)(A);
typedef R result_type;
typedef A argument_type;
};
template <class Operation>
struct binary_traits
{
typedef typename detail::binary_traits_imp<Operation*>::function_type function_type;
typedef typename detail::binary_traits_imp<Operation*>::param_type param_type;
typedef typename detail::binary_traits_imp<Operation*>::result_type result_type;
typedef typename detail::binary_traits_imp<Operation*>::first_argument_type first_argument_type;
typedef typename detail::binary_traits_imp<Operation*>::second_argument_type second_argument_type;
};
template <class R, class A1, class A2>
struct binary_traits<R(*)(A1,A2)>
{
typedef R (*function_type)(A1,A2);
typedef R (*param_type)(A1,A2);
typedef R result_type;
typedef A1 first_argument_type;
typedef A2 second_argument_type;
};
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// --------------------------------------------------------------------------
// If we have no partial specialisation available, decay to a situation
// that is no worse than in the Standard, i.e., ptr_fun will be required.
// --------------------------------------------------------------------------
template <class Operation>
struct unary_traits
{
typedef Operation function_type;
typedef const Operation& param_type;
typedef typename Operation::result_type result_type;
typedef typename Operation::argument_type argument_type;
};
template <class Operation>
struct binary_traits
{
typedef Operation function_type;
typedef const Operation & param_type;
typedef typename Operation::result_type result_type;
typedef typename Operation::first_argument_type first_argument_type;
typedef typename Operation::second_argument_type second_argument_type;
};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// --------------------------------------------------------------------------
// unary_negate, not1
// --------------------------------------------------------------------------
template <class Predicate>
class unary_negate
: public boost::functional::detail::unary_function<typename unary_traits<Predicate>::argument_type,bool>
{
public:
explicit unary_negate(typename unary_traits<Predicate>::param_type x)
:
pred(x)
{}
bool operator()(typename call_traits<typename unary_traits<Predicate>::argument_type>::param_type x) const
{
return !pred(x);
}
private:
typename unary_traits<Predicate>::function_type pred;
};
template <class Predicate>
unary_negate<Predicate> not1(const Predicate &pred)
{
// The cast is to placate Borland C++Builder in certain circumstances.
// I don't think it should be necessary.
return unary_negate<Predicate>((typename unary_traits<Predicate>::param_type)pred);
}
template <class Predicate>
unary_negate<Predicate> not1(Predicate &pred)
{
return unary_negate<Predicate>(pred);
}
// --------------------------------------------------------------------------
// binary_negate, not2
// --------------------------------------------------------------------------
template <class Predicate>
class binary_negate
: public boost::functional::detail::binary_function<
typename binary_traits<Predicate>::first_argument_type,
typename binary_traits<Predicate>::second_argument_type,
bool>
{
public:
explicit binary_negate(typename binary_traits<Predicate>::param_type x)
:
pred(x)
{}
bool operator()(typename call_traits<typename binary_traits<Predicate>::first_argument_type>::param_type x,
typename call_traits<typename binary_traits<Predicate>::second_argument_type>::param_type y) const
{
return !pred(x,y);
}
private:
typename binary_traits<Predicate>::function_type pred;
};
template <class Predicate>
binary_negate<Predicate> not2(const Predicate &pred)
{
// The cast is to placate Borland C++Builder in certain circumstances.
// I don't think it should be necessary.
return binary_negate<Predicate>((typename binary_traits<Predicate>::param_type)pred);
}
template <class Predicate>
binary_negate<Predicate> not2(Predicate &pred)
{
return binary_negate<Predicate>(pred);
}
// --------------------------------------------------------------------------
// binder1st, bind1st
// --------------------------------------------------------------------------
template <class Operation>
class binder1st
: public boost::functional::detail::unary_function<
typename binary_traits<Operation>::second_argument_type,
typename binary_traits<Operation>::result_type>
{
public:
binder1st(typename binary_traits<Operation>::param_type x,
typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type y)
:
op(x), value(y)
{}
typename binary_traits<Operation>::result_type
operator()(typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type x) const
{
return op(value, x);
}
protected:
typename binary_traits<Operation>::function_type op;
typename binary_traits<Operation>::first_argument_type value;
};
template <class Operation>
inline binder1st<Operation> bind1st(const Operation &op,
typename call_traits<
typename binary_traits<Operation>::first_argument_type
>::param_type x)
{
// The cast is to placate Borland C++Builder in certain circumstances.
// I don't think it should be necessary.
return binder1st<Operation>((typename binary_traits<Operation>::param_type)op, x);
}
template <class Operation>
inline binder1st<Operation> bind1st(Operation &op,
typename call_traits<
typename binary_traits<Operation>::first_argument_type
>::param_type x)
{
return binder1st<Operation>(op, x);
}
// --------------------------------------------------------------------------
// binder2nd, bind2nd
// --------------------------------------------------------------------------
template <class Operation>
class binder2nd
: public boost::functional::detail::unary_function<
typename binary_traits<Operation>::first_argument_type,
typename binary_traits<Operation>::result_type>
{
public:
binder2nd(typename binary_traits<Operation>::param_type x,
typename call_traits<typename binary_traits<Operation>::second_argument_type>::param_type y)
:
op(x), value(y)
{}
typename binary_traits<Operation>::result_type
operator()(typename call_traits<typename binary_traits<Operation>::first_argument_type>::param_type x) const
{
return op(x, value);
}
protected:
typename binary_traits<Operation>::function_type op;
typename binary_traits<Operation>::second_argument_type value;
};
template <class Operation>
inline binder2nd<Operation> bind2nd(const Operation &op,
typename call_traits<
typename binary_traits<Operation>::second_argument_type
>::param_type x)
{
// The cast is to placate Borland C++Builder in certain circumstances.
// I don't think it should be necessary.
return binder2nd<Operation>((typename binary_traits<Operation>::param_type)op, x);
}
template <class Operation>
inline binder2nd<Operation> bind2nd(Operation &op,
typename call_traits<
typename binary_traits<Operation>::second_argument_type
>::param_type x)
{
return binder2nd<Operation>(op, x);
}
// --------------------------------------------------------------------------
// mem_fun, etc
// --------------------------------------------------------------------------
template <class S, class T>
class mem_fun_t : public boost::functional::detail::unary_function<T*, S>
{
public:
explicit mem_fun_t(S (T::*p)())
:
ptr(p)
{}
S operator()(T* p) const
{
return (p->*ptr)();
}
private:
S (T::*ptr)();
};
template <class S, class T, class A>
class mem_fun1_t : public boost::functional::detail::binary_function<T*, A, S>
{
public:
explicit mem_fun1_t(S (T::*p)(A))
:
ptr(p)
{}
S operator()(T* p, typename call_traits<A>::param_type x) const
{
return (p->*ptr)(x);
}
private:
S (T::*ptr)(A);
};
template <class S, class T>
class const_mem_fun_t : public boost::functional::detail::unary_function<const T*, S>
{
public:
explicit const_mem_fun_t(S (T::*p)() const)
:
ptr(p)
{}
S operator()(const T* p) const
{
return (p->*ptr)();
}
private:
S (T::*ptr)() const;
};
template <class S, class T, class A>
class const_mem_fun1_t : public boost::functional::detail::binary_function<const T*, A, S>
{
public:
explicit const_mem_fun1_t(S (T::*p)(A) const)
:
ptr(p)
{}
S operator()(const T* p, typename call_traits<A>::param_type x) const
{
return (p->*ptr)(x);
}
private:
S (T::*ptr)(A) const;
};
template<class S, class T>
inline mem_fun_t<S,T> mem_fun(S (T::*f)())
{
return mem_fun_t<S,T>(f);
}
template<class S, class T, class A>
inline mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A))
{
return mem_fun1_t<S,T,A>(f);
}
#ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
template<class S, class T>
inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const)
{
return const_mem_fun_t<S,T>(f);
}
template<class S, class T, class A>
inline const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const)
{
return const_mem_fun1_t<S,T,A>(f);
}
#endif // BOOST_NO_POINTER_TO_MEMBER_CONST
// --------------------------------------------------------------------------
// mem_fun_ref, etc
// --------------------------------------------------------------------------
template <class S, class T>
class mem_fun_ref_t : public boost::functional::detail::unary_function<T&, S>
{
public:
explicit mem_fun_ref_t(S (T::*p)())
:
ptr(p)
{}
S operator()(T& p) const
{
return (p.*ptr)();
}
private:
S (T::*ptr)();
};
template <class S, class T, class A>
class mem_fun1_ref_t : public boost::functional::detail::binary_function<T&, A, S>
{
public:
explicit mem_fun1_ref_t(S (T::*p)(A))
:
ptr(p)
{}
S operator()(T& p, typename call_traits<A>::param_type x) const
{
return (p.*ptr)(x);
}
private:
S (T::*ptr)(A);
};
template <class S, class T>
class const_mem_fun_ref_t : public boost::functional::detail::unary_function<const T&, S>
{
public:
explicit const_mem_fun_ref_t(S (T::*p)() const)
:
ptr(p)
{}
S operator()(const T &p) const
{
return (p.*ptr)();
}
private:
S (T::*ptr)() const;
};
template <class S, class T, class A>
class const_mem_fun1_ref_t : public boost::functional::detail::binary_function<const T&, A, S>
{
public:
explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
:
ptr(p)
{}
S operator()(const T& p, typename call_traits<A>::param_type x) const
{
return (p.*ptr)(x);
}
private:
S (T::*ptr)(A) const;
};
template<class S, class T>
inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)())
{
return mem_fun_ref_t<S,T>(f);
}
template<class S, class T, class A>
inline mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A))
{
return mem_fun1_ref_t<S,T,A>(f);
}
#ifndef BOOST_NO_POINTER_TO_MEMBER_CONST
template<class S, class T>
inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const)
{
return const_mem_fun_ref_t<S,T>(f);
}
template<class S, class T, class A>
inline const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const)
{
return const_mem_fun1_ref_t<S,T,A>(f);
}
#endif // BOOST_NO_POINTER_TO_MEMBER_CONST
// --------------------------------------------------------------------------
// ptr_fun
// --------------------------------------------------------------------------
template <class Arg, class Result>
class pointer_to_unary_function : public boost::functional::detail::unary_function<Arg,Result>
{
public:
explicit pointer_to_unary_function(Result (*f)(Arg))
:
func(f)
{}
Result operator()(typename call_traits<Arg>::param_type x) const
{
return func(x);
}
private:
Result (*func)(Arg);
};
template <class Arg, class Result>
inline pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg))
{
return pointer_to_unary_function<Arg,Result>(f);
}
template <class Arg1, class Arg2, class Result>
class pointer_to_binary_function : public boost::functional::detail::binary_function<Arg1,Arg2,Result>
{
public:
explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))
:
func(f)
{}
Result operator()(typename call_traits<Arg1>::param_type x, typename call_traits<Arg2>::param_type y) const
{
return func(x,y);
}
private:
Result (*func)(Arg1, Arg2);
};
template <class Arg1, class Arg2, class Result>
inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1, Arg2))
{
return pointer_to_binary_function<Arg1,Arg2,Result>(f);
}
} // namespace boost
#endif

View File

@@ -0,0 +1,365 @@
/*
Copyright 2007 Tobias Schwinger
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_FUNCTIONAL_FACTORY_HPP
#define BOOST_FUNCTIONAL_FACTORY_HPP
#include <boost/config.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/type_traits/remove_cv.hpp>
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <memory>
#endif
#include <new>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <utility>
#endif
namespace boost {
enum factory_alloc_propagation {
factory_alloc_for_pointee_and_deleter,
factory_passes_alloc_to_smart_pointer
};
namespace detail {
template<factory_alloc_propagation>
struct fc_tag { };
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
struct fc_rebind {
typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
};
template<class A>
struct fc_pointer {
typedef typename std::allocator_traits<A>::pointer type;
};
#else
template<class A, class T>
struct fc_rebind {
typedef typename A::template rebind<T>::other type;
};
template<class A>
struct fc_pointer {
typedef typename A::pointer type;
};
#endif
#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class A, class T>
inline void
fc_destroy(A& a, T* p)
{
std::allocator_traits<A>::destroy(a, p);
}
#else
template<class A, class T>
inline void
fc_destroy(A&, T* p)
{
p->~T();
}
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T, class... Args>
inline void
fc_construct(A& a, T* p, Args&&... args)
{
std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...);
}
#else
template<class A, class T, class... Args>
inline void
fc_construct(A&, T* p, Args&&... args)
{
::new((void*)p) T(std::forward<Args>(args)...);
}
#endif
#endif
template<class A>
class fc_delete
: boost::empty_value<A> {
typedef boost::empty_value<A> base;
public:
explicit fc_delete(const A& a) BOOST_NOEXCEPT
: base(boost::empty_init_t(), a) { }
void operator()(typename fc_pointer<A>::type p) {
boost::detail::fc_destroy(base::get(), boost::to_address(p));
base::get().deallocate(p, 1);
}
};
template<class R, class A>
class fc_allocate {
public:
explicit fc_allocate(const A& a)
: a_(a)
, p_(a_.allocate(1)) { }
~fc_allocate() {
if (p_) {
a_.deallocate(p_, 1);
}
}
A& state() BOOST_NOEXCEPT {
return a_;
}
typename A::value_type* get() const BOOST_NOEXCEPT {
return boost::to_address(p_);
}
R release(fc_tag<factory_alloc_for_pointee_and_deleter>) {
return R(release(), fc_delete<A>(a_), a_);
}
R release(fc_tag<factory_passes_alloc_to_smart_pointer>) {
return R(release(), fc_delete<A>(a_));
}
private:
typedef typename fc_pointer<A>::type pointer;
pointer release() BOOST_NOEXCEPT {
pointer p = p_;
p_ = pointer();
return p;
}
fc_allocate(const fc_allocate&);
fc_allocate& operator=(const fc_allocate&);
A a_;
pointer p_;
};
} /* detail */
template<class Pointer, class Allocator = void,
factory_alloc_propagation Policy = factory_alloc_for_pointee_and_deleter>
class factory;
template<class Pointer, factory_alloc_propagation Policy>
class factory<Pointer, void, Policy> {
public:
typedef typename remove_cv<Pointer>::type result_type;
private:
typedef typename pointer_traits<result_type>::element_type type;
public:
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args>
result_type operator()(Args&&... args) const {
return result_type(new type(std::forward<Args>(args)...));
}
#else
result_type operator()() const {
return result_type(new type());
}
template<class A0>
result_type operator()(A0& a0) const {
return result_type(new type(a0));
}
template<class A0, class A1>
result_type operator()(A0& a0, A1& a1) const {
return result_type(new type(a0, a1));
}
template<class A0, class A1, class A2>
result_type operator()(A0& a0, A1& a1, A2& a2) const {
return result_type(new type(a0, a1, a2));
}
template<class A0, class A1, class A2, class A3>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const {
return result_type(new type(a0, a1, a2, a3));
}
template<class A0, class A1, class A2, class A3, class A4>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const {
return result_type(new type(a0, a1, a2, a3, a4));
}
template<class A0, class A1, class A2, class A3, class A4, class A5>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4,
A5& a5) const {
return result_type(new type(a0, a1, a2, a3, a4, a5));
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6) const {
return result_type(new type(a0, a1, a2, a3, a4, a5, a6));
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7) const {
return result_type(new type(a0, a1, a2, a3, a4, a5, a6, a7));
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7, A8& a8) const {
return result_type(new type(a0, a1, a2, a3, a4, a5, a6, a7, a8));
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7, A8& a8, A9& a9) const {
return result_type(new type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9));
}
#endif
};
template<class Pointer, class Allocator, factory_alloc_propagation Policy>
class factory
: empty_value<typename detail::fc_rebind<Allocator,
typename pointer_traits<typename
remove_cv<Pointer>::type>::element_type>::type> {
public:
typedef typename remove_cv<Pointer>::type result_type;
private:
typedef typename pointer_traits<result_type>::element_type type;
typedef typename detail::fc_rebind<Allocator, type>::type allocator;
typedef empty_value<allocator> base;
public:
factory() BOOST_NOEXCEPT
: base(empty_init_t()) { }
explicit factory(const Allocator& a) BOOST_NOEXCEPT
: base(empty_init_t(), a) { }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args>
result_type operator()(Args&&... args) const {
detail::fc_allocate<result_type, allocator> s(base::get());
detail::fc_construct(s.state(), s.get(), std::forward<Args>(args)...);
return s.release(detail::fc_tag<Policy>());
}
#else
result_type operator()() const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type();
return s.release(detail::fc_tag<Policy>());
}
template<class A0>
result_type operator()(A0& a0) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1>
result_type operator()(A0& a0, A1& a1) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2>
result_type operator()(A0& a0, A1& a1, A2& a2) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4,
A5& a5) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7, A8& a8) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7, a8);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7, A8& a8, A9& a9) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
return s.release(detail::fc_tag<Policy>());
}
#endif
};
template<class Pointer, class Allocator, factory_alloc_propagation Policy>
class factory<Pointer&, Allocator, Policy> { };
} /* boost */
#endif

View File

@@ -0,0 +1,501 @@
/*=============================================================================
Copyright (c) 2007-2008 Tobias Schwinger
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).
==============================================================================*/
#ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
# ifndef BOOST_PP_IS_ITERATING
# include <boost/config.hpp>
# include <boost/config/workaround.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
# include <boost/preprocessor/facilities/intercept.hpp>
# include <boost/preprocessor/arithmetic/dec.hpp>
# include <boost/utility/result_of.hpp>
# ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY
# define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 6
# elif BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY < 3
# undef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY
# define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 3
# endif
namespace boost
{
template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
class forward_adapter;
//----- ---- --- -- - - - -
namespace detail
{
template< class MostDerived, typename Function, typename FunctionConst,
int Arity, int MinArity >
struct forward_adapter_impl;
struct forward_adapter_result
{
template< typename Sig > struct apply;
// Utility metafunction for qualification adjustment on arguments
template< typename T > struct q { typedef T const t; };
template< typename T > struct q<T const> { typedef T const t; };
template< typename T > struct q<T &> { typedef T t; };
// Utility metafunction to choose target function qualification
template< typename T > struct c
{ typedef typename T::target_function_t t; };
template< typename T > struct c<T& >
{ typedef typename T::target_function_t t; };
template< typename T > struct c<T const >
{ typedef typename T::target_function_const_t t; };
template< typename T > struct c<T const&>
{ typedef typename T::target_function_const_t t; };
};
}
# define BOOST_TMP_MACRO(f,fn,fc) \
boost::detail::forward_adapter_impl< \
forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
(MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
:BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY), \
(Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
template< typename Function, int Arity_Or_MinArity, int MaxArity >
class forward_adapter
: public BOOST_TMP_MACRO(Function,Function,Function const)
, private Function
{
public:
forward_adapter(Function const& f = Function())
: Function(f)
{ }
typedef Function target_function_t;
typedef Function const target_function_const_t;
Function & target_function() { return *this; }
Function const & target_function() const { return *this; }
template< typename Sig > struct result
: detail::forward_adapter_result::template apply<Sig>
{ };
using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
};
template< typename Function, int Arity_Or_MinArity, int MaxArity >
class forward_adapter< Function const, Arity_Or_MinArity, MaxArity >
: public BOOST_TMP_MACRO(Function const, Function const, Function const)
, private Function
{
public:
forward_adapter(Function const& f = Function())
: Function(f)
{ }
typedef Function const target_function_t;
typedef Function const target_function_const_t;
Function const & target_function() const { return *this; }
template< typename Sig > struct result
: detail::forward_adapter_result::template apply<Sig>
{ };
using BOOST_TMP_MACRO(Function const,Function const, Function const)
::operator();
};
template< typename Function, int Arity_Or_MinArity, int MaxArity >
class forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
: public BOOST_TMP_MACRO(Function&, Function, Function)
{
Function& ref_function;
public:
forward_adapter(Function& f)
: ref_function(f)
{ }
typedef Function target_function_t;
typedef Function target_function_const_t;
Function & target_function() const { return this->ref_function; }
template< typename Sig > struct result
: detail::forward_adapter_result::template apply<Sig>
{ };
using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
};
#undef BOOST_TMP_MACRO
namespace detail
{
template< class Self >
struct forward_adapter_result::apply< Self() >
: boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
{ };
// WHen operator()() doesn't have any parameters, it can't
// be templatized and can't use SFINAE, so intead use class
// template parameter SFINAE to decide whether to instantiate it.
template <typename T, typename R = void>
struct forward_adapter_sfinae
{
typedef T type;
};
// This is the fallback for when there isn't an operator()(),
// need to create an operator() that will never instantiate
// so that using parent::operator() will work okay.
template< class MD, class F, class FC, class Enable = void>
struct forward_adapter_impl_zero
{
template <typename T> struct never_instantiate {};
template <typename T>
typename never_instantiate<T>::type operator()(T) const {}
};
template< class MD, class F, class FC>
struct forward_adapter_impl_zero<MD, F, FC,
typename forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
{
inline typename boost::result_of< FC() >::type
operator()() const
{
return static_cast<MD const*>(this)->target_function()();
}
inline typename boost::result_of< F() >::type
operator()()
{
return static_cast<MD*>(this)->target_function()();
}
};
template< class MD, class F, class FC >
struct forward_adapter_impl<MD,F,FC,0,0>
: forward_adapter_impl_zero<MD,F,FC>
{
using forward_adapter_impl_zero<MD,F,FC>::operator();
// closing brace gets generated by preprocessing code, below
# define BOOST_TMP_MACRO(tpl_params,arg_types,params,args) \
template< tpl_params > \
inline typename boost::result_of< FC(arg_types) >::type \
operator()(params) const \
{ \
return static_cast<MD const*>(this)->target_function()(args); \
} \
template< tpl_params > \
inline typename boost::result_of< F(arg_types)>::type \
operator()(params) \
{ \
return static_cast<MD*>(this)->target_function()(args); \
}
# // This is the total number of iterations we need
# define count ((1 << BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY+1)-2)
# // Chain file iteration to virtually one loop
# if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 7
# define limit1 count
# define limit2 0
# define limit3 0
# else
# if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 15
# define limit1 (count >> 8)
# define limit2 255
# define limit3 0
# else
# define limit1 (count >> 16)
# define limit2 255
# define limit3 255
# endif
# endif
# define N 0
# define BOOST_PP_FILENAME_1 <boost/functional/forward_adapter.hpp>
# define BOOST_PP_ITERATION_LIMITS (0,limit1)
# include BOOST_PP_ITERATE()
# undef N
# undef limit3
# undef limit2
# undef limit1
# undef count
# undef BOOST_TMP_MACRO
};
} // namespace detail
template<class F, int A0, int A1>
struct result_of<boost::forward_adapter<F,A0,A1> const ()>
: boost::detail::forward_adapter_result::template apply<
boost::forward_adapter<F,A0,A1> const () >
{ };
template<class F, int A0, int A1>
struct result_of<boost::forward_adapter<F,A0,A1>()>
: boost::detail::forward_adapter_result::template apply<
boost::forward_adapter<F,A0,A1>() >
{ };
template<class F, int A0, int A1>
struct result_of<boost::forward_adapter<F,A0,A1> const& ()>
: boost::detail::forward_adapter_result::template apply<
boost::forward_adapter<F,A0,A1> const () >
{ };
template<class F, int A0, int A1>
struct result_of<boost::forward_adapter<F,A0,A1>& ()>
: boost::detail::forward_adapter_result::template apply<
boost::forward_adapter<F,A0,A1>() >
{ };
}
# define BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
# elif BOOST_PP_ITERATION_DEPTH() == 1 && limit2
# define BOOST_PP_FILENAME_2 <boost/functional/forward_adapter.hpp>
# define BOOST_PP_ITERATION_LIMITS (0,limit2)
# include BOOST_PP_ITERATE()
# elif BOOST_PP_ITERATION_DEPTH() == 2 && limit3
# define BOOST_PP_FILENAME_3 <boost/functional/forward_adapter.hpp>
# define BOOST_PP_ITERATION_LIMITS (0,limit3)
# include BOOST_PP_ITERATE()
# else
# // I is the loop counter
# if limit2 && limit3
# define I (BOOST_PP_ITERATION_1 << 16 | BOOST_PP_ITERATION_2 << 8 | \
BOOST_PP_ITERATION_3)
# elif limit2
# define I (BOOST_PP_ITERATION_1 << 8 | BOOST_PP_ITERATION_2)
# else
# define I BOOST_PP_ITERATION_1
# endif
# if I < count
# // Done for this arity? Increment N
# if (I+2 >> N+1)
# if N == 0
# undef N
# define N 1
# elif N == 1
# undef N
# define N 2
# elif N == 2
# undef N
# define N 3
# elif N == 3
# undef N
# define N 4
# elif N == 4
# undef N
# define N 5
# elif N == 5
# undef N
# define N 6
# elif N == 6
# undef N
# define N 7
# elif N == 7
# undef N
# define N 8
# elif N == 8
# undef N
# define N 9
# elif N == 9
# undef N
# define N 10
# elif N == 10
# undef N
# define N 11
# elif N == 11
# undef N
# define N 12
# elif N == 12
# undef N
# define N 13
# elif N == 13
# undef N
# define N 14
# elif N == 14
# undef N
# define N 15
# elif N == 15
# undef N
# define N 16
# endif
};
template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
struct forward_adapter_result::apply< Self(BOOST_PP_ENUM_PARAMS(N,T)) >
: boost::result_of<
BOOST_DEDUCED_TYPENAME c<Self>::t(BOOST_PP_ENUM_BINARY_PARAMS(N,
typename q<T,>::t& BOOST_PP_INTERCEPT)) >
{ };
template< class MD, class F, class FC >
struct forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
{
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
inline typename boost::result_of< F(
BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
};
template< class MD, class F, class FC, int MinArity >
struct forward_adapter_impl<MD,F,FC,N,MinArity>
: forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
{
using forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>::operator();
# endif
# // Zero based count for each arity would be I-(1<<N)+2, but we don't
# // need it, unless we need a nicer order.
# // Macros for the parameter's type modifiers.
# if I & 0x000001
# define PT0 T0 &
# else
# define PT0 T0 const &
# endif
# if I & 0x000002
# define PT1 T1 &
# else
# define PT1 T1 const &
# endif
# if I & 0x000004
# define PT2 T2 &
# else
# define PT2 T2 const &
# endif
# if I & 0x000008
# define PT3 T3 &
# else
# define PT3 T3 const &
# endif
# if I & 0x000010
# define PT4 T4 &
# else
# define PT4 T4 const &
# endif
# if I & 0x000020
# define PT5 T5 &
# else
# define PT5 T5 const &
# endif
# if I & 0x000040
# define PT6 T6 &
# else
# define PT6 T6 const &
# endif
# if I & 0x000080
# define PT7 T7 &
# else
# define PT7 T7 const &
# endif
# if I & 0x000100
# define PT8 T8 &
# else
# define PT8 T8 const &
# endif
# if I & 0x000200
# define PT9 T9 &
# else
# define PT9 T9 const &
# endif
# if I & 0x000400
# define PT10 T10 &
# else
# define PT10 T10 const &
# endif
# if I & 0x000800
# define PT11 T11 &
# else
# define PT11 T11 const &
# endif
# if I & 0x001000
# define PT12 T12 &
# else
# define PT12 T12 const &
# endif
# if I & 0x002000
# define PT13 T13 &
# else
# define PT13 T13 const &
# endif
# if I & 0x004000
# define PT14 T14 &
# else
# define PT14 T14 const &
# endif
# if I & 0x008000
# define PT15 T15 &
# else
# define PT15 T15 const &
# endif
# if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
inline typename boost::result_of< FC(BOOST_PP_ENUM_PARAMS(N,PT))
>::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const
{
return static_cast<MD const* const>(this)
->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
}
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
inline typename boost::result_of< F(BOOST_PP_ENUM_PARAMS(N,PT))
>::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a))
{
return static_cast<MD* const>(this)
->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
}
# else
BOOST_TMP_MACRO(BOOST_PP_ENUM_PARAMS(N,typename T),
BOOST_PP_ENUM_PARAMS(N,PT), BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a),
BOOST_PP_ENUM_PARAMS(N,a) )
// ...generates uglier code but is faster - it caches ENUM_*
# endif
# undef PT0
# undef PT1
# undef PT2
# undef PT3
# undef PT4
# undef PT5
# undef PT6
# undef PT7
# undef PT8
# undef PT9
# undef PT10
# undef PT11
# undef PT12
# undef PT13
# undef PT14
# undef PT15
# endif // I < count
# undef I
# endif // defined(BOOST_PP_IS_ITERATING)
#endif // include guard

View File

@@ -0,0 +1,61 @@
/*
Copyright 2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_FUNCTIONAL_IDENTITY_HPP
#define BOOST_FUNCTIONAL_IDENTITY_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <utility>
#endif
namespace boost {
struct identity {
typedef void is_transparent;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class T>
BOOST_CONSTEXPR T&& operator()(T&& value) const BOOST_NOEXCEPT {
return std::forward<T>(value);
}
#else
template<class T>
BOOST_CONSTEXPR const T& operator()(const T& value) const BOOST_NOEXCEPT {
return value;
}
template<class T>
BOOST_CONSTEXPR T& operator()(T& value) const BOOST_NOEXCEPT {
return value;
}
#endif
template<class>
struct result { };
template<class T>
struct result<identity(T&)> {
typedef T& type;
};
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class T>
struct result<identity(T)> {
typedef T&& type;
};
template<class T>
struct result<identity(T&&)> {
typedef T&& type;
};
#endif
};
} // boost
#endif

View File

@@ -0,0 +1,288 @@
/*=============================================================================
Copyright (c) 2007 Tobias Schwinger
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).
==============================================================================*/
#ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
# ifndef BOOST_PP_IS_ITERATING
# include <boost/config.hpp>
# include <boost/config/workaround.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
# include <boost/preprocessor/repetition/enum.hpp>
# include <boost/preprocessor/repetition/enum_params.hpp>
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
# include <boost/preprocessor/facilities/intercept.hpp>
# include <boost/utility/result_of.hpp>
# include <boost/ref.hpp>
# ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 10
# elif BOOST_FUNCTIONAL_FORDWARD_ADAPTER_MAX_ARITY < 3
# undef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 3
# endif
namespace boost
{
template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
class lightweight_forward_adapter;
//----- ---- --- -- - - - -
namespace detail
{
template< class MostDerived, typename Function, typename FunctionConst,
int Arity, int MinArity >
struct lightweight_forward_adapter_impl;
struct lightweight_forward_adapter_result
{
template< typename Sig > struct apply;
// Utility metafunction for argument transform
template< typename T > struct x { typedef T const& t; };
template< typename T > struct x< boost::reference_wrapper<T> >
{ typedef T& t; };
template< typename T > struct x<T&> : x<T> { };
template< typename T > struct x<T const&> : x<T> { };
template< typename T > struct x<T const> : x<T> { };
// Utility metafunction to choose target function qualification
template< typename T > struct c
{ typedef typename T::target_function_t t; };
template< typename T > struct c<T& >
{ typedef typename T::target_function_t t; };
template< typename T > struct c<T const >
{ typedef typename T::target_function_const_t t; };
template< typename T > struct c<T const&>
{ typedef typename T::target_function_const_t t; };
};
}
# define BOOST_TMP_MACRO(f,fn,fc) \
boost::detail::lightweight_forward_adapter_impl< \
lightweight_forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
(MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
:BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY), \
(Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
template< typename Function, int Arity_Or_MinArity, int MaxArity >
class lightweight_forward_adapter
: public BOOST_TMP_MACRO(Function,Function,Function const)
, private Function
{
public:
lightweight_forward_adapter(Function const& f = Function())
: Function(f)
{ }
typedef Function target_function_t;
typedef Function const target_function_const_t;
Function & target_function() { return *this; }
Function const & target_function() const { return *this; }
template< typename Sig > struct result
: detail::lightweight_forward_adapter_result::template apply<Sig>
{ };
using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
};
template< typename Function, int Arity_Or_MinArity, int MaxArity >
class lightweight_forward_adapter< Function const, Arity_Or_MinArity,
MaxArity >
: public BOOST_TMP_MACRO(Function const, Function const, Function const)
, private Function
{
public:
lightweight_forward_adapter(Function const& f = Function())
: Function(f)
{ }
typedef Function const target_function_t;
typedef Function const target_function_const_t;
Function const & target_function() const { return *this; }
template< typename Sig > struct result
: detail::lightweight_forward_adapter_result::template apply<Sig>
{ };
using BOOST_TMP_MACRO(Function const,Function const, Function const)
::operator();
};
template< typename Function, int Arity_Or_MinArity, int MaxArity >
class lightweight_forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
: public BOOST_TMP_MACRO(Function&, Function, Function)
{
Function& ref_function;
public:
lightweight_forward_adapter(Function& f)
: ref_function(f)
{ }
typedef Function target_function_t;
typedef Function target_function_const_t;
Function & target_function() const { return this->ref_function; }
template< typename Sig > struct result
: detail::lightweight_forward_adapter_result::template apply<Sig>
{ };
using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
};
#undef BOOST_TMP_MACRO
namespace detail
{
template< class Self >
struct lightweight_forward_adapter_result::apply< Self() >
: boost::result_of< BOOST_DEDUCED_TYPENAME c<Self>::t() >
{ };
// When operator() doesn't have any parameters, it can't
// be templatized and can't use SFINAE, so intead use class
// template parameter SFINAE to decide whether to instantiate it.
template <typename T, typename R = void>
struct lightweight_forward_adapter_sfinae
{
typedef T type;
};
// This is the fallback for when there isn't an operator()(),
// need to create an operator() that will never instantiate
// so that using parent::operator() will work okay.
template< class MD, class F, class FC, class Enable = void>
struct lightweight_forward_adapter_impl_zero
: lightweight_forward_adapter_result
{
template <typename T> struct never_instantiate {};
template <typename T>
typename never_instantiate<T>::type operator()(T) const {}
};
template< class MD, class F, class FC>
struct lightweight_forward_adapter_impl_zero<MD, F, FC,
typename lightweight_forward_adapter_sfinae<typename boost::result_of< FC() >::type>::type>
: lightweight_forward_adapter_result
{
inline typename boost::result_of< FC() >::type
operator()() const
{
return static_cast<MD const*>(this)->target_function()();
}
inline typename boost::result_of< F() >::type
operator()()
{
return static_cast<MD*>(this)->target_function()();
}
};
template< class MD, class F, class FC >
struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
: lightweight_forward_adapter_impl_zero<MD,F,FC>
{
};
# define BOOST_PP_FILENAME_1 \
<boost/functional/lightweight_forward_adapter.hpp>
# define BOOST_PP_ITERATION_LIMITS \
(1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY)
# include BOOST_PP_ITERATE()
} // namespace detail
template<class F, int A0, int A1>
struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const ()>
: boost::detail::lightweight_forward_adapter_result::template apply<
boost::lightweight_forward_adapter<F,A0,A1> const () >
{ };
template<class F, int A0, int A1>
struct result_of<boost::lightweight_forward_adapter<F,A0,A1>()>
: boost::detail::lightweight_forward_adapter_result::template apply<
boost::lightweight_forward_adapter<F,A0,A1>() >
{ };
template<class F, int A0, int A1>
struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const& ()>
: boost::detail::lightweight_forward_adapter_result::template apply<
boost::lightweight_forward_adapter<F,A0,A1> const () >
{ };
template<class F, int A0, int A1>
struct result_of<boost::lightweight_forward_adapter<F,A0,A1>& ()>
: boost::detail::lightweight_forward_adapter_result::template apply<
boost::lightweight_forward_adapter<F,A0,A1>() >
{ };
}
# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
# else // defined(BOOST_PP_IS_ITERATING)
# define N BOOST_PP_ITERATION()
template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
struct lightweight_forward_adapter_result::apply<
Self (BOOST_PP_ENUM_PARAMS(N,T)) >
: boost::result_of<
BOOST_DEDUCED_TYPENAME c<Self>::t (BOOST_PP_ENUM_BINARY_PARAMS(N,
typename x<T,>::t BOOST_PP_INTERCEPT)) >
{ };
template< class MD, class F, class FC >
struct lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
: lightweight_forward_adapter_result
{
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
inline typename boost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N,
T,const& BOOST_PP_INTERCEPT)) >::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
};
template< class MD, class F, class FC, int MinArity >
struct lightweight_forward_adapter_impl<MD,F,FC,N,MinArity>
: lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
{
using lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),
MinArity>::operator();
# define M(z,i,d) \
static_cast<typename d::template x<T##i>::t>(a##i)
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
inline typename lightweight_forward_adapter_result::template apply<
MD const (BOOST_PP_ENUM_BINARY_PARAMS(N,
T,const& BOOST_PP_INTERCEPT)) >::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const
{
typedef lightweight_forward_adapter_result _;
return static_cast<MD const*>(this)->target_function()(
BOOST_PP_ENUM(N,M,_));
}
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
inline typename lightweight_forward_adapter_result::template apply<
MD (BOOST_PP_ENUM_BINARY_PARAMS(N,
T,const& BOOST_PP_INTERCEPT)) >::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a))
{
typedef lightweight_forward_adapter_result _;
return static_cast<MD*>(this)->target_function()(
BOOST_PP_ENUM(N,M,_));
}
# undef M
};
# undef N
# endif // defined(BOOST_PP_IS_ITERATING)
#endif // include guard

View File

@@ -0,0 +1,311 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/functional/overloaded_function
#ifndef DOXYGEN // Doxygen documentation only.
#if !BOOST_PP_IS_ITERATING
# ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_HPP_
# define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_HPP_
# include <boost/functional/overloaded_function/detail/base.hpp>
# include <boost/functional/overloaded_function/detail/function_type.hpp>
# include <boost/functional/overloaded_function/config.hpp>
# include <boost/typeof/typeof.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
# include <boost/preprocessor/repetition/enum.hpp>
# include <boost/preprocessor/repetition/repeat.hpp>
# include <boost/preprocessor/control/expr_iif.hpp>
# include <boost/preprocessor/control/expr_if.hpp>
# include <boost/preprocessor/comparison/greater.hpp>
# include <boost/preprocessor/comparison/less.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/arithmetic/add.hpp>
# include <boost/preprocessor/arithmetic/sub.hpp>
# include <boost/preprocessor/tuple/eat.hpp>
# include <boost/preprocessor/logical/and.hpp>
# include <boost/preprocessor/logical/not.hpp>
# include <boost/preprocessor/facilities/expand.hpp>
#define BOOST_FUNCTIONAL_f_type(z, n, unused) \
BOOST_PP_CAT(F, n)
#define BOOST_FUNCTIONAL_f_arg(z, n, unused) \
BOOST_PP_CAT(f, n)
#define BOOST_FUNCTIONAL_f_tparam(z, n, unused) \
typename BOOST_FUNCTIONAL_f_type(z, n, ~) \
#define BOOST_FUNCTIONAL_f_tparam_dflt(z, n, is_tspec) \
BOOST_FUNCTIONAL_f_tparam(z, n, ~) \
/* overload requires at least 2 functors so F0 and F1 not optional */ \
BOOST_PP_EXPR_IIF(BOOST_PP_AND(BOOST_PP_NOT(is_tspec), \
BOOST_PP_GREATER(n, 1)), \
= void \
)
#define BOOST_FUNCTIONAL_f_arg_decl(z, n, unused) \
BOOST_FUNCTIONAL_f_type(z, n, ~) /* no qualifier to deduce tparam */ \
BOOST_FUNCTIONAL_f_arg(z, n, ~)
#define BOOST_FUNCTIONAL_g_type(z, n, unused) \
BOOST_PP_CAT(G, n)
#define BOOST_FUNCTIONAL_g_arg(z, n, unused) \
BOOST_PP_CAT(g, n)
#define BOOST_FUNCTIONAL_g_tparam(z, n, unused) \
typename BOOST_FUNCTIONAL_g_type(z, n, ~)
#define BOOST_FUNCTIONAL_g_arg_decl(z, n, unused) \
BOOST_FUNCTIONAL_g_type(z, n, ~) /* no qualifier to deduce tparam */ \
BOOST_FUNCTIONAL_g_arg(z, n, ~)
#define BOOST_FUNCTIONAL_base(z, n, unused) \
::boost::overloaded_function_detail::base< \
BOOST_FUNCTIONAL_f_type(z, n, ~) \
>
#define BOOST_FUNCTIONAL_inherit(z, n, unused) \
public BOOST_FUNCTIONAL_base(z, n, ~)
#define BOOST_FUNCTIONAL_base_init(z, n, unused) \
BOOST_FUNCTIONAL_base(z, n, ~)(BOOST_FUNCTIONAL_g_arg(z, n, ~))
#define BOOST_FUNCTIONAL_using_operator_call(z, n, unused) \
using BOOST_FUNCTIONAL_base(z, n, ~)::operator();
#define BOOST_FUNCTIONAL_function_type(z, n, unused) \
typename ::boost::overloaded_function_detail::function_type< \
BOOST_FUNCTIONAL_f_type(z, n, ~) \
>::type
# define BOOST_PP_ITERATION_PARAMS_1 \
/* at least 2 func to overload so start from 2 to MAX */ \
/* (cannot iterate [0, MAX-2) because error on Sun) */ \
(3, (2, BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX, \
"boost/functional/overloaded_function.hpp"))
# include BOOST_PP_ITERATE() // Iterate over function arity.
#undef BOOST_FUNCTIONAL_f_type
#undef BOOST_FUNCTIONAL_f_arg
#undef BOOST_FUNCTIONAL_f_tparam
#undef BOOST_FUNCTIONAL_f_arg_decl
#undef BOOST_FUNCTIONAL_f_tparam_dflt
#undef BOOST_FUNCTIONAL_g_type
#undef BOOST_FUNCTIONAL_g_arg
#undef BOOST_FUNCTIONAL_g_tparam
#undef BOOST_FUNCTIONAL_g_arg_decl
#undef BOOST_FUNCTIONAL_base
#undef BOOST_FUNCTIONAL_inherit
#undef BOOST_FUNCTIONAL_base_init
#undef BOOST_FUNCTIONAL_using_operator_call
#undef BOOST_FUNCTIONAL_function_type
# endif // #include guard
#elif BOOST_PP_ITERATION_DEPTH() == 1
# define BOOST_FUNCTIONAL_overloads \
/* iterate as OVERLOADS, OVERLOADS-1, OVERLOADS-2, ... */ \
/* (add 2 because iteration started from 2 to MAX) */ \
BOOST_PP_ADD(2, BOOST_PP_SUB( \
BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX, \
BOOST_PP_FRAME_ITERATION(1)))
# define BOOST_FUNCTIONAL_is_tspec \
/* if template specialization */ \
BOOST_PP_LESS(BOOST_FUNCTIONAL_overloads, \
BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX)
// For type-of emulation: This must be included at this pp iteration level.
# include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
namespace boost {
template<
BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_tparam_dflt,
BOOST_FUNCTIONAL_is_tspec)
>
class overloaded_function
// Template specialization.
BOOST_PP_EXPR_IIF(BOOST_PP_EXPAND(BOOST_FUNCTIONAL_is_tspec), <)
BOOST_PP_IIF(BOOST_FUNCTIONAL_is_tspec,
BOOST_PP_ENUM
,
BOOST_PP_TUPLE_EAT(3)
)(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_type, ~)
BOOST_PP_EXPR_IIF(BOOST_PP_EXPAND(BOOST_FUNCTIONAL_is_tspec), >)
// Bases (overloads >= 2 so always at least 2 bases).
: BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads,
BOOST_FUNCTIONAL_inherit, ~)
{
public:
template<
BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_g_tparam, ~)
> /* implicit */ inline overloaded_function(
BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads,
BOOST_FUNCTIONAL_g_arg_decl, ~))
// Overloads >= 2 so always at least 2 bases to initialize.
: BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads,
BOOST_FUNCTIONAL_base_init, ~)
{}
BOOST_PP_REPEAT(BOOST_FUNCTIONAL_overloads,
BOOST_FUNCTIONAL_using_operator_call, ~)
};
template<
BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_tparam, ~)
>
overloaded_function<
BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_function_type, ~)
> make_overloaded_function(
BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_arg_decl, ~)
) {
return overloaded_function<
BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads,
BOOST_FUNCTIONAL_function_type, ~)
>(BOOST_PP_ENUM(BOOST_FUNCTIONAL_overloads, BOOST_FUNCTIONAL_f_arg, ~));
}
} // namespace
// For type-of emulation: Register overloaded function type (for _AUTO, etc).
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::overloaded_function,
BOOST_FUNCTIONAL_overloads)
# undef BOOST_FUNCTIONAL_overloads
# undef BOOST_FUNCTIONAL_is_tspec
#endif // iteration
// DOCUMENTATION //
#else // DOXYGEN
/** @file
@brief Overload distinct function pointers, function references, and
monomorphic function objects into a single function object.
*/
namespace boost {
/**
@brief Function object to overload functions with distinct signatures.
This function object aggregates together calls to functions of all the
specified function types <c>F1</c>, <c>F2</c>, etc which must have distinct
function signatures from one another.
@Params
@Param{F<em>i</em>,
Each function type must be specified using the following syntax (which is
Boost.Function's preferred syntax):
@code
result_type (argument1_type\, argumgnet2_type\, ...)
@endcode
}
@EndParams
In some cases, the @RefFunc{make_overloaded_function} function template can be
useful to construct an overloaded function object without explicitly
specifying the function types.
At least two distinct function types must be specified (because there is
nothing to overload between one or zero functions).
The maximum number of functions to overload is given by the
@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX}
configuration macro.
The maximum number of function parameters for each of the specified function
types is given by the
@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX}
configuration macro.
@See @RefSect{tutorial, Tutorial} section, @RefFunc{make_overloaded_function},
@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX},
@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX},
Boost.Function.
*/
template<typename F1, typename F2, ...>
class overloaded_function {
public:
/**
@brief Construct the overloaded function object.
Any function pointer, function reference, and monomorphic function object
that can be converted to a <c>boost::function</c> function object can be
specified as parameter.
@Note Unfortunately, it is not possible to support polymorphic function
objects (as explained <a
href="http://lists.boost.org/Archives/boost/2012/03/191744.php">here</a>).
*/
overloaded_function(const boost::function<F1>&,
const boost::function<F2>&, ...);
/**
@brief Call operator matching the signature of the function type specified
as 1st template parameter.
This will in turn invoke the call operator of the 1st function passed to
the constructor.
*/
typename boost::function_traits<F1>::result_type operator()(
typename boost::function_traits<F1>::arg1_type,
typename boost::function_traits<F1>::arg2_type,
...) const;
/**
@brief Call operator matching the signature of the function type specified
as 2nd template parameter.
This will in turn invoke the call operator of the 2nd function passed to
the constructor.
@Note Similar call operators are present for all specified function types
<c>F1</c>, <c>F2</c>, etc (even if not exhaustively listed by this
documentation).
*/
typename boost::function_traits<F2>::result_type operator()(
typename boost::function_traits<F2>::arg1_type,
typename boost::function_traits<F2>::arg2_type,
...) const;
};
/**
@brief Make an overloaded function object without explicitly specifying the
function types.
This function template creates and returns an @RefClass{overloaded_function}
object that overloads all the specified functions <c>f1</c>, <c>f2</c>, etc.
The function types are internally determined from the template parameter types
so they do not need to be explicitly specified.
Therefore, this function template usually has a more concise syntax when
compared with @RefClass{overloaded_function}.
This is especially useful when the explicit type of the returned
@RefClass{overloaded_function} object does not need to be known (e.g., when
used with Boost.Typeof's <c>BOOST_AUTO</c>, C++11 <c>auto</c>, or when the
overloaded function object is handled using a function template parameter, see
the @RefSect{tutorial, Tutorial} section).
The maximum number of functions to overload is given by the
@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX}
configuration macro.
@Note In this documentation, <c>__function_type__</c> is a placeholder for a
symbol that is specific to the implementation of this library.
@See @RefSect{tutorial, Tutorial} section, @RefClass{overloaded_function},
@RefMacro{BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX}.
*/
template<typename F1, typename F2, ...>
overloaded_function<
__function_type__<F1>, __function_type__<F2>, ...
> make_overloaded_function(F1 f1, F2 f2, ...);
} // namespace
#endif // DOXYGEN

View File

@@ -0,0 +1,50 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/functional/overloaded_function
#ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_HPP_
#define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_HPP_
/** @file
@brief Change the compile-time configuration of this library.
*/
/**
@brief Specify the maximum number of arguments of the functions being
overloaded.
If this macro is left undefined by the user, it has a default value of 5
(increasing this number might increase compilation time).
When specified by the user, this macro must be a non-negative integer number.
@See @RefSect{getting_started, Getting Started},
@RefClass{boost::overloaded_function}.
*/
#ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX
# define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX 5
#endif
/**
@brief Specify the maximum number of functions that can be overloaded.
If this macro is left undefined by the user, it has a default value of 5
(increasing this number might increase compilation time).
When defined by the user, this macro must be an integer number greater or
equal than 2 (because at least two distinct functions need to be specified in
order to define an overload).
@See @RefSect{getting_started, Getting Started},
@RefClass{boost::overloaded_function}.
*/
#ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX
# define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX 5
#endif
#if BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX < 2
# error "maximum overload macro cannot be less than 2"
#endif
#endif // #include guard

View File

@@ -0,0 +1,86 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/functional/overloaded_function
#if !BOOST_PP_IS_ITERATING
# ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_BASE_HPP_
# define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_BASE_HPP_
# include <boost/functional/overloaded_function/config.hpp>
# include <boost/function.hpp>
# include <boost/preprocessor/iteration/iterate.hpp>
# include <boost/preprocessor/repetition/enum.hpp>
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/comma_if.hpp>
#define BOOST_FUNCTIONAL_DETAIL_arg_type(z, n, unused) \
BOOST_PP_CAT(A, n)
#define BOOST_FUNCTIONAL_DETAIL_arg_name(z, n, unused) \
BOOST_PP_CAT(a, n)
#define BOOST_FUNCTIONAL_DETAIL_arg_tparam(z, n, unused) \
typename BOOST_FUNCTIONAL_DETAIL_arg_type(z, n, unused)
#define BOOST_FUNCTIONAL_DETAIL_arg(z, n, unused) \
BOOST_FUNCTIONAL_DETAIL_arg_type(z, n, unused) \
BOOST_FUNCTIONAL_DETAIL_arg_name(z, n, unused)
#define BOOST_FUNCTIONAL_DETAIL_f \
R (BOOST_PP_ENUM(BOOST_FUNCTIONAL_DETAIL_arity, \
BOOST_FUNCTIONAL_DETAIL_arg_type, ~))
// Do not use namespace ::detail because overloaded_function is already a class.
namespace boost { namespace overloaded_function_detail {
template<typename F>
class base {}; // Empty template cannot be used directly (only its spec).
# define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX, \
"boost/functional/overloaded_function/detail/base.hpp"))
# include BOOST_PP_ITERATE() // Iterate over funciton arity.
} } // namespace
#undef BOOST_FUNCTIONAL_DETAIL_arg_type
#undef BOOST_FUNCTIONAL_DETAIL_arg_name
#undef BOOST_FUNCTIONAL_DETAIL_arg_tparam
#undef BOOST_FUNCTIONAL_DETAIL_arg
#undef BOOST_FUNCTIONAL_DETAIL_f
# endif // #include guard
#elif BOOST_PP_ITERATION_DEPTH() == 1
# define BOOST_FUNCTIONAL_DETAIL_arity BOOST_PP_FRAME_ITERATION(1)
template<
typename R
BOOST_PP_COMMA_IF(BOOST_FUNCTIONAL_DETAIL_arity)
BOOST_PP_ENUM(BOOST_FUNCTIONAL_DETAIL_arity,
BOOST_FUNCTIONAL_DETAIL_arg_tparam, ~)
>
class base< BOOST_FUNCTIONAL_DETAIL_f > {
public:
/* implicit */ inline base(
// This requires specified type to be implicitly convertible to
// a boost::function<> functor.
boost::function< BOOST_FUNCTIONAL_DETAIL_f > const& f): f_(f)
{}
inline R operator()(BOOST_PP_ENUM(BOOST_FUNCTIONAL_DETAIL_arity,
BOOST_FUNCTIONAL_DETAIL_arg, ~)) const {
return f_(BOOST_PP_ENUM(BOOST_FUNCTIONAL_DETAIL_arity,
BOOST_FUNCTIONAL_DETAIL_arg_name, ~));
}
private:
boost::function< BOOST_FUNCTIONAL_DETAIL_f > const f_;
};
# undef BOOST_FUNCTIONAL_DETAIL_arity
#endif // iteration

View File

@@ -0,0 +1,85 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/functional/overloaded_function
#ifndef BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_FUNCTION_TYPE_HPP_
#define BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_DETAIL_FUNCTION_TYPE_HPP_
#include <boost/function_types/is_function.hpp>
#include <boost/function_types/is_function_pointer.hpp>
#include <boost/function_types/is_function_reference.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/function.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/typeof/typeof.hpp>
// Do not use namespace ::detail because overloaded_function is already a class.
namespace boost { namespace overloaded_function_detail {
// Requires: F is a monomorphic functor (i.e., has non-template `operator()`).
// Returns: F's function type `result_type (arg1_type, arg2_type, ...)`.
// It does not assume F typedef result_type, arg1_type, ... but needs typeof.
template<typename F>
class functor_type {
// NOTE: clang does not accept extra parenthesis `&(...)`.
typedef BOOST_TYPEOF_TPL(&F::operator()) call_ptr;
public:
typedef
typename boost::function_types::function_type<
typename boost::mpl::push_front<
typename boost::mpl::pop_front< // Remove functor type (1st).
typename boost::function_types::parameter_types<
call_ptr>::type
>::type
, typename boost::function_types::result_type<call_ptr>::type
>::type
>::type
type;
};
// NOTE: When using boost::function in Boost.Typeof emulation mode, the user
// has to register boost::functionN instead of boost::function in oder to
// do TYPEOF(F::operator()). That is confusing, so boost::function is handled
// separately so it does not require any Boost.Typeof registration at all.
template<typename F>
struct functor_type< boost::function<F> > {
typedef F type;
};
// Requires: F is a function type, pointer, reference, or monomorphic functor.
// Returns: F's function type `result_type (arg1_type, arg2_type, ...)`.
template<typename F>
struct function_type {
typedef
typename boost::mpl::if_<boost::function_types::is_function<F>,
boost::mpl::identity<F>
,
typename boost::mpl::if_<boost::function_types::
is_function_pointer<F>,
boost::remove_pointer<F>
,
typename boost::mpl::if_<boost::function_types::
is_function_reference<F>,
boost::remove_reference<F>
, // Else, requires that F is a functor.
functor_type<F>
>::type
>::type
>::type
::type type;
};
} } // namespace
#endif // #include guard

View File

@@ -0,0 +1,106 @@
/*
Copyright 2007 Tobias Schwinger
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_HPP
#define BOOST_FUNCTIONAL_VALUE_FACTORY_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <utility>
#endif
namespace boost {
template<class T>
class value_factory;
template<class T>
class value_factory {
public:
typedef T result_type;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args>
result_type operator()(Args&&... args) const {
return result_type(std::forward<Args>(args)...);
}
#else
result_type operator()() const {
return result_type();
}
template<class A0>
result_type operator()(A0& a0) const {
return result_type(a0);
}
template<class A0, class A1>
result_type operator()(A0& a0, A1& a1) const {
return result_type(a0, a1);
}
template<class A0, class A1, class A2>
result_type operator()(A0& a0, A1& a1, A2& a2) const {
return result_type(a0, a1, a2);
}
template<class A0, class A1, class A2, class A3>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const {
return result_type(a0, a1, a2, a3);
}
template<class A0, class A1, class A2, class A3, class A4>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const {
return result_type(a0, a1, a2, a3, a4);
}
template<class A0, class A1, class A2, class A3, class A4, class A5>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4,
A5& a5) const {
return result_type(a0, a1, a2, a3, a4, a5);
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6) const {
return result_type(a0, a1, a2, a3, a4, a5, a6);
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7) const {
return result_type(a0, a1, a2, a3, a4, a5, a6, a7);
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7, A8& a8) const {
return result_type(a0, a1, a2, a3, a4, a5, a6, a7, a8);
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7, A8& a8, A9& a9) const {
return result_type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
#endif
};
template<class T>
class value_factory<T&> { };
} /* boost */
#endif

View File

@@ -0,0 +1,269 @@
<!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">
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Boost Function Object Adapter Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2" summary="">
<tr>
<td bgcolor="#FFFFFF"><img src="../../boost.png" alt=
"boost.png (6897 bytes)" width="277" height="86"></td>
<td><a href="../../index.htm"><font face="Arial" color=
"#FFFFFF"><big>Home</big></font></a></td>
<td><a href="../libraries.htm"><font face="Arial" color=
"#FFFFFF"><big>Libraries</big></font></a></td>
<td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color=
"#FFFFFF"><big>People</big></font></a></td>
<td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color=
"#FFFFFF"><big>FAQ</big></font></a></td>
<td><a href="../../more/index.htm"><font face="Arial" color=
"#FFFFFF"><big>More</big></font></a></td>
</tr>
</table>
<h1>Improved Function Object Adapters</h1>
<p>The header <a href="../../boost/functional.hpp">functional.hpp</a>
provides enhancements to the function object adapters specified in the C++
Standard Library (sections 20.3.5, through to 20.3.8). The enhancements are
principally possible due to two changes:</p>
<ol>
<li>We use the Boost <tt><a href=
"../utility/call_traits.htm">call_traits</a></tt> templates to avoid the
problem of <a href="binders.html#refref">references to references</a>,
and to improve the efficiency of <a href="mem_fun.html#args">parameter
passing</a>.</li>
<li>We use two <a href="function_traits.html">function object traits</a>
class templates to avoid the need for <tt><a href=
"ptr_fun.html">ptr_fun</a></tt> with the adapters in this library.</li>
</ol>
<h3>Contents</h3>
<p>The header contains the following function and class templates:</p>
<table border="1" cellpadding="5" summary="">
<tr>
<th align="left"><a href="function_traits.html">Function object
traits</a></th>
<td valign="top"><tt>unary_traits<br>
binary_traits</tt></td>
<td valign="top">Used to determine the types of function objects' and
functions' arguments. Eliminate the necessity for
<tt>ptr_fun</tt>.</td>
</tr>
<tr>
<th align="left"><a href="negators.html">Negators</a></th>
<td valign="top"><tt>unary_negate<br>
binary_negate<br>
not1<br>
not2</tt></td>
<td valign="top">Based on section 20.3.5 of the standard.</td>
</tr>
<tr>
<th align="left"><a href="binders.html">Binders</a></th>
<td valign="top"><tt>binder1st<br>
binder2nd<br>
bind1st<br>
bind2nd</tt></td>
<td valign="top">Based on section 20.3.6 of the standard.</td>
</tr>
<tr>
<th align="left"><a href="ptr_fun.html">Adapters for pointers to
functions</a></th>
<td valign="top"><tt>pointer_to_unary_function<br>
pointer_to_binary_function<br>
ptr_fun</tt></td>
<td valign="top">Based on section 20.3.7 of the standard. Not required
for use with this library since the binders and negators can adapt
functions, but may be needed with third party adapters.</td>
</tr>
<tr>
<th align="left"><a href="mem_fun.html">Adapters for pointers to member
functions</a></th>
<td valign="top"><tt>mem_fun_t<br>
mem_fun1_t<br>
const_mem_fun_t<br>
const_mem_fun1_t<br>
mem_fun_ref_t<br>
mem_fun1_ref_t<br>
const_mem_fun_ref_t<br>
const_mem_fun1_ref_t<br>
mem_fun<br>
mem_fun_ref</tt></td>
<td valign="top">Based on section 20.3.8 of the standard.</td>
</tr>
<tr>
<th align="left"><a href="identity.html">Identity</a></th>
<td valign="top"><tt>identity</tt></td>
<td valign="top">[func.identity] in ISO/IEC 14882:2020</td>
</tr>
</table>
<h3>Usage</h3>
<p>Using these adapters should be pretty much the same as using the
standard function object adapters; the only differences are that you need
to write <tt>boost::</tt> instead of <tt>std::</tt>, and that you will get
fewer headaches.</p>
<p>For example, suppose you had a <tt>Person</tt> class that contained a
<tt>set_name</tt> function:</p>
<blockquote>
<pre>
class Person
{
public:
void set_name(const std::string &amp;name);
// ...
};
</pre>
</blockquote>
<p>You could rename a bunch of people in a collection, <tt>c</tt>, by
writing</p>
<blockquote>
<pre>
std::for_each(c.begin(), c.end(),
boost::bind2nd(boost::mem_fun_ref(&amp;Person::set_name), "Fred"));
</pre>
</blockquote>
<p>If the standard adapters had been used instead then this code would
normally fail to compile, because <tt>set_name</tt> takes a reference
argument. Refer to the comments in the <a href="binders.html#refref">binder
documentation</a> to explain why this is so.</p>
<h3>Compiler Compatibility</h3>
<p>The header and <a href="test/function_test.cpp">test program</a> have been
compiled with the following compilers:</p>
<table border="1" cellpadding="5" summary="">
<tr>
<th>Compiler</th>
<th>Comments</th>
</tr>
<tr>
<td valign="top">Borland C++Builder 4 Update 2</td>
<td valign="top">No known issues.</td>
</tr>
<tr>
<td valign="top">Borland C++ 5.5</td>
<td valign="top">No known issues.</td>
</tr>
<tr>
<td valign="top">g++ 2.95.2</td>
<td valign="top">No known issues.</td>
</tr>
<tr>
<td valign="top">Microsoft Visual C++ Service Pack 3</td>
<td valign="top">
Compiler lacks partial specialisation, so this library offers little
more than is provided by the standard adapters:
<ul>
<li>The <tt>call_traits</tt> mechanism is unable to prevent
references to references, and so the adapters in this library will
be usable in fewer situations.</li>
<li>The <tt>function_traits</tt> mechanism is unable to determine
the argument and result types of functions, therefore
<tt>ptr_fun</tt> continues to be required to adapt functions.</li>
</ul>
</td>
</tr>
</table>
<h3>Future Directions</h3>
<p>This library's primary focus is to solve the problem of references to
references while maintaining as much compatibility as possible with the
standard library. This allows you to use the techniques you read about in
books and magazines with many of today's compilers.</p>
<p>In the longer term, even better solutions are likely:</p>
<ol>
<li>Several Boost members are working on expression template libraries.
These will allow a more natural syntax for combining and adapting
functions. As this is a new technology, it may be some time before it has
matured and is widely supported by major compilers but shows great
promise. In the meantime, the functional.hpp library fills the gap.</li>
<li>The Standard Committee has recognised the problem of references to
references occurring during template instantiation and has moved to fix
the standard (see the <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#106">C++
standard core language active issues list</a>).</li>
</ol>
<h3>Author</h3>
<p><a href="http://www.boost.org/people/mark_rodgers.htm">Mark Rodgers</a></p>
<h3>Acknowledgements</h3>
<p>Thanks to <a href="http://www.boost.org/people/john_maddock.htm">John Maddock</a> for
suggesting the mechanism that allowed the function objects traits to work
correctly. <a href="http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a> provided
invaluable feedback during the <a href=
"http://www.boost.org/more/formal_review_process.htm">formal review process</a>.</p>
<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 -->02
December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
<p><i>Copyright &copy; 2000 Cadenza New Zealand Ltd.</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>

View File

@@ -0,0 +1,201 @@
<!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>Boost Function Object Adapter Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2" summary="">
<tr>
<td bgcolor="#FFFFFF"><img src="../../boost.png" alt=
"boost.png (6897 bytes)" width="277" height="86"></td>
<td><a href="../../index.htm"><font face="Arial" color=
"#FFFFFF"><big>Home</big></font></a></td>
<td><a href="../libraries.htm"><font face="Arial" color=
"#FFFFFF"><big>Libraries</big></font></a></td>
<td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color=
"#FFFFFF"><big>People</big></font></a></td>
<td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color=
"#FFFFFF"><big>FAQ</big></font></a></td>
<td><a href="../../more/index.htm"><font face="Arial" color=
"#FFFFFF"><big>More</big></font></a></td>
</tr>
</table>
<h1>Member Function Adapters</h1>
<p>The header <a href="../../boost/functional.hpp">functional.hpp</a>
includes improved versions of the full range of member function adapters
from the the C++ Standard Library (&sect;20.3.8):</p>
<ul>
<li><tt>mem_fun_t</tt></li>
<li><tt>mem_fun1_t</tt></li>
<li><tt>const_mem_fun_t</tt></li>
<li><tt>const_mem_fun1_t</tt></li>
<li><tt>mem_fun_ref_t</tt></li>
<li><tt>mem_fun1_ref_t</tt></li>
<li><tt>const_mem_fun_ref_t</tt></li>
<li><tt>const_mem_fun1_ref_t</tt></li>
</ul>
<p>as well as the corresponding overloaded helper functions</p>
<ul>
<li><tt>mem_fun</tt></li>
<li><tt>mem_fun_ref</tt></li>
</ul>
<p>The following changes have been made to the adapters as specified in the
Standard:</p>
<ul>
<li>The <tt>first_argument_type</tt> typedef has been corrected for the
<tt>const_</tt> family of member function adapters (see <a href=
"#firstarg">below</a>).</li>
<li>The argument passed to <tt>mem_fun1_t</tt> and its variants is passed
using the <tt>call_traits::param_type</tt> for the member function's
argument type.</li>
</ul>
<h3 id="firstarg">first_argument_type</h3>
<p>The standard specifies <tt>const_mem_fun1_t</tt>, for example, like
this:</p>
<blockquote>
<pre>
template &lt;class S, class T, class A&gt; class const_mem_fun1_t
: public binary_function&lt;<strong>T*</strong>, A, S&gt; {
public:
explicit const_mem_fun1_t(S (T::*p)(A) const);
S operator()(<strong>const T*</strong> p, A x) const;
};
</pre>
</blockquote>
<p>Note that the first argument to <tt>binary_function</tt> is <tt>T*</tt>
despite the fact that the first argument to <tt>operator()</tt> is actually
of type <tt><em>const</em>&nbsp;T*</tt>.</p>
<p>Does this matter? Well, consider what happens when we write</p>
<blockquote>
<pre>
struct Foo { void bar(int) const; };
const Foo *cp = new Foo;
std::bind1st(std::mem_fun(&amp;Foo::bar), cp);
</pre>
</blockquote>
<p>We have created a <tt>const_mem_fun1_t</tt> object which will
effectively contain the following</p>
<blockquote>
<pre>
typedef Foo* first_argument_type;
</pre>
</blockquote>
<p>The <tt>bind1st</tt> will then create a <tt>binder1st</tt> object that
will use this <tt>typedef</tt> as the type of a member which will be
initialised with <tt>cp</tt>. In other words, we will need to initialise a
<tt>Foo*</tt> member with a <tt>const&nbsp;Foo*</tt> pointer! Clearly this
is not possible, so to implement this your Standard Library vendor will
have had to cast away the constness of <tt>cp</tt>, probably within the
body of <tt>bind1st</tt>.</p>
<p>This hack will not suffice with the improved <a href=
"binders.html">binders</a> in this library, so we have had to provide
corrected versions of the member function adapters as well.</p>
<h3 id="args">Argument Types</h3>
<p>The standard defines <tt>mem_fun1_t</tt>, for example, like this
(&sect;20.3.8&nbsp;&para;2):</p>
<blockquote>
<pre>
template &lt;class S, class T, class A&gt; class mem_fun1_t
: public binary_function&lt;T*, A, S&gt; {
public:
explicit mem_fun1_t(S (T::*p)(<strong>A</strong>));
S operator()(T* p, <strong>A</strong> x) const;
};
</pre>
</blockquote>
<p>Note that the second argument to <tt>operator()</tt> is exactly the same
type as the argument to the member function. If this is a value type, the
argument will be passed by value and copied twice.</p>
<p>However, if we were to try and eliminate this inefficiency by instead
declaring the argument as <tt>const&nbsp;A&amp;</tt>, then if A were a
reference type, we would have a reference to a reference, which is
currently illegal (but see <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#106">C++ core
language issue number 106)</a></p>
<p>So the way in which we want to declare the second argument for
<tt>operator()</tt> depends on whether or not the member function's
argument is a reference. If it is a reference, we want to declare it simply
as <tt>A</tt>; if it is a value we want to declare it as
<tt>const&nbsp;A&amp;</tt>.</p>
<p>The Boost <a href="../utility/call_traits.htm">call_traits</a> class
template contains a <tt>param_type</tt> typedef, which uses partial
specialisation to make precisely this decision. By declaring the
<tt>operator()</tt> as</p>
<blockquote>
<pre>
S operator()(T* p, typename call_traits&lt;A&gt;::param_type x) const
</pre>
</blockquote>
<p>we achieve the desired result - we improve efficiency without generating
references to references.</p>
<h3>Limitations</h3>
<p>The call traits template used to realise some improvements relies on
partial specialisation, so these improvements are only available on
compilers that support that feature. With other compilers, the argument
passed to the member function (in the <tt>mem_fun1_t</tt> family) will
always be passed by reference, thus generating the possibility of
references to references.</p>
<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 -->02 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
<p><i>Copyright &copy; 2000 Cadenza New Zealand Ltd.</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>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017-2018 Daniel James
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)
-->
<explicit-failures-markup>
<!-- functional/factory -->
<library name="functional/factory">
<mark-expected-failures>
<test name="factory_with_allocator"/>
<toolset name="borland-*"/>
<note author="Tobias Schwinger">
Probably broken const conversion with that compiler.
</note>
</mark-expected-failures>
</library>
<!-- functional/forward -->
<library name="functional/foward">
<mark-unusable>
<toolset name="msvc-7.0*"/>
<toolset name="msvc-7.1*"/>
<toolset name="sun-5.*"/>
<toolset name="vacpp*"/>
<toolset name="borland-*"/>
<note author="Tobias Schwinger">
This compiler is currently not supported.
</note>
</mark-unusable>
</library>
</explicit-failures-markup>

View File

@@ -0,0 +1,68 @@
[
{
"key": "functional",
"boost-version": "1.16.0",
"name": "Functional",
"authors": [
"Mark Rodgers"
],
"description": "The Boost.Function library contains a family of class templates that are function object wrappers.",
"category": [
"Function-objects"
],
"cxxstd": "03"
},
{
"key": "functional/factory",
"boost-version": "1.43.0",
"name": "Functional/Factory",
"authors": [
"Glen Fernandes",
"Tobias Schwinger"
],
"maintainers": [
"Glen Fernandes <glenjofe -at- gmail.com>",
"Tobias Schwinger <tschwinger -at- isonews2.com>"
],
"description": "Function object templates for dynamic and static object creation",
"documentation": "factory/",
"category": [
"Function-objects"
],
"cxxstd": "03"
},
{
"key": "functional/forward",
"boost-version": "1.43.0",
"name": "Functional/Forward",
"authors": [
"Tobias Schwinger"
],
"maintainers": [
"Tobias Schwinger <tschwinger -at- isonews2.com>"
],
"description": "Adapters to allow generic function objects to accept arbitrary arguments",
"documentation": "forward/",
"category": [
"Function-objects"
],
"cxxstd": "03"
},
{
"key": "functional/overloaded_function",
"boost-version": "1.50.0",
"name": "Functional/Overloaded Function",
"authors": [
"Lorenzo Caminiti"
],
"maintainers": [
"Lorenzo Caminiti <lorcaminiti -at- gmail.com>"
],
"description": "Overload different functions into a single function object.",
"documentation": "overloaded_function/",
"category": [
"Function-objects"
],
"cxxstd": "03"
}
]

View File

@@ -0,0 +1,158 @@
<!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>Boost Function Object Adapter Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2" summary="">
<tr>
<td bgcolor="#FFFFFF"><img src="../../boost.png" alt=
"boost.png (6897 bytes)" width="277" height="86"></td>
<td><a href="../../index.htm"><font face="Arial" color=
"#FFFFFF"><big>Home</big></font></a></td>
<td><a href="../libraries.htm"><font face="Arial" color=
"#FFFFFF"><big>Libraries</big></font></a></td>
<td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color=
"#FFFFFF"><big>People</big></font></a></td>
<td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color=
"#FFFFFF"><big>FAQ</big></font></a></td>
<td><a href="../../more/index.htm"><font face="Arial" color=
"#FFFFFF"><big>More</big></font></a></td>
</tr>
</table>
<h1>Negators</h1>
<p>The header <a href="../../boost/functional.hpp">functional.hpp</a>
provides enhanced versions of both the negator adapters from the C++
Standard Library (&sect;20.3.5):</p>
<ul>
<li><tt>unary_negate</tt></li>
<li><tt>binary_negate</tt></li>
</ul>
<p>As well as the corresponding helper functions</p>
<ul>
<li><tt>not1</tt></li>
<li><tt>not2</tt></li>
</ul>
<p>However, the negators in this library improve on the standard versions
in two ways:</p>
<ul>
<li>They use <a href="function_traits.html">function object traits</a> to
avoid the need for <tt>ptr_fun</tt> when negating a function rather than
an adaptable function object.</li>
<li>They use Boost <a href=
"../utility/call_traits.htm">call&nbsp;traits</a> to determine the best
way to declare their arguments and pass them through to the adapted
function (see <a href="#arguments">below</a>).</li>
</ul>
<h3>Usage</h3>
<p>Usage is identical to the standard negators. For example,</p>
<blockquote>
<pre>
bool bad(const Foo &amp;foo) { ... }
...
std::vector&lt;Foo&gt; c;
...
std::find_if(c.begin(), c.end(), boost::not1(bad));
</pre>
</blockquote>
<h3 id="arguments">Argument Types</h3>
<p>The C++ Standard (&sect;20.3.5) defines unary negate like this (binary
negate is similar):</p>
<blockquote>
<pre>
template &lt;class Predicate&gt;
class unary_negate
: public unary_function&lt;typename Predicate::argument_type,bool&gt; {
public:
explicit unary_negate(const Predicate&amp; pred);
bool operator()(<strong>const typename Predicate::argument_type&amp;</strong> x) const;
};
</pre>
</blockquote>
<p>Note that if the Predicate's <tt>argument_type</tt> is a reference, the
type of <tt>operator()</tt>'s argument would be a reference to a reference.
Currently this is illegal in C++ (but see the <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#106">C++
standard core language active issues list</a>).</p>
<p>However, if we instead defined <tt>operator()</tt> to accept Predicate's
argument_type unmodified, this would be needlessly inefficient if it were a
value type; the argument would be copied twice - once when calling
<tt>unary_negate</tt>'s <tt>operator()</tt>, and again when
<tt>operator()</tt> called the adapted function.</p>
<p>So how we want to declare the argument for <tt>operator()</tt> depends
on whether or not the Predicate's <tt>argument_type</tt> is a reference. If
it is a reference, we want to declare it simply as <tt>argument_type</tt>;
if it is a value we want to declare it as
<tt>const&nbsp;argument_type&amp;</tt>.</p>
<p>The Boost <a href="../utility/call_traits.htm">call_traits</a> class
template contains a <tt>param_type</tt> typedef, which uses partial
specialisation to make precisely this decision. If we were to declare
<tt>operator()</tt> as</p>
<blockquote>
<pre>
bool operator()(typename call_traits&lt;typename Predicate::argument_type&gt;::param_type x) const
</pre>
</blockquote>
<p>the desired result would be achieved - we would eliminate references to
references without loss of efficiency. In fact, the actual declaration is
slightly more complicated because of the use of function object traits, but
the effect remains the same.</p>
<h3>Limitations</h3>
<p>Both the function object traits and call traits used to realise these
improvements rely on partial specialisation, these improvements are only
available on compilers that support that feature. With other compilers, the
negators in this library behave very much like those in the Standard -
<tt>ptr_fun</tt> will be required to adapt functions, and references to
references will not be avoided.</p>
<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 -->02
December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
<p><i>Copyright &copy; 2000 Cadenza New Zealand Ltd.</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>

View File

@@ -0,0 +1,33 @@
# Copyright (C) 2009-2012 Lorenzo Caminiti
# Distributed under the Boost Software License, Version 1.0
# (see accompanying file LICENSE_1_0.txt or a copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Home at http://www.boost.org/libs/functional/overloaded_function
import quickbook ;
using boostbook ;
doxygen reference
: ../../../../boost/functional/overloaded_function.hpp
../../../../boost/functional/overloaded_function/config.hpp
: <reftitle>"Reference"
<doxygen:param>PREDEFINED="DOXYGEN"
<doxygen:param>QUIET=YES
<doxygen:param>WARN_IF_UNDOCUMENTED=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>HIDE_UNDOC_CLASSES=YES
<doxygen:param>ALIASES=" Params=\"<b>Parameters:</b> <table border="0">\" Param{2}=\"<tr><td><b><tt>\\1</tt></b></td><td>\\2</td></tr>\" EndParams=\"</table>\" Returns=\"<b>Returns:</b>\" Note=\"<b>Note:</b>\" Warning=\"<b>Warning:</b>\" See=\"<b>See:</b>\" RefSect{2}=\"\\xmlonly<link linkend='boost_functional_overloadedfunction.\\1'>\\2</link>\\endxmlonly\" RefClass{1}=\"\\xmlonly<computeroutput><classname alt='\\1'>\\1</classname></computeroutput>\\endxmlonly\" RefFunc{1}=\"\\xmlonly<computeroutput><functionname alt='\\1'>\\1</functionname></computeroutput>\\endxmlonly\" RefMacro{1}=\"\\xmlonly<computeroutput><macroname alt='\\1'>\\1</macroname></computeroutput>\\endxmlonly\" "
;
xml qbk : overloaded_function.qbk : <dependency>reference ;
boostbook doc : qbk
: <xsl:param>boost.root=../../../../..
<xsl:param>boost.defaults=Boost
<xsl:param>generate.consistent.ids=1
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/functional/overloaded_function/doc/html
;
install pdfinstall : doc/<format>pdf : <location>. <install-type>PDF <name>overloaded_function.pdf ;
explicit pdfinstall ;

View File

@@ -0,0 +1,54 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="up" href="reference.html#header.boost.functional.overloaded_function.config_hpp" title="Header &lt;boost/functional/overloaded_function/config.hpp&gt;">
<link rel="prev" href="boost/make_overloaded_function.html" title="Function template make_overloaded_function">
<link rel="next" href="BOOST_FUNCTIONAL_O_1_7_3_3.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX">
</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">
<a accesskey="p" href="boost/make_overloaded_function.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="reference.html#header.boost.functional.overloaded_function.config_hpp"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="BOOST_FUNCTIONAL_O_1_7_3_3.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="refentry">
<a name="BOOST_FUNCTIONAL_O_1_7_3_2"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2><span class="refentrytitle">Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX</span></h2>
<p>BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX &#8212; Specify the maximum number of arguments of the functions being overloaded. </p>
</div>
<h2 xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv-title">Synopsis</h2>
<div xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv"><pre class="synopsis"><span class="comment">// In header: &lt;<a class="link" href="reference.html#header.boost.functional.overloaded_function.config_hpp" title="Header &lt;boost/functional/overloaded_function/config.hpp&gt;">boost/functional/overloaded_function/config.hpp</a>&gt;
</span>BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX</pre></div>
<div class="refsect1">
<a name="id-1.7.3.4.4"></a><h2>Description</h2>
<p>If this macro is left undefined by the user, it has a default value of 5 (increasing this number might increase compilation time). When specified by the user, this macro must be a non-negative integer number.</p>
<p><span class="bold"><strong>See:</strong></span> <a class="link" href="boost_functional_overloadedfunction/getting_started.html" title="Getting Started"> Getting Started</a>, <code class="computeroutput"><a class="link" href="boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code>. </p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2011, 2012 Lorenzo Caminiti<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></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="boost/make_overloaded_function.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="reference.html#header.boost.functional.overloaded_function.config_hpp"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="BOOST_FUNCTIONAL_O_1_7_3_3.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,54 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="up" href="reference.html#header.boost.functional.overloaded_function.config_hpp" title="Header &lt;boost/functional/overloaded_function/config.hpp&gt;">
<link rel="prev" href="BOOST_FUNCTIONAL_O_1_7_3_2.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX">
<link rel="next" href="boost_functional_overloadedfunction/acknowledgments.html" title="Acknowledgments">
</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">
<a accesskey="p" href="BOOST_FUNCTIONAL_O_1_7_3_2.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="reference.html#header.boost.functional.overloaded_function.config_hpp"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="boost_functional_overloadedfunction/acknowledgments.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="refentry">
<a name="BOOST_FUNCTIONAL_O_1_7_3_3"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2><span class="refentrytitle">Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX</span></h2>
<p>BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX &#8212; Specify the maximum number of functions that can be overloaded. </p>
</div>
<h2 xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv-title">Synopsis</h2>
<div xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv"><pre class="synopsis"><span class="comment">// In header: &lt;<a class="link" href="reference.html#header.boost.functional.overloaded_function.config_hpp" title="Header &lt;boost/functional/overloaded_function/config.hpp&gt;">boost/functional/overloaded_function/config.hpp</a>&gt;
</span>BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX</pre></div>
<div class="refsect1">
<a name="id-1.7.3.5.4"></a><h2>Description</h2>
<p>If this macro is left undefined by the user, it has a default value of 5 (increasing this number might increase compilation time). When defined by the user, this macro must be an integer number greater or equal than 2 (because at least two distinct functions need to be specified in order to define an overload).</p>
<p><span class="bold"><strong>See:</strong></span> <a class="link" href="boost_functional_overloadedfunction/getting_started.html" title="Getting Started"> Getting Started</a>, <code class="computeroutput"><a class="link" href="boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code>. </p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2011, 2012 Lorenzo Caminiti<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></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="BOOST_FUNCTIONAL_O_1_7_3_2.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="reference.html#header.boost.functional.overloaded_function.config_hpp"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="boost_functional_overloadedfunction/acknowledgments.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,60 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Function template make_overloaded_function</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="up" href="../reference.html#header.boost.functional.overloaded_function_hpp" title="Header &lt;boost/functional/overloaded_function.hpp&gt;">
<link rel="prev" href="overloaded_function.html" title="Class template overloaded_function">
<link rel="next" href="../BOOST_FUNCTIONAL_O_1_7_3_2.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX">
</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">
<a accesskey="p" href="overloaded_function.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html#header.boost.functional.overloaded_function_hpp"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../BOOST_FUNCTIONAL_O_1_7_3_2.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="refentry">
<a name="boost.make_overloaded_function"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2><span class="refentrytitle">Function template make_overloaded_function</span></h2>
<p>boost::make_overloaded_function &#8212; Make an overloaded function object without explicitly specifying the function types. </p>
</div>
<h2 xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv-title">Synopsis</h2>
<div xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv"><pre class="synopsis"><span class="comment">// In header: &lt;<a class="link" href="../reference.html#header.boost.functional.overloaded_function_hpp" title="Header &lt;boost/functional/overloaded_function.hpp&gt;">boost/functional/overloaded_function.hpp</a>&gt;
</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> F1<span class="special">,</span> <span class="keyword">typename</span> F2<span class="special">,</span> <span class="special">...</span> <span class="special">&gt;</span>
<a class="link" href="overloaded_function.html" title="Class template overloaded_function">overloaded_function</a><span class="special">&lt;</span> <span class="identifier">__function_type__</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span><span class="special">,</span> <span class="identifier">__function_type__</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span><span class="special">,</span><span class="special">...</span> <span class="special">&gt;</span>
<span class="identifier">make_overloaded_function</span><span class="special">(</span><span class="identifier">F1</span> f1<span class="special">,</span> <span class="identifier">F2</span> f2<span class="special">,</span> <span class="special">...</span><span class="special">)</span><span class="special">;</span></pre></div>
<div class="refsect1">
<a name="id-1.7.2.5.4"></a><h2>Description</h2>
<p>This function template creates and returns an <code class="computeroutput"><code class="computeroutput"><a class="link" href="overloaded_function.html" title="Class template overloaded_function">overloaded_function</a></code></code> object that overloads all the specified functions <code class="computeroutput">f1</code>, <code class="computeroutput">f2</code>, etc.</p>
<p>The function types are internally determined from the template parameter types so they do not need to be explicitly specified. Therefore, this function template usually has a more concise syntax when compared with <code class="computeroutput"><code class="computeroutput"><a class="link" href="overloaded_function.html" title="Class template overloaded_function">overloaded_function</a></code></code>. This is especially useful when the explicit type of the returned <code class="computeroutput"><code class="computeroutput"><a class="link" href="overloaded_function.html" title="Class template overloaded_function">overloaded_function</a></code></code> object does not need to be known (e.g., when used with Boost.Typeof's <code class="computeroutput">BOOST_AUTO</code>, C++11 <code class="computeroutput">auto</code>, or when the overloaded function object is handled using a function template parameter, see the <a class="link" href="../boost_functional_overloadedfunction/tutorial.html" title="Tutorial"> Tutorial</a> section).</p>
<p>The maximum number of functions to overload is given by the <code class="computeroutput"><code class="computeroutput"><a class="link" href="../BOOST_FUNCTIONAL_O_1_7_3_3.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX</a></code></code> configuration macro.</p>
<p><span class="bold"><strong>Note:</strong></span> In this documentation, <code class="computeroutput">__function_type__</code> is a placeholder for a symbol that is specific to the implementation of this library.</p>
<p><span class="bold"><strong>See:</strong></span> <a class="link" href="../boost_functional_overloadedfunction/tutorial.html" title="Tutorial"> Tutorial</a> section, <code class="computeroutput"><code class="computeroutput"><a class="link" href="overloaded_function.html" title="Class template overloaded_function">overloaded_function</a></code></code>, <code class="computeroutput"><code class="computeroutput"><a class="link" href="../BOOST_FUNCTIONAL_O_1_7_3_3.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX</a></code></code>. </p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2011, 2012 Lorenzo Caminiti<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></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="overloaded_function.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html#header.boost.functional.overloaded_function_hpp"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../BOOST_FUNCTIONAL_O_1_7_3_2.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,112 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Class template overloaded_function</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="up" href="../reference.html#header.boost.functional.overloaded_function_hpp" title="Header &lt;boost/functional/overloaded_function.hpp&gt;">
<link rel="prev" href="../reference.html" title="Reference">
<link rel="next" href="make_overloaded_function.html" title="Function template make_overloaded_function">
</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">
<a accesskey="p" href="../reference.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html#header.boost.functional.overloaded_function_hpp"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="make_overloaded_function.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="refentry">
<a name="boost.overloaded_function"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2><span class="refentrytitle">Class template overloaded_function</span></h2>
<p>boost::overloaded_function &#8212; Function object to overload functions with distinct signatures. </p>
</div>
<h2 xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv-title">Synopsis</h2>
<div xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv"><pre class="synopsis"><span class="comment">// In header: &lt;<a class="link" href="../reference.html#header.boost.functional.overloaded_function_hpp" title="Header &lt;boost/functional/overloaded_function.hpp&gt;">boost/functional/overloaded_function.hpp</a>&gt;
</span><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> F1<span class="special">,</span> <span class="keyword">typename</span> F2<span class="special">,</span> <span class="special">...</span> <span class="special">&gt;</span>
<span class="keyword">class</span> <a class="link" href="overloaded_function.html" title="Class template overloaded_function">overloaded_function</a> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="comment">// <a class="link" href="overloaded_function.html#boost.overloaded_functionconstruct-copy-destruct">construct/copy/destruct</a></span>
<a class="link" href="overloaded_function.html#id-1_7_2_2_1_5-bb"><span class="identifier">overloaded_function</span></a><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span><span class="special">;</span>
<span class="comment">// <a class="link" href="overloaded_function.html#id-1_7_2_2_1_4-bb">public member functions</a></span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">result_type</span>
<a class="link" href="overloaded_function.html#id-1_7_2_2_1_4_1-bb"><span class="keyword">operator</span><span class="special">(</span><span class="special">)</span></a><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">arg1_type</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">arg2_type</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">result_type</span>
<a class="link" href="overloaded_function.html#id-1_7_2_2_1_4_2-bb"><span class="keyword">operator</span><span class="special">(</span><span class="special">)</span></a><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">arg1_type</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">arg2_type</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
<span class="special">}</span><span class="special">;</span></pre></div>
<div class="refsect1">
<a name="id-1.7.2.4.4"></a><h2>Description</h2>
<p>This function object aggregates together calls to functions of all the specified function types <code class="computeroutput">F1</code>, <code class="computeroutput">F2</code>, etc which must have distinct function signatures from one another.</p>
<p><span class="bold"><strong>Parameters:</strong></span> </p>
<div class="informaltable"><table class="table">
<colgroup>
<col>
<col>
</colgroup>
<tbody><tr>
<td><span class="bold"><strong><code class="computeroutput">F<span class="emphasis"><em>i</em></span></code></strong></span></td>
<td>Each function type must be specified using the following syntax (which is Boost.Function's preferred syntax): <pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="identifier">result_type</span> <span class="special">(</span><span class="identifier">argument1_type</span><span class="special">,</span> <span class="identifier">argumgnet2_type</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span>
</pre> </td>
</tr></tbody>
</table></div>
<p>
</p>
<p>In some cases, the <code class="computeroutput"><a class="link" href="make_overloaded_function.html" title="Function template make_overloaded_function">make_overloaded_function</a></code> function template can be useful to construct an overloaded function object without explicitly specifying the function types.</p>
<p>At least two distinct function types must be specified (because there is nothing to overload between one or zero functions). The maximum number of functions to overload is given by the <code class="computeroutput"><a class="link" href="../BOOST_FUNCTIONAL_O_1_7_3_3.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX</a></code> configuration macro. The maximum number of function parameters for each of the specified function types is given by the <code class="computeroutput"><a class="link" href="../BOOST_FUNCTIONAL_O_1_7_3_2.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX</a></code> configuration macro.</p>
<p><span class="bold"><strong>See:</strong></span> <a class="link" href="../boost_functional_overloadedfunction/tutorial.html" title="Tutorial"> Tutorial</a> section, <code class="computeroutput"><a class="link" href="make_overloaded_function.html" title="Function template make_overloaded_function">make_overloaded_function</a></code>, <code class="computeroutput"><a class="link" href="../BOOST_FUNCTIONAL_O_1_7_3_3.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX</a></code>, <code class="computeroutput"><a class="link" href="../BOOST_FUNCTIONAL_O_1_7_3_2.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX</a></code>, Boost.Function. </p>
<div class="refsect2">
<a name="id-1.7.2.4.4.7"></a><h3>
<a name="boost.overloaded_functionconstruct-copy-destruct"></a><code class="computeroutput">overloaded_function</code>
public
construct/copy/destruct</h3>
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<pre class="literallayout"><a name="id-1_7_2_2_1_5-bb"></a><span class="identifier">overloaded_function</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">,</span>
<span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span> <span class="special">&amp;</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span><span class="special">;</span></pre>Construct the overloaded function object. <p>Any function pointer, function reference, and monomorphic function object that can be converted to a <code class="computeroutput">boost::function</code> function object can be specified as parameter.</p>
<p><span class="bold"><strong>Note:</strong></span> Unfortunately, it is not possible to support polymorphic function objects (as explained <a href="http://lists.boost.org/Archives/boost/2012/03/191744.php" target="_top">here</a>). </p>
</li></ol></div>
</div>
<div class="refsect2">
<a name="id-1.7.2.4.4.8"></a><h3>
<a name="id-1_7_2_2_1_4-bb"></a><code class="computeroutput">overloaded_function</code> public member functions</h3>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
<pre class="literallayout"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">result_type</span>
<a name="id-1_7_2_2_1_4_1-bb"></a><span class="keyword">operator</span><span class="special">(</span><span class="special">)</span><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">arg1_type</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">arg2_type</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></pre>Call operator matching the signature of the function type specified as 1st template parameter. <p>This will in turn invoke the call operator of the 1st function passed to the constructor. </p>
</li>
<li class="listitem">
<pre class="literallayout"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">result_type</span>
<a name="id-1_7_2_2_1_4_2-bb"></a><span class="keyword">operator</span><span class="special">(</span><span class="special">)</span><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">arg1_type</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span><span class="special">::</span><span class="identifier">arg2_type</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span></pre>Call operator matching the signature of the function type specified as 2nd template parameter. <p>This will in turn invoke the call operator of the 2nd function passed to the constructor.</p>
<p><span class="bold"><strong>Note:</strong></span> Similar call operators are present for all specified function types <code class="computeroutput">F1</code>, <code class="computeroutput">F2</code>, etc (even if not exhaustively listed by this documentation). </p>
</li>
</ol></div>
</div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2011, 2012 Lorenzo Caminiti<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></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../reference.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html#header.boost.functional.overloaded_function_hpp"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="make_overloaded_function.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,60 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Acknowledgments</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="prev" href="../BOOST_FUNCTIONAL_O_1_7_3_3.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX">
</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">
<a accesskey="p" href="../BOOST_FUNCTIONAL_O_1_7_3_3.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functional_overloadedfunction.acknowledgments"></a><a class="link" href="acknowledgments.html" title="Acknowledgments">Acknowledgments</a>
</h2></div></div></div>
<p>
Many thanks to Mathias Gaunard for suggesting to implement <code class="computeroutput"><a class="link" href="../boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code>
and for some sample code.
</p>
<p>
Thanks to John Bytheway for suggesting to implement <code class="computeroutput"><a class="link" href="../boost/make_overloaded_function.html" title="Function template make_overloaded_function">boost::make_overloaded_function</a></code>.
</p>
<p>
Thanks to Nathan Ridge for suggestions on how to implement <code class="computeroutput"><a class="link" href="../boost/make_overloaded_function.html" title="Function template make_overloaded_function">boost::make_overloaded_function</a></code>.
</p>
<p>
Thanks to Robert Stewart for commenting on the library name.
</p>
<p>
Many thanks to the entire <a href="http://www.boost.org" target="_top">Boost</a> community
and mailing list for providing valuable comments about this library and great
insights on the C++ programming language.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2011, 2012 Lorenzo Caminiti<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></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../BOOST_FUNCTIONAL_O_1_7_3_3.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,95 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Getting Started</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="prev" href="../index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="next" href="tutorial.html" title="Tutorial">
</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">
<a accesskey="p" href="../index.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutorial.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functional_overloadedfunction.getting_started"></a><a class="link" href="getting_started.html" title="Getting Started">Getting
Started</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="getting_started.html#boost_functional_overloadedfunction.getting_started.compilers_and_platforms">Compilers
and Platforms</a></span></dt>
<dt><span class="section"><a href="getting_started.html#boost_functional_overloadedfunction.getting_started.installation">Installation</a></span></dt>
</dl></div>
<p>
This section explains how to setup a system to use this library.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_functional_overloadedfunction.getting_started.compilers_and_platforms"></a><a class="link" href="getting_started.html#boost_functional_overloadedfunction.getting_started.compilers_and_platforms" title="Compilers and Platforms">Compilers
and Platforms</a>
</h3></div></div></div>
<p>
The authors originally developed and tested this library on:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features
enabled <code class="computeroutput"><span class="special">-</span><span class="identifier">std</span><span class="special">=</span><span class="identifier">c</span><span class="special">++</span><span class="number">0</span><span class="identifier">x</span></code>)
on Cygwin.
</li>
<li class="listitem">
Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7.
</li>
</ol></div>
<p>
See the library <a href="http://www.boost.org/development/tests/release/developer/functional-overloaded_function.html" target="_top">regressions
test results</a> for detailed information on supported compilers and
platforms. Check the library regression test <a href="../../../test/Jamfile.v2" target="_top"><code class="literal">Jamfile.v2</code></a>
for any special configuration that might be required for a specific compiler.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_functional_overloadedfunction.getting_started.installation"></a><a class="link" href="getting_started.html#boost_functional_overloadedfunction.getting_started.installation" title="Installation">Installation</a>
</h3></div></div></div>
<p>
This library is composed of header files only. Therefore there is no pre-compiled
object file which needs to be installed. Programmers can simply instruct
the compiler where to find the library header files (<code class="computeroutput"><span class="special">-</span><span class="identifier">I</span></code> option on GCC, <code class="computeroutput"><span class="special">/</span><span class="identifier">I</span></code> option on MSVC, etc) and compile code
using the library.
</p>
<p>
The maximum number of functions to overload is given by the <code class="computeroutput"><a class="link" href="../BOOST_FUNCTIONAL_O_1_7_3_3.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX</a></code>
configuration macro. The maximum number of function parameters for each of
the specified function type is given by the <code class="computeroutput"><a class="link" href="../BOOST_FUNCTIONAL_O_1_7_3_2.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX</a></code>
configuration macro. All configuration macros have appropriate default values
when they are left undefined.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2011, 2012 Lorenzo Caminiti<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></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutorial.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,228 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Tutorial</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="prev" href="getting_started.html" title="Getting Started">
<link rel="next" href="../reference.html" title="Reference">
</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">
<a accesskey="p" href="getting_started.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functional_overloadedfunction.tutorial"></a><a class="link" href="tutorial.html" title="Tutorial">Tutorial</a>
</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="tutorial.html#boost_functional_overloadedfunction.tutorial.overloading">Overloading</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_functional_overloadedfunction.tutorial.without_function_types">Without
Function Types</a></span></dt>
</dl></div>
<p>
This section explains how to use this library.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_functional_overloadedfunction.tutorial.overloading"></a><a class="link" href="tutorial.html#boost_functional_overloadedfunction.tutorial.overloading" title="Overloading">Overloading</a>
</h3></div></div></div>
<p>
Consider the following functions which have distinct signatures:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&amp;</span> <span class="identifier">identity_s</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">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="comment">// Function (as pointer).</span>
<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">identity_i_impl</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">int</span> <span class="special">(&amp;</span><span class="identifier">identity_i</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">identity_i_impl</span><span class="special">;</span> <span class="comment">// Function reference.</span>
<span class="keyword">double</span> <span class="identifier">identity_d_impl</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span><span class="special">;</span> <span class="special">}</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">double</span> <span class="special">(</span><span class="keyword">double</span><span class="special">)&gt;</span> <span class="identifier">identity_d</span> <span class="special">=</span> <span class="identifier">identity_d_impl</span><span class="special">;</span> <span class="comment">// Functor.</span>
</pre>
<p>
</p>
<p>
This library header <code class="computeroutput"><a class="link" href="../reference.html#header.boost.functional.overloaded_function_hpp" title="Header &lt;boost/functional/overloaded_function.hpp&gt;">boost/functional/overloaded_function.hpp</a></code>
provides a <code class="computeroutput"><a class="link" href="../boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code>
class template that creates a single overloaded function object that can
be used to call the specified functions instead of using the separate function
names (see also <a href="../../../test/functor.cpp" target="_top"><code class="literal">functor.cpp</code></a>
and <a href="../../../test/identity.hpp" target="_top"><code class="literal">identity.hpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">overloaded_function</span><span class="special">&lt;</span>
<span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&amp;</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">&amp;)</span>
<span class="special">,</span> <span class="keyword">int</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="special">,</span> <span class="keyword">double</span> <span class="special">(</span><span class="keyword">double</span><span class="special">)</span>
<span class="special">&gt;</span> <span class="identifier">identity</span><span class="special">(</span><span class="identifier">identity_s</span><span class="special">,</span> <span class="identifier">identity_i</span><span class="special">,</span> <span class="identifier">identity_d</span><span class="special">);</span>
<span class="comment">// All calls via single `identity` function.</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="string">"abc"</span><span class="special">)</span> <span class="special">==</span> <span class="string">"abc"</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="number">123</span><span class="special">)</span> <span class="special">==</span> <span class="number">123</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="number">1.23</span><span class="special">)</span> <span class="special">==</span> <span class="number">1.23</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
Note how each function type is passed as a template parameter of <code class="computeroutput"><a class="link" href="../boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code> using
the following syntax (this is <a href="http://www.boost.org/libs/function" target="_top">Boost.Function</a>'s
preferred syntax):
</p>
<pre class="programlisting"><span class="emphasis"><em>result-type</em></span> <span class="special">(</span><span class="emphasis"><em>argument1-type</em></span><span class="special">,</span> <span class="emphasis"><em>argument2-type</em></span><span class="special">,</span> <span class="special">...)</span>
</pre>
<p>
Then the relative function pointers, function references, or <a href="http://en.wikipedia.org/wiki/Polymorphism_(computer_science)" target="_top">monomorphic
function</a> objects are passed to the <code class="computeroutput"><a class="link" href="../boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code>
constructor matching the order of the specified template parameters. <a href="#ftn.boost_functional_overloadedfunction.tutorial.overloading.f0" class="footnote"><sup class="footnote"><a name="boost_functional_overloadedfunction.tutorial.overloading.f0"></a>[2]</sup></a> In the above example, <code class="computeroutput"><span class="identifier">identity_s</span></code>
is passed as a function pointer (the function address is automatically taken
from the function name by the compiler), <code class="computeroutput"><span class="identifier">identity_i</span></code>
as a function reference, and <code class="computeroutput"><span class="identifier">identity_d</span></code>
as a function object.
</p>
<p>
All specified function types must have distinct parameters from one another
(so the overloaded calls can be resolved by this library). <a href="#ftn.boost_functional_overloadedfunction.tutorial.overloading.f1" class="footnote"><sup class="footnote"><a name="boost_functional_overloadedfunction.tutorial.overloading.f1"></a>[3]</sup></a> In order to create an overloaded function object, it is necessary
to specify at least two function types (because there is nothing to overload
between one or zero functions).
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_functional_overloadedfunction.tutorial.without_function_types"></a><a class="link" href="tutorial.html#boost_functional_overloadedfunction.tutorial.without_function_types" title="Without Function Types">Without
Function Types</a>
</h3></div></div></div>
<p>
For convenience, this library also provides the <code class="computeroutput"><a class="link" href="../boost/make_overloaded_function.html" title="Function template make_overloaded_function">boost::make_overloaded_function</a></code>
function template which allows to create the overloaded function object without
explicitly specifying the function types. The function types are automatically
deduced from the specified functions and the appropriate <code class="computeroutput"><a class="link" href="../boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code>
instantiation is returned by <code class="computeroutput"><a class="link" href="../boost/make_overloaded_function.html" title="Function template make_overloaded_function">boost::make_overloaded_function</a></code>.
</p>
<p>
The <code class="computeroutput"><a class="link" href="../boost/make_overloaded_function.html" title="Function template make_overloaded_function">boost::make_overloaded_function</a></code>
function template can be useful when used together with <a href="http://www.boost.org/doc/libs/typeof" target="_top">Boost.Typeof</a>'s
<code class="computeroutput"><span class="identifier">BOOST_AUTO</span></code> (or C++11 <code class="computeroutput"><span class="keyword">auto</span></code>). For example (see also <a href="../../../test/make_decl.cpp" target="_top"><code class="literal">make_decl.cpp</code></a>
and <a href="../../../test/identity.hpp" target="_top"><code class="literal">identity.hpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">BOOST_AUTO</span><span class="special">(</span><span class="identifier">identity</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_overloaded_function</span><span class="special">(</span>
<span class="identifier">identity_s</span><span class="special">,</span> <span class="identifier">identity_i</span><span class="special">,</span> <span class="identifier">identity_d</span><span class="special">));</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="string">"abc"</span><span class="special">)</span> <span class="special">==</span> <span class="string">"abc"</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="number">123</span><span class="special">)</span> <span class="special">==</span> <span class="number">123</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="number">1.23</span><span class="special">)</span> <span class="special">==</span> <span class="number">1.23</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
Note how the overloaded function object <code class="computeroutput"><span class="identifier">identity</span></code>
has been created specifying only the functions <code class="computeroutput"><span class="identifier">identity_s</span></code>,
<code class="computeroutput"><span class="identifier">identity_i</span></code>, <code class="computeroutput"><span class="identifier">identity_d</span></code> and without specifying the function
types <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">&amp;</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">&amp;)</span></code>,
<code class="computeroutput"><span class="keyword">int</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span></code>, and
<code class="computeroutput"><span class="keyword">double</span> <span class="special">(</span><span class="keyword">double</span><span class="special">)</span></code> as
required instead by <code class="computeroutput"><a class="link" href="../boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code>.
Therefore, <code class="computeroutput"><a class="link" href="../boost/make_overloaded_function.html" title="Function template make_overloaded_function">boost::make_overloaded_function</a></code>
provides a more concise syntax in this context when compared with <code class="computeroutput"><a class="link" href="../boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code>.
</p>
<p>
Another case where <code class="computeroutput"><a class="link" href="../boost/make_overloaded_function.html" title="Function template make_overloaded_function">boost::make_overloaded_function</a></code>
can be useful is when the overloaded function object is passed to a function
template which can hold the specific <code class="computeroutput"><a class="link" href="../boost/overloaded_function.html" title="Class template overloaded_function">boost::overloaded_function</a></code>
type using a template parameter. For example (see also <a href="../../../test/make_call.cpp" target="_top"><code class="literal">make_call.cpp</code></a>
and <a href="../../../test/identity.hpp" target="_top"><code class="literal">identity.hpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">check</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">identity</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="string">"abc"</span><span class="special">)</span> <span class="special">==</span> <span class="string">"abc"</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="number">123</span><span class="special">)</span> <span class="special">==</span> <span class="number">123</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="number">1.23</span><span class="special">)</span> <span class="special">==</span> <span class="number">1.23</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">check</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_overloaded_function</span><span class="special">(</span><span class="identifier">identity_s</span><span class="special">,</span> <span class="identifier">identity_i</span><span class="special">,</span> <span class="identifier">identity_d</span><span class="special">));</span>
</pre>
<p>
</p>
<p>
The library implementation of <code class="computeroutput"><a class="link" href="../boost/make_overloaded_function.html" title="Function template make_overloaded_function">boost::make_overloaded_function</a></code>
uses <a href="http://www.boost.org/doc/libs/typeof" target="_top">Boost.Typeof</a>
to automatically deduce some of the function types. In order to compile code
in <a href="http://www.boost.org/doc/libs/typeof" target="_top">Boost.Typeof</a>
emulation mode, all types should be properly registered using <code class="computeroutput"><span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span></code> and <code class="computeroutput"><span class="identifier">BOOST_TYPEOF_REGISTER_TEMPLATE</span></code>, or appropriate
<a href="http://www.boost.org/doc/libs/typeof" target="_top">Boost.Typeof</a> headers
should be included (see <a href="http://www.boost.org/doc/libs/typeof" target="_top">Boost.Typeof</a>
for more information). For the above examples, it is sufficient to include
the <a href="http://www.boost.org/doc/libs/typeof" target="_top">Boost.Typeof</a>
header that registers <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
(this library does not require to register <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span></code>
for <a href="http://www.boost.org/doc/libs/typeof" target="_top">Boost.Typeof</a>
emulation):
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">typeof</span><span class="special">/</span><span class="identifier">std</span><span class="special">/</span><span class="identifier">string</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <span class="comment">// No need to register `boost::function`.</span>
</pre>
<p>
</p>
</div>
<div class="footnotes">
<br><hr style="width:100; align:left;">
<div id="ftn.boost_functional_overloadedfunction.tutorial.overloading.f0" class="footnote"><p><a href="#boost_functional_overloadedfunction.tutorial.overloading.f0" class="para"><sup class="para">[2] </sup></a>
Function pointers are of the form <code class="literal"><span class="emphasis"><em>result-type </em></span></code><code class="computeroutput"><span class="special">(*)(</span></code><code class="literal"><span class="emphasis"><em>argument1-type</em></span></code><code class="computeroutput"><span class="special">,</span> <span class="special">...)</span></code> (the
C++ compiler is usually able to automatically promote a function name to
a function pointer in a context where a function pointer is expected even
if the function name is not prefixed by <code class="computeroutput"><span class="special">&amp;</span></code>).
Function references are of the form <code class="literal"><span class="emphasis"><em>result-type </em></span></code><code class="computeroutput"><span class="special">(&amp;)(</span></code><code class="literal"><span class="emphasis"><em>argument1-type</em></span></code><code class="computeroutput"><span class="special">,</span> <span class="special">...)</span></code>.
Function types are of the form <code class="literal"><span class="emphasis"><em>result-type </em></span></code><code class="computeroutput"><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>argument1-type</em></span></code><code class="computeroutput"><span class="special">,</span> <span class="special">...)</span></code> (note
how they lack of both <code class="computeroutput"><span class="special">*</span></code> and
<code class="computeroutput"><span class="special">&amp;</span></code> when compared to function
pointers and function references). Finally, monomorphic function objects
are instances of classes with a non-template call operator of the form
<code class="literal"><span class="emphasis"><em>result-type </em></span></code><code class="computeroutput"><span class="keyword">operator</span><span class="special">()(</span></code><code class="literal"><span class="emphasis"><em>argument1-type</em></span></code><code class="computeroutput"><span class="special">,</span> <span class="special">...)</span></code>.
Unfortunately, it is not possible to support polymorphic function objects
(see <a href="http://lists.boost.org/Archives/boost/2012/03/191744.php" target="_top">http://lists.boost.org/Archives/boost/2012/03/191744.php</a>).
</p></div>
<div id="ftn.boost_functional_overloadedfunction.tutorial.overloading.f1" class="footnote"><p><a href="#boost_functional_overloadedfunction.tutorial.overloading.f1" class="para"><sup class="para">[3] </sup></a>
Note that in C++ the function result type is not used for overload resolution
(to avoid making the overload resolution context dependent). Therefore,
at least one of the function parameters must be distinct for each specified
function type.
</p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2011, 2012 Lorenzo Caminiti<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></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="getting_started.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,147 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="next" href="boost_functional_overloadedfunction/getting_started.html" title="Getting Started">
</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"><a accesskey="n" href="boost_functional_overloadedfunction/getting_started.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a></div>
<div class="chapter">
<div class="titlepage"><div>
<div><h2 class="title">
<a name="boost_functional_overloadedfunction"></a>Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0</h2></div>
<div><div class="author"><h3 class="author">
<span class="firstname">Lorenzo</span> <span class="surname">Caminiti <code class="email">&lt;<a class="email" href="mailto:lorcaminiti@gmail.com">lorcaminiti@gmail.com</a>&gt;</code></span>
</h3></div></div>
<div><p class="copyright">Copyright &#169; 2011, 2012 Lorenzo Caminiti</p></div>
<div><div class="legalnotice">
<a name="boost_functional_overloadedfunction.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></div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="section"><a href="index.html#boost_functional_overloadedfunction.introduction">Introduction</a></span></dt>
<dt><span class="section"><a href="boost_functional_overloadedfunction/getting_started.html">Getting
Started</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="boost_functional_overloadedfunction/getting_started.html#boost_functional_overloadedfunction.getting_started.compilers_and_platforms">Compilers
and Platforms</a></span></dt>
<dt><span class="section"><a href="boost_functional_overloadedfunction/getting_started.html#boost_functional_overloadedfunction.getting_started.installation">Installation</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="boost_functional_overloadedfunction/tutorial.html">Tutorial</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="boost_functional_overloadedfunction/tutorial.html#boost_functional_overloadedfunction.tutorial.overloading">Overloading</a></span></dt>
<dt><span class="section"><a href="boost_functional_overloadedfunction/tutorial.html#boost_functional_overloadedfunction.tutorial.without_function_types">Without
Function Types</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="reference.html">Reference</a></span></dt>
<dd><dl>
<dt><span class="section"><a href="reference.html#header.boost.functional.overloaded_function_hpp">Header &lt;boost/functional/overloaded_function.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.functional.overloaded_function.config_hpp">Header &lt;boost/functional/overloaded_function/config.hpp&gt;</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="boost_functional_overloadedfunction/acknowledgments.html">Acknowledgments</a></span></dt>
</dl>
</div>
<p>
This library allows to overload different functions into a single function object.
</p>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functional_overloadedfunction.introduction"></a><a class="link" href="index.html#boost_functional_overloadedfunction.introduction" title="Introduction">Introduction</a>
</h2></div></div></div>
<p>
Consider the following functions which have distinct signatures:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&amp;</span> <span class="identifier">identity_s</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">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="comment">// Function (as pointer).</span>
<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">identity_i_impl</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">int</span> <span class="special">(&amp;</span><span class="identifier">identity_i</span><span class="special">)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">identity_i_impl</span><span class="special">;</span> <span class="comment">// Function reference.</span>
<span class="keyword">double</span> <span class="identifier">identity_d_impl</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span><span class="special">;</span> <span class="special">}</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">double</span> <span class="special">(</span><span class="keyword">double</span><span class="special">)&gt;</span> <span class="identifier">identity_d</span> <span class="special">=</span> <span class="identifier">identity_d_impl</span><span class="special">;</span> <span class="comment">// Functor.</span>
</pre>
<p>
</p>
<p>
Instead of calling them using their separate names (here <code class="computeroutput"><span class="identifier">BOOST_TEST</span></code>
is equivalent to <code class="computeroutput"><span class="identifier">assert</span></code>):
<a href="#ftn.boost_functional_overloadedfunction.introduction.f0" class="footnote"><sup class="footnote"><a name="boost_functional_overloadedfunction.introduction.f0"></a>[1]</sup></a>
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity_s</span><span class="special">(</span><span class="string">"abc"</span><span class="special">)</span> <span class="special">==</span> <span class="string">"abc"</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity_i</span><span class="special">(</span><span class="number">123</span><span class="special">)</span> <span class="special">==</span> <span class="number">123</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity_d</span><span class="special">(</span><span class="number">1.23</span><span class="special">)</span> <span class="special">==</span> <span class="number">1.23</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
It is possible to use this library to create a single <a href="http://en.wikipedia.org/wiki/Function_overloading" target="_top">overloaded</a>
function object (or <a href="http://en.wikipedia.org/wiki/Functor" target="_top">functor</a>)
named <code class="computeroutput"><span class="identifier">identity</span></code> that aggregates
together the calls to the specific functions (see also <a href="../../test/functor.cpp" target="_top"><code class="literal">functor.cpp</code></a>
and <a href="../../test/identity.hpp" target="_top"><code class="literal">identity.hpp</code></a>):
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">overloaded_function</span><span class="special">&lt;</span>
<span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&amp;</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">&amp;)</span>
<span class="special">,</span> <span class="keyword">int</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span>
<span class="special">,</span> <span class="keyword">double</span> <span class="special">(</span><span class="keyword">double</span><span class="special">)</span>
<span class="special">&gt;</span> <span class="identifier">identity</span><span class="special">(</span><span class="identifier">identity_s</span><span class="special">,</span> <span class="identifier">identity_i</span><span class="special">,</span> <span class="identifier">identity_d</span><span class="special">);</span>
<span class="comment">// All calls via single `identity` function.</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="string">"abc"</span><span class="special">)</span> <span class="special">==</span> <span class="string">"abc"</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="number">123</span><span class="special">)</span> <span class="special">==</span> <span class="number">123</span><span class="special">);</span>
<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">identity</span><span class="special">(</span><span class="number">1.23</span><span class="special">)</span> <span class="special">==</span> <span class="number">1.23</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
Note how the functions are called via a single overloaded function object
<code class="computeroutput"><span class="identifier">identity</span></code> instead of using their
different names <code class="computeroutput"><span class="identifier">identity_s</span></code>,
<code class="computeroutput"><span class="identifier">identity_i</span></code>, and <code class="computeroutput"><span class="identifier">identity_d</span></code>.
</p>
</div>
<div class="footnotes">
<br><hr style="width:100; align:left;">
<div id="ftn.boost_functional_overloadedfunction.introduction.f0" class="footnote"><p><a href="#boost_functional_overloadedfunction.introduction.f0" class="para"><sup class="para">[1] </sup></a>
In most of the examples presented in this documentation, the Boost.Core/LightweightTest
(<code class="literal">boost/core/lightweight_test.hpp</code>) macro <code class="computeroutput"><span class="identifier">BOOST_TEST</span></code> is used to check correctness
conditions (conceptually similar to <code class="computeroutput"><span class="identifier">assert</span></code>).
A failure of the checked condition does not abort the execution of the program,
it will instead make <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span></code>
return a non-zero program exit code. Using Boost.Core/LightweightTest allows
to add the examples to the library regression tests so to make sure that
they always compile and run correctly.
</p></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 10, 2018 at 15:18:50 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
<div class="spirit-nav"><a accesskey="n" href="boost_functional_overloadedfunction/getting_started.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a></div>
</body>
</html>

View File

@@ -0,0 +1,66 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Reference</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<link rel="home" href="index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="up" href="index.html" title="Chapter&#160;1.&#160;Boost.Functional/OverloadedFunction 1.0.0">
<link rel="prev" href="boost_functional_overloadedfunction/tutorial.html" title="Tutorial">
<link rel="next" href="boost/overloaded_function.html" title="Class template overloaded_function">
</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">
<a accesskey="p" href="boost_functional_overloadedfunction/tutorial.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="boost/overloaded_function.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="reference"></a>Reference</h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="reference.html#header.boost.functional.overloaded_function_hpp">Header &lt;boost/functional/overloaded_function.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="reference.html#header.boost.functional.overloaded_function.config_hpp">Header &lt;boost/functional/overloaded_function/config.hpp&gt;</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.functional.overloaded_function_hpp"></a>Header &lt;<a href="../../../../../boost/functional/overloaded_function.hpp" target="_top">boost/functional/overloaded_function.hpp</a>&gt;</h3></div></div></div>
<p>Overload distinct function pointers, function references, and monomorphic function objects into a single function object. </p>
<pre class="synopsis"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> F1<span class="special">,</span> <span class="keyword">typename</span> F2<span class="special">,</span> <span class="special">...</span> <span class="special">&gt;</span> <span class="keyword">class</span> <a class="link" href="boost/overloaded_function.html" title="Class template overloaded_function">overloaded_function</a><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> F1<span class="special">,</span> <span class="keyword">typename</span> F2<span class="special">,</span> <span class="special">...</span> <span class="special">&gt;</span>
<a class="link" href="boost/overloaded_function.html" title="Class template overloaded_function">overloaded_function</a><span class="special">&lt;</span> <span class="identifier">__function_type__</span><span class="special">&lt;</span> <span class="identifier">F1</span> <span class="special">&gt;</span><span class="special">,</span> <span class="identifier">__function_type__</span><span class="special">&lt;</span> <span class="identifier">F2</span> <span class="special">&gt;</span><span class="special">,</span><span class="special">...</span> <span class="special">&gt;</span>
<a class="link" href="boost/make_overloaded_function.html" title="Function template make_overloaded_function"><span class="identifier">make_overloaded_function</span></a><span class="special">(</span><span class="identifier">F1</span><span class="special">,</span> <span class="identifier">F2</span><span class="special">,</span> <span class="special">...</span><span class="special">)</span><span class="special">;</span>
<span class="special">}</span></pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="header.boost.functional.overloaded_function.config_hpp"></a>Header &lt;<a href="../../../../../boost/functional/overloaded_function/config.hpp" target="_top">boost/functional/overloaded_function/config.hpp</a>&gt;</h3></div></div></div>
<p>Change the compile-time configuration of this library. </p>
<pre class="synopsis">
<a class="link" href="BOOST_FUNCTIONAL_O_1_7_3_2.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX</a>
<a class="link" href="BOOST_FUNCTIONAL_O_1_7_3_3.html" title="Macro BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX">BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX</a></pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2011, 2012 Lorenzo Caminiti<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></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="boost_functional_overloadedfunction/tutorial.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="boost/overloaded_function.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,171 @@
[/ Copyright (C) 2009-2012 Lorenzo Caminiti ]
[/ Distributed under the Boost Software License, Version 1.0 ]
[/ (see accompanying file LICENSE_1_0.txt or a copy at ]
[/ http://www.boost.org/LICENSE_1_0.txt) ]
[/ Home at http://www.boost.org/libs/functional/overloaded_function ]
[library Boost.Functional/OverloadedFunction
[quickbook 1.5]
[version 1.0.0]
[copyright 2011-2012 Lorenzo Caminiti]
[purpose overload functions with one function object]
[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 [Caminiti <email>lorcaminiti@gmail.com</email>, Lorenzo]]
[category Function Objects and Higher-Order Programming]
]
[def __Introduction__ [link functional_overloaded_function.introduction Introduction]]
[def __Getting_Started__ [link functional_overloaded_function.getting_started Getting Started]]
[def __Tutorial__ [link functional_overloaded_function.tutorial Tutorial]]
[def __Boost__ [@http://www.boost.org Boost]]
[def __Boost_Test__ [@http://www.boost.org/libs/test Boost.Test]]
[def __Boost_Function__ [@http://www.boost.org/libs/function Boost.Function]]
[def __Boost_Typeof__ [@http://www.boost.org/doc/libs/typeof Boost.Typeof]]
[import ../test/identity.hpp]
[import ../test/functor.cpp]
[import ../test/make_decl.cpp]
[import ../test/make_call.cpp]
This library allows to overload different functions into a single function object.
[section Introduction]
Consider the following functions which have distinct signatures:
[identity_decls]
Instead of calling them using their separate names (here `BOOST_TEST` is equivalent to `assert`):
[footnote
In most of the examples presented in this documentation, the Boost.Core/LightweightTest (=boost/core/lightweight_test.hpp=) macro `BOOST_TEST` is used to check correctness conditions (conceptually similar to `assert`).
A failure of the checked condition does not abort the execution of the program, it will instead make `boost::report_errors` return a non-zero program exit code.
Using Boost.Core/LightweightTest allows to add the examples to the library regression tests so to make sure that they always compile and run correctly.
]
[identity_calls]
It is possible to use this library to create a single [@http://en.wikipedia.org/wiki/Function_overloading overloaded] function object (or [@http://en.wikipedia.org/wiki/Functor functor]) named `identity` that aggregates together the calls to the specific functions (see also [@../../test/functor.cpp =functor.cpp=] and [@../../test/identity.hpp =identity.hpp=]):
[identity_functor]
Note how the functions are called via a single overloaded function object `identity` instead of using their different names `identity_s`, `identity_i`, and `identity_d`.
[endsect]
[section Getting Started]
This section explains how to setup a system to use this library.
[section Compilers and Platforms]
The authors originally developed and tested this library on:
# GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled `-std=c++0x`) on Cygwin.
# Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7.
See the library [@http://www.boost.org/development/tests/release/developer/functional-overloaded_function.html regressions test results] for detailed information on supported compilers and platforms.
Check the library regression test [@../../test/Jamfile.v2 =Jamfile.v2=] for any special configuration that might be required for a specific compiler.
[endsect]
[section Installation]
This library is composed of header files only.
Therefore there is no pre-compiled object file which needs to be installed.
Programmers can simply instruct the compiler where to find the library header files (`-I` option on GCC, `/I` option on MSVC, etc) and compile code using the library.
The maximum number of functions to overload is given by the [macroref BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_OVERLOAD_MAX] configuration macro.
The maximum number of function parameters for each of the specified function type is given by the [macroref BOOST_FUNCTIONAL_OVERLOADED_FUNCTION_CONFIG_ARITY_MAX] configuration macro.
All configuration macros have appropriate default values when they are left undefined.
[endsect]
[endsect]
[section Tutorial]
This section explains how to use this library.
[section Overloading]
Consider the following functions which have distinct signatures:
[identity_decls]
This library header [headerref boost/functional/overloaded_function.hpp] provides a [classref boost::overloaded_function] class template that creates a single overloaded function object that can be used to call the specified functions instead of using the separate function names (see also [@../../test/functor.cpp =functor.cpp=] and [@../../test/identity.hpp =identity.hpp=]):
[identity_functor]
Note how each function type is passed as a template parameter of [classref boost::overloaded_function] using the following syntax (this is __Boost_Function__'s preferred syntax):
``/result-type/`` (``/argument1-type/``, ``/argument2-type/``, ...)
Then the relative function pointers, function references, or [@http://en.wikipedia.org/wiki/Polymorphism_(computer_science) monomorphic function] objects are passed to the [classref boost::overloaded_function] constructor matching the order of the specified template parameters.
[footnote
Function pointers are of the form [^['result-type ]]`(*)(`[^['argument1-type]]`, ...)` (the C++ compiler is usually able to automatically promote a function name to a function pointer in a context where a function pointer is expected even if the function name is not prefixed by `&`).
Function references are of the form [^['result-type ]]`(&)(`[^['argument1-type]]`, ...)`.
Function types are of the form [^['result-type ]]`(`[^['argument1-type]]`, ...)` (note how they lack of both `*` and `&` when compared to function pointers and function references).
Finally, monomorphic function objects are instances of classes with a non-template call operator of the form [^['result-type ]]`operator()(`[^['argument1-type]]`, ...)`.
Unfortunately, it is not possible to support polymorphic function objects (see [@http://lists.boost.org/Archives/boost/2012/03/191744.php]).
]
In the above example, `identity_s` is passed as a function pointer (the function address is automatically taken from the function name by the compiler), `identity_i` as a function reference, and `identity_d` as a function object.
All specified function types must have distinct parameters from one another (so the overloaded calls can be resolved by this library).
[footnote
Note that in C++ the function result type is not used for overload resolution (to avoid making the overload resolution context dependent).
Therefore, at least one of the function parameters must be distinct for each specified function type.
]
In order to create an overloaded function object, it is necessary to specify at least two function types (because there is nothing to overload between one or zero functions).
[endsect]
[section Without Function Types]
For convenience, this library also provides the [funcref boost::make_overloaded_function] function template which allows to create the overloaded function object without explicitly specifying the function types.
The function types are automatically deduced from the specified functions and the appropriate [classref boost::overloaded_function] instantiation is returned by [funcref boost::make_overloaded_function].
The [funcref boost::make_overloaded_function] function template can be useful when used together with __Boost_Typeof__'s `BOOST_AUTO` (or C++11 `auto`).
For example (see also [@../../test/make_decl.cpp =make_decl.cpp=] and [@../../test/identity.hpp =identity.hpp=]):
[identity_make_decl]
Note how the overloaded function object `identity` has been created specifying only the functions `identity_s`, `identity_i`, `identity_d` and without specifying the function types `const std::string& (const std::string&)`, `int (int)`, and `double (double)` as required instead by [classref boost::overloaded_function].
Therefore, [funcref boost::make_overloaded_function] provides a more concise syntax in this context when compared with [classref boost::overloaded_function].
Another case where [funcref boost::make_overloaded_function] can be useful is when the overloaded function object is passed to a function template which can hold the specific [classref boost::overloaded_function] type using a template parameter.
For example (see also [@../../test/make_call.cpp =make_call.cpp=] and [@../../test/identity.hpp =identity.hpp=]):
[identity_make_checks]
[identity_make_call]
The library implementation of [funcref boost::make_overloaded_function] uses __Boost_Typeof__ to automatically deduce some of the function types.
In order to compile code in __Boost_Typeof__ emulation mode, all types should be properly registered using `BOOST_TYPEOF_REGISTER_TYPE` and `BOOST_TYPEOF_REGISTER_TEMPLATE`, or appropriate __Boost_Typeof__ headers should be included (see __Boost_Typeof__ for more information).
For the above examples, it is sufficient to include the __Boost_Typeof__ header that registers `std::string` (this library does not require to register `boost::function` for __Boost_Typeof__ emulation):
[identity_typeof]
[endsect]
[endsect]
[xinclude reference.xml]
[section Acknowledgments]
Many thanks to Mathias Gaunard for suggesting to implement [classref boost::overloaded_function] and for some sample code.
Thanks to John Bytheway for suggesting to implement [funcref boost::make_overloaded_function].
Thanks to Nathan Ridge for suggestions on how to implement [funcref boost::make_overloaded_function].
Thanks to Robert Stewart for commenting on the library name.
Many thanks to the entire __Boost__ community and mailing list for providing valuable comments about this library and great insights on the C++ programming language.
[endsect]

View File

@@ -0,0 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatic redirection failed, click this
<a href="doc/html/index.html">link</a> &nbsp;<hr>
<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
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

View File

@@ -0,0 +1,16 @@
# Copyright (C) 2009-2012 Lorenzo Caminiti
# Distributed under the Boost Software License, Version 1.0
# (see accompanying file LICENSE_1_0.txt or a copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Home at http://www.boost.org/libs/functional/overloaded_function
import testing ;
# Sun does not automatically detect type-of emulation (force it).
project : requirements <toolset>sun:<define>BOOST_TYPEOF_EMULATION ;
run functor.cpp ;
run make_decl.cpp ;
run make_call.cpp ;

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/functional/overloaded_function
#include "identity.hpp"
#include <boost/functional/overloaded_function.hpp>
#include <boost/core/lightweight_test.hpp>
int main() {
//[identity_calls
BOOST_TEST(identity_s("abc") == "abc");
BOOST_TEST(identity_i(123) == 123);
BOOST_TEST(identity_d(1.23) == 1.23);
//]
//[identity_functor
boost::overloaded_function<
const std::string& (const std::string&)
, int (int)
, double (double)
> identity(identity_s, identity_i, identity_d);
// All calls via single `identity` function.
BOOST_TEST(identity("abc") == "abc");
BOOST_TEST(identity(123) == 123);
BOOST_TEST(identity(1.23) == 1.23);
//]
return boost::report_errors();
}

View File

@@ -0,0 +1,29 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/functional/overloaded_function
#ifndef IDENTITY_HPP_
#define IDENTITY_HPP_
//[identity_typeof
#include <boost/typeof/std/string.hpp> // No need to register `boost::function`.
//]
#include <boost/function.hpp>
#include <string>
//[identity_decls
const std::string& identity_s(const std::string& x) // Function (as pointer).
{ return x; }
int identity_i_impl(int x) { return x; }
int (&identity_i)(int) = identity_i_impl; // Function reference.
double identity_d_impl(double x) { return x; }
boost::function<double (double)> identity_d = identity_d_impl; // Functor.
//]
#endif // #include guard

View File

@@ -0,0 +1,27 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/functional/overloaded_function
#include "identity.hpp"
#include <boost/functional/overloaded_function.hpp>
#include <boost/core/lightweight_test.hpp>
//[identity_make_checks
template<typename F>
void check(F identity) {
BOOST_TEST(identity("abc") == "abc");
BOOST_TEST(identity(123) == 123);
BOOST_TEST(identity(1.23) == 1.23);
}
//]
int main() {
//[identity_make_call
check(boost::make_overloaded_function(identity_s, identity_i, identity_d));
//]
return boost::report_errors();
}

View File

@@ -0,0 +1,24 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/functional/overloaded_function
#include "identity.hpp"
#include <boost/functional/overloaded_function.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/core/lightweight_test.hpp>
int main() {
//[identity_make_decl
BOOST_AUTO(identity, boost::make_overloaded_function(
identity_s, identity_i, identity_d));
BOOST_TEST(identity("abc") == "abc");
BOOST_TEST(identity(123) == 123);
BOOST_TEST(identity(1.23) == 1.23);
//]
return boost::report_errors();
}

View File

@@ -0,0 +1,158 @@
<!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>Boost Function Object Adapter Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2" summary="">
<tr>
<td bgcolor="#FFFFFF"><img src="../../boost.png" alt=
"boost.png (6897 bytes)" width="277" height="86"></td>
<td><a href="../../index.htm"><font face="Arial" color=
"#FFFFFF"><big>Home</big></font></a></td>
<td><a href="../libraries.htm"><font face="Arial" color=
"#FFFFFF"><big>Libraries</big></font></a></td>
<td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color=
"#FFFFFF"><big>People</big></font></a></td>
<td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color=
"#FFFFFF"><big>FAQ</big></font></a></td>
<td><a href="../../more/index.htm"><font face="Arial" color=
"#FFFFFF"><big>More</big></font></a></td>
</tr>
</table>
<h1>Function Pointer Adapters</h1>
<p>The header <a href="../../boost/functional.hpp">functional.hpp</a>
provides enhanced versions of both the function pointer adapters from the
C++ Standard Library (&sect;20.3.7):</p>
<ul>
<li><tt>pointer_to_unary_function</tt></li>
<li><tt>pointer_to_binary_function</tt></li>
</ul>
<p>As well as the corresponding helper function template:</p>
<ul>
<li><tt>ptr_fun</tt></li>
</ul>
<p>However, you should not need to use the adapters in conjunction with the
adapters in this library due to our use of <a href=
"function_traits.html">function object traits</a>. You will however need to
use them if your implementation fails to work properly with our traits
classes (due to lack if partial specialisation), or if you wish to use a
function object adapter from a third party.</p>
<h3>Usage</h3>
<p>If you need to use these adapters, usage is identical to the standard
function pointer adapters. For example,</p>
<blockquote>
<pre>
bool bad(std::string foo) { ... }
...
std::vector&lt;std::string&gt; c;
...
std::vector&lt;std::string&gt;::iterator it
= std::find_if(c.begin(), c.end(), std::not1(boost::ptr_fun(bad)));
</pre>
</blockquote>
<p>Note however that this library contains enhanced <a href=
"negators.html">negators</a> that support function object traits, so the
line above could equally be written</p>
<blockquote>
<pre>
std::vector&lt;std::string&gt;::iterator it
= std::find_if(c.begin(), c.end(), boost::not1(bad));
</pre>
</blockquote>
<h3>Argument Types</h3>
<p>The standard defines <tt>pointer_to_unary_function</tt> like this
(&sect;20.3.8&nbsp;&para;2):</p>
<blockquote>
<pre>
template &lt;class Arg, class Result&gt;
class pointer_to_unary_function : public unary_function&lt;Arg, Result&gt; {
public:
explicit pointer_to_unary_function(Result (* f)(<strong>Arg</strong>));
Result operator()(<strong>Arg</strong> x) const;
};
</pre>
</blockquote>
<p>Note that the argument to <tt>operator()</tt> is exactly the same type
as the argument to the wrapped function. If this is a value type, the
argument will be passed by value and copied twice.
<tt>pointer_to_binary_function</tt> has a similar problem.</p>
<p>However, if we were to try and eliminate this inefficiency by instead
declaring the argument as <tt>const&nbsp;Arg&amp;</tt>, then if Arg were a
reference type, we would have a reference to a reference, which is
currently illegal (but see <a href=
"http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#106">C++ core
language issue number 106)</a></p>
<p>So the way in which we want to declare the argument for
<tt>operator()</tt> depends on whether or not the wrapped function's
argument is a reference. If it is a reference, we want to declare it simply
as <tt>Arg</tt>; if it is a value we want to declare it as
<tt>const&nbsp;Arg&amp;</tt>.</p>
<p>The Boost <a href="../utility/call_traits.htm">call_traits</a> class
template contains a <tt>param_type</tt> typedef, which uses partial
specialisation to make precisely this decision. By declaring the
<tt>operator()</tt> as</p>
<blockquote>
<pre>
Result operator()(typename call_traits&lt;Arg&gt;::param_type x) const
</pre>
</blockquote>
<p>we achieve the desired result - we improve efficiency without generating
references to references.</p>
<h3>Limitations</h3>
<p>The call traits template used to realise this improvement relies on
partial specialisation, so this improvement is only available on compilers
that support that feature. With other compilers, the argument passed to the
function will always be passed by reference, thus generating the
possibility of references to references.</p>
<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 -->02
December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
<p><i>Copyright &copy; 2000 Cadenza New Zealand Ltd.</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>

View File

@@ -0,0 +1,13 @@
#~ Copyright Rene Rivera 2008
#~ 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)
import testing ;
test-suite functional :
[ run function_test.cpp ]
[ run identity_test.cpp ]
[ run identity_rvalue_test.cpp ]
[ run identity_result_of_test.cpp ]
[ run identity_result_of_rvalue_test.cpp ]
;

View File

@@ -0,0 +1,334 @@
// ------------------------------------------------------------------------------
// Copyright (c) 2000 Cadenza New Zealand Ltd
// Distributed under the Boost Software License, Version 1.0. (See accompany-
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// ------------------------------------------------------------------------------
// Tests for the Boost functional.hpp header file
//
// Note that functional.hpp relies on partial specialisation to be
// effective. If your compiler lacks this feature, very few of the
// tests would compile, and so have been excluded from the test.
// ------------------------------------------------------------------------------
// $Id$
// ------------------------------------------------------------------------------
// $Log$
// Revision 1.3 2006/12/02 13:57:32 andreas_huber69
// Fixed license & copyright issues.
//
// From Mark Rodgers Fri Dec 1 12:59:14 2006
// X-Apparently-To: ahd6974-boostorg -at- yahoo.com via 68.142.206.160; Fri, 01 Dec 2006 12:59:41 -0800
// X-Originating-IP: [195.112.4.54]
// Return-Path: <mark.rodgers -at- cadenza.co.nz>
// Authentication-Results: mta550.mail.mud.yahoo.com from=cadenza.co.nz; domainkeys=neutral (no sig)
// Received: from 195.112.4.54 (EHLO smtp.nildram.co.uk) (195.112.4.54) by mta550.mail.mud.yahoo.com with SMTP; Fri, 01 Dec 2006 12:59:40 -0800
// Received: from snagglepuss.cadenza.co.nz (81-6-246-87.dyn.gotadsl.co.uk [81.6.246.87]) by smtp.nildram.co.uk (Postfix) with ESMTP id D32EA2B6D8C for <ahd6974-boostorg -at- yahoo.com>; Fri, 1 Dec 2006 20:59:35 +0000 (GMT)
// Received: from penfold.cadenza.co.nz ([192.168.55.56]) by snagglepuss.cadenza.co.nz with esmtp (Exim 4.63) (envelope-from <mark.rodgers -at- cadenza.co.nz>) id J9M4Y9-0009TO-9K for ahd6974-boostorg -at- yahoo.com; Fri, 01 Dec 2006 20:58:57 +0000
// Message-ID: <457097A2.1090305@cadenza.co.nz>
// Date: Fri, 01 Dec 2006 20:59:14 +0000
// From: "Mark Rodgers" <mark.rodgers -at- cadenza.co.nz>
// User-Agent: Thunderbird 1.5.0.8 (Macintosh/20061025)
// MIME-Version: 1.0
// To: ahd6974-boostorg -at- yahoo.com [Edit - Delete]
// Subject: Re: [boost] Reminder: Need your permission to correct license & copyright issues
// References: <379990.36007.qm@web33507.mail.mud.yahoo.com>
// In-Reply-To: <379990.36007.qm@web33507.mail.mud.yahoo.com>
// Content-Type: text/plain; charset=ISO-8859-1; format=flowed
// Content-Transfer-Encoding: 7bit
// Content-Length: 812
// Gidday Andreas
//
// Sure that's fine. I'm happy for you to do 1, 2 and 3.
//
// Regards
// Mark
//
// Andreas Huber wrote:
// > Hello Mark
// >
// > Quite a while ago it was decided that every file that goes into the
// > 1.34 release of the Boost distribution (www.boost.org) needs uniform
// > license and copyright information. For more information please see:
// >
// > <http://www.boost.org/more/license_info.html>
// >
// > You are receiving this email because several files you contributed
// > lack such information or have an old license:
// >
// > boost/functional/functional.hpp
// > boost/libs/functional/binders.html
// > boost/libs/functional/function_test.cpp
// > boost/libs/functional/function_traits.html
// > boost/libs/functional/index.html
// > boost/libs/functional/mem_fun.html
// > boost/libs/functional/negators.html
// > boost/libs/functional/ptr_fun.html
// > boost/people/mark_rodgers.htm
// >
// > I therefore kindly ask you to grant the permission to do the
// > following:
// >
// > 1. For the files above that already have a license text (all except
// > mark_rodgers.htm), replace the license text with:
// >
// > "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)"
// >
// > 2. For the file that does not yet have a license and copyright
// > (mark_rodgers.htm) add the same license text as under 1. and add the
// > following copyright:
// >
// > "(c) Copyright Mark Rodgers 2000"
// >
// > 3. (Optional) I would also want to convert all HTML files to conform
// > the HTML 4.01 Standard by running them through HTML Tidy, see
// > <http://tidy.sf.net>
// >
// > It would be great if you could grant me permission to do 1 & 2 and
// > optionally also 3.
// >
// > Thank you!
// >
// > Regards,
// >
// > Andreas Huber
// >
//
// Revision 1.2 2001/09/22 11:52:24 johnmaddock
// Intel C++ fixes: no void return types supported.
//
// Revision 1.1.1.1 2000/07/07 16:04:18 beman
// 1.16.1 initial CVS checkin
//
// Revision 1.3 2000/06/26 09:44:01 mark
// Updated following feedback from Jens Maurer.
//
// Revision 1.2 2000/05/17 08:31:45 mark
// Added extra tests now that function traits work correctly.
// For compilers with no support for partial specialisation,
// excluded tests that won't work.
//
// Revision 1.1 2000/05/07 09:14:41 mark
// Initial revision
// ------------------------------------------------------------------------------
// To demonstrate what the boosted function object adapters do for
// you, try compiling with USE_STD defined. This will endeavour to
// use the standard function object adapters, but is likely to result
// in numerous errors due to the fact that you cannot have references
// to references.
#ifdef USE_STD
#include <functional>
#define boost std
#else
#include <boost/functional.hpp>
#endif
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
class Person
{
public:
Person() {}
Person(const char *n) : name(n) {}
const std::string &get_name() const { return name; }
void print(std::ostream &os) const { os << name << " "; }
void set_name(const std::string &n) { name = n; std::cout << name << " "; }
std::string clear_name() { std::string ret = name; name = ""; return ret; }
void do_something(int) const {}
bool is_fred() const { return name == "Fred"; }
private:
std::string name;
};
namespace
{
bool is_equal(const std::string &s1, const std::string &s2)
{
return s1 == s2;
}
bool is_betty(const std::string &s)
{
return s == "Betty";
}
void do_set_name(Person *p, const std::string &name)
{
p->set_name(name);
}
void do_set_name_ref(Person &p, const std::string &name)
{
p.set_name(name);
}
}
int main()
{
std::vector<Person> v1;
v1.push_back("Fred");
v1.push_back("Wilma");
v1.push_back("Barney");
v1.push_back("Betty");
const std::vector<Person> cv1(v1.begin(), v1.end());
std::vector<std::string> v2;
v2.push_back("Fred");
v2.push_back("Wilma");
v2.push_back("Barney");
v2.push_back("Betty");
Person person;
Person &r = person;
Person fred("Fred");
Person wilma("Wilma");
Person barney("Barney");
Person betty("Betty");
std::vector<Person*> v3;
v3.push_back(&fred);
v3.push_back(&wilma);
v3.push_back(&barney);
v3.push_back(&betty);
const std::vector<Person*> cv3(v3.begin(), v3.end());
std::vector<const Person*> v3c(v3.begin(), v3.end());
std::ostream &os = std::cout;
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__ICL)
// unary_traits, unary_negate
std::transform(v2.begin(), v2.end(),
std::ostream_iterator<bool>(std::cout, " "),
boost::not1(is_betty));
std::cout << '\n';
std::transform(v1.begin(), v1.end(),
std::ostream_iterator<bool>(std::cout, " "),
boost::not1(boost::mem_fun_ref(&Person::is_fred)));
// binary_traits, binary_negate
std::cout << '\n';
std::transform(v2.begin(), v2.end(),
std::ostream_iterator<bool>(std::cout, " "),
boost::bind1st(boost::not2(is_equal), "Betty"));
std::cout << '\n';
std::transform(v2.begin(), v2.end(),
std::ostream_iterator<bool>(std::cout, " "),
boost::bind2nd(boost::not2(is_equal), "Betty"));
// pointer_to_unary_function
std::cout << '\n';
std::transform(v2.begin(), v2.end(),
std::ostream_iterator<bool>(std::cout, " "),
boost::not1(boost::ptr_fun(is_betty)));
// binary_traits, bind1st, bind2nd
std::cout << '\n';
std::transform(v2.begin(), v2.end(),
std::ostream_iterator<bool>(std::cout, " "),
boost::bind1st(is_equal, "Betty"));
std::cout << '\n';
std::transform(v2.begin(), v2.end(),
std::ostream_iterator<bool>(std::cout, " "),
boost::bind2nd(is_equal, "Betty"));
// pointer_to_binary_function, bind1st
std::cout << '\n';
std::for_each(v2.begin(), v2.end(), boost::bind1st(boost::ptr_fun(do_set_name), &person));
std::cout << '\n';
std::for_each(v2.begin(), v2.end(), boost::bind1st(boost::ptr_fun(do_set_name_ref), person));
std::cout << '\n';
std::for_each(v2.begin(), v2.end(), boost::bind1st(boost::ptr_fun(do_set_name_ref), r));
// binary_traits
std::cout << '\n';
std::for_each(v2.begin(), v2.end(), boost::bind1st(do_set_name, &person));
std::cout << '\n';
std::for_each(v2.begin(), v2.end(), boost::bind1st(do_set_name_ref, person));
std::cout << '\n';
std::for_each(v2.begin(), v2.end(), boost::bind1st(do_set_name_ref, r));
#endif
// const_mem_fun_t
std::cout << '\n';
std::transform(v3.begin(), v3.end(),
std::ostream_iterator<std::string>(std::cout, " "),
boost::mem_fun(&Person::get_name));
std::cout << '\n';
std::transform(cv3.begin(), cv3.end(),
std::ostream_iterator<std::string>(std::cout, " "),
boost::mem_fun(&Person::get_name));
std::cout << '\n';
std::transform(v3c.begin(), v3c.end(),
std::ostream_iterator<std::string>(std::cout, " "),
boost::mem_fun(&Person::get_name));
// const_mem_fun_ref_t
std::cout << '\n';
std::transform(v1.begin(), v1.end(),
std::ostream_iterator<std::string>(std::cout, " "),
boost::mem_fun_ref(&Person::get_name));
std::cout << '\n';
std::transform(cv1.begin(), cv1.end(),
std::ostream_iterator<std::string>(std::cout, " "),
boost::mem_fun_ref(&Person::get_name));
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// const_mem_fun1_t, bind2nd
std::cout << '\n';
std::for_each(v3.begin(), v3.end(), boost::bind2nd(boost::mem_fun(&Person::print), std::cout));
std::cout << '\n';
std::for_each(v3.begin(), v3.end(), boost::bind2nd(boost::mem_fun(&Person::print), os));
// const_mem_fun1_ref_t, bind2nd
std::cout << '\n';
std::for_each(v1.begin(), v1.end(), boost::bind2nd(boost::mem_fun_ref(&Person::print), std::cout));
std::cout << '\n';
std::for_each(v1.begin(), v1.end(), boost::bind2nd(boost::mem_fun_ref(&Person::print), os));
// mem_fun1_t, bind1st
std::cout << '\n';
std::for_each(v2.begin(), v2.end(), boost::bind1st(boost::mem_fun(&Person::set_name), &person));
// mem_fun1_ref_t, bind1st
std::cout << '\n';
std::for_each(v2.begin(), v2.end(), boost::bind1st(boost::mem_fun_ref(&Person::set_name), person));
std::cout << '\n';
std::for_each(v2.begin(), v2.end(), boost::bind1st(boost::mem_fun_ref(&Person::set_name), r));
#endif
// mem_fun_t
std::cout << '\n';
std::transform(v3.begin(), v3.end(), std::ostream_iterator<std::string>(std::cout, " "),
boost::mem_fun(&Person::clear_name));
// mem_fun_ref_t
std::cout << '\n';
std::transform(v1.begin(), v1.end(), std::ostream_iterator<std::string>(std::cout, " "),
boost::mem_fun_ref(&Person::clear_name));
std::cout << '\n';
return 0;
}

View File

@@ -0,0 +1,31 @@
/*
Copyright 2022 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <boost/functional/identity.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/utility/result_of.hpp>
int main()
{
BOOST_TEST_TRAIT_SAME(boost::result_of<boost::identity(int)>::type,
int&&);
BOOST_TEST_TRAIT_SAME(boost::result_of<boost::identity(const int)>::type,
int&&);
BOOST_TEST_TRAIT_SAME(boost::result_of<boost::identity(int&&)>::type,
int&&);
BOOST_TEST_TRAIT_SAME(boost::result_of<boost::identity(const int&&)>::type,
const int&&);
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,18 @@
/*
Copyright 2022 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/identity.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/utility/result_of.hpp>
int main()
{
BOOST_TEST_TRAIT_SAME(boost::result_of<boost::identity(int&)>::type, int&);
BOOST_TEST_TRAIT_SAME(boost::result_of<boost::identity(const int&)>::type,
const int&);
return boost::report_errors();
}

View File

@@ -0,0 +1,75 @@
/*
Copyright 2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <boost/functional/identity.hpp>
#include <boost/core/lightweight_test.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
enum kind {
rvalue,
crvalue,
other
};
kind result(std::string&&)
{
return rvalue;
}
kind result(const std::string&&)
{
return crvalue;
}
template<class T>
kind result(T&&)
{
return other;
}
void simple_test()
{
typedef std::string string;
BOOST_TEST(boost::identity()(string("a")) == string("a"));
BOOST_TEST(result(boost::identity()(string("a"))) == rvalue);
typedef const std::string cstring;
BOOST_TEST(boost::identity()(cstring("a")) == cstring("a"));
BOOST_TEST(result(boost::identity()(cstring("a"))) == crvalue);
}
void algorithm_test()
{
std::vector<std::string> v1;
v1.push_back(std::string("a"));
v1.push_back(std::string("b"));
v1.push_back(std::string("c"));
std::vector<std::string> v2(v1);
std::vector<std::string> v3;
std::transform(std::make_move_iterator(v2.begin()),
std::make_move_iterator(v2.end()),
std::back_inserter(v3),
boost::identity());
BOOST_TEST(v3 == v1);
}
int main()
{
simple_test();
algorithm_test();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,72 @@
/*
Copyright 2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/identity.hpp>
#include <boost/core/lightweight_test.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
enum kind {
ref,
cref,
other
};
kind result(std::string&)
{
return ref;
}
kind result(const std::string&)
{
return cref;
}
template<class T>
kind result(T&)
{
return other;
}
template<class T>
kind result(const T&)
{
return other;
}
void simple_test()
{
std::string s1("a");
BOOST_TEST(boost::identity()(s1) == s1);
BOOST_TEST(&boost::identity()(s1) == &s1);
BOOST_TEST(result(boost::identity()(s1)) == ref);
const std::string s2("a");
BOOST_TEST(boost::identity()(s2) == s2);
BOOST_TEST(&boost::identity()(s2) == &s2);
BOOST_TEST(result(boost::identity()(s2)) == cref);
}
void algorithm_test()
{
std::vector<std::string> v1;
v1.push_back(std::string("a"));
v1.push_back(std::string("b"));
v1.push_back(std::string("c"));
std::vector<std::string> v2;
std::transform(v1.begin(), v1.end(), std::back_inserter(v2),
boost::identity());
BOOST_TEST(v2 == v1);
}
int main()
{
simple_test();
algorithm_test();
return boost::report_errors();
}

View File

@@ -0,0 +1,7 @@
-- Downloading https://github.com/boostorg/functional/archive/boost-1.79.0.tar.gz -> boostorg-functional-boost-1.79.0.tar.gz...
-- Extracting source D:/a/1/s/externals/vcpkg/downloads/boostorg-functional-boost-1.79.0.tar.gz
-- Using source at D:/a/1/s/externals/vcpkg/buildtrees/boost-functional/src/ost-1.79.0-741881ec28.clean
-- Copying headers
-- Copying headers done
-- Installing: D:/a/1/s/externals/vcpkg/packages/boost-functional_x64-windows/share/boost-functional/usage
-- Installing: D:/a/1/s/externals/vcpkg/packages/boost-functional_x64-windows/share/boost-functional/copyright

View File

@@ -0,0 +1,21 @@
boost-config 797535e8975ed7cf5bbe11d9f7fe26caa5da8fe819888564758d82a21109fade
boost-core 498aea0b6b68bcfe1ec683e76c2f0d32477dfe9ba958f518980ff806b6faba90
boost-function fb9fcf8a7e9bcbcde04a10397958d4090714de5b6cbbf29ecd04e5091ab5778d
boost-function-types 62bb37e6456348c32f9971b254f2647c013769fb4e5263fe293f32fb4a75c597
boost-mpl 89695bf75ab1fa2b706b2a0c2ef28c6726c3abd61ff51fb0966e3270153a6cd9
boost-preprocessor bf16615c7acc80769793c4f62c492a31cf3d22cd0d8393ccfd77d192da7c41b2
boost-type-traits 74f62124585467fbb6c4fa16015164d11e1a079d6bdb70ec1c3fe7cf65b9a594
boost-typeof aa3e58f01b489bc8672d51c4fbd25562aa3e06fcea0e131b1160d546b2a5f3a7
boost-utility cbe2d95223a1f8fb253145878922052018dccca3926ffb59d0e20676d6b0d3ac
boost-vcpkg-helpers c81c7b003df356a1a120a7c0c2f5a2ac95f3c33b006a2a5b4c02dcf0c9f3deaa
cmake 3.23.2
features core
portfile.cmake dd2ba57d688328c6c6cb576907dc38679415dcf09170d2e60f771d4715792779
ports.cmake 366c60b768113102408b32ac1d7c7b48ef7d30a477af2a220ecc222d9ffa3166
post_build_checks 2
powershell 7.2.5
triplet x64-windows
triplet_abi 4556164a2cd3dd6f4742101eabb46def7e71b6e5856faa88e5d005aac12a803c-c0600b35e024ce0485ed253ef5419f3686f7257cfb58cb6a24febcb600fc4b4c-27ebd443f77a6c449168adfa6ce8def60cf46e88
vcpkg.json 3aef10a004fa4ff59711e14b44eaef76fb8519f49eb725fbb784a6118cf39e7f
vcpkg_from_git 0aab20e34e84d52ba4763f009e539bfa8f418c41c918c8cf700156f1a8551a10
vcpkg_from_github b743742296a114ea1b18ae99672e02f142c4eb2bef7f57d36c038bedbfb0502f