2
0
mirror of https://github.com/boostorg/lambda.git synced 2026-01-21 04:52:25 +00:00

Compare commits

..

131 Commits

Author SHA1 Message Date
Peter Dimov
016b12959b Add a Focal libc++ configuration 2021-05-18 05:29:36 +03:00
Peter Dimov
ca87d33f3d Disable UBSan on libc++ configuration; Clang 7 fails with a link error 2021-05-18 05:18:49 +03:00
Peter Dimov
a96b87e777 Merge branch 'develop' of https://github.com/Jac1494/lambda into feature/pr-17 2021-05-18 04:16:22 +03:00
Peter Dimov
bbbe1a9041 Update .travis.yml 2021-05-18 03:20:52 +03:00
Peter Dimov
1a8f8cfead Update .travis.yml 2021-05-18 03:18:03 +03:00
Peter Dimov
7be3075575 Merge branch 'develop' 2021-05-18 03:10:07 +03:00
Peter Dimov
ddf7dfe25e Add CMakeLists.txt 2021-03-19 04:33:05 +02:00
Glen Fernandes
8de6d9cb9f Make all include guards BOOST_LAMBDA_ prefixed 2019-12-24 18:54:19 -05:00
Jaydeep Chauhan
641dd2b0a6 Disabled one test which returns local address 2019-07-25 18:19:15 +05:30
Glen Fernandes
d27fc70114 Merge pull request #14 from tinko92/develop
Fix broken sgi/stl links.
2019-04-24 05:49:02 +10:00
Tinko Bartels
1c11cf9570 Fix broken sgi/stl links. 2019-04-23 19:38:24 +02:00
Edward Diener
7355f36b9f Updated for b2 cmake support. 2018-12-19 22:30:41 -05:00
Edward Diener
8824e81d52 Merge branch 'develop' 2018-10-25 22:20:53 -04:00
Edward Diener
6395013860 Merge pull request #13 from danieljames/remove-random-shuffle-support-when-appropriate
Only support std::random_shuffle when available
2018-04-19 23:43:00 -04:00
Daniel James
8c0410fff5 Only support std::random_shuffle when available
It was removed in C++17. We could emulate it when it isn't available,
but that doesn't seem worth the effort.
2018-04-07 15:10:29 +01:00
Edward Diener
b8a2f400ac Merge branch 'develop' 2018-02-20 09:07:34 -05:00
Edward Diener
4fc4454f3e Merge pull request #12 from Kojoley/fix-unused-variable-warnings-from-core_hpp
Fixed unused variable warnings from core.hpp
2017-11-11 13:39:03 -05:00
Nikita Kniazev
02999cca47 Fixed unused variable warnings from core.hpp 2017-11-10 15:48:28 +03:00
eldiener
e8eda93ef0 Merge branch 'develop' 2017-10-30 11:44:46 -04:00
eldiener
9d171774af Removed --depth 1 2017-10-29 21:44:06 -04:00
eldiener
f4b5e00a4f Merge branch 'develop' 2017-10-27 22:27:04 -04:00
Edward Diener
42b499ec9b Better appveyor file setup. 2017-10-09 12:08:07 -04:00
Edward Diener
61119a8e37 Added Appveyor file and Travis CI file. 2017-10-09 08:18:50 -04:00
Edward Diener
4b00716f5f Merge branch 'develop' 2017-09-26 12:05:44 -04:00
Edward Diener
4baf512ed2 Removed executable flag. 2017-09-16 06:59:04 -04:00
Edward Diener
4c0ef8e469 Merge branch 'develop' 2017-01-04 11:21:46 -05:00
Edward Diener
18bc9b84cb Updated link for fc++. 2016-12-19 20:23:07 -05:00
Edward Diener
ad5673c9de Use std::bind instead of std::bind1st when appropriate 2016-11-07 12:42:43 -05:00
Rene Rivera
8d9106ab17 Add, and update, documentation build targets. 2016-10-10 11:39:50 -05:00
Rene Rivera
f12bd0ef93 Add, and update, documentation build targets. 2016-10-07 23:07:34 -05:00
Edward Diener
b788075b6d Merge branch 'develop' 2015-10-16 21:38:07 -04:00
Edward Diener
5508ede384 Merge pull request #10 from mclow/develop
Remove mentions of deprecated macros
2015-09-11 04:40:43 -04:00
Marshall Clow
e4b5434e27 Remove mentions of deprecated macros in documentation 2015-09-10 20:01:11 -07:00
Edward Diener
4c4387a277 Merge branch 'develop' 2015-07-19 00:12:41 -04:00
Edward Diener
0f44d72275 Remove unnecessary header. 2015-05-18 19:55:22 -04:00
Edward Diener
723485bfa7 Merge branch 'develop' of https://github.com/boostorg/lambda into develop 2015-05-18 19:05:23 -04:00
Edward Diener
f85d2f0025 Merge pull request #9 from eldiener/develop
Changes for type_traits Version2
2015-05-18 19:04:38 -04:00
Edward Diener
45c391b380 Merge branch 'develop' of https://github.com/boostorg/lambda into develop 2015-05-18 19:03:04 -04:00
Edward Diener
69482a3b49 Merge pull request #6 from alexhenrie/develop
Correct spelling of "suppress"
2015-05-18 18:46:55 -04:00
Edward Diener
0afac59bc1 Merge pull request #4 from jzmaddock/patch-5
Update operator_return_type_traits.hpp
2015-05-18 18:43:23 -04:00
Edward Diener
5a6ae7f79d Merge pull request #3 from jzmaddock/patch-4
Update return_type_traits.hpp
2015-05-18 18:42:17 -04:00
Edward Diener
9a581dafb7 Added 'void const' specialization to fix problem with clang 2015-05-06 16:23:39 -04:00
Edward Diener
5e574813a2 Simplifed using direct operators rather than mpl constructs. 2015-04-27 03:00:19 -04:00
Edward Diener
11a6698eec Remove ice_xxx.hpp header and change functionality to use mpl. 2015-03-31 03:32:50 -04:00
Edward Diener
5ba2e0aa6a This file needs to include the type_traits headers it actually uses - problem exposed by ongoing type traits rewrite. 2015-03-05 11:02:49 -05:00
Edward Diener
59e1516609 This header should include the type_traits headers it needs and not depend on implicit inclusion which will go away in the current type_traits rewrite. 2015-03-05 11:02:19 -05:00
Alex Henrie
fba5d5e822 Correct spelling of "suppress" 2015-02-07 01:57:05 -07:00
jzmaddock
635d0fb6ce Update operator_return_type_traits.hpp
This file needs to include the type_traits headers it actually uses - problem exposed by ongoing type traits rewrite.
2015-01-21 17:03:07 +00:00
jzmaddock
ba8e62af76 Update return_type_traits.hpp
This header should include the type_traits hedaers it needs and not depend on implicit inclusion which will go away in the current type_traits rewrite.
2015-01-21 17:00:41 +00:00
Noel Belcourt
545b6af540 Merge pull request #1 from jzmaddock/patch-2
Update Jamfile.v2

Thanks John.
2014-11-02 15:44:45 -07:00
Noel Belcourt
ce6b030b06 Merge pull request #2 from danieljames/metadata
Create metadata file.
2014-09-01 20:33:39 -06:00
Daniel James
ecf547cbef Add metadata file. 2014-08-18 15:55:52 +01:00
jzmaddock
aef7c9fe51 Update Jamfile.v2
There can be only one project named boost/doc - and we already have that under doc/
This fixes the PDF doc build.
2014-08-13 18:29:22 +01:00
Daniel James
677be04dd7 Create merge base for git. 2014-06-01 19:21:47 +01:00
Daniel James
7d1d0d4fdd Remove file accidentally recreated by git conversion.
Some old files deleted in the CVS days were accidentally restored, this
appears to be one of them. You can see it wasn't in subversion at:

http://svn.boost.org/svn/boost/trunk/libs/lambda/
2014-06-01 19:20:51 +01:00
Stephen Kelly
7d21ea7cbb Lambda: Remove obsolete GCC version checks.
[SVN r86072]
2013-09-30 16:00:14 +00:00
Stephen Kelly
0d069c2c0c Remove use of obsolete BOOST_NO_TEMPLATED_STREAMS macro.
It was only defined for no-longer-supported-gcc.

[SVN r86062]
2013-09-30 15:56:52 +00:00
Steven Watanabe
25d6c0e3b1 Merge lambda from the trunk.
[SVN r83442]
2013-03-15 18:07:37 +00:00
Steven Watanabe
4545234f94 Handle const lambda functors for nullary result_of. Fixes #6914.
[SVN r83020]
2013-02-19 19:52:03 +00:00
Steven Watanabe
657a0b9dd7 Handle nullary result_of. Fixes #6914.
[SVN r82935]
2013-02-16 20:26:34 +00:00
Steven Watanabe
fab5a8041b Remove name of unused parameter. Fixes #8033.
[SVN r82932]
2013-02-16 20:01:07 +00:00
Marshall Clow
55cd962166 Merge comment typo fixes to release; Fixes #7714
[SVN r82236]
2012-12-28 16:54:24 +00:00
Marshall Clow
9c376db7e5 Fixed 'the the' in comments; Refs #7714
[SVN r82235]
2012-12-28 16:51:09 +00:00
Steven Watanabe
3caa685662 Merge [67640] from the trunk.
[SVN r70065]
2011-03-17 16:29:28 +00:00
Steven Watanabe
2ed8d7f4df Fix return type deduction for pointers to data members. Fixes #4962. Fixes #4566.
[SVN r67640]
2011-01-03 22:31:21 +00:00
Daniel Walker
2c14c3a13b merged changeset 63726 from trunk
[SVN r63907]
2010-07-12 01:36:38 +00:00
Daniel Walker
4091f55a4b removed arity detection from has_xxx_template
[SVN r63726]
2010-07-07 20:44:59 +00:00
Steven Watanabe
0d0f71272e Merge lambda from the trunk
[SVN r63555]
2010-07-03 19:05:15 +00:00
Daniel James
08b3f6336c Merge documentation fixes.
* Use `doc/src/*.css` instead of `doc/html/*.css`.
* Remove wiki and people directories.
* Some documentation fixes.
* Left out `minimal.css` changes and boostbook changes because of clashes.


[SVN r63347]
2010-06-26 12:30:09 +00:00
Daniel James
45c6ba535c Update various libraries' documentation build.
Mostly to use the images and css files under doc/src instead of
doc/html, usually be deleting the settings in order to use the defaults.
Also add 'boost.root' to some builds in order to fix links which rely on
it.

[SVN r63146]
2010-06-20 18:00:48 +00:00
Steven Watanabe
57a605d7cc Revert [62617], since there is already a Jamfile for Lambda's tests
[SVN r62628]
2010-06-09 02:10:06 +00:00
Steven Watanabe
fcfcc42baf Enable using result_of with Boost.Lambda. Fixes #426. Fixes #864
[SVN r62627]
2010-06-09 01:39:48 +00:00
Jeremiah Willcock
c516504670 Changed compound assignment (and actually all binary operators) to copy their RHS arguments like the documentation said; added a test for this; fixes #4043
[SVN r62620]
2010-06-09 00:33:25 +00:00
Jeremiah Willcock
c479b3b7b7 Fixed warning
[SVN r62619]
2010-06-09 00:31:02 +00:00
Jeremiah Willcock
269ac93b1b Added Jamfile.v2 from Daniel Walker; refs #864
[SVN r62617]
2010-06-09 00:16:43 +00:00
Steven Watanabe
15d4e6ab79 Make sure that all top level headers in Lambda include their dependencies. Fixes #4203
[SVN r61881]
2010-05-09 20:07:07 +00:00
Steven Watanabe
77495bb7e1 Deal with warnings with /Za. Fixes #3485
[SVN r57479]
2009-11-08 04:11:21 +00:00
Troy D. Straszheim
c183b699bc rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
Troy D. Straszheim
e368877636 rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Troy D. Straszheim
3d4a3e7050 Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
Troy D. Straszheim
22bc52b7c4 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Steven Watanabe
8a943f6510 Merge [43113], [45097], [53261], [53343], [53648], [53649], and [53651] from the trunk
[SVN r53875]
2009-06-13 21:18:10 +00:00
Steven Watanabe
c14095472e Don't propagate constness from pointer to pointee. Fixes #1572
[SVN r53651]
2009-06-05 02:43:54 +00:00
Steven Watanabe
1afc4b6779 Use boost/detail/container_fwd.hpp. Fixes #2601
[SVN r53649]
2009-06-05 01:43:39 +00:00
Steven Watanabe
41eb864595 Add result_type to lambda::ret. Fixes #1222
[SVN r53648]
2009-06-05 01:20:06 +00:00
Jeremiah Willcock
0f60055086 Fixed tabs
[SVN r53343]
2009-05-28 14:49:25 +00:00
Steven Watanabe
d69f83d074 Merge [53061] and [53233] from the trunk
[SVN r53266]
2009-05-26 00:59:17 +00:00
Steven Watanabe
9a8e5d7784 Fix lambda regression with msvc 7.1
[SVN r53261]
2009-05-25 21:52:12 +00:00
Steven Watanabe
6985fca6ee Avoid ambiguities between boost::lambda::bind and std::bind with VC10. Fixes #3075
[SVN r53233]
2009-05-24 22:58:52 +00:00
Steven Watanabe
04ae944c3c Avoid using namespace std; to prevent ambiguity between boost and std components. Fixes #3025
[SVN r53061]
2009-05-17 00:25:06 +00:00
Steven Watanabe
7648a7adf1 Merge [51448] from the trunk.
[SVN r51617]
2009-03-05 03:52:26 +00:00
Steven Watanabe
0c4e251ebe Supress warnings on gcc and msvc. Fixes #1515
[SVN r51448]
2009-02-26 02:33:15 +00:00
John Maddock
48e6f45d92 Merge PDF build changes from Trunk.
[SVN r51417]
2009-02-23 18:39:32 +00:00
Steven Watanabe
927a04351e Merge [50516] and [50999] from the trunk. These are the fixes for #781 and #2446 respectively
[SVN r51368]
2009-02-21 18:10:20 +00:00
John Maddock
0faeb3f19e Add Jamfile to build PDF versions of all the docs.
Tweaked some existing Jamfiles so that PDF build finds all the necessary image files etc.
Tweaked fo.xsl to provide more options by default, and improve formatting.

[SVN r51104]
2009-02-08 16:59:14 +00:00
Steven Watanabe
150736273e Add <async-exceptions>on. Fixes #2446
[SVN r50999]
2009-02-03 21:47:58 +00:00
Troy D. Straszheim
b5b41af8f4 merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Marshall Clow
1f6ca994e6 Merged revisions 50413 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r50413 | marshall | 2008-12-30 10:27:43 -0800 (Tue, 30 Dec 2008) | 1 line
  
  Typo: fixes bug #2583
........


[SVN r50602]
2009-01-15 03:46:14 +00:00
Steven Watanabe
d5a98758fa Add specializations of plain_return_type_2 for std::string. Fixes #781
[SVN r50516]
2009-01-08 16:58:48 +00:00
Marshall Clow
cd3d5fd03a Typo: fixes bug #2583
[SVN r50413]
2008-12-30 18:27:43 +00:00
Michael A. Jackson
48a89b7705 Updating dependency information for modularized libraries.
[SVN r49628]
2008-11-07 17:05:27 +00:00
Michael A. Jackson
ec350abf06 Updating CMake files to latest trunk. Added dependency information for regression tests and a few new macros for internal use.
[SVN r49627]
2008-11-07 17:02:56 +00:00
Michael A. Jackson
d56abd61ce Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor
[SVN r49510]
2008-11-01 13:15:41 +00:00
Beman Dawes
4a254c4161 With his kind permission, change Jaakko "Järvi" to "Jarvi"
[SVN r46809]
2008-06-28 13:57:20 +00:00
Beman Dawes
2788ede42a With his kind permission, change Jaakko "Järvi" to "Jarvi"
[SVN r46808]
2008-06-28 13:45:21 +00:00
Marshall Clow
1c953ed38c Updated docs re bug #1855
[SVN r45097]
2008-05-03 23:45:30 +00:00
Marshall Clow
b2dc95bb18 Applied patch (fixes bug #1307)
[SVN r43113]
2008-02-05 16:15:35 +00:00
Beman Dawes
e67976c740 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes
a0cd34c938 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Beman Dawes
672c8e10d4 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
Vladimir Prus
797b5756cf Update for V2
[SVN r38520]
2007-08-08 19:16:43 +00:00
Peter Dimov
bd4da55f0f Rvalue support
[SVN r38299]
2007-07-29 20:33:46 +00:00
nobody
87dd3997e7 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Daniel James
47bf3df0ae Merge fixed links from RC_1_34_0.
[SVN r36660]
2007-01-07 23:50:56 +00:00
Daniel James
b112fb9254 Fix a link.
[SVN r36651]
2007-01-07 22:42:25 +00:00
Jaakko Järvi
13ec0c5bbc fixed omission
[SVN r36201]
2006-11-29 19:28:48 +00:00
Jaakko Järvi
ff0929e6e3 fixed bug 1444052
[SVN r36200]
2006-11-29 19:21:46 +00:00
Jaakko Järvi
29ab5a2814 fixed bug 1444052
[SVN r36200]
2006-11-29 19:21:46 +00:00
Jaakko Järvi
9b925abaff added ->* to the table of actions for return types deduction
[SVN r36199]
2006-11-29 18:54:18 +00:00
Beman Dawes
a0cfe43611 Merged copyright and license addition
[SVN r35907]
2006-11-07 19:27:00 +00:00
Beman Dawes
bf50f2fe7f Add copyright, license
[SVN r35905]
2006-11-07 19:11:57 +00:00
Rene Rivera
fe858cf734 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Daryle Walker
85630d55a6 Correct placement of base class declaration
[SVN r34533]
2006-07-14 08:04:08 +00:00
Peter Dimov
2e8c4eb8f3 is_placeholder, is_bind_expression added.
[SVN r34468]
2006-07-06 13:47:26 +00:00
nobody
b3120233dc This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
Jaakko Järvi
24e8602cf1 typo
[SVN r31518]
2005-10-31 20:11:23 +00:00
Jaakko Järvi
7f77f987c1 Fixed typos in comments
[SVN r30381]
2005-08-02 17:43:37 +00:00
Jaakko Järvi
d854239945 Patch by Jonathan Wakely to expand special handling of GCC when used in
debug mode.


[SVN r28684]
2005-05-06 05:08:32 +00:00
Jaakko Järvi
4aef261258 added a flag to the test makefile
[SVN r28683]
2005-05-06 05:06:11 +00:00
Jaakko Järvi
6b67606f40 class to struct
[SVN r27493]
2005-02-24 05:27:28 +00:00
Stefan Slapeta
b0ce56c74f replaced BOOST_TEST
[SVN r27057]
2005-02-03 13:55:45 +00:00
63 changed files with 14828 additions and 533 deletions

172
.travis.yml Normal file
View File

@@ -0,0 +1,172 @@
# Copyright 2016 Edward Diener
# Copyright 2016, 2017, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
dist: xenial
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc CXXSTD=98
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
env: TOOLSET=gcc CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc CXXSTD=03,11,14
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: TOOLSET=gcc CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: g++-10
env: TOOLSET=gcc CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-10
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
dist: bionic
compiler: g++-11
env: UBSAN=1 TOOLSET=gcc CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-11
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
compiler: clang++-11
env: TOOLSET=clang CXXSTD=03,11,14,17,20
addons:
apt:
packages:
- clang-11
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-11 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
compiler: clang++-12
env: UBSAN=1 TOOLSET=clang CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-12
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-12 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: bionic
compiler: clang++-libc++
env: TOOLSET=clang CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- libc++-dev
- os: linux
dist: focal
compiler: clang++-libc++
env: UBSAN=1 TOOLSET=clang CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: UBSAN=1 TOOLSET=clang CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
- cd ..
- git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/boostdep
- cp -r $TRAVIS_BUILD_DIR/* libs/lambda
- python tools/boostdep/depinst/depinst.py lambda
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $TRAVIS_COMPILER ;" > ~/user-config.jam
- ./b2 -j3 libs/lambda/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
notifications:
email:
on_success: always

34
CMakeLists.txt Normal file
View File

@@ -0,0 +1,34 @@
# Generated by `boostdep --cmake lambda`
# 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_lambda VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_lambda INTERFACE)
add_library(Boost::lambda ALIAS boost_lambda)
target_include_directories(boost_lambda INTERFACE include)
target_link_libraries(boost_lambda
INTERFACE
Boost::bind
Boost::config
Boost::core
Boost::detail
Boost::iterator
Boost::mpl
Boost::preprocessor
Boost::tuple
Boost::type_traits
Boost::utility
)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()

38
appveyor.yml Normal file
View File

@@ -0,0 +1,38 @@
# Copyright 2017 Edward Diener
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0,msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
install:
- cd ..
- git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- git submodule update --init tools/boost_install
- git submodule update --init libs/headers
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\lambda
- python tools/boostdep/depinst/depinst.py lambda
- bootstrap
- b2 headers
build: off
test_script:
- b2 libs/lambda/test toolset=%TOOLSET%

View File

@@ -1,5 +1,21 @@
project boost/doc ;
project lambda/doc ;
import boostbook : boostbook ;
boostbook lambda-doc : lambda.xml ;
# Are these really the correct images??
path-constant images : ../../spirit/phoenix/doc/html ;
boostbook lambda-doc : lambda.xml
:
<xsl:param>boost.root=../../../..
<format>pdf:<xsl:param>img.src.path=$(images)/
;
###############################################################################
alias boostdoc
: lambda.xml
:
:
: ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;

8
doc/detail/lambda_doc.xml Executable file → Normal file
View File

@@ -163,8 +163,8 @@ The STL contains predefined function objects for some common cases (such as <lit
As an example, one possible implementation for the standard <literal>plus</literal> template is:
<programlisting>
<![CDATA[template <class T> : public binary_function<T, T, T>
struct plus {
<![CDATA[template <class T>
struct plus : public binary_function<T, T, T> {
T operator()(const T& i, const T& j) const {
return i + j;
}
@@ -3281,7 +3281,7 @@ was dropped.
<abbrev>SGI02</abbrev>
<title>The SGI Standard Template Library</title>
<pubdate>2002</pubdate>
<bibliomisc><ulink url="http://www.sgi.com/tech/stl/">www.sgi.com/tech/stl/</ulink></bibliomisc>
<bibliomisc><ulink url="https://www.boost.org/sgi/stl/">www.boost.org/sgi/stl/</ulink></bibliomisc>
</biblioentry>
@@ -3435,7 +3435,7 @@ was dropped.
<firstname>Brian</firstname>
<surname>McNamara</surname>
</author>
<bibliomisc><ulink url="http://www.cc.gatech.edu/~yannis/fc++/">www.cc.gatech.edu/~yannis/fc++/</ulink>
<bibliomisc><ulink url="http://yanniss.github.io/fc++/">yanniss.github.io/fc++/ </ulink>
</bibliomisc>
<pubdate>2002</pubdate>
</biblioentry>

View File

@@ -3,6 +3,10 @@
<meta http-equiv="refresh" content="0; URL=../../../doc/html/lambda.html">
</head>
<body>
Automatic redirection failed, please go to <a href="../../../doc/html/lambda.html">www.boost.org/doc/html/lambda.html</a>
Automatic redirection failed, please go to <a href="../../../doc/html/lambda.html">www.boost.org/doc/html/lambda.html</a>&nbsp;<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>
</html>

View File

@@ -44,7 +44,7 @@
<para>
The Boost Lambda Library (BLL in the sequel) is a C++ template
library, which implements form of <emphasis>lambda abstractions</emphasis> for C++.
library, which implements a form of <emphasis>lambda abstractions</emphasis> for C++.
The term originates from functional programming and lambda calculus, where a lambda abstraction defines an unnamed function.
The primary motivation for the BLL is to provide flexible and
convenient means to define unnamed function objects for STL algorithms.
@@ -165,8 +165,8 @@ The STL contains predefined function objects for some common cases (such as <lit
As an example, one possible implementation for the standard <literal>plus</literal> template is:
<programlisting>
<![CDATA[template <class T> : public binary_function<T, T, T>
struct plus {
<![CDATA[template <class T>
struct plus : public binary_function<T, T, T> {
T operator()(const T& i, const T& j) const {
return i + j;
}
@@ -1908,7 +1908,7 @@ For example:
int foo(int); int bar(int);
...
int i;
bind(foo, bind(bar, _1)(i);
bind(foo, bind(bar, _1))(i);
</programlisting>
The last line makes the call <literal>foo(bar(i));</literal>
@@ -2640,6 +2640,7 @@ which require that the argument types are references.
<row><entry><literal><![CDATA[&]]></literal></entry><entry><literal><![CDATA[other_action<address_of_action>]]></literal></entry></row>
<row><entry><literal><![CDATA[*]]></literal></entry><entry><literal><![CDATA[other_action<contents_of_action>]]></literal></entry></row>
<row><entry><literal><![CDATA[,]]></literal></entry><entry><literal><![CDATA[other_action<comma_action>]]></literal></entry></row>
<row><entry><literal><![CDATA[->*]]></literal></entry><entry><literal><![CDATA[other_action<member_pointer_action>]]></literal></entry></row>
</tbody>
</tgroup>
@@ -3190,7 +3191,7 @@ to extend the library with new features.
<appendix>
<section>
<title>Rationale for some of the design decisions</title>
<section id="lambda.why_weak_arity">
@@ -3255,7 +3256,7 @@ was dropped.
</section>
</appendix>
</section>
@@ -3285,7 +3286,7 @@ was dropped.
<abbrev>SGI02</abbrev>
<title>The SGI Standard Template Library</title>
<pubdate>2002</pubdate>
<bibliomisc><ulink url="http://www.sgi.com/tech/stl/">www.sgi.com/tech/stl/</ulink></bibliomisc>
<bibliomisc><ulink url="https://www.boost.org/sgi/stl/">www.boost.org/sgi/stl/</ulink></bibliomisc>
</biblioentry>
@@ -3439,7 +3440,7 @@ was dropped.
<firstname>Brian</firstname>
<surname>McNamara</surname>
</author>
<bibliomisc><ulink url="http://www.cc.gatech.edu/~yannis/fc++/">www.cc.gatech.edu/~yannis/fc++/</ulink>
<bibliomisc><ulink url="http://yanniss.github.io/fc++/">yanniss.github.io/fc++/ </ulink>
</bibliomisc>
<pubdate>2002</pubdate>
</biblioentry>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,19 @@
// -- bind.hpp -- Boost Lambda Library --------------------------------------
// Copyright (C) 1999-2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Gary Powell (gwpowell@hotmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
#ifndef BOOST_LAMBDA_BIND_HPP
#define BOOST_LAMBDA_BIND_HPP
#include "boost/lambda/core.hpp"
#include "boost/lambda/detail/bind_functions.hpp"
#endif

View File

@@ -0,0 +1,226 @@
// - casts.hpp -- BLambda Library -------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
// -----------------------------------------------
#if !defined(BOOST_LAMBDA_CASTS_HPP)
#define BOOST_LAMBDA_CASTS_HPP
#include "boost/lambda/detail/suppress_unused.hpp"
#include "boost/lambda/core.hpp"
#include <typeinfo>
namespace boost {
namespace lambda {
template<class Act, class Args>
struct return_type_N;
template<class T> class cast_action;
template<class T> class static_cast_action;
template<class T> class dynamic_cast_action;
template<class T> class const_cast_action;
template<class T> class reinterpret_cast_action;
class typeid_action;
class sizeof_action;
// Cast actions
template<class T> class cast_action<static_cast_action<T> >
{
public:
template<class RET, class Arg1>
static RET apply(Arg1 &a1) {
return static_cast<RET>(a1);
}
};
template<class T> class cast_action<dynamic_cast_action<T> > {
public:
template<class RET, class Arg1>
static RET apply(Arg1 &a1) {
return dynamic_cast<RET>(a1);
}
};
template<class T> class cast_action<const_cast_action<T> > {
public:
template<class RET, class Arg1>
static RET apply(Arg1 &a1) {
return const_cast<RET>(a1);
}
};
template<class T> class cast_action<reinterpret_cast_action<T> > {
public:
template<class RET, class Arg1>
static RET apply(Arg1 &a1) {
return reinterpret_cast<RET>(a1);
}
};
// typeid action
class typeid_action {
public:
template<class RET, class Arg1>
static RET apply(Arg1 &a1) {
detail::suppress_unused_variable_warnings(a1);
return typeid(a1);
}
};
// sizeof action
class sizeof_action
{
public:
template<class RET, class Arg1>
static RET apply(Arg1 &a1) {
return sizeof(a1);
}
};
// return types of casting lambda_functors (all "T" type.)
template<template <class> class cast_type, class T, class A>
struct return_type_N<cast_action< cast_type<T> >, A> {
typedef T type;
};
// return type of typeid_action
template<class A>
struct return_type_N<typeid_action, A> {
typedef std::type_info const & type;
};
// return type of sizeof_action
template<class A>
struct return_type_N<sizeof_action, A> {
typedef std::size_t type;
};
// the four cast & typeid overloads.
// casts can take ordinary variables (not just lambda functors)
// static_cast
template <class T, class Arg1>
inline const lambda_functor<
lambda_functor_base<
action<1, cast_action<static_cast_action<T> > >,
tuple<typename const_copy_argument <const Arg1>::type>
>
>
ll_static_cast(const Arg1& a1) {
return
lambda_functor_base<
action<1, cast_action<static_cast_action<T> > >,
tuple<typename const_copy_argument <const Arg1>::type>
>
( tuple<typename const_copy_argument <const Arg1>::type>(a1));
}
// dynamic_cast
template <class T, class Arg1>
inline const lambda_functor<
lambda_functor_base<
action<1, cast_action<dynamic_cast_action<T> > >,
tuple<typename const_copy_argument <const Arg1>::type>
>
>
ll_dynamic_cast(const Arg1& a1) {
return
lambda_functor_base<
action<1, cast_action<dynamic_cast_action<T> > >,
tuple<typename const_copy_argument <const Arg1>::type>
>
( tuple<typename const_copy_argument <const Arg1>::type>(a1));
}
// const_cast
template <class T, class Arg1>
inline const lambda_functor<
lambda_functor_base<
action<1, cast_action<const_cast_action<T> > >,
tuple<typename const_copy_argument <const Arg1>::type>
>
>
ll_const_cast(const Arg1& a1) {
return
lambda_functor_base<
action<1, cast_action<const_cast_action<T> > >,
tuple<typename const_copy_argument <const Arg1>::type>
>
( tuple<typename const_copy_argument <const Arg1>::type>(a1));
}
// reinterpret_cast
template <class T, class Arg1>
inline const lambda_functor<
lambda_functor_base<
action<1, cast_action<reinterpret_cast_action<T> > >,
tuple<typename const_copy_argument <const Arg1>::type>
>
>
ll_reinterpret_cast(const Arg1& a1) {
return
lambda_functor_base<
action<1, cast_action<reinterpret_cast_action<T> > >,
tuple<typename const_copy_argument <const Arg1>::type>
>
( tuple<typename const_copy_argument <const Arg1>::type>(a1));
}
// typeid
// can be applied to a normal variable as well (can refer to a polymorphic
// class object)
template <class Arg1>
inline const lambda_functor<
lambda_functor_base<
action<1, typeid_action>,
tuple<typename const_copy_argument <const Arg1>::type>
>
>
ll_typeid(const Arg1& a1) {
return
lambda_functor_base<
action<1, typeid_action>,
tuple<typename const_copy_argument <const Arg1>::type>
>
( tuple<typename const_copy_argument <const Arg1>::type>(a1));
}
// sizeof(expression)
// Always takes a lambda expression (if not, built in sizeof will do)
template <class Arg1>
inline const lambda_functor<
lambda_functor_base<
action<1, sizeof_action>,
tuple<lambda_functor<Arg1> >
>
>
ll_sizeof(const lambda_functor<Arg1>& a1) {
return
lambda_functor_base<
action<1, sizeof_action>,
tuple<lambda_functor<Arg1> >
>
( tuple<lambda_functor<Arg1> >(a1));
}
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,274 @@
/*=============================================================================
Adaptable closures
Phoenix V0.9
Copyright (c) 2001-2002 Joel de Guzman
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)
URL: http://spirit.sourceforge.net/
==============================================================================*/
#ifndef BOOST_LAMBDA_CLOSURES_HPP
#define BOOST_LAMBDA_CLOSURES_HPP
///////////////////////////////////////////////////////////////////////////////
#include "boost/lambda/core.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace lambda {
///////////////////////////////////////////////////////////////////////////////
//
// Adaptable closures
//
// The framework will not be complete without some form of closures
// support. Closures encapsulate a stack frame where local
// variables are created upon entering a function and destructed
// upon exiting. Closures provide an environment for local
// variables to reside. Closures can hold heterogeneous types.
//
// Phoenix closures are true hardware stack based closures. At the
// very least, closures enable true reentrancy in lambda functions.
// A closure provides access to a function stack frame where local
// variables reside. Modeled after Pascal nested stack frames,
// closures can be nested just like nested functions where code in
// inner closures may access local variables from in-scope outer
// closures (accessing inner scopes from outer scopes is an error
// and will cause a run-time assertion failure).
//
// There are three (3) interacting classes:
//
// 1) closure:
//
// At the point of declaration, a closure does not yet create a
// stack frame nor instantiate any variables. A closure declaration
// declares the types and names[note] of the local variables. The
// closure class is meant to be subclassed. It is the
// responsibility of a closure subclass to supply the names for
// each of the local variable in the closure. Example:
//
// struct my_closure : closure<int, string, double> {
//
// member1 num; // names the 1st (int) local variable
// member2 message; // names the 2nd (string) local variable
// member3 real; // names the 3rd (double) local variable
// };
//
// my_closure clos;
//
// Now that we have a closure 'clos', its local variables can be
// accessed lazily using the dot notation. Each qualified local
// variable can be used just like any primitive actor (see
// primitives.hpp). Examples:
//
// clos.num = 30
// clos.message = arg1
// clos.real = clos.num * 1e6
//
// The examples above are lazily evaluated. As usual, these
// expressions return composite actors that will be evaluated
// through a second function call invocation (see operators.hpp).
// Each of the members (clos.xxx) is an actor. As such, applying
// the operator() will reveal its identity:
//
// clos.num() // will return the current value of clos.num
//
// *** [note] Acknowledgement: Juan Carlos Arevalo-Baeza (JCAB)
// introduced and initilally implemented the closure member names
// that uses the dot notation.
//
// 2) closure_member
//
// The named local variables of closure 'clos' above are actually
// closure members. The closure_member class is an actor and
// conforms to its conceptual interface. member1..memberN are
// predefined typedefs that correspond to each of the listed types
// in the closure template parameters.
//
// 3) closure_frame
//
// When a closure member is finally evaluated, it should refer to
// an actual instance of the variable in the hardware stack.
// Without doing so, the process is not complete and the evaluated
// member will result to an assertion failure. Remember that the
// closure is just a declaration. The local variables that a
// closure refers to must still be instantiated.
//
// The closure_frame class does the actual instantiation of the
// local variables and links these variables with the closure and
// all its members. There can be multiple instances of
// closure_frames typically situated in the stack inside a
// function. Each closure_frame instance initiates a stack frame
// with a new set of closure local variables. Example:
//
// void foo()
// {
// closure_frame<my_closure> frame(clos);
// /* do something */
// }
//
// where 'clos' is an instance of our closure 'my_closure' above.
// Take note that the usage above precludes locally declared
// classes. If my_closure is a locally declared type, we can still
// use its self_type as a paramater to closure_frame:
//
// closure_frame<my_closure::self_type> frame(clos);
//
// Upon instantiation, the closure_frame links the local variables
// to the closure. The previous link to another closure_frame
// instance created before is saved. Upon destruction, the
// closure_frame unlinks itself from the closure and relinks the
// preceding closure_frame prior to this instance.
//
// The local variables in the closure 'clos' above is default
// constructed in the stack inside function 'foo'. Once 'foo' is
// exited, all of these local variables are destructed. In some
// cases, default construction is not desirable and we need to
// initialize the local closure variables with some values. This
// can be done by passing in the initializers in a compatible
// tuple. A compatible tuple is one with the same number of
// elements as the destination and where each element from the
// destination can be constructed from each corresponding element
// in the source. Example:
//
// tuple<int, char const*, int> init(123, "Hello", 1000);
// closure_frame<my_closure> frame(clos, init);
//
// Here now, our closure_frame's variables are initialized with
// int: 123, char const*: "Hello" and int: 1000.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// closure_frame class
//
///////////////////////////////////////////////////////////////////////////////
template <typename ClosureT>
class closure_frame : public ClosureT::tuple_t {
public:
closure_frame(ClosureT& clos)
: ClosureT::tuple_t(), save(clos.frame), frame(clos.frame)
{ clos.frame = this; }
template <typename TupleT>
closure_frame(ClosureT& clos, TupleT const& init)
: ClosureT::tuple_t(init), save(clos.frame), frame(clos.frame)
{ clos.frame = this; }
~closure_frame()
{ frame = save; }
private:
closure_frame(closure_frame const&); // no copy
closure_frame& operator=(closure_frame const&); // no assign
closure_frame* save;
closure_frame*& frame;
};
///////////////////////////////////////////////////////////////////////////////
//
// closure_member class
//
///////////////////////////////////////////////////////////////////////////////
template <int N, typename ClosureT>
class closure_member {
public:
typedef typename ClosureT::tuple_t tuple_t;
closure_member()
: frame(ClosureT::closure_frame_ref()) {}
template <typename TupleT>
struct sig {
typedef typename detail::tuple_element_as_reference<
N, typename ClosureT::tuple_t
>::type type;
};
template <class Ret, class A, class B, class C>
// typename detail::tuple_element_as_reference
// <N, typename ClosureT::tuple_t>::type
Ret
call(A&, B&, C&) const
{
assert(frame);
return boost::tuples::get<N>(*frame);
}
private:
typename ClosureT::closure_frame_t*& frame;
};
///////////////////////////////////////////////////////////////////////////////
//
// closure class
//
///////////////////////////////////////////////////////////////////////////////
template <
typename T0 = null_type,
typename T1 = null_type,
typename T2 = null_type,
typename T3 = null_type,
typename T4 = null_type
>
class closure {
public:
typedef tuple<T0, T1, T2, T3, T4> tuple_t;
typedef closure<T0, T1, T2, T3, T4> self_t;
typedef closure_frame<self_t> closure_frame_t;
closure()
: frame(0) { closure_frame_ref(&frame); }
closure_frame_t& context() { assert(frame); return frame; }
closure_frame_t const& context() const { assert(frame); return frame; }
typedef lambda_functor<closure_member<0, self_t> > member1;
typedef lambda_functor<closure_member<1, self_t> > member2;
typedef lambda_functor<closure_member<2, self_t> > member3;
typedef lambda_functor<closure_member<3, self_t> > member4;
typedef lambda_functor<closure_member<4, self_t> > member5;
private:
closure(closure const&); // no copy
closure& operator=(closure const&); // no assign
template <int N, typename ClosureT>
friend class closure_member;
template <typename ClosureT>
friend class closure_frame;
static closure_frame_t*&
closure_frame_ref(closure_frame_t** frame_ = 0)
{
static closure_frame_t** frame = 0;
if (frame_ != 0)
frame = frame_;
return *frame;
}
closure_frame_t* frame;
};
}}
// namespace
#endif

View File

@@ -0,0 +1,240 @@
// - construct.hpp -- Lambda Library -------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
//
// -----------------------------------------------
#if !defined(BOOST_LAMBDA_CONSTRUCT_HPP)
#define BOOST_LAMBDA_CONSTRUCT_HPP
#include "boost/type_traits/remove_cv.hpp"
#include "boost/type_traits/is_pointer.hpp"
namespace boost {
namespace lambda {
// constructor is used together with bind. constructor<A> creates a bindable
// function object that passes its arguments forward to a constructor call
// of type A
template<class T> struct constructor {
template <class U> struct sig { typedef T type; };
T operator()() const {
return T();
}
template<class A1>
T operator()(A1& a1) const {
return T(a1);
}
template<class A1, class A2>
T operator()(A1& a1, A2& a2) const {
return T(a1, a2);
}
template<class A1, class A2, class A3>
T operator()(A1& a1, A2& a2, A3& a3) const {
return T(a1, a2, a3);
}
template<class A1, class A2, class A3, class A4>
T operator()(A1& a1, A2& a2, A3& a3, A4& a4) const {
return T(a1, a2, a3, a4);
}
template<class A1, class A2, class A3, class A4, class A5>
T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) const {
return T(a1, a2, a3, a4, a5);
}
template<class A1, class A2, class A3, class A4, class A5, class A6>
T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) const {
return T(a1, a2, a3, a4, a5, a6);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7>
T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) const {
return T(a1, a2, a3, a4, a5, a6, a7);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) const {
return T(a1, a2, a3, a4, a5, a6, a7, a8);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9) const {
return T(a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
T operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9, A10& a10) const {
return T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
}
};
namespace detail {
// A standard conforming compiler could disambiguate between
// A1* and A1&, but not all compilers do that, so we need the
// helpers
template <bool IsPointer>
struct destructor_helper {
template<class A1>
static void exec(A1& a1) {
// remove all the qualifiers, not sure whether it is necessary
typedef typename boost::remove_cv<A1>::type plainA1;
a1.~plainA1();
}
};
template <>
struct destructor_helper<true> {
template<class A1>
static void exec(A1* a1) {
typedef typename boost::remove_cv<A1>::type plainA1;
(*a1).~plainA1();
}
};
}
// destructor funtion object
struct destructor {
template <class T> struct sig { typedef void type; };
template<class A1>
void operator()(A1& a1) const {
typedef typename boost::remove_cv<A1>::type plainA1;
detail::destructor_helper<boost::is_pointer<plainA1>::value>::exec(a1);
}
};
// new_ptr is used together with bind.
// note: placement new is not supported
template<class T> struct new_ptr {
template <class U> struct sig { typedef T* type; };
T* operator()() const {
return new T();
}
template<class A1>
T* operator()(A1& a1) const {
return new T(a1);
}
template<class A1, class A2>
T* operator()(A1& a1, A2& a2) const {
return new T(a1, a2);
}
template<class A1, class A2, class A3>
T* operator()(A1& a1, A2& a2, A3& a3) const {
return new T(a1, a2, a3);
}
template<class A1, class A2, class A3, class A4>
T* operator()(A1& a1, A2& a2, A3& a3, A4& a4) const {
return new T(a1, a2, a3, a4);
}
template<class A1, class A2, class A3, class A4, class A5>
T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) const {
return new T(a1, a2, a3, a4, a5);
}
template<class A1, class A2, class A3, class A4, class A5, class A6>
T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) const {
return new T(a1, a2, a3, a4, a5, a6);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7>
T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) const {
return new T(a1, a2, a3, a4, a5, a6, a7);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) const {
return new T(a1, a2, a3, a4, a5, a6, a7, a8);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9) const {
return new T(a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
T* operator()(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9, A10& a10) const {
return new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
}
};
// delete_ptr return void
struct delete_ptr {
template <class U> struct sig { typedef void type; };
template <class A1>
void operator()(A1& a1) const {
delete a1;
}
};
// new_array is used together with bind.
template<class T> struct new_array {
template <class U> struct sig { typedef T* type; };
T* operator()(int size) const {
return new T[size];
}
};
// delete_ptr return void
struct delete_array {
template <class U> struct sig { typedef void type; };
template <class A1>
void operator()(A1& a1) const {
delete[] a1;
}
};
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,23 @@
// -- control_structures.hpp -- Boost Lambda Library --------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
#ifndef BOOST_LAMBDA_CONTROL_STRUCTURES_HPP
#define BOOST_LAMBDA_CONTROL_STRUCTURES_HPP
#include "boost/lambda/core.hpp"
// Arithmetic type promotion needed for if_then_else_return
#include "boost/lambda/detail/operator_actions.hpp"
#include "boost/lambda/detail/operator_return_type_traits.hpp"
#include "boost/lambda/if.hpp"
#include "boost/lambda/loops.hpp"
#endif

View File

@@ -0,0 +1,81 @@
// -- core.hpp -- Boost Lambda Library -------------------------------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
//
// Includes the core of LL, without any real features for client:
//
// tuples, lambda functors, return type deduction templates,
// argument substitution mechanism (select functions)
//
// Some functionality comes as well:
// Assignment and subscript operators, as well as function
// call operator for placeholder variables.
// -------------------------------------------------------------------------
#ifndef BOOST_LAMBDA_CORE_HPP
#define BOOST_LAMBDA_CORE_HPP
#include "boost/config.hpp"
#include "boost/type_traits/transform_traits.hpp"
#include "boost/type_traits/cv_traits.hpp"
#include "boost/tuple/tuple.hpp"
// inject some of the tuple names into lambda
namespace boost {
namespace lambda {
using ::boost::tuples::tuple;
using ::boost::tuples::null_type;
} // lambda
} // boost
#include "boost/lambda/detail/lambda_config.hpp"
#include "boost/lambda/detail/lambda_fwd.hpp"
#include "boost/lambda/detail/arity_code.hpp"
#include "boost/lambda/detail/actions.hpp"
#include "boost/lambda/detail/lambda_traits.hpp"
#include "boost/lambda/detail/function_adaptors.hpp"
#include "boost/lambda/detail/return_type_traits.hpp"
#include "boost/lambda/detail/select_functions.hpp"
#include "boost/lambda/detail/lambda_functor_base.hpp"
#include "boost/lambda/detail/lambda_functors.hpp"
#include "boost/lambda/detail/ret.hpp"
namespace boost {
namespace lambda {
namespace {
// These are constants types and need to be initialised
boost::lambda::placeholder1_type free1 = boost::lambda::placeholder1_type();
boost::lambda::placeholder2_type free2 = boost::lambda::placeholder2_type();
boost::lambda::placeholder3_type free3 = boost::lambda::placeholder3_type();
boost::lambda::placeholder1_type& BOOST_ATTRIBUTE_UNUSED _1 = free1;
boost::lambda::placeholder2_type& BOOST_ATTRIBUTE_UNUSED _2 = free2;
boost::lambda::placeholder3_type& BOOST_ATTRIBUTE_UNUSED _3 = free3;
// _1, _2, ... naming scheme by Peter Dimov
} // unnamed
} // lambda
} // boost
#endif //BOOST_LAMBDA_CORE_HPP

View File

@@ -0,0 +1,174 @@
// -- Boost Lambda Library - actions.hpp ----------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see www.boost.org
// ----------------------------------------------------------------
#ifndef BOOST_LAMBDA_ACTIONS_HPP
#define BOOST_LAMBDA_ACTIONS_HPP
namespace boost {
namespace lambda {
template<int Arity, class Act> class action;
// these need to be defined here, since the corresponding lambda
// functions are members of lambda_functor classes
class assignment_action {};
class subscript_action {};
template <class Action> class other_action;
// action for specifying the explicit return type
template <class RET> class explicit_return_type_action {};
// action for preventing the expansion of a lambda expression
struct protect_action {};
// must be defined here, comma is a special case
struct comma_action {};
// actions, for which the existence of protect is checked in return type
// deduction.
template <class Action> struct is_protectable {
BOOST_STATIC_CONSTANT(bool, value = false);
};
// NOTE: comma action is protectable. Other protectable actions
// are listed in operator_actions.hpp
template<> struct is_protectable<other_action<comma_action> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
namespace detail {
// this type is used in return type deductions to signal that deduction
// did not find a result. It does not necessarily mean an error, it commonly
// means that something else should be tried.
class unspecified {};
}
// function action is a special case: bind functions can be called with
// the return type specialized explicitly e.g. bind<int>(foo);
// If this call syntax is used, the return type is stored in the latter
// argument of function_action template. Otherwise the argument gets the type
// 'unspecified'.
// This argument is only relevant in the return type deduction code
template <int I, class Result_type = detail::unspecified>
class function_action {};
template<class T> class function_action<1, T> {
public:
template<class RET, class A1>
static RET apply(A1& a1) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1);
}
};
template<class T> class function_action<2, T> {
public:
template<class RET, class A1, class A2>
static RET apply(A1& a1, A2& a2) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1, a2);
}
};
template<class T> class function_action<3, T> {
public:
template<class RET, class A1, class A2, class A3>
static RET apply(A1& a1, A2& a2, A3& a3) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1, a2, a3);
}
};
template<class T> class function_action<4, T> {
public:
template<class RET, class A1, class A2, class A3, class A4>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1, a2, a3, a4);
}
};
template<class T> class function_action<5, T> {
public:
template<class RET, class A1, class A2, class A3, class A4, class A5>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1, a2, a3, a4, a5);
}
};
template<class T> class function_action<6, T> {
public:
template<class RET, class A1, class A2, class A3, class A4, class A5,
class A6>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1, a2, a3, a4, a5, a6);
}
};
template<class T> class function_action<7, T> {
public:
template<class RET, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1, a2, a3, a4, a5, a6, a7);
}
};
template<class T> class function_action<8, T> {
public:
template<class RET, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7,
A8& a8) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1, a2, a3, a4, a5, a6, a7, a8);
}
};
template<class T> class function_action<9, T> {
public:
template<class RET, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7,
A8& a8, A9& a9) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
};
template<class T> class function_action<10, T> {
public:
template<class RET, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9, class A10>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7,
A8& a8, A9& a9, A10& a10) {
return function_adaptor<typename boost::remove_cv<A1>::type>::
template apply<RET>(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
}
};
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,110 @@
// -- Boost Lambda Library -------------------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// --------------------------------------------------
#ifndef BOOST_LAMBDA_ARITY_CODE_HPP
#define BOOST_LAMBDA_ARITY_CODE_HPP
#include "boost/type_traits/cv_traits.hpp"
#include "boost/type_traits/transform_traits.hpp"
namespace boost {
namespace lambda {
// These constants state, whether a lambda_functor instantiation results from
// an expression which contains no placeholders (NONE),
// only free1 placeholders (FIRST),
// free2 placeholders and maybe free1 placeholders (SECOND),
// free3 and maybe free1 and free2 placeholders (THIRD),
// freeE placeholders and maybe free1 and free2 (EXCEPTION).
// RETHROW means, that a rethrow expression is used somewhere in the lambda_functor.
enum { NONE = 0x00, // Notice we are using bits as flags here.
FIRST = 0x01,
SECOND = 0x02,
THIRD = 0x04,
EXCEPTION = 0x08,
RETHROW = 0x10};
template<class T>
struct get_tuple_arity;
namespace detail {
template <class T> struct get_arity_;
} // end detail;
template <class T> struct get_arity {
BOOST_STATIC_CONSTANT(int, value = detail::get_arity_<typename boost::remove_cv<typename boost::remove_reference<T>::type>::type>::value);
};
namespace detail {
template<class T>
struct get_arity_ {
BOOST_STATIC_CONSTANT(int, value = 0);
};
template<class T>
struct get_arity_<lambda_functor<T> > {
BOOST_STATIC_CONSTANT(int, value = get_arity<T>::value);
};
template<class Action, class Args>
struct get_arity_<lambda_functor_base<Action, Args> > {
BOOST_STATIC_CONSTANT(int, value = get_tuple_arity<Args>::value);
};
template<int I>
struct get_arity_<placeholder<I> > {
BOOST_STATIC_CONSTANT(int, value = I);
};
} // detail
template<class T>
struct get_tuple_arity {
BOOST_STATIC_CONSTANT(int, value = get_arity<typename T::head_type>::value | get_tuple_arity<typename T::tail_type>::value);
};
template<>
struct get_tuple_arity<null_type> {
BOOST_STATIC_CONSTANT(int, value = 0);
};
// Does T have placeholder<I> as it's subexpression?
template<class T, int I>
struct has_placeholder {
BOOST_STATIC_CONSTANT(bool, value = (get_arity<T>::value & I) != 0);
};
template<int I, int J>
struct includes_placeholder {
BOOST_STATIC_CONSTANT(bool, value = (J & I) != 0);
};
template<int I, int J>
struct lacks_placeholder {
BOOST_STATIC_CONSTANT(bool, value = ((J & I) == 0));
};
} // namespace lambda
} // namespace boost
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,50 @@
// Boost Lambda Library -- control_constructs_common.hpp -------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// --------------------------------------------------------------------------
#if !defined(BOOST_CONTROL_CONSTRUCTS_COMMON_HPP)
#define BOOST_CONTROL_CONSTRUCTS_COMMON_HPP
namespace boost {
namespace lambda {
// special types of lambda functors, used with control structures
// to guarantee that they are composed correctly.
template<class Tag, class LambdaFunctor>
class tagged_lambda_functor;
template<class Tag, class Args>
class tagged_lambda_functor<Tag, lambda_functor<Args> >
: public lambda_functor<Args>
{
public:
tagged_lambda_functor(const Args& a) : lambda_functor<Args>(a) {}
tagged_lambda_functor(const lambda_functor<Args>& a)
: lambda_functor<Args>(a) {}
// for the no body cases in control structures.
tagged_lambda_functor() : lambda_functor<Args>() {}
};
} // lambda
} // boost
#endif // BOOST_CONTROL_CONSTRUCTS_COMMON_HPP

View File

@@ -0,0 +1,789 @@
// Boost Lambda Library - function_adaptors.hpp ----------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
#ifndef BOOST_LAMBDA_FUNCTION_ADAPTORS_HPP
#define BOOST_LAMBDA_FUNCTION_ADAPTORS_HPP
#include "boost/mpl/has_xxx.hpp"
#include "boost/tuple/tuple.hpp"
#include "boost/type_traits/same_traits.hpp"
#include "boost/type_traits/remove_reference.hpp"
#include "boost/type_traits/remove_cv.hpp"
#include "boost/type_traits/add_const.hpp"
#include "boost/type_traits/add_volatile.hpp"
#include "boost/utility/result_of.hpp"
namespace boost {
namespace lambda {
namespace detail {
BOOST_MPL_HAS_XXX_TEMPLATE_DEF(sig)
template<class Tuple>
struct remove_references_from_elements {
typedef typename boost::tuples::cons<
typename boost::remove_reference<typename Tuple::head_type>::type,
typename remove_references_from_elements<typename Tuple::tail_type>::type
> type;
};
template<>
struct remove_references_from_elements<boost::tuples::null_type> {
typedef boost::tuples::null_type type;
};
}
template <class Func> struct function_adaptor {
typedef typename detail::remove_reference_and_cv<Func>::type plainF;
#if !defined(BOOST_NO_RESULT_OF)
// Support functors that use the boost::result_of return type convention.
template<class Tuple, int Length, bool HasSig>
struct result_converter;
template<class Tuple, int Length>
struct result_converter<Tuple, Length, true>
: plainF::template sig<
typename detail::remove_references_from_elements<Tuple>::type
>
{};
template<class Tuple>
struct result_converter<Tuple, 0, false>
: result_of<plainF()>
{};
template<class Tuple>
struct result_converter<Tuple, 1, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 2, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 3, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 4, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 5, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 6, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 7, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type,
typename tuples::element<7, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 8, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type,
typename tuples::element<7, Tuple>::type,
typename tuples::element<8, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 9, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type,
typename tuples::element<7, Tuple>::type,
typename tuples::element<8, Tuple>::type,
typename tuples::element<9, Tuple>::type)
>
{};
// we do not know the return type off-hand, we must ask it from Func
// To sig we pass a cons list, where the head is the function object type
// itself (potentially cv-qualified)
// and the tail contains the types of the actual arguments to be passed
// to the function object. The arguments can be cv qualified
// as well.
template <class Args>
struct sig
: result_converter<
Args
, tuples::length<typename Args::tail_type>::value
, detail::has_sig<plainF>::value
>
{};
#else // BOOST_NO_RESULT_OF
template <class Args> class sig {
typedef typename detail::remove_reference_and_cv<Func>::type plainF;
public:
typedef typename plainF::template sig<
typename detail::remove_references_from_elements<Args>::type
>::type type;
};
#endif
template<class RET, class A1>
static RET apply(A1& a1) {
return a1();
}
template<class RET, class A1, class A2>
static RET apply(A1& a1, A2& a2) {
return a1(a2);
}
template<class RET, class A1, class A2, class A3>
static RET apply(A1& a1, A2& a2, A3& a3) {
return a1(a2, a3);
}
template<class RET, class A1, class A2, class A3, class A4>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4) {
return a1(a2, a3, a4);
}
template<class RET, class A1, class A2, class A3, class A4, class A5>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
return a1(a2, a3, a4, a5);
}
template<class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
return a1(a2, a3, a4, a5, a6);
}
template<class RET, class A1, class A2, class A3, class A4, class A5, class A6,
class A7>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6,
A7& a7) {
return a1(a2, a3, a4, a5, a6, a7);
}
template<class RET, class A1, class A2, class A3, class A4, class A5, class A6,
class A7, class A8>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6,
A7& a7, A8& a8) {
return a1(a2, a3, a4, a5, a6, a7, a8);
}
template<class RET, class A1, class A2, class A3, class A4, class A5, class A6,
class A7, class A8, class A9>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6,
A7& a7, A8& a8, A9& a9) {
return a1(a2, a3, a4, a5, a6, a7, a8, a9);
}
template<class RET, class A1, class A2, class A3, class A4, class A5, class A6,
class A7, class A8, class A9, class A10>
static RET apply(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6,
A7& a7, A8& a8, A9& a9, A10& a10) {
return a1(a2, a3, a4, a5, a6, a7, a8, a9, a10);
}
};
template <class Func> struct function_adaptor<const Func>; // error
// -- function adaptors with data member access
template <class Object, class T>
struct function_adaptor<T Object::*> {
// typedef detail::unspecified type;
// T can have qualifiers and can be a reference type
// We get the return type by adding const, if the object through which
// the data member is accessed is const, and finally adding a reference
template<class Args> class sig {
typedef typename boost::tuples::element<1, Args>::type argument_type;
typedef typename boost::remove_reference<
argument_type
>::type unref_type;
typedef typename detail::IF<boost::is_const<unref_type>::value,
typename boost::add_const<T>::type,
T
>::RET properly_consted_return_type;
typedef typename detail::IF<boost::is_volatile<unref_type>::value,
typename boost::add_volatile<properly_consted_return_type>::type,
properly_consted_return_type
>::RET properly_cvd_return_type;
public:
typedef typename detail::IF<boost::is_reference<argument_type>::value,
typename boost::add_reference<properly_cvd_return_type>::type,
typename boost::remove_cv<T>::type
>::RET type;
};
template <class RET>
static RET apply( T Object::*data, Object& o) {
return o.*data;
}
template <class RET>
static RET apply( T Object::*data, const Object& o) {
return o.*data;
}
template <class RET>
static RET apply( T Object::*data, volatile Object& o) {
return o.*data;
}
template <class RET>
static RET apply( T Object::*data, const volatile Object& o) {
return o.*data;
}
template <class RET>
static RET apply( T Object::*data, Object* o) {
return o->*data;
}
template <class RET>
static RET apply( T Object::*data, const Object* o) {
return o->*data;
}
template <class RET>
static RET apply( T Object::*data, volatile Object* o) {
return o->*data;
}
template <class RET>
static RET apply( T Object::*data, const volatile Object* o) {
return o->*data;
}
};
// -- function adaptors with 1 argument apply
template <class Result>
struct function_adaptor<Result (void)> {
template<class T> struct sig { typedef Result type; };
template <class RET>
static Result apply(Result (*func)()) {
return func();
}
};
template <class Result>
struct function_adaptor<Result (*)(void)> {
template<class T> struct sig { typedef Result type; };
template <class RET>
static Result apply(Result (*func)()) {
return func();
}
};
// -- function adaptors with 2 argument apply
template <class Object, class Result>
struct function_adaptor<Result (Object::*)() const> {
template<class T> struct sig { typedef Result type; };
template <class RET>
static Result apply( Result (Object::*func)() const, const Object* o) {
return (o->*func)();
}
template <class RET>
static Result apply( Result (Object::*func)() const, const Object& o) {
return (o.*func)();
}
};
template <class Object, class Result>
struct function_adaptor<Result (Object::*)()> {
template<class T> struct sig { typedef Result type; };
template <class RET>
static Result apply( Result (Object::*func)(), Object* o) {
return (o->*func)();
}
template <class RET>
static Result apply( Result (Object::*func)(), Object& o) {
return (o.*func)();
}
};
template <class Arg1, class Result>
struct function_adaptor<Result (Arg1)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1>
static Result apply(Result (*func)(Arg1), A1& a1) {
return func(a1);
}
};
template <class Arg1, class Result>
struct function_adaptor<Result (*)(Arg1)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1>
static Result apply(Result (*func)(Arg1), A1& a1) {
return func(a1);
}
};
// -- function adaptors with 3 argument apply
template <class Object, class Arg1, class Result>
struct function_adaptor<Result (Object::*)(Arg1) const> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1>
static Result apply( Result (Object::*func)(Arg1) const, const Object* o,
A1& a1) {
return (o->*func)(a1);
}
template <class RET, class A1>
static Result apply( Result (Object::*func)(Arg1) const, const Object& o,
A1& a1) {
return (o.*func)(a1);
}
};
template <class Object, class Arg1, class Result>
struct function_adaptor<Result (Object::*)(Arg1)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1>
static Result apply( Result (Object::*func)(Arg1), Object* o, A1& a1) {
return (o->*func)(a1);
}
template <class RET, class A1>
static Result apply( Result (Object::*func)(Arg1), Object& o, A1& a1) {
return (o.*func)(a1);
}
};
template <class Arg1, class Arg2, class Result>
struct function_adaptor<Result (Arg1, Arg2)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2>
static Result apply(Result (*func)(Arg1, Arg2), A1& a1, A2& a2) {
return func(a1, a2);
}
};
template <class Arg1, class Arg2, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2>
static Result apply(Result (*func)(Arg1, Arg2), A1& a1, A2& a2) {
return func(a1, a2);
}
};
// -- function adaptors with 4 argument apply
template <class Object, class Arg1, class Arg2, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2) const> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2>
static Result apply( Result (Object::*func)(Arg1, Arg2) const, const Object* o, A1& a1, A2& a2) {
return (o->*func)(a1, a2);
}
template <class RET, class A1, class A2>
static Result apply( Result (Object::*func)(Arg1, Arg2) const, const Object& o, A1& a1, A2& a2) {
return (o.*func)(a1, a2);
}
};
template <class Object, class Arg1, class Arg2, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2>
static Result apply( Result (Object::*func)(Arg1, Arg2), Object* o, A1& a1, A2& a2) {
return (o->*func)(a1, a2);
}
template <class RET, class A1, class A2>
static Result apply( Result (Object::*func)(Arg1, Arg2), Object& o, A1& a1, A2& a2) {
return (o.*func)(a1, a2);
}
};
template <class Arg1, class Arg2, class Arg3, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3>
static Result apply(Result (*func)(Arg1, Arg2, Arg3), A1& a1, A2& a2, A3& a3) {
return func(a1, a2, a3);
}
};
template <class Arg1, class Arg2, class Arg3, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3>
static Result apply(Result (*func)(Arg1, Arg2, Arg3), A1& a1, A2& a2, A3& a3) {
return func(a1, a2, a3);
}
};
// -- function adaptors with 5 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3) const> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3) const, const Object* o, A1& a1, A2& a2, A3& a3) {
return (o->*func)(a1, a2, a3);
}
template <class RET, class A1, class A2, class A3>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3) const, const Object& o, A1& a1, A2& a2, A3& a3) {
return (o.*func)(a1, a2, a3);
}
};
template <class Object, class Arg1, class Arg2, class Arg3, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3), Object* o, A1& a1, A2& a2, A3& a3) {
return (o->*func)(a1, a2, a3);
}
template <class RET, class A1, class A2, class A3>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3), Object& o, A1& a1, A2& a2, A3& a3) {
return (o.*func)(a1, a2, a3);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4), A1& a1, A2& a2, A3& a3, A4& a4) {
return func(a1, a2, a3, a4);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4), A1& a1, A2& a2, A3& a3, A4& a4) {
return func(a1, a2, a3, a4);
}
};
// -- function adaptors with 6 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4) const> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4) {
return (o->*func)(a1, a2, a3, a4);
}
template <class RET, class A1, class A2, class A3, class A4>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4) const, const Object& o, A1& a1, A2& a2, A3& a3, A4& a4) {
return (o.*func)(a1, a2, a3, a4);
}
};
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4), Object* o, A1& a1, A2& a2, A3& a3, A4& a4) {
return (o->*func)(a1, a2, a3, a4);
}
template <class RET, class A1, class A2, class A3, class A4>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4), Object& o, A1& a1, A2& a2, A3& a3, A4& a4) {
return (o.*func)(a1, a2, a3, a4);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
return func(a1, a2, a3, a4, a5);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
return func(a1, a2, a3, a4, a5);
}
};
// -- function adaptors with 7 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5) const> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
return (o->*func)(a1, a2, a3, a4, a5);
}
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5) const, const Object& o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
return (o.*func)(a1, a2, a3, a4, a5);
}
};
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5), Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
return (o->*func)(a1, a2, a3, a4, a5);
}
template <class RET, class A1, class A2, class A3, class A4, class A5>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5), Object& o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
return (o.*func)(a1, a2, a3, a4, a5);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
return func(a1, a2, a3, a4, a5, a6);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
return func(a1, a2, a3, a4, a5, a6);
}
};
// -- function adaptors with 8 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
return (o->*func)(a1, a2, a3, a4, a5, a6);
}
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) const, const Object& o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
return (o.*func)(a1, a2, a3, a4, a5, a6);
}
};
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
return (o->*func)(a1, a2, a3, a4, a5, a6);
}
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), Object& o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6) {
return (o.*func)(a1, a2, a3, a4, a5, a6);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
return func(a1, a2, a3, a4, a5, a6, a7);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
return func(a1, a2, a3, a4, a5, a6, a7);
}
};
// -- function adaptors with 9 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
return (o->*func)(a1, a2, a3, a4, a5, a6, a7);
}
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) const, const Object& o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
return (o.*func)(a1, a2, a3, a4, a5, a6, a7);
}
};
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7), Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
return (o->*func)(a1, a2, a3, a4, a5, a6, a7);
}
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7), Object& o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7) {
return (o.*func)(a1, a2, a3, a4, a5, a6, a7);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
return func(a1, a2, a3, a4, a5, a6, a7, a8);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
return func(a1, a2, a3, a4, a5, a6, a7, a8);
}
};
// -- function adaptors with 10 argument apply
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) const> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) const, const Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
return (o->*func)(a1, a2, a3, a4, a5, a6, a7, a8);
}
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) const, const Object& o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
return (o.*func)(a1, a2, a3, a4, a5, a6, a7, a8);
}
};
template <class Object, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Result>
struct function_adaptor<Result (Object::*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), Object* o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
return (o->*func)(a1, a2, a3, a4, a5, a6, a7, a8);
}
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
static Result apply( Result (Object::*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), Object& o, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8) {
return (o.*func)(a1, a2, a3, a4, a5, a6, a7, a8);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9, class Result>
struct function_adaptor<Result (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9) {
return func(a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
};
template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9, class Result>
struct function_adaptor<Result (*)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)> {
template<class T> struct sig { typedef Result type; };
template <class RET, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
static Result apply(Result (*func)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9), A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6, A7& a7, A8& a8, A9& a9) {
return func(a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
};
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,104 @@
// Boost Lambda Library - is_instance_of.hpp ---------------------
// Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ---------------------------------------------------------------
#ifndef BOOST_LAMBDA_IS_INSTANCE_OF
#define BOOST_LAMBDA_IS_INSTANCE_OF
#include "boost/config.hpp" // for BOOST_STATIC_CONSTANT
#include "boost/type_traits/conversion_traits.hpp" // for is_convertible
#include "boost/preprocessor/enum_shifted_params.hpp"
#include "boost/preprocessor/repeat_2nd.hpp"
// is_instance_of --------------------------------
//
// is_instance_of_n<A, B>::value is true, if type A is
// an instantiation of a template B, or A derives from an instantiation
// of template B
//
// n is the number of template arguments for B
//
// Example:
// is_instance_of_2<std::istream, basic_stream>::value == true
// The original implementation was somewhat different, with different versions
// for different compilers. However, there was still a problem
// with gcc.3.0.2 and 3.0.3 compilers, which didn't think regard
// is_instance_of_N<...>::value was a constant.
// John Maddock suggested the way around this problem by building
// is_instance_of templates using boost::is_convertible.
// Now we only have one version of is_instance_of templates, which delagate
// all the nasty compiler tricks to is_convertible.
#define BOOST_LAMBDA_CLASS(z, N,A) BOOST_PP_COMMA_IF(N) class
#define BOOST_LAMBDA_CLASS_ARG(z, N,A) BOOST_PP_COMMA_IF(N) class A##N
#define BOOST_LAMBDA_ARG(z, N,A) BOOST_PP_COMMA_IF(N) A##N
#define BOOST_LAMBDA_CLASS_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_CLASS, NAME)
#define BOOST_LAMBDA_CLASS_ARG_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_CLASS_ARG, NAME)
#define BOOST_LAMBDA_ARG_LIST(n, NAME) BOOST_PP_REPEAT(n, BOOST_LAMBDA_ARG, NAME)
namespace boost {
namespace lambda {
#define BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE(INDEX) \
\
namespace detail { \
\
template <template<BOOST_LAMBDA_CLASS_LIST(INDEX,T)> class F> \
struct BOOST_PP_CAT(conversion_tester_,INDEX) { \
template<BOOST_LAMBDA_CLASS_ARG_LIST(INDEX,A)> \
BOOST_PP_CAT(conversion_tester_,INDEX) \
(const F<BOOST_LAMBDA_ARG_LIST(INDEX,A)>&); \
}; \
\
} /* end detail */ \
\
template <class From, template <BOOST_LAMBDA_CLASS_LIST(INDEX,T)> class To> \
struct BOOST_PP_CAT(is_instance_of_,INDEX) \
{ \
private: \
typedef ::boost::is_convertible< \
From, \
BOOST_PP_CAT(detail::conversion_tester_,INDEX)<To> \
> helper_type; \
\
public: \
BOOST_STATIC_CONSTANT(bool, value = helper_type::value); \
};
#define BOOST_LAMBDA_HELPER(z, N, A) BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE( BOOST_PP_INC(N) )
// Generate the traits for 1-4 argument templates
BOOST_PP_REPEAT_2ND(4,BOOST_LAMBDA_HELPER,FOO)
#undef BOOST_LAMBDA_HELPER
#undef BOOST_LAMBDA_IS_INSTANCE_OF_TEMPLATE
#undef BOOST_LAMBDA_CLASS
#undef BOOST_LAMBDA_ARG
#undef BOOST_LAMBDA_CLASS_ARG
#undef BOOST_LAMBDA_CLASS_LIST
#undef BOOST_LAMBDA_ARG_LIST
#undef BOOST_LAMBDA_CLASS_ARG_LIST
} // lambda
} // boost
#endif

View File

@@ -0,0 +1,41 @@
// Boost Lambda Library - lambda_config.hpp ------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ---------------------------------------------------------------
#ifndef BOOST_LAMBDA_LAMBDA_CONFIG_HPP
#define BOOST_LAMBDA_LAMBDA_CONFIG_HPP
// add to boost/config.hpp
// for now
# if defined __GNUC__
# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
# define BOOST_REF_TO_FUNC_CONFLICTS_WITH_REF_TO_T
# define BOOST_LAMBDA_INCORRECT_BIND_OVERLOADING
# endif
# endif // __GNUC__
#if defined __KCC
#define BOOST_NO_FDECL_TEMPLATES_AS_TEMPLATE_TEMPLATE_PARAMS
#endif // __KCC
#endif

View File

@@ -0,0 +1,615 @@
// Boost Lambda Library lambda_functor_base.hpp -----------------------------
//
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ------------------------------------------------------------
#ifndef BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
#define BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
#include "boost/type_traits/add_reference.hpp"
#include "boost/type_traits/add_const.hpp"
#include "boost/type_traits/remove_const.hpp"
#include "boost/lambda/detail/lambda_fwd.hpp"
#include "boost/lambda/detail/lambda_traits.hpp"
namespace boost {
namespace lambda {
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
// for return type deductions we wrap bound argument to this class,
// which fulfils the base class contract for lambda_functors
template <class T>
class identity {
T elem;
public:
typedef T element_t;
// take all parameters as const references. Note that non-const references
// stay as they are.
typedef typename boost::add_reference<
typename boost::add_const<T>::type
>::type par_t;
explicit identity(par_t t) : elem(t) {}
template <typename SigArgs>
struct sig { typedef typename boost::remove_const<element_t>::type type; };
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return elem; }
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
template <class T>
inline lambda_functor<identity<T&> > var(T& t) { return identity<T&>(t); }
// for lambda functors, var is an identity operator. It was forbidden
// at some point, but we might want to var something that can be a
// non-lambda functor or a lambda functor.
template <class T>
lambda_functor<T> var(const lambda_functor<T>& t) { return t; }
template <class T> struct var_type {
typedef lambda_functor<identity<T&> > type;
};
template <class T>
inline
lambda_functor<identity<typename bound_argument_conversion<const T>::type> >
constant(const T& t) {
return identity<typename bound_argument_conversion<const T>::type>(t);
}
template <class T>
lambda_functor<T> constant(const lambda_functor<T>& t) { return t; }
template <class T> struct constant_type {
typedef
lambda_functor<
identity<typename bound_argument_conversion<const T>::type>
> type;
};
template <class T>
inline lambda_functor<identity<const T&> > constant_ref(const T& t) {
return identity<const T&>(t);
}
template <class T>
lambda_functor<T> constant_ref(const lambda_functor<T>& t) { return t; }
template <class T> struct constant_ref_type {
typedef
lambda_functor<identity<const T&> > type;
};
// as_lambda_functor turns any types to lambda functors
// non-lambda_functors will be bound argument types
template <class T>
struct as_lambda_functor {
typedef typename
detail::remove_reference_and_cv<T>::type plain_T;
typedef typename
detail::IF<is_lambda_functor<plain_T>::value,
plain_T,
lambda_functor<
identity<typename bound_argument_conversion<T>::type>
>
>::RET type;
};
// turns arbitrary objects into lambda functors
template <class T>
inline
lambda_functor<identity<typename bound_argument_conversion<const T>::type> >
to_lambda_functor(const T& t) {
return identity<typename bound_argument_conversion<const T>::type>(t);
}
template <class T>
inline lambda_functor<T>
to_lambda_functor(const lambda_functor<T>& t) {
return t;
}
namespace detail {
// In a call constify_rvals<T>::go(x)
// x should be of type T. If T is a non-reference type, do
// returns x as const reference.
// Otherwise the type doesn't change.
// The purpose of this class is to avoid
// 'cannot bind temporaries to non-const references' errors.
template <class T> struct constify_rvals {
template<class U>
static inline const U& go(const U& u) { return u; }
};
template <class T> struct constify_rvals<T&> {
template<class U>
static inline U& go(U& u) { return u; }
};
// check whether one of the elements of a tuple (cons list) is of type
// null_type. Needed, because the compiler goes ahead and instantiates
// sig template for nullary case even if the nullary operator() is not
// called
template <class T> struct is_null_type
{ BOOST_STATIC_CONSTANT(bool, value = false); };
template <> struct is_null_type<null_type>
{ BOOST_STATIC_CONSTANT(bool, value = true); };
template<class Tuple> struct has_null_type {
BOOST_STATIC_CONSTANT(bool, value = (is_null_type<typename Tuple::head_type>::value || has_null_type<typename Tuple::tail_type>::value));
};
template<> struct has_null_type<null_type> {
BOOST_STATIC_CONSTANT(bool, value = false);
};
// helpers -------------------
template<class Args, class SigArgs>
class deduce_argument_types_ {
typedef typename as_lambda_functor<typename Args::head_type>::type lf_t;
typedef typename lf_t::inherited::template sig<SigArgs>::type el_t;
public:
typedef
boost::tuples::cons<
el_t,
typename deduce_argument_types_<typename Args::tail_type, SigArgs>::type
> type;
};
template<class SigArgs>
class deduce_argument_types_<null_type, SigArgs> {
public:
typedef null_type type;
};
// // note that tuples cannot have plain function types as elements.
// // Hence, all other types will be non-const, except references to
// // functions.
// template <class T> struct remove_reference_except_from_functions {
// typedef typename boost::remove_reference<T>::type t;
// typedef typename detail::IF<boost::is_function<t>::value, T, t>::RET type;
// };
template<class Args, class SigArgs>
class deduce_non_ref_argument_types_ {
typedef typename as_lambda_functor<typename Args::head_type>::type lf_t;
typedef typename lf_t::inherited::template sig<SigArgs>::type el_t;
public:
typedef
boost::tuples::cons<
// typename detail::remove_reference_except_from_functions<el_t>::type,
typename boost::remove_reference<el_t>::type,
typename deduce_non_ref_argument_types_<typename Args::tail_type, SigArgs>::type
> type;
};
template<class SigArgs>
class deduce_non_ref_argument_types_<null_type, SigArgs> {
public:
typedef null_type type;
};
// -------------
// take stored Args and Open Args, and return a const list with
// deduced elements (real return types)
template<class Args, class SigArgs>
class deduce_argument_types {
typedef typename deduce_argument_types_<Args, SigArgs>::type t1;
public:
typedef typename detail::IF<
has_null_type<t1>::value, null_type, t1
>::RET type;
};
// take stored Args and Open Args, and return a const list with
// deduced elements (references are stripped from the element types)
template<class Args, class SigArgs>
class deduce_non_ref_argument_types {
typedef typename deduce_non_ref_argument_types_<Args, SigArgs>::type t1;
public:
typedef typename detail::IF<
has_null_type<t1>::value, null_type, t1
>::RET type;
};
template <int N, class Args, class SigArgs>
struct nth_return_type_sig {
typedef typename
as_lambda_functor<
typename boost::tuples::element<N, Args>::type
// typename tuple_element_as_reference<N, Args>::type
>::type lf_type;
typedef typename lf_type::inherited::template sig<SigArgs>::type type;
};
template<int N, class Tuple> struct element_or_null {
typedef typename boost::tuples::element<N, Tuple>::type type;
};
template<int N> struct element_or_null<N, null_type> {
typedef null_type type;
};
} // end detail
// -- lambda_functor base ---------------------
// the explicit_return_type_action case -----------------------------------
template<class RET, class Args>
class lambda_functor_base<explicit_return_type_action<RET>, Args>
{
public:
Args args;
typedef RET result_type;
explicit lambda_functor_base(const Args& a) : args(a) {}
template <class SigArgs> struct sig { typedef RET type; };
template<class RET_, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const
{
return detail::constify_rvals<RET>::go(
detail::r_select<RET>::go(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS));
}
};
// the protect_action case -----------------------------------
template<class Args>
class lambda_functor_base<protect_action, Args>
{
public:
Args args;
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const
{
CALL_USE_ARGS;
return boost::tuples::get<0>(args);
}
template<class SigArgs> struct sig {
// typedef typename detail::tuple_element_as_reference<0, SigArgs>::type type;
typedef typename boost::tuples::element<0, Args>::type type;
};
};
// Do nothing --------------------------------------------------------
class do_nothing_action {};
template<class Args>
class lambda_functor_base<do_nothing_action, Args> {
// Args args;
public:
// explicit lambda_functor_base(const Args& a) {}
lambda_functor_base() {}
template<class RET, CALL_TEMPLATE_ARGS> RET call(CALL_FORMAL_ARGS) const {
return CALL_USE_ARGS;
}
template<class SigArgs> struct sig { typedef void type; };
};
// These specializations provide a shorter notation to define actions.
// These lambda_functor_base instances take care of the recursive evaluation
// of the arguments and pass the evaluated arguments to the apply function
// of an action class. To make action X work with these classes, one must
// instantiate the lambda_functor_base as:
// lambda_functor_base<action<ARITY, X>, Args>
// Where ARITY is the arity of the apply function in X
// The return type is queried as:
// return_type_N<X, EvaluatedArgumentTypes>::type
// for which there must be a specialization.
// Function actions, casts, throws,... all go via these classes.
template<class Act, class Args>
class lambda_functor_base<action<0, Act>, Args>
{
public:
// Args args; not needed
explicit lambda_functor_base(const Args& /*a*/) {}
template<class SigArgs> struct sig {
typedef typename return_type_N<Act, null_type>::type type;
};
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
CALL_USE_ARGS;
return Act::template apply<RET>();
}
};
#if defined BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART
#error "Multiple defines of BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART"
#endif
#define BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(ARITY) \
template<class Act, class Args> \
class lambda_functor_base<action<ARITY, Act>, Args> \
{ \
public: \
Args args; \
\
explicit lambda_functor_base(const Args& a) : args(a) {} \
\
template<class SigArgs> struct sig { \
typedef typename \
detail::deduce_argument_types<Args, SigArgs>::type rets_t; \
public: \
typedef typename \
return_type_N_prot<Act, rets_t>::type type; \
}; \
\
\
template<class RET, CALL_TEMPLATE_ARGS> \
RET call(CALL_FORMAL_ARGS) const { \
using boost::tuples::get; \
using detail::constify_rvals; \
using detail::r_select; \
using detail::element_or_null; \
using detail::deduce_argument_types;
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(1)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS))
);
}
};
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(2)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
typedef typename element_or_null<1, rets_t>::type rt1;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS))
);
}
};
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(3)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
typedef typename element_or_null<1, rets_t>::type rt1;
typedef typename element_or_null<2, rets_t>::type rt2;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS))
);
}
};
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(4)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
typedef typename element_or_null<1, rets_t>::type rt1;
typedef typename element_or_null<2, rets_t>::type rt2;
typedef typename element_or_null<3, rets_t>::type rt3;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS))
);
}
};
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(5)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
typedef typename element_or_null<1, rets_t>::type rt1;
typedef typename element_or_null<2, rets_t>::type rt2;
typedef typename element_or_null<3, rets_t>::type rt3;
typedef typename element_or_null<4, rets_t>::type rt4;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS))
);
}
};
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(6)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
typedef typename element_or_null<1, rets_t>::type rt1;
typedef typename element_or_null<2, rets_t>::type rt2;
typedef typename element_or_null<3, rets_t>::type rt3;
typedef typename element_or_null<4, rets_t>::type rt4;
typedef typename element_or_null<5, rets_t>::type rt5;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS))
);
}
};
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(7)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
typedef typename element_or_null<1, rets_t>::type rt1;
typedef typename element_or_null<2, rets_t>::type rt2;
typedef typename element_or_null<3, rets_t>::type rt3;
typedef typename element_or_null<4, rets_t>::type rt4;
typedef typename element_or_null<5, rets_t>::type rt5;
typedef typename element_or_null<6, rets_t>::type rt6;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS))
);
}
};
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(8)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
typedef typename element_or_null<1, rets_t>::type rt1;
typedef typename element_or_null<2, rets_t>::type rt2;
typedef typename element_or_null<3, rets_t>::type rt3;
typedef typename element_or_null<4, rets_t>::type rt4;
typedef typename element_or_null<5, rets_t>::type rt5;
typedef typename element_or_null<6, rets_t>::type rt6;
typedef typename element_or_null<7, rets_t>::type rt7;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt7>::go(r_select<rt7>::go(get<7>(args), CALL_ACTUAL_ARGS))
);
}
};
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(9)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
typedef typename element_or_null<1, rets_t>::type rt1;
typedef typename element_or_null<2, rets_t>::type rt2;
typedef typename element_or_null<3, rets_t>::type rt3;
typedef typename element_or_null<4, rets_t>::type rt4;
typedef typename element_or_null<5, rets_t>::type rt5;
typedef typename element_or_null<6, rets_t>::type rt6;
typedef typename element_or_null<7, rets_t>::type rt7;
typedef typename element_or_null<8, rets_t>::type rt8;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt7>::go(r_select<rt7>::go(get<7>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt8>::go(r_select<rt8>::go(get<8>(args), CALL_ACTUAL_ARGS))
);
}
};
BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART(10)
typedef typename
deduce_argument_types<Args, tuple<CALL_REFERENCE_TYPES> >::type rets_t;
typedef typename element_or_null<0, rets_t>::type rt0;
typedef typename element_or_null<1, rets_t>::type rt1;
typedef typename element_or_null<2, rets_t>::type rt2;
typedef typename element_or_null<3, rets_t>::type rt3;
typedef typename element_or_null<4, rets_t>::type rt4;
typedef typename element_or_null<5, rets_t>::type rt5;
typedef typename element_or_null<6, rets_t>::type rt6;
typedef typename element_or_null<7, rets_t>::type rt7;
typedef typename element_or_null<8, rets_t>::type rt8;
typedef typename element_or_null<9, rets_t>::type rt9;
return Act::template apply<RET>(
constify_rvals<rt0>::go(r_select<rt0>::go(get<0>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt1>::go(r_select<rt1>::go(get<1>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt2>::go(r_select<rt2>::go(get<2>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt3>::go(r_select<rt3>::go(get<3>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt4>::go(r_select<rt4>::go(get<4>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt5>::go(r_select<rt5>::go(get<5>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt6>::go(r_select<rt6>::go(get<6>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt7>::go(r_select<rt7>::go(get<7>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt8>::go(r_select<rt8>::go(get<8>(args), CALL_ACTUAL_ARGS)),
constify_rvals<rt9>::go(r_select<rt9>::go(get<9>(args), CALL_ACTUAL_ARGS))
);
}
};
#undef BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_FIRST_PART
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,357 @@
// Boost Lambda Library - lambda_functors.hpp -------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
// ------------------------------------------------
#ifndef BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
#define BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/result_of.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
#include <boost/mpl/or.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_array.hpp>
#define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1)\
typename lazy_disable_if<is_array<A1>, typename R1 >::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) \
typename lazy_disable_if<mpl::or_<is_array<A1>, is_array<A2> >, typename R1, R2 >::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) \
typename lazy_disable_if<mpl::or_<is_array<A1>, is_array<A2>, is_array<A3> >, typename R1, R2, R3 >::type
#else
#define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1) typename R1::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) typename R1, R2::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) typename R1, R2, R3::type
#endif
namespace boost {
namespace lambda {
// -- lambda_functor --------------------------------------------
// --------------------------------------------------------------
//inline const null_type const_null_type() { return null_type(); }
namespace detail {
namespace {
static const null_type constant_null_type = null_type();
} // unnamed
} // detail
class unused {};
#define cnull_type() detail::constant_null_type
// -- free variables types --------------------------------------------------
// helper to work around the case where the nullary return type deduction
// is always performed, even though the functor is not nullary
namespace detail {
template<int N, class Tuple> struct get_element_or_null_type {
typedef typename
detail::tuple_element_as_reference<N, Tuple>::type type;
};
template<int N> struct get_element_or_null_type<N, null_type> {
typedef null_type type;
};
}
template <int I> struct placeholder;
template<> struct placeholder<FIRST> {
template<class SigArgs> struct sig {
typedef typename detail::get_element_or_null_type<0, SigArgs>::type type;
};
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
BOOST_STATIC_ASSERT(boost::is_reference<RET>::value);
CALL_USE_ARGS; // does nothing, prevents warnings for unused args
return a;
}
};
template<> struct placeholder<SECOND> {
template<class SigArgs> struct sig {
typedef typename detail::get_element_or_null_type<1, SigArgs>::type type;
};
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return b; }
};
template<> struct placeholder<THIRD> {
template<class SigArgs> struct sig {
typedef typename detail::get_element_or_null_type<2, SigArgs>::type type;
};
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return c; }
};
template<> struct placeholder<EXCEPTION> {
template<class SigArgs> struct sig {
typedef typename detail::get_element_or_null_type<3, SigArgs>::type type;
};
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return env; }
};
typedef const lambda_functor<placeholder<FIRST> > placeholder1_type;
typedef const lambda_functor<placeholder<SECOND> > placeholder2_type;
typedef const lambda_functor<placeholder<THIRD> > placeholder3_type;
///////////////////////////////////////////////////////////////////////////////
// free variables are lambda_functors. This is to allow uniform handling with
// other lambda_functors.
// -------------------------------------------------------------------
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
// -- lambda_functor NONE ------------------------------------------------
template <class T>
class lambda_functor : public T
{
BOOST_STATIC_CONSTANT(int, arity_bits = get_arity<T>::value);
public:
typedef T inherited;
lambda_functor() {}
lambda_functor(const lambda_functor& l) : inherited(l) {}
lambda_functor(const T& t) : inherited(t) {}
template <class SigArgs> struct sig {
typedef typename inherited::template
sig<typename SigArgs::tail_type>::type type;
};
// Note that this return type deduction template is instantiated, even
// if the nullary
// operator() is not called at all. One must make sure that it does not fail.
typedef typename
inherited::template sig<null_type>::type
nullary_return_type;
// Support for boost::result_of.
template <class Sig> struct result;
template <class F>
struct result<F()> {
typedef nullary_return_type type;
};
template <class F, class A>
struct result<F(A)> {
typedef typename sig<tuple<F, A> >::type type;
};
template <class F, class A, class B>
struct result<F(A, B)> {
typedef typename sig<tuple<F, A, B> >::type type;
};
template <class F, class A, class B, class C>
struct result<F(A, B, C)> {
typedef typename sig<tuple<F, A, B, C> >::type type;
};
nullary_return_type operator()() const {
return inherited::template
call<nullary_return_type>
(cnull_type(), cnull_type(), cnull_type(), cnull_type());
}
template<class A>
typename inherited::template sig<tuple<A&> >::type
operator()(A& a) const {
return inherited::template call<
typename inherited::template sig<tuple<A&> >::type
>(a, cnull_type(), cnull_type(), cnull_type());
}
template<class A>
BOOST_LAMBDA_DISABLE_IF_ARRAY1(A, inherited::template sig<tuple<A const&> >)
operator()(A const& a) const {
return inherited::template call<
typename inherited::template sig<tuple<A const&> >::type
>(a, cnull_type(), cnull_type(), cnull_type());
}
template<class A, class B>
typename inherited::template sig<tuple<A&, B&> >::type
operator()(A& a, B& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A&, B&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B>
BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A const&, B&> >)
operator()(A const& a, B& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A const&, B&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B>
BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A&, B const&> >)
operator()(A& a, B const& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A&, B const&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B>
BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A const&, B const&> >)
operator()(A const& a, B const& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A const&, B const&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B, class C>
typename inherited::template sig<tuple<A&, B&, C&> >::type
operator()(A& a, B& b, C& c) const
{
return inherited::template call<
typename inherited::template sig<tuple<A&, B&, C&> >::type
>(a, b, c, cnull_type());
}
template<class A, class B, class C>
BOOST_LAMBDA_DISABLE_IF_ARRAY3(A, B, C, inherited::template sig<tuple<A const&, B const&, C const&> >)
operator()(A const& a, B const& b, C const& c) const
{
return inherited::template call<
typename inherited::template sig<tuple<A const&, B const&, C const&> >::type
>(a, b, c, cnull_type());
}
// for internal calls with env
template<CALL_TEMPLATE_ARGS>
typename inherited::template sig<tuple<CALL_REFERENCE_TYPES> >::type
internal_call(CALL_FORMAL_ARGS) const {
return inherited::template
call<typename inherited::template
sig<tuple<CALL_REFERENCE_TYPES> >::type>(CALL_ACTUAL_ARGS);
}
template<class A>
const lambda_functor<lambda_functor_base<
other_action<assignment_action>,
boost::tuple<lambda_functor,
typename const_copy_argument <const A>::type> > >
operator=(const A& a) const {
return lambda_functor_base<
other_action<assignment_action>,
boost::tuple<lambda_functor,
typename const_copy_argument <const A>::type> >
( boost::tuple<lambda_functor,
typename const_copy_argument <const A>::type>(*this, a) );
}
template<class A>
const lambda_functor<lambda_functor_base<
other_action<subscript_action>,
boost::tuple<lambda_functor,
typename const_copy_argument <const A>::type> > >
operator[](const A& a) const {
return lambda_functor_base<
other_action<subscript_action>,
boost::tuple<lambda_functor,
typename const_copy_argument <const A>::type> >
( boost::tuple<lambda_functor,
typename const_copy_argument <const A>::type>(*this, a ) );
}
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
} // namespace lambda
} // namespace boost
namespace boost {
#if !defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_NO_CXX11_DECLTYPE)
template<class T>
struct result_of<boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
template<class T>
struct result_of<const boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
#endif
template<class T>
struct tr1_result_of<boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
template<class T>
struct tr1_result_of<const boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
}
// is_placeholder
#include <boost/is_placeholder.hpp>
namespace boost
{
template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::FIRST> > >
{
enum _vt { value = 1 };
};
template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::SECOND> > >
{
enum _vt { value = 2 };
};
template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::THIRD> > >
{
enum _vt { value = 3 };
};
} // namespace boost
#endif

View File

@@ -0,0 +1,74 @@
// lambda_fwd.hpp - Boost Lambda Library -------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// -------------------------------------------------------
#ifndef BOOST_LAMBDA_FWD_HPP
#define BOOST_LAMBDA_FWD_HPP
namespace boost {
namespace lambda {
namespace detail {
template<class T> struct generate_error;
}
// -- placeholders --------------------------------------------
template <int I> struct placeholder;
// function_adaptors
template <class Func>
struct function_adaptor;
template <int I, class Act> class action;
template <class Base>
class lambda_functor;
template <class Act, class Args>
class lambda_functor_base;
} // namespace lambda
} // namespace boost
// #define CALL_TEMPLATE_ARGS class A, class Env
// #define CALL_FORMAL_ARGS A& a, Env& env
// #define CALL_ACTUAL_ARGS a, env
// #define CALL_ACTUAL_ARGS_NO_ENV a
// #define CALL_REFERENCE_TYPES A&, Env&
// #define CALL_PLAIN_TYPES A, Env
#define CALL_TEMPLATE_ARGS class A, class B, class C, class Env
#define CALL_FORMAL_ARGS A& a, B& b, C& c, Env& env
#define CALL_ACTUAL_ARGS a, b, c, env
#define CALL_ACTUAL_ARGS_NO_ENV a, b, c
#define CALL_REFERENCE_TYPES A&, B&, C&, Env&
#define CALL_PLAIN_TYPES A, B, C, Env
namespace boost {
namespace lambda {
namespace detail {
template<class A1, class A2, class A3, class A4>
void do_nothing(A1&, A2&, A3&, A4&) {}
} // detail
} // lambda
} // boost
// prevent the warnings from unused arguments
#define CALL_USE_ARGS \
::boost::lambda::detail::do_nothing(a, b, c, env)
#endif

View File

@@ -0,0 +1,583 @@
// - lambda_traits.hpp --- Boost Lambda Library ----------------------------
//
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// -------------------------------------------------------------------------
#ifndef BOOST_LAMBDA_LAMBDA_TRAITS_HPP
#define BOOST_LAMBDA_LAMBDA_TRAITS_HPP
#include "boost/type_traits/transform_traits.hpp"
#include "boost/type_traits/cv_traits.hpp"
#include "boost/type_traits/function_traits.hpp"
#include "boost/type_traits/object_traits.hpp"
#include "boost/tuple/tuple.hpp"
namespace boost {
namespace lambda {
// -- if construct ------------------------------------------------
// Proposed by Krzysztof Czarnecki and Ulrich Eisenecker
namespace detail {
template <bool If, class Then, class Else> struct IF { typedef Then RET; };
template <class Then, class Else> struct IF<false, Then, Else> {
typedef Else RET;
};
// An if construct that doesn't instantiate the non-matching template:
// Called as:
// IF_type<condition, A, B>::type
// The matching template must define the typeded 'type'
// I.e. A::type if condition is true, B::type if condition is false
// Idea from Vesa Karvonen (from C&E as well I guess)
template<class T>
struct IF_type_
{
typedef typename T::type type;
};
template<bool C, class T, class E>
struct IF_type
{
typedef typename
IF_type_<typename IF<C, T, E>::RET >::type type;
};
// helper that can be used to give typedef T to some type
template <class T> struct identity_mapping { typedef T type; };
// An if construct for finding an integral constant 'value'
// Does not instantiate the non-matching branch
// Called as IF_value<condition, A, B>::value
// If condition is true A::value must be defined, otherwise B::value
template<class T>
struct IF_value_
{
BOOST_STATIC_CONSTANT(int, value = T::value);
};
template<bool C, class T, class E>
struct IF_value
{
BOOST_STATIC_CONSTANT(int, value = (IF_value_<typename IF<C, T, E>::RET>::value));
};
// --------------------------------------------------------------
// removes reference from other than function types:
template<class T> class remove_reference_if_valid
{
typedef typename boost::remove_reference<T>::type plainT;
public:
typedef typename IF<
boost::is_function<plainT>::value,
T,
plainT
>::RET type;
};
template<class T> struct remove_reference_and_cv {
typedef typename boost::remove_cv<
typename boost::remove_reference<T>::type
>::type type;
};
// returns a reference to the element of tuple T
template<int N, class T> struct tuple_element_as_reference {
typedef typename
boost::tuples::access_traits<
typename boost::tuples::element<N, T>::type
>::non_const_type type;
};
// returns the cv and reverence stripped type of a tuple element
template<int N, class T> struct tuple_element_stripped {
typedef typename
remove_reference_and_cv<
typename boost::tuples::element<N, T>::type
>::type type;
};
// is_lambda_functor -------------------------------------------------
template <class T> struct is_lambda_functor_ {
BOOST_STATIC_CONSTANT(bool, value = false);
};
template <class Arg> struct is_lambda_functor_<lambda_functor<Arg> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
} // end detail
template <class T> struct is_lambda_functor {
BOOST_STATIC_CONSTANT(bool,
value =
detail::is_lambda_functor_<
typename detail::remove_reference_and_cv<T>::type
>::value);
};
namespace detail {
// -- parameter_traits_ ---------------------------------------------
// An internal parameter type traits class that respects
// the reference_wrapper class.
// The conversions performed are:
// references -> compile_time_error
// T1 -> T2,
// reference_wrapper<T> -> T&
// const array -> ref to const array
// array -> ref to array
// function -> ref to function
// ------------------------------------------------------------------------
template<class T1, class T2>
struct parameter_traits_ {
typedef T2 type;
};
// Do not instantiate with reference types
template<class T, class Any> struct parameter_traits_<T&, Any> {
typedef typename
generate_error<T&>::
parameter_traits_class_instantiated_with_reference_type type;
};
// Arrays can't be stored as plain types; convert them to references
template<class T, int n, class Any> struct parameter_traits_<T[n], Any> {
typedef T (&type)[n];
};
template<class T, int n, class Any>
struct parameter_traits_<const T[n], Any> {
typedef const T (&type)[n];
};
template<class T, int n, class Any>
struct parameter_traits_<volatile T[n], Any> {
typedef volatile T (&type)[n];
};
template<class T, int n, class Any>
struct parameter_traits_<const volatile T[n], Any> {
typedef const volatile T (&type)[n];
};
template<class T, class Any>
struct parameter_traits_<boost::reference_wrapper<T>, Any >{
typedef T& type;
};
template<class T, class Any>
struct parameter_traits_<const boost::reference_wrapper<T>, Any >{
typedef T& type;
};
template<class T, class Any>
struct parameter_traits_<volatile boost::reference_wrapper<T>, Any >{
typedef T& type;
};
template<class T, class Any>
struct parameter_traits_<const volatile boost::reference_wrapper<T>, Any >{
typedef T& type;
};
template<class Any>
struct parameter_traits_<void, Any> {
typedef void type;
};
template<class Arg, class Any>
struct parameter_traits_<lambda_functor<Arg>, Any > {
typedef lambda_functor<Arg> type;
};
template<class Arg, class Any>
struct parameter_traits_<const lambda_functor<Arg>, Any > {
typedef lambda_functor<Arg> type;
};
// Are the volatile versions needed?
template<class Arg, class Any>
struct parameter_traits_<volatile lambda_functor<Arg>, Any > {
typedef lambda_functor<Arg> type;
};
template<class Arg, class Any>
struct parameter_traits_<const volatile lambda_functor<Arg>, Any > {
typedef lambda_functor<Arg> type;
};
} // end namespace detail
// ------------------------------------------------------------------------
// traits classes for lambda expressions (bind functions, operators ...)
// must be instantiated with non-reference types
// The default is const plain type -------------------------
// const T -> const T,
// T -> const T,
// references -> compile_time_error
// reference_wrapper<T> -> T&
// array -> const ref array
template<class T>
struct const_copy_argument {
typedef typename
detail::parameter_traits_<
T,
typename detail::IF<boost::is_function<T>::value, T&, const T>::RET
>::type type;
};
// T may be a function type. Without the IF test, const would be added
// to a function type, which is illegal.
// all arrays are converted to const.
// This traits template is used for 'const T&' parameter passing
// and thus the knowledge of the potential
// non-constness of an actual argument is lost.
template<class T, int n> struct const_copy_argument <T[n]> {
typedef const T (&type)[n];
};
template<class T, int n> struct const_copy_argument <volatile T[n]> {
typedef const volatile T (&type)[n];
};
template<class T>
struct const_copy_argument<T&> {};
// do not instantiate with references
// typedef typename detail::generate_error<T&>::references_not_allowed type;
template<>
struct const_copy_argument<void> {
typedef void type;
};
template<>
struct const_copy_argument<void const> {
typedef void type;
};
// Does the same as const_copy_argument, but passes references through as such
template<class T>
struct bound_argument_conversion {
typedef typename const_copy_argument<T>::type type;
};
template<class T>
struct bound_argument_conversion<T&> {
typedef T& type;
};
// The default is non-const reference -------------------------
// const T -> const T&,
// T -> T&,
// references -> compile_time_error
// reference_wrapper<T> -> T&
template<class T>
struct reference_argument {
typedef typename detail::parameter_traits_<T, T&>::type type;
};
template<class T>
struct reference_argument<T&> {
typedef typename detail::generate_error<T&>::references_not_allowed type;
};
template<class Arg>
struct reference_argument<lambda_functor<Arg> > {
typedef lambda_functor<Arg> type;
};
template<class Arg>
struct reference_argument<const lambda_functor<Arg> > {
typedef lambda_functor<Arg> type;
};
// Are the volatile versions needed?
template<class Arg>
struct reference_argument<volatile lambda_functor<Arg> > {
typedef lambda_functor<Arg> type;
};
template<class Arg>
struct reference_argument<const volatile lambda_functor<Arg> > {
typedef lambda_functor<Arg> type;
};
template<>
struct reference_argument<void> {
typedef void type;
};
namespace detail {
// Array to pointer conversion
template <class T>
struct array_to_pointer {
typedef T type;
};
template <class T, int N>
struct array_to_pointer <const T[N]> {
typedef const T* type;
};
template <class T, int N>
struct array_to_pointer <T[N]> {
typedef T* type;
};
template <class T, int N>
struct array_to_pointer <const T (&) [N]> {
typedef const T* type;
};
template <class T, int N>
struct array_to_pointer <T (&) [N]> {
typedef T* type;
};
// ---------------------------------------------------------------------------
// The call_traits for bind
// Respects the reference_wrapper class.
// These templates are used outside of bind functions as well.
// the bind_tuple_mapper provides a shorter notation for default
// bound argument storing semantics, if all arguments are treated
// uniformly.
// from template<class T> foo(const T& t) : bind_traits<const T>::type
// from template<class T> foo(T& t) : bind_traits<T>::type
// Conversions:
// T -> const T,
// cv T -> cv T,
// T& -> T&
// reference_wrapper<T> -> T&
// const reference_wrapper<T> -> T&
// array -> const ref array
// make bound arguments const, this is a deliberate design choice, the
// purpose is to prevent side effects to bound arguments that are stored
// as copies
template<class T>
struct bind_traits {
typedef const T type;
};
template<class T>
struct bind_traits<T&> {
typedef T& type;
};
// null_types are an exception, we always want to store them as non const
// so that other templates can assume that null_type is always without const
template<>
struct bind_traits<null_type> {
typedef null_type type;
};
// the bind_tuple_mapper, bind_type_generators may
// introduce const to null_type
template<>
struct bind_traits<const null_type> {
typedef null_type type;
};
// Arrays can't be stored as plain types; convert them to references.
// All arrays are converted to const. This is because bind takes its
// parameters as const T& and thus the knowledge of the potential
// non-constness of actual argument is lost.
template<class T, int n> struct bind_traits <T[n]> {
typedef const T (&type)[n];
};
template<class T, int n>
struct bind_traits<const T[n]> {
typedef const T (&type)[n];
};
template<class T, int n> struct bind_traits<volatile T[n]> {
typedef const volatile T (&type)[n];
};
template<class T, int n>
struct bind_traits<const volatile T[n]> {
typedef const volatile T (&type)[n];
};
template<class R>
struct bind_traits<R()> {
typedef R(&type)();
};
template<class R, class Arg1>
struct bind_traits<R(Arg1)> {
typedef R(&type)(Arg1);
};
template<class R, class Arg1, class Arg2>
struct bind_traits<R(Arg1, Arg2)> {
typedef R(&type)(Arg1, Arg2);
};
template<class R, class Arg1, class Arg2, class Arg3>
struct bind_traits<R(Arg1, Arg2, Arg3)> {
typedef R(&type)(Arg1, Arg2, Arg3);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
};
template<class T>
struct bind_traits<reference_wrapper<T> >{
typedef T& type;
};
template<class T>
struct bind_traits<const reference_wrapper<T> >{
typedef T& type;
};
template<>
struct bind_traits<void> {
typedef void type;
};
template <
class T0 = null_type, class T1 = null_type, class T2 = null_type,
class T3 = null_type, class T4 = null_type, class T5 = null_type,
class T6 = null_type, class T7 = null_type, class T8 = null_type,
class T9 = null_type
>
struct bind_tuple_mapper {
typedef
tuple<typename bind_traits<T0>::type,
typename bind_traits<T1>::type,
typename bind_traits<T2>::type,
typename bind_traits<T3>::type,
typename bind_traits<T4>::type,
typename bind_traits<T5>::type,
typename bind_traits<T6>::type,
typename bind_traits<T7>::type,
typename bind_traits<T8>::type,
typename bind_traits<T9>::type> type;
};
// bind_traits, except map const T& -> const T
// this is needed e.g. in currying. Const reference arguments can
// refer to temporaries, so it is not safe to store them as references.
template <class T> struct remove_const_reference {
typedef typename bind_traits<T>::type type;
};
template <class T> struct remove_const_reference<const T&> {
typedef const T type;
};
// maps the bind argument types to the resulting lambda functor type
template <
class T0 = null_type, class T1 = null_type, class T2 = null_type,
class T3 = null_type, class T4 = null_type, class T5 = null_type,
class T6 = null_type, class T7 = null_type, class T8 = null_type,
class T9 = null_type
>
class bind_type_generator {
typedef typename
detail::bind_tuple_mapper<
T0, T1, T2, T3, T4, T5, T6, T7, T8, T9
>::type args_t;
BOOST_STATIC_CONSTANT(int, nof_elems = boost::tuples::length<args_t>::value);
typedef
action<
nof_elems,
function_action<nof_elems>
> action_type;
public:
typedef
lambda_functor<
lambda_functor_base<
action_type,
args_t
>
> type;
};
} // detail
template <class T> inline const T& make_const(const T& t) { return t; }
} // end of namespace lambda
} // end of namespace boost
#endif // BOOST_LAMBDA_TRAITS_HPP

View File

@@ -0,0 +1,737 @@
// Boost Lambda Library -- member_ptr.hpp ---------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// --------------------------------------------------------------------------
#if !defined(BOOST_LAMBDA_MEMBER_PTR_HPP)
#define BOOST_LAMBDA_MEMBER_PTR_HPP
namespace boost {
namespace lambda {
class member_pointer_action {};
namespace detail {
// the boost type_traits member_pointer traits are not enough,
// need to know more details.
template<class T>
struct member_pointer {
typedef typename boost::add_reference<T>::type type;
typedef detail::unspecified class_type;
typedef detail::unspecified qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};
template<class T, class U>
struct member_pointer<T U::*> {
typedef typename boost::add_reference<T>::type type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = true);
BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};
template<class T, class U>
struct member_pointer<const T U::*> {
typedef typename boost::add_reference<const T>::type type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = true);
BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};
template<class T, class U>
struct member_pointer<volatile T U::*> {
typedef typename boost::add_reference<volatile T>::type type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = true);
BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};
template<class T, class U>
struct member_pointer<const volatile T U::*> {
typedef typename boost::add_reference<const volatile T>::type type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = true);
BOOST_STATIC_CONSTANT(bool, is_function_member = false);
};
// -- nonconst member functions --
template<class T, class U>
struct member_pointer<T (U::*)()> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1>
struct member_pointer<T (U::*)(A1)> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2>
struct member_pointer<T (U::*)(A1, A2)> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3>
struct member_pointer<T (U::*)(A1, A2, A3)> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4>
struct member_pointer<T (U::*)(A1, A2, A3, A4)> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5)> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6)> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7)> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8)> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
typedef T type;
typedef U class_type;
typedef U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
// -- const member functions --
template<class T, class U>
struct member_pointer<T (U::*)() const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1>
struct member_pointer<T (U::*)(A1) const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2>
struct member_pointer<T (U::*)(A1, A2) const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3>
struct member_pointer<T (U::*)(A1, A2, A3) const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4>
struct member_pointer<T (U::*)(A1, A2, A3, A4) const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const> {
typedef T type;
typedef U class_type;
typedef const U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
// -- volatile --
template<class T, class U>
struct member_pointer<T (U::*)() volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1>
struct member_pointer<T (U::*)(A1) volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2>
struct member_pointer<T (U::*)(A1, A2) volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3>
struct member_pointer<T (U::*)(A1, A2, A3) volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4>
struct member_pointer<T (U::*)(A1, A2, A3, A4) volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) volatile> {
typedef T type;
typedef U class_type;
typedef volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
// -- const volatile
template<class T, class U>
struct member_pointer<T (U::*)() const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1>
struct member_pointer<T (U::*)(A1) const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2>
struct member_pointer<T (U::*)(A1, A2) const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3>
struct member_pointer<T (U::*)(A1, A2, A3) const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4>
struct member_pointer<T (U::*)(A1, A2, A3, A4) const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5) const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6) const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7) const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8) const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
template<class T, class U, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
struct member_pointer<T (U::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const volatile> {
typedef T type;
typedef U class_type;
typedef const volatile U qualified_class_type;
BOOST_STATIC_CONSTANT(bool, is_data_member = false);
BOOST_STATIC_CONSTANT(bool, is_function_member = true);
};
} // detail
namespace detail {
// this class holds a pointer to a member function and the object.
// when called, it just calls the member function with the parameters
// provided
// It would have been possible to use existing lambda_functors to represent
// a bound member function like this, but to have a separate template is
// safer, since now this functor doesn't mix and match with lambda_functors
// only thing you can do with this is to call it
// note that previously instantiated classes
// (other_action<member_pointer_action> and member_pointer_action_helper
// guarantee, that A and B are
// such types, that for objects a and b of corresponding types, a->*b leads
// to the builtin ->* to be called. So types that would end in a call to
// a user defined ->* do not create a member_pointer_caller object.
template<class RET, class A, class B>
class member_pointer_caller {
A a; B b;
public:
member_pointer_caller(const A& aa, const B& bb) : a(aa), b(bb) {}
RET operator()() const { return (a->*b)(); }
template<class A1>
RET operator()(const A1& a1) const { return (a->*b)(a1); }
template<class A1, class A2>
RET operator()(const A1& a1, const A2& a2) const { return (a->*b)(a1, a2); }
template<class A1, class A2, class A3>
RET operator()(const A1& a1, const A2& a2, const A3& a3) const {
return (a->*b)(a1, a2, a3);
}
template<class A1, class A2, class A3, class A4>
RET operator()(const A1& a1, const A2& a2, const A3& a3,
const A4& a4) const {
return (a->*b)(a1, a2, a3, a4);
}
template<class A1, class A2, class A3, class A4, class A5>
RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5) const {
return (a->*b)(a1, a2, a3, a4, a5);
}
template<class A1, class A2, class A3, class A4, class A5, class A6>
RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6) const {
return (a->*b)(a1, a2, a3, a4, a5, a6);
}
template<class A1, class A2, class A3, class A4, class A5, class A6,
class A7>
RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7) const {
return (a->*b)(a1, a2, a3, a4, a5, a6, a7);
}
template<class A1, class A2, class A3, class A4, class A5, class A6,
class A7, class A8>
RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7,
const A8& a8) const {
return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8);
}
template<class A1, class A2, class A3, class A4, class A5, class A6,
class A7, class A8, class A9>
RET operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
const A5& a5, const A6& a6, const A7& a7,
const A8& a8, const A9& a9) const {
return (a->*b)(a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
};
// helper templates for return type deduction and action classes
// different cases for data member, function member, neither
// true-true case
template <bool Is_data_member, bool Is_function_member>
struct member_pointer_action_helper;
// cannot be both, no body provided
// data member case
// this means, that B is a data member and A is a pointer type,
// so either built-in ->* should be called, or there is an error
template <>
struct member_pointer_action_helper<true, false> {
public:
template<class RET, class A, class B>
static RET apply(A& a, B& b) {
return a->*b;
}
template<class A, class B>
struct return_type {
private:
typedef typename detail::remove_reference_and_cv<B>::type plainB;
typedef typename detail::member_pointer<plainB>::type type0;
// we remove the reference now, as we may have to add cv:s
typedef typename boost::remove_reference<type0>::type type1;
// A is a reference to pointer
// remove the top level cv qualifiers and reference
typedef typename
detail::remove_reference_and_cv<A>::type non_ref_A;
// A is a pointer type, so take the type pointed to
typedef typename ::boost::remove_pointer<non_ref_A>::type non_pointer_A;
public:
// For non-reference types, we must add const and/or volatile if
// the pointer type has these qualifiers
// If the member is a reference, these do not have any effect
// (cv T == T if T is a reference type)
typedef typename detail::IF<
::boost::is_const<non_pointer_A>::value,
typename ::boost::add_const<type1>::type,
type1
>::RET type2;
typedef typename detail::IF<
::boost::is_volatile<non_pointer_A>::value,
typename ::boost::add_volatile<type2>::type,
type2
>::RET type3;
// add reference back
typedef typename ::boost::add_reference<type3>::type type;
};
};
// neither case
template <>
struct member_pointer_action_helper<false, false> {
public:
template<class RET, class A, class B>
static RET apply(A& a, B& b) {
// not a built in member pointer operator, just call ->*
return a->*b;
}
// an overloaded member pointer operators, user should have specified
// the return type
// At this point we know that there is no matching specialization for
// return_type_2, so try return_type_2_plain
template<class A, class B>
struct return_type {
typedef typename plain_return_type_2<
other_action<member_pointer_action>, A, B
>::type type;
};
};
// member pointer function case
// This is a built in ->* call for a member function,
// the only thing that you can do with that, is to give it some arguments
// note, it is guaranteed that A is a pointer type, and thus it cannot
// be a call to overloaded ->*
template <>
struct member_pointer_action_helper<false, true> {
public:
template<class RET, class A, class B>
static RET apply(A& a, B& b) {
typedef typename ::boost::remove_cv<B>::type plainB;
typedef typename detail::member_pointer<plainB>::type ret_t;
typedef typename ::boost::remove_cv<A>::type plainA;
// we always strip cv:s to
// make the two routes (calling and type deduction)
// to give the same results (and the const does not make any functional
// difference)
return detail::member_pointer_caller<ret_t, plainA, plainB>(a, b);
}
template<class A, class B>
struct return_type {
typedef typename detail::remove_reference_and_cv<B>::type plainB;
typedef typename detail::member_pointer<plainB>::type ret_t;
typedef typename detail::remove_reference_and_cv<A>::type plainA;
typedef detail::member_pointer_caller<ret_t, plainA, plainB> type;
};
};
} // detail
template<> class other_action<member_pointer_action> {
public:
template<class RET, class A, class B>
static RET apply(A& a, B& b) {
typedef typename
::boost::remove_cv<B>::type plainB;
return detail::member_pointer_action_helper<
boost::is_pointer<A>::value &&
detail::member_pointer<plainB>::is_data_member,
boost::is_pointer<A>::value &&
detail::member_pointer<plainB>::is_function_member
>::template apply<RET>(a, b);
}
};
// return type deduction --
// If the right argument is a pointer to data member,
// and the left argument is of compatible pointer to class type
// return type is a reference to the data member type
// if right argument is a pointer to a member function, and the left
// argument is of a compatible type, the return type is a
// member_pointer_caller (see above)
// Otherwise, return type deduction fails. There is either an error,
// or the user is trying to call an overloaded ->*
// In such a case either ret<> must be used, or a return_type_2 user
// defined specialization must be provided
template<class A, class B>
struct return_type_2<other_action<member_pointer_action>, A, B> {
private:
typedef typename
detail::remove_reference_and_cv<B>::type plainB;
public:
typedef typename
detail::member_pointer_action_helper<
detail::member_pointer<plainB>::is_data_member,
detail::member_pointer<plainB>::is_function_member
>::template return_type<A, B>::type type;
};
// this is the way the generic lambda_functor_base functions instantiate
// return type deduction. We turn it into return_type_2, so that the
// user can provide specializations on that level.
template<class Args>
struct return_type_N<other_action<member_pointer_action>, Args> {
typedef typename boost::tuples::element<0, Args>::type A;
typedef typename boost::tuples::element<1, Args>::type B;
typedef typename
return_type_2<other_action<member_pointer_action>,
typename boost::remove_reference<A>::type,
typename boost::remove_reference<B>::type
>::type type;
};
template<class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
action<2, other_action<member_pointer_action> >,
tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
>
>
operator->*(const lambda_functor<Arg1>& a1, const Arg2& a2)
{
return
lambda_functor_base<
action<2, other_action<member_pointer_action> >,
tuple<lambda_functor<Arg1>, typename const_copy_argument<Arg2>::type>
>
(tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type>(a1, a2));
}
template<class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
action<2, other_action<member_pointer_action> >,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
operator->*(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2)
{
return
lambda_functor_base<
action<2, other_action<member_pointer_action> >,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
(tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
}
template<class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
action<2, other_action<member_pointer_action> >,
tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
>
>
operator->*(const Arg1& a1, const lambda_functor<Arg2>& a2)
{
return
lambda_functor_base<
action<2, other_action<member_pointer_action> >,
tuple<typename const_copy_argument<Arg1>::type, lambda_functor<Arg2> >
>
(tuple<typename const_copy_argument<Arg1>::type,
lambda_functor<Arg2> >(a1, a2));
}
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,139 @@
// -- operator_actions.hpp - Boost Lambda Library ----------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://lambda.cs.utu.fi
#ifndef BOOST_LAMBDA_OPERATOR_ACTIONS_HPP
#define BOOST_LAMBDA_OPERATOR_ACTIONS_HPP
namespace boost {
namespace lambda {
// -- artihmetic ----------------------
class plus_action {};
class minus_action {};
class multiply_action {};
class divide_action {};
class remainder_action {};
// -- bitwise -------------------
class leftshift_action {};
class rightshift_action {};
class xor_action {};
// -- bitwise/logical -------------------
class and_action {};
class or_action {};
class not_action {};
// -- relational -------------------------
class less_action {};
class greater_action {};
class lessorequal_action {};
class greaterorequal_action {};
class equal_action {};
class notequal_action {};
// -- increment/decrement ------------------------------
class increment_action {};
class decrement_action {};
// -- void return ------------------------------
// -- other ------------------------------
class addressof_action {};
// class comma_action {}; // defined in actions.hpp
class contentsof_action {};
// class member_pointer_action {}; (defined in member_ptr.hpp)
// -- actioun group templates --------------------
template <class Action> class arithmetic_action;
template <class Action> class bitwise_action;
template <class Action> class logical_action;
template <class Action> class relational_action;
template <class Action> class arithmetic_assignment_action;
template <class Action> class bitwise_assignment_action;
template <class Action> class unary_arithmetic_action;
template <class Action> class pre_increment_decrement_action;
template <class Action> class post_increment_decrement_action;
// ---------------------------------------------------------
// actions, for which the existence of protect is checked in return type
// deduction.
template <class Act> struct is_protectable<arithmetic_action<Act> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<bitwise_action<Act> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<logical_action<Act> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<relational_action<Act> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act>
struct is_protectable<arithmetic_assignment_action<Act> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<bitwise_assignment_action<Act> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct is_protectable<unary_arithmetic_action<Act> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act>
struct is_protectable<pre_increment_decrement_action<Act> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Act> struct
is_protectable<post_increment_decrement_action<Act> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <> struct is_protectable<other_action<addressof_action> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <> struct is_protectable<other_action<contentsof_action> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<> struct is_protectable<other_action<subscript_action> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<> struct is_protectable<other_action<assignment_action> > {
BOOST_STATIC_CONSTANT(bool, value = true);
};
// NOTE: comma action is also protectable, but the specialization is
// in actions.hpp
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,271 @@
// Boost Lambda Library - operator_lambda_func_base.hpp -----------------
//
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ------------------------------------------------------------
#ifndef BOOST_LAMBDA_OPERATOR_LAMBDA_FUNC_BASE_HPP
#define BOOST_LAMBDA_OPERATOR_LAMBDA_FUNC_BASE_HPP
namespace boost {
namespace lambda {
// These operators cannot be implemented as apply functions of action
// templates
// Specialization for comma.
template<class Args>
class lambda_functor_base<other_action<comma_action>, Args> {
public:
Args args;
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS),
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
template<class SigArgs> struct sig {
private:
typedef typename
detail::deduce_argument_types<Args, SigArgs>::type rets_t;
public:
typedef typename return_type_2_comma< // comma needs special handling
typename detail::element_or_null<0, rets_t>::type,
typename detail::element_or_null<1, rets_t>::type
>::type type;
};
};
namespace detail {
// helper traits to make the expression shorter, takes binary action
// bound argument tuple, open argument tuple and gives the return type
template<class Action, class Bound, class Open> class binary_rt {
private:
typedef typename
detail::deduce_argument_types<Bound, Open>::type rets_t;
public:
typedef typename return_type_2_prot<
Action,
typename detail::element_or_null<0, rets_t>::type,
typename detail::element_or_null<1, rets_t>::type
>::type type;
};
// same for unary actions
template<class Action, class Bound, class Open> class unary_rt {
private:
typedef typename
detail::deduce_argument_types<Bound, Open>::type rets_t;
public:
typedef typename return_type_1_prot<
Action,
typename detail::element_or_null<0, rets_t>::type
>::type type;
};
} // end detail
// Specialization for logical and (to preserve shortcircuiting)
// this could be done with a macro as the others, code used to be different
template<class Args>
class lambda_functor_base<logical_action<and_action>, Args> {
public:
Args args;
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) &&
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
template<class SigArgs> struct sig {
typedef typename
detail::binary_rt<logical_action<and_action>, Args, SigArgs>::type type;
};
};
// Specialization for logical or (to preserve shortcircuiting)
// this could be done with a macro as the others, code used to be different
template<class Args>
class lambda_functor_base<logical_action< or_action>, Args> {
public:
Args args;
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ||
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
template<class SigArgs> struct sig {
typedef typename
detail::binary_rt<logical_action<or_action>, Args, SigArgs>::type type;
};
};
// Specialization for subscript
template<class Args>
class lambda_functor_base<other_action<subscript_action>, Args> {
public:
Args args;
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)
[detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS)];
}
template<class SigArgs> struct sig {
typedef typename
detail::binary_rt<other_action<subscript_action>, Args, SigArgs>::type
type;
};
};
#define BOOST_LAMBDA_BINARY_ACTION(SYMBOL, ACTION_CLASS) \
template<class Args> \
class lambda_functor_base<ACTION_CLASS, Args> { \
public: \
Args args; \
public: \
explicit lambda_functor_base(const Args& a) : args(a) {} \
\
template<class RET, CALL_TEMPLATE_ARGS> \
RET call(CALL_FORMAL_ARGS) const { \
return detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) \
SYMBOL \
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); \
} \
template<class SigArgs> struct sig { \
typedef typename \
detail::binary_rt<ACTION_CLASS, Args, SigArgs>::type type; \
}; \
};
#define BOOST_LAMBDA_PREFIX_UNARY_ACTION(SYMBOL, ACTION_CLASS) \
template<class Args> \
class lambda_functor_base<ACTION_CLASS, Args> { \
public: \
Args args; \
public: \
explicit lambda_functor_base(const Args& a) : args(a) {} \
\
template<class RET, CALL_TEMPLATE_ARGS> \
RET call(CALL_FORMAL_ARGS) const { \
return SYMBOL \
detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS); \
} \
template<class SigArgs> struct sig { \
typedef typename \
detail::unary_rt<ACTION_CLASS, Args, SigArgs>::type type; \
}; \
};
#define BOOST_LAMBDA_POSTFIX_UNARY_ACTION(SYMBOL, ACTION_CLASS) \
template<class Args> \
class lambda_functor_base<ACTION_CLASS, Args> { \
public: \
Args args; \
public: \
explicit lambda_functor_base(const Args& a) : args(a) {} \
\
template<class RET, CALL_TEMPLATE_ARGS> \
RET call(CALL_FORMAL_ARGS) const { \
return \
detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) SYMBOL; \
} \
template<class SigArgs> struct sig { \
typedef typename \
detail::unary_rt<ACTION_CLASS, Args, SigArgs>::type type; \
}; \
};
BOOST_LAMBDA_BINARY_ACTION(+,arithmetic_action<plus_action>)
BOOST_LAMBDA_BINARY_ACTION(-,arithmetic_action<minus_action>)
BOOST_LAMBDA_BINARY_ACTION(*,arithmetic_action<multiply_action>)
BOOST_LAMBDA_BINARY_ACTION(/,arithmetic_action<divide_action>)
BOOST_LAMBDA_BINARY_ACTION(%,arithmetic_action<remainder_action>)
BOOST_LAMBDA_BINARY_ACTION(<<,bitwise_action<leftshift_action>)
BOOST_LAMBDA_BINARY_ACTION(>>,bitwise_action<rightshift_action>)
BOOST_LAMBDA_BINARY_ACTION(&,bitwise_action<and_action>)
BOOST_LAMBDA_BINARY_ACTION(|,bitwise_action<or_action>)
BOOST_LAMBDA_BINARY_ACTION(^,bitwise_action<xor_action>)
BOOST_LAMBDA_BINARY_ACTION(<,relational_action<less_action>)
BOOST_LAMBDA_BINARY_ACTION(>,relational_action<greater_action>)
BOOST_LAMBDA_BINARY_ACTION(<=,relational_action<lessorequal_action>)
BOOST_LAMBDA_BINARY_ACTION(>=,relational_action<greaterorequal_action>)
BOOST_LAMBDA_BINARY_ACTION(==,relational_action<equal_action>)
BOOST_LAMBDA_BINARY_ACTION(!=,relational_action<notequal_action>)
BOOST_LAMBDA_BINARY_ACTION(+=,arithmetic_assignment_action<plus_action>)
BOOST_LAMBDA_BINARY_ACTION(-=,arithmetic_assignment_action<minus_action>)
BOOST_LAMBDA_BINARY_ACTION(*=,arithmetic_assignment_action<multiply_action>)
BOOST_LAMBDA_BINARY_ACTION(/=,arithmetic_assignment_action<divide_action>)
BOOST_LAMBDA_BINARY_ACTION(%=,arithmetic_assignment_action<remainder_action>)
BOOST_LAMBDA_BINARY_ACTION(<<=,bitwise_assignment_action<leftshift_action>)
BOOST_LAMBDA_BINARY_ACTION(>>=,bitwise_assignment_action<rightshift_action>)
BOOST_LAMBDA_BINARY_ACTION(&=,bitwise_assignment_action<and_action>)
BOOST_LAMBDA_BINARY_ACTION(|=,bitwise_assignment_action<or_action>)
BOOST_LAMBDA_BINARY_ACTION(^=,bitwise_assignment_action<xor_action>)
BOOST_LAMBDA_BINARY_ACTION(=,other_action< assignment_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(+, unary_arithmetic_action<plus_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(-, unary_arithmetic_action<minus_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(~, bitwise_action<not_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(!, logical_action<not_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(++, pre_increment_decrement_action<increment_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(--, pre_increment_decrement_action<decrement_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(&,other_action<addressof_action>)
BOOST_LAMBDA_PREFIX_UNARY_ACTION(*,other_action<contentsof_action>)
BOOST_LAMBDA_POSTFIX_UNARY_ACTION(++, post_increment_decrement_action<increment_action>)
BOOST_LAMBDA_POSTFIX_UNARY_ACTION(--, post_increment_decrement_action<decrement_action>)
#undef BOOST_LAMBDA_POSTFIX_UNARY_ACTION
#undef BOOST_LAMBDA_PREFIX_UNARY_ACTION
#undef BOOST_LAMBDA_BINARY_ACTION
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,892 @@
// operator_return_type_traits.hpp -- Boost Lambda Library ------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
#ifndef BOOST_LAMBDA_OPERATOR_RETURN_TYPE_TRAITS_HPP
#define BOOST_LAMBDA_OPERATOR_RETURN_TYPE_TRAITS_HPP
#include "boost/lambda/detail/is_instance_of.hpp"
#include "boost/type_traits/is_same.hpp"
#include "boost/type_traits/is_pointer.hpp"
#include "boost/type_traits/is_float.hpp"
#include "boost/type_traits/is_convertible.hpp"
#include "boost/type_traits/remove_pointer.hpp"
#include "boost/type_traits/remove_const.hpp"
#include "boost/type_traits/remove_reference.hpp"
#include "boost/indirect_reference.hpp"
#include "boost/detail/container_fwd.hpp"
#include <cstddef> // needed for the ptrdiff_t
#include <iosfwd> // for istream and ostream
#include <iterator> // needed for operator&
namespace boost {
namespace lambda {
namespace detail {
// -- general helper templates for type deduction ------------------
// Much of the type deduction code for standard arithmetic types from Gary Powell
template <class A> struct promote_code { static const int value = -1; };
// this means that a code is not defined for A
// -- the next 5 types are needed in if_then_else_return
// the promotion order is not important, but they must have distinct values.
template <> struct promote_code<bool> { static const int value = 10; };
template <> struct promote_code<char> { static const int value = 20; };
template <> struct promote_code<unsigned char> { static const int value = 30; };
template <> struct promote_code<signed char> { static const int value = 40; };
template <> struct promote_code<short int> { static const int value = 50; };
// ----------
template <> struct promote_code<int> { static const int value = 100; };
template <> struct promote_code<unsigned int> { static const int value = 200; };
template <> struct promote_code<long> { static const int value = 300; };
template <> struct promote_code<unsigned long> { static const int value = 400; };
template <> struct promote_code<float> { static const int value = 500; };
template <> struct promote_code<double> { static const int value = 600; };
template <> struct promote_code<long double> { static const int value = 700; };
// TODO: wchar_t
// forward delcaration of complex.
} // namespace detail
} // namespace lambda
} // namespace boost
namespace boost {
namespace lambda {
namespace detail {
template <> struct promote_code< std::complex<float> > { static const int value = 800; };
template <> struct promote_code< std::complex<double> > { static const int value = 900; };
template <> struct promote_code< std::complex<long double> > { static const int value = 1000; };
// -- int promotion -------------------------------------------
template <class T> struct promote_to_int { typedef T type; };
template <> struct promote_to_int<bool> { typedef int type; };
template <> struct promote_to_int<char> { typedef int type; };
template <> struct promote_to_int<unsigned char> { typedef int type; };
template <> struct promote_to_int<signed char> { typedef int type; };
template <> struct promote_to_int<short int> { typedef int type; };
// The unsigned short int promotion rule is this:
// unsigned short int to signed int if a signed int can hold all values
// of unsigned short int, otherwise go to unsigned int.
template <> struct promote_to_int<unsigned short int>
{
typedef
detail::IF<sizeof(int) <= sizeof(unsigned short int),
// I had the logic reversed but ">" messes up the parsing.
unsigned int,
int>::RET type;
};
// TODO: think, should there be default behaviour for non-standard types?
} // namespace detail
// ------------------------------------------
// Unary actions ----------------------------
// ------------------------------------------
template<class Act, class A>
struct plain_return_type_1 {
typedef detail::unspecified type;
};
template<class Act, class A>
struct plain_return_type_1<unary_arithmetic_action<Act>, A> {
typedef A type;
};
template<class Act, class A>
struct return_type_1<unary_arithmetic_action<Act>, A> {
typedef
typename plain_return_type_1<
unary_arithmetic_action<Act>,
typename detail::remove_reference_and_cv<A>::type
>::type type;
};
template<class A>
struct plain_return_type_1<bitwise_action<not_action>, A> {
typedef A type;
};
// bitwise not, operator~()
template<class A> struct return_type_1<bitwise_action<not_action>, A> {
typedef
typename plain_return_type_1<
bitwise_action<not_action>,
typename detail::remove_reference_and_cv<A>::type
>::type type;
};
// prefix increment and decrement operators return
// their argument by default as a non-const reference
template<class Act, class A>
struct plain_return_type_1<pre_increment_decrement_action<Act>, A> {
typedef A& type;
};
template<class Act, class A>
struct return_type_1<pre_increment_decrement_action<Act>, A> {
typedef
typename plain_return_type_1<
pre_increment_decrement_action<Act>,
typename detail::remove_reference_and_cv<A>::type
>::type type;
};
// post decrement just returns the same plain type.
template<class Act, class A>
struct plain_return_type_1<post_increment_decrement_action<Act>, A> {
typedef A type;
};
template<class Act, class A>
struct return_type_1<post_increment_decrement_action<Act>, A>
{
typedef
typename plain_return_type_1<
post_increment_decrement_action<Act>,
typename detail::remove_reference_and_cv<A>::type
>::type type;
};
// logical not, operator!()
template<class A>
struct plain_return_type_1<logical_action<not_action>, A> {
typedef bool type;
};
template<class A>
struct return_type_1<logical_action<not_action>, A> {
typedef
typename plain_return_type_1<
logical_action<not_action>,
typename detail::remove_reference_and_cv<A>::type
>::type type;
};
// address of action ---------------------------------------
template<class A>
struct return_type_1<other_action<addressof_action>, A> {
typedef
typename plain_return_type_1<
other_action<addressof_action>,
typename detail::remove_reference_and_cv<A>::type
>::type type1;
// If no user defined specialization for A, then return the
// cv qualified pointer to A
typedef typename detail::IF<
boost::is_same<type1, detail::unspecified>::value,
typename boost::remove_reference<A>::type*,
type1
>::RET type;
};
// contentsof action ------------------------------------
// TODO: this deduction may lead to fail directly,
// (if A has no specialization for iterator_traits and has no
// typedef A::reference.
// There is no easy way around this, cause there doesn't seem to be a way
// to test whether a class is an iterator or not.
// The default works with std::iterators.
namespace detail {
// A is a nonreference type
template <class A> struct contentsof_type {
typedef typename boost::indirect_reference<A>::type type;
};
// this is since the nullary () in lambda_functor is always instantiated
template <> struct contentsof_type<null_type> {
typedef detail::unspecified type;
};
template <class A> struct contentsof_type<const A> {
typedef typename contentsof_type<A>::type type;
};
template <class A> struct contentsof_type<volatile A> {
typedef typename contentsof_type<A>::type type;
};
template <class A> struct contentsof_type<const volatile A> {
typedef typename contentsof_type<A>::type type;
};
// standard iterator traits should take care of the pointer types
// but just to be on the safe side, we have the specializations here:
// these work even if A is cv-qualified.
template <class A> struct contentsof_type<A*> {
typedef A& type;
};
template <class A> struct contentsof_type<A* const> {
typedef A& type;
};
template <class A> struct contentsof_type<A* volatile> {
typedef A& type;
};
template <class A> struct contentsof_type<A* const volatile> {
typedef A& type;
};
template<class A, int N> struct contentsof_type<A[N]> {
typedef A& type;
};
template<class A, int N> struct contentsof_type<const A[N]> {
typedef const A& type;
};
template<class A, int N> struct contentsof_type<volatile A[N]> {
typedef volatile A& type;
};
template<class A, int N> struct contentsof_type<const volatile A[N]> {
typedef const volatile A& type;
};
} // end detail
template<class A>
struct return_type_1<other_action<contentsof_action>, A> {
typedef
typename plain_return_type_1<
other_action<contentsof_action>,
typename detail::remove_reference_and_cv<A>::type
>::type type1;
// If no user defined specialization for A, then return the
// cv qualified pointer to A
typedef typename
detail::IF_type<
boost::is_same<type1, detail::unspecified>::value,
detail::contentsof_type<
typename boost::remove_reference<A>::type
>,
detail::identity_mapping<type1>
>::type type;
};
// ------------------------------------------------------------------
// binary actions ---------------------------------------------------
// ------------------------------------------------------------------
// here the default case is: no user defined versions:
template <class Act, class A, class B>
struct plain_return_type_2 {
typedef detail::unspecified type;
};
namespace detail {
// error classes
class illegal_pointer_arithmetic{};
// pointer arithmetic type deductions ----------------------
// value = false means that this is not a pointer arithmetic case
// value = true means, that this can be a pointer arithmetic case, but not necessarily is
// This means, that for user defined operators for pointer types, say for some operator+(X, *Y),
// the deductions must be coded at an earliel level (return_type_2).
template<class Act, class A, class B>
struct pointer_arithmetic_traits { static const bool value = false; };
template<class A, class B>
struct pointer_arithmetic_traits<plus_action, A, B> {
typedef typename
array_to_pointer<typename boost::remove_reference<A>::type>::type AP;
typedef typename
array_to_pointer<typename boost::remove_reference<B>::type>::type BP;
static const bool is_pointer_A = boost::is_pointer<AP>::value;
static const bool is_pointer_B = boost::is_pointer<BP>::value;
static const bool value = is_pointer_A || is_pointer_B;
// can't add two pointers.
// note, that we do not check wether the other type is valid for
// addition with a pointer.
// the compiler will catch it in the apply function
typedef typename
detail::IF<
is_pointer_A && is_pointer_B,
detail::return_type_deduction_failure<
detail::illegal_pointer_arithmetic
>,
typename detail::IF<is_pointer_A, AP, BP>::RET
>::RET type;
};
template<class A, class B>
struct pointer_arithmetic_traits<minus_action, A, B> {
typedef typename
array_to_pointer<typename boost::remove_reference<A>::type>::type AP;
typedef typename
array_to_pointer<typename boost::remove_reference<B>::type>::type BP;
static const bool is_pointer_A = boost::is_pointer<AP>::value;
static const bool is_pointer_B = boost::is_pointer<BP>::value;
static const bool value = is_pointer_A || is_pointer_B;
static const bool same_pointer_type =
is_pointer_A && is_pointer_B &&
boost::is_same<
typename boost::remove_const<
typename boost::remove_pointer<
typename boost::remove_const<AP>::type
>::type
>::type,
typename boost::remove_const<
typename boost::remove_pointer<
typename boost::remove_const<BP>::type
>::type
>::type
>::value;
// ptr - ptr has type ptrdiff_t
// note, that we do not check if, in ptr - B, B is
// valid for subtraction with a pointer.
// the compiler will catch it in the apply function
typedef typename
detail::IF<
same_pointer_type, const std::ptrdiff_t,
typename detail::IF<
is_pointer_A,
AP,
detail::return_type_deduction_failure<detail::illegal_pointer_arithmetic>
>::RET
>::RET type;
};
} // namespace detail
// -- arithmetic actions ---------------------------------------------
namespace detail {
template<bool is_pointer_arithmetic, class Act, class A, class B>
struct return_type_2_arithmetic_phase_1;
template<class A, class B> struct return_type_2_arithmetic_phase_2;
template<class A, class B> struct return_type_2_arithmetic_phase_3;
} // namespace detail
// drop any qualifiers from the argument types within arithmetic_action
template<class A, class B, class Act>
struct return_type_2<arithmetic_action<Act>, A, B>
{
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<arithmetic_action<Act>, plain_A, plain_B>::type type1;
// if user defined return type, do not enter the whole arithmetic deductions
typedef typename
detail::IF_type<
boost::is_same<type1, detail::unspecified>::value,
detail::return_type_2_arithmetic_phase_1<
detail::pointer_arithmetic_traits<Act, A, B>::value, Act, A, B
>,
plain_return_type_2<arithmetic_action<Act>, plain_A, plain_B>
>::type type;
};
namespace detail {
// perform integral promotion, no pointer arithmetic
template<bool is_pointer_arithmetic, class Act, class A, class B>
struct return_type_2_arithmetic_phase_1
{
typedef typename
return_type_2_arithmetic_phase_2<
typename remove_reference_and_cv<A>::type,
typename remove_reference_and_cv<B>::type
>::type type;
};
// pointer_arithmetic
template<class Act, class A, class B>
struct return_type_2_arithmetic_phase_1<true, Act, A, B>
{
typedef typename
pointer_arithmetic_traits<Act, A, B>::type type;
};
template<class A, class B>
struct return_type_2_arithmetic_phase_2 {
typedef typename
return_type_2_arithmetic_phase_3<
typename promote_to_int<A>::type,
typename promote_to_int<B>::type
>::type type;
};
// specialization for unsigned int.
// We only have to do these two specialization because the value promotion will
// take care of the other cases.
// The unsigned int promotion rule is this:
// unsigned int to long if a long can hold all values of unsigned int,
// otherwise go to unsigned long.
// struct so I don't have to type this twice.
struct promotion_of_unsigned_int
{
typedef
detail::IF<sizeof(long) <= sizeof(unsigned int),
unsigned long,
long>::RET type;
};
template<>
struct return_type_2_arithmetic_phase_2<unsigned int, long>
{
typedef promotion_of_unsigned_int::type type;
};
template<>
struct return_type_2_arithmetic_phase_2<long, unsigned int>
{
typedef promotion_of_unsigned_int::type type;
};
template<class A, class B> struct return_type_2_arithmetic_phase_3 {
enum { promote_code_A_value = promote_code<A>::value,
promote_code_B_value = promote_code<B>::value }; // enums for KCC
typedef typename
detail::IF<
promote_code_A_value == -1 || promote_code_B_value == -1,
detail::return_type_deduction_failure<return_type_2_arithmetic_phase_3>,
typename detail::IF<
((int)promote_code_A_value > (int)promote_code_B_value),
A,
B
>::RET
>::RET type;
};
} // namespace detail
// -- bitwise actions -------------------------------------------
// note: for integral types deuduction is similar to arithmetic actions.
// drop any qualifiers from the argument types within arithmetic action
template<class A, class B, class Act>
struct return_type_2<bitwise_action<Act>, A, B>
{
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<bitwise_action<Act>, plain_A, plain_B>::type type1;
// if user defined return type, do not enter type deductions
typedef typename
detail::IF_type<
boost::is_same<type1, detail::unspecified>::value,
return_type_2<arithmetic_action<plus_action>, A, B>,
plain_return_type_2<bitwise_action<Act>, plain_A, plain_B>
>::type type;
// plus_action is just a random pick, has to be a concrete instance
// TODO: This check is only valid for built-in types, overloaded types might
// accept floating point operators
// bitwise operators not defined for floating point types
// these test are not strictly needed here, since the error will be caught in
// the apply function
BOOST_STATIC_ASSERT(!(boost::is_float<plain_A>::value && boost::is_float<plain_B>::value));
};
namespace detail {
template <class T> struct get_ostream_type {
typedef std::basic_ostream<typename T::char_type,
typename T::traits_type>& type;
};
template <class T> struct get_istream_type {
typedef std::basic_istream<typename T::char_type,
typename T::traits_type>& type;
};
template<class A, class B>
struct leftshift_type {
private:
typedef typename boost::remove_reference<A>::type plainA;
public:
typedef typename detail::IF_type<
is_instance_of_2<plainA, std::basic_ostream>::value,
get_ostream_type<plainA>, //reference to the stream
detail::remove_reference_and_cv<A>
>::type type;
};
template<class A, class B>
struct rightshift_type {
private:
typedef typename boost::remove_reference<A>::type plainA;
public:
typedef typename detail::IF_type<
is_instance_of_2<plainA, std::basic_istream>::value,
get_istream_type<plainA>, //reference to the stream
detail::remove_reference_and_cv<A>
>::type type;
};
} // end detail
// ostream
template<class A, class B>
struct return_type_2<bitwise_action<leftshift_action>, A, B>
{
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<bitwise_action<leftshift_action>, plain_A, plain_B>::type type1;
// if user defined return type, do not enter type deductions
typedef typename
detail::IF_type<
boost::is_same<type1, detail::unspecified>::value,
detail::leftshift_type<A, B>,
plain_return_type_2<bitwise_action<leftshift_action>, plain_A, plain_B>
>::type type;
};
// istream
template<class A, class B>
struct return_type_2<bitwise_action<rightshift_action>, A, B>
{
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<bitwise_action<rightshift_action>, plain_A, plain_B>::type type1;
// if user defined return type, do not enter type deductions
typedef typename
detail::IF_type<
boost::is_same<type1, detail::unspecified>::value,
detail::rightshift_type<A, B>,
plain_return_type_2<bitwise_action<rightshift_action>, plain_A, plain_B>
>::type type;
};
// -- logical actions ----------------------------------------
// always bool
// NOTE: this may not be true for some weird user-defined types,
template<class A, class B, class Act>
struct plain_return_type_2<logical_action<Act>, A, B> {
typedef bool type;
};
template<class A, class B, class Act>
struct return_type_2<logical_action<Act>, A, B> {
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<logical_action<Act>, plain_A, plain_B>::type type;
};
// -- relational actions ----------------------------------------
// always bool
// NOTE: this may not be true for some weird user-defined types,
template<class A, class B, class Act>
struct plain_return_type_2<relational_action<Act>, A, B> {
typedef bool type;
};
template<class A, class B, class Act>
struct return_type_2<relational_action<Act>, A, B> {
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<relational_action<Act>, plain_A, plain_B>::type type;
};
// Assingment actions -----------------------------------------------
// return type is the type of the first argument as reference
// note that cv-qualifiers are preserved.
// Yes, assignment operator can be const!
// NOTE: this may not be true for some weird user-defined types,
template<class A, class B, class Act>
struct return_type_2<arithmetic_assignment_action<Act>, A, B> {
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<
arithmetic_assignment_action<Act>, plain_A, plain_B
>::type type1;
typedef typename
detail::IF<
boost::is_same<type1, detail::unspecified>::value,
typename boost::add_reference<A>::type,
type1
>::RET type;
};
template<class A, class B, class Act>
struct return_type_2<bitwise_assignment_action<Act>, A, B> {
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<
bitwise_assignment_action<Act>, plain_A, plain_B
>::type type1;
typedef typename
detail::IF<
boost::is_same<type1, detail::unspecified>::value,
typename boost::add_reference<A>::type,
type1
>::RET type;
};
template<class A, class B>
struct return_type_2<other_action<assignment_action>, A, B> {
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<
other_action<assignment_action>, plain_A, plain_B
>::type type1;
typedef typename
detail::IF<
boost::is_same<type1, detail::unspecified>::value,
typename boost::add_reference<A>::type,
type1
>::RET type;
};
// -- other actions ----------------------------------------
// comma action ----------------------------------
// Note: this may not be true for some weird user-defined types,
// NOTE! This only tries the plain_return_type_2 layer and gives
// detail::unspecified as default. If no such specialization is found, the
// type rule in the spcecialization of the return_type_2_prot is used
// to give the type of the right argument (which can be a reference too)
// (The built in operator, can return a l- or rvalue).
template<class A, class B>
struct return_type_2<other_action<comma_action>, A, B> {
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename
plain_return_type_2<
other_action<comma_action>, plain_A, plain_B
>::type type;
};
// subscript action -----------------------------------------------
namespace detail {
// A and B are nonreference types
template <class A, class B> struct subscript_type {
typedef detail::unspecified type;
};
template <class A, class B> struct subscript_type<A*, B> {
typedef A& type;
};
template <class A, class B> struct subscript_type<A* const, B> {
typedef A& type;
};
template <class A, class B> struct subscript_type<A* volatile, B> {
typedef A& type;
};
template <class A, class B> struct subscript_type<A* const volatile, B> {
typedef A& type;
};
template<class A, class B, int N> struct subscript_type<A[N], B> {
typedef A& type;
};
// these 3 specializations are needed to make gcc <3 happy
template<class A, class B, int N> struct subscript_type<const A[N], B> {
typedef const A& type;
};
template<class A, class B, int N> struct subscript_type<volatile A[N], B> {
typedef volatile A& type;
};
template<class A, class B, int N> struct subscript_type<const volatile A[N], B> {
typedef const volatile A& type;
};
} // end detail
template<class A, class B>
struct return_type_2<other_action<subscript_action>, A, B> {
typedef typename detail::remove_reference_and_cv<A>::type plain_A;
typedef typename detail::remove_reference_and_cv<B>::type plain_B;
typedef typename boost::remove_reference<A>::type nonref_A;
typedef typename boost::remove_reference<B>::type nonref_B;
typedef typename
plain_return_type_2<
other_action<subscript_action>, plain_A, plain_B
>::type type1;
typedef typename
detail::IF_type<
boost::is_same<type1, detail::unspecified>::value,
detail::subscript_type<nonref_A, nonref_B>,
plain_return_type_2<other_action<subscript_action>, plain_A, plain_B>
>::type type;
};
template<class Key, class T, class Cmp, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::map<Key, T, Cmp, Allocator>, B> {
typedef T& type;
// T == std::map<Key, T, Cmp, Allocator>::mapped_type;
};
template<class Key, class T, class Cmp, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::multimap<Key, T, Cmp, Allocator>, B> {
typedef T& type;
// T == std::map<Key, T, Cmp, Allocator>::mapped_type;
};
// deque
template<class T, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::deque<T, Allocator>, B> {
typedef typename std::deque<T, Allocator>::reference type;
};
template<class T, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, const std::deque<T, Allocator>, B> {
typedef typename std::deque<T, Allocator>::const_reference type;
};
// vector
template<class T, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::vector<T, Allocator>, B> {
typedef typename std::vector<T, Allocator>::reference type;
};
template<class T, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, const std::vector<T, Allocator>, B> {
typedef typename std::vector<T, Allocator>::const_reference type;
};
// basic_string
template<class Char, class Traits, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::basic_string<Char, Traits, Allocator>, B> {
typedef typename std::basic_string<Char, Traits, Allocator>::reference type;
};
template<class Char, class Traits, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, const std::basic_string<Char, Traits, Allocator>, B> {
typedef typename std::basic_string<Char, Traits, Allocator>::const_reference type;
};
template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
std::basic_string<Char, Traits, Allocator>,
std::basic_string<Char, Traits, Allocator> > {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
const Char*,
std::basic_string<Char, Traits, Allocator> > {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
std::basic_string<Char, Traits, Allocator>,
const Char*> {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator, std::size_t N>
struct plain_return_type_2<arithmetic_action<plus_action>,
Char[N],
std::basic_string<Char, Traits, Allocator> > {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator, std::size_t N>
struct plain_return_type_2<arithmetic_action<plus_action>,
std::basic_string<Char, Traits, Allocator>,
Char[N]> {
typedef std::basic_string<Char, Traits, Allocator> type;
};
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,352 @@
// Boost Lambda Library - operators.hpp --------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ---------------------------------------------------------------
#ifndef BOOST_LAMBDA_OPERATORS_HPP
#define BOOST_LAMBDA_OPERATORS_HPP
#include "boost/lambda/detail/is_instance_of.hpp"
namespace boost {
namespace lambda {
#if defined BOOST_LAMBDA_BE1
#error "Multiple defines of BOOST_LAMBDA_BE1"
#endif
// For all BOOSTA_LAMBDA_BE* macros:
// CONSTA must be either 'A' or 'const A'
// CONSTB must be either 'B' or 'const B'
// It is stupid to have the names A and B as macro arguments, but it avoids
// the need to pass in emtpy macro arguments, which gives warnings on some
// compilers
#define BOOST_LAMBDA_BE1(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION) \
template<class Arg, class B> \
inline const \
lambda_functor< \
lambda_functor_base< \
ACTION, \
tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type> \
> \
> \
OPER_NAME (const lambda_functor<Arg>& a, CONSTB& b) { \
return \
lambda_functor_base< \
ACTION, \
tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>\
> \
(tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>(a, b)); \
}
#if defined BOOST_LAMBDA_BE2
#error "Multiple defines of BOOST_LAMBDA_BE2"
#endif
#define BOOST_LAMBDA_BE2(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION) \
template<class A, class Arg> \
inline const \
lambda_functor< \
lambda_functor_base< \
ACTION, \
tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> > \
> \
> \
OPER_NAME (CONSTA& a, const lambda_functor<Arg>& b) { \
return \
lambda_functor_base< \
ACTION, \
tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> > \
> \
(tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> >(a, b)); \
}
#if defined BOOST_LAMBDA_BE3
#error "Multiple defines of BOOST_LAMBDA_BE3"
#endif
#define BOOST_LAMBDA_BE3(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION) \
template<class ArgA, class ArgB> \
inline const \
lambda_functor< \
lambda_functor_base< \
ACTION, \
tuple<lambda_functor<ArgA>, lambda_functor<ArgB> > \
> \
> \
OPER_NAME (const lambda_functor<ArgA>& a, const lambda_functor<ArgB>& b) { \
return \
lambda_functor_base< \
ACTION, \
tuple<lambda_functor<ArgA>, lambda_functor<ArgB> > \
> \
(tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >(a, b)); \
}
#if defined BOOST_LAMBDA_BE
#error "Multiple defines of BOOST_LAMBDA_BE"
#endif
#define BOOST_LAMBDA_BE(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION) \
BOOST_LAMBDA_BE1(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION) \
BOOST_LAMBDA_BE2(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION) \
BOOST_LAMBDA_BE3(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION)
#define BOOST_LAMBDA_EMPTY()
BOOST_LAMBDA_BE(operator+, arithmetic_action<plus_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator-, arithmetic_action<minus_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator*, arithmetic_action<multiply_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator/, arithmetic_action<divide_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator%, arithmetic_action<remainder_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator<<, bitwise_action<leftshift_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator>>, bitwise_action<rightshift_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator&, bitwise_action<and_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator|, bitwise_action<or_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator^, bitwise_action<xor_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator&&, logical_action<and_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator||, logical_action<or_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator<, relational_action<less_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator>, relational_action<greater_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator<=, relational_action<lessorequal_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator>=, relational_action<greaterorequal_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator==, relational_action<equal_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator!=, relational_action<notequal_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE(operator+=, arithmetic_assignment_action<plus_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator-=, arithmetic_assignment_action<minus_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator*=, arithmetic_assignment_action<multiply_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator/=, arithmetic_assignment_action<divide_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator%=, arithmetic_assignment_action<remainder_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator<<=, bitwise_assignment_action<leftshift_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator>>=, bitwise_assignment_action<rightshift_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator&=, bitwise_assignment_action<and_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator|=, bitwise_assignment_action<or_action>, A, const B, reference_argument)
BOOST_LAMBDA_BE(operator^=, bitwise_assignment_action<xor_action>, A, const B, reference_argument)
// A special trick for comma operator for correct preprocessing
#if defined BOOST_LAMBDA_COMMA_OPERATOR_NAME
#error "Multiple defines of BOOST_LAMBDA_COMMA_OPERATOR_NAME"
#endif
#define BOOST_LAMBDA_COMMA_OPERATOR_NAME operator,
BOOST_LAMBDA_BE1(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE2(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const A, const B, const_copy_argument)
BOOST_LAMBDA_BE3(BOOST_LAMBDA_COMMA_OPERATOR_NAME, other_action<comma_action>, const A, const B, const_copy_argument)
namespace detail {
// special cases for ostream& << Any and istream& >> Any ---------------
// the actual stream classes may vary and thus a specialisation for,
// say ostream& does not match (the general case above is chosen).
// Therefore we specialise for non-const reference:
// if the left argument is a stream, we store the stream as reference
// if it is something else, we store a const plain by default
// Note that the overloading is const vs. non-const first argument
template<class T> struct convert_ostream_to_ref_others_to_c_plain_by_default {
typedef typename detail::IF<
is_instance_of_2<
T, std::basic_ostream
>::value,
T&,
typename const_copy_argument <T>::type
>::RET type;
};
template<class T> struct convert_istream_to_ref_others_to_c_plain_by_default {
typedef typename detail::IF<
is_instance_of_2<
T, std::basic_istream
>::value,
T&,
typename const_copy_argument <T>::type
>::RET type;
};
} // detail
BOOST_LAMBDA_BE2(operator<<, bitwise_action< leftshift_action>, A, const B, detail::convert_ostream_to_ref_others_to_c_plain_by_default)
BOOST_LAMBDA_BE2(operator>>, bitwise_action< rightshift_action>, A, const B, detail::convert_istream_to_ref_others_to_c_plain_by_default)
// special case for io_manipulators.
// function references cannot be given as arguments to lambda operator
// expressions in general. With << and >> the use of manipulators is
// so common, that specializations are provided to make them work.
template<class Arg, class Ret, class ManipArg>
inline const
lambda_functor<
lambda_functor_base<
bitwise_action<leftshift_action>,
tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>
>
>
operator<<(const lambda_functor<Arg>& a, Ret(&b)(ManipArg))
{
return
lambda_functor_base<
bitwise_action<leftshift_action>,
tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>
>
( tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>(a, b) );
}
template<class Arg, class Ret, class ManipArg>
inline const
lambda_functor<
lambda_functor_base<
bitwise_action<rightshift_action>,
tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>
>
>
operator>>(const lambda_functor<Arg>& a, Ret(&b)(ManipArg))
{
return
lambda_functor_base<
bitwise_action<rightshift_action>,
tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>
>
( tuple<lambda_functor<Arg>, Ret(&)(ManipArg)>(a, b) );
}
// (+ and -) take their arguments as const references.
// This has consquences with pointer artihmetic
// E.g int a[]; ... *a = 1 works but not *(a+1) = 1.
// the result of a+1 would be const
// To make the latter work too,
// non-const arrays are taken as non-const and stored as non-const as well.
#if defined BOOST_LAMBDA_PTR_ARITHMETIC_E1
#error "Multiple defines of BOOST_LAMBDA_PTR_ARITHMETIC_E1"
#endif
#define BOOST_LAMBDA_PTR_ARITHMETIC_E1(OPER_NAME, ACTION, CONSTB) \
template<class Arg, int N, class B> \
inline const \
lambda_functor< \
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
> \
OPER_NAME (const lambda_functor<Arg>& a, CONSTB(&b)[N]) \
{ \
return \
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
(tuple<lambda_functor<Arg>, CONSTB(&)[N]>(a, b)); \
}
#if defined BOOST_LAMBDA_PTR_ARITHMETIC_E2
#error "Multiple defines of BOOST_LAMBDA_PTR_ARITHMETIC_E2"
#endif
#define BOOST_LAMBDA_PTR_ARITHMETIC_E2(OPER_NAME, ACTION, CONSTA) \
template<int N, class A, class Arg> \
inline const \
lambda_functor< \
lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
> \
OPER_NAME (CONSTA(&a)[N], const lambda_functor<Arg>& b) \
{ \
return \
lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
(tuple<CONSTA(&)[N], lambda_functor<Arg> >(a, b)); \
}
BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator+, arithmetic_action<plus_action>, B)
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator+, arithmetic_action<plus_action>, A)
BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator+, arithmetic_action<plus_action>,const B)
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator+, arithmetic_action<plus_action>,const A)
//BOOST_LAMBDA_PTR_ARITHMETIC_E1(operator-, arithmetic_action<minus_action>)
// This is not needed, since the result of ptr-ptr is an rvalue anyway
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, A)
BOOST_LAMBDA_PTR_ARITHMETIC_E2(operator-, arithmetic_action<minus_action>, const A)
#undef BOOST_LAMBDA_BE1
#undef BOOST_LAMBDA_BE2
#undef BOOST_LAMBDA_BE3
#undef BOOST_LAMBDA_BE
#undef BOOST_LAMBDA_COMMA_OPERATOR_NAME
#undef BOOST_LAMBDA_PTR_ARITHMETIC_E1
#undef BOOST_LAMBDA_PTR_ARITHMETIC_E2
// ---------------------------------------------------------------------
// unary operators -----------------------------------------------------
// ---------------------------------------------------------------------
#if defined BOOST_LAMBDA_UE
#error "Multiple defines of BOOST_LAMBDA_UE"
#endif
#define BOOST_LAMBDA_UE(OPER_NAME, ACTION) \
template<class Arg> \
inline const \
lambda_functor<lambda_functor_base<ACTION, tuple<lambda_functor<Arg> > > > \
OPER_NAME (const lambda_functor<Arg>& a) \
{ \
return \
lambda_functor_base<ACTION, tuple<lambda_functor<Arg> > > \
( tuple<lambda_functor<Arg> >(a) ); \
}
BOOST_LAMBDA_UE(operator+, unary_arithmetic_action<plus_action>)
BOOST_LAMBDA_UE(operator-, unary_arithmetic_action<minus_action>)
BOOST_LAMBDA_UE(operator~, bitwise_action<not_action>)
BOOST_LAMBDA_UE(operator!, logical_action<not_action>)
BOOST_LAMBDA_UE(operator++, pre_increment_decrement_action<increment_action>)
BOOST_LAMBDA_UE(operator--, pre_increment_decrement_action<decrement_action>)
BOOST_LAMBDA_UE(operator*, other_action<contentsof_action>)
BOOST_LAMBDA_UE(operator&, other_action<addressof_action>)
#if defined BOOST_LAMBDA_POSTFIX_UE
#error "Multiple defines of BOOST_LAMBDA_POSTFIX_UE"
#endif
#define BOOST_LAMBDA_POSTFIX_UE(OPER_NAME, ACTION) \
template<class Arg> \
inline const \
lambda_functor<lambda_functor_base<ACTION, tuple<lambda_functor<Arg> > > > \
OPER_NAME (const lambda_functor<Arg>& a, int) \
{ \
return \
lambda_functor_base<ACTION, tuple<lambda_functor<Arg> > > \
( tuple<lambda_functor<Arg> >(a) ); \
}
BOOST_LAMBDA_POSTFIX_UE(operator++, post_increment_decrement_action<increment_action>)
BOOST_LAMBDA_POSTFIX_UE(operator--, post_increment_decrement_action<decrement_action>)
#undef BOOST_LAMBDA_UE
#undef BOOST_LAMBDA_POSTFIX_UE
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,325 @@
// Boost Lambda Library ret.hpp -----------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
#ifndef BOOST_LAMBDA_RET_HPP
#define BOOST_LAMBDA_RET_HPP
namespace boost {
namespace lambda {
// TODO:
// Add specializations for function references for ret, protect and unlambda
// e.g void foo(); unlambda(foo); fails, as it would add a const qualifier
// for a function type.
// on the other hand unlambda(*foo) does work
// -- ret -------------------------
// the explicit return type template
// TODO: It'd be nice to make ret a nop for other than lambda functors
// but causes an ambiguiyty with gcc (not with KCC), check what is the
// right interpretation.
// // ret for others than lambda functors has no effect
// template <class U, class T>
// inline const T& ret(const T& t) { return t; }
template<class RET, class Arg>
inline const
lambda_functor<
lambda_functor_base<
explicit_return_type_action<RET>,
tuple<lambda_functor<Arg> >
>
>
ret(const lambda_functor<Arg>& a1)
{
return
lambda_functor_base<
explicit_return_type_action<RET>,
tuple<lambda_functor<Arg> >
>
(tuple<lambda_functor<Arg> >(a1));
}
// protect ------------------
// protecting others than lambda functors has no effect
template <class T>
inline const T& protect(const T& t) { return t; }
template<class Arg>
inline const
lambda_functor<
lambda_functor_base<
protect_action,
tuple<lambda_functor<Arg> >
>
>
protect(const lambda_functor<Arg>& a1)
{
return
lambda_functor_base<
protect_action,
tuple<lambda_functor<Arg> >
>
(tuple<lambda_functor<Arg> >(a1));
}
// -------------------------------------------------------------------
// Hides the lambda functorness of a lambda functor.
// After this, the functor is immune to argument substitution, etc.
// This can be used, e.g. to make it safe to pass lambda functors as
// arguments to functions, which might use them as target functions
// note, unlambda and protect are different things. Protect hides the lambda
// functor for one application, unlambda for good.
template <class LambdaFunctor>
class non_lambda_functor
{
LambdaFunctor lf;
public:
// This functor defines the result_type typedef.
// The result type must be deducible without knowing the arguments
template <class SigArgs> struct sig {
typedef typename
LambdaFunctor::inherited::
template sig<typename SigArgs::tail_type>::type type;
};
explicit non_lambda_functor(const LambdaFunctor& a) : lf(a) {}
typename LambdaFunctor::nullary_return_type
operator()() const {
return lf.template
call<typename LambdaFunctor::nullary_return_type>
(cnull_type(), cnull_type(), cnull_type(), cnull_type());
}
template<class A>
typename sig<tuple<const non_lambda_functor, A&> >::type
operator()(A& a) const {
return lf.template call<typename sig<tuple<const non_lambda_functor, A&> >::type >(a, cnull_type(), cnull_type(), cnull_type());
}
template<class A, class B>
typename sig<tuple<const non_lambda_functor, A&, B&> >::type
operator()(A& a, B& b) const {
return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&> >::type >(a, b, cnull_type(), cnull_type());
}
template<class A, class B, class C>
typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type
operator()(A& a, B& b, C& c) const {
return lf.template call<typename sig<tuple<const non_lambda_functor, A&, B&, C&> >::type>(a, b, c, cnull_type());
}
};
template <class Arg>
inline const Arg& unlambda(const Arg& a) { return a; }
template <class Arg>
inline const non_lambda_functor<lambda_functor<Arg> >
unlambda(const lambda_functor<Arg>& a)
{
return non_lambda_functor<lambda_functor<Arg> >(a);
}
// Due to a language restriction, lambda functors cannot be made to
// accept non-const rvalue arguments. Usually iterators do not return
// temporaries, but sometimes they do. That's why a workaround is provided.
// Note, that this potentially breaks const correctness, so be careful!
// any lambda functor can be turned into a const_incorrect_lambda_functor
// The operator() takes arguments as consts and then casts constness
// away. So this breaks const correctness!!! but is a necessary workaround
// in some cases due to language limitations.
// Note, that this is not a lambda_functor anymore, so it can not be used
// as a sub lambda expression.
template <class LambdaFunctor>
struct const_incorrect_lambda_functor {
LambdaFunctor lf;
public:
explicit const_incorrect_lambda_functor(const LambdaFunctor& a) : lf(a) {}
template <class SigArgs> struct sig {
typedef typename
LambdaFunctor::inherited::template
sig<typename SigArgs::tail_type>::type type;
};
// The nullary case is not needed (no arguments, no parameter type problems)
template<class A>
typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type
operator()(const A& a) const {
return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&> >::type >(const_cast<A&>(a), cnull_type(), cnull_type(), cnull_type());
}
template<class A, class B>
typename sig<tuple<const const_incorrect_lambda_functor, A&, B&> >::type
operator()(const A& a, const B& b) const {
return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&, B&> >::type >(const_cast<A&>(a), const_cast<B&>(b), cnull_type(), cnull_type());
}
template<class A, class B, class C>
typename sig<tuple<const const_incorrect_lambda_functor, A&, B&, C&> >::type
operator()(const A& a, const B& b, const C& c) const {
return lf.template call<typename sig<tuple<const const_incorrect_lambda_functor, A&, B&, C&> >::type>(const_cast<A&>(a), const_cast<B&>(b), const_cast<C&>(c), cnull_type());
}
};
// ------------------------------------------------------------------------
// any lambda functor can be turned into a const_parameter_lambda_functor
// The operator() takes arguments as const.
// This is useful if lambda functors are called with non-const rvalues.
// Note, that this is not a lambda_functor anymore, so it can not be used
// as a sub lambda expression.
template <class LambdaFunctor>
struct const_parameter_lambda_functor {
LambdaFunctor lf;
public:
explicit const_parameter_lambda_functor(const LambdaFunctor& a) : lf(a) {}
template <class SigArgs> struct sig {
typedef typename
LambdaFunctor::inherited::template
sig<typename SigArgs::tail_type>::type type;
};
// The nullary case is not needed: no arguments, no constness problems.
template<class A>
typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type
operator()(const A& a) const {
return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&> >::type >(a, cnull_type(), cnull_type(), cnull_type());
}
template<class A, class B>
typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type
operator()(const A& a, const B& b) const {
return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&> >::type >(a, b, cnull_type(), cnull_type());
}
template<class A, class B, class C>
typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&>
>::type
operator()(const A& a, const B& b, const C& c) const {
return lf.template call<typename sig<tuple<const const_parameter_lambda_functor, const A&, const B&, const C&> >::type>(a, b, c, cnull_type());
}
};
template <class Arg>
inline const const_incorrect_lambda_functor<lambda_functor<Arg> >
break_const(const lambda_functor<Arg>& lf)
{
return const_incorrect_lambda_functor<lambda_functor<Arg> >(lf);
}
template <class Arg>
inline const const_parameter_lambda_functor<lambda_functor<Arg> >
const_parameters(const lambda_functor<Arg>& lf)
{
return const_parameter_lambda_functor<lambda_functor<Arg> >(lf);
}
// make void ------------------------------------------------
// make_void( x ) turns a lambda functor x with some return type y into
// another lambda functor, which has a void return type
// when called, the original return type is discarded
// we use this action. The action class will be called, which means that
// the wrapped lambda functor is evaluated, but we just don't do anything
// with the result.
struct voidifier_action {
template<class Ret, class A> static void apply(A&) {}
};
template<class Args> struct return_type_N<voidifier_action, Args> {
typedef void type;
};
template<class Arg1>
inline const
lambda_functor<
lambda_functor_base<
action<1, voidifier_action>,
tuple<lambda_functor<Arg1> >
>
>
make_void(const lambda_functor<Arg1>& a1) {
return
lambda_functor_base<
action<1, voidifier_action>,
tuple<lambda_functor<Arg1> >
>
(tuple<lambda_functor<Arg1> > (a1));
}
// for non-lambda functors, make_void does nothing
// (the argument gets evaluated immediately)
template<class Arg1>
inline const
lambda_functor<
lambda_functor_base<do_nothing_action, null_type>
>
make_void(const Arg1&) {
return
lambda_functor_base<do_nothing_action, null_type>();
}
// std_functor -----------------------------------------------------
// The STL uses the result_type typedef as the convention to let binders know
// the return type of a function object.
// LL uses the sig template.
// To let LL know that the function object has the result_type typedef
// defined, it can be wrapped with the std_functor function.
// Just inherit form the template parameter (the standard functor),
// and provide a sig template. So we have a class which is still the
// same functor + the sig template.
template<class T>
struct result_type_to_sig : public T {
template<class Args> struct sig { typedef typename T::result_type type; };
result_type_to_sig(const T& t) : T(t) {}
};
template<class F>
inline result_type_to_sig<F> std_functor(const F& f) { return f; }
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,269 @@
// return_type_traits.hpp -- Boost Lambda Library ---------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
#ifndef BOOST_LAMBDA_RETURN_TYPE_TRAITS_HPP
#define BOOST_LAMBDA_RETURN_TYPE_TRAITS_HPP
#include "boost/mpl/has_xxx.hpp"
#include <cstddef> // needed for the ptrdiff_t
namespace boost {
namespace lambda {
// Much of the type deduction code for standard arithmetic types
// from Gary Powell
// different arities:
template <class Act, class A1> struct return_type_1; // 1-ary actions
template <class Act, class A1, class A2> struct return_type_2; // 2-ary
template <class Act, class Args> struct return_type_N; // >3- ary
template <class Act, class A1> struct return_type_1_prot;
template <class Act, class A1, class A2> struct return_type_2_prot; // 2-ary
template <class Act, class A1> struct return_type_N_prot; // >3-ary
namespace detail {
template<class> class return_type_deduction_failure {};
// In some cases return type deduction should fail (an invalid lambda
// expression). Sometimes the lambda expression can be ok, the return type
// just is not deducible (user defined operators). Then return type deduction
// should never be entered at all, and the use of ret<> does this.
// However, for nullary lambda functors, return type deduction is always
// entered, and there seems to be no way around this.
// (the return type is part of the prototype of the non-template
// operator()(). The prototype is instantiated, even though the body
// is not.)
// So, in the case the return type deduction should fail, it should not
// fail directly, but rather result in a valid but wrong return type,
// causing a compile time error only if the function is really called.
} // end detail
// return_type_X_prot classes --------------------------------------------
// These classes are the first layer that gets instantiated from the
// lambda_functor_base sig templates. It will check whether
// the action is protectable and one of arguments is "protected" or its
// evaluation will otherwise result in another lambda functor.
// If this is a case, the result type will be another lambda functor.
// The arguments are always non-reference types, except for comma action
// where the right argument can be a reference too. This is because it
// matters (in the builtin case) whether the argument is an lvalue or
// rvalue: int i; i, 1 -> rvalue; 1, i -> lvalue
template <class Act, class A> struct return_type_1_prot {
public:
typedef typename
detail::IF<
is_protectable<Act>::value && is_lambda_functor<A>::value,
lambda_functor<
lambda_functor_base<
Act,
tuple<typename detail::remove_reference_and_cv<A>::type>
>
>,
typename return_type_1<Act, A>::type
>::RET type;
};
// take care of the unavoidable instantiation for nullary case
template<class Act> struct return_type_1_prot<Act, null_type> {
typedef null_type type;
};
// Unary actions (result from unary operators)
// do not have a default return type.
template<class Act, class A> struct return_type_1 {
typedef typename
detail::return_type_deduction_failure<return_type_1> type;
};
namespace detail {
template <class T>
class protect_conversion {
typedef typename boost::remove_reference<T>::type non_ref_T;
public:
// add const to rvalues, so that all rvalues are stored as const in
// the args tuple
typedef typename detail::IF_type<
boost::is_reference<T>::value && !boost::is_const<non_ref_T>::value,
detail::identity_mapping<T>,
const_copy_argument<non_ref_T> // handles funtion and array
>::type type; // types correctly
};
} // end detail
template <class Act, class A, class B> struct return_type_2_prot {
// experimental feature
// We may have a lambda functor as a result type of a subexpression
// (if protect) has been used.
// Thus, if one of the parameter types is a lambda functor, the result
// is a lambda functor as well.
// We need to make a conservative choise here.
// The resulting lambda functor stores all const reference arguments as
// const copies. References to non-const are stored as such.
// So if the source of the argument is a const open argument, a bound
// argument stored as a const reference, or a function returning a
// const reference, that information is lost. There is no way of
// telling apart 'real const references' from just 'LL internal
// const references' (or it would be really hard)
// The return type is a subclass of lambda_functor, which has a converting
// copy constructor. It can copy any lambda functor, that has the same
// action type and code, and a copy compatible argument tuple.
typedef typename boost::remove_reference<A>::type non_ref_A;
typedef typename boost::remove_reference<B>::type non_ref_B;
typedef typename
detail::IF<
is_protectable<Act>::value &&
(is_lambda_functor<A>::value || is_lambda_functor<B>::value),
lambda_functor<
lambda_functor_base<
Act,
tuple<typename detail::protect_conversion<A>::type,
typename detail::protect_conversion<B>::type>
>
>,
typename return_type_2<Act, non_ref_A, non_ref_B>::type
>::RET type;
};
// take care of the unavoidable instantiation for nullary case
template<class Act> struct return_type_2_prot<Act, null_type, null_type> {
typedef null_type type;
};
// take care of the unavoidable instantiation for nullary case
template<class Act, class Other> struct return_type_2_prot<Act, Other, null_type> {
typedef null_type type;
};
// take care of the unavoidable instantiation for nullary case
template<class Act, class Other> struct return_type_2_prot<Act, null_type, Other> {
typedef null_type type;
};
// comma is a special case, as the user defined operator can return
// an lvalue (reference) too, hence it must be handled at this level.
template<class A, class B>
struct return_type_2_comma
{
typedef typename boost::remove_reference<A>::type non_ref_A;
typedef typename boost::remove_reference<B>::type non_ref_B;
typedef typename
detail::IF<
is_protectable<other_action<comma_action> >::value && // it is protectable
(is_lambda_functor<A>::value || is_lambda_functor<B>::value),
lambda_functor<
lambda_functor_base<
other_action<comma_action>,
tuple<typename detail::protect_conversion<A>::type,
typename detail::protect_conversion<B>::type>
>
>,
typename
return_type_2<other_action<comma_action>, non_ref_A, non_ref_B>::type
>::RET type1;
// if no user defined return_type_2 (or plain_return_type_2) specialization
// matches, then return the righthand argument
typedef typename
detail::IF<
boost::is_same<type1, detail::unspecified>::value,
B,
type1
>::RET type;
};
// currently there are no protectable actions with > 2 args
template<class Act, class Args> struct return_type_N_prot {
typedef typename return_type_N<Act, Args>::type type;
};
// take care of the unavoidable instantiation for nullary case
template<class Act> struct return_type_N_prot<Act, null_type> {
typedef null_type type;
};
// handle different kind of actions ------------------------
// use the return type given in the bind invocation as bind<Ret>(...)
template<int I, class Args, class Ret>
struct return_type_N<function_action<I, Ret>, Args> {
typedef Ret type;
};
// ::result_type support
namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
template<class F> struct get_result_type
{
typedef typename F::result_type type;
};
template<class F, class A> struct get_sig
{
typedef typename function_adaptor<F>::template sig<A>::type type;
};
} // namespace detail
// Ret is detail::unspecified, so try to deduce return type
template<int I, class Args>
struct return_type_N<function_action<I, detail::unspecified>, Args > {
// in the case of function action, the first element in Args is
// some type of function
typedef typename Args::head_type Func;
typedef typename detail::remove_reference_and_cv<Func>::type plain_Func;
public:
// pass the function to function_adaptor, and get the return type from
// that
typedef typename detail::IF<
detail::has_result_type<plain_Func>::value,
detail::get_result_type<plain_Func>,
detail::get_sig<plain_Func, Args>
>::RET::type type;
};
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,74 @@
// -- select_functions.hpp -- Boost Lambda Library --------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
#ifndef BOOST_LAMBDA_SELECT_FUNCTIONS_HPP
#define BOOST_LAMBDA_SELECT_FUNCTIONS_HPP
namespace boost {
namespace lambda {
namespace detail {
// select functions -------------------------------
template<class Any, CALL_TEMPLATE_ARGS>
inline Any& select(Any& any, CALL_FORMAL_ARGS) { CALL_USE_ARGS; return any; }
template<class Arg, CALL_TEMPLATE_ARGS>
inline typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
select ( const lambda_functor<Arg>& op, CALL_FORMAL_ARGS ) {
return op.template call<
typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
>(CALL_ACTUAL_ARGS);
}
template<class Arg, CALL_TEMPLATE_ARGS>
inline typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
select ( lambda_functor<Arg>& op, CALL_FORMAL_ARGS) {
return op.template call<
typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
>(CALL_ACTUAL_ARGS);
}
// ------------------------------------------------------------------------
// select functions where the return type is explicitly given
// Note: on many functions, this return type is just discarded.
// The select functions are inside a class template, and the return type
// is a class template argument.
// The first implementation used function templates with an explicitly
// specified template parameter.
// However, this resulted in ambiguous calls (at least with gcc 2.95.2
// and edg 2.44). Not sure whether the compilers were right or wrong.
template<class RET> struct r_select {
// Any == RET
template<class Any, CALL_TEMPLATE_ARGS>
static
inline RET go (Any& any, CALL_FORMAL_ARGS) { CALL_USE_ARGS; return any; }
template<class Arg, CALL_TEMPLATE_ARGS>
static
inline RET go (const lambda_functor<Arg>& op, CALL_FORMAL_ARGS ) {
return op.template call<RET>(CALL_ACTUAL_ARGS);
}
template<class Arg, CALL_TEMPLATE_ARGS>
static
inline RET go (lambda_functor<Arg>& op, CALL_FORMAL_ARGS ) {
return op.template call<RET>(CALL_ACTUAL_ARGS);
}
};
} // namespace detail
} // namespace lambda
} // namespace boost
#endif

View File

@@ -0,0 +1,27 @@
// Boost Lambda Library suppress_unused.hpp -----------------------------
//
// Copyright (C) 2009 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ------------------------------------------------------------
#ifndef BOOST_LAMBDA_SUPPRESS_UNUSED_HPP
#define BOOST_LAMBDA_SUPPRESS_UNUSED_HPP
namespace boost {
namespace lambda {
namespace detail {
template<class T>
inline void suppress_unused_variable_warnings(const T&) {}
}
}
}
#endif

File diff suppressed because it is too large Load Diff

462
include/boost/lambda/if.hpp Normal file
View File

@@ -0,0 +1,462 @@
// Boost Lambda Library -- if.hpp ------------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 2001-2002 Joel de Guzman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// --------------------------------------------------------------------------
#if !defined(BOOST_LAMBDA_IF_HPP)
#define BOOST_LAMBDA_IF_HPP
#include "boost/lambda/core.hpp"
// Arithmetic type promotion needed for if_then_else_return
#include "boost/lambda/detail/operator_actions.hpp"
#include "boost/lambda/detail/operator_return_type_traits.hpp"
namespace boost {
namespace lambda {
// -- if control construct actions ----------------------
class ifthen_action {};
class ifthenelse_action {};
class ifthenelsereturn_action {};
// Specialization for if_then.
template<class Args>
class
lambda_functor_base<ifthen_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
};
// If Then
template <class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
ifthen_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
if_then(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
return
lambda_functor_base<
ifthen_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2) );
}
// Specialization for if_then_else.
template<class Args>
class
lambda_functor_base<ifthenelse_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
else
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
}
};
// If then else
template <class Arg1, class Arg2, class Arg3>
inline const
lambda_functor<
lambda_functor_base<
ifthenelse_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
>
>
if_then_else(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
const lambda_functor<Arg3>& a3) {
return
lambda_functor_base<
ifthenelse_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
>
(tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
(a1, a2, a3) );
}
// Our version of operator?:()
template <class Arg1, class Arg2, class Arg3>
inline const
lambda_functor<
lambda_functor_base<
other_action<ifthenelsereturn_action>,
tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type,
typename const_copy_argument<Arg3>::type>
>
>
if_then_else_return(const lambda_functor<Arg1>& a1,
const Arg2 & a2,
const Arg3 & a3) {
return
lambda_functor_base<
other_action<ifthenelsereturn_action>,
tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type,
typename const_copy_argument<Arg3>::type>
> ( tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type,
typename const_copy_argument<Arg3>::type> (a1, a2, a3) );
}
namespace detail {
// return type specialization for conditional expression begins -----------
// start reading below and move upwards
// PHASE 6:1
// check if A is conbertible to B and B to A
template<int Phase, bool AtoB, bool BtoA, bool SameType, class A, class B>
struct return_type_2_ifthenelsereturn;
// if A can be converted to B and vice versa -> ambiguous
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, true, true, false, A, B> {
typedef
detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
// ambiguous type in conditional expression
};
// if A can be converted to B and vice versa and are of same type
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, true, true, true, A, B> {
typedef A type;
};
// A can be converted to B
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, true, false, false, A, B> {
typedef B type;
};
// B can be converted to A
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, false, true, false, A, B> {
typedef A type;
};
// neither can be converted. Then we drop the potential references, and
// try again
template<class A, class B>
struct return_type_2_ifthenelsereturn<1, false, false, false, A, B> {
// it is safe to add const, since the result will be an rvalue and thus
// const anyway. The const are needed eg. if the types
// are 'const int*' and 'void *'. The remaining type should be 'const void*'
typedef const typename boost::remove_reference<A>::type plainA;
typedef const typename boost::remove_reference<B>::type plainB;
// TODO: Add support for volatile ?
typedef typename
return_type_2_ifthenelsereturn<
2,
boost::is_convertible<plainA,plainB>::value,
boost::is_convertible<plainB,plainA>::value,
boost::is_same<plainA,plainB>::value,
plainA,
plainB>::type type;
};
// PHASE 6:2
template<class A, class B>
struct return_type_2_ifthenelsereturn<2, false, false, false, A, B> {
typedef
detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
// types_do_not_match_in_conditional_expression
};
// PHASE 5: now we know that types are not arithmetic.
template<class A, class B>
struct non_numeric_types {
typedef typename
return_type_2_ifthenelsereturn<
1, // phase 1
is_convertible<A,B>::value,
is_convertible<B,A>::value,
is_same<A,B>::value,
A,
B>::type type;
};
// PHASE 4 :
// the base case covers arithmetic types with differing promote codes
// use the type deduction of arithmetic_actions
template<int CodeA, int CodeB, class A, class B>
struct arithmetic_or_not {
typedef typename
return_type_2<arithmetic_action<plus_action>, A, B>::type type;
// plus_action is just a random pick, has to be a concrete instance
};
// this case covers the case of artihmetic types with the same promote codes.
// non numeric deduction is used since e.g. integral promotion is not
// performed with operator ?:
template<int CodeA, class A, class B>
struct arithmetic_or_not<CodeA, CodeA, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
// if either A or B has promote code -1 it is not an arithmetic type
template<class A, class B>
struct arithmetic_or_not <-1, -1, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
template<int CodeB, class A, class B>
struct arithmetic_or_not <-1, CodeB, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
template<int CodeA, class A, class B>
struct arithmetic_or_not <CodeA, -1, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
// PHASE 3 : Are the types same?
// No, check if they are arithmetic or not
template <class A, class B>
struct same_or_not {
typedef typename detail::remove_reference_and_cv<A>::type plainA;
typedef typename detail::remove_reference_and_cv<B>::type plainB;
typedef typename
arithmetic_or_not<
detail::promote_code<plainA>::value,
detail::promote_code<plainB>::value,
A,
B>::type type;
};
// Yes, clear.
template <class A> struct same_or_not<A, A> {
typedef A type;
};
} // detail
// PHASE 2 : Perform first the potential array_to_pointer conversion
template<class A, class B>
struct return_type_2<other_action<ifthenelsereturn_action>, A, B> {
typedef typename detail::array_to_pointer<A>::type A1;
typedef typename detail::array_to_pointer<B>::type B1;
typedef typename
boost::add_const<typename detail::same_or_not<A1, B1>::type>::type type;
};
// PHASE 1 : Deduction is based on the second and third operand
// return type specialization for conditional expression ends -----------
// Specialization of lambda_functor_base for if_then_else_return.
template<class Args>
class
lambda_functor_base<other_action<ifthenelsereturn_action>, Args> {
public:
Args args;
template <class SigArgs> struct sig {
private:
typedef typename detail::nth_return_type_sig<1, Args, SigArgs>::type ret1;
typedef typename detail::nth_return_type_sig<2, Args, SigArgs>::type ret2;
public:
typedef typename return_type_2<
other_action<ifthenelsereturn_action>, ret1, ret2
>::type type;
};
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
return (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) ?
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS)
:
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
}
};
// The code below is from Joel de Guzman, some name changes etc.
// has been made.
///////////////////////////////////////////////////////////////////////////////
//
// if_then_else_composite
//
// This composite has two (2) forms:
//
// if_(condition)
// [
// statement
// ]
//
// and
//
// if_(condition)
// [
// true_statement
// ]
// .else_
// [
// false_statement
// ]
//
// where condition is an lambda_functor that evaluates to bool. If condition
// is true, the true_statement (again an lambda_functor) is executed
// otherwise, the false_statement (another lambda_functor) is executed. The
// result type of this is void. Note the trailing underscore after
// if_ and the leading dot and the trailing underscore before
// and after .else_.
//
///////////////////////////////////////////////////////////////////////////////
template <typename CondT, typename ThenT, typename ElseT>
struct if_then_else_composite {
typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
template <class SigArgs>
struct sig { typedef void type; };
if_then_else_composite(
CondT const& cond_,
ThenT const& then_,
ElseT const& else__)
: cond(cond_), then(then_), else_(else__) {}
template <class Ret, CALL_TEMPLATE_ARGS>
Ret call(CALL_FORMAL_ARGS) const
{
if (cond.internal_call(CALL_ACTUAL_ARGS))
then.internal_call(CALL_ACTUAL_ARGS);
else
else_.internal_call(CALL_ACTUAL_ARGS);
}
CondT cond; ThenT then; ElseT else_; // lambda_functors
};
//////////////////////////////////
template <typename CondT, typename ThenT>
struct else_gen {
else_gen(CondT const& cond_, ThenT const& then_)
: cond(cond_), then(then_) {}
template <typename ElseT>
lambda_functor<if_then_else_composite<CondT, ThenT,
typename as_lambda_functor<ElseT>::type> >
operator[](ElseT const& else_)
{
typedef if_then_else_composite<CondT, ThenT,
typename as_lambda_functor<ElseT>::type>
result;
return result(cond, then, to_lambda_functor(else_));
}
CondT cond; ThenT then;
};
//////////////////////////////////
template <typename CondT, typename ThenT>
struct if_then_composite {
template <class SigArgs>
struct sig { typedef void type; };
if_then_composite(CondT const& cond_, ThenT const& then_)
: cond(cond_), then(then_), else_(cond, then) {}
template <class Ret, CALL_TEMPLATE_ARGS>
Ret call(CALL_FORMAL_ARGS) const
{
if (cond.internal_call(CALL_ACTUAL_ARGS))
then.internal_call(CALL_ACTUAL_ARGS);
}
CondT cond; ThenT then; // lambda_functors
else_gen<CondT, ThenT> else_;
};
//////////////////////////////////
template <typename CondT>
struct if_gen {
if_gen(CondT const& cond_)
: cond(cond_) {}
template <typename ThenT>
lambda_functor<if_then_composite<
typename as_lambda_functor<CondT>::type,
typename as_lambda_functor<ThenT>::type> >
operator[](ThenT const& then) const
{
typedef if_then_composite<
typename as_lambda_functor<CondT>::type,
typename as_lambda_functor<ThenT>::type>
result;
return result(
to_lambda_functor(cond),
to_lambda_functor(then));
}
CondT cond;
};
//////////////////////////////////
template <typename CondT>
inline if_gen<CondT>
if_(CondT const& cond)
{
return if_gen<CondT>(cond);
}
} // lambda
} // boost
#endif // BOOST_LAMBDA_IF_HPP

View File

@@ -0,0 +1,29 @@
// -- lambda.hpp -- Boost Lambda Library -----------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://lambda.cs.utu.fi
#ifndef BOOST_LAMBDA_LAMBDA_HPP
#define BOOST_LAMBDA_LAMBDA_HPP
#include "boost/lambda/core.hpp"
#ifdef BOOST_NO_FDECL_TEMPLATES_AS_TEMPLATE_TEMPLATE_PARAMS
#include <istream>
#include <ostream>
#endif
#include "boost/lambda/detail/operator_actions.hpp"
#include "boost/lambda/detail/operator_lambda_func_base.hpp"
#include "boost/lambda/detail/operator_return_type_traits.hpp"
#include "boost/lambda/detail/operators.hpp"
#include "boost/lambda/detail/member_ptr.hpp"
#endif

View File

@@ -0,0 +1,505 @@
// Boost Lambda Library -- loops.hpp ----------------------------------------
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (c) 2001-2002 Joel de Guzman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// --------------------------------------------------------------------------
#if !defined(BOOST_LAMBDA_LOOPS_HPP)
#define BOOST_LAMBDA_LOOPS_HPP
#include "boost/lambda/core.hpp"
namespace boost {
namespace lambda {
// -- loop control structure actions ----------------------
class forloop_action {};
class forloop_no_body_action {};
class whileloop_action {};
class whileloop_no_body_action {};
class dowhileloop_action {};
class dowhileloop_no_body_action {};
// For loop
template <class Arg1, class Arg2, class Arg3, class Arg4>
inline const
lambda_functor<
lambda_functor_base<
forloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3>, lambda_functor<Arg4> >
>
>
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
const lambda_functor<Arg3>& a3, const lambda_functor<Arg4>& a4) {
return
lambda_functor_base<
forloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3>, lambda_functor<Arg4> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3>, lambda_functor<Arg4> >(a1, a2, a3, a4)
);
}
// No body case.
template <class Arg1, class Arg2, class Arg3>
inline const
lambda_functor<
lambda_functor_base<
forloop_no_body_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
>
>
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
const lambda_functor<Arg3>& a3) {
return
lambda_functor_base<
forloop_no_body_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3> >(a1, a2, a3) );
}
// While loop
template <class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
whileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
return
lambda_functor_base<
whileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
}
// No body case.
template <class Arg1>
inline const
lambda_functor<
lambda_functor_base<
whileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
>
while_loop(const lambda_functor<Arg1>& a1) {
return
lambda_functor_base<
whileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
( tuple<lambda_functor<Arg1> >(a1) );
}
// Do While loop
template <class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
dowhileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
do_while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
return
lambda_functor_base<
dowhileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
}
// No body case.
template <class Arg1>
inline const
lambda_functor<
lambda_functor_base<
dowhileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
>
do_while_loop(const lambda_functor<Arg1>& a1) {
return
lambda_functor_base<
dowhileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
( tuple<lambda_functor<Arg1> >(a1));
}
// Control loop lambda_functor_base specializations.
// Specialization for for_loop.
template<class Args>
class
lambda_functor_base<forloop_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS);
}
};
// No body case
template<class Args>
class
lambda_functor_base<forloop_no_body_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) {}
}
};
// Specialization for while_loop.
template<class Args>
class
lambda_functor_base<whileloop_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
};
// No body case
template<class Args>
class
lambda_functor_base<whileloop_no_body_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) {}
}
};
// Specialization for do_while_loop.
// Note that the first argument is the condition.
template<class Args>
class
lambda_functor_base<dowhileloop_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
do {
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
}
};
// No body case
template<class Args>
class
lambda_functor_base<dowhileloop_no_body_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
do {} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
}
};
// The code below is from Joel de Guzman, some name changes etc.
// has been made.
///////////////////////////////////////////////////////////////////////////////
//
// while_composite
//
// This composite has the form:
//
// while_(condition)
// [
// statement
// ]
//
// While the condition (an lambda_functor) evaluates to true, statement
// (another lambda_functor) is executed. The result type of this is void.
// Note the trailing underscore after while_.
//
///////////////////////////////////////////////////////////////////////////////
template <typename CondT, typename DoT>
struct while_composite {
typedef while_composite<CondT, DoT> self_t;
template <class SigArgs>
struct sig { typedef void type; };
while_composite(CondT const& cond_, DoT const& do__)
: cond(cond_), do_(do__) {}
template <class Ret, CALL_TEMPLATE_ARGS>
Ret call(CALL_FORMAL_ARGS) const
{
while (cond.internal_call(CALL_ACTUAL_ARGS))
do_.internal_call(CALL_ACTUAL_ARGS);
}
CondT cond;
DoT do_;
};
//////////////////////////////////
template <typename CondT>
struct while_gen {
while_gen(CondT const& cond_)
: cond(cond_) {}
template <typename DoT>
lambda_functor<while_composite<
typename as_lambda_functor<CondT>::type,
typename as_lambda_functor<DoT>::type> >
operator[](DoT const& do_) const
{
typedef while_composite<
typename as_lambda_functor<CondT>::type,
typename as_lambda_functor<DoT>::type>
result;
return result(
to_lambda_functor(cond),
to_lambda_functor(do_));
}
CondT cond;
};
//////////////////////////////////
template <typename CondT>
inline while_gen<CondT>
while_(CondT const& cond)
{
return while_gen<CondT>(cond);
}
///////////////////////////////////////////////////////////////////////////////
//
// do_composite
//
// This composite has the form:
//
// do_
// [
// statement
// ]
// .while_(condition)
//
// While the condition (an lambda_functor) evaluates to true, statement
// (another lambda_functor) is executed. The statement is executed at least
// once. The result type of this is void. Note the trailing
// underscore after do_ and the leading dot and the trailing
// underscore before and after .while_.
//
///////////////////////////////////////////////////////////////////////////////
template <typename DoT, typename CondT>
struct do_composite {
typedef do_composite<DoT, CondT> self_t;
template <class SigArgs>
struct sig { typedef void type; };
do_composite(DoT const& do__, CondT const& cond_)
: do_(do__), cond(cond_) {}
template <class Ret, CALL_TEMPLATE_ARGS>
Ret call(CALL_FORMAL_ARGS) const
{
do
do_.internal_call(CALL_ACTUAL_ARGS);
while (cond.internal_call(CALL_ACTUAL_ARGS));
}
DoT do_;
CondT cond;
};
////////////////////////////////////
template <typename DoT>
struct do_gen2 {
do_gen2(DoT const& do__)
: do_(do__) {}
template <typename CondT>
lambda_functor<do_composite<
typename as_lambda_functor<DoT>::type,
typename as_lambda_functor<CondT>::type> >
while_(CondT const& cond) const
{
typedef do_composite<
typename as_lambda_functor<DoT>::type,
typename as_lambda_functor<CondT>::type>
result;
return result(
to_lambda_functor(do_),
to_lambda_functor(cond));
}
DoT do_;
};
////////////////////////////////////
struct do_gen {
template <typename DoT>
do_gen2<DoT>
operator[](DoT const& do_) const
{
return do_gen2<DoT>(do_);
}
};
do_gen const do_ = do_gen();
///////////////////////////////////////////////////////////////////////////////
//
// for_composite
//
// This statement has the form:
//
// for_(init, condition, step)
// [
// statement
// ]
//
// Where init, condition, step and statement are all lambda_functors. init
// is executed once before entering the for-loop. The for-loop
// exits once condition evaluates to false. At each loop iteration,
// step and statement is called. The result of this statement is
// void. Note the trailing underscore after for_.
//
///////////////////////////////////////////////////////////////////////////////
template <typename InitT, typename CondT, typename StepT, typename DoT>
struct for_composite {
template <class SigArgs>
struct sig { typedef void type; };
for_composite(
InitT const& init_,
CondT const& cond_,
StepT const& step_,
DoT const& do__)
: init(init_), cond(cond_), step(step_), do_(do__) {}
template <class Ret, CALL_TEMPLATE_ARGS>
Ret
call(CALL_FORMAL_ARGS) const
{
for (init.internal_call(CALL_ACTUAL_ARGS); cond.internal_call(CALL_ACTUAL_ARGS); step.internal_call(CALL_ACTUAL_ARGS))
do_.internal_call(CALL_ACTUAL_ARGS);
}
InitT init; CondT cond; StepT step; DoT do_; // lambda_functors
};
//////////////////////////////////
template <typename InitT, typename CondT, typename StepT>
struct for_gen {
for_gen(
InitT const& init_,
CondT const& cond_,
StepT const& step_)
: init(init_), cond(cond_), step(step_) {}
template <typename DoT>
lambda_functor<for_composite<
typename as_lambda_functor<InitT>::type,
typename as_lambda_functor<CondT>::type,
typename as_lambda_functor<StepT>::type,
typename as_lambda_functor<DoT>::type> >
operator[](DoT const& do_) const
{
typedef for_composite<
typename as_lambda_functor<InitT>::type,
typename as_lambda_functor<CondT>::type,
typename as_lambda_functor<StepT>::type,
typename as_lambda_functor<DoT>::type>
result;
return result(
to_lambda_functor(init),
to_lambda_functor(cond),
to_lambda_functor(step),
to_lambda_functor(do_));
}
InitT init; CondT cond; StepT step;
};
//////////////////////////////////
template <typename InitT, typename CondT, typename StepT>
inline for_gen<InitT, CondT, StepT>
for_(InitT const& init, CondT const& cond, StepT const& step)
{
return for_gen<InitT, CondT, StepT>(init, cond, step);
}
} // lambda
} // boost
#endif // BOOST_LAMBDA_LOOPS_HPP

View File

@@ -0,0 +1,119 @@
// -- numeric.hpp -- Boost Lambda Library -----------------------------------
// Copyright (C) 2002 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2002 Gary Powell (gwpowell@hotmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
#ifndef BOOST_LAMBDA_NUMERIC_HPP
#define BOOST_LAMBDA_NUMERIC_HPP
#include "boost/lambda/core.hpp"
#include <numeric>
namespace boost {
namespace lambda {
namespace ll {
// accumulate ---------------------------------
struct accumulate {
template <class Args>
struct sig {
typedef typename boost::remove_const<
typename boost::tuples::element<3, Args>::type
>::type type;
};
template <class A, class B, class C>
C
operator()(A a, B b, C c) const
{ return ::std::accumulate(a, b, c); }
template <class A, class B, class C, class D>
C
operator()(A a, B b, C c, D d) const
{ return ::std::accumulate(a, b, c, d); }
};
// inner_product ---------------------------------
struct inner_product {
template <class Args>
struct sig {
typedef typename boost::remove_const<
typename boost::tuples::element<4, Args>::type
>::type type;
};
template <class A, class B, class C, class D>
D
operator()(A a, B b, C c, D d) const
{ return ::std::inner_product(a, b, c, d); }
template <class A, class B, class C, class D, class E, class F>
D
operator()(A a, B b, C c, D d, E e, F f) const
{ return ::std::inner_product(a, b, c, d, e, f); }
};
// partial_sum ---------------------------------
struct partial_sum {
template <class Args>
struct sig {
typedef typename boost::remove_const<
typename boost::tuples::element<3, Args>::type
>::type type;
};
template <class A, class B, class C>
C
operator()(A a, B b, C c) const
{ return ::std::partial_sum(a, b, c); }
template <class A, class B, class C, class D>
C
operator()(A a, B b, C c, D d) const
{ return ::std::partial_sum(a, b, c, d); }
};
// adjacent_difference ---------------------------------
struct adjacent_difference {
template <class Args>
struct sig {
typedef typename boost::remove_const<
typename boost::tuples::element<3, Args>::type
>::type type;
};
template <class A, class B, class C>
C
operator()(A a, B b, C c) const
{ return ::std::adjacent_difference(a, b, c); }
template <class A, class B, class C, class D>
C
operator()(A a, B b, C c, D d) const
{ return ::std::adjacent_difference(a, b, c, d); }
};
} // end of ll namespace
} // end of lambda namespace
} // end of boost namespace
#endif

View File

@@ -0,0 +1,508 @@
// Boost Lambda Library -- switch.hpp -----------------------------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// --------------------------------------------------------------------------
#if !defined(BOOST_LAMBDA_SWITCH_HPP)
#define BOOST_LAMBDA_SWITCH_HPP
#include "boost/lambda/core.hpp"
#include "boost/lambda/detail/control_constructs_common.hpp"
#include "boost/preprocessor/enum_shifted_params.hpp"
#include "boost/preprocessor/repeat_2nd.hpp"
#include "boost/preprocessor/tuple.hpp"
namespace boost {
namespace lambda {
// Switch actions
template <int N, class Switch1 = null_type, class Switch2 = null_type,
class Switch3 = null_type, class Switch4 = null_type,
class Switch5 = null_type, class Switch6 = null_type,
class Switch7 = null_type, class Switch8 = null_type,
class Switch9 = null_type>
struct switch_action {};
namespace detail {
// templates to represent special lambda functors for the cases in
// switch statements
template <int Value> struct case_label {};
struct default_label {};
template<class Type> struct switch_case_tag {};
// a normal case is represented as:
// tagged_lambda_functor<switch_case_tag<case_label<N> > >, LambdaFunctor>
// the default case as:
// tagged_lambda_functor<switch_case_tag<default_label> >, LambdaFunctor>
} // end detail
/// create switch_case_tag tagged_lambda_functors
template <int CaseValue, class Arg>
inline const
tagged_lambda_functor<
detail::switch_case_tag<detail::case_label<CaseValue> >,
lambda_functor<Arg>
>
case_statement(const lambda_functor<Arg>& a) {
return
tagged_lambda_functor<
detail::switch_case_tag<detail::case_label<CaseValue> >,
lambda_functor<Arg>
>(a);
}
// No case body case.
template <int CaseValue>
inline const
tagged_lambda_functor<
detail::switch_case_tag<detail::case_label<CaseValue> >,
lambda_functor<
lambda_functor_base<
do_nothing_action,
null_type
>
>
>
case_statement() {
return
tagged_lambda_functor<
detail::switch_case_tag<detail::case_label<CaseValue> >,
lambda_functor<
lambda_functor_base<
do_nothing_action,
null_type
>
>
> () ;
}
// default label
template <class Arg>
inline const
tagged_lambda_functor<
detail::switch_case_tag<detail::default_label>,
lambda_functor<Arg>
>
default_statement(const lambda_functor<Arg>& a) {
return
tagged_lambda_functor<
detail::switch_case_tag<detail::default_label>,
lambda_functor<Arg>
>(a);
}
// default lable, no case body case.
inline const
tagged_lambda_functor<
detail::switch_case_tag<detail::default_label>,
lambda_functor<
lambda_functor_base<
do_nothing_action,
null_type
>
>
>
default_statement() {
return
lambda_functor_base<
do_nothing_action,
null_type
> () ;
}
// Specializations for lambda_functor_base of case_statement -----------------
// 0 case type:
// useless (just the condition part) but provided for completeness.
template<class Args>
class
lambda_functor_base<
switch_action<1>,
Args
>
{
public:
Args args;
template <class SigArgs> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
detail::select(::boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
};
// 1 case type:
// template<class Args, int Case1>
// class
// lambda_functor_base<
// action<
// 2,
// return_void_action<switch_action<detail::case_label<Case1> > >
// >,
// Args
// >
// {
// Args args;
// public:
// explicit lambda_functor_base(const Args& a) : args(a) {}
// template<class RET, class A, class B, class C>
// RET call(A& a, B& b, C& c) const {
// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )
// {
// case Case1:
// detail::select(::boost::tuples::get<1>(args), a, b, c);
// break;
// }
// }
// };
// switch with default being the sole label - doesn't make much sense but
// it is there for completeness
// template<class Args>
// class
// lambda_functor_base<
// action<
// 2,
// return_void_action<switch_action<detail::default_label> >
// >,
// Args
// >
// {
// Args args;
// public:
// explicit lambda_functor_base(const Args& a) : args(a) {}
//
// template<class RET, class A, class B, class C>
// RET call(A& a, B& b, C& c) const {
// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )
// {
// default:
// detail::select(::boost::tuples::get<1>(args), a, b, c);
// break;
// }
// }
// };
// // 2 case type:
// The different specializations are generated with Vesa Karvonen's
// preprocessor library.
// This is just a comment to show what the generated classes look like
// template<class Args, int Case1, int Case2>
// class
// lambda_functor_base<
// action<3,
// return_void_action<
// switch_action<
// detail::case_label<Case1>,
// detail::case_label<Case2>
// >
// >
// >,
// Args
// >
// {
// Args args;
// public:
// explicit lambda_functor_base(const Args& a) : args(a) {}
// template<class RET, class A, class B, class C>
// RET call(A& a, B& b, C& c) const {
// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )
// {
// case Case1:
// detail::select(::boost::tuples::get<1>(args), a, b, c);
// break;
// case Case2:
// detail::select(::boost::tuples::get<2>(args), a, b, c);
// break;
// }
// }
// };
// template<class Args, int Case1>
// class
// lambda_functor_base<
// action<3,
// return_void_action<
// switch_action<
// detail::case_label<Case1>,
// detail::default_label
// >
// >
// >,
// Args
// >
// {
// Args args;
// public:
// explicit lambda_functor_base(const Args& a) : args(a) {}
// template<class RET, class A, class B, class C>
// RET call(A& a, B& b, C& c) const {
// switch( detail::select(::boost::tuples::get<0>(args), a, b, c) )
// {
// case Case1:
// detail::select(::boost::tuples::get<1>(args), a, b, c);
// break;
// default:
// detail::select(::boost::tuples::get<2>(args), a, b, c);
// break;
// }
// }
// };
// -------------------------
// Some helper preprocessor macros ---------------------------------
// BOOST_LAMBDA_A_I_LIST(N, X) is a list of form X0, X1, ..., XN
// BOOST_LAMBDA_A_I_B_LIST(N, X, Y) is a list of form X0 Y, X1 Y, ..., XN Y
#define BOOST_LAMBDA_A_I(z, i, A) \
BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A,i)
#define BOOST_LAMBDA_A_I_B(z, i, T) \
BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,T),i) BOOST_PP_TUPLE_ELEM(2,1,T)
#define BOOST_LAMBDA_A_I_LIST(i, A) \
BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I, A)
#define BOOST_LAMBDA_A_I_B_LIST(i, A, B) \
BOOST_PP_REPEAT(i,BOOST_LAMBDA_A_I_B, (A,B))
// Switch related macros -------------------------------------------
#define BOOST_LAMBDA_SWITCH_CASE_BLOCK(z, N, A) \
case Case##N: \
detail::select(::boost::tuples::get<BOOST_PP_INC(N)>(args), CALL_ACTUAL_ARGS); \
break;
#define BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N) \
BOOST_PP_REPEAT(N, BOOST_LAMBDA_SWITCH_CASE_BLOCK, FOO)
// 2 case type:
#define BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N) \
template<class Args, BOOST_LAMBDA_A_I_LIST(N, int Case)> \
class \
lambda_functor_base< \
switch_action<BOOST_PP_INC(N), \
BOOST_LAMBDA_A_I_B_LIST(N, detail::case_label<Case,>) \
>, \
Args \
> \
{ \
public: \
Args args; \
template <class SigArgs> struct sig { typedef void type; }; \
public: \
explicit lambda_functor_base(const Args& a) : args(a) {} \
\
template<class RET, CALL_TEMPLATE_ARGS> \
RET call(CALL_FORMAL_ARGS) const { \
switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \
{ \
BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(N) \
} \
} \
};
#define BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N) \
template< \
class Args BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) \
BOOST_LAMBDA_A_I_LIST(BOOST_PP_DEC(N), int Case) \
> \
class \
lambda_functor_base< \
switch_action<BOOST_PP_INC(N), \
BOOST_LAMBDA_A_I_B_LIST(BOOST_PP_DEC(N), \
detail::case_label<Case, >) \
BOOST_PP_COMMA_IF(BOOST_PP_DEC(N)) \
detail::default_label \
>, \
Args \
> \
{ \
public: \
Args args; \
template <class SigArgs> struct sig { typedef void type; }; \
public: \
explicit lambda_functor_base(const Args& a) : args(a) {} \
\
template<class RET, CALL_TEMPLATE_ARGS> \
RET call(CALL_FORMAL_ARGS) const { \
switch( detail::select(::boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) ) \
{ \
BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST(BOOST_PP_DEC(N)) \
default: \
detail::select(::boost::tuples::get<N>(args), CALL_ACTUAL_ARGS); \
break; \
} \
} \
};
// switch_statement bind functions -------------------------------------
// The zero argument case, for completeness sake
inline const
lambda_functor<
lambda_functor_base<
do_nothing_action,
null_type
>
>
switch_statement() {
return
lambda_functor_base<
do_nothing_action,
null_type
>
();
}
// 1 argument case, this is useless as well, just the condition part
template <class TestArg>
inline const
lambda_functor<
lambda_functor_base<
switch_action<1>,
tuple<lambda_functor<TestArg> >
>
>
switch_statement(const lambda_functor<TestArg>& a1) {
return
lambda_functor_base<
switch_action<1>,
tuple< lambda_functor<TestArg> >
>
( tuple<lambda_functor<TestArg> >(a1));
}
#define HELPER(z, N, FOO) \
BOOST_PP_COMMA_IF(N) \
BOOST_PP_CAT( \
const tagged_lambda_functor<detail::switch_case_tag<TagData, \
N>) \
BOOST_PP_COMMA() Arg##N>& a##N
#define HELPER_LIST(N) BOOST_PP_REPEAT(N, HELPER, FOO)
#define BOOST_LAMBDA_SWITCH_STATEMENT(N) \
template <class TestArg, \
BOOST_LAMBDA_A_I_LIST(N, class TagData), \
BOOST_LAMBDA_A_I_LIST(N, class Arg)> \
inline const \
lambda_functor< \
lambda_functor_base< \
switch_action<BOOST_PP_INC(N), \
BOOST_LAMBDA_A_I_LIST(N, TagData) \
>, \
tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
> \
> \
switch_statement( \
const lambda_functor<TestArg>& ta, \
HELPER_LIST(N) \
) \
{ \
return \
lambda_functor_base< \
switch_action<BOOST_PP_INC(N), \
BOOST_LAMBDA_A_I_LIST(N, TagData) \
>, \
tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
> \
( tuple<lambda_functor<TestArg>, BOOST_LAMBDA_A_I_LIST(N, Arg)> \
(ta, BOOST_LAMBDA_A_I_LIST(N, a) )); \
}
// Here's the actual generation
#define BOOST_LAMBDA_SWITCH(N) \
BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE(N) \
BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE(N)
// Use this to avoid case 0, these macros work only from case 1 upwards
#define BOOST_LAMBDA_SWITCH_HELPER(z, N, A) \
BOOST_LAMBDA_SWITCH( BOOST_PP_INC(N) )
// Use this to avoid cases 0 and 1, these macros work only from case 2 upwards
#define BOOST_LAMBDA_SWITCH_STATEMENT_HELPER(z, N, A) \
BOOST_LAMBDA_SWITCH_STATEMENT(BOOST_PP_INC(N))
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4065)
#endif
// up to 9 cases supported (counting default:)
BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_HELPER,FOO)
BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_STATEMENT_HELPER,FOO)
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
} // namespace lambda
} // namespace boost
#undef HELPER
#undef HELPER_LIST
#undef BOOST_LAMBDA_SWITCH_HELPER
#undef BOOST_LAMBDA_SWITCH
#undef BOOST_LAMBDA_SWITCH_NO_DEFAULT_CASE
#undef BOOST_LAMBDA_SWITCH_WITH_DEFAULT_CASE
#undef BOOST_LAMBDA_SWITCH_CASE_BLOCK
#undef BOOST_LAMBDA_SWITCH_CASE_BLOCK_LIST
#undef BOOST_LAMBDA_SWITCH_STATEMENT
#undef BOOST_LAMBDA_SWITCH_STATEMENT_HELPER
#endif

View File

@@ -3,6 +3,10 @@
<meta http-equiv="refresh" content="0; URL=../../doc/html/lambda.html">
</head>
<body>
Automatic redirection failed, please go to <a href="../../doc/html/lambda.html">www.boost.org/doc/html/lambda.html</a>
Automatic redirection failed, please go to <a href="../../doc/html/lambda.html">www.boost.org/doc/html/lambda.html</a>&nbsp;<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

15
meta/libraries.json Normal file
View File

@@ -0,0 +1,15 @@
{
"key": "lambda",
"name": "Lambda",
"authors": [
"Jaakko Järvi",
"Gary Powell"
],
"description": "Define small unnamed function objects at the actual call site, and more.",
"category": [
"Function-objects"
],
"maintainers": [
"Jaakko Jarvi <jarvi -at- cs.tamu.edu>"
]
}

View File

@@ -8,52 +8,28 @@
# For more information, see http://www.boost.org/
import testing ;
subproject libs/lambda/test ;
# bring in rules for testing
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
include testing.jam ;
# Make tests run by default.
DEPENDS all : test ;
{
# look in BOOST_ROOT for sources first, just in this Jamfile
local SEARCH_SOURCE = $(BOOST_ROOT) $(SEARCH_SOURCE) ;
test-suite lambda
:
[ run libs/lambda/test/algorithm_test.cpp : : : : ]
[ run libs/lambda/test/bind_tests_simple.cpp : : : : ]
[ run libs/lambda/test/bind_tests_advanced.cpp : : : : ]
[ run libs/lambda/test/bind_tests_simple_f_refs.cpp : : : : ]
[ run libs/lambda/test/bll_and_function.cpp : : : : ]
[ run libs/lambda/test/cast_test.cpp : : : : ]
[ run libs/lambda/test/constructor_tests.cpp : : : : ]
[ run libs/lambda/test/control_structures.cpp : : : : ]
[ run libs/lambda/test/exception_test.cpp : : : : ]
[ run libs/lambda/test/extending_rt_traits.cpp : : : : ]
[ run libs/lambda/test/is_instance_of_test.cpp : : : : ]
[ run libs/lambda/test/member_pointer_test.cpp : : : : ]
[ run libs/lambda/test/operator_tests_simple.cpp : : : : ]
[ run libs/lambda/test/phoenix_control_structures.cpp : : : : ]
[ run libs/lambda/test/switch_construct.cpp : : : : ]
;
}
project
: requirements <toolset>msvc:<asynch-exceptions>on
;
test-suite lambda
: [ run algorithm_test.cpp ]
[ run bind_tests_simple.cpp ]
[ run bind_tests_advanced.cpp ]
[ run bind_tests_simple_f_refs.cpp ]
[ run bll_and_function.cpp ]
[ run cast_test.cpp : : : : lambda_cast_test ]
[ run constructor_tests.cpp ]
[ run control_structures.cpp ]
[ run exception_test.cpp ]
[ run extending_rt_traits.cpp ]
[ run is_instance_of_test.cpp ]
[ run member_pointer_test.cpp ]
[ run operator_tests_simple.cpp ]
[ run phoenix_control_structures.cpp ]
[ run switch_construct.cpp ]
[ run result_of_tests.cpp ]
[ run ret_test.cpp ]
;

4
test/Makefile Executable file → Normal file
View File

@@ -1,7 +1,7 @@
BOOST = ../../..
CXX = gcc
EXTRAFLAGS = -pedantic -Wno-long-long -ftemplate-depth-50
CXX = g++
EXTRAFLAGS = -pedantic -Wno-long-long -Wno-long-double -ftemplate-depth-50
LIBS = -lstdc++
#CXX = KCC

View File

@@ -1,6 +1,6 @@
// bll_and_function.cpp - The Boost Lambda Library -----------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -41,7 +41,7 @@ void test_foreach() {
bind(ll::for_each(), _1, _1 + 20,
protect((sum += _1))));
BOOST_TEST(sum == (199 + 1)/ 2 * 199);
BOOST_CHECK(sum == (199 + 1)/ 2 * 199);
}
// More tests needed (for all algorithms)

View File

@@ -1,7 +1,8 @@
// bind_tests_advanced.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
// Copyright (C) 2010 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -19,6 +20,9 @@
#include "boost/any.hpp"
#include "boost/type_traits/is_reference.hpp"
#include "boost/mpl/assert.hpp"
#include "boost/mpl/if.hpp"
#include <iostream>
@@ -27,7 +31,8 @@
#include <algorithm>
using namespace boost::lambda;
using namespace boost::lambda;
namespace bl = boost::lambda;
int sum_0() { return 0; }
int sum_1(int a) { return a; }
@@ -60,16 +65,16 @@ void test_nested_binds()
bool condition;
condition = true;
BOOST_TEST(bind(bind(&sum_or_product, _1), 1, 2)(condition)==3);
BOOST_TEST(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==5);
BOOST_CHECK(bind(bind(&sum_or_product, _1), 1, 2)(condition)==3);
BOOST_CHECK(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==5);
condition = false;
BOOST_TEST(bind(bind(&sum_or_product, _1), 1, 2)(condition)==2);
BOOST_TEST(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==6);
BOOST_CHECK(bind(bind(&sum_or_product, _1), 1, 2)(condition)==2);
BOOST_CHECK(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==6);
which_one wo;
BOOST_TEST(bind(bind(bind(wo), _1), _2, _3)(condition, j, k)==6);
BOOST_CHECK(bind(bind(bind(wo), _1), _2, _3)(condition, j, k)==6);
return;
@@ -91,7 +96,7 @@ int call_with_100(const F& f) {
// This would result in;
// bind(_1 + 1, _1)(make_const(100)) , which would be a compile time error
return bind(unlambda(f), _1)(make_const(100));
return bl::bind(unlambda(f), _1)(make_const(100));
// for other functors than lambda functors, unlambda has no effect
// (except for making them const)
@@ -109,18 +114,26 @@ void test_unlambda() {
int i = 1;
BOOST_TEST(unlambda(_1 + _2)(i, i) == 2);
BOOST_TEST(unlambda(++var(i))() == 2);
BOOST_TEST(call_with_100(_1 + 1) == 101);
BOOST_CHECK(unlambda(_1 + _2)(i, i) == 2);
BOOST_CHECK(unlambda(++var(i))() == 2);
BOOST_CHECK(call_with_100(_1 + 1) == 101);
BOOST_TEST(call_with_101(_1 + 1) == 102);
BOOST_CHECK(call_with_101(_1 + 1) == 102);
BOOST_TEST(call_with_100(bind(std_functor(std::bind1st(std::plus<int>(), 1)), _1)) == 101);
#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
BOOST_CHECK(call_with_100(bl::bind(std_functor(std::bind1st(std::plus<int>(), 1)), _1)) == 101);
#else
BOOST_CHECK(call_with_100(bl::bind(std_functor(std::bind(std::plus<int>(), 1, std::placeholders::_1)), _1)) == 101);
#endif
// std_functor insturcts LL that the functor defines a result_type typedef
// rather than a sig template.
bind(std_functor(std::plus<int>()), _1, _2)(i, i);
bl::bind(std_functor(std::plus<int>()), _1, _2)(i, i);
}
@@ -200,7 +213,7 @@ void test_protect()
bind(ll::for_each(), _1, _1 + 5,
protect(sum += _1))
);
BOOST_TEST(sum == (1+15)*15/2);
BOOST_CHECK(sum == (1+15)*15/2);
sum = 0;
@@ -208,17 +221,17 @@ void test_protect()
bind(ll::for_each(), _1, _1 + 5,
sum += 1 + protect(_1)) // add element count
);
BOOST_TEST(sum == (1+15)*15/2 + 15);
BOOST_CHECK(sum == (1+15)*15/2 + 15);
(1 + protect(_1))(sum);
int k = 0;
((k += constant(1)) += protect(constant(2)))();
BOOST_TEST(k==1);
BOOST_CHECK(k==1);
k = 0;
((k += constant(1)) += protect(constant(2)))()();
BOOST_TEST(k==3);
BOOST_CHECK(k==3);
// note, the following doesn't work:
@@ -276,10 +289,10 @@ void test_lambda_functors_as_arguments_to_lambda_functors() {
// sum_0() + 7, but rather
// bind(sum_0) + 7, which results in another lambda functor
// (lambda functor + int) and can be called again
BOOST_TEST((_1 + _2)(bind(&sum_0), make_const(7))() == 7);
BOOST_CHECK((_1 + _2)(bind(&sum_0), make_const(7))() == 7);
int i = 3, j = 12;
BOOST_TEST((_1 - _2)(_2, _1)(i, j) == j - i);
BOOST_CHECK((_1 - _2)(_2, _1)(i, j) == j - i);
// also, note that lambda functor are no special case for bind if received
// as a parameter. In oder to be bindable, the functor must
@@ -292,12 +305,12 @@ void test_lambda_functors_as_arguments_to_lambda_functors() {
int a = 5, b = 6;
// Let type deduction find out the return type
BOOST_TEST(bind(_1, _2, _3)(unlambda(_1 + _2), a, b) == 11);
BOOST_CHECK(bind(_1, _2, _3)(unlambda(_1 + _2), a, b) == 11);
//specify it yourself:
BOOST_TEST(bind(_1, _2, _3)(ret<int>(_1 + _2), a, b) == 11);
BOOST_TEST(ret<int>(bind(_1, _2, _3))(_1 + _2, a, b) == 11);
BOOST_TEST(bind<int>(_1, _2, _3)(_1 + _2, a, b) == 11);
BOOST_CHECK(bind(_1, _2, _3)(ret<int>(_1 + _2), a, b) == 11);
BOOST_CHECK(ret<int>(bind(_1, _2, _3))(_1 + _2, a, b) == 11);
BOOST_CHECK(bind<int>(_1, _2, _3)(_1 + _2, a, b) == 11);
bind(_1,1.0)(_1+_1);
return;
@@ -310,10 +323,10 @@ void test_const_parameters() {
// (_1 + _2)(1, 2); // this would fail,
// Either make arguments const:
BOOST_TEST((_1 + _2)(make_const(1), make_const(2)) == 3);
BOOST_CHECK((_1 + _2)(make_const(1), make_const(2)) == 3);
// Or use const_parameters:
BOOST_TEST(const_parameters(_1 + _2)(1, 2) == 3);
BOOST_CHECK(const_parameters(_1 + _2)(1, 2) == 3);
@@ -323,7 +336,7 @@ void test_rvalue_arguments()
{
// Not quite working yet.
// Problems with visual 7.1
// BOOST_TEST((_1 + _2)(1, 2) == 3);
// BOOST_CHECK((_1 + _2)(1, 2) == 3);
}
void test_break_const()
@@ -348,7 +361,56 @@ void test_break_const()
// OLD COMMENT: (_1 += _2)(i, 2) // fails, 2 is a non-const rvalue
// OLD COMMENT: const_parameters(_1 += _2)(i, 2) // fails, side-effect to i
break_const(_1 += _2)(i, 2); // ok
BOOST_TEST(i == 3);
BOOST_CHECK(i == 3);
}
template<class T>
struct func {
template<class Args>
struct sig {
typedef typename boost::tuples::element<1, Args>::type arg1;
// If the argument type is not the same as the expected type,
// return void, which will cause an error. Note that we
// can't just assert that the types are the same, because
// both const and non-const versions can be instantiated
// even though only one is ultimately used.
typedef typename boost::mpl::if_<boost::is_same<arg1, T>,
typename boost::remove_const<arg1>::type,
void
>::type type;
};
template<class U>
U operator()(const U& arg) const {
return arg;
}
};
void test_sig()
{
int i = 1;
BOOST_CHECK(bind(func<int>(), 1)() == 1);
BOOST_CHECK(bind(func<const int>(), _1)(static_cast<const int&>(i)) == 1);
BOOST_CHECK(bind(func<int>(), _1)(i) == 1);
}
class base {
public:
virtual int foo() = 0;
};
class derived : public base {
public:
virtual int foo() {
return 1;
}
};
void test_abstract()
{
derived d;
base& b = d;
BOOST_CHECK(bind(&base::foo, var(b))() == 1);
BOOST_CHECK(bind(&base::foo, *_1)(&b) == 1);
}
int test_main(int, char *[]) {
@@ -360,17 +422,7 @@ int test_main(int, char *[]) {
test_const_parameters();
test_rvalue_arguments();
test_break_const();
test_sig();
test_abstract();
return 0;
}

View File

@@ -1,6 +1,6 @@
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -18,9 +18,7 @@
#include <iostream>
using namespace std;
using namespace boost::lambda;
using namespace boost::lambda;
int sum_of_args_0() { return 0; }
@@ -65,79 +63,96 @@ void test_member_functions()
BOOST_TEST(bind(&A::add, ref(a), _1)(i) == 11);
BOOST_TEST(bind(&A::add, &a, _1)(i) == 11);
BOOST_TEST(bind(&A::add, _1, 1)(a) == 11);
BOOST_TEST(bind(&A::add, _1, 1)(make_const(&a)) == 11);
BOOST_CHECK(bind(&A::add, ref(a), _1)(i) == 11);
BOOST_CHECK(bind(&A::add, &a, _1)(i) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(a) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(make_const(&a)) == 11);
BOOST_TEST(bind(&A::add2, _1, 1, 1)(a) == 12);
BOOST_TEST(bind(&A::add3, _1, 1, 1, 1)(a) == 13);
BOOST_TEST(bind(&A::add4, _1, 1, 1, 1, 1)(a) == 14);
BOOST_TEST(bind(&A::add5, _1, 1, 1, 1, 1, 1)(a) == 15);
BOOST_TEST(bind(&A::add6, _1, 1, 1, 1, 1, 1, 1)(a) == 16);
BOOST_TEST(bind(&A::add7, _1, 1, 1, 1, 1, 1, 1, 1)(a) == 17);
BOOST_TEST(bind(&A::add8, _1, 1, 1, 1, 1, 1, 1, 1, 1)(a) == 18);
BOOST_CHECK(bind(&A::add2, _1, 1, 1)(a) == 12);
BOOST_CHECK(bind(&A::add3, _1, 1, 1, 1)(a) == 13);
BOOST_CHECK(bind(&A::add4, _1, 1, 1, 1, 1)(a) == 14);
BOOST_CHECK(bind(&A::add5, _1, 1, 1, 1, 1, 1)(a) == 15);
BOOST_CHECK(bind(&A::add6, _1, 1, 1, 1, 1, 1, 1)(a) == 16);
BOOST_CHECK(bind(&A::add7, _1, 1, 1, 1, 1, 1, 1, 1)(a) == 17);
BOOST_CHECK(bind(&A::add8, _1, 1, 1, 1, 1, 1, 1, 1, 1)(a) == 18);
// This should fail, as lambda functors store arguments as const
// bind(&A::add, a, _1);
}
struct B {
B(int n) : i(n) {};
int i;
};
void test_data_members()
{
using boost::ref;
B b(10);
BOOST_CHECK(bind(&B::i, ref(b))() == 10);
BOOST_CHECK(bind(&B::i, b)() == 10);
BOOST_CHECK(bind(&B::i, _1)(b) == 10);
BOOST_CHECK(bind(&B::i, _1)(B(11)) == 11);
bind(&B::i, ref(b))() = 1;
BOOST_CHECK(b.i == 1);
}
int test_main(int, char *[]) {
int i = 1; int j = 2; int k = 3;
int result;
// bind all parameters
BOOST_TEST(bind(&sum_of_args_0)()==0);
BOOST_TEST(bind(&sum_of_args_1, 1)()==1);
BOOST_TEST(bind(&sum_of_args_2, 1, 2)()==3);
BOOST_TEST(bind(&sum_of_args_3, 1, 2, 3)()==6);
BOOST_TEST(bind(&sum_of_args_4, 1, 2, 3, 4)()==10);
BOOST_TEST(bind(&sum_of_args_5, 1, 2, 3, 4, 5)()==15);
BOOST_TEST(bind(&sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
BOOST_TEST(bind(&sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
BOOST_TEST(bind(&sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
BOOST_TEST(bind(&sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
BOOST_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, 1)()==1);
BOOST_CHECK(bind(&sum_of_args_2, 1, 2)()==3);
BOOST_CHECK(bind(&sum_of_args_3, 1, 2, 3)()==6);
BOOST_CHECK(bind(&sum_of_args_4, 1, 2, 3, 4)()==10);
BOOST_CHECK(bind(&sum_of_args_5, 1, 2, 3, 4, 5)()==15);
BOOST_CHECK(bind(&sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
BOOST_CHECK(bind(&sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
BOOST_CHECK(bind(&sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
BOOST_CHECK(bind(&sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
// first parameter open
BOOST_TEST(bind(&sum_of_args_0)()==0);
BOOST_TEST(bind(&sum_of_args_1, _1)(i)==1);
BOOST_TEST(bind(&sum_of_args_2, _1, 2)(i)==3);
BOOST_TEST(bind(&sum_of_args_3, _1, 2, 3)(i)==6);
BOOST_TEST(bind(&sum_of_args_4, _1, 2, 3, 4)(i)==10);
BOOST_TEST(bind(&sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
BOOST_TEST(bind(&sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
BOOST_TEST(bind(&sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
BOOST_TEST(bind(&sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
BOOST_TEST(bind(&sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
BOOST_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(&sum_of_args_2, _1, 2)(i)==3);
BOOST_CHECK(bind(&sum_of_args_3, _1, 2, 3)(i)==6);
BOOST_CHECK(bind(&sum_of_args_4, _1, 2, 3, 4)(i)==10);
BOOST_CHECK(bind(&sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
BOOST_CHECK(bind(&sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
BOOST_CHECK(bind(&sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
BOOST_CHECK(bind(&sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
BOOST_CHECK(bind(&sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
// two open arguments
BOOST_TEST(bind(&sum_of_args_0)()==0);
BOOST_TEST(bind(&sum_of_args_1, _1)(i)==1);
BOOST_TEST(bind(&sum_of_args_2, _1, _2)(i, j)==3);
BOOST_TEST(bind(&sum_of_args_3, _1, _2, 3)(i, j)==6);
BOOST_TEST(bind(&sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
BOOST_TEST(bind(&sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
BOOST_TEST(bind(&sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
BOOST_TEST(bind(&sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
BOOST_TEST(bind(&sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
BOOST_TEST(bind(&sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
BOOST_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(&sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(&sum_of_args_3, _1, _2, 3)(i, j)==6);
BOOST_CHECK(bind(&sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
BOOST_CHECK(bind(&sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
BOOST_CHECK(bind(&sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
BOOST_CHECK(bind(&sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
BOOST_CHECK(bind(&sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
BOOST_CHECK(bind(&sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
// three open arguments
BOOST_TEST(bind(&sum_of_args_0)()==0);
BOOST_TEST(bind(&sum_of_args_1, _1)(i)==1);
BOOST_TEST(bind(&sum_of_args_2, _1, _2)(i, j)==3);
BOOST_TEST(bind(&sum_of_args_3, _1, _2, _3)(i, j, k)==6);
BOOST_TEST(bind(&sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
BOOST_TEST(bind(&sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
BOOST_TEST(bind(&sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
BOOST_TEST(bind(&sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
BOOST_TEST(bind(&sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
BOOST_TEST(bind(&sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
BOOST_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(&sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(&sum_of_args_3, _1, _2, _3)(i, j, k)==6);
BOOST_CHECK(bind(&sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
BOOST_CHECK(bind(&sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
BOOST_CHECK(bind(&sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
BOOST_CHECK(bind(&sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
BOOST_CHECK(bind(&sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
BOOST_CHECK(bind(&sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
// function compositions with bind
BOOST_TEST(bind(&sum_of_args_3, bind(&sum_of_args_2, _1, 2), 2, 3)(i)==8);
BOOST_TEST(
BOOST_CHECK(bind(&sum_of_args_3, bind(&sum_of_args_2, _1, 2), 2, 3)(i)==8);
BOOST_CHECK(
bind(&sum_of_args_9,
bind(&sum_of_args_0), // 0
bind(&sum_of_args_1, _1), // 1
@@ -163,7 +178,7 @@ int test_main(int, char *[]) {
_3,
4)
)(i, j, k);
BOOST_TEST(result == 12);
BOOST_CHECK(result == 12);
test_member_functions();

View File

@@ -1,6 +1,6 @@
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -18,9 +18,7 @@
#include <iostream>
using namespace std;
using namespace boost::lambda;
using namespace boost::lambda;
int sum_of_args_0() { return 0; }
@@ -50,10 +48,10 @@ void test_member_functions()
A a(10);
int i = 1;
BOOST_TEST(bind(&A::add, ref(a), _1)(i) == 11);
BOOST_TEST(bind(&A::add, &a, _1)(i) == 11);
BOOST_TEST(bind(&A::add, _1, 1)(a) == 11);
BOOST_TEST(bind(&A::add, _1, 1)(make_const(&a)) == 11);
BOOST_CHECK(bind(&A::add, ref(a), _1)(i) == 11);
BOOST_CHECK(bind(&A::add, &a, _1)(i) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(a) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(make_const(&a)) == 11);
// This should fail, as lambda functors store arguments as const
// bind(&A::add, a, _1);
@@ -66,56 +64,56 @@ int test_main(int, char *[]) {
// bind all parameters
BOOST_TEST(bind(sum_of_args_0)()==0);
BOOST_TEST(bind(sum_of_args_1, 1)()==1);
BOOST_TEST(bind(sum_of_args_2, 1, 2)()==3);
BOOST_TEST(bind(sum_of_args_3, 1, 2, 3)()==6);
BOOST_TEST(bind(sum_of_args_4, 1, 2, 3, 4)()==10);
BOOST_TEST(bind(sum_of_args_5, 1, 2, 3, 4, 5)()==15);
BOOST_TEST(bind(sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
BOOST_TEST(bind(sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
BOOST_TEST(bind(sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
BOOST_TEST(bind(sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
BOOST_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, 1)()==1);
BOOST_CHECK(bind(sum_of_args_2, 1, 2)()==3);
BOOST_CHECK(bind(sum_of_args_3, 1, 2, 3)()==6);
BOOST_CHECK(bind(sum_of_args_4, 1, 2, 3, 4)()==10);
BOOST_CHECK(bind(sum_of_args_5, 1, 2, 3, 4, 5)()==15);
BOOST_CHECK(bind(sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
BOOST_CHECK(bind(sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
BOOST_CHECK(bind(sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
BOOST_CHECK(bind(sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
// first parameter open
BOOST_TEST(bind(sum_of_args_0)()==0);
BOOST_TEST(bind(sum_of_args_1, _1)(i)==1);
BOOST_TEST(bind(sum_of_args_2, _1, 2)(i)==3);
BOOST_TEST(bind(sum_of_args_3, _1, 2, 3)(i)==6);
BOOST_TEST(bind(sum_of_args_4, _1, 2, 3, 4)(i)==10);
BOOST_TEST(bind(sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
BOOST_TEST(bind(sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
BOOST_TEST(bind(sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
BOOST_TEST(bind(sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
BOOST_TEST(bind(sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
BOOST_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(sum_of_args_2, _1, 2)(i)==3);
BOOST_CHECK(bind(sum_of_args_3, _1, 2, 3)(i)==6);
BOOST_CHECK(bind(sum_of_args_4, _1, 2, 3, 4)(i)==10);
BOOST_CHECK(bind(sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
BOOST_CHECK(bind(sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
BOOST_CHECK(bind(sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
BOOST_CHECK(bind(sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
BOOST_CHECK(bind(sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
// two open arguments
BOOST_TEST(bind(sum_of_args_0)()==0);
BOOST_TEST(bind(sum_of_args_1, _1)(i)==1);
BOOST_TEST(bind(sum_of_args_2, _1, _2)(i, j)==3);
BOOST_TEST(bind(sum_of_args_3, _1, _2, 3)(i, j)==6);
BOOST_TEST(bind(sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
BOOST_TEST(bind(sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
BOOST_TEST(bind(sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
BOOST_TEST(bind(sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
BOOST_TEST(bind(sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
BOOST_TEST(bind(sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
BOOST_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(sum_of_args_3, _1, _2, 3)(i, j)==6);
BOOST_CHECK(bind(sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
BOOST_CHECK(bind(sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
BOOST_CHECK(bind(sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
BOOST_CHECK(bind(sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
BOOST_CHECK(bind(sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
BOOST_CHECK(bind(sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
// three open arguments
BOOST_TEST(bind(sum_of_args_0)()==0);
BOOST_TEST(bind(sum_of_args_1, _1)(i)==1);
BOOST_TEST(bind(sum_of_args_2, _1, _2)(i, j)==3);
BOOST_TEST(bind(sum_of_args_3, _1, _2, _3)(i, j, k)==6);
BOOST_TEST(bind(sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
BOOST_TEST(bind(sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
BOOST_TEST(bind(sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
BOOST_TEST(bind(sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
BOOST_TEST(bind(sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
BOOST_TEST(bind(sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
BOOST_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(sum_of_args_3, _1, _2, _3)(i, j, k)==6);
BOOST_CHECK(bind(sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
BOOST_CHECK(bind(sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
BOOST_CHECK(bind(sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
BOOST_CHECK(bind(sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
BOOST_CHECK(bind(sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
BOOST_CHECK(bind(sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
// function compositions with bind
BOOST_TEST(bind(sum_of_args_3, bind(sum_of_args_2, _1, 2), 2, 3)(i)==8);
BOOST_TEST(
BOOST_CHECK(bind(sum_of_args_3, bind(sum_of_args_2, _1, 2), 2, 3)(i)==8);
BOOST_CHECK(
bind(sum_of_args_9,
bind(sum_of_args_0), // 0
bind(sum_of_args_1, _1), // 1
@@ -141,7 +139,7 @@ int test_main(int, char *[]) {
_3,
4)
)(i, j, k);
BOOST_TEST(result == 12);
BOOST_CHECK(result == 12);
test_member_functions();

View File

@@ -1,6 +1,6 @@
// bll_and_function.cpp - The Boost Lambda Library -----------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -32,12 +32,12 @@ void test_function() {
boost::function<int (int, int)> f;
f = _1 + _2;
BOOST_TEST(f(1, 2)== 3);
BOOST_CHECK(f(1, 2)== 3);
int i=1; int j=2;
boost::function<int& (int&, int)> g = _1 += _2;
g(i, j);
BOOST_TEST(i==3);
BOOST_CHECK(i==3);
@@ -45,7 +45,7 @@ void test_function() {
*sum = 0;
boost::function<int& (int)> counter = *sum += _1;
counter(5); // ok, sum* = 5;
BOOST_TEST(*sum == 5);
BOOST_CHECK(*sum == 5);
delete sum;
// The next statement would lead to a dangling reference

View File

@@ -1,6 +1,6 @@
// cast_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -29,7 +29,7 @@ class base {
public:
virtual std::string class_name() const { return "const base"; }
virtual std::string class_name() { return "base"; }
virtual ~base() {}
};
class derived : public base {
@@ -53,46 +53,46 @@ void do_test() {
(var(b) = ll_static_cast<base *>(p_derived))();
(var(d) = ll_static_cast<derived *>(b))();
BOOST_TEST(b->class_name() == "derived");
BOOST_TEST(d->class_name() == "derived");
BOOST_CHECK(b->class_name() == "derived");
BOOST_CHECK(d->class_name() == "derived");
(var(b) = ll_dynamic_cast<derived *>(b))();
BOOST_TEST(b != 0);
BOOST_TEST(b->class_name() == "derived");
BOOST_CHECK(b != 0);
BOOST_CHECK(b->class_name() == "derived");
(var(d) = ll_dynamic_cast<derived *>(p_base))();
BOOST_TEST(d == 0);
BOOST_CHECK(d == 0);
const derived* p_const_derived = p_derived;
BOOST_TEST(p_const_derived->class_name() == "const derived");
BOOST_CHECK(p_const_derived->class_name() == "const derived");
(var(d) = ll_const_cast<derived *>(p_const_derived))();
BOOST_TEST(d->class_name() == "derived");
BOOST_CHECK(d->class_name() == "derived");
int i = 10;
char* cp = reinterpret_cast<char*>(&i);
int* ip;
(var(ip) = ll_reinterpret_cast<int *>(cp))();
BOOST_TEST(*ip == 10);
BOOST_CHECK(*ip == 10);
// typeid
BOOST_TEST(string(ll_typeid(d)().name()) == string(typeid(d).name()));
BOOST_CHECK(string(ll_typeid(d)().name()) == string(typeid(d).name()));
// sizeof
BOOST_TEST(ll_sizeof(_1)(p_derived) == sizeof(p_derived));
BOOST_TEST(ll_sizeof(_1)(*p_derived) == sizeof(*p_derived));
BOOST_TEST(ll_sizeof(_1)(p_base) == sizeof(p_base));
BOOST_TEST(ll_sizeof(_1)(*p_base) == sizeof(*p_base));
BOOST_CHECK(ll_sizeof(_1)(p_derived) == sizeof(p_derived));
BOOST_CHECK(ll_sizeof(_1)(*p_derived) == sizeof(*p_derived));
BOOST_CHECK(ll_sizeof(_1)(p_base) == sizeof(p_base));
BOOST_CHECK(ll_sizeof(_1)(*p_base) == sizeof(*p_base));
int an_array[100];
BOOST_TEST(ll_sizeof(_1)(an_array) == 100 * sizeof(int));
BOOST_CHECK(ll_sizeof(_1)(an_array) == 100 * sizeof(int));
delete p_derived;
delete p_base;

View File

@@ -1,6 +1,6 @@
// constructor_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -24,8 +24,12 @@
#include <algorithm>
#include <vector>
#ifdef BOOST_MSVC
#pragma warning(disable:4512)
#endif
using namespace boost::lambda;
using namespace std;
namespace bl = boost::lambda;
template<class T>
bool check_tuple(int n, const T& t)
@@ -34,7 +38,7 @@ bool check_tuple(int n, const T& t)
}
template <>
bool check_tuple(int n, const null_type& ) { return true; }
bool check_tuple(int /*n*/, const null_type& ) { return true; }
void constructor_all_lengths()
@@ -45,63 +49,63 @@ void constructor_all_lengths()
bind(constructor<tuple<int> >(),
1)()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int> >(),
1, 2)()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int> >(),
1, 2, 3)()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int> >(),
1, 2, 3, 4)()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int> >(),
1, 2, 3, 4, 5)()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6)()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7)()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8)()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8, 9)()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
}
@@ -113,63 +117,63 @@ void new_ptr_all_lengths()
*(bind(new_ptr<tuple<int> >(),
1))()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int> >(),
1, 2))()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int> >(),
1, 2, 3))()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int> >(),
1, 2, 3, 4))()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int> >(),
1, 2, 3, 4, 5))()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6))()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7))()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8))()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8, 9))()
);
BOOST_TEST(ok);
BOOST_CHECK(ok);
}
@@ -183,17 +187,17 @@ public:
void test_destructor ()
{
char space[sizeof(is_destructor_called)];
bool flag;
bool flag = false;
is_destructor_called* idc = new(space) is_destructor_called(flag);
BOOST_TEST(flag == false);
BOOST_CHECK(flag == false);
bind(destructor(), _1)(idc);
BOOST_TEST(flag == true);
BOOST_CHECK(flag == true);
idc = new(space) is_destructor_called(flag);
BOOST_TEST(flag == false);
BOOST_CHECK(flag == false);
bind(destructor(), _1)(*idc);
BOOST_TEST(flag == true);
BOOST_CHECK(flag == true);
}
@@ -208,18 +212,18 @@ int count_deletes::count = 0;
void test_news_and_deletes ()
{
int* i[10];
for_each(i, i+10, _1 = bind(new_ptr<int>(), 2));
std::for_each(i, i+10, _1 = bind(new_ptr<int>(), 2));
int count_errors = 0;
for_each(i, i+10, (*_1 == 2) || ++var(count_errors));
BOOST_TEST(count_errors == 0);
std::for_each(i, i+10, (*_1 == 2) || ++var(count_errors));
BOOST_CHECK(count_errors == 0);
count_deletes* ct[10];
for_each(ct, ct+10, _1 = bind(new_ptr<count_deletes>()));
std::for_each(ct, ct+10, _1 = bind(new_ptr<count_deletes>()));
count_deletes::count = 0;
for_each(ct, ct+10, bind(delete_ptr(), _1));
BOOST_TEST(count_deletes::count == 10);
std::for_each(ct, ct+10, bind(delete_ptr(), _1));
BOOST_CHECK(count_deletes::count == 10);
}
@@ -230,22 +234,22 @@ void test_array_new_and_delete()
count_deletes::count = 0;
bind(delete_array(), _1)(c);
BOOST_TEST(count_deletes::count == 5);
BOOST_CHECK(count_deletes::count == 5);
}
void delayed_construction()
{
vector<int> x(3);
vector<int> y(3);
std::vector<int> x(3);
std::vector<int> y(3);
fill(x.begin(), x.end(), 0);
fill(y.begin(), y.end(), 1);
std::fill(x.begin(), x.end(), 0);
std::fill(y.begin(), y.end(), 1);
vector<pair<int, int> > v;
std::vector<std::pair<int, int> > v;
transform(x.begin(), x.end(), y.begin(), back_inserter(v),
bind(constructor<pair<int, int> >(), _1, _2) );
std::transform(x.begin(), x.end(), y.begin(), std::back_inserter(v),
bl::bind(constructor<std::pair<int, int> >(), _1, _2) );
}
int test_main(int, char *[]) {

View File

@@ -1,6 +1,6 @@
// -- control_structures.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -50,41 +50,41 @@ void simple_loops() {
int i;
int arithmetic_series = 0;
for_loop(_1 = 0, _1 < 10, _1++, arithmetic_series += _1)(i);
BOOST_TEST(arithmetic_series == 45);
BOOST_CHECK(arithmetic_series == 45);
// no body case
for_loop(boost::lambda::var(i) = 0, boost::lambda::var(i) < 100, ++boost::lambda::var(i))();
BOOST_TEST(i == 100);
BOOST_CHECK(i == 100);
// while loops -------------------------------------------------------
int a = 0, b = 0, c = 0;
while_loop((_1 + _2) >= (_1 * _2), (++_1, ++_2, ++_3))(a, b, c);
BOOST_TEST(c == 3);
BOOST_CHECK(c == 3);
int count;
count = 0; i = 0;
while_loop(_1++ < 10, ++boost::lambda::var(count))(i);
BOOST_TEST(count == 10);
BOOST_CHECK(count == 10);
// note that the first parameter of do_while_loop is the condition
count = 0; i = 0;
do_while_loop(_1++ < 10, ++boost::lambda::var(count))(i);
BOOST_TEST(count == 11);
BOOST_CHECK(count == 11);
a = 0;
do_while_loop(constant(false), _1++)(a);
BOOST_TEST(a == 1);
BOOST_CHECK(a == 1);
// no body cases
a = 40; b = 30;
while_loop(--_1 > _2)(a, b);
BOOST_TEST(a == b);
BOOST_CHECK(a == b);
// (the no body case for do_while_loop is pretty redundant)
a = 40; b = 30;
do_while_loop(--_1 > _2)(a, b);
BOOST_TEST(a == b);
BOOST_CHECK(a == b);
}
@@ -93,25 +93,25 @@ void simple_ifs () {
int value = 42;
if_then(_1 < 0, _1 = 0)(value);
BOOST_TEST(value == 42);
BOOST_CHECK(value == 42);
value = -42;
if_then(_1 < 0, _1 = -_1)(value);
BOOST_TEST(value == 42);
BOOST_CHECK(value == 42);
int min;
if_then_else(_1 < _2, boost::lambda::var(min) = _1, boost::lambda::var(min) = _2)
(make_const(1), make_const(2));
BOOST_TEST(min == 1);
BOOST_CHECK(min == 1);
if_then_else(_1 < _2, boost::lambda::var(min) = _1, boost::lambda::var(min) = _2)
(make_const(5), make_const(3));
BOOST_TEST(min == 3);
BOOST_CHECK(min == 3);
int x, y;
x = -1; y = 1;
BOOST_TEST(if_then_else_return(_1 < _2, _2, _1)(x, y) == (std::max)(x ,y));
BOOST_TEST(if_then_else_return(_1 < _2, _2, _1)(y, x) == (std::max)(x ,y));
BOOST_CHECK(if_then_else_return(_1 < _2, _2, _1)(x, y) == (std::max)(x ,y));
BOOST_CHECK(if_then_else_return(_1 < _2, _2, _1)(y, x) == (std::max)(x ,y));
}

View File

@@ -1,6 +1,6 @@
// -- exception_test.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -29,7 +29,7 @@ using namespace boost::lambda;
using namespace std;
// to prevent unused variables warnings
template <class T> void dummy(const T& t) {}
template <class T> void dummy(const T&) {}
void erroneous_exception_related_lambda_expressions() {
@@ -98,7 +98,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 1);
BOOST_CHECK(ecount == 1);
ecount = 0;
for(int i=1; i<=2; i++)
@@ -113,7 +113,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 2);
BOOST_CHECK(ecount == 2);
ecount = 0;
for(int i=1; i<=3; i++)
@@ -131,7 +131,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 3);
BOOST_CHECK(ecount == 3);
ecount = 0;
for(int i=1; i<=4; i++)
@@ -152,7 +152,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 4);
BOOST_CHECK(ecount == 4);
ecount = 0;
for(int i=1; i<=5; i++)
@@ -176,7 +176,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 5);
BOOST_CHECK(ecount == 5);
ecount = 0;
for(int i=1; i<=6; i++)
@@ -203,7 +203,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 6);
BOOST_CHECK(ecount == 6);
ecount = 0;
for(int i=1; i<=7; i++)
@@ -233,7 +233,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 7);
BOOST_CHECK(ecount == 7);
ecount = 0;
for(int i=1; i<=8; i++)
@@ -266,7 +266,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 8);
BOOST_CHECK(ecount == 8);
ecount = 0;
for(int i=1; i<=9; i++)
@@ -302,7 +302,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 9);
BOOST_CHECK(ecount == 9);
// with catch(...) blocks
@@ -317,7 +317,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 1);
BOOST_CHECK(ecount == 1);
ecount = 0;
for(int i=1; i<=2; i++)
@@ -332,7 +332,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 2);
BOOST_CHECK(ecount == 2);
ecount = 0;
for(int i=1; i<=3; i++)
@@ -350,7 +350,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 3);
BOOST_CHECK(ecount == 3);
ecount = 0;
for(int i=1; i<=4; i++)
@@ -371,7 +371,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 4);
BOOST_CHECK(ecount == 4);
ecount = 0;
for(int i=1; i<=5; i++)
@@ -395,7 +395,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 5);
BOOST_CHECK(ecount == 5);
ecount = 0;
for(int i=1; i<=6; i++)
@@ -422,7 +422,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 6);
BOOST_CHECK(ecount == 6);
ecount = 0;
for(int i=1; i<=7; i++)
@@ -452,7 +452,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 7);
BOOST_CHECK(ecount == 7);
ecount = 0;
for(int i=1; i<=8; i++)
@@ -485,7 +485,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 8);
BOOST_CHECK(ecount == 8);
ecount = 0;
for(int i=1; i<=9; i++)
@@ -521,7 +521,7 @@ void test_different_number_of_catch_blocks() {
)
)(i);
}
BOOST_TEST(ecount == 9);
BOOST_CHECK(ecount == 9);
}
void test_empty_catch_blocks() {
@@ -551,7 +551,7 @@ void return_type_matching() {
int i = 1;
BOOST_TEST(
BOOST_CHECK(
try_catch(
_1 + 1,
@@ -575,14 +575,14 @@ void return_type_matching() {
make_void(_1 += 1),
catch_exception<char>(_e) // since try is void, catch can return anything
)(i);
BOOST_TEST(i == 2);
BOOST_CHECK(i == 2);
try_catch(
(_1 += 1, throw_exception('a')),
catch_exception<char>(_e) // since try throws, it is void,
// so catch can return anything
)(i);
BOOST_TEST(i == 3);
BOOST_CHECK(i == 3);
char a = 'a';
try_catch(
@@ -592,7 +592,7 @@ void return_type_matching() {
),
catch_exception<char>( _1 = _e )
)(a);
BOOST_TEST(a == 'b');
BOOST_CHECK(a == 'b');
}
int test_main(int, char *[]) {
@@ -603,13 +603,13 @@ int test_main(int, char *[]) {
return_type_matching();
test_empty_catch_blocks();
}
catch (int x)
catch (int)
{
BOOST_TEST(false);
BOOST_CHECK(false);
}
catch(...)
{
BOOST_TEST(false);
BOOST_CHECK(false);
}

View File

@@ -1,6 +1,6 @@
// extending_return_type_traits.cpp -- The Boost Lambda Library --------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -16,6 +16,7 @@
#include "boost/lambda/bind.hpp"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/detail/suppress_unused.hpp"
#include <iostream>
@@ -23,6 +24,8 @@
#include <algorithm>
using boost::lambda::detail::suppress_unused_variable_warnings;
class A {};
class B {};
@@ -81,7 +84,7 @@ struct plain_return_type_1<other_action<contentsof_action>, A> {
} // lambda
} // boost
void ok(B b) {}
void ok(B /*b*/) {}
void test_unary_operators()
{
@@ -96,7 +99,7 @@ void test_unary_operators()
ok((&_1)(a));
ok((*_1)(a));
BOOST_TEST((*_1)(make_const(&i)) == 1);
BOOST_CHECK((*_1)(make_const(&i)) == 1);
}
class X {};
@@ -127,7 +130,7 @@ class my_vector {};
template<class A, class B>
my_vector<typename return_type_2<arithmetic_action<plus_action>, A&, B&>::type>
operator+(const my_vector<A>& a, const my_vector<B>& b)
operator+(const my_vector<A>& /*a*/, const my_vector<B>& /*b*/)
{
typedef typename
return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
@@ -175,8 +178,8 @@ Z operator^=( X&, const Y&) { return Z(); }
// assignment
class Assign {
public:
void operator=(const Assign& a) {}
X operator[](const int& i) { return X(); }
void operator=(const Assign& /*a*/) {}
X operator[](const int& /*i*/) { return X(); }
};
@@ -329,9 +332,16 @@ void test_binary_operators() {
XX dummy3 = (_1 * _2)(vxx, vyy);
VV dummy4 = (_1 * _2)(cvxx, cvyy);
suppress_unused_variable_warnings(dummy1);
suppress_unused_variable_warnings(dummy2);
suppress_unused_variable_warnings(dummy3);
suppress_unused_variable_warnings(dummy4);
my_vector<int> v1; my_vector<double> v2;
my_vector<double> d = (_1 + _2)(v1, v2);
suppress_unused_variable_warnings(d);
// bitwise
(_1 << _2)(x, y);

View File

@@ -1,6 +1,6 @@
// is_instance_of_test.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -53,25 +53,25 @@ using boost::lambda::is_instance_of_3;
using boost::lambda::is_instance_of_4;
BOOST_TEST((is_instance_of_1<B1, A1>::value == true));
BOOST_TEST((is_instance_of_1<A1<float>, A1>::value == true));
BOOST_TEST((is_instance_of_1<int, A1>::value == false));
BOOST_TEST((is_instance_of_1<C1, A1>::value == false));
BOOST_CHECK((is_instance_of_1<B1, A1>::value == true));
BOOST_CHECK((is_instance_of_1<A1<float>, A1>::value == true));
BOOST_CHECK((is_instance_of_1<int, A1>::value == false));
BOOST_CHECK((is_instance_of_1<C1, A1>::value == false));
BOOST_TEST((is_instance_of_2<B2, A2>::value == true));
BOOST_TEST((is_instance_of_2<A2<int, float>, A2>::value == true));
BOOST_TEST((is_instance_of_2<int, A2>::value == false));
BOOST_TEST((is_instance_of_2<C2, A2>::value == false));
BOOST_CHECK((is_instance_of_2<B2, A2>::value == true));
BOOST_CHECK((is_instance_of_2<A2<int, float>, A2>::value == true));
BOOST_CHECK((is_instance_of_2<int, A2>::value == false));
BOOST_CHECK((is_instance_of_2<C2, A2>::value == false));
BOOST_TEST((is_instance_of_3<B3, A3>::value == true));
BOOST_TEST((is_instance_of_3<A3<int, float, char>, A3>::value == true));
BOOST_TEST((is_instance_of_3<int, A3>::value == false));
BOOST_TEST((is_instance_of_3<C3, A3>::value == false));
BOOST_CHECK((is_instance_of_3<B3, A3>::value == true));
BOOST_CHECK((is_instance_of_3<A3<int, float, char>, A3>::value == true));
BOOST_CHECK((is_instance_of_3<int, A3>::value == false));
BOOST_CHECK((is_instance_of_3<C3, A3>::value == false));
BOOST_TEST((is_instance_of_4<B4, A4>::value == true));
BOOST_TEST((is_instance_of_4<A4<int, float, char, double>, A4>::value == true));
BOOST_TEST((is_instance_of_4<int, A4>::value == false));
BOOST_TEST((is_instance_of_4<C4, A4>::value == false));
BOOST_CHECK((is_instance_of_4<B4, A4>::value == true));
BOOST_CHECK((is_instance_of_4<A4<int, float, char, double>, A4>::value == true));
BOOST_CHECK((is_instance_of_4<int, A4>::value == false));
BOOST_CHECK((is_instance_of_4<C4, A4>::value == false));
return 0;

30
test/istreambuf_test.cpp Normal file
View File

@@ -0,0 +1,30 @@
// istreambuf_test - test lambda function objects with istreambuf_iterator
//
// Copyright (c) 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/lambda/lambda.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <iterator>
#include <sstream>
#include <algorithm>
int main()
{
using namespace boost::lambda;
std::stringstream is( "ax2" );
std::istreambuf_iterator<char> b2( is );
std::istreambuf_iterator<char> e2;
std::istreambuf_iterator<char> i = std::find_if( b2, e2, _1 == 'x' );
BOOST_TEST( *i == 'x' );
BOOST_TEST( std::distance( i, e2 ) == 2 );
return boost::report_errors();
}

View File

@@ -1,6 +1,6 @@
// member_pointer_test.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -50,65 +50,65 @@ void pointer_to_data_member_tests() {
// int i = 0;
my_struct *y = &x;
BOOST_TEST((_1 ->* &my_struct::mem)(y) == 3);
BOOST_CHECK((_1 ->* &my_struct::mem)(y) == 3);
(_1 ->* &my_struct::mem)(y) = 4;
BOOST_TEST(x.mem == 4);
BOOST_CHECK(x.mem == 4);
((_1 ->* &my_struct::mem) = 5)(y);
BOOST_TEST(x.mem == 5);
BOOST_CHECK(x.mem == 5);
// &my_struct::mem is a temporary, must be constified
((y ->* _1) = 6)(make_const(&my_struct::mem));
BOOST_TEST(x.mem == 6);
BOOST_CHECK(x.mem == 6);
((_1 ->* _2) = 7)(y, make_const(&my_struct::mem));
BOOST_TEST(x.mem == 7);
BOOST_CHECK(x.mem == 7);
}
void pointer_to_member_function_tests() {
my_struct *y = new my_struct(1);
BOOST_TEST( (_1 ->* &my_struct::foo)(y)() == (y->mem));
BOOST_TEST( (_1 ->* &my_struct::fooc)(y)() == (y->mem));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo))() == (y->mem));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::fooc))() == (y->mem));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo))() == (y->mem));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::fooc))() == (y->mem));
BOOST_CHECK( (_1 ->* &my_struct::foo)(y)() == (y->mem));
BOOST_CHECK( (_1 ->* &my_struct::fooc)(y)() == (y->mem));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo))() == (y->mem));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::fooc))() == (y->mem));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo))() == (y->mem));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::fooc))() == (y->mem));
BOOST_TEST( (_1 ->* &my_struct::foo1)(y)(1) == (y->mem+1));
BOOST_TEST( (_1 ->* &my_struct::foo1c)(y)(1) == (y->mem+1));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo1))(1) == (y->mem+1));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo1c))(1) == (y->mem+1));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo1))(1) == (y->mem+1));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo1c))(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* &my_struct::foo1)(y)(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* &my_struct::foo1c)(y)(1) == (y->mem+1));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo1))(1) == (y->mem+1));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo1c))(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo1))(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo1c))(1) == (y->mem+1));
BOOST_TEST( (_1 ->* &my_struct::foo2)(y)(1,2) == (y->mem+1+2));
BOOST_TEST( (_1 ->* &my_struct::foo2c)(y)(1,2) == (y->mem+1+2));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* &my_struct::foo2)(y)(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* &my_struct::foo2c)(y)(1,2) == (y->mem+1+2));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
BOOST_TEST( (_1 ->* &my_struct::foo3)(y)(1,2,3) == (y->mem+1+2+3));
BOOST_TEST( (_1 ->* &my_struct::foo3c)(y)(1,2,3) == (y->mem+1+2+3));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* &my_struct::foo3)(y)(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* &my_struct::foo3c)(y)(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
BOOST_TEST( (_1 ->* &my_struct::foo4)(y)(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_TEST( (_1 ->* &my_struct::foo4c)(y)(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_TEST( (y ->* _1)(make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_TEST( (_1 ->* _2)(y, make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* &my_struct::foo4)(y)(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* &my_struct::foo4c)(y)(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
// member functions with default values do not work (inherent language issue)
// BOOST_TEST( (_1 ->* &my_struct::foo3default)(y)() == (y->mem+1+2+3));
// BOOST_CHECK( (_1 ->* &my_struct::foo3default)(y)() == (y->mem+1+2+3));
}
@@ -118,11 +118,11 @@ class C {};
class D {};
// ->* can be overloaded to do anything
bool operator->*(A a, B b) {
bool operator->*(A /*a*/, B /*b*/) {
return false;
}
bool operator->*(B b, A a) {
bool operator->*(B /*b*/, A /*a*/) {
return true;
}
@@ -163,21 +163,21 @@ void test_overloaded_pointer_to_member()
A a; B b;
// this won't work, can't deduce the return type
// BOOST_TEST((_1->*_2)(a, b) == false);
// BOOST_CHECK((_1->*_2)(a, b) == false);
// ret<bool> gives the return type
BOOST_TEST(ret<bool>(_1->*_2)(a, b) == false);
BOOST_TEST(ret<bool>(a->*_1)(b) == false);
BOOST_TEST(ret<bool>(_1->*b)(a) == false);
BOOST_TEST((ret<bool>((var(a))->*b))() == false);
BOOST_TEST((ret<bool>((var(a))->*var(b)))() == false);
BOOST_CHECK(ret<bool>(_1->*_2)(a, b) == false);
BOOST_CHECK(ret<bool>(a->*_1)(b) == false);
BOOST_CHECK(ret<bool>(_1->*b)(a) == false);
BOOST_CHECK((ret<bool>((var(a))->*b))() == false);
BOOST_CHECK((ret<bool>((var(a))->*var(b)))() == false);
// this is ok without ret<bool> due to the return_type_2 spcialization above
BOOST_TEST((_1->*_2)(b, a) == true);
BOOST_TEST((b->*_1)(a) == true);
BOOST_TEST((_1->*a)(b) == true);
BOOST_TEST((var(b)->*a)() == true);
BOOST_CHECK((_1->*_2)(b, a) == true);
BOOST_CHECK((b->*_1)(a) == true);
BOOST_CHECK((_1->*a)(b) == true);
BOOST_CHECK((var(b)->*a)() == true);
return;
}

View File

@@ -1,6 +1,6 @@
// operator_tests_simple.cpp -- The Boost Lambda Library ---------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -17,6 +17,10 @@
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/detail/suppress_unused.hpp"
#include <boost/shared_ptr.hpp>
#include <vector>
#include <map>
#include <set>
@@ -47,7 +51,7 @@ void cout_tests()
(os << constant("FOO"))();
BOOST_TEST(os.str() == std::string("10FOO"));
BOOST_CHECK(os.str() == std::string("10FOO"));
istringstream is("ABC 1");
@@ -57,21 +61,21 @@ void cout_tests()
is >> s;
is >> k;
BOOST_TEST(s == std::string("ABC"));
BOOST_TEST(k == 1);
BOOST_CHECK(s == std::string("ABC"));
BOOST_CHECK(k == 1);
// test for constant, constant_ref and var
i = 5;
constant_type<int>::type ci(constant(i));
var_type<int>::type vi(var(i));
(vi = _1)(make_const(100));
BOOST_TEST((ci)() == 5);
BOOST_TEST(i == 100);
BOOST_CHECK((ci)() == 5);
BOOST_CHECK(i == 100);
int a;
constant_ref_type<int>::type cr(constant_ref(i));
(++vi, var(a) = cr)();
BOOST_TEST(i == 101);
BOOST_CHECK(i == 101);
#endif
}
@@ -81,115 +85,117 @@ void arithmetic_operators() {
using namespace std;
using namespace boost::lambda;
BOOST_TEST((_1 + 1)(i)==2);
BOOST_TEST(((_1 + 1) * _2)(i, j)==4);
BOOST_TEST((_1 - 1)(i)==0);
BOOST_CHECK((_1 + 1)(i)==2);
BOOST_CHECK(((_1 + 1) * _2)(i, j)==4);
BOOST_CHECK((_1 - 1)(i)==0);
BOOST_TEST((_1 * 2)(j)==4);
BOOST_TEST((_1 / 2)(j)==1);
BOOST_CHECK((_1 * 2)(j)==4);
BOOST_CHECK((_1 / 2)(j)==1);
BOOST_TEST((_1 % 2)(k)==1);
BOOST_CHECK((_1 % 2)(k)==1);
BOOST_TEST((-_1)(i) == -1);
BOOST_TEST((+_1)(i) == 1);
BOOST_CHECK((-_1)(i) == -1);
BOOST_CHECK((+_1)(i) == 1);
// test that unary plus really does something
unary_plus_tester u;
unary_plus_tester up = (+_1)(u);
boost::lambda::detail::suppress_unused_variable_warnings(up);
}
void bitwise_operators() {
unsigned int ui = 2;
BOOST_TEST((_1 << 1)(ui)==(2 << 1));
BOOST_TEST((_1 >> 1)(ui)==(2 >> 1));
BOOST_CHECK((_1 << 1)(ui)==(2 << 1));
BOOST_CHECK((_1 >> 1)(ui)==(2 >> 1));
BOOST_TEST((_1 & 1)(ui)==(2 & 1));
BOOST_TEST((_1 | 1)(ui)==(2 | 1));
BOOST_TEST((_1 ^ 1)(ui)==(2 ^ 1));
BOOST_TEST((~_1)(ui)==~2u);
BOOST_CHECK((_1 & 1)(ui)==(2 & 1));
BOOST_CHECK((_1 | 1)(ui)==(2 | 1));
BOOST_CHECK((_1 ^ 1)(ui)==(2 ^ 1));
BOOST_CHECK((~_1)(ui)==~2u);
}
void comparison_operators() {
int i = 0, j = 1;
BOOST_TEST((_1 < _2)(i, j) == true);
BOOST_TEST((_1 <= _2)(i, j) == true);
BOOST_TEST((_1 == _2)(i, j) == false);
BOOST_TEST((_1 != _2)(i, j) == true);
BOOST_TEST((_1 > _2)(i, j) == false);
BOOST_TEST((_1 >= _2)(i, j) == false);
BOOST_CHECK((_1 < _2)(i, j) == true);
BOOST_CHECK((_1 <= _2)(i, j) == true);
BOOST_CHECK((_1 == _2)(i, j) == false);
BOOST_CHECK((_1 != _2)(i, j) == true);
BOOST_CHECK((_1 > _2)(i, j) == false);
BOOST_CHECK((_1 >= _2)(i, j) == false);
BOOST_TEST((!(_1 < _2))(i, j) == false);
BOOST_TEST((!(_1 <= _2))(i, j) == false);
BOOST_TEST((!(_1 == _2))(i, j) == true);
BOOST_TEST((!(_1 != _2))(i, j) == false);
BOOST_TEST((!(_1 > _2))(i, j) == true);
BOOST_TEST((!(_1 >= _2))(i, j) == true);
BOOST_CHECK((!(_1 < _2))(i, j) == false);
BOOST_CHECK((!(_1 <= _2))(i, j) == false);
BOOST_CHECK((!(_1 == _2))(i, j) == true);
BOOST_CHECK((!(_1 != _2))(i, j) == false);
BOOST_CHECK((!(_1 > _2))(i, j) == true);
BOOST_CHECK((!(_1 >= _2))(i, j) == true);
}
void logical_operators() {
bool t = true, f = false;
BOOST_TEST((_1 && _2)(t, t) == true);
BOOST_TEST((_1 && _2)(t, f) == false);
BOOST_TEST((_1 && _2)(f, t) == false);
BOOST_TEST((_1 && _2)(f, f) == false);
BOOST_CHECK((_1 && _2)(t, t) == true);
BOOST_CHECK((_1 && _2)(t, f) == false);
BOOST_CHECK((_1 && _2)(f, t) == false);
BOOST_CHECK((_1 && _2)(f, f) == false);
BOOST_TEST((_1 || _2)(t, t) == true);
BOOST_TEST((_1 || _2)(t, f) == true);
BOOST_TEST((_1 || _2)(f, t) == true);
BOOST_TEST((_1 || _2)(f, f) == false);
BOOST_CHECK((_1 || _2)(t, t) == true);
BOOST_CHECK((_1 || _2)(t, f) == true);
BOOST_CHECK((_1 || _2)(f, t) == true);
BOOST_CHECK((_1 || _2)(f, f) == false);
BOOST_TEST((!_1)(t) == false);
BOOST_TEST((!_1)(f) == true);
BOOST_CHECK((!_1)(t) == false);
BOOST_CHECK((!_1)(f) == true);
// test short circuiting
int i=0;
(false && ++_1)(i);
BOOST_TEST(i==0);
BOOST_CHECK(i==0);
i = 0;
(true && ++_1)(i);
BOOST_TEST(i==1);
BOOST_CHECK(i==1);
i = 0;
(false || ++_1)(i);
BOOST_TEST(i==1);
BOOST_CHECK(i==1);
i = 0;
(true || ++_1)(i);
BOOST_TEST(i==0);
BOOST_CHECK(i==0);
i = 0;
}
void unary_incs_and_decs() {
int i = 0;
BOOST_TEST(_1++(i) == 0);
BOOST_TEST(i == 1);
BOOST_CHECK(_1++(i) == 0);
BOOST_CHECK(i == 1);
i = 0;
BOOST_TEST(_1--(i) == 0);
BOOST_TEST(i == -1);
BOOST_CHECK(_1--(i) == 0);
BOOST_CHECK(i == -1);
i = 0;
BOOST_TEST((++_1)(i) == 1);
BOOST_TEST(i == 1);
BOOST_CHECK((++_1)(i) == 1);
BOOST_CHECK(i == 1);
i = 0;
BOOST_TEST((--_1)(i) == -1);
BOOST_TEST(i == -1);
BOOST_CHECK((--_1)(i) == -1);
BOOST_CHECK(i == -1);
i = 0;
// the result of prefix -- and ++ are lvalues
(++_1)(i) = 10;
BOOST_TEST(i==10);
BOOST_CHECK(i==10);
i = 0;
(--_1)(i) = 10;
BOOST_TEST(i==10);
BOOST_CHECK(i==10);
i = 0;
}
@@ -199,77 +205,93 @@ void compound_operators() {
// normal variable as the left operand
(i += _1)(make_const(1));
BOOST_TEST(i == 2);
BOOST_CHECK(i == 2);
(i -= _1)(make_const(1));
BOOST_TEST(i == 1);
BOOST_CHECK(i == 1);
(i *= _1)(make_const(10));
BOOST_TEST(i == 10);
BOOST_CHECK(i == 10);
(i /= _1)(make_const(2));
BOOST_TEST(i == 5);
BOOST_CHECK(i == 5);
(i %= _1)(make_const(2));
BOOST_TEST(i == 1);
BOOST_CHECK(i == 1);
// lambda expression as a left operand
(_1 += 1)(i);
BOOST_TEST(i == 2);
BOOST_CHECK(i == 2);
(_1 -= 1)(i);
BOOST_TEST(i == 1);
BOOST_CHECK(i == 1);
(_1 *= 10)(i);
BOOST_TEST(i == 10);
BOOST_CHECK(i == 10);
(_1 /= 2)(i);
BOOST_TEST(i == 5);
BOOST_CHECK(i == 5);
(_1 %= 2)(i);
BOOST_TEST(i == 1);
BOOST_CHECK(i == 1);
// lambda expression as a left operand with rvalue on RHS
(_1 += (0 + 1))(i);
BOOST_CHECK(i == 2);
(_1 -= (0 + 1))(i);
BOOST_CHECK(i == 1);
(_1 *= (0 + 10))(i);
BOOST_CHECK(i == 10);
(_1 /= (0 + 2))(i);
BOOST_CHECK(i == 5);
(_1 %= (0 + 2))(i);
BOOST_CHECK(i == 1);
// shifts
unsigned int ui = 2;
(_1 <<= 1)(ui);
BOOST_TEST(ui==(2 << 1));
BOOST_CHECK(ui==(2 << 1));
ui = 2;
(_1 >>= 1)(ui);
BOOST_TEST(ui==(2 >> 1));
BOOST_CHECK(ui==(2 >> 1));
ui = 2;
(ui <<= _1)(make_const(1));
BOOST_TEST(ui==(2 << 1));
BOOST_CHECK(ui==(2 << 1));
ui = 2;
(ui >>= _1)(make_const(1));
BOOST_TEST(ui==(2 >> 1));
BOOST_CHECK(ui==(2 >> 1));
// and, or, xor
ui = 2;
(_1 &= 1)(ui);
BOOST_TEST(ui==(2 & 1));
BOOST_CHECK(ui==(2 & 1));
ui = 2;
(_1 |= 1)(ui);
BOOST_TEST(ui==(2 | 1));
BOOST_CHECK(ui==(2 | 1));
ui = 2;
(_1 ^= 1)(ui);
BOOST_TEST(ui==(2 ^ 1));
BOOST_CHECK(ui==(2 ^ 1));
ui = 2;
(ui &= _1)(make_const(1));
BOOST_TEST(ui==(2 & 1));
BOOST_CHECK(ui==(2 & 1));
ui = 2;
(ui |= _1)(make_const(1));
BOOST_TEST(ui==(2 | 1));
BOOST_CHECK(ui==(2 | 1));
ui = 2;
(ui ^= _1)(make_const(1));
BOOST_TEST(ui==(2 ^ 1));
BOOST_CHECK(ui==(2 ^ 1));
}
@@ -283,24 +305,24 @@ void assignment_and_subscript() {
string s;
(_1 = "one")(s);
BOOST_TEST(s == string("one"));
BOOST_CHECK(s == string("one"));
(var(s) = "two")();
BOOST_TEST(s == string("two"));
BOOST_CHECK(s == string("two"));
BOOST_TEST((var(s)[_1])(make_const(2)) == 'o');
BOOST_TEST((_1[2])(s) == 'o');
BOOST_TEST((_1[_2])(s, make_const(2)) == 'o');
BOOST_CHECK((var(s)[_1])(make_const(2)) == 'o');
BOOST_CHECK((_1[2])(s) == 'o');
BOOST_CHECK((_1[_2])(s, make_const(2)) == 'o');
// subscript returns lvalue
(var(s)[_1])(make_const(1)) = 'o';
BOOST_TEST(s == "too");
BOOST_CHECK(s == "too");
(_1[1])(s) = 'a';
BOOST_TEST(s == "tao");
BOOST_CHECK(s == "tao");
(_1[_2])(s, make_const(0)) = 'm';
BOOST_TEST(s == "mao");
BOOST_CHECK(s == "mao");
// TODO: tests for vector, set, map, multimap
}
@@ -311,16 +333,26 @@ void address_of_and_dereference() {
A a; int i = 42;
BOOST_TEST((&_1)(a) == &a);
BOOST_TEST((*&_1)(i) == 42);
BOOST_CHECK((&_1)(a) == &a);
BOOST_CHECK((*&_1)(i) == 42);
std::vector<int> vi; vi.push_back(1);
std::vector<int>::iterator it = vi.begin();
(*_1 = 7)(it);
BOOST_TEST(vi[0] == 7);
BOOST_CHECK(vi[0] == 7);
const std::vector<int>::iterator cit(it);
(*_1 = 8)(cit);
BOOST_CHECK(vi[0] == 8);
// TODO: Add tests for more complex iterator types
boost::shared_ptr<int> ptr(new int(0));
(*_1 = 7)(ptr);
BOOST_CHECK(*ptr == 7);
const boost::shared_ptr<int> cptr(ptr);
(*_1 = 8)(cptr);
BOOST_CHECK(*ptr == 8);
}
@@ -328,7 +360,7 @@ void address_of_and_dereference() {
void comma() {
int i = 100;
BOOST_TEST((_1 = 10, 2 * _1)(i) == 20);
BOOST_CHECK((_1 = 10, 2 * _1)(i) == 20);
// TODO: that the return type is the exact type of the right argument
// (that r/l valueness is preserved)
@@ -347,32 +379,32 @@ void pointer_arithmetic() {
// non-const array
BOOST_TEST((*(_1 + 1))(ia) == 2);
BOOST_CHECK((*(_1 + 1))(ia) == 2);
// non-const pointer
BOOST_TEST((*(_1 + 1))(ip) == 2);
BOOST_CHECK((*(_1 + 1))(ip) == 2);
BOOST_TEST((*(_1 - 1))(ia_last) == 3);
BOOST_CHECK((*(_1 - 1))(ia_last) == 3);
// const array
BOOST_TEST((*(_1 + 1))(cia) == 2);
BOOST_CHECK((*(_1 + 1))(cia) == 2);
// const pointer
BOOST_TEST((*(_1 + 1))(cip) == 2);
BOOST_TEST((*(_1 - 1))(cia_last) == 3);
BOOST_CHECK((*(_1 + 1))(cip) == 2);
BOOST_CHECK((*(_1 - 1))(cia_last) == 3);
// pointer arithmetic should not make non-consts const
(*(_1 + 2))(ia) = 0;
(*(_1 + 3))(ip) = 0;
BOOST_TEST(ia[2] == 0);
BOOST_TEST(ia[3] == 0);
BOOST_CHECK(ia[2] == 0);
BOOST_CHECK(ia[3] == 0);
// pointer - pointer
BOOST_TEST((_1 - _2)(ia_last, ia) == 3);
BOOST_TEST((_1 - _2)(cia_last, cia) == 3);
BOOST_TEST((ia_last - _1)(ia) == 3);
BOOST_TEST((cia_last - _1)(cia) == 3);
BOOST_TEST((cia_last - _1)(cip) == 3);
BOOST_CHECK((_1 - _2)(ia_last, ia) == 3);
BOOST_CHECK((_1 - _2)(cia_last, cia) == 3);
BOOST_CHECK((ia_last - _1)(ia) == 3);
BOOST_CHECK((cia_last - _1)(cia) == 3);
BOOST_CHECK((cia_last - _1)(cip) == 3);
}

View File

@@ -1,6 +1,6 @@
// phoenix_style_control_structures.cpp -- The Boost Lambda Library ------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -60,7 +60,7 @@ int test_main(int, char *[]) {
]
);
BOOST_TEST(sum == 4+5+6+7+8);
BOOST_CHECK(sum == 4+5+6+7+8);
int gt = 0, eq = 0, lt = 0;
//////////////////////////////////
@@ -82,9 +82,9 @@ int test_main(int, char *[]) {
]
);
BOOST_TEST(lt==4);
BOOST_TEST(eq==1);
BOOST_TEST(gt==5);
BOOST_CHECK(lt==4);
BOOST_CHECK(eq==1);
BOOST_CHECK(gt==5);
vector<int> t = v;
@@ -101,8 +101,8 @@ int test_main(int, char *[]) {
)
);
BOOST_TEST(counta == 55);
BOOST_TEST(countb == 10);
BOOST_CHECK(counta == 55);
BOOST_CHECK(countb == 10);
v = t;
@@ -120,8 +120,8 @@ int test_main(int, char *[]) {
)
);
BOOST_TEST(counta == (2+11)*10/2);
BOOST_TEST(countb == 10);
BOOST_CHECK(counta == (2+11)*10/2);
BOOST_CHECK(countb == 10);
v = t;
@@ -138,8 +138,8 @@ int test_main(int, char *[]) {
)
);
BOOST_TEST(counta == (1+10)*10/2);
BOOST_TEST(countb == 10);
BOOST_CHECK(counta == (1+10)*10/2);
BOOST_CHECK(countb == 10);
v = t;

315
test/result_of_tests.cpp Normal file
View File

@@ -0,0 +1,315 @@
// result_of_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2010 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
struct with_result_type {
typedef int result_type;
int operator()() const { return 0; }
int operator()(int) const { return 1; }
int operator()(int, int) const { return 2; }
int operator()(int, int, int) const { return 3; }
int operator()(int, int, int, int) const { return 4; }
int operator()(int, int, int, int, int) const { return 5; }
int operator()(int, int, int, int, int, int) const { return 6; }
int operator()(int, int, int, int, int, int, int) const { return 7; }
int operator()(int, int, int, int, int, int, int, int) const { return 8; }
int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
};
struct with_result_template_value {
template<class Sig>
struct result;
template<class This>
struct result<This()> {
typedef int type;
};
template<class This, class A1>
struct result<This(A1)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
typedef int type;
};
template<class This, class A1, class A2>
struct result<This(A1, A2)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3>
struct result<This(A1, A2, A3)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4>
struct result<This(A1, A2, A3, A4)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5>
struct result<This(A1, A2, A3, A4, A5)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
struct result<This(A1, A2, A3, A4, A5, A6)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
BOOST_MPL_ASSERT((boost::is_same<A7, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
BOOST_MPL_ASSERT((boost::is_same<A7, int>));
BOOST_MPL_ASSERT((boost::is_same<A8, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
BOOST_MPL_ASSERT((boost::is_same<A7, int>));
BOOST_MPL_ASSERT((boost::is_same<A8, int>));
BOOST_MPL_ASSERT((boost::is_same<A9, int>));
typedef int type;
};
int operator()() const { return 0; }
int operator()(int) const { return 1; }
int operator()(int, int) const { return 2; }
int operator()(int, int, int) const { return 3; }
int operator()(int, int, int, int) const { return 4; }
int operator()(int, int, int, int, int) const { return 5; }
int operator()(int, int, int, int, int, int) const { return 6; }
int operator()(int, int, int, int, int, int, int) const { return 7; }
int operator()(int, int, int, int, int, int, int, int) const { return 8; }
int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
};
struct with_result_template_reference {
template<class Sig>
struct result;
template<class This>
struct result<This()> {
typedef int type;
};
template<class This, class A1>
struct result<This(A1)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
typedef int type;
};
template<class This, class A1, class A2>
struct result<This(A1, A2)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3>
struct result<This(A1, A2, A3)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4>
struct result<This(A1, A2, A3, A4)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5>
struct result<This(A1, A2, A3, A4, A5)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
struct result<This(A1, A2, A3, A4, A5, A6)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
BOOST_MPL_ASSERT((boost::is_same<A9, int&>));
typedef int type;
};
int operator()() const { return 0; }
int operator()(int) const { return 1; }
int operator()(int, int) const { return 2; }
int operator()(int, int, int) const { return 3; }
int operator()(int, int, int, int) const { return 4; }
int operator()(int, int, int, int, int) const { return 5; }
int operator()(int, int, int, int, int, int) const { return 6; }
int operator()(int, int, int, int, int, int, int) const { return 7; }
int operator()(int, int, int, int, int, int, int, int) const { return 8; }
int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
};
template<class F>
typename boost::result_of<F()>::type apply0(F f) {
return f();
}
template<class A, class F>
typename boost::result_of<F(A)>::type apply1(F f, A a) {
return f(a);
}
template<class A, class B, class F>
typename boost::result_of<F(A, B)>::type apply2(F f, A a, B b) {
return f(a, b);
}
template<class A, class B, class C, class F>
typename boost::result_of<F(A, B, C)>::type apply3(F f, A a, B b, C c) {
return f(a, b, c);
}
using namespace boost::lambda;
int test_main(int, char *[]) {
BOOST_CHECK(boost::lambda::bind(with_result_type())() == 0);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1)() == 1);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2)() == 2);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3)() == 3);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4)() == 4);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5)() == 5);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6)() == 6);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7)() == 7);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
// Nullary result_of fails
//BOOST_CHECK(boost::lambda::bind(with_result_template_value())() == 0);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1)() == 1);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2)() == 2);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3)() == 3);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4)() == 4);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5)() == 5);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6)() == 6);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7)() == 7);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
int one = 1,
two = 2,
three = 3,
four = 4,
five = 5,
six = 6,
seven = 7,
eight = 8,
nine = 9;
// Nullary result_of fails
//BOOST_CHECK(boost::lambda::bind(with_result_template_reference())() == 0);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one))() == 1);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two))() == 2);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three))() == 3);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four))() == 4);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five))() == 5);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six))() == 6);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven))() == 7);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight))() == 8);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight), var(nine))() == 9);
// Check using result_of with lambda functors
BOOST_CHECK(apply0(constant(0)) == 0);
// returns local address and leads to undefined behavior
//~ BOOST_CHECK(apply1<int>(_1, one) == 1);
BOOST_CHECK(apply1<int&>(_1, one) == 1);
BOOST_CHECK(apply1<const int&>(_1, one) == 1);
BOOST_CHECK((apply2<int, int>(_1 + _2, one, two) == 3));
BOOST_CHECK((apply2<int&, int&>(_1 + _2, one, two) == 3));
BOOST_CHECK((apply2<const int&, const int&>(_1 + _2, one, two) == 3));
BOOST_CHECK((apply3<int, int, int>(_1 + _2 + _3, one, two, three) == 6));
BOOST_CHECK((apply3<int&, int&, int&>(_1 + _2 + _3, one, two, three) == 6));
BOOST_CHECK((apply3<const int&, const int&, const int&>(_1 + _2 + _3, one, two, three) == 6));
return 0;
}

53
test/ret_test.cpp Normal file
View File

@@ -0,0 +1,53 @@
// ret_test.cpp - The Boost Lambda Library -----------------------
//
// Copyright (C) 2009 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
#include <boost/test/minimal.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
template<class R, class F>
void test_ret(R r, F f) {
typename F::result_type x = f();
BOOST_MPL_ASSERT((boost::is_same<R, typename F::result_type>));
BOOST_CHECK(x == r);
}
template<class R, class F, class T1>
void test_ret(R r, F f, T1& t1) {
typename F::result_type x = f(t1);
BOOST_MPL_ASSERT((boost::is_same<R, typename F::result_type>));
BOOST_CHECK(x == r);
}
class add_result {
public:
add_result(int i = 0) : value(i) {}
friend bool operator==(const add_result& lhs, const add_result& rhs) {
return(lhs.value == rhs.value);
}
private:
int value;
};
class addable {};
add_result operator+(addable, addable) {
return add_result(7);
}
int test_main(int, char*[]) {
addable test;
test_ret(add_result(7), boost::lambda::ret<add_result>(boost::lambda::_1 + test), test);
test_ret(8.0, boost::lambda::ret<double>(boost::lambda::constant(7) + 1));
return 0;
}

57
test/rvalue_test.cpp Normal file
View File

@@ -0,0 +1,57 @@
// rvalue_test - test lambda function objects with rvalue arguments
//
// Copyright (c) 2007 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/lambda/lambda.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
using namespace boost::lambda;
int x = 0;
int const y = 1;
int const z = 2;
BOOST_TEST( _1( x ) == 0 );
BOOST_TEST( _1( y ) == 1 );
BOOST_TEST( _1( 2 ) == 2 );
BOOST_TEST( _2( x, x ) == 0 );
BOOST_TEST( _2( x, y ) == 1 );
BOOST_TEST( _2( x, 2 ) == 2 );
BOOST_TEST( _2( 4, x ) == 0 );
BOOST_TEST( _2( 4, y ) == 1 );
BOOST_TEST( _2( 4, 2 ) == 2 );
(_1 = _2)( x, y );
BOOST_TEST( x == y );
(_1 = _2)( x, 3 );
BOOST_TEST( x == 3 );
(_2 = _1)( z, x );
BOOST_TEST( x == z );
(_2 = _1)( 4, x );
BOOST_TEST( x == 4 );
BOOST_TEST( _3( x, x, x ) == x );
BOOST_TEST( _3( x, x, y ) == y );
BOOST_TEST( _3( x, x, 2 ) == 2 );
BOOST_TEST( _3( x, 5, x ) == x );
BOOST_TEST( _3( x, 5, y ) == y );
BOOST_TEST( _3( x, 5, 2 ) == 2 );
BOOST_TEST( _3( 9, 5, x ) == x );
BOOST_TEST( _3( 9, 5, y ) == y );
BOOST_TEST( _3( 9, 5, 2 ) == 2 );
return boost::report_errors();
}

View File

@@ -1,6 +1,6 @@
// switch_test.cpp -- The Boost Lambda Library --------------------------
//
// Copyright (C) 2000-2003 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See
@@ -63,7 +63,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_TEST(check(w, 0));
BOOST_CHECK(check(w, 0));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -75,7 +75,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_TEST(check(w, 1));
BOOST_CHECK(check(w, 1));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -88,7 +88,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_TEST(check(w, 2));
BOOST_CHECK(check(w, 2));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -102,7 +102,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_TEST(check(w, 3));
BOOST_CHECK(check(w, 3));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -117,7 +117,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_TEST(check(w, 4));
BOOST_CHECK(check(w, 4));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -133,7 +133,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_TEST(check(w, 5));
BOOST_CHECK(check(w, 5));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -150,7 +150,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_TEST(check(w, 6));
BOOST_CHECK(check(w, 6));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -168,7 +168,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_TEST(check(w, 7));
BOOST_CHECK(check(w, 7));
std::fill_n(w.begin(), 10, 0);
// ---
@@ -187,7 +187,7 @@ void do_switch_no_defaults_tests() {
)
);
BOOST_TEST(check(w, 8));
BOOST_CHECK(check(w, 8));
std::fill_n(w.begin(), 10, 0);
}
@@ -216,8 +216,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_TEST(check(w, -1));
BOOST_TEST(default_count == 10);
BOOST_CHECK(check(w, -1));
BOOST_CHECK(default_count == 10);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -230,8 +230,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_TEST(check(w, 0));
BOOST_TEST(default_count == 9);
BOOST_CHECK(check(w, 0));
BOOST_CHECK(default_count == 9);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -245,8 +245,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_TEST(check(w, 1));
BOOST_TEST(default_count == 8);
BOOST_CHECK(check(w, 1));
BOOST_CHECK(default_count == 8);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -261,8 +261,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_TEST(check(w, 2));
BOOST_TEST(default_count == 7);
BOOST_CHECK(check(w, 2));
BOOST_CHECK(default_count == 7);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -278,8 +278,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_TEST(check(w, 3));
BOOST_TEST(default_count == 6);
BOOST_CHECK(check(w, 3));
BOOST_CHECK(default_count == 6);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -296,8 +296,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_TEST(check(w, 4));
BOOST_TEST(default_count == 5);
BOOST_CHECK(check(w, 4));
BOOST_CHECK(default_count == 5);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -315,8 +315,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_TEST(check(w, 5));
BOOST_TEST(default_count == 4);
BOOST_CHECK(check(w, 5));
BOOST_CHECK(default_count == 4);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -335,8 +335,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_TEST(check(w, 6));
BOOST_TEST(default_count == 3);
BOOST_CHECK(check(w, 6));
BOOST_CHECK(default_count == 3);
std::fill_n(w.begin(), 10, 0);
// ---
@@ -356,8 +356,8 @@ void do_switch_yes_defaults_tests() {
)
);
BOOST_TEST(check(w, 7));
BOOST_TEST(default_count == 2);
BOOST_CHECK(check(w, 7));
BOOST_CHECK(default_count == 2);
std::fill_n(w.begin(), 10, 0);
}