mirror of
https://github.com/boostorg/functional.git
synced 2025-07-29 12:07:19 +02:00
Merge branch 'develop'
This commit is contained in:
61
.appveyor.yml
Normal file
61
.appveyor.yml
Normal file
@ -0,0 +1,61 @@
|
||||
# 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
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-10.0
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-11.0
|
||||
- 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 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%
|
351
.travis.yml
351
.travis.yml
@ -1,74 +1,293 @@
|
||||
# Copyright (C) 2016 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)
|
||||
# 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
|
||||
|
||||
# Use Trusty to get a reasonably recent version of Boost.
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
language: c++
|
||||
python: "2.7"
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
env: |
|
||||
USER_CONFIG="using gcc : : g++-4.8 ;"
|
||||
CXXSTD=03,11
|
||||
- compiler: clang
|
||||
env: |
|
||||
USER_CONFIG="using clang : : clang++ ;"
|
||||
CXXSTD=03,11
|
||||
- compiler: clang
|
||||
env: |
|
||||
USER_CONFIG="using clang : : clang++ -D_HAS_AUTO_PTR_ETC=0 ;"
|
||||
CXXSTD=11
|
||||
|
||||
before_script:
|
||||
- export BOOST_VERSION=1.67.0
|
||||
- export BOOST_FILENAME=boost_1_67_0
|
||||
- export BOOST_ROOT=${HOME}/boost
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- touch Jamroot.jam
|
||||
- cd $HOME
|
||||
- echo $USER_CONFIG > ~/user-config.jam
|
||||
- cat ~/user-config.jam
|
||||
- |
|
||||
mkdir $HOME/download
|
||||
mkdir $HOME/extract
|
||||
cd $HOME/download
|
||||
if [ "$TRAVIS_EVENT_TYPE" == "cron" ]
|
||||
then
|
||||
if [ "$TRAVIS_BRANCH" == "master" ]
|
||||
then
|
||||
snapshot_branch=master
|
||||
else
|
||||
snapshot_branch=develop
|
||||
fi
|
||||
download_url=$(curl https://api.bintray.com/packages/boostorg/$snapshot_branch/snapshot/files |
|
||||
python -c "import os.path, sys, json; x = json.load(sys.stdin); print '\n'.join(a['path'] for a in x if os.path.splitext(a['path'])[1] == '.bz2')" |
|
||||
head -n 1 |
|
||||
sed "s/^/http:\/\/dl.bintray.com\/boostorg\/$snapshot_branch\//")
|
||||
else
|
||||
download_url=https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/${BOOST_FILENAME}.tar.bz2/download
|
||||
fi
|
||||
echo "Downloading ${download_url}"
|
||||
wget -O boost.tar.bz2 $download_url
|
||||
cd $HOME/extract
|
||||
tar -xjf $HOME/download/boost.tar.bz2
|
||||
mv * ${BOOST_ROOT}
|
||||
- rm ${BOOST_ROOT}/boost/functional.hpp
|
||||
- find ${BOOST_ROOT}/boost/functional -type f | grep -v hash | xargs -r rm
|
||||
- cd ${BOOST_ROOT}/tools/build
|
||||
- mkdir ${HOME}/opt
|
||||
- ./bootstrap.sh
|
||||
- ./b2 install --prefix=$HOME/opt
|
||||
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: 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 STANDARD=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 functional
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- cd ${TRAVIS_BUILD_DIR}/test
|
||||
- ${HOME}/opt/bin/b2 -j 3 cxxstd=$CXXSTD -q include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include
|
||||
- cd ${TRAVIS_BUILD_DIR}/forward/test
|
||||
- ${HOME}/opt/bin/b2 -j 3 cxxstd=$CXXSTD -q include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include
|
||||
- cd ${TRAVIS_BUILD_DIR}/factory/test
|
||||
- ${HOME}/opt/bin/b2 -j 3 cxxstd=$CXXSTD -q include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include
|
||||
- cd ${TRAVIS_BUILD_DIR}/overloaded_function/test
|
||||
- ${HOME}/opt/bin/b2 -j 3 cxxstd=$CXXSTD -q include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include
|
||||
- |-
|
||||
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
|
||||
|
@ -1,62 +1,72 @@
|
||||
[library Boost.Functional/Factory
|
||||
[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 templates for object creation.]
|
||||
[category higher-order]
|
||||
[category generic]
|
||||
[last-revision $Date: 2008/11/01 21:44:52 $]
|
||||
[/
|
||||
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)
|
||||
]
|
||||
|
||||
[def __boost_bind__ [@http://www.boost.org/libs/bind/bind.html Boost.Bind]]
|
||||
[def __boost__bind__ [@http://www.boost.org/libs/bind/bind.html `boost::bind`]]
|
||||
[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__forward_adapter__ [@http://www.boost.org/libs/functional/forward/doc/index.html `boost::forward_adapter`]]
|
||||
[def __fusion_functional_adapters__ [@http://www.boost.org/libs/fusion/doc/html/functional.html Fusion Functional Adapters]]
|
||||
[def __boost__bind__
|
||||
[@http://www.boost.org/libs/bind/bind.html `boost::bind`]]
|
||||
|
||||
[def __boost_function__ [@http://www.boost.org/doc/html/function.html Boost.Function]]
|
||||
[def __boost__function__ [@http://www.boost.org/doc/html/function.html `boost::function`]]
|
||||
[def __boost__forward_adapter__
|
||||
[@http://www.boost.org/libs/functional/forward/doc/index.html
|
||||
`boost::forward_adapter`]]
|
||||
|
||||
[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 __boost_function__
|
||||
[@http://www.boost.org/doc/html/function.html Boost.Function]]
|
||||
|
||||
[def __std__map__ [@http://www.sgi.com/tech/stl/map.html `std::map`]]
|
||||
[def __std__string__ [@http://www.sgi.com/tech/stl/string.html `std::string`]]
|
||||
[def __allocator__ [@http://www.sgi.com/tech/stl/concepts/allocator.html Allocator]]
|
||||
[def __std_allocator__ [@http://www.sgi.com/tech/stl/concepts/allocator.html Allocator]]
|
||||
[def __std_allocators__ [@http://www.sgi.com/tech/stl/concepts/allocator.html Allocators]]
|
||||
[def __smart_pointer__
|
||||
[@http://www.boost.org/libs/smart_ptr/index.html Smart Pointer]]
|
||||
|
||||
[def __boost__ptr_map__ [@http://www.boost.org/libs/ptr_container/doc/ptr_map.html `boost::ptr_map`]]
|
||||
[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 __factory__ `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`.
|
||||
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__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)
|
||||
__boost__value_factory__<T>()(arg1,arg2,arg3)
|
||||
// same as T(arg1,arg2,arg3)
|
||||
```
|
||||
|
||||
For technical reasons 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__.
|
||||
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]
|
||||
|
||||
@ -66,80 +76,75 @@ 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
|
||||
```
|
||||
// assuming a_concrete_class and another_concrete_class are derived
|
||||
// from an_abstract_class
|
||||
|
||||
class a_factory
|
||||
{
|
||||
public:
|
||||
virtual an_abstract_class* create() const = 0;
|
||||
virtual ~a_factory() { }
|
||||
};
|
||||
struct a_factory {
|
||||
virtual an_abstract_class* create() const = 0;
|
||||
virtual ~a_factory() { }
|
||||
};
|
||||
|
||||
class a_concrete_factory : public a_factory
|
||||
{
|
||||
public:
|
||||
virtual an_abstract_class* create() const
|
||||
{
|
||||
return new a_concrete_class();
|
||||
}
|
||||
};
|
||||
struct a_concrete_factory
|
||||
: a_factory {
|
||||
an_abstract_class* create() const {
|
||||
return new a_concrete_class();
|
||||
}
|
||||
};
|
||||
|
||||
class another_concrete_factory : public a_factory
|
||||
{
|
||||
public:
|
||||
virtual an_abstract_class* create() const
|
||||
{
|
||||
return new another_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;
|
||||
|
||||
// [...]
|
||||
|
||||
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));
|
||||
|
||||
// [...]
|
||||
// [...]
|
||||
|
||||
factories.insert("a_name",std::auto_ptr<a_factory>(
|
||||
new a_concrete_factory));
|
||||
factories.insert("another_name",std::auto_ptr<a_factory>(
|
||||
new another_concrete_factory));
|
||||
std::unique_ptr<an_abstract_class> x(factories.at(some_name).create());
|
||||
|
||||
// [...]
|
||||
// [...]
|
||||
}
|
||||
```
|
||||
|
||||
std::auto_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:
|
||||
|
||||
// [...]
|
||||
}
|
||||
|
||||
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 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 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
|
||||
* 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.
|
||||
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.
|
||||
operator, respectively.
|
||||
|
||||
We let the function objects forward their arguments to the construction
|
||||
expressions they encapsulate. Over this __boost__factory__ optionally allows
|
||||
@ -147,99 +152,103 @@ 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);
|
||||
```
|
||||
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.
|
||||
// [...]
|
||||
}
|
||||
// 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.
|
||||
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);
|
||||
```
|
||||
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.
|
||||
// [...]
|
||||
}
|
||||
// for conceptually similar objects x we neither need virtual
|
||||
// functions nor a common base class in this context.
|
||||
// [...]
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// [...]
|
||||
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.
|
||||
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;
|
||||
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);
|
||||
```
|
||||
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).
|
||||
// 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 __factory__ instead
|
||||
// of __value_factory__]
|
||||
// [... 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.
|
||||
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;
|
||||
```
|
||||
typedef boost::function<an_abstract_class*()> a_factory;
|
||||
|
||||
// [...]
|
||||
|
||||
int main()
|
||||
{
|
||||
std::map<std::string, a_factory> factories;
|
||||
|
||||
// [...]
|
||||
|
||||
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*>();
|
||||
|
||||
// [...]
|
||||
|
||||
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]
|
||||
@ -247,105 +256,111 @@ return __smart_pointers__.
|
||||
Function object template that invokes the constructor of the type `T`.
|
||||
|
||||
[heading Header]
|
||||
#include <boost/functional/value_factory.hpp>
|
||||
|
||||
```
|
||||
#include <boost/functional/value_factory.hpp>
|
||||
```
|
||||
|
||||
[heading Synopsis]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template< typename T >
|
||||
class value_factory;
|
||||
}
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template<class T>
|
||||
class value_factory;
|
||||
|
||||
} // boost
|
||||
```
|
||||
|
||||
[variablelist Notation
|
||||
[[`T`] [an arbitrary type with at least one public constructor]]
|
||||
[[`a0`...`aN`] [argument LValues to a constructor of `T`]]
|
||||
[[`F`] [the type `value_factory<F>`]]
|
||||
[[`f`] [an instance object of `F`]]
|
||||
]
|
||||
[[`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`.]]
|
||||
]
|
||||
[[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]
|
||||
|
||||
The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set the
|
||||
maximum arity. It defaults to 10.
|
||||
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 `boost::pointee<Pointer>::type` yields
|
||||
the pointee type.
|
||||
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 `boost::pointee<Pointer>::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 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`
|
||||
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>
|
||||
|
||||
```
|
||||
#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
|
||||
};
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
template< typename Pointer,
|
||||
class Allocator = void,
|
||||
factory_alloc_propagation AllocProp =
|
||||
factory_alloc_for_pointee_and_deleter >
|
||||
class factory;
|
||||
}
|
||||
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 LValues to a constructor of `T`]]
|
||||
[[`F`] [the type `factory<P>`]]
|
||||
[[`f`] [an instance object of `F`]]
|
||||
]
|
||||
[[`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.]]
|
||||
]
|
||||
[[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]
|
||||
|
||||
The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the
|
||||
maximum arity. It defaults to 10.
|
||||
Before C++11, the maximum number of arguments supported is 10. Since C++11 an
|
||||
arbitrary number of arguments is supported.
|
||||
|
||||
[endsect]
|
||||
|
||||
@ -353,20 +368,41 @@ maximum arity. It defaults to 10.
|
||||
|
||||
[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.
|
||||
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]
|
||||
|
||||
Eric Niebler requested a function to invoke a type's constructor (with the
|
||||
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.
|
||||
|
||||
@ -375,25 +411,22 @@ useful hints for the implementation.
|
||||
|
||||
Joel de Guzman's documentation style was copied from Fusion.
|
||||
|
||||
Further, I want to thank Peter Dimov for sharing his insights on language
|
||||
details and their evolution.
|
||||
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
|
||||
Gamma et al. - Addison Wesley Publishing, 1995
|
||||
|
||||
# [@http://www.sgi.com/tech/stl/ Standard Template Library Programmer's Guide],
|
||||
Hewlett-Packard Company, 1994
|
||||
# [@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/libs/bind/bind.html Boost.Bind],
|
||||
Peter Dimov, 2001-2005
|
||||
|
||||
# [@http://www.boost.org/doc/html/function.html Boost.Function],
|
||||
Douglas Gregor, 2001-2004
|
||||
Douglas Gregor, 2001-2004
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
@ -1,24 +1,20 @@
|
||||
|
||||
# (C) Copyright Tobias Schwinger
|
||||
# Copyright 2007,2008 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).
|
||||
# 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 ;
|
||||
|
||||
project factory-tests
|
||||
;
|
||||
|
||||
test-suite functional/factory
|
||||
:
|
||||
[ run value_factory.cpp ]
|
||||
[ run factory.cpp ]
|
||||
[ run factory_with_allocator.cpp ]
|
||||
[ run factory_with_std_allocator.cpp ]
|
||||
[ compile-fail factory_with_none_t.cpp ]
|
||||
[ run factory.cpp : : : <define>BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory ]
|
||||
[ run factory_with_allocator.cpp : : : <define>BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory_with_allocator ]
|
||||
[ run factory_with_std_allocator.cpp : : : <define>BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory_with_std_allocator ]
|
||||
[ run factory_with_none_t.cpp : : : <define>BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory_with_none_t ]
|
||||
;
|
||||
|
||||
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 ;
|
||||
|
@ -1,53 +1,87 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2007 Tobias Schwinger
|
||||
/*
|
||||
Copyright 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).
|
||||
==============================================================================*/
|
||||
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>
|
||||
|
||||
#include <memory>
|
||||
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) { }
|
||||
|
||||
class sum
|
||||
{
|
||||
int val_sum;
|
||||
public:
|
||||
sum(int a, int b) : val_sum(a + b) { }
|
||||
int get() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
operator int() const { return this->val_sum; }
|
||||
private:
|
||||
int value_;
|
||||
};
|
||||
|
||||
// Suppress warnings about std::auto_ptr.
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
int one = 1, two = 2;
|
||||
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;
|
||||
{
|
||||
sum* instance( boost::factory< sum* >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
boost::scoped_ptr<sum> s(x());
|
||||
BOOST_TEST(s->get() == 0);
|
||||
}
|
||||
#if !defined(BOOST_NO_AUTO_PTR)
|
||||
{
|
||||
std::auto_ptr<sum> instance( boost::factory< std::auto_ptr<sum> >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
boost::scoped_ptr<sum> s(x(a));
|
||||
BOOST_TEST(s->get() == 1);
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
{
|
||||
std::unique_ptr<sum> instance( boost::factory< std::unique_ptr<sum> >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
85
factory/test/factory_allocator_throws.cpp
Normal file
85
factory/test/factory_allocator_throws.cpp
Normal 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();
|
||||
}
|
||||
|
42
factory/test/factory_args.cpp
Normal file
42
factory/test/factory_args.cpp
Normal 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
|
56
factory/test/factory_default_allocator.cpp
Normal file
56
factory/test/factory_default_allocator.cpp
Normal 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();
|
||||
}
|
55
factory/test/factory_move.cpp
Normal file
55
factory/test/factory_move.cpp
Normal 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
|
@ -1,84 +1,95 @@
|
||||
/*=============================================================================
|
||||
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).
|
||||
==============================================================================*/
|
||||
/*
|
||||
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>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
class sum {
|
||||
public:
|
||||
sum(int a, int b)
|
||||
: value_(a + b) { }
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
// none of the deprecated members of std::allocate are used here
|
||||
# pragma warning(disable:4996) // Various members of std::allocator are deprecated in C++17
|
||||
#endif
|
||||
|
||||
using std::size_t;
|
||||
|
||||
class sum
|
||||
{
|
||||
int val_sum;
|
||||
public:
|
||||
sum(int a, int b) : val_sum(a + b) { }
|
||||
|
||||
operator int() const { return this->val_sum; }
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class counting_allocator : public std::allocator<T>
|
||||
{
|
||||
public:
|
||||
counting_allocator()
|
||||
{ }
|
||||
|
||||
template< typename OtherT >
|
||||
struct rebind { typedef counting_allocator<OtherT> other; };
|
||||
|
||||
template< typename OtherT >
|
||||
counting_allocator(counting_allocator<OtherT> const& that)
|
||||
{ }
|
||||
|
||||
static size_t n_allocated;
|
||||
T* allocate(size_t n, void const* hint = 0l)
|
||||
{
|
||||
n_allocated += 1;
|
||||
return std::allocator<T>::allocate(n,hint);
|
||||
int get() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
static size_t n_deallocated;
|
||||
void deallocate(T* ptr, size_t n)
|
||||
{
|
||||
n_deallocated += 1;
|
||||
return std::allocator<T>::deallocate(ptr,n);
|
||||
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< typename T > size_t counting_allocator<T>::n_allocated = 0;
|
||||
template< typename T > size_t counting_allocator<T>::n_deallocated = 0;
|
||||
|
||||
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 one = 1, two = 2;
|
||||
int a = 1;
|
||||
int b = 2;
|
||||
{
|
||||
boost::shared_ptr<sum> instance(
|
||||
boost::factory< boost::shared_ptr<sum>, counting_allocator<void>,
|
||||
boost::factory_alloc_for_pointee_and_deleter >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
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(counting_allocator<sum>::n_allocated == 1);
|
||||
BOOST_TEST(counting_allocator<sum>::n_deallocated == 1);
|
||||
BOOST_TEST(creator<sum>::count == 0);
|
||||
{
|
||||
boost::shared_ptr<sum> instance(
|
||||
boost::factory< boost::shared_ptr<sum>, counting_allocator<void>,
|
||||
boost::factory_passes_alloc_to_smart_pointer >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
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(counting_allocator<sum>::n_allocated == 2);
|
||||
BOOST_TEST(counting_allocator<sum>::n_deallocated == 2);
|
||||
BOOST_TEST(creator<sum>::count == 0);
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
@ -1,56 +0,0 @@
|
||||
/*=============================================================================
|
||||
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/functional/factory.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/none_t.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class sum
|
||||
{
|
||||
int val_sum;
|
||||
public:
|
||||
sum(int a, int b) : val_sum(a + b) { }
|
||||
|
||||
operator int() const { return this->val_sum; }
|
||||
};
|
||||
|
||||
// Suppress warnings about std::auto_ptr.
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
int one = 1, two = 2;
|
||||
{
|
||||
sum* instance( boost::factory< sum*, boost::none_t >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
}
|
||||
#if !defined(BOOST_NO_AUTO_PTR)
|
||||
{
|
||||
std::auto_ptr<sum> instance(
|
||||
boost::factory< std::auto_ptr<sum>, boost::none_t >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
{
|
||||
std::unique_ptr<sum> instance(
|
||||
boost::factory< std::unique_ptr<sum>, boost::none_t >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
}
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
@ -1,45 +1,46 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2007 Tobias Schwinger
|
||||
Copyright (c) 2017 Daniel James
|
||||
/*
|
||||
Copyright 2007 Tobias Schwinger
|
||||
Copyright 2017 Daniel James
|
||||
|
||||
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).
|
||||
==============================================================================*/
|
||||
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/detail/lightweight_test.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
class sum
|
||||
{
|
||||
int val_sum;
|
||||
public:
|
||||
sum(int a, int b) : val_sum(a + b) { }
|
||||
class sum {
|
||||
public:
|
||||
sum(int a, int b)
|
||||
: value_(a + b) { }
|
||||
|
||||
operator int() const { return this->val_sum; }
|
||||
int get() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
int value_;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int one = 1, two = 2;
|
||||
int a = 1;
|
||||
int b = 2;
|
||||
{
|
||||
boost::shared_ptr<sum> instance(
|
||||
boost::factory< boost::shared_ptr<sum>, std::allocator<int>,
|
||||
boost::factory_alloc_for_pointee_and_deleter >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
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> instance(
|
||||
boost::factory< boost::shared_ptr<sum>, std::allocator<int>,
|
||||
boost::factory_passes_alloc_to_smart_pointer >()(one,two) );
|
||||
BOOST_TEST(*instance == 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();
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,86 @@
|
||||
/*=============================================================================
|
||||
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).
|
||||
==============================================================================*/
|
||||
/*
|
||||
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
|
||||
{
|
||||
int val_sum;
|
||||
public:
|
||||
sum(int a, int b) : val_sum(a + b) { }
|
||||
operator int() const { return this->val_sum; }
|
||||
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()
|
||||
{
|
||||
int one = 1, two = 2;
|
||||
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 instance( boost::value_factory< sum >()(one,two) );
|
||||
BOOST_TEST(instance == 3);
|
||||
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();
|
||||
}
|
||||
|
||||
|
40
factory/test/value_factory_args.cpp
Normal file
40
factory/test/value_factory_args.cpp
Normal 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
|
54
factory/test/value_factory_move.cpp
Normal file
54
factory/test/value_factory_move.cpp
Normal 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
|
@ -1,214 +1,365 @@
|
||||
/*=============================================================================
|
||||
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).
|
||||
==============================================================================*/
|
||||
/*
|
||||
Copyright 2007 Tobias Schwinger
|
||||
|
||||
#ifndef BOOST_FUNCTIONAL_FACTORY_HPP_INCLUDED
|
||||
# ifndef BOOST_PP_IS_ITERATING
|
||||
Copyright 2019 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
# include <boost/preprocessor/iteration/iterate.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
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 <new>
|
||||
# include <boost/pointee.hpp>
|
||||
# include <boost/get_pointer.hpp>
|
||||
# include <boost/non_type.hpp>
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <boost/core/pointer_traits.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/config.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
|
||||
|
||||
# if defined(BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T)
|
||||
# include <boost/none_t.hpp>
|
||||
# endif
|
||||
namespace boost {
|
||||
|
||||
# ifndef BOOST_FUNCTIONAL_FACTORY_MAX_ARITY
|
||||
# define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 10
|
||||
# elif BOOST_FUNCTIONAL_FACTORY_MAX_ARITY < 3
|
||||
# undef BOOST_FUNCTIONAL_FACTORY_MAX_ARITY
|
||||
# define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 3
|
||||
# endif
|
||||
enum factory_alloc_propagation {
|
||||
factory_alloc_for_pointee_and_deleter,
|
||||
factory_passes_alloc_to_smart_pointer
|
||||
};
|
||||
|
||||
namespace boost
|
||||
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)
|
||||
{
|
||||
enum factory_alloc_propagation
|
||||
{
|
||||
factory_alloc_for_pointee_and_deleter,
|
||||
factory_passes_alloc_to_smart_pointer
|
||||
};
|
||||
|
||||
#if defined(BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T)
|
||||
template< typename Pointer, class Allocator = boost::none_t,
|
||||
factory_alloc_propagation AP = factory_alloc_for_pointee_and_deleter >
|
||||
class factory;
|
||||
#else
|
||||
template< typename Pointer, class Allocator = void,
|
||||
factory_alloc_propagation AP = factory_alloc_for_pointee_and_deleter >
|
||||
class factory;
|
||||
#endif
|
||||
|
||||
//----- ---- --- -- - - - -
|
||||
|
||||
template< typename Pointer, factory_alloc_propagation AP >
|
||||
class factory<Pointer, void, AP>
|
||||
{
|
||||
public:
|
||||
typedef typename boost::remove_cv<Pointer>::type result_type;
|
||||
typedef typename boost::pointee<result_type>::type value_type;
|
||||
|
||||
factory()
|
||||
{ }
|
||||
|
||||
# define BOOST_PP_FILENAME_1 <boost/functional/factory.hpp>
|
||||
# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_FACTORY_MAX_ARITY)
|
||||
# include BOOST_PP_ITERATE()
|
||||
};
|
||||
|
||||
#if defined(BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T)
|
||||
template< typename Pointer, factory_alloc_propagation AP >
|
||||
class factory<Pointer, boost::none_t, AP>
|
||||
: public factory<Pointer, void, AP>
|
||||
{};
|
||||
#endif
|
||||
|
||||
template< class Pointer, class Allocator, factory_alloc_propagation AP >
|
||||
class factory
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
: private Allocator::template rebind< typename boost::pointee<
|
||||
typename boost::remove_cv<Pointer>::type >::type >::other
|
||||
#else
|
||||
: private std::allocator_traits<Allocator>::template rebind_alloc<
|
||||
typename boost::pointee< typename boost::remove_cv<Pointer>::type >::type >
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
typedef typename boost::remove_cv<Pointer>::type result_type;
|
||||
typedef typename boost::pointee<result_type>::type value_type;
|
||||
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename Allocator::template rebind<value_type>::other
|
||||
allocator_type;
|
||||
#else
|
||||
typedef typename std::allocator_traits<Allocator>::template rebind_alloc<value_type>
|
||||
allocator_type;
|
||||
typedef std::allocator_traits<allocator_type> allocator_traits;
|
||||
#endif
|
||||
|
||||
explicit factory(allocator_type const & a = allocator_type())
|
||||
: allocator_type(a)
|
||||
{ }
|
||||
|
||||
private:
|
||||
|
||||
struct deleter
|
||||
: allocator_type
|
||||
{
|
||||
inline deleter(allocator_type const& that)
|
||||
: allocator_type(that)
|
||||
{ }
|
||||
|
||||
allocator_type& get_allocator() const
|
||||
{
|
||||
return *const_cast<allocator_type*>(
|
||||
static_cast<allocator_type const*>(this));
|
||||
}
|
||||
|
||||
void operator()(value_type* ptr) const
|
||||
{
|
||||
if (!! ptr) {
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
ptr->~value_type();
|
||||
const_cast<allocator_type*>(static_cast<allocator_type const*>(
|
||||
this))->deallocate(ptr,1);
|
||||
#else
|
||||
allocator_traits::destroy(this->get_allocator(), ptr);
|
||||
allocator_traits::deallocate(this->get_allocator(),ptr,1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline allocator_type& get_allocator() const
|
||||
{
|
||||
return *const_cast<allocator_type*>(
|
||||
static_cast<allocator_type const*>(this));
|
||||
}
|
||||
|
||||
inline result_type make_pointer(value_type* ptr, boost::non_type<
|
||||
factory_alloc_propagation,factory_passes_alloc_to_smart_pointer>)
|
||||
const
|
||||
{
|
||||
return result_type(ptr,deleter(this->get_allocator()));
|
||||
}
|
||||
inline result_type make_pointer(value_type* ptr, boost::non_type<
|
||||
factory_alloc_propagation,factory_alloc_for_pointee_and_deleter>)
|
||||
const
|
||||
{
|
||||
return result_type(ptr,deleter(this->get_allocator()),
|
||||
this->get_allocator());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
# define BOOST_TMP_MACRO
|
||||
# define BOOST_PP_FILENAME_1 <boost/functional/factory.hpp>
|
||||
# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_FACTORY_MAX_ARITY)
|
||||
# include BOOST_PP_ITERATE()
|
||||
# undef BOOST_TMP_MACRO
|
||||
};
|
||||
|
||||
template< typename Pointer, class Allocator, factory_alloc_propagation AP >
|
||||
class factory<Pointer&, Allocator, AP>;
|
||||
// forbidden, would create a dangling reference
|
||||
std::allocator_traits<A>::destroy(a, p);
|
||||
}
|
||||
#else
|
||||
template<class A, class T>
|
||||
inline void
|
||||
fc_destroy(A&, T* p)
|
||||
{
|
||||
p->~T();
|
||||
}
|
||||
#endif
|
||||
|
||||
# define BOOST_FUNCTIONAL_FACTORY_HPP_INCLUDED
|
||||
# else // defined(BOOST_PP_IS_ITERATING)
|
||||
# define N BOOST_PP_ITERATION()
|
||||
# if !defined(BOOST_TMP_MACRO)
|
||||
# if N > 0
|
||||
template< BOOST_PP_ENUM_PARAMS(N, typename T) >
|
||||
# endif
|
||||
inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const
|
||||
{
|
||||
return result_type( new value_type(BOOST_PP_ENUM_PARAMS(N,a)) );
|
||||
#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);
|
||||
}
|
||||
# else // defined(BOOST_TMP_MACRO)
|
||||
# if N > 0
|
||||
template< BOOST_PP_ENUM_PARAMS(N, typename T) >
|
||||
# endif
|
||||
inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
value_type* memory = this->get_allocator().allocate(1);
|
||||
#else
|
||||
value_type* memory = allocator_traits::allocate(this->get_allocator(), 1);
|
||||
#endif
|
||||
try
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
new(memory) value_type(BOOST_PP_ENUM_PARAMS(N,a));
|
||||
#else
|
||||
allocator_traits::construct(this->get_allocator(), memory
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(N,a));
|
||||
#endif
|
||||
}
|
||||
catch (...) {
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
this->get_allocator().deallocate(memory,1);
|
||||
#else
|
||||
allocator_traits::deallocate(this->get_allocator(), memory, 1);
|
||||
#endif
|
||||
throw;
|
||||
}
|
||||
};
|
||||
|
||||
return make_pointer(memory, boost::non_type<factory_alloc_propagation,AP>());
|
||||
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);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# undef N
|
||||
# endif // defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
#endif // include guard
|
||||
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;
|
||||
|
||||
fc_allocate(const fc_allocate&);
|
||||
fc_allocate& operator=(const fc_allocate&);
|
||||
|
||||
pointer release() BOOST_NOEXCEPT {
|
||||
pointer p = p_;
|
||||
p_ = pointer();
|
||||
return p;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -1,69 +1,106 @@
|
||||
/*=============================================================================
|
||||
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).
|
||||
==============================================================================*/
|
||||
/*
|
||||
Copyright 2007 Tobias Schwinger
|
||||
|
||||
#ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_HPP_INCLUDED
|
||||
# ifndef BOOST_PP_IS_ITERATING
|
||||
Copyright 2019 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
# include <boost/preprocessor/iteration/iterate.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
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 <new>
|
||||
# include <boost/pointee.hpp>
|
||||
# include <boost/get_pointer.hpp>
|
||||
# include <boost/non_type.hpp>
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
# ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY
|
||||
# define BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY 10
|
||||
# elif BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY < 3
|
||||
# undef BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY
|
||||
# define BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY 3
|
||||
# endif
|
||||
namespace boost {
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template< typename T >
|
||||
class value_factory;
|
||||
template<class T>
|
||||
class value_factory;
|
||||
|
||||
//----- ---- --- -- - - - -
|
||||
template<class T>
|
||||
class value_factory {
|
||||
public:
|
||||
typedef T result_type;
|
||||
|
||||
template< typename T >
|
||||
class value_factory
|
||||
{
|
||||
public:
|
||||
typedef T result_type;
|
||||
|
||||
value_factory()
|
||||
{ }
|
||||
|
||||
# define BOOST_PP_FILENAME_1 <boost/functional/value_factory.hpp>
|
||||
# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY)
|
||||
# include BOOST_PP_ITERATE()
|
||||
};
|
||||
|
||||
template< typename T > class value_factory<T&>;
|
||||
// forbidden, would create a dangling reference
|
||||
}
|
||||
# define BOOST_FUNCTIONAL_VALUE_FACTORY_HPP_INCLUDED
|
||||
# else // defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
# define N BOOST_PP_ITERATION()
|
||||
# if N > 0
|
||||
template< BOOST_PP_ENUM_PARAMS(N, typename T) >
|
||||
# endif
|
||||
inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const
|
||||
{
|
||||
return result_type(BOOST_PP_ENUM_PARAMS(N,a));
|
||||
#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();
|
||||
}
|
||||
# undef N
|
||||
|
||||
# endif // defined(BOOST_PP_IS_ITERATING)
|
||||
template<class A0>
|
||||
result_type operator()(A0& a0) const {
|
||||
return result_type(a0);
|
||||
}
|
||||
|
||||
#endif // include guard
|
||||
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
|
||||
|
@ -16,9 +16,11 @@
|
||||
"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",
|
||||
|
Reference in New Issue
Block a user