1
0
forked from boostorg/mpl

Compare commits

..

623 Commits

Author SHA1 Message Date
Alexander Grund b440c45c28 Avoid Wzero-as-null-pointer-constant warning (#75)
Newer compilers may warn when using `0`, e.g.:
```
./boost/iterator/detail/facade_iterator_category.hpp:161:5: error: zero as null pointer constant [-Werror,-Wzero-as-null-pointer-constant]
    BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
    ^
./boost/mpl/assert.hpp:324:58: note: expanded from macro 'BOOST_MPL_ASSERT_NOT'
              boost::mpl::assert_not_arg( (void (*) pred)0, 1 ) \
```
2023-05-10 21:16:45 -06:00
Alexander Grund db09fb1dce Fix ccache saving on cache hit (#66)
See boostorg/boost-ci#166
2022-06-24 08:57:36 -07:00
Nikita Kniazev 8f10d06b96 Fix unused variable warning from BOOST_MPL_ASSERT_* on Clang 2022-05-01 17:23:44 -04:00
Mat Berchtold 03d89ec586 Fixes issue https://github.com/boostorg/mpl/issues/46 2022-05-01 16:07:58 -04:00
James E. King III 3301d917dc Disable bigendian CI build to eliminate PR check failure for #50 2022-05-01 08:47:52 -04:00
James E. King III bd4ec497a8 Use BOOST_WORKAROUND when checking compiler level 2022-05-01 08:47:52 -04:00
Anis Ladram 4634ef904e Fix -Wparentheses warning not ignored on NVCC
BOOST_GCC is not defined for NVCC, therefore we should use BOOST_GCC_VERSION.
2022-05-01 08:47:52 -04:00
Ion Gaztañaga c61b1e3508 Fix some -Wsign-conversion warnings 2022-04-30 22:45:39 -04:00
James E. King III e9e3faf4be Align to Boost.CI 2022.04 2022-04-30 17:31:53 -04:00
Jonathan Wakely 5f79900dcc Fix some XML validation errors (#60)
Relates #59
2021-12-01 19:37:28 -08:00
Sam Darwin 793bf12d42 Update GitHub Actions CI file (#58) 2021-08-04 07:03:02 -07:00
Peter Dimov 341748e4cb Update CMakeLists.txt 2021-06-10 00:54:16 +03:00
Sam Darwin db132085b9 Add GitHub Actions config [ci skip] (#56) 2021-03-03 18:30:05 -08:00
Sam Darwin f3464e3ef7 add drone config [ci skip] (#54) 2021-02-25 12:02:20 -05:00
Edward Diener 71ee3ac5bd [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. (#55) 2021-01-20 15:39:33 -05:00
Edward Diener cc883aa12a Address model for msvc-10 and msvc-11 must be only 32-bit in appveyor.yml (#53) 2020-09-25 15:15:05 -04:00
Edward Diener 6704b09dcf It normally should not be necessary to use the _Z form of the BOOST_P… (#52)
* It normally should not be necessary to use the _Z form of the BOOST_PP_ENUM macro, although it is perfectly legal and helpful to do so, but in this case it is necessary as a workaround for a bug in the new VC++ standard conforming preprocessor. The bug manifests itself when testing the TTI library, which internally uses the Boost MPL code. The bug in the new VC++ standard conforming compiler is fixed in the VS2019 preview product, so that fix is sure to find its way to the official VS2019 product sometime soon. In the meantime this "fix" shortens the macro expansion somewhat and, while it should not be necessary, is still helpful.

* Fix for appveyor.yml file

* Added VS2019 tests, also with new preprocessor. Further MPL Fixes for new preprocessor bug, which are also useful and will speed up preprocessing.

* Can't seem to test msvc-10.0 or msvc-11.0 any more with Appveyor

* Update description
2020-09-24 06:07:26 -04:00
Jonathan Wakely 9c0f98f088 Fix invalid XHTML markup (#51) 2020-08-05 08:57:41 -07:00
Edward Diener 3d8a60ed6a Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers. (#48)
Co-authored-by: Edward Diener <eldlistmailingz@tropicsoft.com>
2020-04-12 09:48:24 -07:00
tinko92 e01a10925d Replace three links that seem broken (keep timing out)
Fix broken sgi/stl links.
Fix broken gmane link.
2019-04-24 05:47:07 +10:00
Mike Dev 273db79266 [CMake] Update formatting and add copy right note 2019-02-13 19:06:08 -05:00
Mike Dev c7df450a81 [CMake] Generate cmake target that other libraries can use
... to express their dependency on this library and retrieve any
configuration information such as the include directory, binary
to link to (if any), transitive dependencies, necessary compiler
options or the required c++ standards level.
2019-02-13 19:06:08 -05:00
Edward Diener ac67f5952e Back out fix for VC++8.0 2018-11-14 11:54:53 -05:00
James E. King III 758a7f6c6a Enhance CI with libc++ and VS2017 strict builds 2018-11-04 06:55:26 -05:00
Edward Diener 95733a1c45 Merge pull request #36 from robinlinden/msvc-linking-fix
Fix BOOST_MPL_ASSERT_MSG for VC++8
2018-08-23 17:40:47 -04:00
Robin Lindén e44b2ae761 Fix BOOST_MPL_ASSERT_MSG for VC++8
The struct member function inside BOOST_MPL_ASSERT_MSG_IMPL was causing
multiple definitions of the same symbol when used inside e.g. template
functions.

An example of where this is a big issue is in the boost/geometry library
where you currently only can call each function once for each geometry
or you get hit by the multiple definitions linking error.

This fix* works around the issue by gracefully degrading to
BOOST_STATIC_ASSERT_MSG instead of failing during linking.
2018-08-20 19:23:02 +02:00
Robin Lindén 42c794ad42 Add test checking that MPL_ASSERT_MSG works under VC++8 2018-08-20 19:22:48 +02:00
James E. King III 270f33f679 fix broken ci jobs in travis 2018-07-14 20:48:03 +00:00
James E. King III 41d036aea2 Merge branch 'master' into develop 2018-06-16 19:42:39 +00:00
James E. King III 44ebb23b6a Fix appveyor and coverity links and badges in readme 2018-06-14 17:39:05 -04:00
James E. King III b877c35841 fix coverity scan integration 2018-06-13 18:09:24 +00:00
James E. King III b295845afe fix building in boostorg appveyor account 2018-06-03 00:10:22 +00:00
James E. King III 71d523d949 Added CI framework
- travis with valgrind, cppcheck, ubsan, codecov, covscan (future)
      - appveyor with MSVC 2010 through 2017, cygwin 32/64, mingw 32/64
      - README, LICENSE, etc.
2018-05-29 20:02:33 -04:00
Edward Diener 3c1910797c Merge pull request #34 from Romain-Geissler-1A/ignore-gcc-8-warning
Ignore gcc 8 warnings.
2018-03-07 17:25:05 -05:00
Romain Geissler f48fd09d02 Ignore gcc 8 warnings. 2018-03-01 09:59:33 +01:00
Edward Diener 29c10a72a1 Merge pull request #32 from mihaipop11/changes
changed angled brackets with quotes for gcc include file in preproces…
2018-02-26 12:31:21 -05:00
mihai.pop 238cda5fb9 changed angled brackets with quotes for gcc include file in preprocess.cmd 2018-02-15 10:23:48 +01:00
Edward Diener 2371f85461 Merge branch 'develop' 2017-09-26 12:03:27 -04:00
Edward Diener f311a495ed Removed executable tag. 2017-09-16 07:22:05 -04:00
Edward Diener dbcc7b8c7b Merge branch 'develop' 2017-09-14 11:42:27 -04:00
Edward Diener ef60815c66 Updated examples to use unique_ptr when available rather than auto_ptr, which is being deprecated. 2017-08-26 15:06:30 -04:00
Marshall Clow 523bc5a782 Merge pull request #30 from dkolsen-pgi/pgi-compiler-support
Update PGI C++ compiler support
2017-07-26 13:03:22 -07:00
David Olsen a81b00a5f0 Update PGI C++ compiler support
Add PGI C++ to list of compilers that use enums rather than static constants for compile-time assertions, because, like GCC, PGI issues warnings for unused static constants.
2017-07-26 12:46:48 -07:00
Edward Diener 13e4e53259 Merge pull request #29 from amarzial/develop
Fixed a bug with the template substitution adding temporary string
2017-07-10 12:32:35 -04:00
Alessandro Marzialetti ecb4d2a89f Fixed a bug with the template substitution adding temporary string
placeholders to avoid unexpected substitutions

(e.g.) with i = 110:
line = re.sub(r'20', re.escape(str(i+10)), line.rstrip())
    20 -> 110
line = re.sub(r'11', re.escape(str(i + 1)), line.rstrip())
    110 -> 1010
line = re.sub(r'10(?![0-9])', re.escape(str(i)), line.rstrip())
    1100 -> 10100
2017-07-10 12:45:36 +02:00
Edward Diener 4265eb6319 Merge pull request #28 from ohhmm/develop
introducing get_tag and math sigmoid
2017-07-03 01:33:38 -04:00
Sergei Krivonos 525c773836 adding get_tag definition 2017-07-03 06:53:38 +03:00
Marshall Clow efc2a862a3 Merge to master for 1.62.0 release 2016-08-17 13:27:42 -07:00
Edward Diener 3b126bdf8c Merge pull request #27 from morinmorin/fix/print_warning
Fix "-Wc++11-extensions" warning on Clang in C++03 mode
2016-07-12 16:43:45 -04:00
morinmorin 869438d60b Fix "-Wc++11-extensions" warning on Clang in C++03 mode 2016-07-02 14:27:29 +09:00
Marshall Clow f023a68f78 Merge branch 'develop' 2015-10-03 09:51:29 -07:00
Marshall Clow bc8b860037 Merge pull request #25 from trel/patch-2
Thanks.
2015-09-14 12:38:44 -07:00
Terrell Russell 7a15566169 fix typo
this time onto develop...
2015-09-14 15:03:50 -04:00
Marshall Clow e1cb5fe91e Merge pull request #24 from boostorg/revert-23-patch-1
Revert "fix typo"
2015-09-14 11:58:29 -07:00
Marshall Clow 9153e25b63 Revert "fix typo" 2015-09-14 11:58:14 -07:00
Marshall Clow 1f463f62ef Merge pull request #23 from trel/patch-1
Thanks.
2015-09-14 11:58:09 -07:00
Terrell Russell daaf813cee fix typo 2015-09-14 14:55:13 -04:00
Marshall Clow 53d9af7e8f Merge pull request #22 from akumta/patch-1
Update for Boost ticket #11594 - @akumta , please watch the test bots and ping me in a week or so to merge to master.
2015-09-02 08:02:02 -07:00
akumta 1f64380f62 Update for Boost ticket #11594 2015-08-27 10:36:15 -07:00
Edward Diener 4d1b6b3dc7 Merge branch 'develop' 2015-07-18 10:39:03 -04:00
Edward Diener b4fe64a73c Merge pull request #21 from Bagira80/additions_to_fix_for_issue11224
Addition to fix / workaround for issue #11224.
2015-05-20 02:33:21 -04:00
Deniz Bahadir 7c9701ee5c Addition to fix / workaround for issue #11224.
* Added default-value for cmdline-option which expects the Boost
  source-directory. It points to the Boost source-directory in which the
  script "boost_mpl_preprocess.py" is located.
* Adjusted "README.txt" file to reflect these changes.

Signed-off-by: Deniz Bahadir <dbahadir@benocs.com>
2015-05-19 12:11:44 +02:00
Edward Diener dd5f2d9c03 Merge pull request #20 from Bagira80/develop
Fix for issue 11224 ("Pre-processing / Pre-generating MPL-containers stopped working")
2015-05-18 10:42:49 -04:00
Deniz Bahadir 0e262c22a0 Fix / Workaround for issue #11224. (cont.)
* Extended script "boost_mpl_preprocess.py" to automatically call script
  "fix_boost_mpl_preprocess.py" prior to pre-processing and thereby
  automatically fix issue #11224.
* Extended script "fix_boost_mpl_preprocess.py" to just allow checking
  if the selected Boost source-directory requires fixing because of
  issue #11224.
* Adjusted the "README.txt" accordingly.

Signed-off-by: Deniz Bahadir <dbahadir@benocs.com>
2015-05-01 18:07:59 +02:00
Deniz Bahadir 7cd0559ce8 Fix / Workaround for issue #11224. (cont.)
* Corrected a small error in a regex of "boost_mpl_preprocess.py" which
  did match too much and therefore resulted in wrong substitution in
  some cases.
* Added some more directories with files that need fixing to script
  "fix_boost_mpl_preprocess.py".

Signed-off-by: Deniz Bahadir <dbahadir@benocs.com>
2015-05-01 17:57:34 +02:00
Edward Diener 10e7609c67 Merge pull request #16 from brunocodutra/Tickets7975_8749
Fix to Tickets #7975 and #8749 - Branched off from develop. Please check regression tests to mak sure there are no problems caused by this fix.
2015-04-28 16:28:32 -04:00
Edward Diener 133a980224 Merge pull request #14 from brunocodutra/Ticket11001
Fix to Ticket #11001
2015-04-28 16:06:42 -04:00
Deniz Bahadir 95f79d95a5 Fix / Workaround for issue #11224.
Python-script "fix_boost_mpl_preprocess.py" fixes the header-problems
described in issue #11224.
Python-script "boost_mpl_preprocess.py" simplifies the pre-processing of
MPL-containers.

Signed-off-by: Deniz Bahadir <dbahadir@benocs.com>
2015-04-22 13:47:06 +02:00
Deniz Bahadir d5dcd7abb1 Removed references to non-supported compilers.
Signed-off-by: Deniz Bahadir <dbahadir@benocs.com>
2015-04-21 15:40:24 +02:00
Edward Diener 2531010a0a Added include for integral constant. 2015-04-02 08:00:13 -04:00
Edward Diener 90951ea9e4 Remove reliance on deprecated type_traits headers. Fixed apply test. 2015-04-02 07:54:36 -04:00
Marshall Clow 8a8b7b134e Merge changes from develop 2015-03-30 10:09:26 -07:00
Edward Diener 82e81345f2 Merge pull request #19 from brunocodutra/Ticket7769
Fix to pull request #13
2015-03-22 14:25:07 -04:00
Bruno Dutra 0f5451623c adding tests to attest other views don't suffer of it either 2015-03-21 22:19:56 -03:00
Bruno Dutra eaa3f26c9c fixing the issue for empty_sequence's as well 2015-03-21 22:04:52 -03:00
Bruno Dutra 07a5457dcd avoiding errors on visual studio compilers
errors were due to the way MPL_ASSERT is defined for these compilers
2015-03-21 21:08:05 -03:00
Marshall Clow f0f1680f3c Merge pull request #18 from felgru/develop
fix typos in the documentation; pull request from @felgru
2015-03-20 16:19:21 -07:00
Felix Gruber 2be4714cc5 fix typos in the documentation 2015-03-20 22:42:27 +01:00
Marshall Clow 952471841f Merge pull request #13 from brunocodutra/Ticket7769
Fix to Ticket #7769 - @brunocodutra, please watch the test runners, and ping me in a few days. I will merge to master then. Thanks!
2015-03-19 10:26:39 -07:00
Bruno Dutra c8fe35643d Fix to Tickets #7975 and #8749
Originally Tickets 7975 and 8749 referred only to insertion of keys into
maps, but the very same bug can be reproduced for sets as well.
Moreover, the removal of keys from both also suffers of the same bug.
2015-02-22 20:59:59 -03:00
Bruno Dutra feb7835e62 Adding newly added test to the Jamfile 2015-02-21 23:19:03 -03:00
Bruno Dutra faf17ec858 Adding test cases for a scenario of increased arity limit
Test cases are based on calling apply to forward to the and_ predicate
an increasing number, from 2 to 15, of true_ constants. Since the arity
limit on the current version is set to 5,
BOOST_MPL_LIMIT_METAFUNCTION_ARITY and
BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS must be appropriately set.
2015-02-21 23:15:38 -03:00
Bruno Dutra 77cda02d85 Adding a new test case for insert_range.
Tests whether insert_range works with set, set_c and map as it should.
2015-02-21 19:44:20 -02:00
Bruno Dutra f807edab2e Specializing insert_range for aux::set_tag as well
Follows the same rationale as for maps.
2015-02-21 19:42:38 -02:00
Bruno Dutra fc18efc259 Specializing insert_range for aux::map_tag
Taking advantage of the fact that order of insertion doesn't really
matter for associative sequences.
Comparing to the default implementation, which at any rate does work for
associative sequences, this specialization essencially avoids
reinserting every element of Sequence into a new sequence, besides the
fact no joint_view nor iterator_range needs to be instantiated.
2015-02-10 20:59:54 -02:00
Bruno Dutra c7798600d6 Inserting elements at the beginning of Sequence, rather than at the end
This way we take advantage of the constant-time insertion and removal of
elements at the beginning of Front Extensible sequences, such as list.
This implementation is closer to the original.
2015-02-09 20:48:55 -02:00
Bruno Dutra 1c02715e49 Fix to bug 11001
According to reference, insert_range should work for any Extensible
sequence or Extensible Associative sequence, but the default
implementation of insert_range_impl assumes a front_inserter is defined
for the given sequence, but neither Extensible nor every Extensible
Associative sequences are required to also be a Front Extensible
sequence. This fix rely only on insert, which is defined for every
Extensible sequence.
2015-02-09 00:04:07 -02:00
Bruno Dutra 6fd793c787 keeping it simple 2015-02-08 19:14:55 -02:00
Bruno Dutra ff4944f0ec using BOOST_PP_ENUM_PARAMS to generate base seq accordingly
hardcoding a base seq from 0 to 9 was the culprit behind Ticket #7769
2015-02-08 17:07:22 -02:00
K. Noel Belcourt 6a0f617a6c Revert "Merge pull request #11 from Lastique/modularization"
This reverts commit a9a1eddba8, reversing
changes made to d6bc9845ba.
2014-09-19 18:55:00 -06:00
K. Noel Belcourt a30e4a49a8 Revert "Merge pull request #12 from Lastique/modularization_fix"
This reverts commit c296697981, reversing
changes made to a9a1eddba8.
2014-09-19 18:54:50 -06:00
Edward Diener c296697981 Merge pull request #12 from Lastique/modularization_fix
Move compiler.hpp to MPL.Core to avoid circular dependency.
2014-09-17 19:31:37 -04:00
Andrey Semashev c7997e039d Moved compiler.hpp to MPL.Core to avoid circular dependency. 2014-09-16 15:43:08 +04:00
Noel Belcourt a9a1eddba8 Merge pull request #11 from Lastique/modularization
Separate MPL and MPL.Core

Unfortunately, I'm not able to test it right now.
2014-09-10 14:36:48 -06:00
Andrey Semashev cddc55a6c4 Updated tests and jamfiles to reflect the changed testing headers location. 2014-09-04 23:39:44 +04:00
Andrey Semashev 332389f50e Moved testing headers to tests to avoid dependency on Boost.Core. 2014-09-04 23:15:04 +04:00
Andrey Semashev 6064a97e3a Moved sizeof.hpp to core components. 2014-08-31 14:41:53 +04:00
Andrey Semashev a46a787a49 Use core/lightweight_test.hpp. 2014-08-31 14:11:17 +04:00
Andrey Semashev 9bbc806090 Fixed tests compilation. 2014-08-31 14:09:10 +04:00
Andrey Semashev 64f50f82aa Removed workaround for Borland Compiler 5.9 to avoid dependency on TypeTraits. 2014-08-30 21:00:05 +04:00
Andrey Semashev 6b37526352 Added a readme file. 2014-08-30 20:48:46 +04:00
Andrey Semashev b2d6e667a0 Added a sublibs tag file. 2014-08-30 20:42:30 +04:00
Andrey Semashev a469a67ab8 Removed dependency on TypeTraits. 2014-08-30 20:39:07 +04:00
Andrey Semashev e296279084 Moved min/max to MPL.Core. 2014-08-30 20:26:01 +04:00
Andrey Semashev 07bff9e105 Moved tests for core components to the sub-library. 2014-08-30 20:15:54 +04:00
Andrey Semashev 82890fd03e Moved Boost.MPL.Core headers to a sublibrary. 2014-08-30 17:21:16 +04:00
Edward Diener d6bc9845ba Merge pull request #10 from danieljames/metadata
Create metadata file.
2014-08-18 11:38:29 -04:00
Daniel James afe0e6bbc4 Add metadata file. 2014-08-18 15:07:32 +01:00
Eric Niebler 0341108f6b add back the has_xxx workaround for msvc if used with nvcc 2014-07-09 17:12:31 -04:00
Eric Niebler 2b6fba6f6c eliminate unnecessary workaround for modern msvc versions 2014-07-09 17:11:36 -04:00
Edward Diener bde91646cf Merge pull request #9 from ericniebler/develop
add back the has_xxx workaround for msvc if used with nvcc
2014-07-07 19:36:08 -04:00
Eric Niebler aec459a49c add back the has_xxx workaround for msvc if used with nvcc 2014-07-07 15:47:06 -07:00
Edward Diener 1169c26856 Merge pull request #8 from ericniebler/has-xxx-msvc
eliminate unnecessary workaround for modern msvc versions
2014-06-27 07:42:17 -04:00
Eric Niebler 6893e5e5de eliminate unnecessary workaround for modern msvc versions 2014-06-26 22:25:53 -07:00
Peter Dimov e6bca9d8fc Merge branch 'develop' 2014-06-05 00:25:39 +03:00
Peter Dimov 0b6167c840 Remove dependency on Detail by using Predef directly. 2014-06-05 00:23:41 +03:00
Paul f976861e13 Add test for constexpr conversion operator 2014-05-16 07:49:35 -06:00
Paul ed58434c88 Add constexpr to conversion operator for bool integral constants 2014-05-16 07:49:35 -06:00
Paul 1f482c4fa1 Add constexpr to conversion operator for integral constants 2014-05-16 07:49:34 -06:00
Noel Belcourt d032c78c1d Merge pull request #6 from boostorg/develop
Merge to master
2014-05-08 20:24:29 -06:00
Noel Belcourt e5e30a45a4 Merge pull request #5 from ericniebler/develop
mpl::for_each works on nvidia gpu's

Nice, thanks.
2014-05-01 19:38:00 -06:00
Eric Niebler 7f823bec1c mpl::for_each works on nvidia gpu's 2014-05-01 15:38:13 -07:00
Marshall Clow cafafafea3 Merge pull request #4 from robertramey/develop
added mol print functionally for Clang compiler
2014-03-26 19:10:36 -07:00
Robert Ramey de26efa6ea added mol print functionally for Clang compiler 2014-03-26 12:41:20 -07:00
Daniel James 04d02649d8 Merge branch 'develop'
No-op since develop and master are now the same - will make it easier to
merge future changes.
2014-03-25 08:34:40 +00:00
Daniel James db7e720ce1 Revert Stephen Kelly's changes.
They should really wait until MPL's dependencies have dealt with his
changes.
2014-03-25 08:33:44 +00:00
Edward Diener 51b8f0e100 Cast to long for c++11.
[SVN r86693]
2014-03-23 15:52:52 -04:00
Edward Diener 77651e4aa1 In clang using VC++ RTL the VC++ macros are keywords.
[SVN r86682]
2014-03-23 15:52:24 -04:00
Daniel James 0be4fc4b34 Merge whitespace fix. 2014-03-20 23:01:00 +00:00
Daniel James 858652cd0d Create merge base for develop.
From cherry-picking changes into develop.
2014-03-20 22:58:58 +00:00
Daniel James 8a2e64723c Merge cherry-picked changes from develop. 2014-03-20 22:57:52 +00:00
Daniel James 27815b8d37 Merge pull request #2 from danieljames/develop-cherry-pick
Cherry pick old changes from master, and a small whitespace fix.
2014-03-20 22:53:28 +00:00
Daniel James ea6c446ad6 Fix whitespace in 'test/always.cpp'. 2014-03-17 11:38:13 +00:00
Aleksey Gurtovoy bf895af8f7 Docs/cosmetic: fix td/th border style in Firefox
[SVN r69117]
2014-03-02 23:42:31 +00:00
Aleksey Gurtovoy d1a05aed0a Closing ticket #816
[SVN r69116]
2014-03-02 23:42:31 +00:00
Joel Falcou 2d3c8f076d Applied an adapted version of patch from Ticket #4364
[SVN r72020]
2014-03-02 23:40:28 +00:00
Joel Falcou 94154603ec mpl::always is now nullary. Test is updated to take care of new possible calls using apply and apply0.
[SVN r71163]
2014-03-02 23:40:10 +00:00
Joel Falcou 74fef329d4 Applied documentation patch from Daniel James. Fix Ticket #5240
[SVN r71159]
2014-03-02 23:39:50 +00:00
Joel Falcou 3bf644fc10 Fully qualified mpl::for_each call to prevent conflict with phoenix::for_each on
some compiler.

[SVN r69601]
2014-03-02 23:39:33 +00:00
Steven Watanabe 8886e3d7da Fix name in list example. Fixes #4875.
[SVN r67105]
2014-03-02 23:39:14 +00:00
Steven Watanabe e174e49e32 Fix set_c iterators.
[SVN r65166]
2014-03-02 23:38:55 +00:00
Neil Groves 11b9928353 Improve compatibility with compilers other than GCC.
[SVN r61922]
2014-03-02 23:38:35 +00:00
Aleksey Gurtovoy 4cee88eae9 MPL refmanual: for_each doc fixes (thanks to Emil Dotchevski)
[SVN r55858]
2014-03-02 23:38:13 +00:00
Aleksey Gurtovoy acdd0e5a92 dummy file
[SVN r11268]
2014-03-02 23:37:55 +00:00
Edward Diener ec73776cbd Cast to long for c++11.
[SVN r86693]
2013-11-14 04:43:57 +00:00
Edward Diener cccddd65c7 In clang using VC++ RTL the VC++ macros are keywords.
[SVN r86682]
2013-11-13 17:38:31 +00:00
Beman Dawes 3e3b4aeef2 Merge 84443 from trunk, to fix mpl assert failures for msvc in many libraries.
[SVN r86514]
2013-10-29 13:15:03 +00:00
Stephen Kelly 2c77a2b9c1 Fix mpl on MSVC.
MSVC defines this macro to 0.

[SVN r86263]
2013-10-12 13:07:26 +00:00
Stephen Kelly c77da6a6da MPL: Limit a GCC workaround to a version tested to not need it.
[SVN r86261]
2013-10-12 10:32:40 +00:00
Stephen Kelly eccea8a324 MPL: Remove obsolete GCC version checks.
[SVN r86260]
2013-10-12 10:19:11 +00:00
Stephen Kelly 553aa2e52f Remove remaining occurances of BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
These evaded scripting.

[SVN r86249]
2013-10-11 23:22:36 +00:00
Stephen Kelly f580ae3b0a Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
[SVN r86248]
2013-10-11 23:20:59 +00:00
Stephen Kelly b519e4b12b Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #elif...#else...#endif blocks.

[SVN r86247]
2013-10-11 23:19:44 +00:00
Stephen Kelly d6d7e5abe0 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#else...#endif blocks.

[SVN r86245]
2013-10-11 23:17:48 +00:00
Stephen Kelly 2a61f750a9 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#endif conditions.

[SVN r86244]
2013-10-11 23:15:00 +00:00
Stephen Kelly 9b42f0453e Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifdef...#endif blocks.

[SVN r86243]
2013-10-11 23:13:10 +00:00
Stephen Kelly 61d75128b4 Remove obsolete files.
[SVN r86242]
2013-10-11 23:11:35 +00:00
Stephen Kelly d2fcd238d6 MPL: Remove obsolete GCC version checks.
[SVN r86070]
2013-09-30 15:59:23 +00:00
Stephen Kelly 27b31c31be MPL: Remove nntp_decl.hpp and obsolete includes.
[SVN r85961]
2013-09-26 14:10:37 +00:00
Stephen Kelly 8143a00562 MPL: Remove use of obsolete macro.
[SVN r85958]
2013-09-26 13:07:02 +00:00
Stephen Kelly 18d0db5b5c MPL: Remove use of obsolete macro.
[SVN r85957]
2013-09-26 13:06:05 +00:00
Stephen Kelly 76dab04fa9 MPL: Remove obsolete MSVC version checks.
[SVN r85956]
2013-09-26 13:05:50 +00:00
Stephen Kelly 50865751ae MPL: Remove workaround for no-longer-supported MSVC
[SVN r85948]
2013-09-26 09:47:38 +00:00
Stephen Kelly 83d7bb938f MPL: Remove apply-wrap workaround for no-longer-supported MSVC
[SVN r85947]
2013-09-26 09:47:19 +00:00
Stephen Kelly 310ab7a6ce MPL: Remove use of obsolete macro.
[SVN r85946]
2013-09-26 09:47:03 +00:00
Stephen Kelly 403aea61fe MPL: Remove MSVC 6 and 7 early template instantiation workaround.
[SVN r85945]
2013-09-26 09:46:46 +00:00
Stephen Kelly 3b026baefe MPL: Remove obsolete MSVC version checks.
[SVN r85944]
2013-09-26 09:45:59 +00:00
Stephen Kelly 76a5c4cf54 MPL: Remove obsolete files for old MSVC compilers.
[SVN r85943]
2013-09-26 09:45:41 +00:00
Stephen Kelly cefaca1789 MPL: Bump the MSVC compiler requirements
[SVN r85942]
2013-09-26 09:44:29 +00:00
Stephen Kelly de207e3775 MPL: Remove assert workaround for no-longer-supported MSVC.
[SVN r85892]
2013-09-25 10:28:10 +00:00
Stephen Kelly 8951fa2a3b MPL: Remove MSVC workaround for void templates.
[SVN r85891]
2013-09-25 10:27:56 +00:00
Stephen Kelly 67f5d73999 MPL: Remove use of obsolete BOOST_MPL_CFG_NO_APPLY_TEMPLATE
It was only defined for MSVC versions which are no longer supported.

[SVN r85887]
2013-09-25 08:26:46 +00:00
Stephen Kelly 50f26179f6 MPL: Remove use of obsolete BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
[SVN r85886]
2013-09-25 08:26:31 +00:00
Stephen Kelly 0e065bc65a MPL: Remove use of obsolete BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
This macro is no longer defined for any compiler.

[SVN r85885]
2013-09-25 08:26:10 +00:00
Steven Watanabe d6c3a16e1e Make BOOST_WORKAROUND consistent.
[SVN r84443]
2013-05-23 14:42:25 +00:00
Steven Watanabe 6e78a8f0f4 Merge [81027] from the trunk.
[SVN r84442]
2013-05-23 14:38:22 +00:00
Steven Watanabe aa8e43a017 Work around VC11 bug when evaluating nested BOOST_MPL_ASSERTs.
[SVN r81027]
2012-10-20 16:43:51 +00:00
Joel Falcou 7d2a04eea3 Applied an adapted version of patch from Ticket #4364
[SVN r72020]
2011-05-17 18:16:59 +00:00
Joel Falcou f8e9b04e6a mpl::always is now nullary. Test is updated to take care of new possible calls using apply and apply0.
[SVN r71163]
2011-04-10 11:27:54 +00:00
Joel Falcou de377710d4 Applied documentation patch from Daniel James. Fix Ticket #5240
[SVN r71159]
2011-04-10 07:07:01 +00:00
Joel Falcou fc13a7ac60 Fully qualified mpl::for_each call to prevent conflict with phoenix::for_each on
some compiler.



[SVN r69601]
2011-03-06 11:09:13 +00:00
Aleksey Gurtovoy 161b05edfb Docs/cosmetic: fix td/th border style in Firefox
[SVN r69117]
2011-02-21 10:00:08 +00:00
Aleksey Gurtovoy 3a4c350910 Closing ticket #816
[SVN r69116]
2011-02-21 09:41:45 +00:00
Steven Watanabe 7cd1d88886 Fix name in list example. Fixes #4875.
[SVN r67105]
2010-12-08 17:21:32 +00:00
Eric Niebler 61f3e9cb9a Merged revisions 65167 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r65167 | steven_watanabe | 2010-09-01 09:08:21 -0700 (Wed, 01 Sep 2010) | 1 line
  
  Fix for_each test for C++0x
........


[SVN r66257]
2010-10-29 21:36:38 +00:00
Steven Watanabe 08c6156599 Fix for_each test for C++0x
[SVN r65167]
2010-09-01 16:08:21 +00:00
Steven Watanabe 2a2c4d2895 Fix set_c iterators.
[SVN r65166]
2010-09-01 15:16:53 +00:00
Daniel Walker cad61ebca3 merged [64705] MPL documentation from trunk
[SVN r64743]
2010-08-11 17:04:29 +00:00
Steven Watanabe 6f63e9d0c6 Update generated html docs for MPL.
[SVN r64705]
2010-08-09 20:07:24 +00:00
Daniel Walker 41ab25a8a1 merged [64144] from trunk
[SVN r64146]
2010-07-19 00:46:31 +00:00
Daniel Walker 45d0bcadc2 fixed missing header dependency
[SVN r64144]
2010-07-18 23:59:27 +00:00
Daniel Walker cbd633b4d0 merged changeset 63726 from trunk
[SVN r63907]
2010-07-12 01:36:38 +00:00
Daniel Walker ff2df79e35 removed arity detection from has_xxx_template
[SVN r63726]
2010-07-07 20:44:59 +00:00
Aleksey Gurtovoy fb038c188d Manually merge changesets @55858 and @58111 from the trunk (svnmerge.py refuses to)
[SVN r63521]
2010-07-02 09:26:29 +00:00
Aleksey Gurtovoy 315ad7d60d Merged revisions 59248 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r59248 | agurtovoy | 2010-01-23 23:45:36 -0600 (Sat, 23 Jan 2010) | 1 line
  
  Fix bitand/bitor conflicts with iso64.h header
........


[SVN r63520]
2010-07-02 08:59:55 +00:00
Aleksey Gurtovoy ea638a4478 Merged revisions 62579 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r62579 | steven_watanabe | 2010-06-08 09:24:55 -0500 (Tue, 08 Jun 2010) | 1 line
  
  Add BOOST_MPL_HAS_XXX_TEMPLATE_DEF.  Fixes #861
........


[SVN r63518]
2010-07-02 08:32:03 +00:00
Eric Niebler e66d77051e Merged revisions 63024 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r63024 | eric_niebler | 2010-06-16 13:57:41 -0400 (Wed, 16 Jun 2010) | 1 line
  
  make mpl::string work with mpl::transform
........


[SVN r63079]
2010-06-18 13:21:30 +00:00
Eric Niebler a5ba971297 make mpl::string work with mpl::transform
[SVN r63024]
2010-06-16 17:57:41 +00:00
Steven Watanabe 360322e894 Add BOOST_MPL_HAS_XXX_TEMPLATE_DEF. Fixes #861
[SVN r62579]
2010-06-08 14:24:55 +00:00
Neil Groves 52d8442055 Improve compatibility with compilers other than GCC.
[SVN r61922]
2010-05-11 22:20:19 +00:00
Neil Groves 9e138e28ca Removed workaround for MSVC == 1600 in eval_if.hpp
[SVN r61921]
2010-05-11 21:33:24 +00:00
Neil Groves 75e47b8597 Remove regression introduced by my previous 'fix'
[SVN r61920]
2010-05-11 21:12:26 +00:00
Neil Groves b6e98cdd5a Fixed defect that showed up with Visual C++ 10. This has been affecting numerous libraries as a knock-on effect.
[SVN r61916]
2010-05-11 18:30:04 +00:00
Aleksey Gurtovoy c5621d99cd MPL: merge fix for ticket #1992
[SVN r61591]
2010-04-26 21:31:09 +00:00
Aleksey Gurtovoy 31a2c78a5a MPL: merge fix for ticket #4061
[SVN r61584]
2010-04-26 18:48:26 +00:00
Hartmut Kaiser cc82b7a924 MPL: fixed #4061: gcc-4.5 compilation problems related to arity_helper, applied attached patch to the main aux_/template_arity.hpp and regenerated the corresponding file preprocessed/gcc/template_arity.hpp. No other preprocessed files are affected.
This patch seemed to be fine as all it does is to qualify an internal name in order to avoid it being looked up through ADL. This appears to be reasonably safe as this name is internal and not supposed to be found using ADL in the first place.


[SVN r61467]
2010-04-21 17:19:06 +00:00
Aleksey Gurtovoy 4678423fee Fix for #1992
[SVN r60888]
2010-03-28 14:23:38 +00:00
Aleksey Gurtovoy 38e0d6157f Fix bitand/bitor conflicts with iso64.h header
[SVN r59248]
2010-01-24 05:45:36 +00:00
Aleksey Gurtovoy 9e7f06d29b Fix bogus protect example
[SVN r58111]
2009-12-03 10:44:05 +00:00
Troy D. Straszheim ae88433250 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 62d52d9d8b 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
Aleksey Gurtovoy b74cf94d04 MPL refmanual: for_each doc fixes (thanks to Emil Dotchevski)
[SVN r55858]
2009-08-29 08:48:11 +00:00
Aleksey Gurtovoy e6ba4cc17c MPL: merge test for #2042/#3298 from the trunk (thanks to Steven Watanabe for the fix!)
[SVN r55752]
2009-08-24 04:17:30 +00:00
Aleksey Gurtovoy 294dd90076 MPL: merge fix for #2042/#3298 from the trunk (thanks to Steven Watanabe for the fix!)
[SVN r55751]
2009-08-24 04:11:00 +00:00
Steven Watanabe d38f271fae Use order instead of size to find the next order in the non-typeof implementation of mpl::insert for mpl::map. Fixes #2042.
[SVN r55727]
2009-08-23 04:42:25 +00:00
Aleksey Gurtovoy 15a9930acb MPL: merge fix for #3337 from the trunk (thanks Steven!)
[SVN r55679]
2009-08-20 07:50:16 +00:00
Steven Watanabe c1de64359f Provide definitions for the dummy structs used by has_push_back_impl and has_push_front_impl so that they work with Fusion containers. Fixes #3337.
[SVN r55672]
2009-08-19 22:52:27 +00:00
Aleksey Gurtovoy 4f0675cd13 Merge boost/mpl fixes from the trunk
[SVN r55648]
2009-08-18 05:16:53 +00:00
Aleksey Gurtovoy 16dd55a902 Merge libs/mpl from the trunk
[SVN r55647]
2009-08-18 05:00:17 +00:00
Aleksey Gurtovoy b4f37ef70f More MPL refmanual fixes
[SVN r55643]
2009-08-18 01:22:15 +00:00
Aleksey Gurtovoy c40417c2d3 MPL refmanual fixes
[SVN r55641]
2009-08-18 01:03:26 +00:00
Aleksey Gurtovoy 9028f43fc9 MPL refmanual: add forgotten docs
[SVN r55635]
2009-08-17 23:36:52 +00:00
Aleksey Gurtovoy 43d395d050 Updated MPL refmanul docs + new style
[SVN r55624]
2009-08-17 11:30:52 +00:00
Aleksey Gurtovoy e42394d3ec Assign copyright back to Eric (fixing copy & paste error in changeset 55621)
[SVN r55623]
2009-08-17 11:01:40 +00:00
Aleksey Gurtovoy 5442b57228 Assign copyright back to Eric (fixing copy & paste error in changeset 55621)
[SVN r55622]
2009-08-17 10:45:29 +00:00
Aleksey Gurtovoy 0efce8938c MPL refmanul: fix copyrights, move all build files in the _build dir
[SVN r55621]
2009-08-17 10:27:13 +00:00
Eric Niebler 5a2abc4d58 more generic c_str implementation from Mathis Gaunard
[SVN r55377]
2009-08-03 00:24:46 +00:00
Eric Niebler 837a031a0e Merged revisions 55146 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r55146 | eric_niebler | 2009-07-24 10:22:50 -0700 (Fri, 24 Jul 2009) | 1 line
  
  fix bug with signed char
........


[SVN r55206]
2009-07-27 18:39:32 +00:00
Troy D. Straszheim 991277330b 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
Eric Niebler e1fa211c83 fix bug with signed char
[SVN r55146]
2009-07-24 17:22:50 +00:00
Troy D. Straszheim e5dfdf47ed Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Steven Watanabe e6024bc6f7 Call clear before checking for the existence of push_back
[SVN r54949]
2009-07-14 16:52:05 +00:00
Steven Watanabe 1ba6d35b4d Fix default implementation of has_push_back and has_push_front
[SVN r54948]
2009-07-14 16:49:45 +00:00
Eric Niebler 4599fe865f Merged revisions 52208,52241,52271,52314-52315,52317,52361,52542,52579 via svnmerge from
https://svn.boost.org/svn/boost/trunk


[SVN r53838]
2009-06-13 01:03:44 +00:00
Aleksey Gurtovoy 78364897a1 Further MPL doc generation fixes
[SVN r53747]
2009-06-08 13:12:50 +00:00
Aleksey Gurtovoy e1c57fa777 More MPL refmanual doc generation fixes
[SVN r53744]
2009-06-08 11:16:27 +00:00
Gennadiy Rozental bade8a503a avoid C style casts
[SVN r53667]
2009-06-06 09:34:12 +00:00
Aleksey Gurtovoy 2d5e02f382 Fix #640 in sources
[SVN r53534]
2009-06-01 12:55:33 +00:00
Aleksey Gurtovoy 4169d45c82 Bring up MPL refmanual docs generation
[SVN r53532]
2009-06-01 11:50:35 +00:00
Hartmut Kaiser 54bf81da35 Fixed a bogus preprocessor directive
[SVN r53189]
2009-05-22 20:07:55 +00:00
Hartmut Kaiser d53111cfc8 Fixed a bogus preprocessor directive
[SVN r53188]
2009-05-22 20:06:55 +00:00
Jeremiah Willcock 14b652ed90 Fixed most tab and min/max issues from trunk inspection report
[SVN r53141]
2009-05-20 19:19:00 +00:00
Eric Niebler 58be5a2bd5 portability patch for sunpro on little-endian platforms
[SVN r52579]
2009-04-24 15:23:40 +00:00
Eric Niebler dfc596a7bf isolate implementation-defined behavior in macros for easier portability
[SVN r52577]
2009-04-23 21:46:30 +00:00
Eric Niebler 9708dbc454 add workaround for sun
[SVN r52542]
2009-04-22 16:36:18 +00:00
Aleksey Gurtovoy cec3e22b63 terminology.rst -> Terminology.rst (step 2)
[SVN r52503]
2009-04-20 08:43:50 +00:00
Aleksey Gurtovoy 81135e4e91 terminology.rst -> Terminology.rst (step 1)
[SVN r52502]
2009-04-20 08:41:04 +00:00
Eric Niebler d88ee00afe saving some additional template instantiations
[SVN r52361]
2009-04-12 23:07:37 +00:00
Eric Niebler 5cac79c3e6 add and document BOOST_MPL_LIMIT_STRING_SIZE and mpl/limits/string.hpp
[SVN r52317]
2009-04-11 06:30:53 +00:00
Eric Niebler 2cf51a12f1 fix off-by-1 errors
[SVN r52315]
2009-04-11 06:07:54 +00:00
Eric Niebler 0ee68a2c76 mpl::string is a bidirectional sequence, not random access; c_str is a separate metafunction, not a class static
[SVN r52314]
2009-04-11 05:48:51 +00:00
Eric Niebler c7025170c7 workaround for msvc-8.0 bug
[SVN r52271]
2009-04-08 21:57:03 +00:00
Eric Niebler bf25909150 msvc-7.1 portability fix, signed/unsigned warning fix
[SVN r52241]
2009-04-07 19:53:53 +00:00
Eric Niebler a96b0e9924 add mpl::char_ and mpl::string, fixes #2905
[SVN r52208]
2009-04-06 06:00:57 +00:00
Aleksey Gurtovoy 98008e8e21 Fix prior's requirements (see http://article.gmane.org/gmane.comp.lib.boost.devel/187753/)
[SVN r52207]
2009-04-06 04:52:19 +00:00
Aleksey Gurtovoy 8513479231 mpl/doc/src/README.txt: expand on 'Install prerequisites' (see http://article.gmane.org/gmane.comp.lib.boost.devel/187592)
[SVN r52206]
2009-04-06 04:28:16 +00:00
Aleksey Gurtovoy 2ab6ebd29b apply2 -> apply_wrap2 (see http://article.gmane.org/gmane.comp.lib.boost.devel/187573)
[SVN r52205]
2009-04-06 02:38:36 +00:00
Aleksey Gurtovoy 83f2c7a600 Fix fold/reverse_fold docs (http://thread.gmane.org/gmane.comp.lib.boost.devel/187366)
[SVN r51791]
2009-03-16 06:28:47 +00:00
Troy D. Straszheim 951004474c merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Michael A. Jackson 699740a53e Updating dependency information for modularized libraries.
[SVN r49628]
2008-11-07 17:05:27 +00:00
Michael A. Jackson 59b2f369d1 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 74bdc378ea 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
Aleksey Gurtovoy 3aca8ba417 Merged revisions 48658 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r48658 | rwgk | 2008-09-07 21:13:41 -0500 (Sun, 07 Sep 2008) | 1 line
  
  mpl/find_if.hpp: MIPSpro 7.41 workaround
........


[SVN r49274]
2008-10-11 07:22:05 +00:00
Aleksey Gurtovoy 638af6028b Merged revisions 49260 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49260 | agurtovoy | 2008-10-10 16:59:29 -0500 (Fri, 10 Oct 2008) | 1 line
  
  has_xxx: Adjust MSVC 7.1/8.0 workaround (ticket #1317)
........


[SVN r49273]
2008-10-11 06:54:06 +00:00
Aleksey Gurtovoy 6ae9e83763 Merged revisions 49246 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49246 | agurtovoy | 2008-10-10 05:48:48 -0500 (Fri, 10 Oct 2008) | 1 line
  
  MPL: regenerate preprocessed headers for BCC (ticket #2345)
........


[SVN r49272]
2008-10-11 06:50:46 +00:00
Aleksey Gurtovoy 3abcd697ff Merged revisions 49245 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49245 | agurtovoy | 2008-10-10 05:23:28 -0500 (Fri, 10 Oct 2008) | 1 line
  
  Okay, it was partially tested, on vector_c only. Restore it conditionally
........


[SVN r49271]
2008-10-11 06:46:00 +00:00
Aleksey Gurtovoy f0c26b3f47 Merged revisions 49244 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49244 | agurtovoy | 2008-10-10 05:11:23 -0500 (Fri, 10 Oct 2008) | 1 line
  
  Fix preprocessed headers generation
........


[SVN r49270]
2008-10-11 06:35:10 +00:00
Aleksey Gurtovoy c49c03ea77 Merged revisions 49241 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49241 | agurtovoy | 2008-10-10 04:24:39 -0500 (Fri, 10 Oct 2008) | 1 line
  
  $Source$ -> $Id$
........


[SVN r49269]
2008-10-11 06:30:50 +00:00
Aleksey Gurtovoy 1bba6367cc Merged revisions 49240 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49240 | agurtovoy | 2008-10-10 04:21:07 -0500 (Fri, 10 Oct 2008) | 1 line
  
  $Source$ -> $Id$
........


[SVN r49268]
2008-10-11 06:26:17 +00:00
Aleksey Gurtovoy bf864547c1 Merged revisions 49239 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49239 | agurtovoy | 2008-10-10 04:10:26 -0500 (Fri, 10 Oct 2008) | 1 line
  
  $Source$ -> $Id$
........


[SVN r49267]
2008-10-11 06:19:02 +00:00
Aleksey Gurtovoy 5980a45b30 Merged revisions 49228 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49228 | nmusatti | 2008-10-09 17:06:06 -0500 (Thu, 09 Oct 2008) | 1 line
  
  Applied patch from ticket #2345
........


[SVN r49266]
2008-10-11 06:06:10 +00:00
Aleksey Gurtovoy afbaa1252e has_xxx: Adjust MSVC 7.1/8.0 workaround (ticket #1317)
[SVN r49260]
2008-10-10 21:59:29 +00:00
Daniel James 240607a350 Merge the mpl fixes for gcc 4.4. (But not the python ones). Refs #2069.
Merged revisions 48960 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r48960 | rwgk | 2008-09-25 05:49:24 +0100 (Thu, 25 Sep 2008) | 1 line
  
  boost/python, boost/mpl: gcc 4.4 compatibility (see http://svn.boost.org/trac/boost/ticket/2069)
........


[SVN r49257]
2008-10-10 19:58:46 +00:00
Aleksey Gurtovoy 8e75b0f4ae MPL: regenerate preprocessed headers for BCC (ticket #2345)
[SVN r49246]
2008-10-10 10:48:48 +00:00
Aleksey Gurtovoy 6ed8bf8572 Okay, it was partially tested, on vector_c only. Restore it conditionally
[SVN r49245]
2008-10-10 10:23:28 +00:00
Aleksey Gurtovoy 48f67ece2e Fix preprocessed headers generation
[SVN r49244]
2008-10-10 10:11:23 +00:00
Aleksey Gurtovoy 5f8bfd09a4 Revert changeset 31196 -- the corresponding preprocessed headers has never been regenerated since the change and therefore it has never been properly tested
[SVN r49243]
2008-10-10 09:59:34 +00:00
Aleksey Gurtovoy 7dbbf92d37 $Source$ -> $Id$
[SVN r49241]
2008-10-10 09:24:39 +00:00
Aleksey Gurtovoy a6c47df14c $Source$ -> $Id$
[SVN r49240]
2008-10-10 09:21:07 +00:00
Aleksey Gurtovoy d1197e1f7d $Source$ -> $Id$
[SVN r49239]
2008-10-10 09:10:26 +00:00
Aleksey Gurtovoy 6371d09c89 Test $HeadURL$ keyword substitution
[SVN r49238]
2008-10-10 09:00:11 +00:00
Aleksey Gurtovoy 2d97b44886 Test $Id$ keyword substitution
[SVN r49237]
2008-10-10 08:48:36 +00:00
Aleksey Gurtovoy 56c8b411c9 Test $URL$ keyword substitution
[SVN r49236]
2008-10-10 08:43:45 +00:00
Nicola Musatti 0e43d67c9b Applied patch from ticket #2345
[SVN r49228]
2008-10-09 22:06:06 +00:00
Ralf W. Grosse-Kunstleve 51adb2aa8d boost/python, boost/mpl: gcc 4.4 compatibility (see http://svn.boost.org/trac/boost/ticket/2069)
[SVN r48960]
2008-09-25 04:49:24 +00:00
Ralf W. Grosse-Kunstleve 54b5387eb2 mpl/find_if.hpp: MIPSpro 7.41 workaround
[SVN r48658]
2008-09-08 02:13:41 +00:00
Aleksey Gurtovoy 0b84aa1225 Merge in critical bug fixes from the trunk (r46570, 46546 and 46620)
[SVN r47650]
2008-07-21 08:00:06 +00:00
Aleksey Gurtovoy b953a6b63b Fix redeclaration errors detected by GCC 4.3.0 (ticket #1528)
[SVN r46620]
2008-06-23 02:31:22 +00:00
Aleksey Gurtovoy 5d7d593327 Fix duplicate include guards (ticket #1568)
[SVN r46570]
2008-06-21 02:55:14 +00:00
Aleksey Gurtovoy 8335231e2e Proper (well, better) diagnostics for passing non-sequence types to sequence algoritms/metafunctions, see http://thread.gmane.org/gmane.comp.lib.boost.user/36876
[SVN r46546]
2008-06-20 04:43:41 +00:00
Aleksey Gurtovoy 52f7685342 MPL docs: README, build script, and numerous fixes to bring up docs generation (unfinished)
[SVN r46462]
2008-06-17 21:46:20 +00:00
Beman Dawes 4d29901677 Apply changeset 43865, fixing #1718
[SVN r43872]
2008-03-26 17:13:05 +00:00
Dave Abrahams 827aa4828a Work around intel-win-10.0 preprocessor bug
[SVN r43865]
2008-03-25 23:06:50 +00:00
Daniel James 94523928d4 Merged revisions 43206,43208-43213 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43206 | danieljames | 2008-02-10 09:55:03 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix some broken links.
........
  r43209 | danieljames | 2008-02-10 14:56:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Link to people pages on the website, as they've been removed from the download.
........
  r43210 | danieljames | 2008-02-10 15:02:17 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Point links to the pages that used to be in 'more' to the site.
........
  r43212 | danieljames | 2008-02-10 16:10:16 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Fix links on the home page as well.
........
  r43213 | danieljames | 2008-02-10 16:21:22 +0000 (Sun, 10 Feb 2008) | 1 line
  
  Generated documentation which is no longer generated.
........


[SVN r43214]
2008-02-10 16:39:38 +00:00
Daniel James 73d2968369 Point links to the pages that used to be in 'more' to the site.
[SVN r43210]
2008-02-10 15:02:17 +00:00
K. Noel Belcourt 159d23ff7a Fixes #640
Corrected the mpl push_front html documentation.



[SVN r42985]
2008-01-26 18:51:28 +00:00
Aleksey Gurtovoy b990fbcd2a map doc clarification (thanks to Larry Evans)
[SVN r42396]
2008-01-01 01:41:32 +00:00
Beman Dawes b91fcf5664 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes 7ec3e698d6 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Dave Abrahams 842489b5f2 Added missing copyright/license
[SVN r40862]
2007-11-06 23:39:09 +00:00
Dave Abrahams 4f93f21dcc Merging some of the more obvious changes from RC_1_34_0
[SVN r40714]
2007-11-03 03:25:13 +00:00
Beman Dawes d71c289879 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
Nicola Musatti 00ad56405f Updated to support C++Builder 2007 Update 3 (bcc32 5.9.2)
[SVN r39663]
2007-10-02 20:32:05 +00:00
Boris Gubenko 7775ef9867 add conditionalization for g++ on HP-UX
[SVN r39190]
2007-09-11 16:24:28 +00:00
Vladimir Prus 51deca6bae Update to V2
[SVN r38529]
2007-08-08 19:39:42 +00:00
Vladimir Prus 8509f491e9 Update to V2
[SVN r38528]
2007-08-08 19:38:27 +00:00
Vladimir Prus 925a4f4359 Remove V1 Jamfiles
[SVN r38516]
2007-08-08 19:02:26 +00:00
nobody c3184eb9dd This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Aleksey Gurtovoy fa401f0e4d Merge documentation fixes from RC_1_34_0
[SVN r38223]
2007-07-16 02:26:38 +00:00
Aleksey Gurtovoy 7518d7dab3 Ticket #907
[SVN r38169]
2007-07-09 06:41:59 +00:00
Thomas Witt e42b58021c Patch from Trac #583.
[SVN r37849]
2007-06-01 16:31:21 +00:00
Aleksey Gurtovoy d970498445 Add an example that shows use of if_ with dependent entities
[SVN r37810]
2007-05-29 06:59:16 +00:00
Aleksey Gurtovoy b4048c1b75 'set' fixes + more thorough regression tests
[SVN r37335]
2007-04-02 07:42:41 +00:00
Aleksey Gurtovoy 3437477789 for-each.html at el.
[SVN r37316]
2007-03-29 08:30:29 +00:00
Aleksey Gurtovoy a352567283 Fix docs generation
[SVN r37315]
2007-03-29 07:47:35 +00:00
Aleksey Gurtovoy 6d0ea17411 Fix BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC (merged from RC_1_34_0)
[SVN r36831]
2007-01-29 07:39:19 +00:00
Aleksey Gurtovoy 6cd485016b Fix BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC
[SVN r36830]
2007-01-29 07:28:45 +00:00
nobody dab3eafd37 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r36324]
2006-12-11 05:02:35 +00:00
Aleksey Gurtovoy 9a516fc3c1 Fix syntax errors
[SVN r36251]
2006-12-02 23:45:58 +00:00
Aleksey Gurtovoy 12c4f8e95c Introduce BOOST_MPL_AUX_PP_COUNTER to workaround MSVC 7.0+ issue with __LINE__ and Edit & Continue mode (http://thread.gmane.org/gmane.comp.lib.boost.user/23207/)
[SVN r36250]
2006-12-02 23:42:34 +00:00
Aleksey Gurtovoy 0fb7bfb970 Merge platform fixes from HEAD
[SVN r36168]
2006-11-23 19:57:11 +00:00
Aleksey Gurtovoy ce552c8aaa Add missing import directive
[SVN r36167]
2006-11-23 19:42:01 +00:00
Aleksey Gurtovoy e1fc6f383b Get rid of platform assumptions
[SVN r36166]
2006-11-23 19:41:11 +00:00
Aleksey Gurtovoy f25c106dda Merge Borland 5.8.2 fixes from RC_1_34_0
[SVN r36117]
2006-11-20 18:02:17 +00:00
Aleksey Gurtovoy c50567d0c0 Borland 5.8.2 fixes (thanks to Alisdair Meredith)
[SVN r36116]
2006-11-20 17:59:29 +00:00
Dave Abrahams 9ab927ebbd *** empty log message ***
[SVN r36040]
2006-11-14 19:29:49 +00:00
Aleksey Gurtovoy 50ad0eac22 Merge comma fix from RC_1_34_0
[SVN r36001]
2006-11-10 23:16:57 +00:00
Aleksey Gurtovoy 329ec97e89 Apply trailing comma patch from Ian McCulloch (http://article.gmane.org/gmane.comp.lib.boost.devel/149741)
[SVN r36000]
2006-11-10 23:15:50 +00:00
Aleksey Gurtovoy 76680cf30e Merge GCC warnings fix from RC_1_34_0
[SVN r35998]
2006-11-10 21:32:25 +00:00
Aleksey Gurtovoy e05b199c9f Revert to using enums for GCC, see http://article.gmane.org/gmane.comp.lib.boost.devel/150691 (this does not reintroduce GCC regressions/#29518, the actual fix for them that worked was made in revision 1.13.14.4)
[SVN r35997]
2006-11-10 21:31:19 +00:00
Aleksey Gurtovoy 1e2ecf080c Merge Borland fixes from RC_1_34_0
[SVN r35963]
2006-11-10 00:57:02 +00:00
Aleksey Gurtovoy 80c25280ae Restore status-quo for Borland
[SVN r35962]
2006-11-10 00:56:12 +00:00
Aleksey Gurtovoy 28101ddf68 More GCC 4.x workarounds merges from RC_1_34_0
[SVN r35961]
2006-11-10 00:40:43 +00:00
Aleksey Gurtovoy 28a2d96840 More GCC 4.x workarounds
[SVN r35960]
2006-11-10 00:39:04 +00:00
Aleksey Gurtovoy 33e1caa14e Merge vacpp preprocessor fixes from RC_1_34_0
[SVN r35939]
2006-11-09 01:48:15 +00:00
Aleksey Gurtovoy 3a822ad2c5 vacpp preprocessor fixes (thanks to Christoph Jaeschke)
[SVN r35938]
2006-11-09 01:44:00 +00:00
Aleksey Gurtovoy cc66759729 vacpp preprocessor fixes (thanks to Christoph Jaeschke)
[SVN r35937]
2006-11-09 01:21:03 +00:00
Aleksey Gurtovoy 8c7f8d8a6b Merge vacpp fix from RC_1_34_0
[SVN r35936]
2006-11-09 01:14:10 +00:00
Aleksey Gurtovoy 2cf805d699 Merge fix from RC_1_34_0
[SVN r35935]
2006-11-09 01:12:50 +00:00
Aleksey Gurtovoy 45d97de592 Add missed slash
[SVN r35934]
2006-11-09 01:06:57 +00:00
Aleksey Gurtovoy 869e19c281 vacpp fixes (thanks to Christoph Jaeschke)
[SVN r35933]
2006-11-09 01:05:31 +00:00
Aleksey Gurtovoy a9e4545cd5 Merge vacpp preprocessor fixes from RC_1_34_0
[SVN r35932]
2006-11-09 00:48:44 +00:00
Aleksey Gurtovoy bda9e2cb89 vacpp preprocessor fixes (thanks to Christoph Jaeschke)
[SVN r35931]
2006-11-09 00:46:57 +00:00
Aleksey Gurtovoy e9184ee375 Merge vacpp MPL asserts config fixes from RC_1_34_0
[SVN r35929]
2006-11-09 00:13:22 +00:00
Aleksey Gurtovoy 185fcb323f Move vacpp MPL asserts config to the right place
[SVN r35928]
2006-11-09 00:10:34 +00:00
Aleksey Gurtovoy 335631321f Merge outdated aCC6 workarounds fix from RC_1_34_0
[SVN r35927]
2006-11-08 21:48:32 +00:00
Aleksey Gurtovoy a508b6dc28 Adjust outdated aCC6 workarounds (http://article.gmane.org/gmane.comp.lib.boost.devel/150572, thanks to Boris Gubenko)
[SVN r35926]
2006-11-08 21:44:30 +00:00
Beman Dawes 75632d1fd6 Merged copyright and license addition
[SVN r35907]
2006-11-07 19:27:00 +00:00
Beman Dawes 911e606005 Add copyright, license
[SVN r35905]
2006-11-07 19:11:57 +00:00
Aleksey Gurtovoy 99c280e3c8 Integrate GCC fixes from RC_1_34_0
[SVN r35896]
2006-11-07 09:03:36 +00:00
Rene Rivera ba565e217a Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Aleksey Gurtovoy d0c56a0b37 Workaround GCC bug #29518
[SVN r35867]
2006-11-06 05:51:40 +00:00
Dave Abrahams 4b303f2a4a Add license/copyright
[SVN r35651]
2006-10-18 06:08:05 +00:00
Dave Abrahams 0acccdb74d Remove bogus file
[SVN r35038]
2006-09-07 23:02:42 +00:00
Aleksey Gurtovoy 57fd7ea3a2 Get rid of temporary files
[SVN r34981]
2006-08-28 07:40:23 +00:00
Aleksey Gurtovoy 021abf6245 Get rid of temporary files
[SVN r34980]
2006-08-28 07:38:22 +00:00
Aleksey Gurtovoy 2f573b3a20 Get rid of temporary files
[SVN r34979]
2006-08-28 07:32:30 +00:00
Aleksey Gurtovoy b890dc4fe9 Document for_each
[SVN r34978]
2006-08-28 07:25:47 +00:00
Aleksey Gurtovoy 5b3bbab314 transform.rst: fix copy & paste errors (merged from RC_1_34_0)
[SVN r34977]
2006-08-28 06:14:30 +00:00
Aleksey Gurtovoy 5575dd2fc5 transform.rst: fix copy & paste errors
[SVN r34976]
2006-08-28 06:06:26 +00:00
Aleksey Gurtovoy a51bd538d6 Integral Constant: Add missing ::tag requirement
[SVN r34757]
2006-07-28 06:11:00 +00:00
Tobias Schwinger 9595b29dae adds test case for Integral Constant type argument
[SVN r34670]
2006-07-22 15:10:50 +00:00
Tobias Schwinger 42bff20795 makes begin< int_<I> > return void_
[SVN r34669]
2006-07-22 15:08:37 +00:00
Aleksey Gurtovoy 3a4b33d399 merge fixes from RC_1_34_0
[SVN r34276]
2006-06-12 07:21:44 +00:00
Aleksey Gurtovoy db83018d5b comment out failing test case -- it tries to test non-existing functionality!
[SVN r34275]
2006-06-12 07:13:12 +00:00
Aleksey Gurtovoy ab1e77ee01 Correct erroneous copyright date
[SVN r34274]
2006-06-12 05:11:55 +00:00
Tobias Schwinger acedeb11a7 introduces test case for is_sequence< int<0> >
[SVN r33979]
2006-05-16 13:37:14 +00:00
Tobias Schwinger fef0cb1b3c makes begin< int_<0> >::type compile
[SVN r33978]
2006-05-16 13:35:43 +00:00
Aleksey Gurtovoy 19ffdaaad4 Fix copy & paste error
[SVN r33943]
2006-05-05 21:48:40 +00:00
Jaakko Järvi edc824ada4 fixed a bug (added missing comma) in one of g++ workarounds
[SVN r33913]
2006-05-03 03:27:58 +00:00
Jaakko Järvi 7ebf2ffd2c Fixing a bug in a g++ workaround
[SVN r33912]
2006-05-03 03:21:36 +00:00
Dave Abrahams 9cdc987730 merged from trunk
[SVN r33506]
2006-03-28 16:15:15 +00:00
Dave Abrahams f100326cf0 Workarounds for GCC bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26904
[SVN r33505]
2006-03-28 16:12:56 +00:00
nobody 487545f03a This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
Dave Abrahams 1177466ac3 Stop using assert() in tests
[SVN r33181]
2006-02-28 22:56:33 +00:00
Dave Abrahams 63867d80b5 Stop using assert() in tests so we can test with NDEBUG defined.
[SVN r33026]
2006-02-20 15:45:40 +00:00
Aleksey Gurtovoy 027f473580 Add missing parameter (thanks to Bruno Martinez)
[SVN r33002]
2006-02-19 06:52:17 +00:00
Dave Abrahams 374d6d0f4e Add a failing test case
[SVN r32997]
2006-02-18 20:54:15 +00:00
Douglas Gregor b37d56ef17 Merged from Version_1_33_1
[SVN r31949]
2005-12-08 03:23:02 +00:00
Larry Joe Evans 0fc68d0a3d enable vector_c.hpp to handle case where T is enumeration
[SVN r31933]
2005-12-06 13:59:34 +00:00
Eric Niebler 3b39c6bbcd fix bad include guard
[SVN r31919]
2005-12-05 17:59:21 +00:00
Larry Joe Evans b6cb514192 #defined AUX778076_CONVERT_CN_TO and used in modified AUX778076_SEQUENCE_N_ARGS
to enable enumerations to be used for T in AUX778076_SEQUENCE_N_ARGS


[SVN r31196]
2005-10-04 18:01:35 +00:00
Aleksey Gurtovoy 9884799fe1 Portability fixes to preprocess.py et al. (thanks to Larry Evans!)
[SVN r31189]
2005-10-04 08:35:29 +00:00
Aleksey Gurtovoy af51dfffc2 Fix typos (thanks to Charles Brockman!)
[SVN r31032]
2005-09-19 04:36:29 +00:00
John Maddock 997a78ad4f Large patch from Ulrich Eckhardt to fix support for EVC++ 4.
[SVN r30670]
2005-08-25 16:27:28 +00:00
Aleksey Gurtovoy 4b9c8b6055 rename files with filenames >31 chars
[SVN r30281]
2005-07-28 11:04:37 +00:00
Aleksey Gurtovoy 71bcf17a33 delete a stale rst
[SVN r30280]
2005-07-28 11:01:26 +00:00
Aleksey Gurtovoy 5005ea67dd fix integral_c<bool,...>
[SVN r30173]
2005-07-19 04:03:12 +00:00
Dave Abrahams d3b64a34d7 Fix workaround for vc-8.0 beta
[SVN r30043]
2005-07-13 13:13:38 +00:00
Dave Abrahams d2d4ed3253 Bugs have been fixed in VC-8
[SVN r29910]
2005-07-06 17:39:38 +00:00
Fernando Cacciola 63732ccefc *** empty log message ***
[SVN r29790]
2005-06-24 21:42:40 +00:00
Fernando Cacciola e4fb6bf5e5 BOOST_TESTED_AT used in numeric_cast
old_numeric_cast takes the exception class from converter_policies


[SVN r29789]
2005-06-24 19:09:13 +00:00
Fernando Cacciola de299f5f3e Old numeric_cast<> completely replaced by new code (except that the old code is retained as a fallback mechanism for old broken compilers that can't deal with the new code)
[SVN r29761]
2005-06-23 23:33:01 +00:00
Markus Schöpflin e653056565 The EDG workaround is only needed when NOT operating in strict ansi (error)
mode, which is identified by __STD_STRICT_ANSI or __STD_STRICT_ANSI_ERRORS.


[SVN r29736]
2005-06-22 15:20:18 +00:00
Dave Abrahams b7fa994f3d Added iterator testing.
[SVN r29682]
2005-06-18 22:42:04 +00:00
Dave Abrahams 04278cf84b Fixed a bug that prevented set iterators from working at all, which
was breaking just about every algorithm when used on sets.


[SVN r29681]
2005-06-18 22:03:09 +00:00
Dave Abrahams eb00ae5d72 Improve bug-revealing test.
[SVN r29680]
2005-06-18 20:51:18 +00:00
Dave Abrahams 3f6ca76da3 Add failing test case for Brian Braatz.
[SVN r29671]
2005-06-18 10:43:36 +00:00
Aleksey Gurtovoy 50c8cde351 VC 7.1 has_xxx/SFINAE fix (thanks to Daniel Wallin!)
[SVN r29583]
2005-06-15 10:43:23 +00:00
Joaquín M. López Muñoz bea1c79ed7 forced operators overloading for vacpp 6.0
[SVN r29558]
2005-06-14 12:42:08 +00:00
Aleksey Gurtovoy 9fba964633 fix equal<vector,vector::type> issue (http://thread.gmane.org/gmane.comp.lib.boost.devel/118872)
[SVN r28913]
2005-05-15 00:39:04 +00:00
Douglas Gregor 94145ff494 Work around name lookup bug in GCC 3.3 for Mac OS X
[SVN r28899]
2005-05-14 16:26:11 +00:00
Douglas Gregor 4228d1489c Turn off char test on GCC 3.3 for Darwin, because it does strange things to the assembler
[SVN r28898]
2005-05-14 16:00:57 +00:00
Dave Abrahams f41a3f5912 Add missing copyright/license
[SVN r28828]
2005-05-11 15:27:14 +00:00
Dave Abrahams eea4b80440 libs/parameter/test/sfinae was choking vc7.1 and vc8 on the plain
version of BOOST_MPL_AUX_ASSERT_NOT_NA(T) with T = const char[4].
This only seems to occur in contexts where T might be deduced.


[SVN r28551]
2005-05-01 13:17:02 +00:00
Vladimir Prus 911659dfa3 Add V2 Jamfile
[SVN r28242]
2005-04-14 11:47:45 +00:00
Aleksey Gurtovoy 9e3cb17cc8 KCC 4.0 workaround
[SVN r28001]
2005-04-06 05:40:43 +00:00
Aleksey Gurtovoy 67dc0f7314 fix a typo (thanks to Yutaka Leon Suematsu)
[SVN r27957]
2005-04-04 17:27:04 +00:00
Aleksey Gurtovoy 6282f44510 Fix typo
[SVN r27912]
2005-04-01 21:23:16 +00:00
Dave Abrahams d6d18f7730 Add missing example from book.
[SVN r27565]
2005-03-07 13:37:07 +00:00
Aleksey Gurtovoy 96345a589c fix bogus Fibonacci series (thanks to Caleb Epstein)
[SVN r27532]
2005-03-02 05:14:26 +00:00
Rene Rivera 3b3506d454 Apply typo fixes from Julio M. Merino Vidal
[SVN r27513]
2005-02-27 17:28:24 +00:00
Dave Abrahams 4e459908ff Add testing jamfile and player2.cpp
[SVN r27506]
2005-02-25 19:37:28 +00:00
Dave Abrahams 681896168b Fix typo
[SVN r27247]
2005-02-08 18:05:42 +00:00
Aleksey Gurtovoy 1b23934761 fix erroneous example (reported by Brad Austin)
[SVN r26885]
2005-01-28 06:53:14 +00:00
Ralf W. Grosse-Kunstleve 84d16ad057 MIPSpro 7.3.1 (EDG 238) workaround
[SVN r26850]
2005-01-26 01:58:33 +00:00
Aleksey Gurtovoy a3c8e2267c fix typo (reported by Max Khesin)
[SVN r26848]
2005-01-25 21:47:19 +00:00
Aleksey Gurtovoy b9ac91e52d merge from 1.32.0 release branch
[SVN r26742]
2005-01-19 15:20:21 +00:00
Aleksey Gurtovoy ecaefb136d fix lambda comment
[SVN r26666]
2005-01-10 14:01:31 +00:00
Aleksey Gurtovoy 5b909f8c2e MSVC 7.0 ETI fix
[SVN r26560]
2004-12-20 19:35:33 +00:00
Aleksey Gurtovoy c0f63bca9e MSVC 7.0 ETI fix
[SVN r26559]
2004-12-20 19:17:16 +00:00
Aleksey Gurtovoy b2d6399e81 MSVC fixes
[SVN r26558]
2004-12-20 17:52:43 +00:00
Aleksey Gurtovoy 00f785c600 MSVC fixes
[SVN r26557]
2004-12-20 17:18:17 +00:00
Aleksey Gurtovoy a1a43e3c08 lambda support bug fix
[SVN r26547]
2004-12-17 19:26:47 +00:00
Aleksey Gurtovoy abc3e73052 support for N-ary numeric metafunctions for no-CTPS compilers
[SVN r26546]
2004-12-17 17:49:06 +00:00
Dave Abrahams 6d3409c76b Cover a few more types.
[SVN r26536]
2004-12-16 22:43:05 +00:00
Dave Abrahams 82c1058415 MSVC6 workarounds
[SVN r26509]
2004-12-14 22:44:57 +00:00
Dave Abrahams 340edb5672 vc6 workarounds for real
[SVN r26508]
2004-12-14 22:34:44 +00:00
Dave Abrahams b09811392e eti workarounds
[SVN r26507]
2004-12-14 22:12:04 +00:00
Dave Abrahams 462a81c9b8 VC6 bug workaround. Remove metafunction forwarding.
[SVN r26506]
2004-12-14 19:32:41 +00:00
Aleksey Gurtovoy 3ba2a75176 map for compilers with no CTPS
[SVN r26498]
2004-12-14 14:05:33 +00:00
Aleksey Gurtovoy 6ca63b6524 add no_ctps configuration for map
[SVN r26496]
2004-12-14 12:57:14 +00:00
Aleksey Gurtovoy 7bda336e5c Doc sources checkin
[SVN r26341]
2004-11-29 06:33:06 +00:00
Aleksey Gurtovoy ec8b22a79c merge RC_1_32_0 fixes
[SVN r26338]
2004-11-28 07:27:50 +00:00
Aleksey Gurtovoy c79f7e74cb merge RC_1_32_0 fixes
[SVN r26337]
2004-11-28 07:18:24 +00:00
Aleksey Gurtovoy 9ad728d2d4 merge RC_1_32_0 fixes
[SVN r26335]
2004-11-28 06:50:55 +00:00
Aleksey Gurtovoy 203a9f086a merge RC_1_32_0 fixes
[SVN r26328]
2004-11-28 03:35:12 +00:00
Aleksey Gurtovoy ff817a2421 merge RC_1_32_0 fixes
[SVN r26326]
2004-11-28 02:04:02 +00:00
Aleksey Gurtovoy 3b04dada5d merge RC_1_32_0 fixes
[SVN r26325]
2004-11-28 01:58:27 +00:00
Aleksey Gurtovoy 130ab6a9d3 merge RC_1_32_0 fixes
[SVN r26324]
2004-11-28 01:39:23 +00:00
Aleksey Gurtovoy fa847908a7 fix gcc 2.95 regressions (see http://thread.gmane.org/gmane.comp.lib.boost.devel/112288)
[SVN r25875]
2004-10-26 14:51:08 +00:00
Aleksey Gurtovoy 744ca77756 tru64cxx fixes
[SVN r25850]
2004-10-24 08:18:08 +00:00
Aleksey Gurtovoy 6fc52e1fff numeric protocol fixes
[SVN r25845]
2004-10-24 06:17:23 +00:00
Aleksey Gurtovoy 46579f35a4 rework set/map to workaround GCC 3.4 problems
[SVN r25712]
2004-10-13 18:25:11 +00:00
Aleksey Gurtovoy 2218105964 add missing include
[SVN r25709]
2004-10-13 14:40:12 +00:00
Aleksey Gurtovoy e75b92f43a try to workaround GCC/Linux 'assert' bug
[SVN r25708]
2004-10-13 14:27:35 +00:00
Aleksey Gurtovoy f40f4e3682 c++boost.gif -> boost.png replacement
[SVN r25573]
2004-10-05 15:45:52 +00:00
Aleksey Gurtovoy 8bef3eeb31 vcapp workaround
[SVN r25528]
2004-10-02 19:08:57 +00:00
Aleksey Gurtovoy 5175a17d87 various iterator fixes
[SVN r25513]
2004-10-01 16:32:41 +00:00
Aleksey Gurtovoy 8e99727506 GCC 2.95 needs the same workaround
[SVN r25484]
2004-09-30 12:17:45 +00:00
Aleksey Gurtovoy 81f7e4bb99 ADL fixes
[SVN r25453]
2004-09-28 13:56:59 +00:00
Aleksey Gurtovoy 2c49d8d21b bool fix
[SVN r25411]
2004-09-26 09:54:25 +00:00
Aleksey Gurtovoy f133ea0b9f MSVC/numeric_cast workaround
[SVN r25314]
2004-09-21 15:02:09 +00:00
Aleksey Gurtovoy e58c07109f MSVC 6.x workaround: replace MPL asserts with BOOST_STATIC_ASSERT
[SVN r25308]
2004-09-21 13:48:10 +00:00
Aleksey Gurtovoy 8bf3e8be3a GCC 3.x workaround
[SVN r25263]
2004-09-20 09:05:34 +00:00
Eric Friedman 2e0115a3a0 Fixed copyright typo (and eliminated unnecessary #includes).
[SVN r25217]
2004-09-19 09:01:45 +00:00
Dave Abrahams f792b0fb68 long long support
[SVN r25205]
2004-09-19 03:08:53 +00:00
Aleksey Gurtovoy 390e8eaeea MWCW 9.x workaround
[SVN r25188]
2004-09-18 07:18:02 +00:00
Aleksey Gurtovoy fca0963794 fix Jamfile
[SVN r25187]
2004-09-18 07:11:37 +00:00
Aleksey Gurtovoy 687c512ec9 MWCW workaround
[SVN r25186]
2004-09-18 06:34:19 +00:00
Aleksey Gurtovoy 03be656c75 fix MWCW function-scope assertions
[SVN r25185]
2004-09-18 06:33:05 +00:00
Aleksey Gurtovoy b11a4e267e fix Boost.Python ICEs
[SVN r25174]
2004-09-17 13:58:19 +00:00
Aleksey Gurtovoy 529cdbb02a fix BCC conflict with boost::next/prior
[SVN r25163]
2004-09-17 06:09:38 +00:00
Aleksey Gurtovoy 30444accf6 fix copyright/license
[SVN r25149]
2004-09-16 14:13:02 +00:00
Aleksey Gurtovoy 63f84a20f5 ADL/placeholders fixes
[SVN r25148]
2004-09-16 14:09:12 +00:00
Aleksey Gurtovoy e5093a77b3 MSVC < 7.1 workaround
[SVN r25119]
2004-09-15 15:29:45 +00:00
Aleksey Gurtovoy 6c519870c0 get rid of apply_if; Spirit 1.6.x doesn't need it
[SVN r25115]
2004-09-15 13:53:23 +00:00
Aleksey Gurtovoy 92170583d9 add copyright/license info
[SVN r25084]
2004-09-14 12:39:55 +00:00
Robert Ramey ca6ddb26fe m initial check in
[SVN r25070]
2004-09-14 04:31:29 +00:00
Aleksey Gurtovoy bc9df29663 MWCW fix
[SVN r25029]
2004-09-13 06:10:10 +00:00
Aleksey Gurtovoy 3837920af0 restrict MWCW workaround to MWCW only
[SVN r25028]
2004-09-13 06:01:03 +00:00
Aleksey Gurtovoy fed559b409 MWCW workaround
[SVN r24996]
2004-09-10 11:18:48 +00:00
Dave Abrahams 8c3f43daeb Workaround cw bug (from branch).
[SVN r24977]
2004-09-08 17:47:27 +00:00
Aleksey Gurtovoy f46335fe1e workaround GCC 3.4.1 bug
[SVN r24971]
2004-09-08 13:04:24 +00:00
Ralf W. Grosse-Kunstleve 3bf1d39bfb bug fix
[SVN r24964]
2004-09-07 23:49:45 +00:00
Ralf W. Grosse-Kunstleve 222792897e emergency fix: all compilers but MIPSpro 7.3 choke on mpl::protect instead of the original plain protect
[SVN r24963]
2004-09-07 21:37:24 +00:00
Aleksey Gurtovoy 3394c6c03d more MIPSpro 7.3 fixes
[SVN r24957]
2004-09-07 12:24:50 +00:00
Aleksey Gurtovoy a60de56828 Visual Age fixes
[SVN r24956]
2004-09-07 12:07:57 +00:00
Ralf W. Grosse-Kunstleve ea5ff5dad2 MIPSpro 7.3.1.3 compatibility
[SVN r24954]
2004-09-07 11:12:28 +00:00
Aleksey Gurtovoy 3e94c1bfbb MIPSpro fix
[SVN r24952]
2004-09-07 10:27:56 +00:00
Ralf W. Grosse-Kunstleve 4870cdb458 fix typo
[SVN r24951]
2004-09-07 10:21:23 +00:00
Aleksey Gurtovoy fe96e236ee asserts fix for MIPSpro 7.3
[SVN r24950]
2004-09-07 10:12:35 +00:00
Aleksey Gurtovoy 1e4fbe142c lambda fixes for MIPSpro
[SVN r24949]
2004-09-07 10:10:47 +00:00
Aleksey Gurtovoy 8ab336fe62 more MIPSpro fixes
[SVN r24948]
2004-09-07 09:06:10 +00:00
Aleksey Gurtovoy 8373f7b2a6 more MIPSpro fixes
[SVN r24947]
2004-09-07 08:53:22 +00:00
Ralf W. Grosse-Kunstleve 5759dd3db6 MIPSpro 7.3 workaround
[SVN r24945]
2004-09-07 02:57:50 +00:00
Aleksey Gurtovoy 15b5566796 MIPSpro 7.3 workarounds
[SVN r24944]
2004-09-07 02:56:52 +00:00
Aleksey Gurtovoy 1a7a514fca DigitalMars workaround
[SVN r24917]
2004-09-05 11:41:08 +00:00
Aleksey Gurtovoy e100bd939c Borland workaround (http://article.gmane.org/gmane.comp.lib.boost.devel/108938/)
[SVN r24916]
2004-09-05 11:01:30 +00:00
Aleksey Gurtovoy 24af838c83 fix includes
[SVN r24913]
2004-09-05 09:54:08 +00:00
Aleksey Gurtovoy f9be91fc35 set/map fixes
[SVN r24912]
2004-09-05 09:45:19 +00:00
Aleksey Gurtovoy ff6d082918 fix GCC regression
[SVN r24911]
2004-09-05 09:08:26 +00:00
Ralf W. Grosse-Kunstleve 8ef4119fde MIPSpro 7.41 compatibility (works around name lookup problems)
[SVN r24897]
2004-09-04 01:33:47 +00:00
Aleksey Gurtovoy 87067f0473 MIPSpro 7.4 fixes
[SVN r24896]
2004-09-04 01:10:23 +00:00
Aleksey Gurtovoy f08838774e post-merge bug fixes
[SVN r24893]
2004-09-03 16:02:24 +00:00
Aleksey Gurtovoy fc5dc3211f post-merge bug fixes
[SVN r24892]
2004-09-03 15:56:59 +00:00
Aleksey Gurtovoy fd0a7e59a0 configuration bugfix
[SVN r24882]
2004-09-03 00:10:42 +00:00
Aleksey Gurtovoy 1689c8ef83 merge new MPL version from 'mplbook' branch
[SVN r24874]
2004-09-02 15:41:37 +00:00
Douglas Gregor e2e70427cc License updates
[SVN r24597]
2004-08-19 15:19:17 +00:00
John Maddock 9384b827b8 Removed Boost.org copyrights, and replace with original authors names (as based on cvs history).
[SVN r24401]
2004-08-11 10:20:52 +00:00
Douglas Gregor 2d657dbb8b Converted to Boost Software License, Version 1.0
[SVN r24055]
2004-07-26 00:32:12 +00:00
Vladimir Prus 8cf0f62c06 Kill another signed/unsigned warning.
[SVN r24005]
2004-07-24 07:00:08 +00:00
Vladimir Prus 1d455351d8 Fix warnings about comparison of unsigned and signed values.
[SVN r23892]
2004-07-21 11:45:21 +00:00
Ralf W. Grosse-Kunstleve f181cf92c5 workaround for MIPSpro 7.3.1.3 name lookup problem
[SVN r23826]
2004-07-20 05:25:05 +00:00
Toon Knapen fb95f0f38a added workaround for vacpp version 6 compiler
[SVN r23056]
2004-06-08 10:51:40 +00:00
Aleksey Gurtovoy 1a4ecca03e fix the comment
[SVN r22871]
2004-05-19 14:11:08 +00:00
Aleksey Gurtovoy 20a6ef4d40 workaround a conflict with <iso646.h> macros
[SVN r22870]
2004-05-19 14:09:47 +00:00
Aleksey Gurtovoy 460430a167 better configurability fix
[SVN r22365]
2004-02-23 02:12:25 +00:00
Aleksey Gurtovoy 631c2f08b1 fix a typo
[SVN r22364]
2004-02-23 01:48:07 +00:00
Aleksey Gurtovoy d37ef5aeb9 restore configurability w/o preprocessed headers
[SVN r22363]
2004-02-23 01:47:11 +00:00
Dave Abrahams 3b0782b112 initial commit
[SVN r22346]
2004-02-21 13:35:55 +00:00
Aleksey Gurtovoy 1eb8c2ee69 insert_range empty sequences bug fix
[SVN r22336]
2004-02-20 11:27:22 +00:00
Peter Dimov 1bf488e87c Fix a VC 7.1 problem when boost/bind.hpp is included before mpl/less.hpp
[SVN r22188]
2004-02-06 20:17:06 +00:00
Dave Abrahams 7df089d2bb bug fix thanks to Martin Ecker <martin.ecker-at-liwest.at>
[SVN r21913]
2004-01-25 14:27:18 +00:00
Aleksey Gurtovoy 90983941be DM fixes
[SVN r21830]
2004-01-19 20:45:33 +00:00
Aleksey Gurtovoy 4b1012e1fe MSVC 7.1 fix, for enums
[SVN r21795]
2004-01-17 10:06:16 +00:00
Dave Abrahams 3e14236cd9 VC7.1+ workaround :(
[SVN r21523]
2004-01-07 05:03:10 +00:00
Dave Abrahams bb07d59b31 Add has_xxx to standard tests
[SVN r21501]
2004-01-05 15:05:49 +00:00
Dave Abrahams dc50912e64 Workarounds for gcc-3.2
[SVN r21499]
2004-01-05 14:36:18 +00:00
Dave Abrahams 7fa0daffb1 Test workaround for EDG bug
[SVN r21488]
2004-01-05 01:25:45 +00:00
Dave Abrahams ac8bd8d5e8 Workaround for EDG bug; improves encapsulation
[SVN r21487]
2004-01-05 01:24:00 +00:00
Dave Abrahams 821c34d2dd Workaround the fact that Intel C++ for Linux #defines __GNUC__
[SVN r21466]
2004-01-03 20:47:15 +00:00
Dave Abrahams dcbbbb85e2 initial commit
[SVN r21434]
2003-12-31 17:16:37 +00:00
Rene Rivera 9f515e90a6 Fix broken links.
[SVN r21400]
2003-12-27 01:05:33 +00:00
Dave Abrahams 648b830d58 added two-sequence forms
[SVN r21238]
2003-12-12 16:16:21 +00:00
Aleksey Gurtovoy b70e276a01 DM workaround
[SVN r21215]
2003-12-10 21:26:11 +00:00
Eric Friedman ccc17b58e4 Workaround for VC7.0 ETI bug.
[SVN r21159]
2003-12-06 04:04:18 +00:00
Aleksey Gurtovoy efb20a69be merge MSVC-specific & no CTPS cases (the former was still ICE-ing sometimes)
[SVN r20928]
2003-11-23 21:33:45 +00:00
Aleksey Gurtovoy 75bc9954e4 MIPSpro 7.41 workaround
[SVN r20807]
2003-11-14 06:55:06 +00:00
Aleksey Gurtovoy 3113b339d4 MIPSpro 7.41 workaround
[SVN r20806]
2003-11-14 06:47:10 +00:00
Aleksey Gurtovoy 5a8aba52c9 VC 7.0 ETI fix
[SVN r20801]
2003-11-13 11:53:32 +00:00
Eric Friedman fc43895f9e MSVC6 and Borland workarounds.
[SVN r20798]
2003-11-13 00:15:15 +00:00
Eric Friedman 1d98500581 Initial release.
[SVN r20797]
2003-11-13 00:14:40 +00:00
Aleksey Gurtovoy 0e5522e837 apply SunOS patch
[SVN r20793]
2003-11-12 08:37:37 +00:00
Aleksey Gurtovoy 43af4b3bea update reference docs
[SVN r20792]
2003-11-12 07:55:12 +00:00
Eric Friedman f4c12dbfdc Added 'common name error' workaround.
[SVN r20781]
2003-11-11 01:03:27 +00:00
Eric Friedman d10783cb1a Added missing dependency.
[SVN r20757]
2003-11-08 11:57:45 +00:00
Eric Friedman e95cad3d01 Simpler implementation.
[SVN r20756]
2003-11-08 11:57:09 +00:00
Eric Friedman e9b1a7ef7f Modified public iter_fold_if behavior.
[SVN r20755]
2003-11-08 11:53:00 +00:00
Eric Friedman d1a2e748f8 Added public interface to iter_fold_if.
[SVN r20716]
2003-11-07 04:30:08 +00:00
Eric Friedman b8440aeef8 Minor fix.
[SVN r20715]
2003-11-07 04:15:09 +00:00
Eric Friedman 4687267d09 1) 'Not found' result is void_; 2) Uses refactored find_if_pred.
[SVN r20714]
2003-11-07 03:49:58 +00:00
Eric Friedman d934b4944f Slightly modified find_if_pred (and refactored into own header).
[SVN r20713]
2003-11-07 03:46:08 +00:00
Aleksey Gurtovoy 44fd2878bf multiset checkin
[SVN r20683]
2003-11-05 15:48:24 +00:00
Eric Friedman e513af9490 Added test: index_of
[SVN r20622]
2003-11-04 01:38:26 +00:00
Eric Friedman 67c98297b6 Initial release.
[SVN r20621]
2003-11-04 01:37:24 +00:00
Dave Abrahams 58f6a455f9 Don't use metafunction forwarding since it confuses vc6/7
[SVN r20494]
2003-10-26 19:09:08 +00:00
Dave Abrahams dafe4fae8b Avoid vc6 confusion from metafunction forwarding
[SVN r20476]
2003-10-24 17:09:08 +00:00
Eric Friedman f9784f1e19 Added max_element, stable_partition, and sort.
[SVN r20451]
2003-10-22 01:03:41 +00:00
Eric Friedman d888228aa9 Migrated from sandbox.
[SVN r20450]
2003-10-22 01:03:06 +00:00
Aleksey Gurtovoy b4851a6eb3 merge MWCW 9.0 fix from RC_1_30_0 branch
[SVN r20360]
2003-10-13 08:14:52 +00:00
Aleksey Gurtovoy 8ac7e401ed fix operator value_type() to work with enums
[SVN r20262]
2003-10-06 11:07:24 +00:00
Eric Friedman 9a289b279b Removed now-duplicated ETI workaround.
[SVN r20221]
2003-09-30 07:16:54 +00:00
Dave Abrahams 9eb621c516 Handle ETI in BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC, since we need to invoke that anyway.
Make is_even work with vc6/7.


[SVN r20122]
2003-09-20 21:27:04 +00:00
Aleksey Gurtovoy d4cedca95e gcc ADL fix for if_
[SVN r20093]
2003-09-18 07:39:27 +00:00
Dave Abrahams 7888b48ac2 Use the import rule
[SVN r19968]
2003-09-08 17:38:49 +00:00
Dave Abrahams 87694f633d Workaround for intel6 "the type of the template partial specialization
template parameter F depends on the type of a template parameter" (or
something) bug.  Re-ordering the partial specialization parameters
fixes it.


[SVN r19944]
2003-09-07 14:45:16 +00:00
Dave Abrahams ce8329aa07 VC 6/7 workarounds
[SVN r19771]
2003-08-25 18:39:20 +00:00
Aleksey Gurtovoy 9233e89c10 msxsl_build.bat tweaks
[SVN r19597]
2003-08-14 14:50:44 +00:00
Aleksey Gurtovoy 73f1057426 check in docs re-generation instructions/resources
[SVN r19596]
2003-08-14 14:48:16 +00:00
Eric Friedman 6e55132748 Added COMMON_NAME_WKND workaround.
[SVN r19575]
2003-08-14 02:16:07 +00:00
Eric Friedman 74d4e978f9 Small fix (for gcc).
[SVN r19541]
2003-08-12 02:22:01 +00:00
Aleksey Gurtovoy f449ec368c undo erroneous changes in advance_* headers
[SVN r19470]
2003-08-06 08:33:20 +00:00
Aleksey Gurtovoy b842e17901 fixes for tagged lambda oversights
[SVN r19451]
2003-08-05 02:13:04 +00:00
Dave Abrahams c159a0d3ce Fixes for mistakes in tagged lambda conversion. Aleksey, I'm not sure if these are really what you intend, but they stop the errors.
[SVN r19436]
2003-08-04 15:42:46 +00:00
Aleksey Gurtovoy c62645ac2b fix preprocessed header name note
[SVN r19418]
2003-08-04 02:21:00 +00:00
Aleksey Gurtovoy 5a060a51ce add support for tagged lambda invocations
[SVN r19417]
2003-08-04 02:03:46 +00:00
Dave Abrahams 8065e071f7 Workaround for a heinous vc7 bug
[SVN r19414]
2003-08-03 11:48:55 +00:00
Aleksey Gurtovoy 6d3dae7102 add template_arity test
[SVN r19407]
2003-08-02 23:17:18 +00:00
Dave Abrahams bb3f38f02b Improved the incomplete type detection workaround for MSVC. It now
works even with the /vmg switch which makes all member pointers the
same size.


[SVN r19402]
2003-08-02 15:58:44 +00:00
Aleksey Gurtovoy 319ef0fffe is_sequence/list fix for MSVC
[SVN r19168]
2003-07-17 09:26:49 +00:00
Eric Friedman f5db13e0f0 Allow DEREF_WNKD outside of mpl namespace.
[SVN r19162]
2003-07-17 00:51:39 +00:00
Aleksey Gurtovoy d49590c199 list<> iteration bug fix
[SVN r18975]
2003-07-08 05:40:14 +00:00
Aleksey Gurtovoy b8a4930412 BOOST_NO_MPL_AUX_HAS_XXX -> BOOST_MPL_NO_AUX_HAS_XXX
[SVN r18974]
2003-07-08 05:10:04 +00:00
Aleksey Gurtovoy bc30ed2002 ETI fix
[SVN r18953]
2003-07-07 06:42:25 +00:00
Aleksey Gurtovoy 6dc817c68a bind1st/bind2nd common name workaround
[SVN r18859]
2003-06-23 12:44:12 +00:00
Aleksey Gurtovoy cf220da789 add missing backslash
[SVN r18857]
2003-06-23 11:43:33 +00:00
Aleksey Gurtovoy 406ae7d211 tools for re-generating preprocessed headers
[SVN r18856]
2003-06-23 11:34:04 +00:00
Dave Abrahams 567c490a97 Fix errors reported by John Torjo <john-at-torjo.com>.
[SVN r18824]
2003-06-17 14:16:16 +00:00
Aleksey Gurtovoy 65605933d4 fix 'size<vector...>' for no-CTPS compilers
[SVN r18786]
2003-06-12 10:52:50 +00:00
Aleksey Gurtovoy daf876a550 is_sequence fix for MSVC 6.5/7.0
[SVN r18785]
2003-06-12 10:17:31 +00:00
Dave Abrahams 85c3973c33 Check in a failing vc7 test.
[SVN r18741]
2003-06-09 11:38:53 +00:00
Aleksey Gurtovoy b275b77f0e fix Borland regression
[SVN r18621]
2003-05-30 23:18:25 +00:00
Aleksey Gurtovoy f33185ee8b fix config for Borland
[SVN r18601]
2003-05-30 00:37:20 +00:00
Aleksey Gurtovoy 21da573b09 add size test
[SVN r18539]
2003-05-26 06:46:17 +00:00
Aleksey Gurtovoy bf4b55d66a make sequence typedefs public
[SVN r18538]
2003-05-26 06:45:39 +00:00
Dave Abrahams 312a42e658 ETI workarounds for vc6
[SVN r18484]
2003-05-21 21:50:30 +00:00
Dave Abrahams fdaf890633 Workarounds for MSVC bugs
[SVN r18483]
2003-05-21 13:39:09 +00:00
Dave Abrahams 5a7c65a762 Pick less-likely names to avoid collisions on broken compilers
[SVN r18471]
2003-05-20 18:59:57 +00:00
Dave Abrahams 8688164a11 Make plus<x,y> into a valid integer constant wrapper
[SVN r18470]
2003-05-20 18:55:44 +00:00
Dave Abrahams 72a8746969 Implemented size for joint_view
[SVN r18469]
2003-05-20 13:04:08 +00:00
Aleksey Gurtovoy b7aa079241 modify type_wrapper for the sake of GCC
[SVN r18382]
2003-05-11 10:48:26 +00:00
Dave Abrahams e44d098414 Used inheritance for syntax-friendly use in conditionals.
[SVN r18374]
2003-05-08 22:22:39 +00:00
Dave Abrahams 6337bf66de initial commit
[SVN r18373]
2003-05-08 22:22:23 +00:00
Aleksey Gurtovoy 92a396c893 restore from the CVS crash
[SVN r18356]
2003-05-08 09:43:23 +00:00
Dave Abrahams a131b28904 restore from disk crash
[SVN r18353]
2003-05-08 02:19:10 +00:00
Beman Dawes 14d8c7b9ec Initial re-commit after CVS disk crash
[SVN r18349]
2003-05-07 20:59:06 +00:00
Aleksey Gurtovoy 2b691fc6c3 basic 'set' operations
[SVN r18342]
2003-05-03 11:13:11 +00:00
Aleksey Gurtovoy 1a48cd1714 set stub implementation
[SVN r18341]
2003-05-03 04:42:21 +00:00
Aleksey Gurtovoy c852ca8d41 set stub implementation
[SVN r18340]
2003-05-03 02:07:24 +00:00
Dave Abrahams d1a4ff6bc5 bug fix
[SVN r18321]
2003-04-28 04:55:23 +00:00
Dave Abrahams 4b05246d3d Lazy evaluation in lambdas
[SVN r18318]
2003-04-27 11:44:15 +00:00
Dave Abrahams a17353cd8f CWPro7 workaround
[SVN r18317]
2003-04-26 14:59:30 +00:00
Aleksey Gurtovoy 3bdab8a641 fix integral constant definition issue
[SVN r18240]
2003-04-12 18:25:44 +00:00
Aleksey Gurtovoy e4c699664e add missing include
[SVN r18233]
2003-04-11 08:55:32 +00:00
Dave Abrahams d808e1fff1 Fixed some config; rationalized # directives, used BOOST_WORKAROUND
[SVN r18227]
2003-04-10 12:45:19 +00:00
Dave Abrahams 2a5b68c117 Added test for BOOST_NO_MPL_AUX_HAS_XXX macro
[SVN r18226]
2003-04-10 12:43:19 +00:00
Dave Abrahams d1a899970f Use Gibbons typeof for Pro8
[SVN r18069]
2003-03-24 02:10:47 +00:00
Aleksey Gurtovoy b54f8d755b update the docs
[SVN r17847]
2003-03-12 14:05:57 +00:00
Aleksey Gurtovoy 696f056592 update the docs
[SVN r17844]
2003-03-12 13:52:13 +00:00
Aleksey Gurtovoy a69baa5eae update the docs
[SVN r17836]
2003-03-12 13:29:12 +00:00
Aleksey Gurtovoy 747dae9e6c remove tabs/update copyright notice
[SVN r17833]
2003-03-12 10:53:42 +00:00
Aleksey Gurtovoy bbcf7e9294 gcc ADL fixes
[SVN r17811]
2003-03-11 11:59:49 +00:00
Aleksey Gurtovoy db4f1d99cb add composite header
[SVN r17810]
2003-03-11 11:59:21 +00:00
Aleksey Gurtovoy f856111c60 make 'bitand_', 'bitor_' and 'bitxor_' binary
[SVN r17809]
2003-03-11 11:58:30 +00:00
Aleksey Gurtovoy 545c0ece08 added test for bitwise ops
[SVN r17808]
2003-03-11 11:55:16 +00:00
Aleksey Gurtovoy 4c750b8152 distance/advance fixes
[SVN r17795]
2003-03-10 02:27:06 +00:00
Aleksey Gurtovoy b43fe08bf2 size_t_c -> size_t renaming
[SVN r17794]
2003-03-09 23:42:58 +00:00
Aleksey Gurtovoy 6b51ae816b fix MSVC degression
[SVN r17790]
2003-03-09 03:51:32 +00:00
Aleksey Gurtovoy 014b9da96b fix some oversights
[SVN r17789]
2003-03-09 02:41:25 +00:00
Aleksey Gurtovoy cb8e80b207 make lambda more EDG-friendly
[SVN r17788]
2003-03-09 02:30:59 +00:00
Ralf W. Grosse-Kunstleve 27a10bcadb MIPSpro compatibility
[SVN r17772]
2003-03-08 00:25:47 +00:00
Aleksey Gurtovoy 293c471a6d restore an old revision for SGI MIPSpro C++
[SVN r17757]
2003-03-07 11:38:59 +00:00
1989 changed files with 249541 additions and 52219 deletions
+115
View File
@@ -0,0 +1,115 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright 2017 - 2019 James E. King III
# Copyright 2019 - 2021 Alexander Grund
# 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)
#
# Generic Appveyor build script for boostorg repositories
# See: https://github.com/boostorg/boost-ci/
#
# Instructions for customizing this script for your library:
#
# 1. Customize the compilers and language levels you want.
# 2. If you have more than include/, src/, test/, example/, examples/,
# benchmark/ or tools/ directories, set the environment variable DEPINST.
# For example if your build uses code in "bench/" and "fog/" directories:
# - DEPINST: --include bench --include fog
# 3. Enable pull request builds in your boostorg/<library> account.
#
# That's it - the script will do everything else for you.
#
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
- /bugfix\/.*/
- /feature\/.*/
- /fix\/.*/
- /pr\/.*/
matrix:
fast_finish: false
# Adding MAYFAIL to any matrix job allows it to fail but the build stays green:
allow_failures:
- MAYFAIL: true
environment:
global:
B2_CI_VERSION: 1
GIT_FETCH_JOBS: 4
# see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties
# to use the default for a given environment, comment it out; recommend you build debug and release however:
# on Windows it is important to exercise all the possibilities, especially shared vs static, however most
# libraries that care about this exercise it in their Jamfiles...
B2_ADDRESS_MODEL: 32,64
B2_LINK: shared,static
# B2_THREADING: threading=multi,single
B2_VARIANT: release
matrix:
- FLAVOR: Visual Studio 2017 C++2a Strict
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_CXXFLAGS: -permissive-
B2_CXXSTD: 2a
B2_TOOLSET: msvc-14.1
- FLAVOR: Visual Studio 2017 C++14/17
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_CXXSTD: 14,17
B2_TOOLSET: msvc-14.1
- FLAVOR: clang-cl
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_ADDRESS_MODEL: 64
B2_CXXSTD: 11,14,17
B2_TOOLSET: clang-win
- FLAVOR: Visual Studio 2015, 2013
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
B2_TOOLSET: msvc-12.0,msvc-14.0
- FLAVOR: cygwin (32-bit)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin\bin;
B2_ADDRESS_MODEL: 32
B2_CXXSTD: 03,11,14,1z
B2_TOOLSET: gcc
- FLAVOR: cygwin (64-bit)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin64\bin;
B2_ADDRESS_MODEL: 64
B2_CXXSTD: 03,11,14,1z
B2_TOOLSET: gcc
- FLAVOR: mingw32
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
B2_ADDRESS_MODEL: 32
ADDPATH: C:\mingw\bin;
B2_CXXSTD: 03,11,14,1z
B2_TOOLSET: gcc
- FLAVOR: mingw64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
B2_ADDRESS_MODEL: 64
B2_CXXSTD: 03,11,14,17,2a
B2_TOOLSET: gcc
install:
- git clone --depth 1 https://github.com/boostorg/boost-ci.git C:\boost-ci-cloned
# Copy ci folder if not testing Boost.CI
- if NOT "%APPVEYOR_PROJECT_NAME%" == "boost-ci" xcopy /s /e /q /i /y C:\boost-ci-cloned\ci .\ci
- rmdir /s /q C:\boost-ci-cloned
- ci\appveyor\install.bat
build: off
test_script: ci\build.bat
+31
View File
@@ -0,0 +1,31 @@
# Copyright 2019 - 2021 Alexander Grund
# 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)
#
# Sample codecov configuration file. Edit as required
codecov:
max_report_age: off
require_ci_to_pass: yes
notify:
# Increase this if you have multiple coverage collection jobs
after_n_builds: 2
wait_for_ci: yes
parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no
# Change how pull request comments look
comment:
layout: "reach,diff,flags,files,footer"
# Ignore specific files or folders. Glob patterns are supported.
# See https://docs.codecov.com/docs/ignoring-paths
ignore:
- libs/mpl/test/
- test/
+339
View File
@@ -0,0 +1,339 @@
# Copyright 2020-2021 Peter Dimov
# Copyright 2021 Andrey Semashev
# Copyright 2021 Alexander Grund
# Copyright 2022 James E. King III
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
---
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- bugfix/**
- feature/**
- fix/**
- pr/**
concurrency:
group: ${{format('{0}:{1}', github.repository, github.ref)}}
cancel-in-progress: true
env:
ASAN_OPTIONS: allocator_may_return_null=1
GIT_FETCH_JOBS: 8
NET_RETRY_COUNT: 5
B2_CI_VERSION: 1
B2_VARIANT: debug,release
B2_LINK: shared,static
LCOV_BRANCH_COVERAGE: 0
CODECOV_NAME: Github Actions
jobs:
posix:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
# Linux, gcc
- { compiler: gcc-4.4, cxxstd: '98,0x', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: gcc-4.6, cxxstd: '03,0x', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: gcc-4.7, cxxstd: '03,11', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: gcc-4.8, cxxstd: '03,11', os: ubuntu-18.04 }
- { compiler: gcc-4.9, cxxstd: '03,11', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: gcc-5, cxxstd: '03,11,14,1z', os: ubuntu-18.04 }
- { compiler: gcc-6, cxxstd: '03,11,14,17', os: ubuntu-18.04 }
- { compiler: gcc-7, cxxstd: '03,11,14,17', os: ubuntu-18.04 }
- { compiler: gcc-8, cxxstd: '03,11,14,17,2a', os: ubuntu-18.04 }
- { compiler: gcc-9, cxxstd: '03,11,14,17,2a', os: ubuntu-18.04 }
- { compiler: gcc-10, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 }
- { compiler: gcc-11, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 }
- { name: GCC w/ sanitizers, sanitize: yes,
compiler: gcc-11, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 }
- { name: Collect coverage, coverage: yes,
compiler: gcc-10, cxxstd: '03,11', os: ubuntu-20.04, install: 'g++-10-multilib', address-model: '32,64' }
# Linux, clang
- { compiler: clang-3.5, cxxstd: '03,11', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: clang-3.6, cxxstd: '03,11,14', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: clang-3.7, cxxstd: '03,11,14', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: clang-3.8, cxxstd: '03,11,14', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: clang-3.9, cxxstd: '03,11,14', os: ubuntu-18.04 }
- { compiler: clang-4.0, cxxstd: '03,11,14', os: ubuntu-18.04 }
- { compiler: clang-5.0, cxxstd: '03,11,14,1z', os: ubuntu-18.04 }
- { compiler: clang-6.0, cxxstd: '03,11,14,17', os: ubuntu-18.04 }
- { compiler: clang-7, cxxstd: '03,11,14,17', os: ubuntu-18.04 }
# Note: clang-8 does not fully support C++20, so it is not compatible with some libstdc++ versions in this mode
- { compiler: clang-8, cxxstd: '03,11,14,17,2a', os: ubuntu-18.04, install: 'clang-8 g++-7', gcc_toolchain: 7 }
- { compiler: clang-9, cxxstd: '03,11,14,17,2a', os: ubuntu-20.04 }
- { compiler: clang-10, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 }
- { compiler: clang-11, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 }
- { name: Clang w/ valgrind, valgrind: yes,
compiler: clang-12, cxxstd: '03,11,14,17,20', os: ubuntu-20.04, install: 'valgrind' }
# libc++
- { compiler: clang-6.0, cxxstd: '03,11,14', os: ubuntu-18.04, stdlib: libc++, install: 'clang-6.0 libc++-dev libc++abi-dev' }
- { name: Clang w/ sanitizers, sanitize: yes,
compiler: clang-12, cxxstd: '03,11,14,17,20', os: ubuntu-20.04, stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev' }
# OSX, clang
- { compiler: clang, cxxstd: '03,11,14,17,2a', os: macos-10.15 }
# Coverity Scan
# requires two github secrets in repo to activate; see ci/github/coverity.sh
# does not run on pull requests, only on pushes into develop and master
- { name: Coverity, coverity: yes,
compiler: clang-10, cxxstd: '17', os: ubuntu-20.04, ccache: no }
# multiarch (bigendian testing) - does not support coverage yet
# Please uncomment when fixing https://github.com/boostorg/mpl/issues/50
# - { name: Big-endian, multiarch: yes,
# compiler: clang, cxxstd: '17', os: ubuntu-20.04, ccache: no, distro: fedora, edition: 34, arch: s390x }
timeout-minutes: 120
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
env: {B2_USE_CCACHE: 1}
steps:
- name: Setup environment
run: |
if [ -f "/etc/debian_version" ]; then
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
export DEBIAN_FRONTEND=noninteractive
fi
if [ -n "${{matrix.container}}" ] && [ -f "/etc/debian_version" ]; then
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common
# Need (newer) git
for i in {1..${NET_RETRY_COUNT:-3}}; do sudo -E add-apt-repository -y ppa:git-core/ppa && break || sleep 10; done
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y g++ python libpython-dev git
fi
# multiple job types are not compatible with ccache, they use "ccache: no" in the matrix
if [[ "${{ matrix.ccache }}" == "no" ]]; then
echo "B2_USE_CCACHE=0" >> $GITHUB_ENV
fi
if [[ "${{ matrix.valgrind }}" == "yes" ]]; then
echo "B2_DEFINES=BOOST_NO_STRESS_TEST=1" >> $GITHUB_ENV
echo "B2_TESTFLAGS=testing.launcher=valgrind" >> $GITHUB_ENV
echo "B2_FLAGS=define=BOOST_USE_VALGRIND=1" >> $GITHUB_ENV
echo "VALGRIND_OPTS=--error-exitcode=1" >> $GITHUB_ENV
fi
git config --global pack.threads 0
- uses: actions/checkout@v3
with:
# For coverage builds fetch the whole history, else only 1 commit using a 'fake ternary'
fetch-depth: ${{ matrix.coverage && '0' || '1' }}
- name: Cache ccache
uses: actions/cache@v3
if: env.B2_USE_CCACHE
with:
path: ~/.ccache
key: ${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}-${{github.sha}}
restore-keys: |
${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}-
${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}
- name: Fetch Boost.CI
uses: actions/checkout@v3
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
# Copy ci folder if not testing Boost.CI
[[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci .
rm -rf boost-ci-cloned
- name: Install packages
if: startsWith(matrix.os, 'ubuntu')
run: |
SOURCE_KEYS=(${{join(matrix.source_keys, ' ')}})
SOURCES=(${{join(matrix.sources, ' ')}})
# Add this by default
SOURCES+=(ppa:ubuntu-toolchain-r/test)
for key in "${SOURCE_KEYS[@]}"; do
for i in {1..$NET_RETRY_COUNT}; do
wget -O - "$key" | sudo apt-key add - && break || sleep 10
done
done
for source in "${SOURCES[@]}"; do
for i in {1..$NET_RETRY_COUNT}; do
sudo add-apt-repository $source && break || sleep 10
done
done
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
if [[ -z "${{matrix.install}}" ]]; then
pkgs="${{matrix.compiler}}"
pkgs="${pkgs/gcc-/g++-}"
else
pkgs="${{matrix.install}}"
fi
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y $pkgs
- name: Setup GCC Toolchain
if: matrix.gcc_toolchain
run: |
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
echo "GCC_TOOLCHAIN_ROOT=$GCC_TOOLCHAIN_ROOT" >> $GITHUB_ENV
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
mkdir -p "$GCC_TOOLCHAIN_ROOT"
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
- name: Setup multiarch
if: matrix.multiarch
run: |
sudo apt-get install --no-install-recommends -y binfmt-support qemu-user-static
sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
git clone https://github.com/jeking3/bdde.git
echo "$(pwd)/bdde/bin/linux" >> ${GITHUB_PATH}
echo "BDDE_DISTRO=${{ matrix.distro }}" >> ${GITHUB_ENV}
echo "BDDE_EDITION=${{ matrix.edition }}" >> ${GITHUB_ENV}
echo "BDDE_ARCH=${{ matrix.arch }}" >> ${GITHUB_ENV}
echo "B2_DEFINES=BOOST_NO_STRESS_TEST=1" >> ${GITHUB_ENV}
echo "B2_WRAPPER=bdde" >> ${GITHUB_ENV}
- name: Setup Boost
env:
B2_ADDRESS_MODEL: ${{matrix.address-model}}
B2_COMPILER: ${{matrix.compiler}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_SANITIZE: ${{matrix.sanitize}}
B2_STDLIB: ${{matrix.stdlib}}
run: source ci/github/install.sh
- name: Setup coverage collection
if: matrix.coverage
run: ci/github/codecov.sh "setup"
- name: Run tests
if: '!matrix.coverity'
run: ci/build.sh
- name: Upload coverage
if: matrix.coverage
run: ci/codecov.sh "upload"
- name: Run coverity
if: matrix.coverity && github.event_name == 'push' && (github.ref_name == 'develop' || github.ref_name == 'master')
run: ci/github/coverity.sh
env:
COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }}
COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
windows:
defaults:
run:
shell: cmd
strategy:
fail-fast: false
matrix:
include:
- { toolset: msvc-14.2, cxxstd: '14,17,20', addrmd: '32,64', os: windows-2019 }
- { name: Collect coverage, coverage: yes,
toolset: msvc-14.3, cxxstd: '14,17,20', addrmd: '32,64', os: windows-2022 }
- { toolset: gcc, cxxstd: '03,11,14,17,2a', addrmd: '64', os: windows-2019 }
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Fetch Boost.CI
uses: actions/checkout@v2
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
REM Copy ci folder if not testing Boost.CI
if "%GITHUB_REPOSITORY%" == "%GITHUB_REPOSITORY:boost-ci=%" xcopy /s /e /q /i /y boost-ci-cloned\ci .\ci
rmdir /s /q boost-ci-cloned
- name: Setup Boost
run: ci\github\install.bat
- name: Run tests
if: '!matrix.coverage'
run: ci\build.bat
env:
B2_TOOLSET: ${{matrix.toolset}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_ADDRESS_MODEL: ${{matrix.addrmd}}
- name: Collect coverage
shell: powershell
if: matrix.coverage
run: ci\opencppcoverage.ps1
env:
B2_TOOLSET: ${{matrix.toolset}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_ADDRESS_MODEL: ${{matrix.addrmd}}
- name: Upload coverage
if: matrix.coverage
uses: codecov/codecov-action@v2
with:
files: __out/cobertura.xml
CMake:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
- { os: ubuntu-20.04, build_shared: ON, build_type: Release, generator: 'Unix Makefiles' }
- { os: ubuntu-20.04, build_shared: OFF, build_type: Debug, generator: 'Unix Makefiles' }
- { os: windows-2019, build_shared: ON, build_type: Release, generator: 'Visual Studio 16 2019' }
- { os: windows-2019, build_shared: OFF, build_type: Debug, generator: 'Visual Studio 16 2019' }
timeout-minutes: 120
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Fetch Boost.CI
uses: actions/checkout@v2
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
# Copy ci folder if not testing Boost.CI
[[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci .
rm -rf boost-ci-cloned
- name: Setup Boost
env: {B2_DONT_BOOTSTRAP: 1}
run: source ci/github/install.sh
- name: Run CMake
run: |
cd "$BOOST_ROOT"
mkdir __build_cmake_test__ && cd __build_cmake_test__
cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DBUILD_TESTING=ON -DBoost_VERBOSE=ON ..
cmake --build . --config ${{matrix.build_type}}
+22
View File
@@ -0,0 +1,22 @@
# Copyright 2018 Mike Dev
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required( VERSION 3.5...3.20 )
project( boost_mpl VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX )
add_library( boost_mpl INTERFACE )
add_library( Boost::mpl ALIAS boost_mpl )
target_include_directories( boost_mpl INTERFACE include )
target_link_libraries( boost_mpl
INTERFACE
Boost::config
Boost::core
Boost::predef
Boost::preprocessor
Boost::static_assert
Boost::type_traits
Boost::utility
)
+11
View File
@@ -0,0 +1,11 @@
# Boost.MPL Library Jamfile
#
# Copyright (c) 2018 James E. King III
#
# Use, modification, and distribution are subject to the
# Boost Software License, Version 1.0. (See accompanying file
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# please order by name to ease maintenance
build-project example ;
build-project test ;
+23
View File
@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+34
View File
@@ -0,0 +1,34 @@
MPL, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), provides a general-purpose, high-level C++ template metaprogramming framework of compile-time algorithms, sequences and metafunctions.
### License
Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
### Properties
* C++03
* Header Only
### Build Status
Branch | GHA CI | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests |
:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- |
[`master`](https://github.com/boostorg/mpl/tree/master) | [![Build Status](https://github.com/boostorg/mpl/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/mpl/actions?query=branch:master) | [![Build status](https://ci.appveyor.com/api/projects/status/lx9pjj2ixqod6flb/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/mpl-nrhfm/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/15866/badge.svg)](https://scan.coverity.com/projects/boostorg-mpl) | [![codecov](https://codecov.io/gh/boostorg/mpl/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/mpl/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/mpl.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](https://www.boost.org/doc/libs/master/libs/mpl/doc/index.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/mpl.html)
[`develop`](https://github.com/boostorg/mpl/tree/develop) | [![Build Status](https://github.com/boostorg/mpl/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/mpl/actions?query=branch:develop) | [![Build status](https://ci.appveyor.com/api/projects/status/lx9pjj2ixqod6flb/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/mpl-nrhfm/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/15866/badge.svg)](https://scan.coverity.com/projects/boostorg-mpl) | [![codecov](https://codecov.io/gh/boostorg/mpl/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/mpl/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/mpl.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](https://www.boost.org/doc/libs/develop/libs/mpl/doc/index.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/mpl.html)
### Directories
| Name | Purpose |
| ----------- | ------------------------------ |
| `doc` | documentation |
| `example` | examples |
| `include` | headers |
| `test` | unit tests |
### More information
* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-mpl)
* [Report bugs](https://github.com/boostorg/mpl/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[mpl]` tag at the beginning of the subject line.
+18
View File
@@ -0,0 +1,18 @@
//
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. 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/mpl/long.hpp"
#include "boost/mpl/alias.hpp"
template< long n > struct binary
: mpl::long_< ( binary< n / 10 >::value << 1 ) + n % 10 >
{
};
template<> struct binary<0>
: mpl::long_<0>
{
};
-67
View File
@@ -1,67 +0,0 @@
div.articletitle
{
text-align: center;
text-transform: uppercase;
}
div.authorgroup
{
text-align: center;
}
h3.title span.emphasis em
{
font-style: normal;
text-decoration: underline;
}
body
{
background-color: white;
color: black;
}
sup
{
font-size: x-small;
font-weight: lighter;
}
a:link,
a:visited
{
color: #505050;
}
sup a:link
,sup a:visited
,a.interlink:link
,a.interlink:visited
{
color: #505050;
text-decoration: none;
}
div.biblioentry p
{
border-style: none none none solid;
border-width: 1px;
border-color: silver;
margin-top: -1em;
padding-left: 0.5em;
padding-top: 0.25em;
}
div.footnote p
{
margin-bottom: -0.5em;
}
pre.programlisting
{
border-style: none none none solid;
border-width: 1px;
border-color: silver;
padding-left: 1em;
}
+68 -485
View File
@@ -1,495 +1,78 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- Copyright Aleksey Gurtovoy 2006. 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) -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.6: http://docutils.sourceforge.net/" />
<title>THE BOOST MPL LIBRARY</title>
<link rel="stylesheet" href="article.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
<meta name="copyright" content="Copyright © Aleksey Gurtovoy and David Abrahams, 2002-2004." />
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="article">
<div class="titlepage">
<div>
<img src="../../../c++boost.gif" align="middle" width="277" height="86">
<div class="articletitle">
<h1 class="title"><a name="idafawr"></a>THE BOOST MPL LIBRARY</h1>
</div>
</div>
</div>
<div class="toc">
<p><b>Table of Contents</b></p>
<body class="docframe">
<a class="reference" href="http://www.boost.org" target="_top">
<img align="left" alt="www.boost.org" src="../../../boost.png"/>
</a>
<h1 class="title">THE BOOST MPL LIBRARY</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright © Aleksey Gurtovoy and David Abrahams, 2002-2004.</td></tr>
<tr class="field"><th class="docinfo-name">License:</th><td class="field-body">Distributed under the Boost Software License, Version 1.0. (See
accompanying file <tt class="literal"><span class="pre">LICENSE_1_0.txt</span></tt> or copy at
<a class="reference" href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)</td>
</tr>
</tbody>
</table>
<div class="document" id="the-boost-mpl-library">
<p>The Boost.MPL library is a general-purpose, high-level C++
template metaprogramming framework of compile-time algorithms, sequences and
metafunctions. It provides a conceptual foundation and an extensive
set of powerful and coherent tools that make doing explict metaprogramming
in C++ as easy and enjoyable as possible within the current language.</p>
<p>There are several places to start when getting familiar with the library,
depending on what you know about metaprogramming in general and
C++ template metaprogramming in particular. Starting with
Boost version 1.32, the MPL comes with both an <a class="reference" href="./tutorial/tutorial-metafunctions.html">in-depth tutorial</a> on its
fundamental concepts and an annotated <a class="reference" href="./tutorial/reference-manual.html">reference manual</a> covering all concepts
and components in the library. While the tutorial
only uncovers a bit of what there is to C++ metaprogramming and the MPL,
it's a perfect place to start if you are only somewhat familiar with the
subject. At the very least, after you're done with it, you will be able to put
the rest of the stuff that appears here into context. The reference manual
is <em>the</em> resource for you if you plan — or are already doing — some actual
development with the library, but a casual reading is still allowed and likely
to bring many insights on the framework's organization and underlying
ideas. Finally, the top-level sections in this document that you
see highlighted below might also offer something of interest.</p>
<p>So, welcome, and happy metaprogramming!</p>
<dl>
<dt>1. <a href="#preface">Preface</a></dt>
<dt>2. <a href="#source">Sources</a></dt>
<dt>3. <a href="#tutorial">Mini-tutorial</a></dt>
<dd>
<dl>
<dt>3.1. <a href="#tutorial.conventions">Conventions used</a></dt>
<dt>3.2. <a href="#metafunctions">Metafunctions</a></dt>
<dt>3.3. <a href="#if">Compile-time if</a></dt>
<dt>3.4. <a href="#applyif">apply_if</a></dt>
<dt>3.5. <a href="#applyif2">apply_if, part 2</a></dt>
<dt><strong>Important</strong>:</dt>
<dd>There have been some major interface changes in the library since the last
public release, many of which are <em>not</em> backward compatible. If you are
a seasoned MPL user, be prepared to have to modify your code after
upgrading. Please refer to the <a class="reference" href="./tutorial/changes-in-boost-1-32-0.html">1.32 release changelog</a>
for the detailed information about the changes.</dd>
</dl>
</dd>
<dt>4. <a href="#technical">Technical details</a></dt>
<dd>
<dl>
<dt>4.1. <a href="#details.headers">Physical structure</a></dt>
<dt>4.2. <a href="#details.depend">Dependencies</a></dt>
<dt>4.3. <a href="#details.portability">Portability</a></dt>
</dl>
</dd>
<dt>5. <a href="#acknw">Acknowledgements</a></dt>
<dt><a href="#bibliography">Bibliography</a></dt>
</dl>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="preface"></a>1. Preface</h2>
</div>
</div>
<p>The MPL library is a C++ template metaprogramming framework of compile-time algorithms, sequences and metafunction classes. The two main documentation sources for the library is &ldquo;the MPL paper&rdquo;, and the library's reference documentation. If you haven't heard about the MPL before, we suggest you to start with the paper, and then move on to the reference documentation and the information in this document.</p>
<div class="itemizedlist">
<ul type="box">
<li style="list-style-type: square">A. Gurtovoy, D. Abrahams, <a href="./paper/html/index.html" target="_top">The Boost C++ Metaprogramming Library</a>, March 2002 | [<a href="./paper/mpl_paper.pdf" target="_top">as .pdf</a>] [<a href="./paper/mpl_paper.html" target="_top">as single .html</a>]</li>
<li style="list-style-type: square"><a href="./ref/Table_of_Contents.html" target="_top">Reference documentation</a>
<div class="orderedlist">
<ol type="1">
<li><a href="./ref/Sequences.html" target="_top">Sequences</a></li>
<li><a href="./ref/Iterators.html" target="_top">Iterators</a></li>
<li><a href="./ref/Algorithms.html" target="_top">Algorithms</a></li>
<li><a href="./ref/Metafunctions.html" target="_top">Metafunctions</a></li>
<li><a href="./ref/Integral_constant_classes.html" target="_top">Integral constant classes</a></li>
<li><a href="./ref/Categorized_index.html" target="_top">Categorized index</a></li>
</ol>
</div>
</li>
<!-- .. section-numbering:: -->
<ul class="toc simple" id="outline">
<li><a class="reference" href="./tutorial/tutorial-metafunctions.html" id="id40" name="id40">Tutorial: Metafunctions and Higher-Order Metaprogramming</a></li>
<li><a class="reference" href="./tutorial/reference-manual.html" id="id61" name="id61">Reference Manual</a></li>
<li><a class="reference" href="./tutorial/changelog-history.html" id="id62" name="id62">Changelog &amp; History</a></li>
<li><a class="reference" href="./tutorial/technical-details.html" id="id70" name="id70">Technical Details</a></li>
<li><a class="reference" href="./tutorial/resources.html" id="id77" name="id77">Resources</a></li>
<li><a class="reference" href="./tutorial/acknowledgements.html" id="id78" name="id78">Acknowledgements</a></li>
<li><a class="reference" href="./tutorial/tutorial_toc.html">Full TOC</a></li>
</ul>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="source"></a>2. Sources</h2>
</div>
</div>
<p>The latest library sources are available from the main trunk of the <a href="http://www.boost.org/more/download.html#CVS" target="_top">Boost CVS</a>. <a href="http://boost.sourceforge.net/release/">Boost 1.30.0 distribution</a> contains a stable version of the library as per March 12, 2003.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="tutorial"></a>3. Mini-tutorial</h2>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="tutorial.conventions"></a>3.1. Conventions used</h3>
</div>
</div>
<p>The examples used through this tutorial use fully qualified names, e.g. <tt>std::vector</tt> instead of plain <tt>vector</tt>. Any unqualified name refers to a local entity defined in the example itself. The names from <tt>boost::mpl</tt> namespace are referred to using <tt>mpl</tt> namespace alias (e.g. <tt>mpl::apply</tt> instead of <tt>boost::mpl::apply</tt>), as if the following namespace alias definition were in effect:</p>
<pre class="programlisting">
namespace mpl = boost::mpl;
</pre>
<p>Note that the library offers a special header, <tt>boost/mpl/alias.hpp</tt>, including which gives you a rough equivalent of the above. Alternatively, you can always spell the namespace alias definition manually in each translation unit as needed (if you choose to use the shorter namespace notation at all).</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="metafunctions"></a>3.2. Metafunctions</h3>
</div>
</div>
<p>In MPL, the metaprogramming equivalent of a function is a <i>class template</i> containing a nested <tt>typedef</tt> member aptly named &ldquo;type&rdquo;:</p>
<pre class="programlisting">
// on the face of it, not very useful
template&lt; typename T &gt;
struct identity
{
typedef T type;
};
// perhaps more useful
template&lt; typename T &gt;
struct result_type
{
typedef typename T::result_type type;
};
</pre>
<p>&ldquo;Invoking&rdquo; a metafunction is as simple as instantiating the class template with particular template parameters (metafunction &ldquo;arguments&rdquo;) and accessing the result through the nested <tt>type</tt> member:</p>
<pre class="programlisting">
typedef identity&lt;int&gt;::type t1; // t1 == int
typedef result_type&lt; std::unary_function&lt;int,bool&gt; &gt;::type t2; // t2 == bool
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="if"></a>3.3. Compile-time if</h3>
</div>
</div>
<p>The most interesting template metaprograms often contain a lot of decision-making code. Some of conditional decisions/behavior can be handled directly by (partial) class template specialization or function overloading <span class="citation">[<a class="interlink" href="#ref.vel95a" title="[vel95a]">Vel95a</a>]</span>, <span class="citation">[<a class="interlink" href="#ref.ale00" title="[ale00]">Ale00</a>]</span>, but in general there is a need for a standalone library primitive that would allow one to choose between two types basing on a compile-time expression. In <tt>boost::mpl</tt> such primitive is called <tt>if_</tt>:</p>
<pre class="programlisting">
template&lt; typename T &gt;
struct heap_holder
{
// ...
private:
boost::scoped_ptr&lt;T&gt; m_object;
};
template&lt; typename T &gt;
struct stack_holder
{
// ...
private:
T m_object;
};
template&lt; typename T &gt;
struct can_be_on_stack
: mpl::bool_c&lt; (sizeof(T) &lt;= sizeof(double)) &gt;
{
};
// use 'if_' to choose where to store 'T' member
template&lt; typename T &gt;
struct lightweight
: private mpl::if_&lt;
can_be_on_stack&lt;T&gt;
, stack_holder&lt;T&gt;
, heap_holder&lt;T&gt;
&gt;::type
{
// ...
};
</pre>
<p>Note that the first template parameter of the <tt>if_</tt> template is a type that should be a model of Integral Constant concept. The library also provides a less generic but sometimes more convenient form that accepts a condition in form of non-type <tt>bool</tt> template parameter:</p>
<pre class="programlisting">
template&lt; typename T &gt;
struct lightweight
: private mpl::if_c&lt;
(sizeof(T) &lt;= sizeof(double))
, stack_holder&lt;T&gt;
, heap_holder&lt;T&gt;
&gt;::type
{
// ...
};
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="applyif"></a>3.4. apply_if</h3>
</div>
</div>
<p>In run-time C++, it is guaranteed that when we reach an <tt>if</tt> statement, only one branch will be executed. Executing the branch for which the result is not required would be unnecessary and inefficient. More importantly, frequently the non-required branch is invalid, and executing it would cause an error. For instance, the following code would be badly broken if both branches of the statement were evaluated:</p>
<pre class="programlisting">
void fun(giraffe* g)
{
if (g)
cout &lt;&lt; g-&gt;name();
else
cout &lt;&lt; "no giraffe";
}
</pre>
<p>In compile-time world, things are different. Which parameters to <tt>if_</tt> template are instantiated is determined by the form of each template parameter and the corresponding language rules (<span class="citation">[<a class="interlink" href="#ref.iso98" title="[iso98]">ISO98</a>]</span>, section 14.7.1), not by the value of the compile-time expression being switched on. That means that if, in attempt to process a particular <tt>if_</tt> construct, the compiler determines that one of its &ldquo;branch&rdquo; template parameters is ill-formed, it will issue a diagnostics even if the value of compile-time expression would lead to &ldquo;choosing&rdquo; the other, valid parameter type.</p>
<p>To clarify what we just said, here is a broken first attempt at writing a <tt>pointed_type</tt> metafunction, that when instantiated for a <tt>T</tt> that is either a plain pointer or a smart pointer, &ldquo;returns&rdquo; the pointed type:</p>
<pre class="programlisting">
template&lt; typename T &gt;
struct pointed_type
{
typedef typename mpl::if_&lt;
boost::is_pointer&lt;T&gt;
, typename boost::remove_pointer&lt;T&gt;::type
, typename T::element_type // #1
&gt;::type type;
};
typedef pointed_type&lt; std::auto_ptr&lt;int&gt; &gt;::type int_ptr; // ok
typedef pointed_type&lt;char*&gt;::type char_ptr; // error in line #1!
</pre>
<p>If we try to compile the above, we will get something like this:</p>
<pre class="programlisting">
Error: name followed by "::" must be a class or namespace name
</pre>
<p>because the expression <tt>typename T::element_type</tt> is not valid in case of <tt>T == char*</tt>.</p>
<p>Here's what we need to do to make <tt>pointed_type</tt> work for plain pointers: <sup><a name="idakqwr" href="#ftn.IDAKQWR">1</a></sup> instead of instantiating our two potential results before passing them to <tt>if_</tt>, we need to write metafunctions that can be used to instantiate the results; then we can use <tt>if_</tt> to choose a metafunction, and only then should we use that function to get the result.</p>
<p><tt>boost::remove_pointer</tt> already is a metafunction. We just need to write an auxiliary function to return the <tt>element_type</tt> of a pointer type:</p>
<pre class="programlisting">
namespace aux {
template&lt; typename T &gt;
struct element_type
{
typedef typename T::element_type type;
};
}
</pre>
<p>Now we can select the metafunction to call based on the result of <tt>boost::is_pointer</tt>, and then <span class="emphasis"><em>apply</em></span> it to form the result:</p>
<pre class="programlisting">
template&lt; typename T &gt;
struct pointed_type
{
private:
// pick a metafunction
typedef typename mpl::if_&lt;
boost::is_pointer&lt;T&gt;
, boost::remove_pointer&lt;T&gt;
, aux::element_type&lt;T&gt;
&gt;::type func_; // #1
public:
// apply the metafunction
typedef typename func_::type type;
};
</pre>
<p>The key knowledge that makes the above viable is that in line #1 the compiler is <span class="emphasis"><em>guaranteed</em></span> not to instantiate <tt>boost::remove_pointer&lt;T&gt;</tt> and <tt>aux::element_type&lt;T&gt;</tt> templates, - even although they are passed as actual arguments to the <tt>if_</tt>.</p>
<p>The described technique is so common in template metaprograms, that it makes sense to facilitate the selection of the nested <tt>type</tt> member by introducing a high level equivalent to <tt>if_</tt> that will do <tt>func_::type</tt> operation as a part of its invocation. The MPL provides such a template - it's called <tt>apply_if</tt>. Using it, we can re-write the above code as simply as:</p>
<pre class="programlisting">
[
template&lt; typename T &gt;
struct pointed_type
{
typedef typename mpl::apply_if&lt;
boost::is_pointer&lt;T&gt;
, boost::remove_pointer&lt;T&gt;
, aux::element_type&lt;T&gt;
&gt;::type type;
};
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="applyif2"></a>3.5. apply_if, part 2</h3>
</div>
</div>
<p>Besides solving the &ldquo;making the code compile&rdquo; problem, the <tt>apply_if</tt> technique we've just learned can be also used to improve metaprogram efficiency.</p>
<p>Suppose we want to define a high-level wrapper around <tt>boost::remove_pointer</tt> traits template, which will strip the pointer qualification conditionally. We will call it <tt>remove_pointer_if</tt>:</p>
<pre class="programlisting">
template&lt;
typename Condition
, typename T
&gt;
struct remove_pointer_if
{
typedef typename mpl::if_&lt;
Condition
, typename boost::remove_pointer&lt;T&gt;::type
, T
&gt;::type type;
};
</pre>
<p>The above works the first time, but it's not the most optimal implementation. Similar to our previous examples, <tt>boost::remove_pointer&lt;T&gt;</tt> gets instantiated even if its result is never used. In the metaprogramming world compilation time is an important resource <span class="citation">[<a class="interlink" href="#ref.abr01" title="[abr01]">Abr01</a>]</span>, and it is wasted by unnecessary template instantiations.</p>
<p>Let's see what we need to substitute <tt>if_</tt> by <tt>apply_if</tt> here. We already have one metafunction to pass to <tt>apply_if</tt> - <tt>boost::remove_pointer&lt;T&gt;</tt>, but we need a second one, - let's call it <tt>f</tt>, - such as <tt>f&lt;T&gt;::type == T</tt>. We could write this one ourselves, but fortunately MPL already provides us with a template that matches this exact definition - it's called <tt>identity</tt>. Applying this knowledge, we get:</p>
<pre class="programlisting">
template&lt;
typename Condition
, typename T
&gt;
struct remove_pointer_if
{
typedef typename mpl::apply_if&lt;
Condition
, boost::remove_pointer&lt;T&gt;
, mpl::identity&lt;T&gt;
&gt;::type type;
};
</pre>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="technical"></a>4. Technical details</h2>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="details.headers"></a>4.1. Physical structure</h3>
</div>
</div>
<p>The library provides you with a fine-grained header structure with one header per public component (class/function template), with the header named after the component; for example, <tt>boost::mpl::apply&lt;&gt;</tt> template is defined in the header <tt>boost/mpl/apply.hpp</tt>. This scheme both ensures that you don't pay for what you don't use in terms of compilation time/header dependencies, and frees you from memorizing/looking up header/component correspondence. Several composite headers for the entities that are likely to be used together (e.g. logical operations - <tt>logical_or</tt>, <tt>logical_and</tt>, etc.) are also provided. It allows one to avoid the burden of spelling many <tt>#include</tt> directives in programs that make an intensive use of the library facilities. <sup><a name="note.headers" href="#ftn.note.headers">2</a></sup></p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="details.depend"></a>4.2. Dependencies</h3>
</div>
</div>
<p>Besides <tt>boost/config.hpp</tt> header, the MPL heavily depends on two other Boost libraries - the Boost Preprocessor library <span class="citation">[<a class="interlink" href="#ref.pre" title="[pre]">PRE</a>]</span>, and the Type Traits library <span class="citation">[<a class="interlink" href="#ref.ttl" title="[ttl]">TTL</a>]</span>. These dependencies are essential and cannot be eliminated. In addition to those, the <tt>boost/mpl/assert_is_same.hpp</tt> header depends on Boost Static Assert library <span class="citation">[<a class="interlink" href="#ref.sal" title="[sal]">SAL</a>]</span>. The library tests and examples may depend on some additional Boost libraries, e.g. Boost Bind <span class="citation">[<a class="interlink" href="#ref.bbl" title="[bbl]">BBL</a>]</span>; you don't have to have those unless you are interested in actually compiling the tests/examples (probably you are, though).</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="details.portability"></a>4.3. Portability</h3>
</div>
</div>
<p>Below is the list of compilers the library has been tested with:</p>
<div class="itemizedlist">
<ul type="box">
<li style="list-style-type: square">Microsoft Visual C++ 6.0, SP 5</li>
<li style="list-style-type: square">Microsoft Visual C++ .NET (7.0)</li>
<li style="list-style-type: square">Metrowerks CodeWariror 7.2/8.1</li>
<li style="list-style-type: square">Intel C++ Compiler 5.0, 6.0</li>
<li style="list-style-type: square">GCC 2.95.3-5</li>
<li style="list-style-type: square">GCC 3.1</li>
<li style="list-style-type: square">Comeau C/C++ 4.2.45/4.3.0</li>
<li style="list-style-type: square">Borland C++ 5.5.1</li>
</ul>
</div>
<p>An incomplete matrix of recent test compilation results is available from here - <a href="http://www.mywikinet.com/mpl/log.html" target="_top">http://www.mywikinet.com/mpl/log.html</a>.</p>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="acknw"></a>5. Acknowledgements</h2>
</div>
</div>
<p>Following is a list of people who in one or another way contributed to the library development. The list is work in progress!</p>
<p>David Abrahams, Emily Winch, Eric Friedman, Vesa Karvonen, Peter Dimov, Mat Marcus, Fernando Cacciola, Paul Mensonides, David B. Held, John Bandela, Arnaldur Gylfason, Hamish Mackenzie.</p>
<p><b>Copyright on this document.&nbsp;</b>Copyright &copy; 2002 Aleksey Gurtovoy, David Abrahams and Emily Winch.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<div>
<h1 class="title"><a name="bibliography"></a>Bibliography</h1>
</div>
</div>
<div class="biblioentry"><a name="ref.abr01"></a>
<p>[Abr01] <span class="authorgroup">David Abrahams and Carlos Pinto Coelho,</span> <span class="title"><i><a href="http://users.rcn.com/abrahams/instantiation_speed/index.html" target="_top">Effects of Metaprogramming Style on Compilation Time</a></i>,</span> <span class="date">2001</span></p>
</div>
<div class="biblioentry"><a name="ref.ale00"></a>
<p>[Ale00] <span class="author">Andrei Alexandrescu,</span> <span class="title"><i><a href="http://www.cuj.com/experts/1810/alexandr.htm" target="_top">On Conversions between Types and Values</a></i>,</span> <span class="publishername">C/C++ Users Journal,</span> <span class="date">October 2000</span></p>
</div>
<div class="biblioentry"><a name="ref.bbl"></a>
<p>[BBL] <span class="title"><i>Boost Bind library</i>,</span> <span class="bibliomisc"><a href="http://www.boost.org/libs/bind/bind.html" target="_top">http://www.boost.org/libs/bind/bind.html</a></span></p>
</div>
<div class="biblioentry"><a name="ref.iso98"></a>
<p>[ISO98] <span class="title"><i>ISO/IEC 14882:1998(E), Programming languages &mdash; C++</i>,</span> <span class="orgname">ISO/IEC,</span> <span class="date">1998</span></p>
</div>
<div class="biblioentry"><a name="ref.pre"></a>
<p>[PRE] <span class="author">Vesa Karvonen,</span> <span class="title"><i>Boost Preprocessor Metaprogramming library</i>,</span> <span class="bibliomisc"><a href="http://www.boost.org/libs/preprocessor/doc/" target="_top">http://www.boost.org/libs/preprocessor/doc/</a></span></p>
</div>
<div class="biblioentry"><a name="ref.ttl"></a>
<p>[TTL] <span class="title"><i>Boost Type Traits library</i>,</span> <span class="bibliomisc"><a href="http://www.boost.org/libs/type_traits/" target="_top">http://www.boost.org/libs/type_traits/</a></span></p>
</div>
<div class="biblioentry"><a name="ref.sal"></a>
<p>[SAL] <span class="title"><i>Boost Static Assert library</i>,</span> <span class="bibliomisc"><a href="http://www.boost.org/libs/static_assert/static_assert.htm" target="_top">http://www.boost.org/libs/static_assert/static_assert.htm</a></span></p>
</div>
<div class="biblioentry"><a name="ref.vel95a"></a>
<p>[Vel95a] <span class="author">Todd Veldhuizen,</span> <span class="title"><i><a href="http://osl.iu.edu/~tveldhui/papers/Template-Metaprograms/meta-art.html" target="_top">Using C++ template metaprograms</a></i>,</span> <span class="biblioset"><i>C++ Report</i>, <span class="publishername">SIGS Publications Inc.,</span> <span class="issn">ISSN 1040-6042,</span></span> <span class="volumenum">Vol. 7,</span> <span class="issuenum">No. 4,</span> <span class="pagenums">pp. 36-43,</span> <span class="date">May 1995</span></p>
</div>
</div>
<div class="footnotes"><br>
<hr width="100" align="left">
<div class="footnote">
<p><sup><a name="ftn.idakqwr" href="#IDAKQWR">1</a></sup> It would be easy to implement <tt>pointed_type</tt> using partial specialization to distinguish the case where <tt>T</tt> is a pointer. <tt>if_</tt> is used here to avoid creating a complicated example.</p>
</div>
<div class="footnote">
<p><sup><a name="ftn.note.headers" href="#note.headers">2</a></sup> The Boost Preprocessor library <span class="citation">[<a class="interlink" href="#ref.pre" title="[pre]">PRE</a>]</span> exposes a very similar physical organization; in fact, the libraries even share the common subdirectory naming (<tt>mpl/arithmetic</tt> &lt;-&gt; <tt>preprocessor/arithmetic</tt>, <tt>mpl/comparison</tt> &lt;-&gt; <tt>preprocessor/comparison</tt>, etc.).</p>
</div>
</div>
<hr class="footer" />
<div class="footer">
Generated on: 2004-11-15 12:20 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/" target="_top">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html" target="_top">reStructuredText</a> source.
</div>
</body>
</html>
-11
View File
@@ -1,11 +0,0 @@
@echo off
if "%4" == "" goto build
f:\msxsl\msxsl.exe f:\home\depot\xml\stylesheets\docbook-xsl-1.50.0\html\titlepage.templates.xml f:\home\depot\xml\stylesheets\docbook-xsl-1.52.2\template\titlepage.xsl | f:\msxsl\msxsl.exe - f:\msxsl\to_utf8.xsl -o f:\home\depot\xml\stylesheets\docbook-1.50.0\html\titlepage.templates.xsl
:build
sx -x lower -x empty %2 >%3.xml
f:\msxsl\msxsl.exe %3.xml f:\home\depot\xml\stylesheets\docbook-xsl-1.50.0\html\my\%1 -o %3
del %3.xml
f:\tidy\tidy.exe -config f:\tidy\config.txt -m %3
f:\tidy\tidy_attr.py %3
-87
View File
@@ -1,87 +0,0 @@
div.articletitle
{
text-align: center;
text-transform: uppercase;
}
div.authorgroup
{
text-align: center;
}
h3.title span.emphasis em
{
font-style: normal;
text-decoration: underline;
}
body
{
background-color: white;
color: black;
}
sup
{
font-size: x-small;
font-weight: lighter;
}
a:link
,a:visited
{
color: #505050;
}
sup a:link
,sup a:visited
,a.interlink:link
,a.interlink:visited
{
color: #505050;
text-decoration: none;
}
div.biblioentry p
{
border-style: none none none solid;
border-width: 1px;
border-color: silver;
margin-top: -1em;
padding-left: 0.5em;
padding-top: 0.25em;
}
div.footnote p
{
margin-bottom: -0.5em;
}
div.table table
{
border: solid;
border-width: 1px;
border-color: silver;
}
div.table table tr th
{
background-color: #f0f0f0;
padding-left: 1em;
padding-right: 1em;
}
div.table table tr td
{
padding-left: 1em;
padding-right: 1em;
}
pre.programlisting
{
border-style: none none none solid;
border-width: 1px;
border-color: silver;
padding-left: 1em;
}
-59
View File
@@ -1,59 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>6. Acknowledgements</title>
<link rel="stylesheet" href="article.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
<meta name="keywords" content="template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time">
<link rel="home" href="index.html" title="the boost c++ metaprogramming library">
<link rel="up" href="index.html" title="the boost c++ metaprogramming library">
<link rel="previous" href="example.html" title="5. example: a compile-time fsm generator">
<link rel="next" href="refs.html" title="references">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">6. Acknowledgements</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="example.html">Prev</a>&nbsp;</td>
<th width="60%" align="center">&nbsp;</th>
<td width="20%" align="right">&nbsp;<a accesskey="n" href="refs.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="acknowl"></a>6. Acknowledgements</h2>
</div>
</div>
<p>Peter Dimov contributed the <tt>bind</tt> functionality without which compile-time lambda expressions wouldn't have been possible. The MPL implementation would have been much more difficult without Vesa Karvonen's wonderful Boost Preprocessor Metaprogramming Library. Authors are also greatly indebted to David B. Held who kindly volunteered to thoroughly edit this document. Of course, any remaining errors are exclusively ours.</p>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="example.html">Prev</a>&nbsp;</td>
<td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
<td width="40%" align="right">&nbsp;<a accesskey="n" href="refs.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">5. Example: a compile-time FSM generator&nbsp;</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">&nbsp;References</td>
</tr>
</table>
</div>
</body>
</html>
-82
View File
@@ -1,82 +0,0 @@
div.articletitle
{
text-align: center;
text-transform: uppercase;
}
div.authorgroup
{
text-align: center;
}
h3.title span.emphasis em
{
font-style: normal;
text-decoration: underline;
}
body
{
background-color: white;
color: black;
}
sup
{
font-size: x-small;
font-weight: lighter;
}
a:link
,a:visited
{
color: #505050;
}
sup a:link
,sup a:visited
,a.interlink:link
,a.interlink:visited
{
color: #505050;
text-decoration: none;
}
div.biblioentry p
{
border-style: none none none solid;
border-width: 1px;
border-color: silver;
margin-top: -1em;
padding-left: 0.5em;
padding-top: 0.25em;
}
div.table table
{
border: solid;
border-width: 1px;
border-color: silver;
}
div.table table tr th
{
background-color: #f0f0f0;
padding-left: 1em;
padding-right: 1em;
}
div.table table tr td
{
padding-left: 1em;
padding-right: 1em;
}
pre.programlisting
{
border-style: none none none solid;
border-width: 1px;
border-color: silver;
padding-left: 1em;
}
-124
View File
@@ -1,124 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>4. Code generation facilities</title>
<link rel="stylesheet" href="article.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
<meta name="keywords" content="template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time">
<link rel="home" href="index.html" title="the boost c++ metaprogramming library">
<link rel="up" href="index.html" title="the boost c++ metaprogramming library">
<link rel="previous" href="lambda.html" title="3. lambda facility">
<link rel="next" href="example.html" title="5. example: a compile-time fsm generator">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">4. Code generation facilities</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="lambda.html">Prev</a>&nbsp;</td>
<th width="60%" align="center">&nbsp;</th>
<td width="20%" align="right">&nbsp;<a accesskey="n" href="example.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="codegeneration"></a>4. Code generation facilities</h2>
</div>
</div>
<p>There are cases, especially in the domain of numeric computation, when one wants to perform some part of the calculations at compile-time, and then pass the results to a run-time part of the program for further processing. For example, suppose one has implemented a complex compile-time algorithm that works with fixed-point arithmetic:</p>
<pre class="programlisting">
// fixed-point algorithm input
typedef mpl::vector&lt;
mpl::fixed_c&lt;-1,2345678&gt;
, mpl::fixed_c&lt;9,0001&gt;
// ..
, mpl::fixed_c&lt;3,14159&gt;
&gt; input_data;
/*
complex compile-time algorithm
*/
typedef /*...*/ result_data;
</pre>
<p>Suppose the <tt>result_data</tt> here is a sequence of <tt>mpl::fixed_c</tt> types that keeps the results of the algorithm, and now one wishes to feed that result to the run-time part of the algorithm. With MPL she can do this:</p>
<pre class="programlisting">
double my_algorithm()
{
// passing the results to the run-time part of the program
std::vector&lt;double&gt; results;
results.reserve(mpl::size&lt;result_data&gt;::value);
mpl::for_each&lt;numbers,_&gt;(
boost::bind(&amp;std::vector&lt;double&gt;::push_back, &amp;results, _1)
);
// ...
}
</pre>
<p>The <tt>for_each&lt;numbers,_&gt;(...)</tt> call is what actually transfers the compile-time <tt>result_data</tt> into run-time <tt>results</tt>. <tt>for_each</tt> is a function template declared as:</p>
<pre class="programlisting">
template&lt;
typename Seq
, typename TransformOp
, typename F
&gt;
void for_each(F f)
{
// ...
}
</pre>
<p>To call the function, one is required to explicitly provide two actual template parameters, a compile-time sequence <tt>Seq</tt> and a unary transformation metafunction <tt>TransformOp</tt>, plus a run-time function argument <tt>f</tt> (in our example, <tt>numbers</tt>, <tt>_</tt>, and <tt>boost::bind(...)</tt> correspondingly). <tt>f</tt> is a function object which <tt>operator()</tt> is called for every element in the <tt>Seq</tt> tranfromed by <tt>TransformOp</tt>.</p>
<p>Applying this to our example, the</p>
<pre class="programlisting">
mpl::for_each&lt;numbers,_&gt;(
boost::bind(&amp;std::vector&lt;double&gt;::push_back, &amp;results, _1)
);
</pre>
<p>call is roughly equivalent to this:</p>
<pre class="programlisting">
f(mpl::apply&lt; _,mpl::at_c&lt;result_data,0&gt;::type &gt;::type());
f(mpl::apply&lt; _,mpl::at_c&lt;result_data,1&gt;::type &gt;::type());
// ...
f(mpl::apply&lt; _,mpl::at_c&lt;result_data,n&gt;::type &gt;::type());
</pre>
<p>where <tt>n == mpl::size&lt;result_data&gt;::type::value</tt>.</p>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="lambda.html">Prev</a>&nbsp;</td>
<td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
<td width="40%" align="right">&nbsp;<a accesskey="n" href="example.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">3. Lambda facility&nbsp;</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">&nbsp;5. Example: a compile-time FSM generator</td>
</tr>
</table>
</div>
</body>
</html>
-325
View File
@@ -1,325 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>5. Example: a compile-time FSM generator</title>
<link rel="stylesheet" href="article.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
<meta name="keywords" content="template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time">
<link rel="home" href="index.html" title="the boost c++ metaprogramming library">
<link rel="up" href="index.html" title="the boost c++ metaprogramming library">
<link rel="previous" href="codegeneration.html" title="4. code generation facilities">
<link rel="next" href="acknowl.html" title="6. acknowledgements">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">5. Example: a compile-time FSM generator</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="codegeneration.html">Prev</a>&nbsp;</td>
<th width="60%" align="center">&nbsp;</th>
<td width="20%" align="right">&nbsp;<a accesskey="n" href="acknowl.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="example"></a>5. Example: a compile-time FSM generator</h2>
</div>
</div>
<p>Finite state machines (FSMs) are an important tool for describing and implementing program behavior <span class="citation">[<a class="interlink" href="refs.html#ref.hu79" title="[hu79]">HU79</a>]</span>, <span class="citation">[<a class="interlink" href="refs.html#ref.mar98" title="[mar98]">Mar98</a>]</span>. They also are a good example of a domain in which metaprogramming can be applied to reduce the amount of repetitive and boilerplate operations one must perform in order to implement these simple mathematical models in code. Below we present a simple state machine generator that has been implemented using Boost Metaprogramming Library facilities. The generator takes a compile-time automata description, and converts it into C++ code that implements the FSM at run-time.</p>
<p>The FSM description is basically a combination of states and events plus a state transition table (STT), which ties them all together. The generator walks through the table and generates the state machine's <tt>process_event</tt> method that is the essence of an FSM.</p>
<p>Suppose we want to implement a simple music player using a finite state machine model. The state transition table for the FSM is shown in <a class="interlink" href="example.html#example.fsm.stt" title="table 1. player's state transition table with actions">Table 1</a>. The STT format reflects the way one usually describes the behavior of an FSM in plain English. For example, the first line of the table can be read as follows: &lsquo;If the model is in the <tt>stopped</tt> state and the <tt>play_event</tt> is received, then the <tt>do_play</tt> transition function is called, and the model transitions to the <tt>playing</tt> state&rsquo;.</p>
<div class="table"><a name="example.fsm.stt"></a>
<table summary="Player's state transition table with actions" border="0">
<colgroup>
<col>
<col>
<col>
<col></colgroup>
<thead>
<tr>
<th align="left">State</th>
<th align="left">Event</th>
<th align="left">Next state</th>
<th align="left">Transition function</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><tt>stopped</tt></td>
<td align="left"><tt>play_event</tt></td>
<td align="left"><tt>playing</tt></td>
<td align="left"><tt>do_play</tt></td>
</tr>
<tr>
<td align="left"><tt>playing</tt></td>
<td align="left"><tt>stop_event</tt></td>
<td align="left"><tt>stopped</tt></td>
<td align="left"><tt>do_stop</tt></td>
</tr>
<tr>
<td align="left"><tt>playing</tt></td>
<td align="left"><tt>pause_event</tt></td>
<td align="left"><tt>paused</tt></td>
<td align="left"><tt>do_pause</tt></td>
</tr>
<tr>
<td align="left"><tt>paused</tt></td>
<td align="left"><tt>play_event</tt></td>
<td align="left"><tt>playing</tt></td>
<td align="left"><tt>do_resume</tt></td>
</tr>
<tr>
<td align="left"><tt>paused</tt></td>
<td align="left"><tt>stop_event</tt></td>
<td align="left"><tt>stopped</tt></td>
<td align="left"><tt>do_stop</tt></td>
</tr>
</tbody>
</table>
<p class="title"><b>Table 1. Player's state transition table with actions</b></p>
</div>
<p>The transition table provides us with a complete formal definition of the target FSM, and there are several ways to transform that definition into code. For instance, if we define states as members of an enumeration type, and events as classes derived from some base <tt>event</tt> class <sup><a name="note.fsm" href="#ftn.note.fsm">10</a></sup> , like so:</p>
<pre class="programlisting">
class player
{
public:
// event declarations
struct event;
struct play_event;
struct stop_event;
struct pause_event;
// "input" function
void process_event(event const&amp;); // throws
private:
// states
enum state_t { stopped, playing, paused };
// transition functions
void do_play(play_event const&amp;);
void do_stop(stop_event const&amp;);
void do_pause(pause_event const&amp;);
void do_resume(play_event const&amp;);
private:
state_t m_state;
};
</pre>
<p>then the most straightforward way to derive the FSM implementation from the above table would be something like this:</p>
<pre class="programlisting">
void player::process_event(event const&amp; e)
{
if (m_state == stopped)
{
if (typeid(e) == typeid(play_event))
{
do_play(static_cast&lt;play_event const&amp;&gt;(e));
m_state = playing;
return;
}
}
else if (m_state == playing)
{
if (typeid(e) == typeid(stop_event))
{
do_stop(static_cast&lt;stop_event const&amp;&gt;(e));
m_state = stopped;
return;
}
if (typeid(e) == typeid(pause_event))
{
do_pause(static_cast&lt;pause_event const&amp;&gt;(e));
m_state = paused;
return;
}
}
else if (m_state == paused)
{
if (typeid(e) == typeid(stop_event))
{
do_stop(static_cast&lt;stop_event const&amp;&gt;(e));
m_state = stopped;
return;
}
if (typeid(e) == typeid(play_event))
{
do_play(static_cast&lt;play_event const&amp;&gt;(e));
m_state = playing;
return;
}
}
else
{
throw logic_error(
boost::format("unknown state: %d")
% static_cast&lt;int&gt;(m_state)
);
}
throw std::logic_error(
"unexpected event: " + typeid(e).name()
);
}
</pre>
<p>Although there is nothing particularly wrong with implementing an FSM's structure using nested <tt>if</tt> (or <tt>switch-case</tt>) statements, the obvious weakness of this approach is that most of the above code is boilerplate. What one tends to do with boilerplate code is to copy and paste it, then change names etc. to adjust it to its new location; and that's where the errors are most likely to creep in. Since all the lines of event processing look alike (structurally), it's very easy to overlook or forget something that needs to be changed, and many such errors won't appear until the runtime.</p>
<p>The transition table of our FSM is just five lines long; ideally, we would like the skeleton implementation of the automata's controlling logic to be equally short (or, at least, to look equally short, i.e. to be encapsulated in some form so we never worry about it).</p>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="example.impl"></a>5.1. Implementation</h3>
</div>
</div>
<p>To represent the STT in a C++ program, we define a <tt>transition</tt> class template that represents a single line of the table. Then the table itself can be represented as a sequence of such lines:</p>
<pre class="programlisting">
typedef mpl::list&lt;
transition&lt;stopped, play_event, playing, &amp;player::do_play&gt;
, transition&lt;playing, stop_event, stopped, &amp;player::do_stop&gt;
, transition&lt;playing, pause_event, paused, &amp;player::do_pause&gt;
, transition&lt;paused, play_event, playing, &amp;player::do_resume&gt;
, transition&lt;paused, stop_event, stopped, &amp;player::do_stop&gt;
&gt;::type transition_table;
</pre>
<p>Now, the complete FSM will look like this:</p>
<pre class="programlisting">
class player
: state_machine&lt;player&gt;
{
private:
typedef player self_t;
// state invariants
void stopped_state_invariant();
void playing_state_invariant();
void paused_state_invariant();
// states (invariants are passed as non-type template arguments,
// and are called then the FSM enters the corresponding state)
typedef state&lt;0, &amp;self_t::stopped_state_invariant&gt; stopped;
typedef state&lt;1, &amp;self_t::playing_state_invariant&gt; playing;
typedef state&lt;2, &amp;self_t::paused_state_invariant&gt; paused;
private:
// event declarations; events are represented as types,
// and can carry a specific data for each event;
// but it's not needed for generator, so we define them later
struct play_event;
struct stop_event;
struct pause_event;
// transition functions
void do_play(play_event const&amp;);
void do_stop(stop_event const&amp;);
void do_pause(pause_event const&amp;);
void do_resume(play_event const&amp;);
// STT
friend class state_machine&lt;player&gt;;
typedef mpl::list&lt;
transition&lt;stopped, play_event, playing, &amp;player::do_play&gt;
, transition&lt;playing, stop_event, stopped, &amp;player::do_stop&gt;
, transition&lt;playing, pause_event, paused, &amp;player::do_pause&gt;
, transition&lt;paused, play_event, playing, &amp;player::do_resume&gt;
, transition&lt;paused, stop_event, stopped, &amp;player::do_stop&gt;
&gt;::type transition_table;
};
</pre>
<p>That's all - the above will generate a complete FSM implementation according to our specification. The only thing we need before using it is the definition of the event types (that were just forward declared before):</p>
<pre class="programlisting">
// event definitions
struct player::play_event
: player::event
{
};
// ...
</pre>
<p>The usage is simple as well:</p>
<pre class="programlisting">
int main()
{
// usage example
player p;
p.process_event(player::play_event());
p.process_event(player::pause_event());
p.process_event(player::play_event());
p.process_event(player::stop_event());
return 0;
}
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="example.relatedwork"></a>5.2. Related work</h3>
</div>
</div>
<p>A notable prior work in the field of automation of general-purpose state machine implementation in C++ is the Robert Martin's <span class="emphasis"><em>State Machine Compiler</em></span> <span class="citation">[<a class="interlink" href="refs.html#ref.smc" title="[smc]">SMC</a>]</span>. The SMC takes an ASCII description of the machine's state transition table and produces C++ code that implements the FSM using a variation of State design pattern <span class="citation">[<a class="interlink" href="refs.html#ref.hun91" title="[hun91]">Hun91</a>]</span>, <span class="citation">[<a class="interlink" href="refs.html#ref.ghj95" title="[ghj+95]">GHJ+95</a>]</span>. Lafreniere <span class="citation">[<a class="interlink" href="refs.html#ref.laf00" title="[laf00]">Laf00</a>]</span> presents another approach, where no external tools are used, and the FSMs are table driven.</p>
</div>
<div class="footnotes"><br>
<hr width="100" align="left">
<div class="footnote">
<p><sup><a name="ftn.note.fsm" href="#note.fsm">10</a></sup>The events need to be passed to action functions, as they may contain some event-specific information for an action.</p>
</div>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="codegeneration.html">Prev</a>&nbsp;</td>
<td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
<td width="40%" align="right">&nbsp;<a accesskey="n" href="acknowl.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">4. Code generation facilities&nbsp;</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">&nbsp;6. Acknowledgements</td>
</tr>
</table>
</div>
</body>
</html>
-181
View File
@@ -1,181 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>The Boost C++ Metaprogramming Library</title>
<link rel="stylesheet" href="article.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
<meta name="keywords" content="template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time">
<link rel="home" href="index.html" title="the boost c++ metaprogramming library">
<link rel="next" href="intro.html" title="1. introduction">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">The Boost C++ Metaprogramming Library</th>
</tr>
<tr>
<td width="20%" align="left">&nbsp;</td>
<th width="60%" align="center">&nbsp;</th>
<td width="20%" align="right">&nbsp;<a accesskey="n" href="intro.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="article">
<div class="titlepage">
<div>
<div class="articletitle">
<h1 class="title"><a name="id1124916"></a>The Boost C++ Metaprogramming Library</h1>
</div>
</div>
<div>
<div class="authorgroup">
<h4>Aleksey Gurtovoy<sup>i</sup> and David Abrahams<sup>ii</sup></h4>
<div class="affiliation"><sup>i</sup><span class="orgname">MetaCommunications,</span> <a href="mailto:agurtovoy@meta-comm.com">agurtovoy@meta-comm.com</a></div>
<div class="affiliation"><sup>ii</sup><span class="orgname">Boost Consulting,</span> <a href="mailto:david.abrahams@rcn.com">david.abrahams@rcn.com</a></div>
</div>
</div>
<div>
<div class="abstract">
<p class="title"><b>Abstract</b></p>
<p>This paper describes the <tt>Boost</tt> C++ template metaprogramming library (MPL), an extensible compile-time framework of algorithms, sequences and metafunction classes. The library brings together important abstractions from the generic and functional programming worlds to build a powerful and easy-to-use toolset which makes template metaprogramming practical enough for the real-world environments. The MPL is heavily influenced by its run-time equivalent - the Standard Template Library (STL), a part of the C++ standard library <span class="citation">[<a class="interlink" href="refs.html#ref.stl94" title="[stl94]">STL94</a>]</span>, <span class="citation">[<a class="interlink" href="refs.html#ref.iso98" title="[iso98]">ISO98</a>]</span>. Like the STL, it defines an open conceptual and implementation framework which can serve as a foundation for future contributions in the domain. The library's fundamental concepts and idioms enable the user to focus on solutions without navigating the universe of possible ad-hoc approaches to a given metaprogramming problem, even if no actual MPL code is used. The library also provides a compile-time lambda expression facility enabling arbitrary currying and composition of class templates, a feature whose runtime counterpart is often cited as missing from the STL. This paper explains the motivation, usage, design, and implementation of the MPL with examples of its real-life applications, and offers some lessons learned about C++ template metaprogramming.</p>
</div>
</div>
<div>
<div class="keywords">
<p><b>Keywords:</b> template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time</p>
</div>
</div>
</div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dt>1. <a href="intro.html">Introduction</a></dt>
<dd>
<dl>
<dt>1.1. <a href="intro.html#intro.native">Native language metaprogramming</a></dt>
<dt>1.2. <a href="intro.html#intro.cxx">Metaprogramming in C++</a></dt>
<dd>
<dl>
<dt>1.2.1. <a href="intro.html#intro.cxx.numeric">Numeric computations</a></dt>
<dt>1.2.2. <a href="intro.html#intro.cxx.type">Type computations</a></dt>
<dt>1.2.3. <a href="intro.html#intro.cxx.seq">Type sequences</a></dt>
</dl>
</dd>
<dt>1.3. <a href="intro.html#intro.whymetaprog">Why metaprogramming?</a></dt>
<dt>1.4. <a href="intro.html#intro.whylibrary">Why a metaprogramming library?</a></dt>
</dl>
</dd>
<dt>2. <a href="usage.html">Basic usage</a></dt>
<dd>
<dl>
<dt>2.1. <a href="usage.html#typeselection">Conditional type selection</a></dt>
<dd>
<dl>
<dt>2.1.1. <a href="usage.html#delayedeval">Delayed evaluation</a></dt>
</dl>
</dd>
<dt>2.2. <a href="usage.html#metafunctions">Metafunctions</a></dt>
<dd>
<dl>
<dt>2.2.1. <a href="usage.html#metafunctions.simple">The simple form</a></dt>
<dt>2.2.2. <a href="usage.html#metafunctions.higherorder">Higher-order metafunctions</a></dt>
<dt>2.2.3. <a href="usage.html#metafunctions.classes">Metafunction classes</a></dt>
<dt>2.2.4. <a href="usage.html#metafunctions.onesize">One size fits all?</a></dt>
<dt>2.2.5. <a href="usage.html#metafunctions.lambda">From metafunction to metafunction class</a></dt>
</dl>
</dd>
<dt>2.3. <a href="usage.html#sequences">Sequences, algorithms, and iterators</a></dt>
<dd>
<dl>
<dt>2.3.1. <a href="usage.html#sequences.intro">Introduction</a></dt>
<dt>2.3.2. <a href="usage.html#sequences.algo">Algorithms and sequences</a></dt>
<dt>2.3.3. <a href="usage.html#sequences.concepts">Sequence concepts</a></dt>
<dt>2.3.4. <a href="usage.html#sequences.revisited">Ad hoc example revisited</a></dt>
<dt>2.3.5. <a href="usage.html#sequences.iterfold">iter_fold as the main iteration algorithm</a></dt>
<dt>2.3.6. <a href="usage.html#sequences.numbers">Sequences of numbers</a></dt>
<dt>2.3.7. <a href="usage.html#sequences.variety">A variety of sequences</a></dt>
<dt>2.3.8. <a href="usage.html#sequences.unrolling">Loop/recursion unrolling</a></dt>
</dl>
</dd>
</dl>
</dd>
<dt>3. <a href="lambda.html">Lambda facility</a></dt>
<dt>4. <a href="codegeneration.html">Code generation facilities</a></dt>
<dt>5. <a href="example.html">Example: a compile-time FSM generator</a></dt>
<dd>
<dl>
<dt>5.1. <a href="example.html#example.impl">Implementation</a></dt>
<dt>5.2. <a href="example.html#example.relatedwork">Related work</a></dt>
</dl>
</dd>
<dt>6. <a href="acknowl.html">Acknowledgements</a></dt>
<dt><a href="refs.html">References</a></dt>
</dl>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">&nbsp;</td>
<td width="20%" align="center">&nbsp;</td>
<td width="40%" align="right">&nbsp;<a accesskey="n" href="intro.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">&nbsp;</td>
<td width="20%" align="center">&nbsp;</td>
<td width="40%" align="right" valign="top">&nbsp;1. Introduction</td>
</tr>
</table>
</div>
</body>
</html>
-359
View File
@@ -1,359 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>1. Introduction</title>
<link rel="stylesheet" href="article.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
<meta name="keywords" content="template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time">
<link rel="home" href="index.html" title="the boost c++ metaprogramming library">
<link rel="up" href="index.html" title="the boost c++ metaprogramming library">
<link rel="previous" href="index.html" title="the boost c++ metaprogramming library">
<link rel="next" href="usage.html" title="2. basic usage">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">1. Introduction</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="index.html">Prev</a>&nbsp;</td>
<th width="60%" align="center">&nbsp;</th>
<td width="20%" align="right">&nbsp;<a accesskey="n" href="usage.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="intro"></a>1. Introduction</h2>
</div>
</div>
<p>Metaprogramming is usually defined as the creation of programs which generate other programs. Parser generators such as YACC <span class="citation">[<a class="interlink" href="refs.html#ref.joh79" title="[joh79]">Joh79</a>]</span> are examples of one kind of program-generating program. The input language to YACC is a context-free grammar in Extended Backus-Naur Form <span class="citation">[<a class="interlink" href="refs.html#ref.ebnf" title="[ebnf]">EBNF</a>]</span>, and its output is a program which parses that grammar. Note that in this case the metaprogram (YACC) is written in a language (C) which does not directly support the description of generated programs. These specifications, which we'll call <span class="emphasis"><em>metadata</em></span>, are not written in C, but in a <span class="emphasis"><em>meta-language</em></span>. Because the the rest of the user's program typically requires a general-purpose programming system and must interact with the generated parser, the metadata is translated into C, which is then compiled and linked together with the rest of the system. The metadata thus undergoes two translation steps, and the user is always very conscious of the boundary between her metadata and the rest of her program.</p>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="intro.native"></a>1.1. Native language metaprogramming</h3>
</div>
</div>
<p>A more interesting form of metaprogramming is available in languages such as Scheme <span class="citation">[<a class="interlink" href="refs.html#ref.ss75" title="[ss75]">SS75</a>]</span>, where the generated program specification is given in the same language as the metaprogram itself. The metaprogrammer defines her meta-language as a subset of the expressible forms of the underlying language, and program generation can take place in the same translation step used to process the rest of the user's program. This allows users to switch transparently between ordinary programming, generated program specification, and metaprogramming, often without being aware of the transition.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="intro.cxx"></a>1.2. Metaprogramming in C++</h3>
</div>
</div>
<p>In C++, it was discovered almost by accident <span class="citation">[<a class="interlink" href="refs.html#ref.unr" title="[unr]">Unr</a>]</span>, <span class="citation">[<a class="interlink" href="refs.html#ref.vel95a" title="[vel95a]">Vel95a</a>]</span> that the template mechanism provides a rich facility for computation at compile-time. In this section, we'll explore the basic mechanisms and some common idioms used for metaprogramming in C++.</p>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="intro.cxx.numeric"></a>1.2.1. Numeric computations</h4>
</div>
</div>
<p>The availability of <span class="emphasis"><em>non-type template parameters</em></span> makes it possible to perform integer computations at compile-time. For example, the following template computes the factorial of its argument:</p>
<pre class="programlisting">
template&lt; unsigned n &gt;
struct factorial
{
static const unsigned value = n * factorial&lt;n-1&gt;::value;
};
template&lt;&gt;
struct factorial&lt;0&gt;
{
static const unsigned value = 1;
};
</pre>
<p>The program fragment above is called a <span class="emphasis"><em>metafunction</em></span>, and it is easy to see its relationship to a function designed to be evaluated at runtime: the &lsquo;metafunction argument&rsquo; is passed as a template parameter, and its &lsquo;return value&rsquo; is defined as a nested static constant. Because of the hard line between the expression of compile-time and runtime computation in C++, metaprograms look different from their runtime counterparts. Thus, although as in Scheme the C++ metaprogrammer writes her code in the same language as the ordinary program, only a subset of the full C++ language is available to her: those expressions which can be evaluated at compile-time. Compare the above with a straightforward runtime definition of the factorial function:</p>
<pre class="programlisting">
unsigned factorial(unsigned N)
{
return N == 0 ? 1 : N * factorial(N - 1);
}
</pre>
<p>While it is easy to see the analogy between the two recursive definitions, recursion is in general more important to C++ metaprograms than it is to runtime C++. In contrast to languages such as Lisp where recursion is idiomatic, C++ programmers will typically avoid recursion when possible. This is done not only for efficiency reasons, but also because of &lsquo;cultural momentum&rsquo;: recursive programs are simply harder (for C++ programmers) to think about. Like pure Lisp, though, the C++ template mechanism is a <span class="emphasis"><em>functional</em></span> programming language: as such it rules out the use of data mutation required to maintain loop variables.</p>
<p>A key difference between the runtime and compile-time factorial functions is the expression of the termination condition: our meta-factorial uses template specialization as a kind of <span class="emphasis"><em>pattern-matching</em></span> mechanism to describe the behavior when <tt>N</tt> is zero. The syntactic analogue in the runtime world would require two separate definitions of the same function. In this case the impact of the second definition is minimal, but in large metaprograms the cost of maintaining and understanding the terminating definitions can become significant.</p>
<p>Note also that a C++ metafunction's return value must be <span class="emphasis"><em>named</em></span>. The name chosen here, <tt>value</tt>, is the same one used for all numeric returns in the MPL. As we'll see, establishing a consistent naming convention for metafunction returns is crucial to the power of the library.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="intro.cxx.type"></a>1.2.2. Type computations</h4>
</div>
</div>
<p>How could we apply our <tt>factorial</tt> metafunction? We might, for example, produce an array type of an appropriate size to hold all permutations of instances of another type:</p>
<pre class="programlisting">
// permutation_holder&lt;T&gt;::type is an array type which can contain
// all permutations of a given T.
// unspecialized template for scalars
template&lt; typename T &gt;
struct permutation_holder
{
typedef T type[1][1];
};
// specialization for array types
template&lt; typename T, unsigned N &gt;
struct permutation_holder&lt;T[N]&gt;
{
typedef T type[factorial&lt;N&gt;::value][N];
};
</pre>
<p>Here we have introduced the notion of a <span class="emphasis"><em>type computation</em></span>. Like <tt>factorial</tt> above, <tt>permutation_holder</tt> template is a metafunction. However, where <tt>factorial</tt> manipulates unsigned integer values, <tt>permutation_holder</tt> accepts and &lsquo;returns&rsquo; a type (as the nested typedef <tt>type</tt>). Because the C++ type system provides a much richer set of expressions than anything we can use as a nontype template argument (e.g. the integers), C++ metaprograms tend to be composed mostly of type computations.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="intro.cxx.seq"></a>1.2.3. Type sequences</h4>
</div>
</div>
<p>The ability to programmatically manipulate collections of types is a central tool of most interesting C++ metaprograms. Because this capability is so well-supported by the MPL, we'll provide just a brief introduction to the basics here. Later on, we'll revisit the example below to show how it can be implemented using MPL.</p>
<p>First, we'd need a way to represent the collection. One idea might be to store the types in a structure:</p>
<pre class="programlisting">
struct types
{
int t1;
long t2;
std::vector&lt;double&gt; t3;
};
</pre>
<p>Unfortunately, this arrangement is not susceptible to the compile-time type introspection power that C++ gives us: there's no way to find out what the names of the members are, and even if we assume that they're named according to some convention as above, there's no way to know how many members there are. The key to solving this problem is to increase the uniformity of the representation. If we have a consistent way to get the first type of any sequence and the rest of the sequence, we can easily access all members:</p>
<pre class="programlisting">
template&lt; typename First, typename Rest &gt;
struct cons
{
typedef First first;
typedef Rest rest;
};
struct nil {};
typedef
cons&lt;int
, cons&lt;long
, cons&lt;std::vector&lt;double&gt;
, nil
&gt; &gt; &gt; my_types;
</pre>
<p>The structure described by <tt>types</tt> above is the compile-time analogue of a singly-linked list; it has been first introduced by Czarnecki and Eisenecker in <span class="citation">[<a class="interlink" href="refs.html#ref.ce98" title="[ce98]">CE98</a>]</span>. Now that we've adjusted the structure so that the C++ template machinery can &lsquo;peel it apart&rsquo;, let's examine a simple metafunction which does so. Suppose a user wished to find the largest of an arbitrary collection of types. We can apply the recursive metafunction formula which should by now be familiar:</p>
<div class="example"><a name="example.largest"></a>
<p class="title"><b>Example 1. 'largest' metafunction</b></p>
<pre class="programlisting">
// choose the larger of two types
template&lt;
typename T1
, typename T2
, bool choose1 = (sizeof(T1) &gt; sizeof(T2)) // hands off!
&gt;
struct choose_larger
{
typedef T1 type;
};
// specialization for the case where sizeof(T2) &gt;= sizeof(T1)
template&lt; typename T1, typename T2 &gt;
struct choose_larger&lt; T1,T2,false &gt;
{
typedef T2 type;
};
// get the largest of a cons-list
template&lt; typename T &gt; struct largest;
// specialization to peel apart the cons list
template&lt; typename First, typename Rest &gt;
struct largest&lt; cons&lt;First,Rest&gt; &gt;
: choose_larger&lt; First, typename largest&lt;Rest&gt;::type &gt;
{
// type inherited from base
};
// specialization for loop termination
template&lt; typename First &gt;
struct largest&lt; cons&lt;First,nil&gt; &gt;
{
typedef First type;
};
int main()
{
// print the name of the largest of my_types
std::cout
&lt;&lt; typeid(largest&lt;my_types&gt;::type).name()
&lt;&lt; std::endl
;
}
</pre>
</div>
<p>There are several things worth noticing about this code:</p>
<div class="itemizedlist">
<ul type="box">
<li style="list-style-type: square">
<p>It uses a few ad-hoc, esoteric techniques, or &lsquo;hacks&rsquo;. The default template argument <tt>choose1</tt> (labeled &lsquo;hands off!&rsquo;) is one example. Without it, we would have needed yet another template to provide the implementation of <tt>choose_larger</tt>, or we would have had to provide the computation explicitly as a parameter to the template - perhaps not bad for this example, but it would make <tt>choose_larger</tt> much less useful and more error-prone. The other hack is the derivation of a specialization of <tt>largest</tt> from <tt>choose_larger</tt>. This is a code-saving device which allows the programmer to avoid writing &lsquo;<tt>typedef typename</tt> ...<tt>::type type</tt>&rsquo; in the template body.</p>
</li>
<li style="list-style-type: square">
<p>Even this simple metaprogram uses three separate partial specializations. The <tt>largest</tt> metafunction uses <span class="emphasis"><em>two</em></span> specializations. One might expect that this indicates there are two termination conditions, but there are not: one specialization is needed simply to deal with access to the sequence elements. These specializations make the code difficult to read by spreading the definition of a single metafunction over several C++ template definitions. Also, because they are <span class="emphasis"><em>partial</em></span> specializations, they make the code unusable for a large community of C++ programmers whose compilers don't support that feature.</p>
</li>
</ul>
</div>
<p>While these techniques are, of course, a valuable part of the arsenal of any good C++ metaprogrammer, their use tends to make programs written in what is already an unusual style harder-to-read and harder-to-write. By encapsulating commonly-used structures and dealing with loop terminations internally, the MPL reduces the need for both tricky hacks and for template specializations.</p>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="intro.whymetaprog"></a>1.3. Why metaprogramming?</h3>
</div>
</div>
<p>It's worth asking why anyone would want to do this. After all, even a simple toy example like the factorial metafunction is somewhat esoteric. To show how the type computation can be put to work, let's examine a simple example. The following code produces an array containing all possible permutations of another array:</p>
<pre class="programlisting">
// can't return an array in C++, so we need this wrapper
template&lt; typename T &gt;
struct wrapper
{
T x;
};
// return an array of the N! permutations of 'in'
template&lt; typename T &gt;
wrapper&lt; typename permutation_holder&lt;T&gt;::type &gt;
all_permutations(T const&amp; in)
{
wrapper&lt;typename permutation_holder&lt;T&gt;::type&gt; result;
// copy the unpermutated array to the first result element
unsigned const N = sizeof(T) / sizeof(**result.x);
std::copy(&amp;*in, &amp;*in + N, result.x[0]);
// enumerate the permutations
unsigned const result_size = sizeof(result.x) / sizeof(T);
for (T* dst = result.x + 1; dst != result.x + result_size; ++dst)
{
T* src = dst - 1;
std::copy(*src, *src + N, *dst);
std::next_permutation(*dst, *dst + N);
}
return result;
}
</pre>
<p>The runtime definition of <tt>factorial</tt> would be useless in <tt>all_permutations</tt> above, since in C++ the sizes of array members must be computed at compile-time. However, there are alternative approaches; how could we avoid metaprogramming, and what would the consequences be?</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>We could write programs to interpret the metadata directly. In our factorial example, the array size could have been a runtime quantity; then we'd have been able to use the straightforward factorial function. However, that would imply the use of dynamic allocation, which is often expensive.</p>
<p>To carry this further, YACC might be rewritten to accept a pointer-to-function returning tokens from the stream to be parsed, and a string containing the grammar description. This approach, however, would impose unacceptable runtime costs for most applications: either the parser would have to treat the grammar nondeterministically, exploring the grammar for each parse, or it would have to begin by replicating at runtime the substantial table-generation and optimization work of the existing YACC for each input grammar.</p>
</li>
<li>
<p>We could replace the compile-time computation with our own analysis. After all, the size of arrays passed to <tt>all_permutations</tt> are always known at compile-time, and thus can be known to its user. We could ask the user to supply the result type explicitly:</p>
<pre class="programlisting">
template&lt; typename Result, typename T &gt;
Result all_permutations(T const&amp; input);
</pre>
<p>The costs to this approach are obvious: we give up expressivity (by requiring the user to explicitly specify implementation details), and correctness (by allowing the user to specify them incorrectly). Anyone who has had to write parser tables by hand will tell you that the impracticality of this approach is the very reason of YACC's existence.</p>
<p>In a language such as C++, where the metadata can be expressed in the same language as the rest of the user's program, expressivity is further enhanced: the user can invoke metaprograms directly, without learning a foreign syntax or interrupting the flow of her code.</p>
</li>
</ol>
</div>
<p>So, the motivation for metaprogramming comes down to the combination of three factors: efficiency, expressivity, and correctness. While in classical programming there is always a tension between expressivity and correctness on one hand and efficiency on the other, in the metaprogramming world we wield new power: we can move the computation required for expressivity from runtime to compile-time.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="intro.whylibrary"></a>1.4. Why a metaprogramming <span class="emphasis"><em>library</em></span>?</h3>
</div>
</div>
<p>One might just as well ask why we need any generic library:</p>
<div class="itemizedlist">
<ul type="box">
<li style="list-style-type: square">
<p>Quality. Code that is appropriate for a general-purpose library is usually incidental to the purpose of its users. To a library developer, it is the central mission. On average, the containers and algorithms provided by any given C++ standard library implementation are more-flexible and better-implemented than the project-specific implementations which abound, because library development was treated as an end in itself rather than a task incidental to the development of some other application. With a centralized implementation for any given function, optimizations and improvements are more likely to have been applied.</p>
</li>
<li style="list-style-type: square">
<p>Re-use. More important even than the re-use of code which all libraries provide, a well-designed generic library establishes a <span class="emphasis"><em>framework of concepts and idioms</em></span> which establishes a reusable mental model for approaching problems. Just as the C++ Standard Template Library gave us iterator concepts and a function object protocol, the Boost Metaprogramming Library provides type-iterators and metafunction class protocol. A well-considered framework of idioms saves the metaprogrammer from considering irrelevant implementation details and allows her to concentrate on the problem at hand.</p>
</li>
<li style="list-style-type: square">
<p>Portability. A good library can smooth over the ugly realities of platform differences. While in theory a metaprogramming library is fully generic and shouldn't be concerned with these issues, in practice support for templates remains inconsistent even four years after standardization. This should perhaps not be surprising: C++ templates are the language's furthest-reaching and most complicated feature, which largely accounts for the power of metaprogramming in C++.</p>
</li>
<li style="list-style-type: square">
<p>Fun. Repeating the same idioms over and over is <span class="emphasis"><em>tedious</em></span>. It makes programmers tired and reduces productivity. Furthermore, when programmers get bored they get sloppy, and buggy code is even more costly than slowly-written code. Often the most useful libraries are simply patterns that have been &ldquo;plucked&rdquo; by an astute programmer from a sea of repetition. The MPL helps to reduce boredom by eliminating the need for the most commonly-repeated boilerplate coding patterns.</p>
</li>
</ul>
</div>
<p>As one can see, the MPL's development is motivated primarily by the same practical, real-world considerations that justify the development of any other library. Perhaps this is an indication that template metaprogramming is finally ready to leave the realm of the esoteric and enter the lingua franca of every day programmers.</p>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="index.html">Prev</a>&nbsp;</td>
<td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
<td width="40%" align="right">&nbsp;<a accesskey="n" href="usage.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">The Boost C++ Metaprogramming Library&nbsp;</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">&nbsp;2. Basic usage</td>
</tr>
</table>
</div>
</body>
</html>
-165
View File
@@ -1,165 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>3. Lambda facility</title>
<link rel="stylesheet" href="article.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
<meta name="keywords" content="template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time">
<link rel="home" href="index.html" title="the boost c++ metaprogramming library">
<link rel="up" href="index.html" title="the boost c++ metaprogramming library">
<link rel="previous" href="usage.html" title="2. basic usage">
<link rel="next" href="codegeneration.html" title="4. code generation facilities">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">3. Lambda facility</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="usage.html">Prev</a>&nbsp;</td>
<th width="60%" align="center">&nbsp;</th>
<td width="20%" align="right">&nbsp;<a accesskey="n" href="codegeneration.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="lambda"></a>3. Lambda facility</h2>
</div>
</div>
<p>The MPL's lambda facility allows the <i>inline composition</i> of class templates into &lsquo;lambda expressions&rsquo;, which are classes and can therefore be passed around as ordinary metafunction classes, or transformed into metafunction classes before application using the expression:</p>
<pre class="programlisting">
typedef mpl::lambda&lt;expr&gt;::type func;
</pre>
<p>For example, <tt>boost::remove_const</tt> traits template from Boost <tt>type_traits</tt> library <span class="citation">[<a class="interlink" href="refs.html#ref.ttl" title="[ttl]">TTL</a>]</span> is a class template (obviously), or a <a class="interlink" href="usage.html#metafunctions" title="2.2. metafunctions">metafunction</a> in MPL terminology. The simplest example of an &lsquo;inline composition&rsquo; of it would be something like:</p>
<pre class="programlisting">
typedef boost::remove_const&lt;_1&gt; expr;
</pre>
<p>This forms a so called &lsquo;lambda expression&rsquo;, which is neither a metafunction class, nor a metafunction, yet can be passed around everywhere because it's an ordinary C++ class, because all MPL facilities are polymorphic with respect to their arguments. Now, that lambda expression can be <span class="emphasis"><em>transformed</em></span> into a metafunction class using the MPL's <tt>lambda</tt> facility:</p>
<pre class="programlisting">
typedef boost::remove_const&lt;_1&gt; expr;
typedef mpl::lambda&lt;expr&gt;::type func;
</pre>
<p>The <tt>func</tt> is a unary metafunction class and can be used as such. In particular, it can be pass around or invoked (applied):</p>
<pre class="programlisting">
typedef mpl::apply&lt;func,int const&gt;::type res;
BOOST_MPL_ASSERT_IS_SAME(res, int);
</pre>
<p>or even</p>
<pre class="programlisting">
typedef func::apply&lt;int const&gt;::type res;
BOOST_MPL_ASSERT_IS_SAME(res, int);
</pre>
<p>Inline composition is very appealing syntactically when one deals with metafunctions, because it makes the expression obvious:</p>
<pre class="programlisting">
typedef mpl::logical_or&lt;
mpl::less&lt; mpl::size_of&lt;_1&gt;, mpl::int_c&lt;16&gt; &gt;
, boost::is_same&lt;_1,_2&gt;
&gt; expr;
typedef mpl::lambda&lt;expr&gt;::type func;
</pre>
<p>And one does not have to specify the last part (<tt>typedef lambda&lt;expr&gt;::type func</tt>), because all the algorithms do this to any of their metafunction class operands internally (a <tt>lambda&lt;T&gt;::type</tt> expression applied to a metafunction class gives back the same metafunction class, so it's safe to apply the expression unconditionally).</p>
<p>The alternative way to write an equivalent of the above metafunction class would be:</p>
<pre class="programlisting">
typedef bind&lt;
mpl::meta_fun2&lt;mpl::logical_or&gt;
, mpl::bind&lt; mpl::meta_fun2&lt;mpl::less&gt;
, mpl::bind&lt; mpl::meta_fun1&lt;mpl::size_of&gt;,_1 &gt;
, mpl::int_c&lt;16&gt;
&gt;
, mpl::bind&lt; mpl::meta_fun2&lt;boost::is_same&gt;,_1,_2 &gt;
&gt; func;
</pre>
<p>Or to use <tt>mpl::compose_</tt> family of templates in a similar way. Here, we use <tt>mpl::meta_fun</tt> templates to convert metafunctions into metafunction classes and then combine them using <tt>mpl::bind</tt>. The transformation from this form to the above inline lambda expression and vice-versa is mechanical, and that is essentially what the <tt>typedef mpl::lambda&lt;expr&gt;::type</tt> expression does.</p>
<p>For its own metafunctions (algorithms, primitives, etc.), MPL enables one to write the above in a less cumbersome way:</p>
<pre class="programlisting">
typedef mpl::bind&lt;
mpl::logical_or&lt;&gt;
, mpl::bind&lt; mpl::less&lt;&gt;, mpl::bind&lt;mpl::size_of&lt;&gt;,_1&gt;, mpl::int_c&lt;16&gt; &gt;
, mpl::bind&lt; mpl::make_f2&lt;boost::is_same&gt;, _1,_2 &gt;
&gt; func;
</pre>
<p>Note that we still have to wrap <tt>is_same</tt> into <tt>make_f2</tt>, because it's a foreign template.</p>
<p>Now, about combining class template metafunctions and metafunction classes in the single lambda expression - it can be done like this:</p>
<pre class="programlisting">
struct my_predicate
{
template&lt; typename T1, typename T2 &gt; struct apply
{
//...
};
};
typedef mpl::logical_or&lt;
mpl::less&lt; mpl::size_of&lt;_&gt;,mpl::int_c&lt;16&gt; &gt;
, mpl::bind&lt; my_predicate,_,_ &gt; // here
&gt; expr;
</pre>
<p>To bind something to one of its arguments (or change the order of parameters), then use either:</p>
<pre class="programlisting">
typedef mpl::logical_or&lt;
mpl::less&lt; mpl::size_of&lt;_&gt;,mpl::int_c&lt;16&gt; &gt;
, mpl::bind&lt;my_predicate,int,_&gt;::type // here
&gt; expr;
</pre>
<p>or</p>
<pre class="programlisting">
typedef mpl::logical_or&lt;
mpl::less&lt; mpl::size_of&lt;_&gt;,mpl::int_c&lt;16&gt; &gt;
, my_predicate::apply&lt;int,_&gt; // here
&gt; expr;
</pre>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="usage.html">Prev</a>&nbsp;</td>
<td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
<td width="40%" align="right">&nbsp;<a accesskey="n" href="codegeneration.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">2. Basic usage&nbsp;</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">&nbsp;4. Code generation facilities</td>
</tr>
</table>
</div>
</body>
</html>
-152
View File
@@ -1,152 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>References</title>
<link rel="stylesheet" href="article.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
<meta name="keywords" content="template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time">
<link rel="home" href="index.html" title="the boost c++ metaprogramming library">
<link rel="up" href="index.html" title="the boost c++ metaprogramming library">
<link rel="previous" href="acknowl.html" title="6. acknowledgements">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">References</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="acknowl.html">Prev</a>&nbsp;</td>
<th width="60%" align="center">&nbsp;</th>
<td width="20%" align="right">&nbsp;</td>
</tr>
</table>
<hr>
</div>
<div class="bibliography">
<div class="titlepage">
<div>
<h1 class="title"><a name="refs"></a>References</h1>
</div>
</div>
<div class="biblioentry"><a name="ref.abr01"></a>
<p>[Abr01] <span class="authorgroup">David Abrahams and Carlos Pinto Coelho,</span> <span class="title"><i><a href="http://users.rcn.com/abrahams/instantiation_speed/index.html" target="_top">Effects of Metaprogramming Style on Compilation Time</a></i>,</span> <span class="date">2001</span></p>
</div>
<div class="biblioentry"><a name="ref.ale01"></a>
<p>[Ale01] <span class="author">Andrei Alexandrescu,</span> <span class="title"><i>Modern C++ Design: Generic Programming and Design Patterns Applied</i>,</span> <span class="publishername">Addison-Wesley,</span> <span class="isbn">ISBN 0-201-70431-5,</span> <span class="date">2001</span></p>
</div>
<div class="biblioentry"><a name="ref.ce98"></a>
<p>[CE98] <span class="authorgroup">Krzysztof Czarnecki and Ulrich Eisenecker,</span> <span class="title"><i>Metalisp</i>,</span> <span class="bibliomisc"><a href="http://home.t-online.de/home/Ulrich.Eisenecker/meta.htm" target="_top">http://home.t-online.de/home/Ulrich.Eisenecker/meta.htm</a></span></p>
</div>
<div class="biblioentry"><a name="ref.ce00"></a>
<p>[CE00] <span class="authorgroup">Krzysztof Czarnecki and Ulrich Eisenecker,</span> <span class="title"><i>Generative Programming: Methods, Tools, and Applications</i>,</span> <span class="publishername">Addison-Wesley,</span> <span class="isbn">ISBN 0-201-30977-7,</span> <span class="date">2000</span></p>
</div>
<div class="biblioentry"><a name="ref.ebnf"></a>
<p>[EBNF] <span class="title"><i>ISO/IEC 14977:1996(E), Information technology &mdash; Syntactic metalanguage &mdash; Extended BNF</i>,</span> <span class="orgname">ISO/IEC,</span> <span class="date">1996</span></p>
</div>
<div class="biblioentry"><a name="ref.ghj95"></a>
<p>[GHJ+95] <span class="authorgroup">Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides,</span> <span class="title"><i>Design Patterns, Elements of Reusable Object-Oriented Software</i>,</span> <span class="publishername">Addison-Wesley,</span> <span class="isbn">ISBN 0-201-63361-2,</span> <span class="date">1995</span></p>
</div>
<div class="biblioentry"><a name="ref.hu79"></a>
<p>[HU79] <span class="authorgroup">Hopcroft and Ullman,</span> <span class="title"><i>Introduction to automata theory, languages and computations</i>,</span> <span class="publishername">Addison-Wesley,</span> <span class="date">1979</span></p>
</div>
<div class="biblioentry"><a name="ref.hud89"></a>
<p>[Hud89] <span class="author">Paul Hudak,</span> <span class="title"><i>Conception, Evolution, and Application of Functional Programming Languages</i>,</span> <span class="biblioset"><i>ACM Computing Surveys</i>, <span class="publishername">Association for Computing Machinery (ACM),</span> <span class="issn">ISSN 0360-0300,</span></span> <span class="volumenum">Vol. 21,</span> <span class="issuenum">No. 3,</span> <span class="pagenums">pp. 359-411,</span> <span class="date">September, 1989</span></p>
</div>
<div class="biblioentry"><a name="ref.hun91"></a>
<p>[Hun91] <span class="author">Immo Huneke,</span> <span class="title"><i>Finite State Machines: A Model of Behavior for C++</i>,</span> <span class="biblioset"><i>C++ Report</i>, <span class="publishername">SIGS Publications Inc.,</span> <span class="issn">ISSN 1040-6042,</span></span> <span class="date">1991</span></p>
</div>
<div class="biblioentry"><a name="ref.iso98"></a>
<p>[ISO98] <span class="title"><i>ISO/IEC 14882:1998(E), Programming languages &mdash; C++</i>,</span> <span class="orgname">ISO/IEC,</span> <span class="date">1998</span></p>
</div>
<div class="biblioentry"><a name="ref.joh79"></a>
<p>[Joh79] <span class="author">Stephen C. Johnson,</span> <span class="title"><i><a href="http://dinosaur.compilertools.net/yacc/index.html" target="_top">Yacc: Yet Another Compiler Compiler</a></i>,</span> <span class="publishername">UNIX Programmer's Manual,</span> <span class="volumenum">Vol. 2b,</span> <span class="pagenums">pp. 353-387,</span> <span class="date">1979</span></p>
</div>
<div class="biblioentry"><a name="ref.laf00"></a>
<p>[Laf00] <span class="author">David Lafreniere,</span> <span class="title"><i><a href="http://www.cuj.com/articles/2000/0005/0005f/0005f.htm?topic=articles" target="_top">State Machine Design in C++</a></i>,</span> <span class="biblioset"><i>C/C++ User Journal</i>, <span class="publishername">CMP Media LCC,</span> <span class="issn">ISSN 1075-2838,</span></span> <span class="volumenum">Vol. 18,</span> <span class="issuenum">No. 5,</span> <span class="date">May 1998</span></p>
</div>
<div class="biblioentry"><a name="ref.loki"></a>
<p>[Loki] <span class="title"><i>The Loki library</i>,</span> <span class="bibliomisc"><a href="http://sourceforge.net/projects/loki-lib/" target="_top">http://sourceforge.net/projects/loki-lib/</a></span></p>
</div>
<div class="biblioentry"><a name="ref.mar98"></a>
<p>[Mar98] <span class="author">Robert C. Martin,</span> <span class="title"><i><a href="http://www.objectmentor.com/resources/articles/umlfsm.pdf" target="_top">UML Tutorial: Finite State Machines</a></i>,</span> <span class="biblioset"><i>C++ Report</i>, <span class="publishername">SIGS Publications Inc.,</span> <span class="issn">ISSN 1040-6042,</span></span> <span class="date">June 1998</span></p>
</div>
<div class="biblioentry"><a name="ref.mplr"></a>
<p>[MPLR] <span class="title"><i>Boost MPL Library Reference Documentation</i>,</span> <span class="bibliomisc"><a href="http://www.mywikinet.com/mpl/ref/Table_of_Content.html" target="_top">http://www.mywikinet.com/mpl/ref/Table_of_Content.html</a></span></p>
</div>
<div class="biblioentry"><a name="ref.pre"></a>
<p>[PRE] <span class="author">Vesa Karvonen,</span> <span class="title"><i>Boost Preprocessor Metaprogramming library</i>,</span> <span class="bibliomisc"><a href="http://www.boost.org/libs/preprocessor/doc/" target="_top">http://www.boost.org/libs/preprocessor/doc/</a></span></p>
</div>
<div class="biblioentry"><a name="ref.smc"></a>
<p>[SMC] <span class="author">Robert C. Martin,</span> <span class="title"><i>SMC - Finite State Machine Compiler (C++)</i>,</span> <span class="bibliomisc"><a href="http://www.objectmentor.com/resources/downloads/index" target="_top">http://www.objectmentor.com/resources/downloads/index</a></span></p>
</div>
<div class="biblioentry"><a name="ref.stl94"></a>
<p>[STL94] <span class="authorgroup">A. A. Stepanov and M. Lee,</span> <span class="title"><i>The Standard Template Library</i>,</span> <span class="orgname">Hewlett-Packard Laboratories,</span> <span class="date">1994</span></p>
</div>
<div class="biblioentry"><a name="ref.spl"></a>
<p>[SPL] <span class="title"><i>Boost Smart Pointer library</i>,</span> <span class="bibliomisc"><a href="http://www.boost.org/libs/smart_ptr/" target="_top">http://www.boost.org/libs/smart_ptr/</a></span></p>
</div>
<div class="biblioentry"><a name="ref.ss75"></a>
<p>[SS75] <span class="authorgroup">Gerald&nbsp;J. Sussman and Guy&nbsp;L. Steele Jr.,</span> <span class="title"><i>Scheme: An interpreter for extended lambda calculus</i>,</span> <span class="biblioset"><i>MIT AI Memo 349</i>, <span class="publishername">Massachusetts Institute of Technology,</span></span> <span class="date">May 1975</span></p>
</div>
<div class="biblioentry"><a name="ref.ttl"></a>
<p>[TTL] <span class="title"><i>Boost Type Traits library</i>,</span> <span class="bibliomisc"><a href="http://www.boost.org/libs/type_traits/" target="_top">http://www.boost.org/libs/type_traits/</a></span></p>
</div>
<div class="biblioentry"><a name="ref.vel95a"></a>
<p>[Vel95a] <span class="author">Todd Veldhuizen,</span> <span class="title"><i><a href="http://osl.iu.edu/~tveldhui/papers/Template-Metaprograms/meta-art.html" target="_top">Using C++ template metaprograms</a></i>,</span> <span class="biblioset"><i>C++ Report</i>, <span class="publishername">SIGS Publications Inc.,</span> <span class="issn">ISSN 1040-6042,</span></span> <span class="volumenum">Vol. 7,</span> <span class="issuenum">No. 4,</span> <span class="pagenums">pp. 36-43,</span> <span class="date">May 1995</span></p>
</div>
<div class="biblioentry"><a name="ref.vel95b"></a>
<p>[Vel95b] <span class="author">Todd Veldhuizen,</span> <span class="title"><i><a href="http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html" target="_top">Expression templates</a></i>,</span> <span class="biblioset"><i>C++ Report</i>, <span class="publishername">SIGS Publications Inc.,</span> <span class="issn">ISSN 1040-6042,</span></span> <span class="volumenum">Vol. 7,</span> <span class="issuenum">No. 5,</span> <span class="pagenums">pp. 26-31,</span> <span class="date">Jun 1995</span></p>
</div>
<div class="biblioentry"><a name="ref.unr"></a>
<p>[Unr] <span class="author">Erwin Unruh,</span> <span class="title"><i>Prime number computation</i>,</span> <span class="publishername">ANSI X3J16-94-0075/ISO WG21-462</span></p>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="acknowl.html">Prev</a>&nbsp;</td>
<td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
<td width="40%" align="right">&nbsp;</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">6. Acknowledgements&nbsp;</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">&nbsp;</td>
</tr>
</table>
</div>
</body>
</html>
-920
View File
@@ -1,920 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
<title>2. Basic usage</title>
<link rel="stylesheet" href="article.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
<meta name="keywords" content="template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time">
<link rel="home" href="index.html" title="the boost c++ metaprogramming library">
<link rel="up" href="index.html" title="the boost c++ metaprogramming library">
<link rel="previous" href="intro.html" title="1. introduction">
<link rel="next" href="lambda.html" title="3. lambda facility">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">2. Basic usage</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="intro.html">Prev</a>&nbsp;</td>
<th width="60%" align="center">&nbsp;</th>
<td width="20%" align="right">&nbsp;<a accesskey="n" href="lambda.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="section">
<div class="titlepage">
<div>
<h2 class="title" style="clear: both"><a name="usage"></a>2. Basic usage</h2>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="typeselection"></a>2.1. Conditional type selection</h3>
</div>
</div>
<p>Conditional type selection is the simplest basic construct of C++ template metaprogramming. Veldhuizen <span class="citation">[<a class="interlink" href="refs.html#ref.vel95a" title="[vel95a]">Vel95a</a>]</span> was the first to show how to implement it, and Czarnecki and Eisenecker <span class="citation">[<a class="interlink" href="refs.html#ref.ce00" title="[ce00]">CE00</a>]</span> first presented it as a standalone library primitive. The MPL defines the corresponding facility as follows:</p>
<pre class="programlisting">
template&lt;
typename Condition
, typename T1
, typename T2
&gt;
struct if_
{
typedef /*unspecified*/ type;
};
</pre>
<p>Note that the first template parameter of the template is a type.</p>
<pre class="programlisting">
// usage/semantics
typedef mpl::if_&lt;mpl::true_c,char,long&gt;::type t1;
typedef mpl::if_&lt;mpl::false_c,char,long&gt;::type t2;
BOOST_MPL_ASSERT_IS_SAME(t1, char);
BOOST_MPL_ASSERT_IS_SAME(t2, long);
</pre>
<p>The construct is important because template metaprograms often contain a lot of decision-making code, and, as we will show, spelling it manually every time via (partial) class template specialization quickly becomes impractical. The template is also important from the point of encapsulating the compiler workarounds.</p>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="delayedeval"></a>2.1.1. Delayed evaluation</h4>
</div>
</div>
<p>The way the C++ template instantiation mechanism works imposes some subtle limitations on applicability of the type selection primitive (<tt>if_</tt>), compared to a manually implemented equivalent of the selection code. For example, suppose we are implementing a <tt>pointed_type</tt> traits template such that <tt>pointed_type&lt;T&gt;::type</tt> instantiated for a <tt>T</tt> that is either a plain pointer (<tt>U*</tt>), <tt>std::auto_ptr&lt;U&gt;</tt>, or any of the Boost smart pointers <span class="citation">[<a class="interlink" href="refs.html#ref.spl" title="[spl]">SPL</a>]</span>, e.g. <tt>boost::scoped_ptr&lt;U&gt;</tt>, will give us the pointed type (<tt>U</tt>):</p>
<pre class="programlisting">
BOOST_MPL_ASSERT_IS_SAME(pointed_type&lt;my*&gt;::type, my);
BOOST_MPL_ASSERT_IS_SAME(pointed_type&lt; std::auto_ptr&lt;my&gt; &gt;::type, my);
BOOST_MPL_ASSERT_IS_SAME(pointed_type&lt; boost::scoped_ptr&lt;my&gt; &gt;::type, my);
</pre>
<p>Unfortunately, the straightforward application of <tt>if_</tt> to this problem does not work: <sup><a name="note.pointedtype" href="#ftn.note.pointedtype">1</a></sup></p>
<pre class="programlisting">
template&lt; typename T &gt;
struct pointed_type
: mpl::if_&lt;
boost::is_pointer&lt;T&gt;
, typename boost::remove_pointer&lt;T&gt;::type
, typename T::element_type // #1
&gt;
{
};
// the following code causes compilation error in line #1:
// name followed by "::" must be a class or namespace name
typedef pointed_type&lt;char*&gt;::type result;
</pre>
<p>Clearly, the expression <tt>typename T::element_type</tt> is not valid in the case of <tt>T == char*</tt>, and that's what the compiler is complaining about. Implementing the selection code manually solves the problem:</p>
<pre class="programlisting">
namespace aux {
// general case
template&lt; typename T, bool is_pointer = false &gt;
struct select_pointed_type
{
typedef typename T::element_type type;
};
// specialization for plain pointers
template&lt; typename T &gt;
struct select_pointed_type&lt;T,true&gt;
{
typedef typename boost::remove_pointer&lt;T&gt;::type type;
};
}
template&lt; typename T &gt;
struct pointed_type
: aux::select_pointed_type&lt;
T, boost::is_pointer&lt;T&gt;::value
&gt;
{
};
</pre>
<p>But this quickly becomes awkward if needs to be done repeatedly, and this awkwardness is compounded when partial specialization is not available. We can try to work around the problem as follows:</p>
<pre class="programlisting">
namespace aux {
template&lt; typename T &gt;
struct element_type
{
typedef typename T::element_type type;
};
}
template&lt; typename T &gt;
struct pointed_type
{
typedef typename mpl::if_&lt;
boost::is_pointer&lt;T&gt;
, typename boost::remove_pointer&lt;T&gt;::type
, typename aux::element_type&lt;T&gt;::type
&gt;::type type;
};
</pre>
<p>but this doesn't work either - the access to the <tt>aux::element_type&lt;T&gt;</tt>'s nested <tt>type</tt> member still forces the compiler to instantiate <tt>element_type&lt;T&gt;</tt> with <tt>T == char*</tt>, and that instantiation is, of course, invalid. Also, although in our case this does not lead to a compile error, the <tt>boost::remove_pointer&lt;T&gt;</tt> template always gets instantiated as well, and for the same reason (because we are accessing its nested <tt>type</tt> member). Unnecessary instantiation that is not fatal may or may be not a problem, depending on the &lsquo;weight&rsquo; of the template (how much the instantiation taxes the compiler), but a general rule of thumb would be to avoid such code.</p>
<p>Returning to our error, to make the above code compile, we need to factor the act of &lsquo;asking&rsquo; <tt>aux::element_type&lt;T&gt;</tt> for its nested <tt>type</tt> out of the <tt>if_</tt> invocation. The fact that both the <tt>boost::remove_pointer&lt;T&gt;</tt> trait template and <tt>aux::element_type&lt;T&gt;</tt> use the same naming convention for their result types makes the refactoring easier:</p>
<pre class="programlisting">
template&lt; typename T &gt;
struct pointed_type
{
private:
typedef typename mpl::if_&lt;
boost::is_pointer&lt;T&gt;
, boost::remove_pointer&lt;T&gt;
, aux::element_type&lt;T&gt;
&gt;::type func_;
public:
typedef typename func_::type type;
};
</pre>
<p>Now the compiler is guaranteed not to instantiate both <tt>boost::remove_pointer&lt;T&gt;</tt> and <tt>aux::element_type&lt;T&gt;</tt>, even although they are used as actual parameters to the <tt>if_</tt> template, so we are allowed to get away with <tt>aux::element_type&lt;char*&gt;</tt> so long as it won't end up being selected as <tt>func_</tt>.</p>
<p>The above technique is so common in template metaprograms, that it even makes sense to facilitate the selection of a nested <tt>type</tt> member by introducing a high-level equivalent to <tt>if_</tt> - the one that will do the <tt>func_::type</tt> operation (that is called [nullary] metafunction class application) as a part of its invocation. The MPL provides such template - it's called <tt>apply_if</tt>. Using it, we can re-write the above code as simple as:</p>
<pre class="programlisting">
template&lt; typename T &gt;
struct pointed_type
{
typedef typename mpl::apply_if&lt;
boost::is_pointer&lt;T&gt;
, boost::remove_pointer&lt;T&gt;
, aux::element_type&lt;T&gt;
&gt;::type type;
};
</pre>
<p>To make our techniques review complete, let's consider a slightly different example - suppose we want to define a high-level wrapper around <tt>boost::remove_pointer</tt> traits template <span class="citation">[<a class="interlink" href="refs.html#ref.ttl" title="[ttl]">TTL</a>]</span>, which will strip the pointer qualification conditionally. We will call it <tt>remove_pointer_if</tt>:</p>
<pre class="programlisting">
template&lt;
typename Condition
, typename T
&gt;
struct remove_pointer_if
{
typedef typename mpl::if_&lt;
Condition
, typename boost::remove_pointer&lt;T&gt;::type
, T
&gt;::type type;
};
</pre>
<p>Now the above works the first time, but it suffers from the problem we mentioned earlier - <tt>boost::remove_pointer&lt;T&gt;</tt> gets instantiated even if its result is never used. In the metaprogramming world compilation time is an important resource <span class="citation">[<a class="interlink" href="refs.html#ref.abr01" title="[abr01]">Abr01</a>]</span>, and it is wasted by unnecessary template instantiations. We've just seen how to deal with the problem when both arguments to <tt>if_</tt> are the results of nullary metafunction class applications, but in this example one of the arguments (<tt>T</tt>) is just a simple type, so the refactoring just doesn't seem possible.</p>
<p>The easiest way out of this situation would be to pass to <tt>if_</tt> a real nullary metafunction instead of <tt>T</tt> - the one that returns <tt>T</tt> on its invocation. The MPL provides a simple way to do it - we just substitute <tt>identity&lt;T&gt;</tt> and <tt>apply_if</tt> for <tt>T</tt> and <tt>if_</tt>:</p>
<pre class="programlisting">
template&lt;
typename Condition
, typename T
&gt;
struct remove_pointer_if
{
typedef typename mpl::apply_if&lt;
Condition
, boost::remove_pointer&lt;T&gt;
, mpl::identity&lt;T&gt;
&gt;::type type;
};
</pre>
<p>which gives us exactly what we wanted.</p>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="metafunctions"></a>2.2. Metafunctions</h3>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="metafunctions.simple"></a>2.2.1. The simple form</h4>
</div>
</div>
<p>In C++, the basic underlying language construct which allows parameterized compile-time computation is the <i>class template</i> (<span class="citation">[<a class="interlink" href="refs.html#ref.iso98" title="[iso98]">ISO98</a>]</span>, section 14.5.1 [temp.class]). A bare class template is the simplest possible model we could choose for metafunctions: it can take types and/or non-type arguments as actual template parameters, and instantiation &lsquo;returns&rsquo; a new type. For example, the following produces a type derived from its arguments:</p>
<pre class="programlisting">
template&lt; typename T1, typename T2 &gt;
struct derive : T1, T2
{
};
</pre>
<p>However, this model is far too limiting: it restricts the metafunction result not only to class types, but to instantiations of a given class template, to say nothing of the fact that every metafunction invocation introduces an additional level of template nesting. While that might be acceptable for this particular metafunction, any model which prevented us from &lsquo;returning&rsquo;, say, <tt>int</tt> is obviously not general enough. To meet this basic requirement, we must rely on a nested type to provide our return value:</p>
<pre class="programlisting">
template&lt; typename T1, typename T2 &gt;
struct derive
{
struct type : N1, N2 {};
};
// silly specialization, but demonstrates "returning" int
template&lt;&gt;
struct derive&lt;void,void&gt;
{
typedef int type;
};
</pre>
<p>Veldhuizen <span class="citation">[<a class="interlink" href="refs.html#ref.vel95a" title="[vel95a]">Vel95a</a>]</span> was first to talk about class templates of this form as &lsquo;compile-time functions&rsquo;, and Czarnecki and Eisenecker <span class="citation">[<a class="interlink" href="refs.html#ref.ce00" title="[ce00]">CE00</a>]</span> have introduced &lsquo;template metafunction&rsquo; as an equivalent term (they also use the simpler term &lsquo;metafunction&rsquo;, as do we). Czarnecki and Eisenecker have also recognized the limitations of the simple metafunction representation and suggested the form that we discuss in <a class="interlink" href="usage.html#metafunctions.classes" title="2.2.3. metafunction classes">Section 2.2.3</a>.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="metafunctions.higherorder"></a>2.2.2. Higher-order metafunctions</h4>
</div>
</div>
<p>While syntactically simple, the simple template metafunction form does not always interact optimally with the rest of C++. In particular, the simple metafunction form makes it unnecessarily awkward and tedious to define and work with higher-order metafunctions (metafunctions that operate on other metafunctions). In order to pass a simple metafunction to another template, we need to use <i>template template parameters</i>:</p>
<pre class="programlisting">
// returns F(T1,F(T2,T3))
template&lt;
template&lt;typename&gt; class F
, typename T1
, typename T2
, typename T3
&gt;
struct apply_twice
{
typedef typename F&lt;
T1
, typename F&lt;T2,T3&gt;::type
&gt;::type type;
};
// a new metafunction returning a type derived from T1, T2, and T3
template&lt;
typename T1
, typename T2
, typename T3
&gt;
struct derive3
: apply_twice&lt;derive,T1,T2,T3&gt;
{
};
</pre>
<p>This looks different, but it seems to work. <sup><a name="note.higherorder" href="#ftn.note.higherorder">2</a></sup> However, things begin to break down noticeably when we want to &lsquo;return&rsquo; a metafunction from our metafunction:</p>
<pre class="programlisting">
// returns G s.t. G(T1,T2,T3) == F(T1,F(T2,T3))
template&lt; template&lt;typename&gt; class F &gt;
struct compose_self
{
template&lt;
typename T1
, typename T2
, typename T3
&gt;
struct type
: apply_twice&lt;F,T1,T2,T3&gt;
{
};
};
</pre>
<p>The first and most obvious problem is that the result of applying <tt>compose_self</tt> is not itself a type, but a template, so it can't be passed in the usual ways to other metafunctions. A more subtle issue, however, is that the metafunction &lsquo;returned&rsquo; is not exactly what we intended. Although it acts just like <tt>apply_twice</tt>, it differs in one important respect: its identity. In the C++ type system, <tt>compose_self&lt;F&gt;::template type&lt;T,U,V&gt;</tt> is not a synonym for <tt>apply_twice&lt;F,T,U,V&gt;</tt>, and any metaprogram which compared metafunctions would discover that fact.</p>
<p>Because C++ makes a strict distinction between type and class template template parameters, reliance on simple metafunctions creates a &lsquo;wall&rsquo; between metafunctions and metadata, relegating metafunctions to the status of second-class citizens. For example, recalling our introduction to type sequences, there's no way to make a <tt>cons</tt> list of metafunctions:</p>
<pre class="programlisting">
typedef cons&lt;derive, cons&lt;derive3, nil&gt; &gt; derive_functions; // error!
</pre>
<p>We might consider redefining our <tt>cons</tt> cell so we can pass <tt>derive</tt> as the head element:</p>
<pre class="programlisting">
template &lt;
template&lt; template&lt;typename T, typename U&gt; class F
, typename Tail
&gt;
struct cons;
</pre>
<p>However, now we have another problem: C++ templates are polymorphic with respect to their type arguments, but not with respect to template template parameters. The arity (number of parameters) of any template template parameter is strictly enforced, so we <span class="emphasis"><em>still</em></span> can't embed <tt>derive3</tt> in a <tt>cons</tt> list. Moreover, polymorphism <span class="emphasis"><em>between</em></span> types and metafunctions is not supported (the compiler expects one or the other), and as we've seen, the syntax and semantics of &lsquo;returned&rsquo; metafunctions is different from that of returned types. Trying to accomplish everything with the simple template metafunction form would seriously limit the applicability of higher-order metafunctions and would have an overall negative effect on the both conceptual and implementation clarity, simplicity and size of the library.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="metafunctions.classes"></a>2.2.3. Metafunction classes</h4>
</div>
</div>
<p>Fortunately, the truism that &lsquo;there is no problem in software which can't be solved by adding yet another level of indirection&rsquo; applies here. To elevate metafunctions to the status of first-class objects, the MPL introduces the concept of a &lsquo;metafunction class&rsquo;:</p>
<pre class="programlisting">
// metafunction class form of derive
struct derive
{
template&lt; typename N1, typename N2 &gt;
struct apply
{
struct type : N1, N2 {};
};
};
</pre>
<p>This form should look familiar to anyone acquainted with function objects in STL, with the nested <tt>apply</tt> template taking the same role as the runtime function-call operator. In fact, compile-time metafunction classes have the same relationship to metafunctions that runtime function objects have to functions:</p>
<pre class="programlisting">
// function form of add
template&lt; typename T &gt; T add(T x, T y) { return x + y; }
// function object form of add
struct add
{
template&lt; typename T &gt;
T operator()(T x, T y) { return x + y; }
};
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="metafunctions.onesize"></a>2.2.4. One size fits all?</h4>
</div>
</div>
<p>The metafunction class form solves all the problems with ordinary template metafunction mentioned earlier: since it is a regular class, it can be placed in compile-time metadata sequences and manipulated by other metafunctions using the same protocols as for any other metadata. We thereby avoid the code-duplication needed to provide versions of each library component to operate on ordinary metadata and on metafunctions with each distinct supported arity.</p>
<p>On the other hand, it seems that accepting metafunction classes as <span class="emphasis"><em>the</em></span> representation for compile-time function entities imposes code duplication danger as well: if the library's own primitives, algorithms, etc. are represented as class templates, that means that one either cannot reuse these algorithms in the context of higher-order functions, or she have to duplicate all algorithms in the second form, so, for instance, there would be two versions of <tt>find</tt>:</p>
<pre class="programlisting">
// user-friendly form
template&lt;
typename Sequence
, typename T
&gt;
struct find
{
typedef /* ... */ type;
};
// "metafunction class" form
struct find_func
{
template&lt; typename Sequence, typename T &gt;
struct apply
{
typedef /* ... */ type;
};
};
</pre>
<p>Of course, the third option is to eliminate &lsquo;user-friendly form&rsquo; completely so one would always have to write:</p>
<pre class="programlisting">
typedef mpl::find::apply&lt;list,long&gt;::type iter;
// or, if one prefers,
// typedef mpl::apply&lt; mpl::find,list,long &gt;::type iter;
</pre>
<p>instead of</p>
<pre class="programlisting">
typedef mpl::find&lt;list,long&gt;::type iter;
</pre>
<p>That too would hurt usability, considering that the direct invocations of library's algorithms are far more often-used than passing algorithms as arguments to other algorithms/metafunctions.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="metafunctions.lambda"></a>2.2.5. From metafunction to metafunction class</h4>
</div>
</div>
<p>The MPL's answer to this dilemma is <i>lambda expressions</i>. Lambda is the mechanism that enables the library to curry metafunctions and convert them into metafunction classes, so when one wants to pass the <tt>find</tt> algorithm as an argument to a higher-order metafunction, she just write:</p>
<pre class="programlisting">
using namespace mpl::placeholder;
typedef mpl::apply&lt; my_f, mpl::find&lt;_1,_2&gt; &gt;::type result;
</pre>
<p>where <tt>_1</tt> and <tt>_2</tt> are placeholders for the first and second arguments to the resulting metafunction class. This preserves the intuitive syntax below for when the user wants to use <tt>find</tt> directly in her code:</p>
<pre class="programlisting">
typedef mpl::find&lt;list,long&gt;::type iter;
</pre>
<p>Lambda facility is described in more details in <a class="interlink" href="lambda.html#lambda" title="3. lambda facility">Section 3</a>.</p>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h3 class="title"><a name="sequences"></a>2.3. Sequences, algorithms, and iterators</h3>
</div>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="sequences.intro"></a>2.3.1. Introduction</h4>
</div>
</div>
<p>Compile-time iteration over a sequence (of types) is one of the basic concepts of template metaprogramming. Differences in types of objects being manipulated is the most common point of variability of similar but not identical code/design, and such designs are the direct target for some metaprogramming. Templates were originally designed to solve this exact problem (e.g. <tt>std::vector</tt>). However, without predefined abstractions/constructs for manipulating/iterating over <span class="emphasis"><em>sequences</em></span> of types (as opposed to standalone types), and without known techniques for emulating these constructs using the current language facilities, their effect on helping high-level metaprogramming happen has been limited.</p>
<p>Czarnecki and Eisenecker <span class="citation">[<a class="interlink" href="refs.html#ref.ce98" title="[ce98]">CE98</a>]</span>, <span class="citation">[<a class="interlink" href="refs.html#ref.ce00" title="[ce00]">CE00</a>]</span> were the first to introduce compile-time sequences of types and some simple algorithms on them, although the idea of representing common data structures like trees, lists, etc. at compile time, using class template composition has been around for a while (e.g. most of the expression template libraries build such trees as a part of their expression "parsing" process <span class="citation">[<a class="interlink" href="refs.html#ref.vel95b" title="[vel95b]">Vel95b</a>]</span>). Alexandrescu <span class="citation">[<a class="interlink" href="refs.html#ref.ale01" title="[ale01]">Ale01</a>]</span> used lists of types and some algorithms on them to implement several design patterns; the accompanying code is known as the Loki library <span class="citation">[<a class="interlink" href="refs.html#ref.loki" title="[loki]">Loki</a>]</span>.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="sequences.algo"></a>2.3.2. Algorithms and sequences</h4>
</div>
</div>
<p>Most of the algorithms in the Boost Metaprogramming Library operate on sequences. For example, searching for a type in a list looks like this:</p>
<pre class="programlisting">
typedef mpl::list&lt;char,short,int,long,float,double&gt; types;
typedef mpl::find&lt;types,long&gt;::type iter;
</pre>
<p>Here, <tt>find</tt> accepts two parameters - a sequence to search (<tt>types</tt>) and the type to search for (<tt>long</tt>) - and returns an iterator <tt>iter</tt> pointing to the first element of the sequence such that <tt>iter::type</tt> is identical to <tt>long</tt>. If no such element exists, <tt>iter</tt> is identical to <tt>end&lt;types&gt;::type</tt>. Basically, this is how one would search for a value in a <tt>std::list</tt> or <tt>std::vector</tt>, except that <tt>mpl::find</tt> accepts the sequence as a single parameter, while <tt>std::find</tt> takes two iterators. Everything else is pretty much the same - the names are the same, the semantics are very close, there are iterators, and one can search not only by type, but also by using a predicate:</p>
<pre class="programlisting">
typedef mpl::find_if&lt; types,boost::is_float&lt;_&gt; &gt;::type iter;
</pre>
<p>This conceptual/syntactical similarity with the STL is not coincidental. Reusing the conceptual framework of the STL in the compile-time world allows us to apply familiar and sound approaches for dealing with sequential data structures. The algorithms and idioms which programmers already know from the STL can be applied again at compile-time. We consider this to be one of MPL's greatest strengths, distinguishing it from earlier attempts to build a template metaprogramming library.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="sequences.concepts"></a>2.3.3. Sequence concepts</h4>
</div>
</div>
<p>In the <tt>find</tt> example above, we searched for the type in a sequence built using the <tt>mpl::list</tt> template; but <tt>list</tt> is not the only sequence that the library provides. Neither is <tt>mpl::find</tt> or any other algorithm hard-coded to work only with <tt>list</tt> sequences. <tt>list</tt> is just one model of MPL's <span class="concept">Forward Sequence</span> concept, and <tt>find</tt> works with anything that satisfies this concept's requirements. The hierarchy of sequence concepts in MPL is quite simple - a <span class="concept">Sequence</span> is any compile-time entity for which <tt>begin&lt;&gt;</tt> and <tt>end&lt;&gt;</tt> produce iterators to the range of its elements; a <span class="concept">Forward Sequence</span> is a Sequence whose iterators satisfy <span class="concept">Forward Iterator</span> requirements; a <span class="concept">Bidirectional Sequence</span> is a Forward Sequence whose iterators satisfy <span class="concept">Bidirectional Iterator</span> requirements; finally, a <span class="concept">Random Access Sequence</span> is a Bidirectional Sequence whose iterators satisfy <span class="concept">Random Access Iterator</span> requirements. <sup><a name="note.seqconcepts" href="#ftn.note.seqconcepts">3</a></sup></p>
<p>Decoupling algorithms from particular sequence implementations (through iterators) allows a metaprogrammer to create her own sequence types and to retain the rest of the library at her disposal. For example, one can define a <tt>tiny_list</tt> for dealing with sequences of three types as follows:</p>
<pre class="programlisting">
template&lt; typename TinyList, long Pos &gt;
struct tiny_list_item;
template&lt; typename TinyList, long Pos &gt;
struct tiny_list_iterator
{
typedef typename tiny_list_item&lt;TinyList,Pos&gt;::type type;
typedef tiny_list_iterator&lt;TinyList, Pos-1&gt; prior;
typedef tiny_list_iterator&lt;TinyList, Pos+1&gt; next;
};
template&lt; typename T0, typename T1, typename T2 &gt;
struct tiny_list
{
typedef tiny_list_iterator&lt;tiny_list, 0&gt; begin;
typedef tiny_list_iterator&lt;tiny_list, 3&gt; end;
typedef T0 type0;
typedef T1 type1;
typedef T2 type2;
};
template&lt; typename TinyList &gt;
struct tiny_list_item&lt;TinyList,0&gt;
{
typedef typename TinyList::type0 type;
};
template&lt; typename TinyList &gt;
struct tiny_list_item&lt;TinyList,1&gt;
{
typedef typename TinyList::type1 type;
};
template&lt; typename TinyList &gt;
struct tiny_list_item&lt;TinyList,2&gt;
{
typedef typename TinyList::type2 type;
};
</pre>
<p>and then use it with any of the library algorithms as if it were <tt>mpl::list</tt>:</p>
<pre class="programlisting">
typedef tiny_list&lt; char,short,int &gt; types;
typedef mpl::transform&lt;
types
, boost::add_pointer&lt;_1&gt;
&gt;::type pointers;
</pre>
<p>Note that <tt>tiny_list</tt> is a model of Bidirectional Sequence; it would be a Random Access Sequence if we added <tt>advance</tt> and <tt>distance</tt> members to <tt>tiny_list_iterator</tt>:</p>
<pre class="programlisting">
template&lt; typename TinyList, long Pos &gt;
struct tiny_list_iterator
{
static long const position = Pos;
typedef typename tiny_list_item&lt;TinyList,Pos&gt;::type type;
typedef tiny_list_iterator&lt;TinyList, Pos-1&gt; prior;
typedef tiny_list_iterator&lt;TinyList, Pos+1&gt; next;
template&lt; typename N &gt; struct advance
{
typedef tiny_list_iterator&lt;
TinyList
, Pos + N::value
&gt; type;
};
template&lt; typename Other &gt; struct distance
{
typedef mpl::integral_c&lt;
long
, Other::position - position
&gt; type;
};
};
</pre>
<p>While the <tt>tiny_list</tt> itself might be not that interesting (after all, it can hold only three elements), if the technique above could be automated so we would be able to define not-so-tiny sequences (with five, ten, twenty, etc. elements), it would be very valuable. <sup><a name="note.tinylist" href="#ftn.note.tinylist">4</a></sup></p>
<p>External code generation is an option, but there exists a solution within the language. However, it is not a template metaprogramming, but rather <span class="emphasis"><em>preprocessor metaprogramming</em></span>. In fact, MPL's <tt>vector</tt> - a fixed-size type sequence that provides random-access iterators - is implemented very much like the above <tt>tiny_list</tt> - using the Boost Preprocessor library <span class="citation">[<a class="interlink" href="refs.html#ref.pre" title="[pre]">PRE</a>]</span>.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="sequences.revisited"></a>2.3.4. Ad hoc example revisited</h4>
</div>
</div>
<p>So, the library provides its users with almost complete compile-time equivalent of the STL framework. Does it help them to solve their metaprogramming tasks? Let's return to our earlier <a class="interlink" href="intro.html#example.largest" title="example 1. 'largest' metafunction"><tt>largest</tt></a> example to see if we can rewrite it in a better way with what MPL has to offer. Well, actually, there is not much to look at, because the MPL implementation is a one-liner (we'll spread it out here for readability) <sup><a name="note.maxelement" href="#ftn.note.maxelement">5</a></sup> :</p>
<pre class="programlisting">
template&lt; typename Sequence &gt;
struct largest
{
typedef typename mpl::max_element&lt;
Sequence
mpl::less&lt;
mpl::size_of&lt;_1&gt;
, mpl::size_of&lt;_2&gt;
&gt;
&gt;::type iter;
typedef typename iter::type type;
};
</pre>
<p>There are no more termination conditions with tricky pattern matching, no more partial specializations; and even more importantly, it's <span class="emphasis"><em>obvious</em></span> what the above code does - even although it's all templates - something that one could not say about the original version.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="sequences.iterfold"></a>2.3.5. iter_fold as the main iteration algorithm</h4>
</div>
</div>
<p>For the purpose of examining a little bit more of the library's internal structure, let's look at how <tt>max_element</tt> from the above example is implemented. One might expect that <span class="emphasis"><em>now</em></span> we will again see all these awkward partial specializations, esoteric pattern matching, etc. Well, let's see:</p>
<pre class="programlisting">
template&lt;
typename Sequence
, typename Predicate
&gt;
struct max_element
{
typedef typename mpl::iter_fold&lt;
Sequence
, typename mpl::begin&lt;Sequence&gt;::type
, if_&lt; less&lt; deref&lt;_1&gt;,deref&lt;_2&gt; &gt;, _2, _1 &gt;
&gt;::type type;
};
</pre>
<p>The first thing to notice here is that this algorithm is implemented in terms of another one: <tt>iter_fold</tt>. In fact, this is probably the most important point of the example, because nearly all other generic sequence algorithms in the library are implemented in terms of <tt>iter_fold</tt>. If a user should ever need to implement her own sequence algorithm, she'll almost certainly be able to do so using this primitive, which means she won't have to resort to implementing hand-crafted iteration, pattern matching of special cases for loop termination, or workarounds for lack of partial specialization. It also means that her algorithm will automatically benefit from any optimizations the library has implemented, (e.g. recursion unrolling), and that it will work with any sequence that is a model of ForwardSequence, because <tt>iter_fold</tt> does not require anything more of its sequence argument.</p>
<p><tt>iter_fold</tt> algorithm is basically a compile-time equivalent of the <tt>fold</tt> or <tt>reduce</tt> functions that comprise the basic and well-known primitives of many functional programming languages. An analogy more familiar to a C++ programmer would be the <tt>std::accumulate</tt> algorithm from the C++ standard library (<span class="citation">[<a class="interlink" href="refs.html#ref.iso98" title="[iso98]">ISO98</a>]</span>, section 26.4.1 [lib.accumulate]). However, <tt>iter_fold</tt> is designed to take advantage of the natural characteristics of recursive traversal: it accepts <span class="emphasis"><em>two</em></span> metafunction class arguments, the first of which is applied to the state "on the way in" and the second of which is applied "on the way out".</p>
<p>The interface to <tt>iter_fold</tt> is defined in MPL as follows:</p>
<pre class="programlisting">
template&lt;
typename Sequence
, typename InitialState
, typename ForwardOp
, typename BackwardOp = _1
&gt;
struct iter_fold
{
typedef /*unspecified*/ type;
};
</pre>
<p>The algorithm &lsquo;returns&rsquo; the result of two-way successive applications of binary <tt>ForwardOp</tt> and <tt>BackwardOp</tt> operations to iterators in range [<tt>begin&lt;Sequence&gt;::type</tt>, <tt>end&lt;Sequence&gt;::type</tt>) and previous result of an operation; the <tt>InitialState</tt> is logically placed before the sequence and included in the forward traversal. The result <tt>type</tt> is identical to <tt>InitialState</tt> if the sequence is empty.</p>
<p>The library also provides <tt>iter_fold_backward</tt>, <tt>fold</tt>, and <tt>fold_backward</tt> algorithms which wrap <tt>iter_fold</tt> to accommodate its most common usage patterns.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="sequences.numbers"></a>2.3.6. Sequences of numbers</h4>
</div>
</div>
<p>What we've seen so far were sequences (and algorithms on sequences) of types. It is both possible and easy to manipulate compile-time <span class="emphasis"><em>values</em></span> using the library as well. The only thing to remember is that in C++, class template non-type template parameters give us one more example of non-polymorphic behavior. In other words, if one declared a metafunction to take a non-type template parameter (e.g. <tt>long</tt>) it's not possible to pass anything besides compile-time integral constants to it:</p>
<pre class="programlisting">
template&lt; long N1, long N2 &gt;
struct equal_to
{
static bool const value = (N1 == N2);
};
equal_to&lt;5,5&gt;::value; // ok
equal_to&lt;int,int&gt;::value; // error!
</pre>
<p>And of course this doesn't work the other way around either:</p>
<pre class="programlisting">
typedef mpl::list&lt;1,2,3,4,5&gt; numbers; // error!
</pre>
<p>While this may be an obvious limitation, it imposes yet another dilemma on the library design: on the one hand, we don't want to restrict users to type manipulations only, and on the other hand, full support for integral manipulations would require at least duplication of most of the library facilities <sup><a name="note.nontype" href="#ftn.note.nontype">6</a></sup> - the same situation as we would have if we had chosen to represent metafunctions as ordinary class templates. The solution for this issue is the same as well: we represent integral values by wrapping them in types <sup><a name="note.valuewrapping" href="#ftn.note.valuewrapping">7</a></sup> . For example, to create a list of numbers one can write:</p>
<pre class="programlisting">
typedef mpl::list&lt;
mpl::int_c&lt;1&gt;
, mpl::int_c&lt;2&gt;
, mpl::int_c&lt;3&gt;
, mpl::int_c&lt;4&gt;
, mpl::int_c&lt;5&gt;
&gt; numbers;
</pre>
<p>Wrapping integral constants into types to make them first-class citizens is important well inside metaprograms, where one often doesn't know (and doesn't care) if the metafunctions she is using operate on types, integral values, other metafunctions, or something else, like fixed-point or rational numbers (<tt>mpl::fixed_c</tt> and <tt>mpl::rational_c</tt>).</p>
<p>But, from the user's perspective, the above example is much more verbose than the shorter, incorrect one. Thus, for the purpose of convenience, the library does provide users with a template that takes non-type template parameters, but offers a more compact notation:</p>
<pre class="programlisting">
typedef mpl::list_c&lt;long,1,2,3,4,5&gt; numbers;
</pre>
<p>There is a similar <tt>vector</tt> counterpart as well:</p>
<pre class="programlisting">
typedef mpl::vector_c&lt;long,1,2,3,4,5&gt; numbers;
</pre>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="sequences.variety"></a>2.3.7. A variety of sequences</h4>
</div>
</div>
<p>Previous efforts to provide generalized metaprogramming facilities for C++ have always concentrated on <tt>cons</tt>-style type lists and a few core algorithms like <tt>size</tt> and <tt>at</tt>, which are tied to the specific sequence implementation. Such systems have an elegant simplicity reminiscent of the analogous functionality in pure functional Lisp. It is much more time-consuming to implement even a basic set of the sequence algorithms provided by equivalent run-time libraries (the STL in particular), but if we have learned anything from the STL, it is that tying those algorithms' implementations to a specific sequence implementation is a misguided effort!</p>
<p>The truth is that there is no single &lsquo;best&rsquo; type sequence implementation for the same reasons that there will never be a single &lsquo;best&rsquo; runtime sequence implementation. Furthermore, there are <span class="emphasis"><em>already</em></span> quite a number of type list implementations in use today; and just as the STL algorithms can operate on sequences which don't come from STL containers, so the MPL algorithms are designed to work with foreign type sequences.</p>
<p>It may be an eye-opening fact for some that type lists are not the only useful compile-time sequence. Again, the need for a variety of compile-time containers arises for the same reasons that we have lists, vectors, deques, and sets in the C++ standard library - different containers have different functional and performance characteristics which determine not only applicability and efficiency of particular algorithms, but also the expressiveness or verbosity of the code that uses them. While runtime performance is not an issue for C++ metaprograms, compilation speed is often a significant bottleneck to advanced C++ software development <span class="citation">[<a class="interlink" href="refs.html#ref.abr01" title="[abr01]">Abr01</a>]</span>.</p>
<p>The MPL provides five built-in sequences: <tt>list</tt>, <tt>list_c</tt> (really just a <tt>list</tt> of value wrappers), <tt>vector</tt>, a randomly-accessible sequence of fixed maximum size, <tt>vector_c</tt>, and <tt>range_c</tt>, a randomly-accessible sequence of consecutive integral values. More important, however, is its ability to adapt to arbitrary sequence types. The only core operations that a sequence is required to provide in order to be used with the library algorithms are <tt>begin&lt;&gt;</tt> and <tt>end&lt;&gt;</tt> metafunctions which "return" iterators into the sequence. As with the STL, it is the iterators which are used to implement most of the general-purpose sequence algorithms the library provides. Also, as with the STL, algorithm specialization is used to take advantage of implementation knowledge about particular sequences: many of the "basic" sequence operations such as <tt>back&lt;&gt;</tt>, <tt>front&lt;&gt;</tt>, <tt>size&lt;&gt;</tt>, and <tt>at&lt;&gt;</tt> are specialized on sequence type to provide a more efficient implementation than the fully generic version.</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<h4 class="title"><a name="sequences.unrolling"></a>2.3.8. Loop/recursion unrolling</h4>
</div>
</div>
<p>Almost coincidentally, loop unrolling can be as important to compile-time iterative algorithms as it is to runtime algorithms. To see why, one must first remember that all "loops" in C++ metaprograms, are in fact, implemented with recursion, and that the template instantiation depth can be a valuable resource in a compiler implementation. In fact, Annex B of the C++ standard (<span class="citation">[<a class="interlink" href="refs.html#ref.iso98" title="[iso98]">ISO98</a>]</span>, annex B [limits]) <span class="emphasis"><em>recommends</em></span> a minimum depth of 17 recursively nested template instantiations; but this is far too low for many serious metaprograms, some of which easily exceed the hard-coded instantiation limits of some otherwise excellent compilers. To see how this works in action, let's examine a straightforward implementation of the <tt>fold</tt> metafunction, which combines some algorithm state with each element of a sequence:</p>
<pre class="programlisting">
namespace aux {
// unspecialized version combines the initial state and first element
// and recurses to process the rest
template&lt;
typename Start
, typename Finish
, typename State
, typename BinaryFunction
&gt;
struct fold_impl
: fold_impl&lt;
typename Start::next
, Finish
, typename apply&lt;
BinaryFunction
, State
, typename Start::type
&gt;::type
, BinaryFunction
&gt;
{
};
// specialization for loop termination
template&lt;
typename Finish
, typename State
, typename BinaryFunction
&gt;
struct fold_impl&lt;Finish,Finish,State,BinaryFunction&gt;
{
typedef State type;
};
} // namespace aux
// public interface
template&lt;
typename Sequence
, typename State
, typename ForwardOp
&gt;
struct fold
: aux::fold_impl&lt;
, typename begin&lt;Sequence&gt;::type
, typename end&lt;Sequence&gt;::type
, State
, typename lambda&lt;ForwardOp&gt;::type
&gt;
{
};
</pre>
<p>Although simple and elegant, this implementation will always incur at least as many levels of recursive template instantiation as there are elements in the input sequence. <sup><a name="note.unrolling1" href="#ftn.note.unrolling1">8</a></sup> The library addresses this problem by explicitly "unrolling" the recursion. To apply the technique to our <tt>fold</tt> example, we begin by factoring out a single step of the algorithm. Our <tt>fold_impl_step</tt> metafunction has two results: <tt>type</tt> (the next state), and <tt>iterator</tt> (the next sequence position).</p>
<pre class="programlisting">
template&lt;
typename BinaryFunction
, typename State
, typename Start
, typename Finish
&gt;
struct fold_impl_step
{
typedef typename apply&lt;
BinaryFunction
, State
, typename Start::type
&gt;::type type;
typedef typename Start::next iterator;
};
</pre>
<p>As with our main algorithm implementation, we specialize for the loop termination condition so that the step becomes a no-op:</p>
<pre class="programlisting">
template&lt;
typename BinaryFunction
, typename State
, typename Finish
&gt;
struct fold_impl_step&lt;BinaryFunction,State,Finish,Finish&gt;
{
typedef State type;
typedef Finish iterator;
};
</pre>
<p>Now we can now reduce <tt>fold</tt>'s instantiation depth by any constant factor N simply by inserting N invocations of <tt>fold_impl_step</tt>. Here we've chosen a factor of 4:</p>
<pre class="programlisting">
template&lt;
typename Start
, typename Finish
, typename State
, typename BinaryFunction
&gt;
struct fold_impl
{
private:
typedef fold_impl_step&lt;
BinaryFunction
, State
, Start
, Finish
&gt; next1;
typedef fold_impl_step&lt;
BinaryFunction
, typename next1::type
, typename next1::iterator
, Finish
&gt; next2;
typedef fold_impl_step&lt;
BinaryFunction
, typename next2::type
, typename next2::iterator
, Finish
&gt; next3;
typedef fold_impl_step&lt;
BinaryFunction
, typename next3::type
, typename next3::iterator
, Finish
&gt; next4;
typedef fold_impl_step&lt;
typename next4::iterator
, Finish
, typename next4::type
, BinaryFunction
&gt; recursion;
public:
typedef typename recursion::type type;
};
</pre>
<p>The MPL applies this unrolling technique across all algorithms with an unrolling factor tuned according to the demands of the C++ implementation in use, and with an option for the user to override the value. <sup><a name="note.unrolling2" href="#ftn.note.unrolling2">9</a></sup> This fact enables users to push beyond the metaprogramming limits they would usually encounter with more naive algorithm implementations. Experiments also show a small (up to 10%) increase in metaprogram instantiation speed on some compilers when loop unrolling is used.</p>
</div>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="intro.html">Prev</a>&nbsp;</td>
<td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
<td width="40%" align="right">&nbsp;<a accesskey="n" href="lambda.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">1. Introduction&nbsp;</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">&nbsp;3. Lambda facility</td>
</tr>
</table>
</div>
</body>
</html>
-11
View File
@@ -1,11 +0,0 @@
@echo off
if "%4" == "" goto build
f:\msxsl\msxsl.exe f:\home\depot\xml\stylesheets\docbook-xsl-1.50.0\html\titlepage.templates.xml f:\home\depot\xml\stylesheets\docbook-1.50.0\template\titlepage.xsl | f:\msxsl\msxsl.exe - f:\msxsl\to_utf8.xsl -o f:\home\depot\xml\stylesheets\docbook-xsl-1.50.0\html\titlepage.templates.xsl
:build
sx -x lower -x empty %2 >%3.xml
xsltproc -o %3 f:\home\depot\xml\stylesheets\docbook-xsl-1.50.0\html\my\%1 %3.xml
del %3.xml
f:\tidy\tidy.exe -config f:\tidy\config.txt -m %3
f:\tidy\tidy_attr.py %3
File diff suppressed because it is too large Load Diff
+2163 -2300
View File
File diff suppressed because it is too large Load Diff
-11
View File
@@ -1,11 +0,0 @@
@echo off
if "%4" == "" goto build
f:\msxsl\msxsl.exe f:\home\depot\xml\stylesheets\docbook-xsl-1.50.0\html\titlepage.templates.xml f:\home\depot\xml\stylesheets\docbook-xsl-1.52.2\template\titlepage.xsl | f:\msxsl\msxsl.exe - f:\msxsl\to_utf8.xsl -o f:\home\depot\xml\stylesheets\docbook-1.50.0\html\titlepage.templates.xsl
:build
sx -x lower -x empty %2 >%3.xml
f:\msxsl\msxsl.exe %3.xml f:\home\depot\xml\stylesheets\docbook-xsl-1.50.0\html\my\%1 -o %3
del %3.xml
f:\tidy\tidy.exe -config f:\tidy\config.txt -m %3
f:\tidy\tidy_attr.py %3
-38
View File
@@ -1,38 +0,0 @@
<articleinfo>
<authorgroup>
<author>
<firstname>Aleksey</><surname>Gurtovoy</>
<affiliation>
<orgname>MetaCommunications</>
<address><email>agurtovoy@meta-comm.com</></>
</affiliation>
</author>
<author>
<firstname>David</><surname>Abrahams</>
<affiliation>
<orgname>Boost Consulting</>
<address><email>david.abrahams@rcn.com</></>
</affiliation>
</author>
</authorgroup>
<abstract>
<para>
This paper describes the &Boost; &Cxx; template metaprogramming library (&MPL;), an extensible compile-time framework of algorithms, sequences and metafunction classes. The library brings together important abstractions from the generic and functional programming worlds to build a powerful and easy-to-use toolset which makes template metaprogramming practical enough for the real-world environments. The &MPL; is heavily influenced by its run-time equivalent - the Standard Template Library (STL), a part of the C++ standard library <citation><xref linkend="ref.STL94"></>, <citation><xref linkend="ref.ISO98"></>. Like the STL, it defines an open conceptual and implementation framework which can serve as a foundation for future contributions in the domain. The library's fundamental concepts and idioms enable the user to focus on solutions without navigating the universe of possible ad-hoc approaches to a given metaprogramming problem, even if no actual &MPL; code is used. The library also provides a compile-time lambda expression facility enabling arbitrary currying and composition of class templates, a feature whose runtime counterpart is often cited as missing from the STL. This paper explains the motivation, usage, design, and implementation of the &MPL; with examples of its real-life applications, and offers some lessons learned about &Cxx; template metaprogramming.
</>
</abstract>
<keywordset>
<keyword>template metaprogramming</>
<keyword>generic programming</>
<keyword>programming languages</>
<keyword>C++</>
<keyword>STL</>
<keyword>type systems</>
<keyword>polymorphism</>
<keyword>compile-time</>
</keywordset>
</articleinfo>
-10
View File
@@ -1,10 +0,0 @@
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="acknowl">
<title>Acknowledgements</>
<para>
Peter Dimov contributed the <literal>bind</> functionality without which compile-time lambda expressions wouldn't have been possible. The &MPL; implementation would have been much more difficult without Vesa Karvonen's wonderful Boost Preprocessor Metaprogramming Library. Authors are also greatly indebted to David B. Held who kindly volunteered to thoroughly edit this document. Of course, any remaining errors are exclusively ours.
</>
</section>
-41
View File
@@ -1,41 +0,0 @@
<!doctype article public "-//OASIS//DTD DocBook V4.1//EN"
[
<!-- abbreviations -->
<!entity mdash "-">
<!entity Boost "<literal>Boost</>">
<!entity Cxx "C++">
<!entity C "C">
<!entity MPL "MPL">
<!entity BMPL "Boost Metaprogramming Library">
<!entity mdat "metadata">
<!entity mping "metaprogramming">
<!entity mfn "metafunction">
<!entity unspec "/*unspecified*/">
<!-- physical entities -->
<!entity abstract SYSTEM "abstract.sgml">
<!entity introduction SYSTEM "introduction.sgml">
<!entity usage SYSTEM "usage.sgml">
<!entity typeselection SYSTEM "typeselection.sgml">
<!entity metafunctions SYSTEM "metafunctions.sgml">
<!entity sequences SYSTEM "sequences.sgml">
<!entity lambda SYSTEM "lambda.sgml">
<!entity codegeneration SYSTEM "codegeneration.sgml">
<!entity example SYSTEM "example.sgml">
<!entity acknowl SYSTEM "acknowl.sgml">
<!entity references SYSTEM "references.sgml">
]>
<article>
<title>The Boost &Cxx; Metaprogramming Library</>
&abstract;
&introduction;
&usage;
&lambda;
&codegeneration;
&example;
&acknowl;
&references;
</article>
-96
View File
@@ -1,96 +0,0 @@
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="codegeneration">
<title>Code generation facilities</>
<para>
There are cases, especially in the domain of numeric computation, when one wants to perform some part of the calculations at compile-time, and then pass the results to a run-time part of the program for further processing. For example, suppose one has implemented a complex compile-time algorithm that works with fixed-point arithmetic:
</>
<programlisting>
<![CDATA[
// fixed-point algorithm input
typedef mpl::vector<
mpl::fixed_c<-1,2345678>
, mpl::fixed_c<9,0001>
// ..
, mpl::fixed_c<3,14159>
> input_data;
/*
complex compile-time algorithm
*/
typedef /*...*/ result_data;
]]>
</>
<para>
Suppose the <literal>result_data</> here is a sequence of <literal>mpl::fixed_c</> types that keeps the results of the algorithm, and now one wishes to feed that result to the run-time part of the algorithm. With &MPL; she can do this:
</>
<programlisting>
<![CDATA[
double my_algorithm()
{
// passing the results to the run-time part of the program
std::vector<double> results;
results.reserve(mpl::size<result_data>::value);
mpl::for_each<numbers,_>(
boost::bind(&std::vector<double>::push_back, &results, _1)
);
// ...
}
]]>
</>
<para>
The <literal>for_each&lt;numbers,_&gt;(...)</> call is what actually transfers the compile-time <literal>result_data</> into run-time <literal>results</>. <literal>for_each</> is a function template declared as:
</>
<programlisting>
<![CDATA[
template<
typename Seq
, typename TransformOp
, typename F
>
void for_each(F f)
{
// ...
}
]]>
</>
<para>To call the function, one is required to explicitly provide two actual template parameters, a compile-time sequence <literal>Seq</> and a unary transformation metafunction <literal>TransformOp</>, plus a run-time function argument <literal>f</> (in our example, <literal>numbers</>, <literal>_</>, and <literal>boost::bind(...)</> correspondingly). <literal>f</> is a function object which <literal>operator()</> is called for every element in the <literal>Seq</> tranfromed by <literal>TransformOp</>.
</>
<para>
Applying this to our example, the
</>
<programlisting>
<![CDATA[
mpl::for_each<numbers,_>(
boost::bind(&std::vector<double>::push_back, &results, _1)
);
]]>
</>
<para>
call is roughly equivalent to this:
</>
<programlisting>
<![CDATA[
f(mpl::apply< _,mpl::at_c<result_data,0>::type >::type());
f(mpl::apply< _,mpl::at_c<result_data,1>::type >::type());
// ...
f(mpl::apply< _,mpl::at_c<result_data,n>::type >::type());
]]>
</>
<para>
where <literal>n == mpl::size&lt;result_data&gt;::type::value</>.
</>
</section>
-294
View File
@@ -1,294 +0,0 @@
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="example">
<title>Example: a compile-time FSM generator</>
<para>
Finite state machines (<acronym>FSMs</>) are an important tool for describing and implementing program behavior <citation><xref linkend="ref.hu79"></>, <citation><xref linkend="ref.mar98"></>. They also are a good example of a domain in which &mping; can be applied to reduce the amount of repetitive and boilerplate operations one must perform in order to implement these simple mathematical models in code. Below we present a simple state machine generator that has been implemented using &BMPL; facilities. The generator takes a compile-time automata description, and converts it into &Cxx; code that implements the FSM at run-time.
</>
<para>
The FSM description is basically a combination of states and events plus a state transition table (<acronym>STT</>), which ties them all together. The generator walks through the table and generates the state machine's <literal>process_event</> method that is the essence of an FSM.
</>
<para>
Suppose we want to implement a simple music player using a finite state machine model. The state transition table
for the FSM is shown in <xref linkend="example.fsm.stt">. The STT format reflects the way one usually describes the behavior of an FSM in plain English. For example, the first line of the table can be read as follows: <quote>If the model is in the <literal>stopped</> state and the <literal>play_event</> is received, then the <literal>do_play</> transition function is called, and the model transitions to the <literal>playing</> state</>.
</>
<table id="example.fsm.stt" frame="none">
<title>Player's state transition table with actions</>
<tgroup cols="4" align="left">
<thead>
<row>
<entry>State</>
<entry>Event</>
<entry>Next state</>
<entry>Transition function</>
</>
</>
<tbody>
<row>
<entry><literal>stopped</></>
<entry><literal>play_event</></>
<entry><literal>playing</></>
<entry><literal>do_play</></>
</>
<row>
<entry><literal>playing</></>
<entry><literal>stop_event</></>
<entry><literal>stopped</></>
<entry><literal>do_stop</></>
</>
<row>
<entry><literal>playing</></>
<entry><literal>pause_event</></>
<entry><literal>paused</></>
<entry><literal>do_pause</></>
</>
<row>
<entry><literal>paused</></>
<entry><literal>play_event</></>
<entry><literal>playing</></>
<entry><literal>do_resume</></>
</>
<row>
<entry><literal>paused</></>
<entry><literal>stop_event</></>
<entry><literal>stopped</></>
<entry><literal>do_stop</></>
</>
</>
</tgroup>
</table>
<para>
The transition table provides us with a complete formal definition of the target FSM, and there are several ways to
transform that definition into code. For instance, if we define states as members of an enumeration type, and events as classes derived from some base <literal>event</> class
<footnote id="note.fsm"><para>The events need to be passed to action functions, as they may contain some event-specific information for an action.</></>
, like so:
</>
<programlisting>
<![CDATA[
class player
{
public:
// event declarations
struct event;
struct play_event;
struct stop_event;
struct pause_event;
// "input" function
void process_event(event const&); // throws
private:
// states
enum state_t { stopped, playing, paused };
// transition functions
void do_play(play_event const&);
void do_stop(stop_event const&);
void do_pause(pause_event const&);
void do_resume(play_event const&);
private:
state_t m_state;
};
]]>
</>
<para>
then the most straightforward way to derive the FSM implementation from the above table would be something
like this:
</>
<programlisting>
<![CDATA[
void player::process_event(event const& e)
{
if (m_state == stopped)
{
if (typeid(e) == typeid(play_event))
{
do_play(static_cast<play_event const&>(e));
m_state = playing;
return;
}
}
else if (m_state == playing)
{
if (typeid(e) == typeid(stop_event))
{
do_stop(static_cast<stop_event const&>(e));
m_state = stopped;
return;
}
if (typeid(e) == typeid(pause_event))
{
do_pause(static_cast<pause_event const&>(e));
m_state = paused;
return;
}
}
else if (m_state == paused)
{
if (typeid(e) == typeid(stop_event))
{
do_stop(static_cast<stop_event const&>(e));
m_state = stopped;
return;
}
if (typeid(e) == typeid(play_event))
{
do_play(static_cast<play_event const&>(e));
m_state = playing;
return;
}
}
else
{
throw logic_error(
boost::format("unknown state: %d")
% static_cast<int>(m_state)
);
}
throw std::logic_error(
"unexpected event: " + typeid(e).name()
);
}
]]>
</>
<para>
Although there is nothing particularly wrong with implementing an FSM's structure using nested <literal>if</> (or <literal>switch-case</>) statements, the obvious weakness of this approach is that most of the above code is boilerplate. What one tends to do with boilerplate code is to copy and paste it, then change names etc. to adjust it to its new location; and that's where the errors are most likely to creep in. Since all the lines of event processing look alike (structurally), it's very easy to overlook or forget something that needs to be changed, and many such errors won't appear until the runtime.
</>
<para>
The transition table of our FSM is just five lines long; ideally, we would like the skeleton implementation of the automata's controlling logic to be equally short (or, at least, to look equally short, i.e. to be encapsulated in some form so we never worry about it).
</>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="example.impl">
<title>Implementation</>
<para>
To represent the STT in a &Cxx; program, we define a <literal>transition</> class template that represents a single line of the table. Then the table itself can be represented as a sequence of such lines:
</>
<programlisting>
<![CDATA[
typedef mpl::list<
transition<stopped, play_event, playing, &player::do_play>
, transition<playing, stop_event, stopped, &player::do_stop>
, transition<playing, pause_event, paused, &player::do_pause>
, transition<paused, play_event, playing, &player::do_resume>
, transition<paused, stop_event, stopped, &player::do_stop>
>::type transition_table;
]]></>
<para>
Now, the complete FSM will look like this:
</>
<programlisting>
<![CDATA[
class player
: state_machine<player>
{
private:
typedef player self_t;
// state invariants
void stopped_state_invariant();
void playing_state_invariant();
void paused_state_invariant();
// states (invariants are passed as non-type template arguments,
// and are called then the FSM enters the corresponding state)
typedef state<0, &self_t::stopped_state_invariant> stopped;
typedef state<1, &self_t::playing_state_invariant> playing;
typedef state<2, &self_t::paused_state_invariant> paused;
private:
// event declarations; events are represented as types,
// and can carry a specific data for each event;
// but it's not needed for generator, so we define them later
struct play_event;
struct stop_event;
struct pause_event;
// transition functions
void do_play(play_event const&);
void do_stop(stop_event const&);
void do_pause(pause_event const&);
void do_resume(play_event const&);
// STT
friend class state_machine<player>;
typedef mpl::list<
transition<stopped, play_event, playing, &player::do_play>
, transition<playing, stop_event, stopped, &player::do_stop>
, transition<playing, pause_event, paused, &player::do_pause>
, transition<paused, play_event, playing, &player::do_resume>
, transition<paused, stop_event, stopped, &player::do_stop>
>::type transition_table;
};
]]>
</>
<para>
That's all &mdash; the above will generate a complete FSM implementation according to our specification. The only thing we need before using it is the definition of the event types (that were just forward declared before):
</>
<programlisting>
<![CDATA[
// event definitions
struct player::play_event
: player::event
{
};
// ...
]]>
</>
<para>
The usage is simple as well:
</>
<programlisting>
<![CDATA[
int main()
{
// usage example
player p;
p.process_event(player::play_event());
p.process_event(player::pause_event());
p.process_event(player::play_event());
p.process_event(player::stop_event());
return 0;
}
]]>
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="example.relatedwork">
<title>Related work</>
<para>
A notable prior work in the field of automation of general-purpose state machine implementation in &Cxx; is the Robert Martin's <emphasis>State Machine Compiler</> <citation><xref linkend="ref.smc"></>. The SMC takes an ASCII description of the machine's state transition table and produces &Cxx; code that implements the FSM using a variation of State design pattern <citation><xref linkend="ref.hun91"></>, <citation><xref linkend="ref.ghj95"></>. Lafreniere <citation><xref linkend="ref.laf00"></> presents another approach, where no external tools are used, and the FSMs are table driven.
</>
</section>
</section>
-375
View File
@@ -1,375 +0,0 @@
<section id="intro">
<title>Introduction</>
<para>
Metaprogramming is usually defined as the creation of programs which generate other programs. Parser generators such as YACC <citation><xref linkend="ref.Joh79"></> are examples of one kind of program-generating program. The input language to YACC is a context-free grammar in Extended Backus-Naur Form <citation><xref linkend="ref.EBNF"></>, and its output is a program which parses that grammar. Note that in this case the metaprogram (YACC) is written in a language (&C;) which does not directly support the description of generated programs. These specifications, which we'll call <emphasis>&mdat;</>, are not written in &C;, but in a <emphasis>meta-language</>. Because the the rest of the user's program typically requires a general-purpose programming system and must interact with the generated parser, the &mdat; is translated into &C;, which is then compiled and linked together with the rest of the system. The &mdat; thus undergoes two translation steps, and the user is always very conscious of the boundary between her &mdat; and the rest of her program.
</>
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="intro.native">
<title>Native language metaprogramming</>
<para>
A more interesting form of &mping; is available in languages such as Scheme <citation><xref linkend="ref.SS75"></>, where the generated program specification is given in the same language as the metaprogram itself. The metaprogrammer defines her meta-language as a subset of the expressible forms of the underlying language, and program generation can take place in the same translation step used to process the rest of the user's program. This
allows users to switch transparently between ordinary programming, generated program specification, and &mping;, often without being aware of the transition.
</>
</section>
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="intro.cxx">
<title>Metaprogramming in &Cxx;</>
<para>
In &Cxx;, it was discovered almost by accident <citation><xref linkend="ref.Unr"></>, <citation><xref linkend="ref.Vel95a"></> that the template mechanism provides a rich facility for computation at compile-time. In this section, we'll explore the basic mechanisms and some common idioms used for metaprogramming in &Cxx;.
</>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="intro.cxx.numeric">
<title>Numeric computations</>
<para>
The availability of <emphasis>non-type template parameters</> makes it possible to perform integer computations at compile-time. For example, the following template computes the factorial of its argument:
</>
<programlisting>
<![CDATA[
template< unsigned n >
struct factorial
{
static const unsigned value = n * factorial<n-1>::value;
};
template<>
struct factorial<0>
{
static const unsigned value = 1;
};
]]>
</>
<para>
The program fragment above is called a <emphasis>&mfn;</>, and it is easy to see its relationship to a function designed to be evaluated at runtime: the <quote>&mfn; argument</> is passed as a template parameter, and its <quote>return value</> is defined as a nested static constant. Because of the hard line between the expression of compile-time and runtime computation in &Cxx;, metaprograms look different from their runtime counterparts. Thus, although as in Scheme the &Cxx; metaprogrammer writes her code in the same language as the ordinary program, only a subset
of the full &Cxx; language is available to her: those expressions which can be evaluated at compile-time. Compare the above with a straightforward runtime definition of the factorial function:
</>
<programlisting>
unsigned factorial(unsigned N)
{
return N == 0 ? 1 : N * factorial(N - 1);
}
</>
<para>
While it is easy to see the analogy between the two recursive definitions, recursion is in general more important to &Cxx; metaprograms than it is to runtime &Cxx;. In contrast to languages such as Lisp where recursion is idiomatic, &Cxx; programmers will typically avoid recursion when possible. This is done not only for efficiency reasons, but also because of <quote>cultural momentum</>: recursive programs are simply harder (for &Cxx; programmers) to think about. Like pure Lisp, though, the &Cxx; template mechanism is a <emphasis>functional</> programming language: as such it rules out the use of data mutation required to maintain loop variables.
</>
<para>
A key difference between the runtime and compile-time factorial functions is the expression of the termination condition: our meta-factorial uses template specialization as a kind of <emphasis>pattern-matching</> mechanism to describe the behavior when <literal>N</> is zero. The syntactic analogue in the runtime world would require two separate definitions of the same function. In this case the impact of the second definition is minimal, but in large
metaprograms the cost of maintaining and understanding the terminating definitions can become significant.
</>
<para>
Note also that a &Cxx; &mfn;'s return value must be <emphasis>named</>. The name chosen here, <literal>value</>, is the same one used for all numeric returns in the &MPL;. As we'll see, establishing a consistent naming
convention for &mfn; returns is crucial to the power of the library.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="intro.cxx.type">
<title>Type computations</>
<para>
How could we apply our <literal>factorial</> &mfn;? We might, for example, produce an array type of an appropriate size to hold all permutations of instances of another type:
</>
<programlisting>
<![CDATA[
// permutation_holder<T>::type is an array type which can contain
// all permutations of a given T.
// unspecialized template for scalars
template< typename T >
struct permutation_holder
{
typedef T type[1][1];
};
// specialization for array types
template< typename T, unsigned N >
struct permutation_holder<T[N]>
{
typedef T type[factorial<N>::value][N];
};
]]>
</>
<para>
Here we have introduced the notion of a <emphasis>type computation</>. Like <literal>factorial</> above, <literal>permutation_holder</> template is a &mfn;. However, where <literal>factorial</> manipulates unsigned integer values, <literal>permutation_holder</> accepts and <quote>returns</> a type (as the nested typedef <literal>type</>). Because the &Cxx; type system provides a much richer set of expressions than anything we can use as a nontype template argument (e.g. the integers), &Cxx; metaprograms tend to be composed mostly of type computations.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="intro.cxx.seq">
<title>Type sequences</>
<para>
The ability to programmatically manipulate collections of types is a central tool of most interesting &Cxx; metaprograms. Because this capability is so well-supported by the &MPL;, we'll provide just a brief
introduction to the basics here. Later on, we'll revisit the example below to show how it can be implemented using &MPL;.
</>
<para>
First, we'd need a way to represent the collection. One idea might be to store the types in a structure:
</>
<programlisting>
<![CDATA[
struct types
{
int t1;
long t2;
std::vector<double> t3;
};
]]>
</>
<para>
Unfortunately, this arrangement is not susceptible to the compile-time type introspection power that &Cxx; gives us: there's no way to find out what the names of the members are, and even if we assume that they're named according to some convention as above, there's no way to know how many members there are. The key to solving this problem is to
increase the uniformity of the representation. If we have a consistent way to get the first type of any sequence and the rest of the sequence, we can easily access all members:
</>
<programlisting>
<![CDATA[
template< typename First, typename Rest >
struct cons
{
typedef First first;
typedef Rest rest;
};
struct nil {};
typedef
cons<int
, cons<long
, cons<std::vector<double>
, nil
> > > my_types;
]]>
</>
<para>
The structure described by <literal>types</> above is the compile-time analogue of a singly-linked list; it has been first introduced by Czarnecki and Eisenecker in <citation><xref linkend="ref.ce98"></>. Now that we've adjusted the structure so that the &Cxx; template machinery can <quote>peel it apart</>, let's examine a simple metafunction which does so. Suppose a user wished to find the largest of an arbitrary collection of types. We can apply the recursive &mfn; formula which should by now be familiar:
</>
<example id="example.largest">
<title>'largest' metafunction</>
<programlisting>
<![CDATA[
// choose the larger of two types
template<
typename T1
, typename T2
, bool choose1 = (sizeof(T1) > sizeof(T2)) // hands off!
>
struct choose_larger
{
typedef T1 type;
};
// specialization for the case where sizeof(T2) >= sizeof(T1)
template< typename T1, typename T2 >
struct choose_larger< T1,T2,false >
{
typedef T2 type;
};
// get the largest of a cons-list
template< typename T > struct largest;
// specialization to peel apart the cons list
template< typename First, typename Rest >
struct largest< cons<First,Rest> >
: choose_larger< First, typename largest<Rest>::type >
{
// type inherited from base
};
// specialization for loop termination
template< typename First >
struct largest< cons<First,nil> >
{
typedef First type;
};
int main()
{
// print the name of the largest of my_types
std::cout
<< typeid(largest<my_types>::type).name()
<< std::endl
;
}
]]>
</>
</>
<para>
There are several things worth noticing about this code:
</>
<itemizedlist mark="box">
<listitem><para>
It uses a few ad-hoc, esoteric techniques, or <quote>hacks</>. The default template argument <literal>choose1</> (labeled <quote>hands off!</>) is one example. Without it, we would have needed yet another template to provide the implementation of <literal>choose_larger</>, or we would have had to provide the computation explicitly as a parameter to the template - perhaps not bad for this example, but it would make <literal>choose_larger</> much less useful and more error-prone. The other hack is the derivation of a specialization of <literal>largest</> from <literal>choose_larger</>. This is a code-saving device which allows the programmer to avoid writing <quote><literal>typedef
typename </>...<literal>::type type</></> in the template body.
</></>
<listitem><para>
Even this simple metaprogram uses three separate partial specializations. The <literal>largest</> &mfn; uses <emphasis>two</> specializations. One might expect that this indicates there are two termination conditions, but there are not: one specialization is needed simply to deal with access to the sequence elements. These specializations make the code difficult to read by spreading the definition of a single &mfn; over several &Cxx; template definitions. Also, because they are <emphasis>partial</> specializations, they make the code unusable for a large community of &Cxx; programmers whose compilers don't support that feature.
</></>
</itemizedlist>
<para>
While these techniques are, of course, a valuable part of the arsenal of any good &Cxx; metaprogrammer, their use tends to make programs written in what is already an unusual style harder-to-read and harder-to-write. By encapsulating commonly-used structures and dealing with loop terminations internally, the &MPL; reduces the need for both tricky hacks and for template specializations.
</>
</section>
</section>
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="intro.whymetaprog">
<title>Why metaprogramming?</>
<!--
maybe we don't need another example of a metaprogram given what
we've done above? We could rewrite and cut most of this section...
-->
<para>
It's worth asking why anyone would want to do this. After all, even a simple toy example like the factorial &mfn; is somewhat esoteric. To show how the type computation can be put to work, let's examine a simple example. The following code produces an array containing all possible permutations of another array:
</>
<programlisting>
<![CDATA[
// can't return an array in C++, so we need this wrapper
template< typename T >
struct wrapper
{
T x;
};
// return an array of the N! permutations of 'in'
template< typename T >
wrapper< typename permutation_holder<T>::type >
all_permutations(T const& in)
{
wrapper<typename permutation_holder<T>::type> result;
// copy the unpermutated array to the first result element
unsigned const N = sizeof(T) / sizeof(**result.x);
std::copy(&*in, &*in + N, result.x[0]);
// enumerate the permutations
unsigned const result_size = sizeof(result.x) / sizeof(T);
for (T* dst = result.x + 1; dst != result.x + result_size; ++dst)
{
T* src = dst - 1;
std::copy(*src, *src + N, *dst);
std::next_permutation(*dst, *dst + N);
}
return result;
}
]]>
</>
<!-- ...up to this point -->
<para>
The runtime definition of <literal>factorial</> would be useless in <literal>all_permutations</> above, since in &Cxx; the sizes of array members must be computed at compile-time. However, there are alternative approaches; how could we avoid &mping;, and what would the consequences be?
</>
<orderedlist>
<listitem>
<para>
We could write programs to interpret the &mdat; directly. In our factorial example, the array size could have been a runtime quantity; then we'd have been able to use the straightforward factorial function. However, that would imply the use of dynamic allocation, which is often expensive.
</>
<para>
To carry this further, YACC might be rewritten to accept a pointer-to-function returning tokens from the stream to be parsed, and a string containing the grammar description. This approach, however, would impose unacceptable runtime costs for most applications: either the parser would have to treat the grammar nondeterministically, exploring the grammar for each parse, or it would have to begin by replicating at runtime the substantial table-generation and optimization work of the existing YACC for each input grammar.
</>
</>
<listitem>
<para>
We could replace the compile-time computation with our own analysis. After all, the size of arrays passed to
<literal>all_permutations</> are always known at compile-time, and thus can be known to its user. We could ask the user to supply the result type explicitly:
</>
<programlisting>
<![CDATA[
template< typename Result, typename T >
Result all_permutations(T const& input);
]]>
</>
<para>
The costs to this approach are obvious: we give up expressivity (by requiring the user to explicitly specify implementation details), and correctness (by allowing the user to specify them incorrectly). Anyone who has had to write parser tables by hand will tell you that the impracticality of this approach is the very reason of YACC's existence.
</>
<para>
In a language such as &Cxx;, where the &mdat; can be expressed in the same language as the rest of the user's program, expressivity is further enhanced: the user can invoke metaprograms directly, without learning a foreign syntax or interrupting the flow of her code.
</>
</>
</orderedlist>
<para>
So, the motivation for &mping; comes down to the combination of three factors: efficiency, expressivity, and correctness. While in classical programming there is always a tension between expressivity and correctness on one hand and efficiency on the other, in the &mping; world we wield new power: we can move the computation required for
expressivity from runtime to compile-time.
</>
</section>
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="intro.whylibrary">
<title>Why a metaprogramming <emphasis>library</>?</>
<para>
One might just as well ask why we need any generic library:
</>
<itemizedlist mark="box">
<listitem>
<para>
Quality. Code that is appropriate for a general-purpose library is usually incidental to the purpose of its users. To a library developer, it is the central mission. On average, the containers and algorithms provided by any given &Cxx; standard library implementation are more-flexible and better-implemented than the project-specific implementations which abound, because library development was treated as an end in itself rather than a task incidental to the development of some other application. With a centralized implementation for any given function, optimizations and improvements are more likely to have been applied.
</>
</>
<listitem>
<para>
Re-use. More important even than the re-use of code which all libraries provide, a well-designed generic library establishes a <emphasis>framework of concepts and idioms</> which establishes a reusable mental model for approaching problems. Just as the &Cxx; Standard Template Library gave us iterator concepts and a function object protocol, the &BMPL; provides type-iterators and metafunction class protocol. A well-considered framework of idioms saves the metaprogrammer from considering irrelevant implementation details and allows her to concentrate on the problem at hand.
</>
</>
<listitem>
<para>
Portability. A good library can smooth over the ugly realities of platform differences. While in theory a &mping; library is fully generic and shouldn't be concerned with these issues, in practice support for templates remains inconsistent even four years after standardization. This should perhaps not be surprising: &Cxx; templates are the language's furthest-reaching and most complicated feature, which largely accounts for the power of &mping; in &Cxx;.
</>
</>
<listitem>
<para>
Fun. Repeating the same idioms over and over is <emphasis>tedious</>. It makes programmers tired and reduces productivity. Furthermore, when programmers get bored they get sloppy, and buggy code is even more costly than slowly-written code. Often the most useful libraries are simply patterns that have been <quote>plucked</> by an astute programmer from a sea of repetition. The &MPL; helps to reduce boredom by eliminating the need for the most commonly-repeated boilerplate coding patterns.
</>
</>
</itemizedlist>
<para>
As one can see, the &MPL;'s development is motivated primarily by the same practical, real-world considerations that justify the development of any other library. Perhaps this is an indication that template &mping; is finally ready to leave the realm of the esoteric and enter the lingua franca of every day programmers.
</>
<!-- probably this paragraph would be better in the conclusions -->
</section>
</section>
-142
View File
@@ -1,142 +0,0 @@
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="lambda">
<title>Lambda facility</>
<para>
The &MPL;'s lambda facility allows the <firstterm>inline composition</> of class templates into <quote>lambda expressions</>, which are classes and can therefore be passed around as ordinary metafunction classes, or transformed into metafunction classes before application using the expression:
</>
<programlisting><![CDATA[
typedef mpl::lambda<expr>::type func;
]]></>
<para>
For example, <literal>boost::remove_const</> traits template from Boost <literal>type_traits</> library <citation><xref linkend="ref.TTL"></> is a class template (obviously), or a <link linkend="metafunctions">metafunction</> in &MPL; terminology. The simplest example of an <quote>inline composition</> of it would be something like:
</>
<programlisting><![CDATA[
typedef boost::remove_const<_1> expr;
]]></>
<para>
This forms a so called <quote>lambda expression</>, which is neither a metafunction class, nor a metafunction, yet can be passed around everywhere because it's an ordinary &Cxx; class, because all &MPL; facilities are polymorphic with respect to their arguments. Now, that lambda expression can be <emphasis>transformed</> into a metafunction class using the &MPL;'s <literal>lambda</> facility:
</>
<programlisting><![CDATA[
typedef boost::remove_const<_1> expr;
typedef mpl::lambda<expr>::type func;
]]></>
<para>
The <literal>func</> is a unary metafunction class and can be used as such. In particular, it can be pass around or invoked (applied):
</>
<programlisting><![CDATA[
typedef mpl::apply<func,int const>::type res;
BOOST_MPL_ASSERT_IS_SAME(res, int);
]]></>
<para>
or even
</>
<programlisting><![CDATA[
typedef func::apply<int const>::type res;
BOOST_MPL_ASSERT_IS_SAME(res, int);
]]></>
<para>
Inline composition is very appealing syntactically when one deals with metafunctions, because it makes the expression obvious:
</>
<programlisting><![CDATA[
typedef mpl::logical_or<
mpl::less< mpl::sizeof_<_1>, mpl::int_c<16> >
, boost::is_same<_1,_2>
> expr;
typedef mpl::lambda<expr>::type func;
]]></>
<para>
And one does not have to specify the last part (<literal>typedef lambda&lt;expr&gt;::type func</>), because all the algorithms do this to any of their metafunction class operands internally (a <literal>lambda&lt;T&gt;::type</> expression applied to a metafunction class gives back the same metafunction class, so it's safe to apply the expression unconditionally).
</>
<para>
The alternative way to write an equivalent of the above metafunction class would be:
</>
<programlisting><![CDATA[
typedef bind<
mpl::meta_fun2<mpl::logical_or>
, mpl::bind< mpl::meta_fun2<mpl::less>
, mpl::bind< mpl::meta_fun1<mpl::sizeof_>,_1 >
, mpl::int_c<16>
>
, mpl::bind< mpl::meta_fun2<boost::is_same>,_1,_2 >
> func;
]]></>
<para>
Or to use <literal>mpl::compose_</> family of templates in a similar way. Here, we use <literal>mpl::meta_fun</> templates to convert metafunctions into metafunction classes and then combine them using <literal>mpl::bind</>. The transformation from this form to the above inline lambda expression and vice-versa is mechanical, and that is essentially what the <literal>typedef mpl::lambda&lt;expr&gt;::type</> expression does.
</>
<para>
For its own metafunctions (algorithms, primitives, etc.), &MPL; enables one to write the above in a less cumbersome way:
</>
<programlisting><![CDATA[
typedef mpl::bind<
mpl::logical_or<>
, mpl::bind< mpl::less<>, mpl::bind<mpl::sizeof_<>,_1>, mpl::int_c<16> >
, mpl::bind< mpl::make_f2<boost::is_same>, _1,_2 >
> func;
]]></>
<para>
Note that we still have to wrap <literal>is_same</> into <literal>make_f2</>, because it's a foreign template.
</>
<para>
Now, about combining class template metafunctions and metafunction classes in the single lambda expression - it can be done like this:
</>
<programlisting><![CDATA[
struct my_predicate
{
template< typename T1, typename T2 > struct apply
{
//...
};
};
typedef mpl::logical_or<
mpl::less< mpl::sizeof_<_>,mpl::int_c<16> >
, mpl::bind< my_predicate,_,_ > // here
> expr;
]]></>
<para>
To bind something to one of its arguments (or change the order of parameters), then use either:
</>
<programlisting><![CDATA[
typedef mpl::logical_or<
mpl::less< mpl::sizeof_<_>,mpl::int_c<16> >
, mpl::bind<my_predicate,int,_>::type // here
> expr;
]]></>
<para>
or
</>
<programlisting><![CDATA[
typedef mpl::logical_or<
mpl::less< mpl::sizeof_<_>,mpl::int_c<16> >
, my_predicate::apply<int,_> // here
> expr;
]]></>
</section>
-282
View File
@@ -1,282 +0,0 @@
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="metafunctions">
<title>Metafunctions</>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="metafunctions.simple">
<title>The simple form</>
<para>
In C++, the basic underlying language construct which allows parameterized compile-time computation is the <firstterm>class template</> (<citation><xref linkend="ref.ISO98"></>, section 14.5.1 [temp.class]). A bare class template is the simplest possible model we could choose for metafunctions: it can take types and/or non-type arguments as actual template parameters, and instantiation <quote>returns</> a new type. For example, the following produces a type derived from its arguments:
</>
<programlisting>
<![CDATA[
template< typename T1, typename T2 >
struct derive : T1, T2
{
};
]]>
</>
<para>
However, this model is far too limiting: it restricts the metafunction result not only to class types, but to instantiations of a given class template, to say nothing of the fact that every metafunction invocation introduces an additional level of template nesting. While that might be acceptable for this particular metafunction, any model which prevented us from <quote>returning</>, say, <literal>int</> is obviously not general enough. To meet this basic requirement, we must rely on a nested type to provide our return value:
</>
<programlisting>
<![CDATA[
template< typename T1, typename T2 >
struct derive
{
struct type : N1, N2 {};
};
// silly specialization, but demonstrates "returning" int
template<>
struct derive<void,void>
{
typedef int type;
};
]]>
</>
<para>
Veldhuizen <citation><xref linkend="ref.Vel95a"></> was first to talk about class templates of this form as <quote>compile-time functions</>, and Czarnecki and Eisenecker <citation><xref linkend="ref.CE00"></> have introduced <quote>template metafunction</> as an equivalent term (they also use the simpler term <quote>metafunction</>, as do we). Czarnecki and Eisenecker have also recognized the limitations of the simple metafunction representation and suggested the form that we discuss in <xref linkend="metafunctions.classes">.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="metafunctions.higherorder">
<title>Higher-order metafunctions</>
<para>
While syntactically simple, the simple template metafunction form does not always interact optimally with the rest of &Cxx;. In particular, the simple metafunction form makes it unnecessarily awkward and tedious to define and work with higher-order metafunctions (metafunctions that operate on other metafunctions). In order to pass a simple metafunction to another template, we need to use <firstterm>template template parameters</>:
</>
<programlisting>
<![CDATA[
// returns F(T1,F(T2,T3))
template<
template<typename> class F
, typename T1
, typename T2
, typename T3
>
struct apply_twice
{
typedef typename F<
T1
, typename F<T2,T3>::type
>::type type;
};
// a new metafunction returning a type derived from T1, T2, and T3
template<
typename T1
, typename T2
, typename T3
>
struct derive3
: apply_twice<derive,T1,T2,T3>
{
};
]]>
</>
<para>
This looks different, but it seems to work.
<footnote id="note.higherorder"><para>In fact it's already broken: <literal>apply_twice</> doesn't even fit the metafunction concept since it requires a template (rather than a type) as its first parameter, which breaks the metafunction protocol.</></>
However, things begin to break down noticeably when we want to <quote>return</> a metafunction from our metafunction:
</>
<programlisting>
<![CDATA[
// returns G s.t. G(T1,T2,T3) == F(T1,F(T2,T3))
template< template<typename> class F >
struct compose_self
{
template<
typename T1
, typename T2
, typename T3
>
struct type
: apply_twice<F,T1,T2,T3>
{
};
};
]]>
</>
<para>
The first and most obvious problem is that the result of applying <literal>compose_self</> is not itself a type, but a template, so it can't be passed in the usual ways to other metafunctions. A more subtle issue, however, is that the metafunction <quote>returned</> is not exactly what we intended. Although it acts just like <literal>apply_twice</>, it differs in one important respect: its identity. In the C++ type system, <literal>compose_self&lt;F&gt;::template type&lt;T,U,V&gt;</> is not a synonym for <literal>apply_twice&lt;F,T,U,V&gt;</>, and any metaprogram which compared metafunctions would discover that fact.
</>
<para>
Because &Cxx; makes a strict distinction between type and class template template parameters, reliance on simple metafunctions creates a <quote>wall</> between metafunctions and metadata, relegating metafunctions to the status of second-class citizens. For example, recalling our introduction to type sequences, there's no way to make a <literal>cons</> list of metafunctions:
</>
<programlisting>
<![CDATA[
typedef cons<derive, cons<derive3, nil> > derive_functions; // error!
]]>
</>
<para>
We might consider redefining our <literal>cons</> cell so we can pass <literal>derive</> as the head element:
</>
<programlisting>
<![CDATA[
template <
template< template<typename T, typename U> class F
, typename Tail
>
struct cons;
]]>
</>
<para>
However, now we have another problem: &Cxx; templates are polymorphic with respect to their type arguments, but not with respect to template template parameters. The arity (number of parameters) of any template template parameter is strictly enforced, so we <emphasis>still</> can't embed <literal>derive3</> in a <literal>cons</> list. Moreover, polymorphism <emphasis>between</> types and metafunctions is not supported (the compiler expects one or the other), and as we've seen, the syntax and semantics of <quote>returned</> metafunctions is different from that of returned types. Trying to accomplish everything with the simple template metafunction form would seriously limit the applicability of higher-order metafunctions and would have an overall negative effect on the both conceptual and implementation clarity, simplicity and size of the library.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="metafunctions.classes">
<title>Metafunction classes</>
<para>
Fortunately, the truism that <quote>there is no problem in software which can't be solved by adding yet another level of indirection</> applies here. To elevate metafunctions to the status of first-class objects, the &MPL; introduces the concept of a <quote>metafunction class</>:
</>
<programlisting>
<![CDATA[
// metafunction class form of derive
struct derive
{
template< typename N1, typename N2 >
struct apply
{
struct type : N1, N2 {};
};
};
]]>
</>
<para>
This form should look familiar to anyone acquainted with function objects in STL, with the nested <literal>apply</> template taking the same role as the runtime function-call operator. In fact, compile-time metafunction classes have the same relationship to metafunctions that runtime function objects have to functions:
</>
<programlisting>
<![CDATA[
// function form of add
template< typename T > T add(T x, T y) { return x + y; }
// function object form of add
struct add
{
template< typename T >
T operator()(T x, T y) { return x + y; }
};
]]>
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="metafunctions.onesize">
<title>One size fits all?</>
<para>
The metafunction class form solves all the problems with ordinary template metafunction mentioned earlier: since it is a regular class, it can be placed in compile-time metadata sequences and manipulated by other metafunctions using the same protocols as for any other metadata. We thereby avoid the code-duplication needed to provide versions of each library component to operate on ordinary metadata and on metafunctions with each distinct supported arity.
</>
<para>
On the other hand, it seems that accepting metafunction classes as <emphasis>the</> representation for compile-time function entities imposes code duplication danger as well: if the library's own primitives, algorithms, etc. are represented as class templates, that means that one either cannot reuse these algorithms in the context of higher-order functions, or she have to duplicate all algorithms in the second form, so, for instance, there would be two versions of <literal>find</>:
</>
<programlisting>
<![CDATA[
// user-friendly form
template<
typename Sequence
, typename T
>
struct find
{
typedef /* ... */ type;
};
// "metafunction class" form
struct find_func
{
template< typename Sequence, typename T >
struct apply
{
typedef /* ... */ type;
};
};
]]>
</>
<para>
Of course, the third option is to eliminate <quote>user-friendly form</> completely so one would always have to write:
</>
<programlisting>
<![CDATA[
typedef mpl::find::apply<list,long>::type iter;
// or, if one prefers,
// typedef mpl::apply< mpl::find,list,long >::type iter;
]]>
</>
<para>
instead of
</>
<programlisting>
<![CDATA[
typedef mpl::find<list,long>::type iter;
]]>
</>
<para>
That too would hurt usability, considering that the direct invocations of library's algorithms are far more often-used than passing algorithms as arguments to other algorithms/metafunctions.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="metafunctions.lambda">
<title>From metafunction to metafunction class</>
<para>
The &MPL;'s answer to this dilemma is <firstterm>lambda expressions</>. Lambda is the mechanism that enables the library to curry metafunctions and convert them into metafunction classes, so when one wants to pass the <literal>find</> algorithm as an argument to a higher-order metafunction, she just write:
</>
<programlisting>
<![CDATA[
using namespace mpl::placeholder;
typedef mpl::apply< my_f, mpl::find<_1,_2> >::type result;
]]>
</>
<para>
where <literal>_1</> and <literal>_2</> are placeholders for the first and second arguments to the resulting metafunction class. This preserves the intuitive syntax below for when the user wants to use <literal>find</> directly in her code:
</>
<programlisting>
<![CDATA[
typedef mpl::find<list,long>::type iter;
]]>
</>
<para>
Lambda facility is described in more details in <xref linkend="lambda">.
</>
</section>
</section>
-247
View File
@@ -1,247 +0,0 @@
<bibliography id="refs">
<title>References</>
<biblioentry id="ref.Abr01">
<abbrev>Abr01</>
<authorgroup>
<author><firstname>David</><surname>Abrahams</></>
<author><firstname>Carlos Pinto</><surname>Coelho</></>
</>
<title><ulink url="http://users.rcn.com/abrahams/instantiation_speed/index.html">Effects of Metaprogramming Style on Compilation Time</></>
<date>2001</>
</biblioentry>
<biblioentry id="ref.Ale01">
<abbrev>Ale01</>
<author><firstname>Andrei</><surname>Alexandrescu</></>
<title>Modern C++ Design: Generic Programming and Design Patterns Applied</>
<publishername>Addison-Wesley</>
<isbn>0-201-70431-5</>
<date>2001</>
</biblioentry>
<biblioentry id="ref.CE98">
<abbrev>CE98</>
<authorgroup>
<author><firstname>Krzysztof</><surname>Czarnecki</></>
<author><firstname>Ulrich</><surname>Eisenecker</></>
</>
<title>Metalisp</>
<bibliomisc><ulink url="http://home.t-online.de/home/Ulrich.Eisenecker/meta.htm"></></>
</biblioentry>
<biblioentry id="ref.CE00">
<abbrev>CE00</>
<authorgroup>
<author><firstname>Krzysztof</><surname>Czarnecki</></>
<author><firstname>Ulrich</><surname>Eisenecker</></>
</>
<title>Generative Programming: Methods, Tools, and Applications</>
<publishername>Addison-Wesley</>
<isbn>0-201-30977-7</>
<date>2000</>
</biblioentry>
<biblioentry id="ref.EBNF">
<abbrev>EBNF</>
<title>ISO/IEC 14977:1996(E), Information technology — Syntactic metalanguage — Extended BNF</>
<orgname>ISO/IEC</>
<date>1996</>
</biblioentry>
<biblioentry id="ref.GHJ95">
<abbrev>GHJ+95</>
<authorgroup>
<author><firstname>Erich</><surname>Gamma</></>
<author><firstname>Richard</><surname>Helm</></>
<author><firstname>Ralph</><surname>Johnson</></>
<author><firstname>John</><surname>Vlissides</></>
</>
<title>Design Patterns, Elements of Reusable Object-Oriented Software</>
<publishername>Addison-Wesley</>
<isbn>0-201-63361-2</>
<date>1995</>
</biblioentry>
<biblioentry id="ref.HU79">
<abbrev>HU79</>
<authorgroup>
<author><surname>Hopcroft</></>
<author><surname>Ullman</></>
</>
<title>Introduction to automata theory, languages and computations</>
<publishername>Addison-Wesley</>
<date>1979</>
</biblioentry>
<biblioentry id="ref.Hud89">
<abbrev>Hud89</>
<author><firstname>Paul</><surname>Hudak</></>
<title>Conception, Evolution, and Application of Functional Programming Languages</>
<biblioset relation='journal'>
<title>ACM Computing Surveys</>
<publishername>Association for Computing Machinery (ACM)</>
<issn>0360-0300</>
</>
<volumenum>21</>
<issuenum>3</>
<pagenums>359-411</>
<date>September, 1989</>
</biblioentry>
<biblioentry id="ref.Hun91">
<abbrev>Hun91</>
<author><firstname>Immo</><surname>Huneke</></>
<title>Finite State Machines: A Model of Behavior for C++</>
<biblioset relation='journal'>
<title>C++ Report</>
<publishername>SIGS Publications Inc.</>
<issn>1040-6042</>
</>
<date>1991</>
</biblioentry>
<biblioentry id="ref.ISO98">
<abbrev>ISO98</>
<title>ISO/IEC 14882:1998(E), Programming languages — C++</>
<orgname>ISO/IEC</>
<date>1998</>
</biblioentry>
<biblioentry id="ref.Joh79">
<abbrev>Joh79</>
<author><firstname>Stephen C.</><surname>Johnson</></>
<title><ulink url="http://dinosaur.compilertools.net/yacc/index.html">Yacc: Yet Another Compiler Compiler</></>
<publishername>UNIX Programmer's Manual</>
<volumenum>2b</>
<pagenums>353-387</>
<date>1979</>
</biblioentry>
<biblioentry id="ref.Laf00">
<abbrev>Laf00</>
<author><firstname>David</><surname>Lafreniere</></>
<title><ulink url="http://www.cuj.com/articles/2000/0005/0005f/0005f.htm?topic=articles">State Machine Design in C++</></>
<biblioset relation='journal'>
<title>C/C++ User Journal</>
<publishername>CMP Media LCC</>
<issn>1075-2838</>
</>
<volumenum>18</>
<issuenum>5</>
<date>May 1998</>
</biblioentry>
<biblioentry id="ref.Loki">
<abbrev>Loki</>
<title>The Loki library</>
<bibliomisc><ulink url="http://sourceforge.net/projects/loki-lib/"></></>
</biblioentry>
<biblioentry id="ref.Mar98">
<abbrev>Mar98</>
<author><firstname>Robert C.</><surname>Martin</></>
<title><ulink url="http://www.objectmentor.com/resources/articles/umlfsm.pdf">UML Tutorial: Finite State Machines</></>
<biblioset relation='journal'>
<title>C++ Report</>
<publishername>SIGS Publications Inc.</>
<issn>1040-6042</>
</>
<date>June 1998</>
</biblioentry>
<biblioentry id="ref.MPLR">
<abbrev>MPLR</>
<title>Boost MPL Library Reference Documentation</>
<bibliomisc><ulink url="http://www.mywikinet.com/mpl/ref/Table_of_Content.html"></></>
</biblioentry>
<biblioentry id="ref.PRE">
<abbrev>PRE</>
<author><firstname>Vesa</><surname>Karvonen</></>
<title>Boost Preprocessor Metaprogramming library</>
<bibliomisc><ulink url="http://www.boost.org/libs/preprocessor/doc/"></></>
</biblioentry>
<biblioentry id="ref.SMC">
<abbrev>SMC</>
<author><firstname>Robert C.</><surname>Martin</></>
<title>SMC - Finite State Machine Compiler (C++)</>
<bibliomisc><ulink url="http://www.objectmentor.com/resources/downloads/index"></></>
</biblioentry>
<biblioentry id="ref.STL94">
<abbrev>STL94</>
<authorgroup>
<author><surname>A. A. Stepanov</></>
<author><surname>M. Lee</></>
</authorgroup>
<title>The Standard Template Library</>
<orgname>Hewlett-Packard Laboratories</>
<date>1994</>
</biblioentry>
<biblioentry id="ref.SPL">
<abbrev>SPL</>
<title>Boost Smart Pointer library</>
<bibliomisc><ulink url="http://www.boost.org/libs/smart_ptr/"></></>
</biblioentry>
<biblioentry id="ref.SS75">
<abbrev>SS75</>
<authorgroup>
<author><firstname>Gerald J.</><surname>Sussman</></>
<author><firstname>Guy L.</><surname>Steele Jr.</></>
</>
<title>Scheme: An interpreter for extended lambda calculus</>
<biblioset relation='journal'>
<title>MIT AI Memo 349</>
<publishername>Massachusetts Institute of Technology</>
</>
<date>May 1975</>
</biblioentry>
<biblioentry id="ref.TTL">
<abbrev>TTL</>
<title>Boost Type Traits library</>
<bibliomisc><ulink url="http://www.boost.org/libs/type_traits/"></></>
</biblioentry>
<biblioentry id="ref.vel95a">
<abbrev>Vel95a</>
<author><firstname>Todd</><surname>Veldhuizen</></>
<title><ulink url="http://osl.iu.edu/~tveldhui/papers/Template-Metaprograms/meta-art.html">Using C++ template metaprograms</></>
<biblioset relation='journal'>
<title>C++ Report</>
<publishername>SIGS Publications Inc.</>
<issn>1040-6042</>
</>
<volumenum>7</>
<issuenum>4</>
<pagenums>36-43</>
<date>May 1995</>
</biblioentry>
<biblioentry id="ref.Vel95b">
<abbrev>Vel95b</>
<author><firstname>Todd</><surname>Veldhuizen</></>
<title><ulink url="http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">Expression templates</></>
<biblioset relation='journal'>
<title>C++ Report</>
<publishername>SIGS Publications Inc.</>
<issn>1040-6042</>
</>
<volumenum>7</>
<issuenum>5</>
<pagenums>26-31</>
<date>Jun 1995</>
</biblioentry>
<biblioentry id="ref.Unr">
<abbrev>Unr</>
<author><firstname>Erwin</><surname>Unruh</></>
<title>Prime number computation</>
<publishername>ANSI X3J16-94-0075/ISO WG21-462</>
</biblioentry>
</bibliography>
-566
View File
@@ -1,566 +0,0 @@
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="sequences">
<title>Sequences, algorithms, and iterators</>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="sequences.intro">
<title>Introduction</>
<para>
Compile-time iteration over a sequence (of types) is one of the basic concepts of template metaprogramming. Differences in types of objects being manipulated is the most common point of variability of similar but not identical code/design, and such designs are the direct target for some metaprogramming. Templates were originally designed to solve this exact problem (e.g. <literal>std::vector</>). However, without predefined abstractions/constructs for manipulating/iterating over <emphasis>sequences</> of types (as opposed to standalone types), and without known techniques for emulating these constructs using the current language facilities, their effect on helping high-level metaprogramming happen has been limited.
</>
<para>
Czarnecki and Eisenecker <citation><xref linkend="ref.CE98"></>, <citation><xref linkend="ref.CE00"></> were the first to introduce compile-time sequences of types and some simple algorithms on them, although the idea of representing common data structures like trees, lists, etc. at compile time, using class template composition has been around for a while (e.g. most of the expression template libraries build such trees as a part of their expression "parsing" process <citation><xref linkend="ref.Vel95b"></>). Alexandrescu <citation><xref linkend="ref.Ale01"></> used lists of types and some algorithms on them to implement several design patterns; the accompanying code is known as the Loki library <citation><xref linkend="ref.Loki"></>.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="sequences.algo">
<title>Algorithms and sequences</>
<para>
Most of the algorithms in the &BMPL; operate on sequences. For example, searching for a type in a list looks like this:
</>
<programlisting>
<![CDATA[
typedef mpl::list<char,short,int,long,float,double> types;
typedef mpl::find<types,long>::type iter;
]]>
</>
<para>
Here, <literal>find</> accepts two parameters - a sequence to search (<literal>types</>) and the type to search for (<literal>long</>) - and returns an iterator <literal>iter</> pointing to the first element of the sequence such that <literal>iter::type</> is identical to <literal>long</>. If no such element exists, <literal>iter</> is identical to <literal>end&lt;types&gt;::type</>. Basically, this is how one would search for a value in a <literal>std::list</> or <literal>std::vector</>, except that <literal>mpl::find</> accepts the sequence as a single parameter, while <literal>std::find</> takes two iterators. Everything else is pretty much the same - the names are the same, the semantics are very close, there are iterators, and one can search not only by type, but also by using a predicate:
</>
<programlisting>
<![CDATA[
typedef mpl::find_if< types,boost::is_float<_> >::type iter;
]]></>
<para>
This conceptual/syntactical similarity with the STL is not coincidental. Reusing the conceptual framework of the STL in the compile-time world allows us to apply familiar and sound approaches for dealing with sequential data structures. The algorithms and idioms which programmers already know from the STL can be applied again at compile-time. We consider this to be one of &MPL;'s greatest strengths, distinguishing it from earlier attempts to build a template metaprogramming library.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="sequences.concepts">
<title>Sequence concepts</>
<para>
In the <literal>find</> example above, we searched for the type in a sequence built using the <literal>mpl::list</> template; but <literal>list</> is not the only sequence that the library provides. Neither is <literal>mpl::find</> or any other algorithm hard-coded to work only with <literal>list</> sequences. <literal>list</> is just one model of &MPL;'s <phrase role="concept">Forward Sequence</> concept, and <literal>find</> works with anything that satisfies this concept's requirements. The hierarchy of sequence concepts in &MPL; is quite simple - a <phrase role="concept">Sequence</> is any compile-time entity for which <literal>begin&lt;&gt;</> and <literal>end&lt;&gt;</> produce iterators to the range of its elements; a <phrase role="concept">Forward Sequence</> is a Sequence whose iterators satisfy <phrase role="concept">Forward Iterator</> requirements; a <phrase role="concept">Bidirectional Sequence</> is a Forward Sequence whose iterators satisfy <phrase role="concept">Bidirectional Iterator</> requirements; finally, a <phrase role="concept">Random Access Sequence</> is a Bidirectional Sequence whose iterators satisfy <phrase role="concept">Random Access Iterator</> requirements.
<footnote id="note.seqconcepts"><para>
A more precise definition of these concepts can be found in the library reference documentation <citation><xref linkend="ref.MPLR"></>.
</></>
</>
<para>
Decoupling algorithms from particular sequence implementations (through iterators) allows a metaprogrammer to create her own sequence types and to retain the rest of the library at her disposal. For example, one can define a <literal>tiny_list</> for dealing with sequences of three types as follows:
</>
<programlisting>
<![CDATA[
template< typename TinyList, long Pos >
struct tiny_list_item;
template< typename TinyList, long Pos >
struct tiny_list_iterator
{
typedef typename tiny_list_item<TinyList,Pos>::type type;
typedef tiny_list_iterator<TinyList, Pos-1> prior;
typedef tiny_list_iterator<TinyList, Pos+1> next;
};
template< typename T0, typename T1, typename T2 >
struct tiny_list
{
typedef tiny_list_iterator<tiny_list, 0> begin;
typedef tiny_list_iterator<tiny_list, 3> end;
typedef T0 type0;
typedef T1 type1;
typedef T2 type2;
};
template< typename TinyList >
struct tiny_list_item<TinyList,0>
{
typedef typename TinyList::type0 type;
};
template< typename TinyList >
struct tiny_list_item<TinyList,1>
{
typedef typename TinyList::type1 type;
};
template< typename TinyList >
struct tiny_list_item<TinyList,2>
{
typedef typename TinyList::type2 type;
};
]]>
</>
<para>
and then use it with any of the library algorithms as if it were <literal>mpl::list</>:
</>
<programlisting>
<![CDATA[
typedef tiny_list< char,short,int > types;
typedef mpl::transform<
types
, boost::add_pointer<_1>
>::type pointers;
]]>
</>
<para>
Note that <literal>tiny_list</> is a model of Bidirectional Sequence; it would be a Random Access Sequence if we added <literal>advance</> and <literal>distance</> members to <literal>tiny_list_iterator</>:
</>
<programlisting>
<![CDATA[
template< typename TinyList, long Pos >
struct tiny_list_iterator
{
static long const position = Pos;
typedef typename tiny_list_item<TinyList,Pos>::type type;
typedef tiny_list_iterator<TinyList, Pos-1> prior;
typedef tiny_list_iterator<TinyList, Pos+1> next;
template< typename N > struct advance
{
typedef tiny_list_iterator<
TinyList
, Pos + N::value
> type;
};
template< typename Other > struct distance
{
typedef mpl::integral_c<
long
, Other::position - position
> type;
};
};
]]>
</>
<para>
While the <literal>tiny_list</> itself might be not that interesting (after all, it can hold only three elements), if the technique above could be automated so we would be able to define not-so-tiny sequences (with five, ten, twenty, etc. elements), it would be very valuable.
<footnote id="note.tinylist"><para>
Random access is almost as important at compile-time as it is at run-time. For example, searching for an item in a sorted random-access sequence using <literal>lower_bound</> can be much faster than performing the same operation on a forward-access-only <literal>list</>.
</></>
</>
<para>
External code generation is an option, but there exists a solution within the language. However, it is not a template metaprogramming, but rather <emphasis>preprocessor metaprogramming</>. In fact, &MPL;'s <literal>vector</> - a fixed-size type sequence that provides random-access iterators - is implemented very much like the above <literal>tiny_list</> - using the Boost Preprocessor library <citation><xref linkend="ref.PRE"></>.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="sequences.revisited">
<title>Ad hoc example revisited</>
<para>
So, the library provides its users with almost complete compile-time equivalent of the STL framework. Does it help them to solve their metaprogramming tasks? Let's return to our earlier <link linkend="example.largest"><literal>largest</></> example to see if we can rewrite it in a better way with what &MPL; has to offer. Well, actually, there is not much to look at, because the &MPL; implementation is a one-liner (we'll spread it out here for readability)
<footnote id="note.maxelement"><para>Here is another, even more elegant implementation:</>
<programlisting>
<![CDATA[
template< typename Sequence >
struct largest
{
typedef typename mpl::max_element<
mpl::transform_view<
Sequence
, mpl::sizeof_<_>
>
>::type type;
};
]]></>
</>
:
</>
<programlisting>
<![CDATA[
template< typename Sequence >
struct largest
{
typedef typename mpl::max_element<
Sequence
mpl::less<
mpl::sizeof_<_1>
, mpl::sizeof_<_2>
>
>::type iter;
typedef typename iter::type type;
};
]]></>
<para>
There are no more termination conditions with tricky pattern matching, no more partial specializations; and even more importantly, it's <emphasis>obvious</> what the above code does - even although it's all templates - something that one could not say about the original version.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="sequences.iterfold">
<title>iter_fold as the main iteration algorithm</>
<para>
For the purpose of examining a little bit more of the library's internal structure, let's look at how <literal>max_element</> from the above example is implemented. One might expect that <emphasis>now</> we will again see all these awkward partial specializations, esoteric pattern matching, etc. Well, let's see:
</>
<programlisting>
<![CDATA[
template<
typename Sequence
, typename Predicate
>
struct max_element
{
typedef typename mpl::iter_fold<
Sequence
, typename mpl::begin<Sequence>::type
, if_< less< deref<_1>,deref<_2> >, _2, _1 >
>::type type;
};
]]>
</>
<para>
The first thing to notice here is that this algorithm is implemented in terms of another one: <literal>iter_fold</>. In fact, this is probably the most important point of the example, because nearly all other generic sequence algorithms in the library are implemented in terms of <literal>iter_fold</>. If a user should ever need to implement her own sequence algorithm, she'll almost certainly be able to do so using this primitive, which means she won't have to resort to implementing hand-crafted iteration, pattern matching of special cases for loop termination, or workarounds for lack of partial specialization. It also means that her algorithm will automatically benefit from any optimizations the library has implemented, (e.g. recursion unrolling), and that it will work with any sequence that is a model of ForwardSequence, because <literal>iter_fold</> does not require anything more of its sequence argument.
</>
<para>
<literal>iter_fold</> algorithm is basically a compile-time equivalent of the <literal>fold</> or <literal>reduce</> functions that comprise the basic and well-known primitives of many functional programming languages. An analogy more familiar to a &Cxx; programmer would be the <literal>std::accumulate</> algorithm from the &Cxx; standard library (<citation><xref linkend="ref.ISO98"></>, section 26.4.1 [lib.accumulate]). However, <literal>iter_fold</> is designed to take advantage of the natural characteristics of recursive traversal: it accepts <emphasis>two</> metafunction class arguments, the first of which is applied to the state "on the way in" and the second of which is applied "on the
way out".
</>
<para>
The interface to <literal>iter_fold</> is defined in &MPL; as follows:
</>
<programlisting>
<![RCDATA[
template<
typename Sequence
, typename InitialState
, typename ForwardOp
, typename BackwardOp = _1
>
struct iter_fold
{
typedef &unspec; type;
};
]]>
</>
<para>
The algorithm <quote>returns</> the result of two-way successive applications of binary <literal>ForwardOp</> and <literal>BackwardOp</> operations to iterators in range [<literal>begin&lt;Sequence&gt;::type</>, <literal>end&lt;Sequence&gt;::type</>) and previous result of an operation; the <literal>InitialState</> is logically placed before the sequence and included in the forward traversal. The result <literal>type</> is identical to <literal>InitialState</> if the sequence is empty.
</>
<para>
The library also provides <literal>iter_fold_backward</>, <literal>fold</>, and <literal>fold_backward</> algorithms which wrap <literal>iter_fold</> to accommodate its most common usage patterns.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="sequences.numbers">
<title>Sequences of numbers</>
<para>
What we've seen so far were sequences (and algorithms on sequences) of types. It is both possible and easy to manipulate compile-time <emphasis>values</> using the library as well. The only thing to remember is that in &Cxx;, class template non-type template parameters give us one more example of non-polymorphic behavior. In other words, if one declared a metafunction to take a non-type template parameter (e.g. <literal>long</>) it's not possible to pass anything besides compile-time integral constants to it:
</>
<programlisting>
<![CDATA[
template< long N1, long N2 >
struct equal_to
{
static bool const value = (N1 == N2);
};
equal_to<5,5>::value; // ok
equal_to<int,int>::value; // error!
]]>
</>
<para>
And of course this doesn't work the other way around either:
</>
<programlisting>
<![CDATA[
typedef mpl::list<1,2,3,4,5> numbers; // error!
]]>
</>
<para>
While this may be an obvious limitation, it imposes yet another dilemma on the library design: on the one hand, we don't want to restrict users to type manipulations only, and on the other hand, full support for integral manipulations would require at least duplication of most of the library facilities
<footnote id="note.nontype"><para>Ideally, if going this route, all the templates should be re-implemented for every integral type - <literal>char</>, <literal>int</>, <literal>short</>, <literal>long</>, etc.
</></>
- the same situation as we would have if we had chosen to represent metafunctions as ordinary class templates. The solution for this issue is the same as well: we represent integral values by wrapping them in types
<footnote id="note.valuewrapping"><para>
The same technique was suggested by Czarnecki and Eisenecker in <citation><xref linkend="ref.CE00"></>.
</></>
. For example, to create a list of numbers one can write:
</>
<programlisting>
<![CDATA[
typedef mpl::list<
mpl::int_c<1>
, mpl::int_c<2>
, mpl::int_c<3>
, mpl::int_c<4>
, mpl::int_c<5>
> numbers;
]]>
</>
<para>
Wrapping integral constants into types to make them first-class citizens is important well inside metaprograms,
where one often doesn't know (and doesn't care) if the metafunctions she is using operate on types, integral values, other metafunctions, or something else, like fixed-point or rational numbers (<literal>mpl::fixed_c</> and <literal>mpl::rational_c</>).
</>
<para>
But, from the user's perspective, the above example is much more verbose than the shorter, incorrect one. Thus, for the purpose of convenience, the library does provide users with a template that takes non-type template parameters, but offers a more compact notation:
</>
<programlisting>
<![CDATA[
typedef mpl::list_c<long,1,2,3,4,5> numbers;
]]></>
<para>
There is a similar <literal>vector</> counterpart as well:
</>
<programlisting>
<![CDATA[
typedef mpl::vector_c<long,1,2,3,4,5> numbers;
]]>
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="sequences.variety">
<title>A variety of sequences</>
<para>
Previous efforts to provide generalized metaprogramming facilities for &Cxx; have always concentrated on <literal>cons</>-style type lists and a few core algorithms like <literal>size</> and <literal>at</>, which are tied to the specific sequence implementation. Such systems have an elegant simplicity reminiscent of the analogous functionality in pure functional Lisp. It is much more time-consuming to implement even a basic set of the sequence algorithms provided by equivalent run-time libraries (the STL in particular), but if we have learned anything from the STL, it is that tying those algorithms' implementations to a specific sequence implementation is a misguided effort!
</>
<para>
The truth is that there is no single <quote>best</> type sequence implementation for the same reasons that there will never be a single <quote>best</> runtime sequence implementation. Furthermore, there are <emphasis>already</> quite a number of type list implementations in use today; and just as the STL algorithms can operate on sequences which don't come from STL containers, so the MPL algorithms are designed to work with foreign type sequences.
</>
<para>
It may be an eye-opening fact for some that type lists are not the only useful compile-time sequence. Again, the need for a variety of compile-time containers arises for the same reasons that we have lists, vectors, deques, and sets in the &Cxx; standard library &mdash; different containers have different functional and performance characteristics which determine not only applicability and efficiency of particular algorithms, but also the expressiveness or verbosity of the code that uses them. While runtime performance is not an issue for &Cxx; metaprograms, compilation speed is often a significant bottleneck to advanced &Cxx; software development <citation><xref linkend="ref.Abr01"></>.
</>
<para>
The &MPL; provides five built-in sequences: <literal>list</>, <literal>list_c</> (really just a <literal>list</> of value wrappers), <literal>vector</>, a randomly-accessible sequence of fixed maximum size, <literal>vector_c</>, and <literal>range_c</>, a randomly-accessible sequence of consecutive integral values. More important, however, is its ability to adapt to arbitrary sequence types. The only core operations that a sequence is required to provide in order to be used with the library algorithms are <literal>begin&lt;&gt;</> and <literal>end&lt;&gt;</> metafunctions which "return" iterators into the sequence. As with the STL, it is the iterators which are used to implement most of the general-purpose sequence algorithms the library provides. Also, as with the STL, algorithm specialization is used to take advantage of implementation knowledge about particular sequences: many of the "basic" sequence operations such as <literal>back&lt;&gt;</>, <literal>front&lt;&gt;</>, <literal>size&lt;&gt;</>, and <literal>at&lt;&gt;</> are specialized on sequence type to provide a more efficient implementation than the fully generic version.
</>
</section>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="sequences.unrolling">
<title>Loop/recursion unrolling</>
<para>
Almost coincidentally, loop unrolling can be as important to compile-time iterative algorithms as it is to runtime algorithms. To see why, one must first remember that all "loops" in &Cxx; metaprograms, are in fact, implemented with recursion, and that the template instantiation depth can be a valuable resource in a compiler implementation. In fact, Annex B of the &Cxx; standard (<citation><xref linkend="ref.ISO98"></>, annex B [limits]) <emphasis>recommends</> a minimum depth of 17 recursively nested template instantiations; but this is far too low for many serious metaprograms, some of which easily exceed the hard-coded instantiation limits of some otherwise excellent compilers. To see how this works in action, let's examine a straightforward implementation of the <literal>fold</> metafunction, which combines some algorithm state with each element of a sequence:
</>
<programlisting>
<![CDATA[
namespace aux {
// unspecialized version combines the initial state and first element
// and recurses to process the rest
template<
typename Start
, typename Finish
, typename State
, typename BinaryFunction
>
struct fold_impl
: fold_impl<
typename Start::next
, Finish
, typename apply<
BinaryFunction
, State
, typename Start::type
>::type
, BinaryFunction
>
{
};
// specialization for loop termination
template<
typename Finish
, typename State
, typename BinaryFunction
>
struct fold_impl<Finish,Finish,State,BinaryFunction>
{
typedef State type;
};
} // namespace aux
// public interface
template<
typename Sequence
, typename State
, typename ForwardOp
>
struct fold
: aux::fold_impl<
, typename begin<Sequence>::type
, typename end<Sequence>::type
, State
, typename lambda<ForwardOp>::type
>
{
};
]]>
</>
<para>
Although simple and elegant, this implementation will always incur at least as many levels of recursive template instantiation as there are elements in the input sequence.
<footnote id="note.unrolling1"><para>It could be much more, depending on the complexity of the <literal>apply&lt;...&gt;</> expression, whose depth is added to the overall recursion depth.
</></>
The library addresses this problem by explicitly "unrolling" the recursion. To apply the technique to our <literal>fold</> example, we begin by factoring out a single step of the algorithm. Our <literal>fold_impl_step</> metafunction has two results: <literal>type</> (the next state), and <literal>iterator</> (the next sequence position).
</>
<programlisting>
<![CDATA[
template<
typename BinaryFunction
, typename State
, typename Start
, typename Finish
>
struct fold_impl_step
{
typedef typename apply<
BinaryFunction
, State
, typename Start::type
>::type type;
typedef typename Start::next iterator;
};
]]>
</>
<para>
As with our main algorithm implementation, we specialize for the loop termination condition so that the step becomes a no-op:
</>
<programlisting>
<![CDATA[
template<
typename BinaryFunction
, typename State
, typename Finish
>
struct fold_impl_step<BinaryFunction,State,Finish,Finish>
{
typedef State type;
typedef Finish iterator;
};
]]>
</>
<para>
Now we can now reduce <literal>fold</>'s instantiation depth by any constant factor N simply by inserting N invocations of <literal>fold_impl_step</>. Here we've chosen a factor of 4:
</>
<programlisting>
<![CDATA[
template<
typename Start
, typename Finish
, typename State
, typename BinaryFunction
>
struct fold_impl
{
private:
typedef fold_impl_step<
BinaryFunction
, State
, Start
, Finish
> next1;
typedef fold_impl_step<
BinaryFunction
, typename next1::type
, typename next1::iterator
, Finish
> next2;
typedef fold_impl_step<
BinaryFunction
, typename next2::type
, typename next2::iterator
, Finish
> next3;
typedef fold_impl_step<
BinaryFunction
, typename next3::type
, typename next3::iterator
, Finish
> next4;
typedef fold_impl_step<
typename next4::iterator
, Finish
, typename next4::type
, BinaryFunction
> recursion;
public:
typedef typename recursion::type type;
};
]]>
</>
<para>
The &MPL; applies this unrolling technique across all algorithms with an unrolling factor tuned according to the demands of the &Cxx; implementation in use, and with an option for the user to override the value.
<footnote id="note.unrolling2"><para>
This implementation detail is made relatively painless through heavy reliance on the Boost Preprocessor Library, so only one copy of the code needs to be maintained.
</></>
This fact enables users to push beyond the metaprogramming limits they would usually encounter with more naive algorithm implementations. Experiments also show a small (up to 10%) increase in metaprogram instantiation speed on some compilers when loop unrolling is used.
</>
</section>
</section>
-242
View File
@@ -1,242 +0,0 @@
<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="typeselection">
<title>Conditional type selection</>
<para>
Conditional type selection is the simplest basic construct of &Cxx; template metaprogramming. Veldhuizen <citation><xref linkend="ref.Vel95a"></> was the first to show how to implement it, and Czarnecki and Eisenecker <citation><xref linkend="ref.CE00"></> first presented it as a standalone library primitive. The &MPL; defines the corresponding facility as follows:
</>
<programlisting>
<![RCDATA[
template<
typename Condition
, typename T1
, typename T2
>
struct if_
{
typedef &unspec; type;
};
]]>
</>
<para>
Note that the first template parameter of the template is a type.
</>
<programlisting>
<![CDATA[
// usage/semantics
typedef mpl::if_<mpl::true_c,char,long>::type t1;
typedef mpl::if_<mpl::false_c,char,long>::type t2;
BOOST_MPL_ASSERT_IS_SAME(t1, char);
BOOST_MPL_ASSERT_IS_SAME(t2, long);
]]>
</>
<para>
The construct is important because template metaprograms often contain a lot of decision-making code, and, as we will show, spelling it manually every time via (partial) class template specialization quickly becomes impractical. The template is also important from the point of encapsulating the compiler workarounds.
</>
<!-- ||||||||||||||||||||||||||||| subsection -->
<section id="delayedeval">
<title>Delayed evaluation</>
<para>
The way the &Cxx; template instantiation mechanism works imposes some subtle limitations on applicability of the type selection primitive (<literal>if_</>), compared to a manually implemented equivalent of the selection code. For example, suppose we are implementing a <literal>pointed_type</> traits template such that <literal>pointed_type&lt;T&gt;::type</> instantiated for a <literal>T</> that is either a plain pointer (<literal>U*</>), <literal>std::auto_ptr&lt;U&gt;</>, or any of the Boost smart pointers <citation><xref linkend="ref.SPL"></>, e.g. <literal>boost::scoped_ptr&lt;U&gt;</>, will give us the pointed type (<literal>U</>):
</>
<programlisting>
<![CDATA[
BOOST_MPL_ASSERT_IS_SAME(pointed_type<my*>::type, my);
BOOST_MPL_ASSERT_IS_SAME(pointed_type< std::auto_ptr<my> >::type, my);
BOOST_MPL_ASSERT_IS_SAME(pointed_type< boost::scoped_ptr<my> >::type, my);
]]>
</>
<para>
Unfortunately, the straightforward application of <literal>if_</> to this problem does not work:
<footnote id="note.pointedtype"><para>
Although it would be easy to implement <literal>pointed_type</> using partial specialization to distinguish the case where <literal>T</> is a pointer, <literal>if_</> is likely to be the right tool for dealing with more complex conditionals. For the purposes of exposition, please suspend disbelief!
</></>
</>
<programlisting>
<![CDATA[
template< typename T >
struct pointed_type
: mpl::if_<
boost::is_pointer<T>
, typename boost::remove_pointer<T>::type
, typename T::element_type // #1
>
{
};
// the following code causes compilation error in line #1:
// name followed by "::" must be a class or namespace name
typedef pointed_type<char*>::type result;
]]>
</>
<para>
Clearly, the expression <literal>typename T::element_type</> is not valid in the case of <literal>T == char*</>, and that's what the compiler is complaining about. Implementing the selection code manually solves the problem:
</>
<programlisting>
<![CDATA[
namespace aux {
// general case
template< typename T, bool is_pointer = false >
struct select_pointed_type
{
typedef typename T::element_type type;
};
// specialization for plain pointers
template< typename T >
struct select_pointed_type<T,true>
{
typedef typename boost::remove_pointer<T>::type type;
};
}
template< typename T >
struct pointed_type
: aux::select_pointed_type<
T, boost::is_pointer<T>::value
>
{
};
]]>
</>
<para>
But this quickly becomes awkward if needs to be done repeatedly, and this awkwardness is compounded when partial specialization is not available. We can try to work around the problem as follows:
</>
<programlisting>
<![CDATA[
namespace aux {
template< typename T >
struct element_type
{
typedef typename T::element_type type;
};
}
template< typename T >
struct pointed_type
{
typedef typename mpl::if_<
boost::is_pointer<T>
, typename boost::remove_pointer<T>::type
, typename aux::element_type<T>::type
>::type type;
};
]]>
</>
<para>
but this doesn't work either - the access to the <literal>aux::element_type&lt;T&gt;</>'s nested <literal>type</> member still forces the compiler to instantiate <literal>element_type&lt;T&gt;</> with <literal>T == char*</>, and that instantiation is, of course, invalid. Also, although in our case this does not lead to a compile error, the <literal>boost::remove_pointer&lt;T&gt;</> template always gets instantiated as well, and for the same reason (because we are accessing its nested <literal>type</> member). Unnecessary instantiation that is not fatal may or may be not a problem, depending on the <quote>weight</> of the template (how much the instantiation taxes the compiler), but a general rule of thumb would be to avoid such code.
</>
<para>
Returning to our error, to make the above code compile, we need to factor the act of <quote>asking</> <literal>aux::element_type&lt;T&gt;</> for its nested <literal>type</> out of the <literal>if_</> invocation. The fact that both the <literal>boost::remove_pointer&lt;T&gt;</> trait template and <literal>aux::element_type&lt;T&gt;</> use the same naming convention for their result types makes the refactoring easier:
</>
<programlisting>
<![CDATA[
template< typename T >
struct pointed_type
{
private:
typedef typename mpl::if_<
boost::is_pointer<T>
, boost::remove_pointer<T>
, aux::element_type<T>
>::type func_;
public:
typedef typename func_::type type;
};
]]>
</>
<para>
Now the compiler is guaranteed not to instantiate both <literal>boost::remove_pointer&lt;T&gt;</> and <literal>aux::element_type&lt;T&gt;</>, even although they are used as actual parameters to the <literal>if_</> template, so we are allowed to get away with <literal>aux::element_type&lt;char*&gt;</> so long as it won't end up being selected as <literal>func_</>.
</>
<para>
The above technique is so common in template metaprograms, that it even makes sense to facilitate the selection of a nested <literal>type</> member by introducing a high-level equivalent to <literal>if_</> - the one that will do the <literal>func_::type</> operation (that is called [nullary] metafunction class application) as a part of its invocation. The &MPL; provides such template - it's called <literal>apply_if</>. Using it, we can re-write the above code as simple as:
</>
<programlisting>
<![CDATA[
template< typename T >
struct pointed_type
{
typedef typename mpl::apply_if<
boost::is_pointer<T>
, boost::remove_pointer<T>
, aux::element_type<T>
>::type type;
};
]]>
</>
<para>
To make our techniques review complete, let's consider a slightly different example - suppose we want to define a high-level wrapper around <literal>boost::remove_pointer</> traits template <citation><xref linkend="ref.TTL"></>, which will strip the pointer qualification conditionally. We will call it <literal>remove_pointer_if</>:
</>
<programlisting>
<![CDATA[
template<
typename Condition
, typename T
>
struct remove_pointer_if
{
typedef typename mpl::if_<
Condition
, typename boost::remove_pointer<T>::type
, T
>::type type;
};
]]>
</>
<para>
Now the above works the first time, but it suffers from the problem we mentioned earlier - <literal>boost::remove_pointer&lt;T&gt;</> gets instantiated even if its result is never used. In the metaprogramming world compilation time is an important resource <citation><xref linkend="ref.Abr01"></>, and it is wasted by unnecessary template instantiations. We've just seen how to deal with the problem when both arguments to <literal>if_</> are the results of nullary metafunction class applications, but in this example one of the arguments (<literal>T</>) is just a simple type, so the refactoring just doesn't seem possible.
</>
<para>
The easiest way out of this situation would be to pass to <literal>if_</> a real nullary metafunction instead of <literal>T</> - the one that returns <literal>T</> on its invocation. The &MPL; provides a simple way to do it - we just substitute <literal>identity&lt;T&gt;</> and <literal>apply_if</> for <literal>T</> and <literal>if_</>:
</>
<programlisting>
<![CDATA[
template<
typename Condition
, typename T
>
struct remove_pointer_if
{
typedef typename mpl::apply_if<
Condition
, boost::remove_pointer<T>
, mpl::identity<T>
>::type type;
};
]]>
</>
<para>
which gives us exactly what we wanted.
</>
</section>
</section>
-8
View File
@@ -1,8 +0,0 @@
<section id="usage">
<title>Basic usage</>
&typeselection;
&metafunctions;
&sequences;
</section>
-7
View File
@@ -1,7 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Acknowledgements</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Acknowledgements</h1>The format and language of this reference documentation has been greatly influenced by the SGI's <a href="http://www.sgi.com/tech/stl/">[Standard Template Library Programmer's Guide]</a>.
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 9:04 am</body></html>
-40
View File
@@ -1,40 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Algorithms</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Algorithms</h1><h4>Iteration algorithms</h4>
<ul>
<li><a href="./Reference/iter_fold.html">iter_fold</a>
<li><a href="./Reference/iter_fold_backward.html">iter_fold_backward</a>
<li><a href="./Reference/fold.html">fold</a>
<li><a href="./Reference/fold_backward.html">fold_backward</a>
<li><a href="./Reference/copy.html">copy</a>
<li><a href="./Reference/copy_if.html">copy_if</a>
<li><a href="./Reference/copy_backward.html">copy_backward</a>
<li><a href="./Reference/copy_backward_if.html">copy_backward_if</a>
</ul>
<h4>Querying algorithms</h4>
<ul>
<li><a href="./Reference/find.html">find</a>
<li><a href="./Reference/find_if.html">find_if</a>
<li><a href="./Reference/contains.html">contains</a>
<li><a href="./Reference/count.html">count</a>
<li><a href="./Reference/count_if.html">count_if</a>
<li><a href="./Reference/equal.html">equal</a>
<li><a href="./Reference/lower_bound.html">lower_bound</a>
<li><a href="./Reference/upper_bound.html">upper_bound</a>
<li><a href="./Reference/max_element.html">max_element</a>
<li><a href="./Reference/min_element.html">min_element</a>
</ul>
<h4>Transformation algorithms</h4>
<ul>
<li><a href="./Reference/transform.html">transform</a>
<li><a href="./Reference/remove.html">remove</a>
<li><a href="./Reference/remove_if.html">remove_if</a>
<li><a href="./Reference/replace.html">replace</a>
<li><a href="./Reference/replace_if.html">replace_if</a>
<li><a href="./Reference/reverse.html">reverse</a>
<li>unique
</ul>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 1:55 am</body></html>
-50
View File
@@ -1,50 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Bidirectional Iterator</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Bidirectional Iterator</h1><h3>Description</h3>
<p>
A Bidirectional Iterator is a <a href="./Forward_Iterator.html">Forward Iterator</a> that provides a way to obtain the previous element in a sequence.
<p>
<p>
<h3>Refinement of</h3>
<p>
<a href="./Forward_Iterator.html">Forward Iterator</a>
<p>
<h3>Definitions</h3>
<ul>
<li>a bidirectional iterator <code>i</code> is <em>decrementable</em> if there is a "previous" iterator, that is, if <code>i::prior</code> expression is well-defined; iterators pointing to the first element of the sequence are not decrementable.
</ul>
<p>
<h3>Valid expressions</h3>
<p>
Bidirectional Iterator both defines a new expression and refines the one described in <a href="./Forward_Iterator.html">Forward Iterator</a>.
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename i::next</code></td><td>A model of <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a> </td></tr>
<tr><td><code>typename i::prior</code></td><td>A model of <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a> </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
Semantics of an expression is defined only where it is not defined in <a href="./Forward_Iterator.html">Forward Iterator</a>.
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Complexity&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition &nbsp;</th></tr>
<tr><td><code>typename i::prior</code></td><td>Amortized constant time</td><td><code>i</code> is decrementable</td><td><code>i::prior</code> is an iterator pointing to the previous element of the sequence</td><td><code>i::prior</code> is dereferencable and incrementable </td></tr>
</table>
<p>
<h3>Invariants</h3>
<p>
For any bidirectional iterators <code>i</code> and <code>j</code> the following invariants always hold:
<p>
<ul>
<li>if <code>i</code> is incrementable, then <code>i::next::prior</code> is a null operation; similarly, if <code>i</code> is decrementable, <code>i::prior::next</code> is a null operation.
</ul>
<p>
<h3>See also</h3>
<p>
<a href="./Bidirectional_Sequence.html">Bidirectional Sequence</a>, <a href="./Forward_Iterator.html">Forward Iterator</a>, <a href="./Random_Access_Iterator.html">Random Access Iterator</a>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited July 15, 2002 11:33 am</body></html>
-35
View File
@@ -1,35 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Bidirectional Sequence</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Bidirectional Sequence</h1><h3>Description</h3>
<p>
A Bidirectional Sequence is a <a href="./Forward_Sequence.html">Forward Sequence</a>, which provides iterators that satisfy the <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a> requirements.
<p>
<h3>Refinement of</h3>
<p>
<a href="./Forward_Sequence.html">Forward Sequence</a>
<p>
<h3>Valid expressions</h3>
<p>
Bidirectional Sequence does not define any new expressions beyond those defined in <a href="./Forward_Sequence.html">Forward Sequence</a>. However, it refines the expression requirements.
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename begin&lt;s&gt;::type</code></td><td>A model of <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a> </td></tr>
<tr><td><code>typename end&lt;s&gt;::type</code></td><td>A model of <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a> </td></tr>
</table>
<p>
<h3>Models</h3>
<p>
<ul>
<li><code><a href="./Reference/vector.html">vector</a></code>
<li><code><a href="./Reference/vector_c.html">vector_c</a></code>
<li><code><a href="./Reference/range_c.html">range_c</a></code>
</ul>
<p>
<h3>See also</h3>
<p>
<a href="./Forward_Sequence.html">Forward Sequence</a>, <a href="./Random_Access_Sequence.html">Random Access Sequence</a>, <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited July 15, 2002 2:36 pm</body></html>
-98
View File
@@ -1,98 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Categorized index</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Categorized index</h1><h4>Concepts</h4>
<p>
<ul>
<li><a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a>
<li><a href="./Bidirectional_Sequence.html">Bidirectional Sequence</a>
<li><a href="./Extensible_Sequence.html">Extensible Sequence</a>
<li><a href="./Forward_Iterator.html">Forward Iterator</a>
<li><a href="./Forward_Sequence.html">Forward Sequence</a>
<li><a href="./Input_Iterator.html">Input Iterator</a>
<li><a href="./Integral_Constant.html">Integral Constant</a>
<li><a href="./Metafunction.html">Metafunction</a>
<li><a href="./Metafunction_Class.html">Metafunction Class</a>
<li><a href="./Random_Access_Iterator.html">Random Access Iterator</a>
<li><a href="./Random_Access_Sequence.html">Random Access Sequence</a>
<li><a href="./Sequence.html">Sequence</a>
<li><a href="./Trivial_Iterator.html">Trivial Iterator</a>
</ul>
<p>
<h4>Components</h4>
<p>
<ul>
<li><a href="./Reference/advance.html">advance</a>
<li><a href="./Reference/and.html">and_</a>
<li><a href="./Reference/at.html">at</a>
<li><a href="./Reference/at_c.html">at_c</a>
<li><a href="./Reference/back.html">back</a>
<li><a href="./Reference/begin.html">begin</a>
<li><a href="./Reference/clear.html">clear</a>
<li><a href="./Reference/contains.html">contains</a>
<li><a href="./Reference/copy.html">copy</a>
<li><a href="./Reference/copy_backward.html">copy_backward</a>
<li><a href="./Reference/copy_backward_if.html">copy_backward_if</a>
<li><a href="./Reference/copy_if.html">copy_if</a>
<li><a href="./Reference/count.html">count</a>
<li><a href="./Reference/count_if.html">count_if</a>
<li><a href="./Reference/deref.html">deref</a>
<li><a href="./Reference/distance.html">distance</a>
<li><a href="./Reference/divides.html">divides</a>
<li><a href="./Reference/empty.html">empty</a>
<li><a href="./Reference/end.html">end</a>
<li><a href="./Reference/equal.html">equal</a>
<li><a href="./Reference/equal_to.html">equal_to</a>
<li><a href="./Reference/erase.html">erase</a>
<li><a href="./Reference/erase_range.html">erase_range</a>
<li><a href="./Reference/filter_view.html">filter_view</a>
<li><a href="./Reference/find.html">find</a>
<li><a href="./Reference/find_if.html">find_if</a>
<li><a href="./Reference/fold.html">fold</a>
<li><a href="./Reference/fold_backward.html">fold_backward</a>
<li><a href="./Reference/front.html">front</a>
<li><a href="./Reference/greater.html">greater</a>
<li><a href="./Reference/greater_equal.html">greater_equal</a>
<li><a href="./Reference/insert.html">insert</a>
<li><a href="./Reference/insert_range.html">insert_range</a>
<li><a href="./Reference/iter_fold.html">iter_fold</a>
<li><a href="./Reference/iter_fold_backward.html">iter_fold_backward</a>
<li><a href="./Reference/iterator_category.html">iterator_category</a>
<li><a href="./Reference/joint_view.html">joint_view</a>
<li><a href="./Reference/less.html">less</a>
<li><a href="./Reference/less_equal.html">less_equal</a>
<li><a href="./Reference/list.html">list</a>
<li><a href="./Reference/list_c.html">list_c</a>
<li><a href="./Reference/lower_bound.html">lower_bound</a>
<li><a href="./Reference/max_element.html">max_element</a>
<li><a href="./Reference/min_element.html">min_element</a>
<li><a href="./Reference/minus.html">minus</a>
<li><a href="./Reference/modulus.html">modulus</a>
<li><a href="./Reference/multiplies.html">multiplies</a>
<li><a href="./Reference/negate.html">negate</a>
<li><a href="./Reference/not.html">not_</a>
<li><a href="./Reference/not_equal_to.html">not_equal_to</a>
<li><a href="./Reference/or.html">or_</a>
<li><a href="./Reference/plus.html">plus</a>
<li><a href="./Reference/pop_back.html">pop_back</a>
<li><a href="./Reference/pop_front.html">pop_front</a>
<li><a href="./Reference/push_back.html">push_back</a>
<li><a href="./Reference/push_front.html">push_front</a>
<li><a href="./Reference/range_c.html">range_c</a>
<li><a href="./Reference/remove.html">remove</a>
<li><a href="./Reference/remove_if.html">remove_if</a>
<li><a href="./Reference/replace.html">replace</a>
<li><a href="./Reference/replace_if.html">replace_if</a>
<li><a href="./Reference/reverse.html">reverse</a>
<li><a href="./Reference/single_view.html">single_view</a>
<li><a href="./Reference/size.html">size</a>
<li><a href="./Reference/transform.html">transform</a>
<li><a href="./Reference/transform_view.html">transform_view</a>
<li><a href="./Reference/upper_bound.html">upper_bound</a>
<li><a href="./Reference/vector.html">vector</a>
<li><a href="./Reference/vector_c.html">vector_c</a>
<li><a href="./Reference/zip_view.html">zip_view</a>
</ul>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited March 12, 2003 7:17 am</body></html>
-40
View File
@@ -1,40 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Extensible Sequence</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Extensible Sequence</h1><h3>Description</h3>
<p>
An Extensible Sequence is either a <a href="./Forward_Sequence.html">Forward Sequence</a>, a <a href="./Bidirectional_Sequence.html">Bidirectional Sequence</a> or a <a href="./Random_Access_Sequence.html">Random Access Sequence</a> that supports insertion and removal operations.
<p>
<h3>Refinement of</h3>
<p>
<a href="./Forward_Sequence.html">Forward Sequence</a>, <a href="./Bidirectional_Sequence.html">Bidirectional Sequence</a> or <a href="./Random_Access_Sequence.html">Random Access Sequence</a>
<p>
<h3>Valid expressions</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename clear&lt;s&gt;::type</code></td><td>A model of concept of <code>s</code> </td></tr>
<tr><td><code>typename insert&lt;s,pos,T&gt;::type</code></td><td>A model of concept of <code>s</code> </td></tr>
<tr><td><code>typename erase&lt;s,pos&gt;::type</code></td><td>A model of concept of <code>s</code> </td></tr>
<tr><td><code>typename erase&lt;s,first,last&gt;::type</code></td><td>A model of concept of <code>s</code> </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
See the description of <a href="./Reference/clear.html">clear</a>, <a href="./Reference/insert.html">insert</a>, and <a href="./Reference/erase.html">erase</a> algorithms.
<p>
<h3>Models</h3>
<p>
<ul>
<li><code><a href="./Reference/vector.html">vector</a></code>
<li><code><a href="./Reference/vector_c.html">vector_c</a></code>
<li><code><a href="./Reference/list.html">list</a></code>
<li><code><a href="./Reference/list_c.html">list_c</a></code>
</ul>
<p>
<h3>See also</h3>
<p>
<a href="./Sequences.html">Sequences</a>, <code><a href="./Reference/clear.html">clear</a></code>, <code><a href="./Reference/insert.html">insert</a></code>, <code><a href="./Reference/erase.html">erase</a></code>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited July 16, 2002 6:27 pm</body></html>
-34
View File
@@ -1,34 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Forward Iterator</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Forward Iterator</h1><h3>Description</h3>
<p>
A Forward Iterator is an <a href="./Input_Iterator.html">Input Iterator</a> that guarantees a linear traversal over the sequence.
<p>
<h3>Refinement of</h3>
<p>
<a href="./Input_Iterator.html">Input Iterator</a>
<p>
<p>
<h3>Valid expressions</h3>
<p>
Forward Iterator does not define any new expressions beyond those defined in <a href="./Input_Iterator.html">Input Iterator</a>. However, some of the restrictions described in <a href="./Input_Iterator.html">Input Iterator</a> are relaxed.
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename i::next</code></td><td>A model of <a href="./Forward_Iterator.html">Forward Iterator</a> </td></tr>
</table>
<p>
<h3>Invariants</h3>
<p>
For any forward iterators i and j the following invariants always hold:
<ul>
<li>if <code>i</code> and <code>j</code> are dereferenceable and <code>i</code> is identical to <code>j</code>, then <code>i::next</code> is identical to <code>j::next</code>.
</ul>
<p>
<h3>See also</h3>
<p>
<a href="./Forward_Sequence.html">Forward Sequence</a>, <a href="./Input_Iterator.html">Input Iterator</a>, <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited July 15, 2002 10:53 am</body></html>
-48
View File
@@ -1,48 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Forward Sequence</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Forward Sequence</h1><h3>Description</h3>
<p>
A Forward Sequence is a <a href="./Sequence.html">Sequence</a> which guarantees that its elements are arranged in a definite order, and that the ordering will not change spontaneously [<a href="#1">1</a>]. Iterators into a forward sequence satisfy the <a href="./Forward_Iterator.html">Forward Iterator</a> requirements.
<p>
<h3>Refinement of</h3>
<p>
<a href="./Sequence.html">Sequence</a>
<p>
<h3>Valid expressions</h3>
<p>
Forward Sequence does not define any new expressions beyond those defined in <a href="./Sequence.html">Sequence</a>. However, it refines the expression requirements.
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename begin&lt;s&gt;::type</code></td><td>A model of <a href="./Forward_Iterator.html">Forward Iterator</a> </td></tr>
<tr><td><code>typename end&lt;s&gt;::type</code></td><td>A model of <a href="./Forward_Iterator.html">Forward Iterator</a> </td></tr>
</table>
<p>
<h3>Invariants</h3>
<p>
For any forward sequence <code>s</code> the following invariants always hold:
<ul>
<li>Two different iterations through <code>s</code> will access its elements in the same order.
</ul>
<p>
<h3>Models</h3>
<p>
<ul>
<li><code><a href="./Reference/vector.html">vector</a></code>
<li><code><a href="./Reference/vector_c.html">vector_c</a></code>
<li><code><a href="./Reference/list.html">list</a></code>
<li><code><a href="./Reference/list_c.html">list_c</a></code>
<li><code><a href="./Reference/range_c.html">range_c</a></code>
</ul>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] Both between compilation sessions and from iteration to iteration.<br>
<p>
<h3>See also</h3>
<p>
<a href="./Sequence.html">Sequence</a>, <a href="./Bidirectional_Sequence.html">Bidirectional Sequence</a>, <a href="./Forward_Iterator.html">Forward Iterator</a>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited July 15, 2002 2:34 pm</body></html>
-44
View File
@@ -1,44 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Input Iterator</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Input Iterator</h1><h3>Description</h3>
<p>
An Input Iterator is a <a href="./Trivial_Iterator.html">Trivial Iterator</a> that provides a way to obtain the next iterator in a sequence.
<p>
<h3>Refinement of</h3>
<p>
<a href="./Trivial_Iterator.html">Trivial Iterator</a>
<p>
<h3>Definitions</h3>
<p>
<ul>
<li>an input iterator is <em>past-the-end</em> if it points beyond the last element of a sequence; past-the-end iterators are non-dereferenceable;
<li>an input iterator is <em>valid</em> if it is dereferenceable or past-the-end;
<li>an input iterator <code>i</code> is <em>incrementable</em> if there is a "next" iterator, that is, if <code>i::next</code> expression is well-defined; past-the-end iterators are not incrementable;
<li>an input iterator <code>j</code> is <em>reachable</em> from a forward iterator <code>i</code> if, after recursive application of <code>next</code> operation to <code>i</code> a finite number of times, <code>i</code> is identical to <code>j</code>;
<li>the notation <code>[i,j)</code> refers to a <em>range</em> of iterators beginning with <code>i</code> and up to but not including <code>j</code>;
<li>the range <code>[i,j)</code> is a <em>valid range</em> if both <code>i</code> and <code>j</code> are valid iterators, and <code>j</code> is reachable from <code>i</code>.
</ul>
<p>
<h3>Valid expressions</h3>
<p>
In addition to the expressions defined in <a href="./Trivial_Iterator.html">Trivial Iterator</a>, the following expressions must be valid.
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename i::next</code></td><td>A model of <a href="./Input_Iterator.html">Input Iterator</a> </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Complexity&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition &nbsp;</th></tr>
<tr><td><code>typename i::next</code></td><td>Amortized constant time</td><td><code>i</code> is incrementable</td><td><code>i::next</code> is the next iterator in a sequence</td><td><code>i::next</code> is dereferenceable or past-the-end </td></tr>
</table>
<p>
<h3>See also</h3>
<p>
<a href="./Sequence.html">Sequence</a>, <a href="./Trivial_Iterator.html">Trivial Iterator</a>, <a href="./Forward_Iterator.html">Forward Iterator</a>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited July 15, 2002 10:48 am</body></html>
-43
View File
@@ -1,43 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Integral Constant</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Integral Constant</h1><h3>Description</h3>
<p>
An Integral Constant is a class representing a value of a built-in integral type (<code>bool</code>, <code>int</code>, <code>long</code>, etc.) in compile-time programs. An integral constant directly supports the increment/decrement operations within the range of the built-in integral type it wraps. Other arithmetic operations are supported through the external metafunctions.
<p>
<h3>Valid expressions</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Return type &nbsp;</th></tr>
<tr><td><code>typename n::value_type</code></td><td>An <em>integral type</em> </td></tr>
<tr><td><code>typename n::type</code></td><td>A model of <a href="./Integral_Constant.html">Integral Constant</a> </td></tr>
<tr><td><code>n::value</code></td><td>A compile-time integral constant of <code>n::value_type</code> </td></tr>
<tr><td><code>typename n::next</code></td><td>A model of <a href="./Integral_Constant.html">Integral Constant</a> </td></tr>
<tr><td><code>typename n::prior</code></td><td>A model of <a href="./Integral_Constant.html">Integral Constant</a> </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Complexity&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition &nbsp;</th></tr>
<tr><td><code>typename n::value_type</code></td><td>Amortized constant time</td><td></td><td><code>n::value_type</code> is identical to <code>typeof(n::value)</code></td><td></td></tr>
<tr><td><code>typename n::type</code></td><td>Amortized constant time</td><td></td><td>Self-reference.</td><td><code>is_same&lt;n::type,n&gt;::value == true</code> </td></tr>
<tr><td><code>n::value</code></td><td>Amortized constant time</td><td></td><td>Value of <code>n</code>.</td><td></td></tr>
<tr><td><code>typename n::next</code></td><td>Amortized constant time</td><td><code>n::value_type</code> supports an increment operation; <code>n::value</code> is incrementable</td><td>Increment operation</td><td><code>n::next::value == n::value + 1</code> </td></tr>
<tr><td><code>typename n::prior</code></td><td>Amortized constant time</td><td><code>n::value_type</code> supports an decrement operation; <code>n::value</code> is decrementable</td><td>Decrement operation</td><td><code>n::prior::value == n::value - 1</code> </td></tr>
</table>
<p>
<h3>Models</h3>
<p>
<ul>
<li><code>integral_c</code>
<li><code>int_</code>
<li><code>bool_</code>
</ul>
<p>
<h3>See also</h3>
<p>
<code>next</code>, <code>prior</code>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 4:21 am</body></html>
-19
View File
@@ -1,19 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Integral constant classes</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Integral constant classes</h1><h4>Concepts</h4>
<ul>
<li><a href="./Integral_Constant.html">Integral Constant</a>
</ul>
<p>
<h4>Types</h4>
<ul>
<li>integral_c
<li>bool_
<li>int_
<li>long_
<li>size_t
</ul>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 1:34 am</body></html>
-31
View File
@@ -1,31 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Iterators</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Iterators</h1>Iterators are a generic means of addressing a particular element or
range of sequential elements in a sequence. They are also the mechanism
that makes it possible to decouple algorithms from concrete compile-time
sequence implementations. Under the hood, all MPL <a href="./Algorithms.html">sequence algorithms</a>
are implemented in terms of iterators, which, in particular, means that
they will work on any custom compile-time sequence, given that the appropriate
iterator inteface is provided.
<p>
<h4>Concepts</h4>
<ul>
<li><a href="./Trivial_Iterator.html">Trivial Iterator</a>
<li><a href="./Input_Iterator.html">Input Iterator</a>
<li><a href="./Forward_Iterator.html">Forward Iterator</a>
<li><a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a>
<li><a href="./Random_Access_Iterator.html">Random Access Iterator</a>
</ul>
<p>
<h4>Metafunctions</h4>
<ul>
<li><a href="./Reference/iterator_category.html">iterator_category</a>
<li><a href="./Reference/begin.html">begin</a>/<a href="./Reference/end.html">end</a>
<li><a href="./Reference/deref.html">deref</a>
<li><a href="./Reference/advance.html">advance</a>
<li><a href="./Reference/distance.html">distance</a>
</ul>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 1:42 am</body></html>
-77
View File
@@ -1,77 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Metafunction</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Metafunction</h1><h3>Description</h3>
<p>
A <em>metafunction</em> is a class or a class template that represents a function invocable at compile-time. A non-nullary metafunction is invoked by instantiating the class template with particular template parameters
(metafunction arguments); the result of the metafunction application is accessible through the instantiation's nested <code>type</code> typedef. All metafunction's arguments must be types (i.e. only <em>type template parameters</em> are allowed). A metafunction can have a variable number of parameters. A nullary metafunction is represented as a class with a nested
<code>type</code> typename member.
<p>
<h3>Valid expressions</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename f::type</code></td><td>A type </td></tr>
<tr><td><code>typename f&lt;a1,..,an&gt;::type</code></td><td>A type </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Complexity&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typename f::type</code></td><td>unspecified</td><td><code>f</code> is a nullary metafunction; <code>f::type</code> is a <em>type-name</em></td><td><code>f::type</code> is the result of the metafunction invocation</td><td></td></tr>
<tr><td><code>typename f&lt;a1,..,an&gt;::type</code></td><td>unspecified</td><td><code>f</code> is an <code>n</code>-ary metafunction; <code>a1,..,an</code> are types; <code>f&lt;a1,..,an&gt;::type</code> is a <em>type-name</em></td><td><code>f&lt;a1,..,an&gt;::type</code> is the result of the metafunction invocation with the actual arguments <code>a1,..,an</code></td><td></td></tr>
</table>
<p>
<p>
<h3>Example</h3>
<p>
<pre>
<span class="cxx-comment">// nullary metafunction</span>
struct always_true { typedef true_ type; };
<p>
<span class="cxx-comment">// unary metafunction</span>
template&lt; typename T &gt; struct sizeof_
{
typedef int_&lt; sizeof(T) &gt; type;
};
<p>
<span class="cxx-comment">// binary metafunction</span>
template&lt; typename T1, typename T2 &gt;
struct is_same
{
typedef false_ type;
};
<p>
template&lt; typename T &gt;
struct is_same&lt;T,T&gt;
{
typedef true_ type;
};
<p>
<span class="cxx-comment">// invocations</span>
typedef always_true::type t1;
typedef sizeof_&lt;int&gt;::type t2;
typedef is_same&lt;int,char&gt;::type t3;
<p>
<span class="cxx-comment">// results checks</span>
BOOST_STATIC_ASSERT(t1::value);
BOOST_STATIC_ASSERT(t2::value == sizeof(int));
BOOST_STATIC_ASSERT(!t3::value);
</pre>
<p>
<h3>Models</h3>
<p>
<ul>
<li><code><a href="./Reference/plus.html">plus</a></code>
<li><code><a href="./Reference/not.html">not_</a></code>
<li><code><a href="./Reference/size.html">size</a></code>
<li><code><a href="./Reference/max_element.html">max_element</a></code>
</ul>
<p>
<h3>See also</h3>
<p>
<a href="./Metafunctions.html">Metafunctions</a>, <a href="./Metafunction_Class.html">Metafunction Class</a>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 3:27 am</body></html>
-67
View File
@@ -1,67 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Metafunction Class</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Metafunction Class</h1><h3>Description</h3>
<p>
A <em>metafunction class</em> is a certain form of metafunction representation that enables higher-order metaprogramming. In particular, a non-nullary metafunction class is a type with a nested class template member <code>apply</code>. A nullary metafunction class has the form of a <a href="./Metafunction.html">nullary metafunction</a>. A metafunction class invocation is defined as invocation of its nested <code>apply</code> <a href="./Metafunction.html">metafunction</a>.
<p>
<h3>Valid expressions</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename f::type</code></td><td>A type </td></tr>
<tr><td><code>typename f::template apply&lt;a1,..,an&gt;::type</code></td><td>A type </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Complexity&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typename f::type</code></td><td>unspecified</td><td><code>f</code> is a nullary metafunction class; <code>f::type</code> is a <em>type-name</em></td><td><code>f::type</code> is the result of the metafunction class invocation</td><td></td></tr>
<tr><td><code>typename f::template apply&lt;a1,..,an&gt;::type</code></td><td>unspecified</td><td><code>f</code> is an <code>n</code>-ary metafunction class; <code>apply</code> is a <a href="./Metafunction.html">metafunction</a></td><td><code>typename f::template apply&lt;a1,..,an&gt;::type</code> is the result of the metafunction class invocation with the actual arguments <code>a1,..,an</code></td><td></td></tr>
</table>
<p>
<p>
<h3>Example</h3>
<p>
<pre>
<span class="cxx-comment">// nullary metafunction class</span>
struct always_true { typedef true_ type; };
<p>
template&lt; long N &gt; struct le
{
template&lt; typename M &gt; struct apply
{
typedef bool_&lt; (M::value &lt; N) &gt; type;
};
};
<p>
<span class="cxx-comment">// unary metafunction class</span>
typedef le&lt;5&gt; less_than_5;
<p>
<span class="cxx-comment">// binary metafunction class</span>
struct less_than
{
template&lt; typename N1, typename N2 &gt; struct apply
{
typedef bool_&lt; (N1::value &lt; N2::value) &gt; type;
};
};
<p>
<span class="cxx-comment">// invocations</span>
typedef always_true::type t1;
typedef less_than_5::apply&lt; int_&lt;7&gt; &gt;::type t2;
typedef less_than::apply&lt; int_&lt;5&gt;,int_&lt;7&gt; &gt;::type t3;
<p>
<span class="cxx-comment">// results checks</span>
BOOST_STATIC_ASSERT(t1::value);
BOOST_STATIC_ASSERT(!t2::value);
BOOST_STATIC_ASSERT(t3::value);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="./Metafunctions.html">Metafunctions</a>, <a href="./Metafunction.html">Metafunction</a>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 4:16 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Metafunctions</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Metafunctions</h1><h4>Concepts</h4>
<ul>
<li><a href="./Metafunction.html">Metafunction</a>
<li><a href="./Metafunction_Class.html">Metafunction Class</a>
</ul>
<p>
<h4>Invocation</h4>
<ul>
<li>apply
</ul>
<p>
<h4>Arithmetic operations </h4>
<ul>
<li><a href="./Reference/plus.html">plus</a>
<li><a href="./Reference/minus.html">minus</a>
<li><a href="./Reference/multiplies.html">multiplies</a>
<li><a href="./Reference/divides.html">divides</a>
<li><a href="./Reference/modulus.html">modulus</a>
<li><a href="./Reference/negate.html">negate</a>
</ul>
<p>
<h4>Comparisons </h4>
<ul>
<li><a href="./Reference/equal_to.html">equal_to</a>
<li><a href="./Reference/not_equal_to.html">not_equal_to</a>
<li><a href="./Reference/less.html">less</a>
<li><a href="./Reference/greater.html">greater</a>
<li><a href="./Reference/less_equal.html">less_equal</a>
<li><a href="./Reference/greater_equal.html">greater_equal</a>
</ul>
<p>
<h4>Logical operations </h4>
<ul>
<li><a href="./Reference/or.html">or_</a>
<li><a href="./Reference/and.html">and_</a>
<li><a href="./Reference/not.html">not_</a>
</ul>
<p>
<h4>Bitwise operations </h4>
<ul>
<li>bitor_
<li>bitand_
<li>bitxor_
<li>shift_left
<li>shift_right
</ul>
<p>
<h4>Identity operations</h4>
<ul>
<li>identity
<li>project1st
<li>project2nd
<li>select1st
<li>select2nd
</ul>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:39 am</body></html>
-48
View File
@@ -1,48 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Random Access Iterator</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Random Access Iterator</h1><h3>Description</h3>
<p>
A Random Access Iterator is a <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a> that provides constant-time methods for moving forward and backward on a sequence in arbitrary-sized steps.
<p>
<p>
<h3>Refinement of</h3>
<p>
<a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a>
<p>
<h3>Valid expressions</h3>
<p>
Random Access Iterator defines two new expressions and refines the ones described in <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a>.
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename i::next</code></td><td>A model of <a href="./Random_Access_Iterator.html">Random Access Iterator</a> </td></tr>
<tr><td><code>typename i::prior</code></td><td>A model of <a href="./Random_Access_Iterator.html">Random Access Iterator</a> </td></tr>
<tr><td><code>typename i::template advance&lt;n&gt;::type</code></td><td>A model of <a href="./Random_Access_Iterator.html">Random Access Iterator</a> </td></tr>
<tr><td><code>typename i::template distance&lt;j&gt;::type</code></td><td>A model of <a href="./Integral_Constant.html">Integral Constant</a> </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
Semantics of an expression is defined only where it is not defined in <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a>.
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Complexity&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition &nbsp;</th></tr>
<tr><td><code>typename i::template advance&lt;n&gt;::type</code></td><td>Amortized constant time</td><td>Including <code>i</code> itself, there must be <code>n::value</code> dereferenceable or past-the-end iterators following or preceding <code>i</code>, depending on whether <code>n</code> is positive or negative.</td><td>If <code>n::value &gt; 0</code>, equivalent to executing <code>i::next</code> <code>n::value</code> times; if <code>n::value &lt; 0</code>, equivalent to executing <code>i::prior</code> <code>n::value</code> times; if <code>n::value == 0</code>, this is a null operation [<a href="#1">1</a>].</td><td>The resulting iterator is dereferenceable or past-the-end. </td></tr>
<tr><td><code>typename i::template distance&lt;j&gt;::type</code></td><td>Amortized constant time</td><td>Either <code>i</code> is reachable from <code>j</code> or <code>j</code> is reachable from <code>i</code>, or both.</td><td>Returns an integral constant <code>n</code> such that <code>i::template advance&lt;n&gt;::type</code> is identical to <code>j</code>. </td></tr>
</table>
<p>
<h3>Invariants</h3>
<p>
For any random access iterators <code>i</code> and <code>j</code> the following invariants always hold:
<p>
<ul>
<li>if <code>i::advance&lt;n&gt;::type</code> is well-defined, then <code>i::advance&lt;n&gt;::type::advance&lt; <a href="./Reference/negate.html">negate</a>&lt;n&gt;::type &gt;::type</code> is a null operation.
</ul>
<p>
<h3>See also</h3>
<p>
<a href="./Random_Access_Sequence.html">Random Access Sequence</a>, <a href="./Bidirectional_Iterator.html">Bidirectional Iterator</a>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited July 15, 2002 11:35 am</body></html>
-35
View File
@@ -1,35 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::Random Access Sequence</title>
<link rel="stylesheet" href="./mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="./Table_of_Contents.html"><img src="./mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>Random Access Sequence</h1><h3>Description</h3>
<p>
A Random Access Sequence is a <a href="./Bidirectional_Sequence.html">Bidirectional Sequence</a> which provides iterators that satisfy the <a href="./Random_Access_Iterator.html">Random Access Iterator</a> requirements. A random access sequence provides amortized constant time access to arbitrary elements.
<p>
<h3>Refinement of</h3>
<p>
<a href="./Bidirectional_Sequence.html">Bidirectional Sequence</a>
<p>
<h3>Valid expressions</h3>
<p>
Random Access Sequence does not define any new expressions beyond those defined in <a href="./Bidirectional_Sequence.html">Bidirectional Sequence</a>. However, it refines the expression requirements.
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type &nbsp;</th></tr>
<tr><td><code>typename begin&lt;s&gt;::type</code></td><td>A model of <a href="./Random_Access_Iterator.html">Random Access Iterator</a> </td></tr>
<tr><td><code>typename end&lt;s&gt;::type</code></td><td>A model of <a href="./Random_Access_Iterator.html">Random Access Iterator</a> </td></tr>
</table>
<p>
<h3>Models</h3>
<p>
<ul>
<li><code><a href="./Reference/vector.html">vector</a></code>
<li><code><a href="./Reference/vector_c.html">vector_c</a></code>
<li><code><a href="./Reference/range_c.html">range_c</a></code>
</ul>
<p>
<h3>See also</h3>
<p>
<a href="./Bidirectional_Sequence.html">Bidirectional Sequence</a>, <a href="./Random_Access_Iterator.html">Random Access Iterator</a>
<p><hr>
<a href="./Table_of_Contents.html">Table of Contents</a><br>Last edited July 15, 2002 2:37 pm</body></html>
-62
View File
@@ -1,62 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::advance</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>advance</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Iterator
, typename N
&gt;
struct advance
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns an new iterator <code>i</code> such as <code>distance&lt; Iterator,i &gt;::type::value == N::value</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/advance.hpp">boost/mpl/advance.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Iterator</code></td><td>A model of <a href="../Input_Iterator.html">Input Iterator</a></td><td></td></tr>
<tr><td><code>N</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef advance&lt;Iterator,N&gt;::type i;</code></td><td>A model of <a href="../Input_Iterator.html">Input Iterator</a></td><td><code>Iterator</code> and every iterator between <code>Iterator</code> and <code>i</code> (inclusive) is nonsingular; <code>N::value</code> must be nonnegative if <code>Iterator</code> is a model of <a href="../Input_Iterator.html">Input Iterator</a> or <a href="../Forward_Iterator.html">Forward Iterator</a></td><td>Equivalent to <code>typedef Iterator::next i1; typedef i1::next i2; .. typedef in-1::next i;</code> if <code>N::value &gt; 0</code>, and <code>typedef Iterator::prior i1; typedef i1::prior i2; .. typedef in-1::prior i;</code> otherwise; if <code>N::value == 0</code>, the algorithm has no effect.</td><td><code>distance&lt; Iterator,i &gt;::type::value == N::value</code> </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time if <code>Iterator</code> is a model of <a href="../Random_Access_Iterator.html">Random Access Iterator</a>, otherwise linear time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef vector_c&lt;int,0,1,2,3,4,5,6,7,8,9&gt; numbers;
typedef begin&lt;numbers&gt;::type first;
typedef end&lt;numbers&gt;::type last;
typedef advance_c&lt;first,10&gt;::type iter1;
typedef advance_c&lt;last,-10&gt;::type iter2;
BOOST_MPL_ASSERT_IS_SAME(iter1, last);
BOOST_MPL_ASSERT_IS_SAME(iter2, first);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Iterators.html">Iterators</a>, <a href="../Sequence.html">Sequence</a>, <code><a href="../Reference/distance.html">distance</a></code>, <code><a href="../Reference/begin.html">begin</a></code>, <code><a href="../Reference/end.html">end</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 6:38 am</body></html>
-62
View File
@@ -1,62 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::and_</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>and_</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename F1
, typename F2
, typename F3 = true_
...
, typename Fn = true_
&gt;
struct and_
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the result of short-circuit <em>logical and</em> (<code>&amp;&amp;</code>) operation on its arguments.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/and.hpp">boost/mpl/and.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>F1, F2, .., Fn</code></td><td>A model of nullary <a href="../Metafunction.html">Metafunction</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef and_&lt;f1,f2,..,fn&gt;::type c;</code></td><td>A model of <code>bool</code> <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Returns <code>false_</code> if either of <code>f1::type::value, f2::type::value, .., fn::type::value</code> expressions evaluates to <code>false</code>, and <code>true_</code> otherwise; guarantees left-to-right evaluation; moreover, the operands subsequent to the first <code>fi</code> metafunction that evaluates to <code>false</code> are not evaluated.</td><td></td></tr>
</table>
<p>
<h3>Example</h3>
<p>
<pre>
<span class="cxx-comment">// will generate compile-time error if invoked with T == any fundamental type</span>
template&lt; typename T &gt; struct fail
{
typedef typename T::nonexistent type;
};
<p>
BOOST_STATIC_ASSERT((and_&lt; true_,false_ &gt;::type::value == false));
BOOST_STATIC_ASSERT((and_&lt; false_,fail&lt;int&gt; &gt;::type::value == false)); <span class="cxx-comment">// OK, fail&lt;int&gt; is never invoked</span>
BOOST_STATIC_ASSERT((and_&lt; true_,false_,fail&lt;int&gt; &gt;::type::value == false)); <span class="cxx-comment">// OK too</span>
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Metafunctions.html">Metafunctions</a>, <code><a href="../Reference/or.html">or_</a></code>, <code><a href="../Reference/not.html">not_</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 1:21 am</body></html>
-59
View File
@@ -1,59 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::at</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>at</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename N
&gt;
struct at
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns a type identical to the <code>N</code>-th element from the beginning of the sequence.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/at.hpp">boost/mpl/at.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to be examined. </td></tr>
<tr><td><code>N</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td>The offset from the beginning of the sequence that specifies the element to be retrieved. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef at&lt;Sequence,N&gt;::type t;</code></td><td>A type</td><td><code>0 &lt;= N::value &lt; size&lt;Sequence&gt;::type::value</code></td><td>Equivalent to <code>typedef advance&lt; begin&lt;Sequence&gt;::type,N &gt;::type::type t;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Depends on the implementation of the particular sequence it is applied to. Linear in the worst case, or amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/range_c.html">range_c</a>&lt;long,10,50&gt; range;
BOOST_STATIC_ASSERT(at&lt; range, int_&lt;0&gt; &gt;::type::value == 10);
BOOST_STATIC_ASSERT(at&lt; range, int_&lt;10&gt; &gt;::type::value == 20);
BOOST_STATIC_ASSERT(at&lt; range, int_&lt;40&gt; &gt;::type::value == 50);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Forward_Sequence.html">Forward Sequence</a>, <code><a href="../Reference/at_c.html">at_c</a></code>, <code><a href="../Reference/front.html">front</a></code>, <code><a href="../Reference/back.html">back</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 12, 2003 6:26 am</body></html>
-59
View File
@@ -1,59 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::at_c</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>at_c</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, long n
&gt;
struct at_c
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns a type identical to the <code>n</code>-th element from the beginning of the sequence. <code>at_c&lt;Sequence,n&gt;::type</code> is a shorcut notation for <code>at&lt; Sequence, integral_c&lt;long,n&gt; &gt;::type</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/at.hpp">boost/mpl/at.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence being examined. </td></tr>
<tr><td><code>n</code></td><td>An compile-time integral constant</td><td>An offset from the beginning of the sequence that specifies the element to be retrieved. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef at_c&lt;Sequence,n&gt;::type t;</code></td><td>A type</td><td><code>0 &lt;= n &lt; size&lt;Sequence&gt;::type::value</code></td><td>Equivalent to <code>typedef at&lt; Sequence, integral_c&lt;long,n&gt; &gt;::type t;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Depends on the implementation of the particular sequence it is applied to. Linear in the worst case, or amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/range_c.html">range_c</a>&lt;long,10,50&gt; range;
BOOST_STATIC_ASSERT(at_c&lt;range,0&gt;::type::value == 10);
BOOST_STATIC_ASSERT(at_c&lt;range,10&gt;::type::value == 20);
BOOST_STATIC_ASSERT(at_c&lt;range,40&gt;::type::value == 50);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Forward_Sequence.html">Forward Sequence</a>, <code><a href="../Reference/at.html">at</a></code>, <code><a href="../Reference/front.html">front</a></code>, <code><a href="../Reference/back.html">back</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited October 21, 2002 4:09 am</body></html>
-64
View File
@@ -1,64 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::back</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>back</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
&gt;
struct back
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns a type identical to the last element in the sequence, that is, the element in a position that preceeds the position of past-the-end iterator.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/back.hpp">boost/mpl/back.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to be examined. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef back&lt;Sequence&gt;::type t;</code></td><td>A type</td><td><code>empty&lt;Sequence&gt;::type::value == false</code></td><td>Equivalent to <code>typedef prior&lt; end&lt;Sequence&gt;::type &gt;::type::type t;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time [<a href="#1">1</a>].
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/range_c.html">range_c</a>&lt;int,0,1&gt; range1;
typedef range_c&lt;int,0,10&gt; range2;
typedef range_c&lt;int,-10,0&gt; range3;
<p>
BOOST_STATIC_ASSERT(back&lt;range1&gt;::type::value == 0);
BOOST_STATIC_ASSERT(back&lt;range2&gt;::type::value == 9);
BOOST_STATIC_ASSERT(back&lt;range3&gt;::type::value == -1);
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The algorithm is provided only if the sequence can meet the stated complexity requirements.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Forward_Sequence.html">Forward Sequence</a>, <code><a href="../Reference/front.html">front</a></code>, <code><a href="../Reference/at.html">at</a></code>, <code><a href="../Reference/end.html">end</a></code>, <code><a href="../Reference/push_back.html">push_back</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 3:47 am</body></html>
-56
View File
@@ -1,56 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::begin</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>begin</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
&gt;
struct begin
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns an iterator that points to the first element of the sequence.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/begin_end.hpp">boost/mpl/begin_end.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef begin&lt;Sequence&gt;::type first;</code></td><td>A model of <a href="../Input_Iterator.html">Input Iterator</a></td><td></td><td><code>first</code> is an iterator pointing to the first element of the <code>Sequence</code>; equivalent to <code>Sequence::begin</code> unless the algorithm has been specialized for the particular type of sequence.</td><td><code>first</code> is either dereferenceable or past-the-end; it is past-the-end if and only if <code>size&lt;Sequence&gt;::type::value == 0</code>. </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef vector&lt;unsigned char,unsigned short,unsigned int, unsigned long&gt; unsigned_types;
typedef begin&lt;unsigned_types&gt;::type iter;
BOOST_STATIC_ASSERT((boost::is_same&lt;iter::type,unsigned char&gt;::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Iterators.html">Iterators</a>, <a href="../Sequence.html">Sequence</a>, <code><a href="../Reference/end.html">end</a></code>, <code><a href="../Reference/size.html">size</a></code>, <code><a href="../Reference/empty.html">empty</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 22, 2002 2:03 am</body></html>
-60
View File
@@ -1,60 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::clear</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>clear</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
&gt;
struct clear
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns an empty sequence that preserves all the functional and performance characteristics of the original <code>Sequence</code>, except its size and identity.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/clear.hpp">boost/mpl/clear.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Extensible_Sequence.html">Extensible Sequence</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef clear&lt;Sequence&gt;::type s;</code></td><td>A model of <a href="../Extensible_Sequence.html">Extensible Sequence</a></td><td></td><td>Equivalent to <code>typedef erase&lt;Sequence, begin&lt;Sequence&gt;::type, end&lt;Sequence&gt;::type&gt;::type s;</code></td><td><code>empty&lt;s&gt;::type::value == true</code> </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time [<a href="#1">1</a>].
<p>
<h3>Example</h3>
<p>
<pre>
typedef list_c&lt;int,1,3,5,7,9,11&gt; odds;
typedef clear&lt;odds&gt;::type nothing;
BOOST_STATIC_ASSERT(empty&lt;nothing&gt;::type::value);
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The algorithm is provided only if the sequence can meet the stated complexity requirements.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Extensible_Sequence.html">Extensible Sequence</a>, <code><a href="../Reference/erase.html">erase</a></code>, <code><a href="../Reference/empty.html">empty</a></code>, <code><a href="../Reference/begin.html">begin</a></code>, <code><a href="../Reference/end.html">end</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 3:58 am</body></html>
-58
View File
@@ -1,58 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::contains</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>contains</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename T
&gt;
struct contains
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns <code>true_</code> if one or more elements in <code>Sequence</code> are identical to <code>T</code>, and <code>false_</code> otherwise.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/contains.hpp">boost/mpl/contains.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to be examined. </td></tr>
<tr><td><code>T</code></td><td>A type</td><td>The type to search for. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef contains&lt;Sequence,T&gt;::type c;</code></td><td>A model of <code>bool</code> <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code>typedef <a href="../Reference/not.html">not_</a>&lt; is_same&lt; <a href="../Reference/find.html">find</a>&lt;Sequence,T&gt;::type, <a href="../Reference/end.html">end</a>&lt;Sequence&gt;::type &gt; &gt;::type c</code>; </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. At most <code>size&lt;Sequence&gt;::value</code> comparisons for identity.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/vector.html">vector</a>&lt;char,int,unsigned,long,unsigned long&gt; types;
typedef contains&lt;types,bool&gt;::type result;
BOOST_STATIC_ASSERT(!result::value);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/find.html">find</a></code>, <code><a href="../Reference/find_if.html">find_if</a></code>, <code><a href="../Reference/count.html">count</a></code>, <code><a href="../Reference/count_if.html">count_if</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 5:33 am</body></html>
-70
View File
@@ -1,70 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::copy</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>copy</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename State
, typename BinaryOp
&gt;
struct copy
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
<code>copy</code> is, in fact, just another name for <code><a href="../Reference/fold.html">fold</a></code>. It was introduced for symmetry with <code><a href="../Reference/copy_if.html">copy_if</a></code> [<a href="#1">1</a>], and because it's a nice name for one of the typical <code>fold</code> applications, that is, copying the content of one sequence into another - see the example below.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/copy.hpp">boost/mpl/copy.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>A sequence to iterate. </td></tr>
<tr><td><code>State</code></td><td>A type</td><td>The initial state for the first <code>BinaryOp</code> application. </td></tr>
<tr><td><code>BinaryOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on forward traversal. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef copy&lt;Sequence,T,Op&gt;::type s;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef fold&lt; Sequence,T,Op &gt;::type s;</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>BinaryOp</code>.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/vector_c.html">vector_c</a>&lt;int,0,1,2,3,4,5,6,7,8,9&gt; numbers;
typedef copy&lt;
<a href="../Reference/range_c.html">range_c</a>&lt;int,10,20&gt;
, <a href="../Reference/push_back.html">push_back</a>&lt;_,_&gt;
, numbers
&gt;::type result;
<p>
BOOST_STATIC_ASSERT(<a href="../Reference/size.html">size</a>&lt;result&gt;::value == 20);
BOOST_STATIC_ASSERT((<a href="../Reference/equal.html">equal</a>&lt; result,<a href="../Reference/range_c.html">range_c</a>&lt;int,0,20&gt; &gt;::type::value));
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] In case if you wonder why <code><a href="../Reference/copy_if.html">copy_if</a></code>, in its turn, wasn't just called <code>fold_if</code>, - something that would allow to eliminate the family of <code>copy</code> algorithms completely - these two have quite different semantics.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/copy_if.html">copy_if</a></code>, <code><a href="../Reference/copy_backward.html">copy_backward</a></code>, <code><a href="../Reference/copy_backward_if.html">copy_backward_if</a></code>, <code><a href="../Reference/fold.html">fold</a></code>, <code><a href="../Reference/fold_backward.html">fold_backward</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 19, 2002 2:10 am</body></html>
-70
View File
@@ -1,70 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::copy_backward</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>copy_backward</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename State
, typename BinaryOp
&gt;
struct copy_backward
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
<code>copy_backward</code> is, in fact, just another name for <code><a href="../Reference/fold_backward.html">fold_backward</a></code>. It was introduced for symmetry with <code><a href="../Reference/copy_backward_if.html">copy_backward_if</a></code> [<a href="#1">1</a>], and because it's a nice name for one of the typical <code>fold_backward</code> applications, that is, copying the content of one sequence into another - see the example below.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/copy_backward.hpp">boost/mpl/copy_backward.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>A sequence to iterate. </td></tr>
<tr><td><code>State</code></td><td>A type</td><td>The initial state for the first <code>BinaryOp</code> application. </td></tr>
<tr><td><code>BinaryOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on backward traversal. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef copy_backward&lt;Sequence,T,Op&gt;::type s;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef fold_backward&lt; Sequence,T,Op &gt;::type s;</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>BinaryOp</code>.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,10,11,12,13,14,15,16,17,18,19&gt;::type numbers;
typedef copy_backward&lt;
<a href="../Reference/range_c.html">range_c</a>&lt;int,0,10&gt;
, <a href="../Reference/push_front.html">push_front</a>&lt;_,_&gt;
, numbers
&gt;::type result;
<p>
BOOST_STATIC_ASSERT(<a href="../Reference/size.html">size</a>&lt;result&gt;::value == 20);
BOOST_STATIC_ASSERT((<a href="../Reference/equal.html">equal</a>&lt; result,<a href="../Reference/range_c.html">range_c</a>&lt;int,0,20&gt; &gt;::type::value));
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] In case if you wonder why <code><a href="../Reference/copy_backward_if.html">copy_backward_if</a></code>, in its turn, wasn't just called <code>fold_backward_if</code>, - something that would allow to eliminate the family of <code>copy_backward</code> algorithms completely - these two have quite different semantics.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/copy_backward_if.html">copy_backward_if</a></code>, <code><a href="../Reference/copy.html">copy</a></code>, <code><a href="../Reference/copy_if.html">copy_if</a></code>, <code><a href="../Reference/fold.html">fold</a></code>, <code><a href="../Reference/fold_backward.html">fold_backward</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 19, 2002 2:11 am</body></html>
-70
View File
@@ -1,70 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::copy_backward_if</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>copy_backward_if</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename State
, typename BinaryOp
, typename Pred
&gt;
struct copy_backward_if
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the result of the successive application of <code>BinaryOp</code> to the result of the previous <code>BinaryOp</code> invocation (<code>State</code> if it's the first call) and every element in the range <code>[begin&lt;Sequence&gt;::type,end&lt;Sequence&gt;::type)</code> that satisfies the predicate <code>Pred</code>, in the reverse order. A typical application for <code>copy_backward_if</code> is to conditionally copy the content of one sequence into another - see the example below.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/copy_backward_if.hpp">boost/mpl/copy_backward_if.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>A sequence to iterate. </td></tr>
<tr><td><code>State</code></td><td>A type</td><td>The initial state for the first <code>BinaryOp</code> application. </td></tr>
<tr><td><code>BinaryOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on backward traversal. </td></tr>
<tr><td><code>Pred</code></td><td>An unary Predicate [Lambda Expression]</td><td>The copying condition. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef copy_backward_if&lt;Sequence,T,Op,Pred&gt;::type s;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef lambda&lt;Op&gt;::type op; typedef lambda&lt;Pred&gt;::type pred; typedef fold_backward&lt; Sequence,T,if_&lt; apply&lt;pred,_2&gt;, apply&lt;op,_1,_2&gt;, _1 &gt; &gt;::type s;</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>Pred</code>, and at most <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>BinaryOp</code>.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,0,1,2,3,4,5,6,7,8,9&gt;::type numbers;
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,0,1,2,3,4&gt;::type answer;
typedef copy_backward_if&lt;
numbers
, <a href="../Reference/list_c.html">list_c</a>&lt;int&gt;
, <a href="../Reference/push_front.html">push_front</a>&lt;_1,_2&gt;
, <a href="../Reference/less.html">less</a>&lt;_1,int_&lt;5&gt; &gt;
&gt;::type result;
<p>
BOOST_STATIC_ASSERT(<a href="../Reference/size.html">size</a>&lt;result&gt;::value == 5);
BOOST_STATIC_ASSERT((<a href="../Reference/equal.html">equal</a>&lt;result,answer&gt;::type::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/copy_backward.html">copy_backward</a></code>, <code><a href="../Reference/copy_if.html">copy_if</a></code>, <code><a href="../Reference/copy.html">copy</a></code>, <code><a href="../Reference/fold.html">fold</a></code>, <code><a href="../Reference/fold_backward.html">fold_backward</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 12, 2003 6:29 am</body></html>
-70
View File
@@ -1,70 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::copy_if</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>copy_if</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename State
, typename BinaryOp
, typename Pred
&gt;
struct copy_if
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the result of the successive application of <code>BinaryOp</code> to the result of the previous <code>BinaryOp</code> invocation (<code>State</code> if it's the first call) and every element in the range <code>[begin&lt;Sequence&gt;::type,end&lt;Sequence&gt;::type)</code> that satisfies the predicate <code>Pred</code>, in the linear order. A typical application for <code>copy_if</code> is to conditionally copy the content of one sequence into another - see the example below.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/copy_if.hpp">boost/mpl/copy_if.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>A sequence to iterate. </td></tr>
<tr><td><code>State</code></td><td>A type</td><td>The initial state for the first <code>BinaryOp</code> application. </td></tr>
<tr><td><code>BinaryOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on forward traversal. </td></tr>
<tr><td><code>Pred</code></td><td>An unary Predicate [Lambda Expression]</td><td>The copying condition. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef copy_if&lt;Sequence,T,Op,Pred&gt;::type s;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef lambda&lt;Op&gt;::type op; typedef lambda&lt;Pred&gt;::type pred; typedef fold&lt; Sequence,T,if_&lt; apply&lt;pred,_2&gt;, apply&lt;op,_1,_2&gt;, _1 &gt; &gt;::type s;</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>Pred</code>, and at most <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>BinaryOp</code>.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,0,1,2,3,4,5,6,7,8,9&gt;::type numbers;
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,0,1,2,3,4&gt;::type answer;
typedef copy_if&lt;
numbers
, <a href="../Reference/vector_c.html">vector_c</a>&lt;int&gt;
, <a href="../Reference/push_back.html">push_back</a>&lt;_1,_2&gt;
, <a href="../Reference/less.html">less</a>&lt;_1,int_&lt;5&gt; &gt;
&gt;::type result;
<p>
BOOST_STATIC_ASSERT(<a href="../Reference/size.html">size</a>&lt;result&gt;::value == 5);
BOOST_STATIC_ASSERT((<a href="../Reference/equal.html">equal</a>&lt;result,answer&gt;::type::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/copy.html">copy</a></code>, <code><a href="../Reference/copy_backward_if.html">copy_backward_if</a></code>, <code><a href="../Reference/copy_backward.html">copy_backward</a></code>, <code><a href="../Reference/fold.html">fold</a></code>, <code><a href="../Reference/iter_fold.html">iter_fold</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 12, 2003 6:30 am</body></html>
-60
View File
@@ -1,60 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::count</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>count</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename T
&gt;
struct count
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the number of elements in a <code>Sequence</code> that are identical to <code>T</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/count.hpp">boost/mpl/count.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to be examined. </td></tr>
<tr><td><code>T</code></td><td>A type</td><td>The type to be searched for. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef count&lt;Sequence,T&gt;::type n;</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code>typedef <a href="../Reference/count_if.html">count_if</a>&lt; Sequence,is_same&lt;_,T&gt; &gt;::type n;</code></td><td></td></tr>
</table>
<p>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::value</code> comparisons for identity.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list.html">list</a>&lt;int,char,long,short,char,short,double,long&gt; types;
typedef find&lt;types, short&gt;::type iter;
BOOST_STATIC_ASSERT((is_same&lt;iter::type,short&gt;::type::value));
BOOST_STATIC_ASSERT((<a href="../Reference/distance.html">distance</a>&lt; begin&lt;types&gt;::type,iter &gt;::type::value == 3));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/count_if.html">count_if</a></code>, <code><a href="../Reference/find.html">find</a></code>, <code><a href="../Reference/find_if.html">find_if</a></code>, <code><a href="../Reference/contains.html">contains</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited December 12, 2002 2:05 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::count_if</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>count_if</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename Pred
&gt;
struct count_if
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the number of elements in a <code>Sequence</code> that satisfy the predicate <code>Pred</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/count_if.hpp">boost/mpl/count_if.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to be examined. </td></tr>
<tr><td><code>Pred</code></td><td>A model of Predicate [Lambda Expression]</td><td>The count condition. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef count_if&lt;Sequence,Pred&gt;::type n;</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code> typedef lambda&lt;Pred&gt;::type pred; typedef <a href="../Reference/fold.html">fold</a>&lt; Sequence,integral_c&lt;unsigned long,0&gt;,if_&lt;pred,next&lt;_1&gt;,_1&gt; &gt;::type n;</code></td><td></td></tr>
</table>
<p>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::value</code> applications of <code>Pred</code>.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list.html">list</a>&lt;int,char,long,short,char,long,double,long&gt; types;
<p>
BOOST_STATIC_ASSERT((count_if&lt; types,boost::is_float&lt;_&gt; &gt;::type::value == 1));
BOOST_STATIC_ASSERT((count_if&lt; types,boost::is_same&lt;_,char&gt; &gt;::type::value == 2));
BOOST_STATIC_ASSERT((count_if&lt; types,boost::is_same&lt;_,void&gt; &gt;::type::value == 0));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/count.html">count</a></code>, <code><a href="../Reference/find_if.html">find_if</a></code>, <code><a href="../Reference/find.html">find</a></code>, <code><a href="../Reference/contains.html">contains</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 4:32 am</body></html>
-56
View File
@@ -1,56 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::deref</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>deref</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Iterator
&gt;
struct deref
{
typedef typename Iterator::type type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Dereferences an iterator.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/deref.hpp">boost/mpl/deref.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Iterator</code></td><td>A model of <a href="../Trivial_Iterator.html">Trivial Iterator</a></td><td>An iterator to be dereferenced. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef deref&lt;Iterator&gt;::type t;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef Iterator::type t;</code>.</td><td><code>Iterator</code> is dereferenceable </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list.html">list</a>&lt;char,short,int,long&gt; types;
typedef <a href="../Reference/begin.html">begin</a>&lt;types&gt;::type iter;
BOOST_STATIC_ASSERT(boost::is_same&lt; deref&lt;iter&gt;::type,char &gt;::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Iterators.html">Iterators</a>, <code><a href="../Reference/begin.html">begin</a>/<a href="../Reference/end.html">end</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 5:30 am</body></html>
-56
View File
@@ -1,56 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::distance</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>distance</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename First
, typename Last
&gt;
struct distance
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Finds the distance between <code>First</code> and <code>Last</code>, that is, an <a href="../Integral_Constant.html">Integral Constant</a> <code>D</code> such as <code>advance&lt; First,D &gt;::type</code> is identical to <code>Last</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/distance.hpp">boost/mpl/distance.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>First</code>, <code>Last</code></td><td>A model of <a href="../Input_Iterator.html">Input Iterator</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef distance&lt;First,Last&gt;::type d;</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td><code>[First, Last)</code> is a valid range</td><td></td><td><code>is_same&lt; advance&lt; First,d &gt;::type, Last &gt;::value</code> </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time if <code>Iterator</code> is a model of <a href="../Random_Access_Iterator.html">Random Access Iterator</a>, otherwise linear time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef range_c&lt;int,0,10&gt;::type range;
BOOST_STATIC_ASSERT((distance&lt; begin&lt;range&gt;::type,end&lt;range&gt;::type &gt;::type::value == 10));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Iterators.html">Iterators</a>, <a href="../Sequence.html">Sequence</a>, <code><a href="../Reference/advance.html">advance</a></code>, <code><a href="../Reference/begin.html">begin</a></code>, <code><a href="../Reference/end.html">end</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 6:47 am</body></html>
-64
View File
@@ -1,64 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::divides</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>divides</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T1
, typename T2
, typename T3 = integral_c&lt;int,1&gt;
, ...
, typename Tn = integral_c&lt;int,1&gt;
&gt;
struct divides
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the quotient of its arguments [<a href="#1">1</a>].
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/divides.hpp">boost/mpl/divides.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>T1, T2, .., Tn</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef divides&lt;t1,t2,..,tn&gt;::type quot;</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td><code>t2::value != 0, t3::value != 0, .., tn::value != 0</code></td><td>Equivalent to <code>typedef integral_c&lt;typeof(t1::value / t2::value .. / tn::value), t1::value / t2::value .. / tn::value &gt; quot;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef divides&lt; integral_c&lt;short,-10&gt;, integral_c&lt;long,3&gt; &gt;::type quot;
BOOST_STATIC_ASSERT(quot::value == -3));
BOOST_MPL_ASSERT_IS_SAME(quot::value_type, long);
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The <code>divides</code> metafunction can be (and is expected to be) specialized by user to work on user-defined types that do not satisfy the <a href="../Integral_Constant.html">Integral Constant</a> requirements. The requirements listed here are the ones imposed by the default implementation.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Metafunctions.html">Metafunctions</a>, <code><a href="../Reference/multiplies.html">multiplies</a></code>, <code><a href="../Reference/modulus.html">modulus</a></code>, <code><a href="../Reference/plus.html">plus</a></code>, <code><a href="../Reference/minus.html">minus</a></code>, <code><a href="../Reference/negate.html">negate</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:32 am</body></html>
-59
View File
@@ -1,59 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::empty</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>empty</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
&gt;
struct empty
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns an <a href="../Integral_Constant.html">Integral Constant</a> <code>c</code> such that <code>c::value == true</code> if and only if the sequence is empty.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/empty.hpp">boost/mpl/empty.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef empty&lt;Sequence&gt;::type c;</code></td><td>A model of <code>bool</code> <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code>typedef is_same&lt; begin&lt;Sequence&gt;::type,end&lt;Sequence&gt;::type &gt;::type c;</code></td><td></td></tr>
</table>
<p>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef range_c&lt;int,0,0&gt; empty_range;
typedef list&lt;long,float,double&gt; types;
<p>
BOOST_STATIC_ASSERT(empty&lt;empty_range&gt;::value)
BOOST_STATIC_ASSERT(!empty&lt;types&gt;::value)
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Sequence.html">Sequence</a>, <code><a href="../Reference/size.html">size</a></code>, <code><a href="../Reference/begin.html">begin</a></code>, <code><a href="../Reference/end.html">end</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 3:52 am</body></html>
-57
View File
@@ -1,57 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::end</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>end</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
&gt;
struct end
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the past-the-end iterator to the sequence.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/begin_end.hpp">boost/mpl/begin_end.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition &nbsp;</th></tr>
<tr><td><code>typedef end&lt;Sequence&gt;::type last;</code></td><td>A model of <a href="../Input_Iterator.html">Input Iterator</a></td><td></td><td><code>last</code> is an iterator pointing one past the last element in the <code>Sequence</code>; equivalent to <code>Sequence::end</code> unless the algorithm has been specialized for the particular type of sequence.</td><td><code>last</code> is past-the-end. </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list.html">list</a>&lt;long&gt; short_list;
typedef <a href="../Reference/begin.html">begin</a>&lt;short_list&gt;::type first;
typedef end&lt;short_list&gt;::type last;
BOOST_STATIC_ASSERT((boost::is_same&lt;first::next,last&gt;::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Iterators.html">Iterators</a>, <a href="../Sequence.html">Sequence</a>, <code><a href="../Reference/begin.html">begin</a></code>, <code><a href="../Reference/size.html">size</a></code>, <code><a href="../Reference/empty.html">empty</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 22, 2002 4:30 pm</body></html>
-59
View File
@@ -1,59 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::equal</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>equal</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence1
, typename Sequence2
, typename Pred = is_same&lt;_1,_2&gt;
&gt;
struct equal
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns <code>true_</code> if the two sequences <code>Sequence1</code> and <code>Sequence2</code> are identical when compared element-by-element, and otherwise returns <code>false_</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/equal.hpp">boost/mpl/equal.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence1</code>, <code>Sequence2</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>Sequences to compare. </td></tr>
<tr><td><code>Pred</code></td><td>A binary Predicate [Lambda Expression]</td><td>The comparison metafunction. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef equal&lt;Sequence1,Sequence2,Pred&gt;::type c;</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td><code>c::value == true</code> is and only if <code>size&lt;Sequence1&gt;::type::value == size&lt;Sequence2&gt;::type::value</code> and for every iterator <code>i</code> in <code>[begin&lt;Sequence&gt;::type,end&lt;Sequence&gt;::type)</code> <code>i::type</code> is identical to <code>advance&lt; begin&lt;Sequence2&gt;::type, distance&lt; begin&lt;Sequence1&gt;::type,i &gt;::type &gt;::type</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. At most <code>size&lt;Sequence1&gt;::value</code> comparisons.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/vector.html">vector</a>&lt;char,int,unsigned,long,unsigned long&gt; s1;
typedef <a href="../Reference/list.html">list</a>&lt;char,int,unsigned,long,unsigned long&gt; s2;
BOOST_STATIC_ASSERT((equal&lt;s1,s2&gt;::type::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/count.html">count</a></code>, <code><a href="../Reference/count_if.html">count_if</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 5:39 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::equal_to</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>equal_to</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T1
, typename T2
&gt;
struct equal_to
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns <code>true_</code> if <code>T1::value == T2::value</code> and <code>false_</code> otherwise [<a href="#1">1</a>].
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/equal_to.hpp">boost/mpl/equal_to.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>T1, T2</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef equal_to&lt;t1,t2&gt;::type c;</code></td><td>A model of <code>bool</code> <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code>typedef bool_&lt;(t1::value == t2::value)&gt; c;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,1,2,3,5,7,12,19,31&gt; fibonacci;
typedef <a href="../Reference/find_if.html">find_if</a>&lt; fibonacci, equal_to&lt;_1,int_&lt;12&gt; &gt; &gt;::type iter;
BOOST_STATIC_ASSERT(equal_to&lt; <a href="../Reference/distance.html">distance</a>&lt; <a href="../Reference/begin.html">begin</a>&lt;fibonacci&gt;::type, iter &gt;::type, int_&lt;5&gt; &gt;::type::value));
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The <code>equal_to</code> metafunction can be (and is expected to be) specialized by user to work on user-defined types that do not satisfy the <a href="../Integral_Constant.html">Integral Constant</a> requirements. The requirements listed here are the ones imposed by the default implementation.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Metafunctions.html">Metafunctions</a>, <code><a href="../Reference/not_equal_to.html">not_equal_to</a></code>, <code><a href="../Reference/less.html">less</a></code>, <code><a href="../Reference/less_equal.html">less_equal</a></code>, <code><a href="../Reference/greater.html">greater</a></code>, <code><a href="../Reference/greater_equal.html">greater_equal</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:26 am</body></html>
-65
View File
@@ -1,65 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::erase</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>erase</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename First
, typename Last = typename First::next
&gt;
struct erase
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
<code>erase</code> performs a removal of one or several consequent elements in the sequence starting from an arbitrary position. The algorithm returns a new sequence which contains all the elements in the ranges <code>[begin&lt;Sequence&gt;::type, First)</code> and <code>[Last, end&lt;Sequence&gt;::type)</code>. The result sequence preserves all the functional and performance characteristics of the original <code>Sequence</code>, except its size and identity.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/erase.hpp">boost/mpl/erase.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description&nbsp;</th><th>&nbsp;Default value &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Extensible_Sequence.html">Extensible Sequence</a></td><td>A sequence to handle the erase operation.</td><td></td></tr>
<tr><td><code>First</code></td><td>A model of <a href="../Forward_Iterator.html">Forward Iterator</a></td><td>Iterator to the beginning of the range to be erased.</td><td></td></tr>
<tr><td><code>Last</code></td><td>A model of <a href="../Forward_Iterator.html">Forward Iterator</a></td><td>Past-the-end iterator of the range to be erased.</td><td><code>typename First::next</code> </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef erase&lt;Sequence,pos&gt;::type s;</code></td><td>A model of <a href="../Extensible_Sequence.html">Extensible Sequence</a></td><td><code>pos</code> is a dereferenceable iterator in <code>Sequence</code>.</td><td>Returns a new sequence which contains all the elements in the ranges <code>[begin&lt;Sequence&gt;::type, pos)</code> and <code>[next&lt;pos&gt;::type, end&lt;Sequence&gt;::type)</code>.</td><td><code>size&lt;s&gt;::type::value == size&lt;Sequence&gt;::type::value - 1</code>; the relative order of the elements in <code>s</code> is the same as in <code>Sequence</code>. </td></tr>
<tr><td><code>typedef erase&lt;Sequence,first,last&gt;::type s;</code></td><td>A model of <a href="../Extensible_Sequence.html">Extensible Sequence</a></td><td><code>[first,last)</code> is a valid range in <code>Sequence</code>.</td><td>Returns a new sequence which contains all the elements in the ranges <code>[begin&lt;Sequence&gt;::type, first)</code> and <code>[last, end&lt;Sequence&gt;::type)</code>.</td><td><code>size&lt;s&gt;::type::value == size&lt;Sequence&gt;::type::value - distance&lt;first,last&gt;::type::value</code>; the relative order of the elements in <code>s</code> is the same as in <code>Sequence</code>. </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
The range form has linear complexity. The complexity of single-element erase is sequence dependent (linear in the worst case, or amortized constant time).
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,1,0,5,1,7,5,0,5&gt; values;
typedef <a href="../Reference/find.html">find</a>&lt; values, integral_c&lt;int,7&gt; &gt;::type pos;
typedef erase&lt;values,pos&gt;::type result_seq;
BOOST_STATIC_ASSERT(<a href="../Reference/size.html">size</a>&lt;result_seq&gt;::type::value == 7);
<p>
typedef find&lt;result, integral_c&lt;int,7&gt; &gt;::type result_iter;
BOOST_MPL_ASSERT_IS_SAME(result_iter, <a href="../Reference/end.html">end</a>&lt;result_seq&gt;::type);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Extensible_Sequence.html">Extensible Sequence</a>, <code><a href="../Reference/pop_front.html">pop_front</a></code>, <code><a href="../Reference/pop_back.html">pop_back</a></code>, <code><a href="../Reference/insert.html">insert</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 3:59 am</body></html>
-63
View File
@@ -1,63 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::erase_range</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>erase_range</h1><h3>Synopsis
</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename First
, typename Last
&gt;
struct erase_range
{
typedef <em>implementation-defined</em> type;
};
</pre>
<p>
<h3>Description
</h3>
<p>
[to do]
<p>
<h3>Definition
</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/erase_range.hpp">boost/mpl/erase_range.hpp</a>"
</pre>
<p>
<h3>Parameters
</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description&nbsp;</th><th>&nbsp;Default argument &nbsp;</th></tr>
<tr><td><code>Param</code></td><td>A model of Concept</td><td>[to do]</td><td>[to do] </td></tr>
</table>
<p>
<h3>Members
</h3>
<table border="1">
<tr><th>&nbsp;Member&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>type</code></td><td>[to do] </td></tr>
</table>
<p>
<h3>Complexity
</h3>
<p>
[to do]
<p>
<h3>Example
</h3>
<p>
<pre>
[to do]
</pre>
<p>
<h3>See also
</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/erase.html">erase</a></code>, <code>erase_all</code>, <code>erase_if</code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited February 19, 2002 3:55 am</body></html>
-63
View File
@@ -1,63 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::filter_view</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>filter_view</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename Pred
&gt;
struct filter_view
{
<span class="cxx-comment">// unspecified</span>
};
</pre>
<p>
<h3>Description</h3>
<p>
<code>filter_view</code> is a sequence wrapper that allows one to operate on the filtered sequence without actually creating one.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/filter_view.hpp">boost/mpl/filter_view.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>A sequence to wrap. </td></tr>
<tr><td><code>Pred</code></td><td>A model of unary Predicate [Lambda Expression]</td><td>A filtering predicate. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef filter_view&lt;Sequence,Pred&gt; s;</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td></td><td><code>s</code> prodives iterators to all the elements in the range <code>[<a href="../Reference/begin.html">begin</a>&lt;Sequence&gt;::type,<a href="../Reference/end.html">end</a>&lt;Sequence&gt;::type)</code> that satisfy the predicate <code>Pred</code>.</td><td><code><a href="../Reference/size.html">size</a>&lt;s&gt;::type::value == <a href="../Reference/count_if.html">count_if</a>&lt; Sequence,Pred &gt;::type::value</code>. </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
Finds the largest floating type in a sequence.
<p>
<pre>
typedef <a href="../Reference/list.html">list</a>&lt;int,float,long,float,char[50],long double,char&gt; types;
typedef <a href="../Reference/max_element.html">max_element</a>&lt;
<a href="../Reference/transform_view.html">transform_view</a>&lt; filter_view&lt; types,boost::is_float&lt;_&gt; &gt;, size_of&lt;_&gt; &gt;
&gt;::type iter;
<p>
BOOST_STATIC_ASSERT((is_same&lt;iter::base::type,long double&gt;::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Sequences.html">Sequences</a>, <code><a href="../Reference/transform_view.html">transform_view</a></code>, <code><a href="../Reference/joint_view.html">joint_view</a></code>, <code><a href="../Reference/zip_view.html">zip_view</a></code>, <code><a href="../Reference/max_element.html">max_element</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 4:42 am</body></html>
-58
View File
@@ -1,58 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::find</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>find</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename T
&gt;
struct find
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Finds the first occurrence of type <code>T</code> in a <code>Sequence</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/find.hpp">boost/mpl/find.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to search in. </td></tr>
<tr><td><code>T</code></td><td>A type</td><td>The type to search for. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef find&lt;Sequence,T&gt;::type i;</code></td><td>A model of <a href="../Forward_Iterator.html">Forward Iterator</a></td><td></td><td>Equivalent to <code>typedef <a href="../Reference/find_if.html">find_if</a>&lt;Sequence, is_same&lt;_,T&gt; &gt;::type i</code>; </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. At most <code>size&lt;Sequence&gt;::value</code> comparisons for identity.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/vector.html">vector</a>&lt;char,int,unsigned,long,unsigned long&gt; types;
typedef find&lt;types,unsigned&gt;::type iter;
BOOST_STATIC_ASSERT(iter::pos::value == 2);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/find_if.html">find_if</a></code>, <code><a href="../Reference/contains.html">contains</a></code>, <code><a href="../Reference/count.html">count</a></code>, <code><a href="../Reference/count_if.html">count_if</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited September 15, 2002 7:24 pm</body></html>
-58
View File
@@ -1,58 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::find_if</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>find_if</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename Pred
&gt;
struct find_if
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Finds the first element in a <code>Sequence</code> that satisfies the predicate <code>Pred</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/find_if.hpp">boost/mpl/find_if.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to search in. </td></tr>
<tr><td><code>Pred</code></td><td>A model of Predicate [Lambda Expression]</td><td>A search condition. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef find_if&lt;Sequence,Pred&gt;::type i;</code></td><td>A model of <a href="../Forward_Iterator.html">Forward Iterator</a></td><td></td><td><code>i</code> is the first iterator in the range <code>[begin&lt;Sequence&gt;::type, end&lt;Sequence&gt;::type)</code> such that <code>apply&lt; lambda&lt;Pred&gt;::type,i::type &gt;::type::value == true</code>; <code>i</code> is identical to <code>end&lt;Sequence&gt;::type</code>, if no such iterator exists.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. At most <code>size&lt;Sequence&gt;::value</code> applications of <code>Pred</code>.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/vector.html">vector</a>&lt;char,int,unsigned,long,unsigned_long&gt; types;
typedef find_if&lt;types, is_same&lt;_1,unsigned&gt; &gt;::type iter;
BOOST_STATIC_ASSERT(iter::pos::value == 2);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/find.html">find</a></code>, <code><a href="../Reference/contains.html">contains</a></code>, <code><a href="../Reference/count.html">count</a></code>, <code><a href="../Reference/count_if.html">count_if</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited September 15, 2002 7:24 pm</body></html>
-65
View File
@@ -1,65 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::fold</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>fold</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename State
, typename ForwardOp
&gt;
struct fold
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the result of the successive application of binary <code>ForwardOp</code> to the result of the previous <code>ForwardOp</code> invocation (<code>State</code> if it's the first call) and every element of the sequence in the range <code>[begin&lt;Sequence&gt;::type,end&lt;Sequence&gt;::type)</code> in the linear order.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/fold.hpp">boost/mpl/fold.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>A sequence to iterate. </td></tr>
<tr><td><code>State</code></td><td>A type</td><td>The initial state for the first <code>ForwardOp</code> application. </td></tr>
<tr><td><code>ForwardOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on forward traversal. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef fold&lt;Sequence,T,Op&gt;::type t;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef lambda&lt;Op&gt;::type op; typedef iter_fold&lt; Sequence,T,apply&lt;op,_1,deref&lt;_2&gt; &gt; &gt;::type t;</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>ForwardOp</code>.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/vector.html">vector</a>&lt;long,float,short,double,float,long,long double&gt; types;
typedef typename fold&lt;
types
, integral_c&lt;long, 0&gt;
, if_&lt; is_float&lt;_2&gt;,next&lt;_1&gt;,_1 &gt;
&gt;::type number_of_floats;
<p>
BOOST_STATIC_ASSERT(number_of_floats::value == 4);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/fold_backward.html">fold_backward</a></code>, <code><a href="../Reference/iter_fold.html">iter_fold</a></code>, <code><a href="../Reference/iter_fold_backward.html">iter_fold_backward</a></code>, <code><a href="../Reference/copy.html">copy</a></code>, <code><a href="../Reference/copy_if.html">copy_if</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited December 12, 2002 4:42 pm</body></html>
-75
View File
@@ -1,75 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::fold_backward</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>fold_backward</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename State
, typename BackwardOp
, typename ForwardOp = _1
&gt;
struct fold_backward
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the result of the successive application of binary <code>BackwardOp</code> to the result of the previous <code>BackwardOp</code> invocation (<code>State</code> if it's the first call) and every element in the range <code>[begin&lt;Sequence&gt;::type,end&lt;Sequence&gt;::type)</code> in the reverse order. If <code>ForwardOp</code> is provided, then it's applied on forward traversal to form the result which is passed to the first <code>BackwardOp</code> call.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/fold_backward.hpp">boost/mpl/fold_backward.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description&nbsp;</th><th>&nbsp;Default value &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>A sequence to iterate.</td><td></td></tr>
<tr><td><code>State</code></td><td>A type</td><td>The initial state for the first <code>BackwardOp</code>/<code>ForwardOp</code> application.</td><td></td></tr>
<tr><td><code>BackwardOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on backward traversal.</td><td></td></tr>
<tr><td><code>ForwardOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on forward traversal.</td><td><code>arg&lt;1&gt;</code> </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef fold_backward&lt; Sequence,T,BackwardOp &gt;::type t;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef lambda&lt;BackwardOp&gt;::type bk_op; typedef begin&lt;Sequence&gt;::type i1; typedef i1::next i2; ...; typedef in::next last; typedef apply&lt;bk_op,T,in::type&gt;::type tn; typedef apply&lt;bk_op,tn,in-1::type&gt;::type tn-1; ...; typedef apply&lt;bk_op,t2,i1::type&gt;::type t1; typedef t1 t</code>, where <code>n == size&lt;Sequence&gt;::type::value</code> and <code>last</code> is identical to <code>end&lt;Sequence&gt;::type</code>; Equivalent to <code>typedef T t;</code> if the sequence is empty.</td><td></td></tr>
<tr><td><code>typedef fold_backward&lt; Sequence,T,BackwardOp,ForwardOp &gt;::type t;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef fold_backward&lt;Sequence, fold&lt;Sequence,State,ForwardOp&gt;::type, BackwardOp&gt;::type t;</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>BackwardOp</code> and <code>ForwardOp</code>.
<p>
<h3>Example</h3>
<p>
Removes negative elements from a sequence [<a href="#1">1</a>].
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,5,-1,0,-7,-2,0,-5,4&gt; numbers;
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,-1,-7,-2,-5&gt; negatives;
typedef fold_backward&lt;
numbers
, <a href="../Reference/list_c.html">list_c</a>&lt;int&gt;
, if_&lt; <a href="../Reference/less.html">less</a>&lt; _2,int_&lt;0&gt; &gt;, push_front&lt;_1,_2,&gt;, _1 &gt;
&gt;::type result;
<p>
BOOST_STATIC_ASSERT(<a href="../Reference/equal.html">equal</a>&lt; negatives,result &gt;::type::value);
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] See <code><a href="../Reference/remove_if.html">remove_if</a></code> for a more compact way to do this.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/fold.html">fold</a></code>, <code><a href="../Reference/iter_fold_backward.html">iter_fold_backward</a></code>, <code><a href="../Reference/iter_fold.html">iter_fold</a></code>, <code><a href="../Reference/copy.html">copy</a></code>, <code><a href="../Reference/copy_backward.html">copy_backward</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 12, 2003 6:30 am</body></html>
-60
View File
@@ -1,60 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::front</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>front</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
&gt;
struct front
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns a type identical to the first element in the sequence.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/front.hpp">boost/mpl/front.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to be examined. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef front&lt;Sequence&gt;::type t;</code></td><td>A type</td><td><code>empty&lt;Sequence&gt;::type::value == false</code></td><td>Equivalent to <code>typedef begin&lt;Sequence&gt;::type::type t;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list.html">list</a>&lt;long&gt;::type types1;
typedef list&lt;int,long&gt;::type types2;
typedef list&lt;char,int,long&gt;::type types3;
<p>
BOOST_MPL_ASSERT_IS_SAME(front&lt;types1&gt;::type, long);
BOOST_MPL_ASSERT_IS_SAME(front&lt;types2&gt;::type, int);
BOOST_MPL_ASSERT_IS_SAME(front&lt;types3&gt;::type, char);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Forward_Sequence.html">Forward Sequence</a>, <code><a href="../Reference/back.html">back</a></code>, <code><a href="../Reference/at.html">at</a></code>, <code><a href="../Reference/push_front.html">push_front</a></code>, <code><a href="../Reference/begin.html">begin</a></code>, <code><a href="../Reference/empty.html">empty</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 3:48 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::greater</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>greater</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T1
, typename T2
&gt;
struct greater
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns <code>true_</code> if <code>T1::value &gt; T2::value</code> and <code>false_</code> otherwise [<a href="#1">1</a>].
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/greater.hpp">boost/mpl/greater.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>T1, T2</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef greater&lt;t1,t2&gt;::type c;</code></td><td>A model of <code>bool</code> <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code>typedef bool_&lt;(t1::value &gt; t2::value)&gt; c;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,1,2,3,5,7,12,19,31&gt; fibonacci;
typedef <a href="../Reference/find_if.html">find_if</a>&lt; fibonacci, greater&lt;_1,int_&lt;10&gt; &gt; &gt;::type iter;
BOOST_STATIC_ASSERT(iter::type::value == 12));
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The <code>greater</code> metafunction can be (and is expected to be) specialized by user to work on user-defined types that do not satisfy the <a href="../Integral_Constant.html">Integral Constant</a> requirements. The requirements listed here are the ones imposed by the default implementation.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Metafunctions.html">Metafunctions</a>, <code><a href="../Reference/greater_equal.html">greater_equal</a></code>, <code><a href="../Reference/less.html">less</a></code>, <code><a href="../Reference/less_equal.html">less_equal</a></code>, <code><a href="../Reference/equal_to.html">equal_to</a></code>, <code><a href="../Reference/not_equal_to.html">not_equal_to</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:24 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::greater_equal</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>greater_equal</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T1
, typename T2
&gt;
struct greater_equal
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns <code>true_</code> if <code>T1::value &gt; T2::value</code> and <code>false_</code> otherwise [<a href="#1">1</a>].
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/greater_equal.hpp">boost/mpl/greater_equal.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>T1, T2</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef greater_equal&lt;t1,t2&gt;::type c;</code></td><td>A model of <code>bool</code> <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code>typedef bool_&lt;(t1::value &gt;= t2::value)&gt; c;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,0,1,2,3,4,5,6,7,8,9&gt; numbers;
typedef <a href="../Reference/remove_if.html">remove_if</a>&lt; numbers, greater_equal&lt;_1,int_&lt;5&gt; &gt; &gt;::type result;
BOOST_STATIC_ASSERT(<a href="../Reference/equal.html">equal</a>&lt; result,<a href="../Reference/range_c.html">range_c</a>&lt;int,0,5&gt; &gt;::type::value));
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The <code>greater_equal</code> metafunction can be (and is expected to be) specialized by user to work on user-defined types that do not satisfy the <a href="../Integral_Constant.html">Integral Constant</a> requirements. The requirements listed here are the ones imposed by the default implementation.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Metafunctions.html">Metafunctions</a>, <code><a href="../Reference/greater.html">greater</a></code>, <code><a href="../Reference/less.html">less</a></code>, <code><a href="../Reference/less_equal.html">less_equal</a></code>, <code><a href="../Reference/equal_to.html">equal_to</a></code>, <code><a href="../Reference/not_equal_to.html">not_equal_to</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:25 am</body></html>
-62
View File
@@ -1,62 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::insert</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>insert</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename Pos
, typename T
&gt;
struct insert
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
<code>insert</code> performs an insertion of type <code>T</code> at an arbitrary position in the sequence. The algorithm returns a new sequence which contains all the elements from <code>Sequence</code> plus the type <code>T</code> at the <code>distance&lt; begin&lt;Sequence&gt;::type,Pos &gt;::type</code> position from the beginning. The result sequence preserves all the functional and performance characteristics of the original <code>Sequence</code>, except its size and identity.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/insert.hpp">boost/mpl/insert.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Extensible_Sequence.html">Extensible Sequence</a></td><td>A sequence to handle the insert operation. </td></tr>
<tr><td><code>Pos</code></td><td>A model of <a href="../Forward_Iterator.html">Forward Iterator</a></td><td>An insert position in the <code>Sequence</code>. </td></tr>
<tr><td><code>T</code></td><td>A type</td><td>The element to be inserted. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef insert&lt;Sequence,pos,T&gt;::type s;</code></td><td>A model of <a href="../Extensible_Sequence.html">Extensible Sequence</a></td><td><code>pos</code> is a valid iterator in <code>Sequence</code>.</td><td><code>s</code> contains <code>T</code> at the <code>distance&lt; begin&lt;Sequence&gt;::type,pos &gt;::type</code> position.</td><td><code>size&lt;s&gt;::type::value == size&lt;Sequence&gt;::type::value + 1</code>; <code>at&lt; distance&lt; begin&lt;Sequence&gt;::type,pos &gt;::type, s &gt;::type</code> is identical to <code>T</code>; the relative order of the elements in <code>s</code> is the same as in <code>Sequence</code>. </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Sequence dependent. Linear in the worst case, or amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,0,1,3,4,5,6,7,8,9&gt; numbers;
typedef <a href="../Reference/find.html">find</a>&lt; numbers,integral_c&lt;int,3&gt; &gt;::type pos;
typedef insert&lt; numbers,pos,integral_c&lt;int,2&gt; &gt;::type range;
BOOST_STATIC_ASSERT(<a href="../Reference/size.html">size</a>&lt;range&gt;::type::value == 10);
BOOST_STATIC_ASSERT((<a href="../Reference/equal.html">equal</a>&lt; range,<a href="../Reference/range_c.html">range_c</a>&lt;int,0,10&gt; &gt;::type::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Extensible_Sequence.html">Extensible Sequence</a>, <code><a href="../Reference/insert_range.html">insert_range</a></code>, <code><a href="../Reference/push_front.html">push_front</a></code>, <code><a href="../Reference/push_back.html">push_back</a></code>, <code><a href="../Reference/erase.html">erase</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 5:17 am</body></html>
-62
View File
@@ -1,62 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::insert_range</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>insert_range</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename Pos
, typename Range
&gt;
struct insert_range
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
<code>insert_range</code> performs an insertion of a range of elements at an arbitrary position in the sequence. The algorithm returns a new sequence which contains all the elements of <code>Sequence</code> plus all the elements of <code>Range</code> starting at the <code>distance&lt; begin&lt;Sequence&gt;::type,Pos &gt;::type</code> position from the beginning. The result sequence preserves all the functional and performance characteristics of the original <code>Sequence</code>, except its size and identity.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/insert_range.hpp">boost/mpl/insert_range.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Extensible_Sequence.html">Extensible Sequence</a></td><td>A sequence to handle the insert operation. </td></tr>
<tr><td><code>Pos</code></td><td>A model of <a href="../Forward_Iterator.html">Forward Iterator</a></td><td>An insert position in the <code>Sequence</code>. </td></tr>
<tr><td><code>Range</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>The range of elements to be inserted. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition &nbsp;</th></tr>
<tr><td><code>typedef insert&lt;Sequence,pos,range&gt;::type s;</code></td><td>A model of <a href="../Extensible_Sequence.html">Extensible Sequence</a></td><td><code>pos</code> is a valid iterator in <code>Sequence</code>.</td><td><code>s</code> contains all the elements from <code>range</code> starting at the <code>distance&lt; begin&lt;Sequence&gt;::type,pos &gt;::type</code> position.</td><td><code>size&lt;s&gt;::type::value == size&lt;Sequence&gt;::type::value + size&lt;range&gt;::type::value</code>; the relative order of the elements in <code>s</code> is the same as in <code>Sequence</code>. </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,0,1,7,8,9&gt; numbers;
typedef <a href="../Reference/find.html">find</a>&lt; numbers,integral_c&lt;int,7&gt; &gt;::type pos;
typedef insert_range&lt; numbers,pos,<a href="../Reference/range_c.html">range_c</a>&lt;int,2,7&gt; &gt;::type range;
BOOST_STATIC_ASSERT(<a href="../Reference/size.html">size</a>&lt;range&gt;::type::value == 10);
BOOST_STATIC_ASSERT((<a href="../Reference/equal.html">equal</a>&lt; range,<a href="../Reference/range_c.html">range_c</a>&lt;int,0,10&gt; &gt;::type::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Extensible_Sequence.html">Extensible Sequence</a>, <code><a href="../Reference/insert.html">insert</a></code>, <code><a href="../Reference/push_front.html">push_front</a></code>, <code><a href="../Reference/push_back.html">push_back</a></code>, <code><a href="../Reference/erase.html">erase</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 22, 2002 4:32 pm</body></html>
-65
View File
@@ -1,65 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::iter_fold</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>iter_fold</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename State
, typename ForwardOp
&gt;
struct iter_fold
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the result of the successive application of binary <code>ForwardOp</code> to the result of the previous <code>ForwardOp</code> invocation (<code>State</code> if it's the first call) and each iterator in the range <code>[begin&lt;Sequence&gt;::type,end&lt;Sequence&gt;::type)</code> in the linear order.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/iter_fold.hpp">boost/mpl/iter_fold.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>A sequence to iterate. </td></tr>
<tr><td><code>State</code></td><td>A type</td><td>The initial state for the first <code>ForwardOp</code> application. </td></tr>
<tr><td><code>ForwardOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on forward traversal. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef iter_fold&lt;Sequence,T,Op&gt;::type t;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef lambda&lt;Op&gt;::type op; typedef begin&lt;Sequence&gt;::type i1; typedef apply&lt;op,T,i1&gt;::type t1; typedef i1::next i2; typedef apply&lt;op,t1,i2&gt;::type t2; ...; typedef apply&lt;op,T,in&gt;::type tn; typedef in::next last; typedef tn t</code>, where <code>n == size&lt;Sequence&gt;::type::value</code> and <code>last</code> is identical to <code>end&lt;Sequence&gt;::type</code>; Equivalent to <code>typedef T t;</code> if the sequence is empty.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>ForwardOp</code>.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,5,-1,0,7,2,0,-5,4&gt; numbers;
typedef iter_fold&lt;
numbers
, <a href="../Reference/begin.html">begin</a>&lt;numbers&gt;::type
, if_&lt; <a href="../Reference/less.html">less</a>&lt; <a href="../Reference/deref.html">deref</a>&lt;_1&gt;, <a href="../Reference/deref.html">deref</a>&lt;_2&gt; &gt;,_2,_1 &gt;
&gt;::type max_element_iter;
<p>
BOOST_STATIC_ASSERT(max_element_iter::type::value == 7);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/iter_fold_backward.html">iter_fold_backward</a></code>, <code><a href="../Reference/fold.html">fold</a></code>, <code><a href="../Reference/fold_backward.html">fold_backward</a></code>, <code><a href="../Reference/copy.html">copy</a></code>, <code><a href="../Reference/copy_backward.html">copy_backward</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 19, 2002 1:16 am</body></html>
-71
View File
@@ -1,71 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::iter_fold_backward</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>iter_fold_backward</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename State
, typename BackwardOp
, typename ForwardOp = _1
&gt;
struct iter_fold_backward
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the result of the successive application of binary <code>BackwardOp</code> to the result of the previous <code>BackwardOp</code> invocation (<code>State</code> if it's the first call) and each iterator in the range <code>[begin&lt;Sequence&gt;::type,end&lt;Sequence&gt;::type)</code> in the reverse order. If <code>ForwardOp</code> is provided, then it's applied on forward traversal to form the result which is passed to the first <code>BackwardOp</code> call.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/iter_fold_backward.hpp">boost/mpl/iter_fold_backward.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description&nbsp;</th><th>&nbsp;Default value &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>A sequence to iterate.</td><td></td></tr>
<tr><td><code>State</code></td><td>A type</td><td>The initial state for the first <code>BackwardOp</code>/<code>ForwardOp</code> application.</td><td></td></tr>
<tr><td><code>BackwardOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on backward traversal.</td><td></td></tr>
<tr><td><code>ForwardOp</code></td><td>A model of [Lambda Function]</td><td>The operation to be executed on forward traversal.</td><td><code>arg&lt;1&gt;</code> </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef iter_fold_backward&lt; Sequence,T,BackwardOp &gt;::type t;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef lambda&lt;BackwardOp&gt;::type bk_op; typedef begin&lt;Sequence&gt;::type i1; typedef i1::next i2; ...; typedef in::next last; typedef apply&lt;bk_op,T,in&gt;::type tn; typedef apply&lt;bk_op,tn,in-1&gt;::type tn-1; ...; typedef apply&lt;bk_op,t2,i1&gt;::type t1; typedef t1 t</code>, where <code>n == size&lt;Sequence&gt;::type::value</code> and <code>last</code> is identical to <code>end&lt;Sequence&gt;::type</code>; Equivalent to <code>typedef T t;</code> if the sequence is empty.</td><td></td></tr>
<tr><td><code>typedef iter_fold_backward&lt; Sequence,T,BackwardOp,ForwardOp &gt;::type t;</code></td><td>A type</td><td></td><td>Equivalent to <code>typedef iter_fold_backward&lt;Sequence, iter_fold&lt;Sequence,State,ForwardOp&gt;::type, BackwardOp&gt;::type t;</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Exactly <code><a href="../Reference/size.html">size</a>&lt;Sequence&gt;::type::value</code> applications of <code>BackwardOp</code> and <code>ForwardOp</code>.
<p>
<h3>Example</h3>
<p>
Builds a list of iterators to the negative elements in a sequence.
<p>
<pre>
typedef <a href="../Reference/vector_c.html">vector_c</a>&lt;int,5,-1,0,-7,-2,0,-5,4&gt; numbers;
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,-1,-7,-2,-5&gt; negatives;
typedef iter_fold_backward&lt;
numbers
, <a href="../Reference/list.html">list</a>&lt;&gt;
, if_&lt; <a href="../Reference/less.html">less</a>&lt; <a href="../Reference/deref.html">deref</a>&lt;_2&gt;,int_&lt;0&gt; &gt;, push_front&lt;_1,_2&gt;, _1 &gt;
&gt;::type iters;
<p>
BOOST_STATIC_ASSERT(<a href="../Reference/equal.html">equal</a>&lt; negatives, <a href="../Reference/transform_view.html">transform_view</a>&lt; iters,<a href="../Reference/deref.html">deref</a>&lt;_1&gt; &gt; &gt;::type::value);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/iter_fold.html">iter_fold</a></code>, <code><a href="../Reference/fold_backward.html">fold_backward</a></code>, <code><a href="../Reference/fold.html">fold</a></code>, <code><a href="../Reference/copy.html">copy</a></code>, <code><a href="../Reference/copy_backward.html">copy_backward</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 12, 2003 6:31 am</body></html>
-62
View File
@@ -1,62 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::iterator_category</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>iterator_category</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Iterator
&gt;
struct iterator_category
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns one of the following iterator category tags: <code>input_iterator_tag</code>, <code>forward_iterator_tag</code>, <code>bidirectional_iterator_tag</code>, or <code>random_access_iterator_tag</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/iterator_category.hpp">boost/mpl/iterator_category.hpp</a>"
#include "<a href="../../../../../boost/mpl/iterator_tag.hpp">boost/mpl/iterator_tag.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Iterator</code></td><td>A model of <a href="../Input_Iterator.html">Input Iterator</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition &nbsp;</th></tr>
<tr><td><code>typedef iterator_category&lt;Iterator&gt;::type tag;</code></td><td>An iterator category tag</td><td></td><td><code>tag</code> is <code>input_iterator_tag</code> if <code>Iterator</code> is a model of <a href="../Input_Iterator.html">Input Iterator</a>, <code>forward_iterator_tag</code> if <code>Iterator</code> is a model of <a href="../Forward_Iterator.html">Forward Iterator</a>, <code>bidirectional_iterator_tag</code> if <code>Iterator</code> is a model of <a href="../Bidirectional_Iterator.html">Bidirectional Iterator</a>, or <code>random_access_iterator_tag</code> if <code>Iterator</code> is a model of <a href="../Random_Access_Iterator.html">Random Access Iterator</a>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
template&lt; typename Iterator &gt;
struct my_algorithm
: my_algorithm_impl&lt;
iterator_category&lt;Iterator&gt;::type
, Iterator
&gt;
{
};
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Iterators.html">Iterators</a>, <a href="../Sequence.html">Sequence</a>, <code><a href="../Reference/begin.html">begin</a></code>, <code><a href="../Reference/end.html">end</a></code>, <code><a href="../Reference/advance.html">advance</a></code>, <code><a href="../Reference/distance.html">distance</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 6:20 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::joint_view</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>joint_view</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence1
, typename Sequence2
&gt;
struct joint_view
{
<span class="cxx-comment">// unspecified</span>
};
</pre>
<p>
<h3>Description</h3>
<p>
<code>joint_view</code> is a two-sequence view that allows one to operate on a sequence of concatenated elements of sequences <code>Sequence1</code> and <code>Sequence2</code> without actually creating one.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/joint_view.hpp">boost/mpl/joint_view.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence1</code>, <code>Sequence2</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td>Sequences to concatenate. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef joint_view&lt;Sequence1,Sequence2&gt; s;</code></td><td>A model of <a href="../Sequence.html">Sequence</a></td><td></td><td><code>s</code> prodives iterators to all the elements in the ranges <code>[<a href="../Reference/begin.html">begin</a>&lt;Sequence1&gt;::type,<a href="../Reference/end.html">end</a>&lt;Sequence1&gt;::type)</code>, <code>[<a href="../Reference/begin.html">begin</a>&lt;Sequence2&gt;::type,<a href="../Reference/end.html">end</a>&lt;Sequence2&gt;::type)</code>.</td><td><code><a href="../Reference/size.html">size</a>&lt;s&gt;::type::value == <a href="../Reference/size.html">size</a>&lt; Sequence1 &gt;::type::value + <a href="../Reference/size.html">size</a>&lt; Sequence2 &gt;::type::value</code>. </td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef joint_view&lt;
<a href="../Reference/range_c.html">range_c</a>&lt;int,0,10&gt;
, <a href="../Reference/range_c.html">range_c</a>&lt;int,10,15&gt;
&gt; numbers;
<p>
typedef <a href="../Reference/range_c.html">range_c</a>&lt;int,0,15&gt; answer;
BOOST_STATIC_ASSERT((<a href="../Reference/equal.html">equal</a>&lt;numbers,answer&gt;::type::value));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Sequences.html">Sequences</a>, <code><a href="../Reference/transform_view.html">transform_view</a></code>, <code><a href="../Reference/filter_view.html">filter_view</a></code>, <code><a href="../Reference/zip_view.html">zip_view</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 5:42 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::less</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>less</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T1
, typename T2
&gt;
struct less
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns <code>true_</code> if <code>T1::value &lt; T2::value</code> and <code>false_</code> otherwise [<a href="#1">1</a>].
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/less.hpp">boost/mpl/less.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>T1, T2</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef less&lt;t1,t2&gt;::type c;</code></td><td>A model of <code>bool</code> <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code>typedef bool_&lt;(t1::value &lt; t2::value)&gt; c;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,0,1,2,3,4,5,6,7,8,9&gt; numbers;
typedef <a href="../Reference/remove_if.html">remove_if</a>&lt; numbers, less&lt;_1,int_&lt;5&gt; &gt; &gt;::type result;
BOOST_STATIC_ASSERT(<a href="../Reference/equal.html">equal</a>&lt; result,<a href="../Reference/range_c.html">range_c</a>&lt;int,5,10&gt; &gt;::type::value));
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The <code>less</code> metafunction can be (and is expected to be) specialized by user to work on user-defined types that do not satisfy the <a href="../Integral_Constant.html">Integral Constant</a> requirements. The requirements listed here are the ones imposed by the default implementation.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Metafunctions.html">Metafunctions</a>, <code><a href="../Reference/less_equal.html">less_equal</a></code>, <code><a href="../Reference/greater.html">greater</a></code>, <code><a href="../Reference/greater_equal.html">greater_equal</a></code>, <code><a href="../Reference/equal.html">equal</a></code>, <code><a href="../Reference/not_equal_to.html">not_equal_to</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:22 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::less_equal</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>less_equal</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T1
, typename T2
&gt;
struct less_equal
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns <code>true_</code> if <code>T1::value &lt;= T2::value</code> and <code>false_</code> otherwise [<a href="#1">1</a>].
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/less_equal.hpp">boost/mpl/less_equal.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>T1, T2</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef less_equal&lt;t1,t2&gt;::type c;</code></td><td>A model of <code>bool</code> <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code>typedef bool_&lt;(t1::value &lt;= t2::value)&gt; c;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,0,1,2,3,4,5,6,7,8,9&gt; numbers;
typedef <a href="../Reference/remove_if.html">remove_if</a>&lt; numbers, less_equal&lt;_1,int_&lt;4&gt; &gt; &gt;::type result;
BOOST_STATIC_ASSERT(<a href="../Reference/equal.html">equal</a>&lt; result,<a href="../Reference/range_c.html">range_c</a>&lt;int,5,10&gt; &gt;::type::value));
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The <code>less_equal</code> metafunction can be (and is expected to be) specialized by user to work on user-defined types that do not satisfy the <a href="../Integral_Constant.html">Integral Constant</a> requirements. The requirements listed here are the ones imposed by the default implementation.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Metafunctions.html">Metafunctions</a>, <code><a href="../Reference/less.html">less</a></code>, <code><a href="../Reference/greater.html">greater</a></code>, <code><a href="../Reference/greater_equal.html">greater_equal</a></code>, <code><a href="../Reference/equal.html">equal</a></code>, <code><a href="../Reference/not_equal_to.html">not_equal_to</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:28 am</body></html>
-45
View File
@@ -1,45 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::list</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>list</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T1 = <em>implementation-defined</em>
, typename T2 = <em>implementation-defined</em>
, ...
, typename Tn = <em>implementation-defined</em>
&gt;
struct list
{
};
</pre>
<p>
<h3>Description</h3>
<p>
A <code>list</code> is a <a href="../Forward_Sequence.html">Forward Sequence</a> of types. It's also an <a href="../Extensible_Sequence.html">Extensible Sequence</a> that supports constant time insertion and removal of elements at the beginning (through <code><a href="../Reference/push_front.html">push_front</a></code>), and linear time insertion and removal of elements at the end or in the middle (through <code><a href="../Reference/insert.html">insert</a></code>/<code><a href="../Reference/erase.html">erase</a></code> algorithms).
<p>
<h3>Example</h3>
<p>
<pre>
typedef list&lt;float,double,long double&gt; floats;
typedef <a href="../Reference/push_front.html">push_front</a>&lt;floating_types,my_float&gt;::type ext_floats;
BOOST_STATIC_ASSERT((boost::is_same&lt; <a href="../Reference/front.html">front</a>&lt;ext_floats&gt;::type, my_float &gt;::value));
</pre>
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/list.hpp">boost/mpl/list.hpp</a>"
#include "<a href="../../../../../boost/mpl/list/list0.hpp">boost/mpl/list/list0.hpp</a>"
#include "<a href="../../../../../boost/mpl/list/list10.hpp">boost/mpl/list/list10.hpp</a>"
...
#include "<a href="../../../../../boost/mpl/list/list50.hpp">boost/mpl/list/list50.hpp</a>"
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Forward_Sequence.html">Forward Sequence</a>, <code><a href="../Reference/list_c.html">list_c</a></code>, <code><a href="../Reference/vector.html">vector</a></code>, <code><a href="../Reference/vector_c.html">vector_c</a></code>, <code><a href="../Reference/range_c.html">range_c</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 8:05 am</body></html>
-58
View File
@@ -1,58 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::list_c</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>list_c</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T
, T C1 = <em>implementation-defined</em>
, T C2 = <em>implementation-defined</em>
, ...
, T CN = <em>implementation-defined</em>
&gt;
struct list_c
{
};
</pre>
<p>
<h3>Description</h3>
<p>
Similary to <code><a href="../Reference/vector_c.html">vector_c</a></code>, <code>list_c</code> is a shorcut interface whose whole purpose is to make the creation of a <code>list</code> of <a href="../Integral_Constant.html">Integral Constant</a>s less verbose:
<p>
<pre>
typedef list_c&lt;unsigned long,-1,0,1,1,-1,0,0,1,-1&gt; data;
</pre>
<p>
If <code>list_c</code> didn't exist, instead of the above line you would have to write this:
<p>
<pre>
typedef list&lt;
integral_c&lt;unsigned long,-1&gt;
, integral_c&lt;unsigned long,0&gt;
, integral_c&lt;unsigned long,1&gt;
, integral_c&lt;unsigned long,1&gt;
, integral_c&lt;unsigned long,-1&gt;
, integral_c&lt;unsigned long,0&gt;
, integral_c&lt;unsigned long,0&gt;
, integral_c&lt;unsigned long,1&gt;
, integral_c&lt;unsigned long,-1&gt;
&gt; data;
</pre>
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/list_c.hpp">boost/mpl/list_c.hpp</a>"
#include "<a href="../../../../../boost/mpl/list/list0_c.hpp">boost/mpl/list/list0_c.hpp</a>"
#include "<a href="../../../../../boost/mpl/list/list10_c.hpp">boost/mpl/list/list10_c.hpp</a>"
...
#include "<a href="../../../../../boost/mpl/list/list50_c.hpp">boost/mpl/list/list50_c.hpp</a>"
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Random_Access_Sequence.html">Random Access Sequence</a>, <code><a href="../Reference/list.html">list</a></code>, <code><a href="../Reference/vector.html">vector</a></code>, <code><a href="../Reference/vector_c.html">vector_c</a></code>, <code><a href="../Reference/range_c.html">range_c</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited July 17, 2002 8:04 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::lower_bound</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>lower_bound</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename T
, typename Pred = <a href="../Reference/less.html">less</a>&lt;_,_&gt;
&gt;
struct lower_bound
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the first position in the sorted <code>Sequence</code> where <code>T</code> could be inserted without violating the ordering.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/lower_bound.hpp">boost/mpl/lower_bound.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sorted sequence. </td></tr>
<tr><td><code>T</code></td><td>A type</td><td>A type to search the position for. </td></tr>
<tr><td><code>Pred</code></td><td>A model of binary Predicate [Lambda Expression]</td><td>A sort criteria. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef lower_bound&lt; Sequence,T,Pred &gt;::type i;</code></td><td>A model of <a href="../Forward_Iterator.html">Forward Iterator</a></td><td></td><td><code>i</code> is the furthermost iterator in <code>[begin&lt;Sequence&gt;::type, end&lt;Sequence&gt;::type)</code> such that, for every iterator <code>j</code> in <code>[begin&lt;Sequence&gt;::type, i)</code>, <code>apply&lt; lambda&lt;Pred&gt;::type, j::type, T &gt;::type::value == true</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
The number of comparisons is logarithmic: at most <code>log(size&lt;Sequence&gt;::type::value) + 1</code>. If <code>Sequence</code> is a <a href="../Random_Access_Sequence.html">Random Access Sequence</a> then the number of steps through the range is also logarithmic; otherwise, the number of steps is proportional to <code>size&lt;Sequence&gt;::type::value</code>.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/list_c.html">list_c</a>&lt;int,1,2,3,3,3,5,8&gt; numbers;
typedef lower_bound&lt; numbers, int_&lt;3&gt; &gt;::type iter;
BOOST_STATIC_ASSERT((<a href="../Reference/distance.html">distance</a>&lt; <a href="../Reference/begin.html">begin</a>&lt;numbers&gt;::type,iter &gt;::type::value == 2));
BOOST_STATIC_ASSERT(iter::type::value == 3);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code>sort</code>, <code><a href="../Reference/upper_bound.html">upper_bound</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 5:43 am</body></html>
-62
View File
@@ -1,62 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::max_element</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>max_element</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename Pred = <a href="../Reference/less.html">less</a>&lt;_1,_2&gt;
&gt;
struct max_element
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Finds the largest element in the <code>Sequence</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/max_element.hpp">boost/mpl/max_element.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to be searched. </td></tr>
<tr><td><code>Pred</code></td><td>A model of binary Predicate [Lambda Expression]</td><td>A comparison criteria. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef max_element&lt; Sequence,Pred &gt;::type i;</code></td><td>A model of <a href="../Forward_Iterator.html">Forward Iterator</a></td><td></td><td><code>i</code> is the first iterator in <code>[begin&lt;Sequence&gt;::type, end&lt;Sequence&gt;::type)</code> such that for every iterator <code>j</code> in <code>[begin&lt;Sequence&gt;::type, end&lt;Sequence&gt;::type)</code>, <code>apply&lt; lambda&lt;Pred&gt;::type, i::type, j::type &gt;::type::value == false</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Zero comparisons if <code>Sequence</code> is empty, otherwise exactly <code>size&lt;Sequence&gt;::value - 1</code> comparisons.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/vector.html">vector</a>&lt;int,char[50],long,double&gt; types;
typedef max_element&lt;
<a href="../Reference/transform_view.html">transform_view</a>&lt; types,sizeof_&lt;_1&gt; &gt;
&gt;::type iter;
<p>
BOOST_STATIC_ASSERT((<a href="../Reference/distance.html">distance</a>&lt; begin&lt;types&gt;::type,iter &gt;::type::value == 1));
BOOST_STATIC_ASSERT(sizeof(<a href="../Reference/deref.html">deref</a>&lt;iter&gt;::type) == 50);
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/min_element.html">min_element</a></code>, <code><a href="../Reference/upper_bound.html">upper_bound</a></code>, <code><a href="../Reference/lower_bound.html">lower_bound</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:01 am</body></html>
-62
View File
@@ -1,62 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::min_element</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>min_element</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename Sequence
, typename Pred = <a href="../Reference/less.html">less</a>&lt;_1,_2&gt;
&gt;
struct min_element
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Finds the smallest element in the <code>Sequence</code>.
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/min_element.hpp">boost/mpl/min_element.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>Sequence</code></td><td>A model of <a href="../Forward_Sequence.html">Forward Sequence</a></td><td>A sequence to be searched. </td></tr>
<tr><td><code>Pred</code></td><td>A model of binary Predicate [Lambda Expression]</td><td>A comparison criteria. </td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef min_element&lt; Sequence,Pred &gt;::type i;</code></td><td>A model of <a href="../Forward_Iterator.html">Forward Iterator</a></td><td></td><td><code>i</code> is the first iterator in <code>[begin&lt;Sequence&gt;::type, end&lt;Sequence&gt;::type)</code> such that for every iterator <code>j</code> in <code>[begin&lt;Sequence&gt;::type, end&lt;Sequence&gt;::type)</code>, <code>apply&lt; lambda&lt;Pred&gt;::type, j::type, i::type &gt;::type::value == false</code>.</td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Linear. Zero comparisons if <code>Sequence</code> is empty, otherwise exactly <code>size&lt;Sequence&gt;::value - 1</code> comparisons.
<p>
<h3>Example</h3>
<p>
<pre>
typedef <a href="../Reference/vector.html">vector</a>&lt;bool,char[50],long,double&gt; types;
typedef min_element&lt;
<a href="../Reference/transform_view.html">transform_view</a>&lt; types,sizeof_&lt;_1&gt; &gt;
&gt;::type iter;
<p>
BOOST_STATIC_ASSERT((<a href="../Reference/distance.html">distance</a>&lt; begin&lt;types&gt;::type,iter &gt;::type::value == 0));
BOOST_STATIC_ASSERT(sizeof(<a href="../Reference/deref.html">deref</a>&lt;iter&gt;::type) == sizeof(bool));
</pre>
<p>
<h3>See also</h3>
<p>
<a href="../Algorithms.html">Algorithms</a>, <code><a href="../Reference/max_element.html">max_element</a></code>, <code><a href="../Reference/upper_bound.html">upper_bound</a></code>, <code><a href="../Reference/lower_bound.html">lower_bound</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:05 am</body></html>
-64
View File
@@ -1,64 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::minus</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>minus</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T1
, typename T2
, typename T3 = integral_c&lt;int,0&gt;
, ...
, typename Tn = integral_c&lt;int,0&gt;
&gt;
struct minus
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the difference of its arguments [<a href="#1">1</a>].
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/minus.hpp">boost/mpl/minus.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>T1, T2, .., Tn</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef minus&lt;t1,t2,..,tn&gt;::type diff;</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td><td>Equivalent to <code>typedef integral_c&lt;typeof(t1::value - t2::value .. - tn::value), t1::value - t2::value .. - tn::value &gt; diff;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef minus&lt; integral_c&lt;short,-1&gt;, integral_c&lt;long,10&gt; &gt;::type diff;
BOOST_STATIC_ASSERT(diff::value == -11));
BOOST_MPL_ASSERT_IS_SAME(diff::value_type, long);
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The <code>minus</code> metafunction can be (and is expected to be) specialized by user to work on user-defined types that do not satisfy the <a href="../Integral_Constant.html">Integral Constant</a> requirements. The requirements listed here are the ones imposed by the default implementation.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Metafunctions.html">Metafunctions</a>, <code><a href="../Reference/plus.html">plus</a></code>, <code><a href="../Reference/divides.html">divides</a></code>, <code><a href="../Reference/multiplies.html">multiplies</a></code>, <code><a href="../Reference/modulus.html">modulus</a></code>, <code><a href="../Reference/negate.html">negate</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:31 am</body></html>
-61
View File
@@ -1,61 +0,0 @@
<!doctype html public "-//ietf//dtd html//en">
<html><head><title>boost::mpl::modulus</title>
<link rel="stylesheet" href="../mpl_wiki.css">
</head><body bgcolor="white">
<h1><a href="../Table_of_Contents.html"><img src="../mpl_logo.jpg" alt="[Home]" border=0 align="right"></a>modulus</h1><h3>Synopsis</h3>
<p>
<pre>
template&lt;
typename T1
, typename T2
&gt;
struct modulus
{
typedef <em>unspecified</em> type;
};
</pre>
<p>
<h3>Description</h3>
<p>
Returns the modulus of its arguments [<a href="#1">1</a>].
<p>
<h3>Definition</h3>
<p>
<pre>
#include "<a href="../../../../../boost/mpl/modulus.hpp">boost/mpl/modulus.hpp</a>"
</pre>
<p>
<h3>Parameters</h3>
<table border="1">
<tr><th>&nbsp;Parameter&nbsp;</th><th>&nbsp;Requirement&nbsp;</th><th>&nbsp;Description &nbsp;</th></tr>
<tr><td><code>T1, T2</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td></td></tr>
</table>
<p>
<h3>Expression semantics</h3>
<p>
<table border="1">
<tr><th>&nbsp;Expression&nbsp;</th><th>&nbsp;Expression&nbsp;type&nbsp;</th><th>&nbsp;Precondition&nbsp;</th><th>&nbsp;Semantics&nbsp;</th><th>&nbsp;Postcondition&nbsp;</th></tr>
<tr><td><code>typedef modulus&lt;t1,t2&gt;::type mod;</code></td><td>A model of <a href="../Integral_Constant.html">Integral Constant</a></td><td><code>t2::value != 0 </code></td><td>Equivalent to <code>typedef integral_c&lt;typeof(t1::value % t2::value), t1::value % t2::value&gt; mod;</code></td><td></td></tr>
</table>
<p>
<h3>Complexity</h3>
<p>
Amortized constant time.
<p>
<h3>Example</h3>
<p>
<pre>
typedef modulus&lt; integral_c&lt;short,10&gt;, integral_c&lt;long,3&gt; &gt;::type mod;
BOOST_STATIC_ASSERT(mod::value == 1));
BOOST_MPL_ASSERT_IS_SAME(mod::value_type, long);
</pre>
<p>
<h3>Notes</h3>
<p>
[<a name="1">1</a>] The <code>modulus</code> metafunction can be (and is expected to be) specialized by user to work on user-defined types that do not satisfy the <a href="../Integral_Constant.html">Integral Constant</a> requirements. The requirements listed here are the ones imposed by the default implementation.<br>
<p>
<h3>See also</h3>
<p>
<a href="../Metafunctions.html">Metafunctions</a>, <code><a href="../Reference/divides.html">divides</a></code>, <code><a href="../Reference/multiplies.html">multiplies</a></code>, <code><a href="../Reference/plus.html">plus</a></code>, <code><a href="../Reference/minus.html">minus</a></code>, <code><a href="../Reference/negate.html">negate</a></code>
<p><hr>
<a href="../Table_of_Contents.html">Table of Contents</a><br>Last edited March 10, 2003 6:32 am</body></html>

Some files were not shown because too many files have changed in this diff Show More