Compare commits

...

1006 Commits

Author SHA1 Message Date
febca584d9 Removed -u command line option for the compressed_pair_test as this option is not recognized by Boost.Test (and presumably never was). This fixes the test execution failure. 2016-09-03 00:25:51 +03:00
21dc552cf9 Added a workaround for gcc 4.6 in C++11 mode as it can't seem to handle defaulted functions with noexcept specifier. The problem was discovered with autotests. 2016-09-02 19:14:00 +03:00
fda210f597 Merge branch 'develop' 2016-09-02 18:34:58 +03:00
3d853b0e83 Reworked to_string test to verify the overload with a custom allocator even when explicit conversion operators are not supported. Made the custom allocator more standard-compliant. 2016-09-01 22:42:29 +03:00
4814d1ebfe Added another overload of to_string when default function template arguments are not supported.
The additional overload more closely emulates the official interface and allows to construct strings with custom allocators.
2016-09-01 22:08:28 +03:00
e5932ebb08 fix compile error on basic_string_view::to_string when Allocator is user-defined 2016-09-01 21:56:20 +03:00
93a2e25092 Merge to master for 1.62.0 release 2016-08-17 13:02:13 -07:00
39577f86d1 Fix rfind (and other finders). Fixes bug https://svn.boost.org/trac/boost/ticket/9518 2016-08-14 11:20:28 -07:00
8392991c46 Remove extraneous semicolon; no functional change 2016-08-14 11:19:32 -07:00
c5b1256650 rename routines in detail namespace so that someone who includes both <string_ref> and <string_view> won't get duplicate decls 2016-08-14 11:11:12 -07:00
c56dd13592 Mark the copy ctor/assignment operator as '= default' when the compiler supports it. This makes these types trivially copy/move assignable/constructible. See https://svn.boost.org/trac/boost/ticket/11684 2016-07-27 11:18:18 -07:00
181f302ee4 Fix Ticket 12140; mark only single-arg ctor as explicit. Thanks to Thimo for the patch. 2016-06-15 15:50:21 -07:00
287844fe76 Merge branch 'develop' of github.com:boostorg/utility into develop 2016-06-15 14:52:40 -07:00
3982b6d633 Ensure the file ends with a newline. Fixes compiler warnings. 2016-04-14 19:20:15 +03:00
0b492bee9c Re-install string_ref - to be removed in the future 2016-04-14 07:50:28 -07:00
a9236d00a9 Ensure the file ends with a newline. Fixes compiler warnings. 2016-03-26 14:00:12 +03:00
4313bfc323 Revert "Remove the 'basic_string_ref template; use 'basic_string_view' instead. Keep the string_ref, etc typedefs around, though"
This reverts commit 8ab8e36dcf.
2016-03-07 08:45:25 -08:00
f61c94e812 Merge ADL protection for Boost.Operators from 'develop' 2016-03-05 11:32:26 +01:00
1dfacff7ec Renamed namespace detail to operators_detail 2016-02-23 20:30:16 +01:00
a25ac4550b Removed unused overloads 2016-02-22 20:46:58 +01:00
d767054a79 Merge branch 'develop' of github.com:boostorg/utility into develop 2016-02-22 20:39:26 +01:00
08a1b7da61 Added ADL protector 2016-02-22 20:39:16 +01:00
8ab8e36dcf Remove the 'basic_string_ref template; use 'basic_string_view' instead. Keep the string_ref, etc typedefs around, though 2016-02-17 11:32:16 -08:00
1caa745dd7 Introduce new 'string_view' to match the one in the standard. Step #2 (up next) is to retire string_ref in favor of string_view 2015-12-21 11:39:59 -08:00
cf5ad341ed Added a missing include. 2015-09-11 19:31:18 +03:00
1f6de83fe2 Merge pull request #20 from MarcelRaad/patch-1
Remove deprecated include
2015-09-11 19:06:38 +03:00
cb6500161b Remove deprecated include
All that boost/iterator.hpp does is pull std::iterator into namespace boost. A comment in that header mentions: "This header is obsolete and will be deprecated."
2015-09-11 17:49:23 +02:00
13610caa36 Update copyright notice; change to_string to avoid UB by calling a different constructor. Fixes #11150 2015-03-28 12:02:41 -07:00
6bcf4f92bf Merge pull request #19 from akumta/patch-1
Update string_ref_test2.cpp
2015-02-27 09:26:11 +03:00
fa8301a56a Update string_ref_test2.cpp
For ticket# 10838
2015-02-25 10:49:14 -08:00
7306c8c359 Merge branch 'develop' 2014-09-06 22:19:24 +04:00
492fd7f091 Moved enable_if to Boost.Core. 2014-08-18 18:57:40 +04:00
4fbd789253 Merge pull request #18 from danieljames/metadata
Create metadata file.
2014-08-18 18:49:04 +04:00
4522603132 Add metadata file. 2014-08-18 15:12:15 +01:00
cae8d90d65 Add a redirect for the compressed pair docs. 2014-07-04 22:05:56 +04:00
2ec0488e2a Merge pull request #16 from danieljames/compressed-pair-redirect
Add a redirect for the compressed pair docs.
2014-07-04 21:56:14 +04:00
520dff9270 Add a redirect for the compressed pair docs. 2014-06-30 22:58:27 +01:00
8e24c798ad Merge pull request #15 from boostorg/next_prior_fix_iterator_backtracking
Reworked next() and prior() taking the distance arguments.
2014-06-25 22:26:44 +04:00
651a869d4f Reworked next() and prior() taking the distance arguments.
The new version should provide the expected behavior in the case (prior(v.end(), v.size()) == v.begin()). It should also work with integers now, as was originally intended by David Abrahams. Added tests to verify these new use cases.
2014-06-24 01:05:32 +04:00
7a8f16efdc Removed trailing spaces and tab. 2014-06-12 21:34:19 +04:00
2fa70612bb Removed docs and tests of the components moved to Boost.Core. Added links and redirections to the docs in Boost.Core. 2014-06-12 21:31:37 +04:00
f1edd107eb Merge pull request #12 from K-ballo/base-from-ref-member
Added base_from_member specialization for members of lvalue-reference types.
2014-06-12 03:54:08 +04:00
c185d2dfa9 Merge pull request #13 from K-ballo/compressed-pair-doc
Ported compressed_pair documentation to Quickbook
2014-06-12 03:38:24 +04:00
4531b2a2a6 Ported compressed_pair documentation to Quickbook 2014-06-11 19:48:23 -03:00
51e482edfe Added base_from_member specialization for members of lvalue-reference type 2014-06-11 18:55:12 -03:00
61d07273fc Remove executable bit from the file. 2014-06-12 01:44:35 +04:00
42d56fbd51 Merge pull request #11 from K-ballo/base-from-member-doc
Ported base_from_member documentation to Quickbook
2014-06-12 01:30:02 +04:00
6a1e97f870 Ported base_from_member documentation to Quickbook 2014-06-11 18:17:33 -03:00
c0fdaba925 Removed auto-generated files. 2014-06-12 01:06:53 +04:00
87bc4c8dce Remove declval.hpp, moved to type_traits. 2014-06-05 17:41:17 +03:00
34c11cb995 Remove generator_iterator.hpp, as it has been moved to iterator. 2014-06-05 02:34:39 +03:00
beab2e74ca Added test for generator_iterator.hpp. 2014-06-05 02:19:58 +03:00
10b8041472 boost::swap, boost::empty_deleter and explicit operator bool macros moved from Boost.Utility to Boost.Core. 2014-06-01 22:44:30 +04:00
1ed9aaa2a4 Remove headers that have been moved into core. 2014-06-01 03:22:30 +03:00
5a54e21ec5 Merge branch 'akrzemi1-patch-1' into develop 2014-05-31 10:46:26 -07:00
8e06104836 Merge branch 'patch-1' of github.com:akrzemi1/utility into akrzemi1-patch-1 2014-05-31 10:44:18 -07:00
45d884ffd7 Merge pull request #9 from danieljames/remove-binary-search-test
Move binary_search_test.cpp into detail module.
2014-05-31 18:16:44 +01:00
329ca0bae8 Move binary_search_test.cpp into detail module.
The header it's testing is in the detail module, so it should be there.
2014-05-31 18:14:18 +01:00
afd9ab17ec removed comparison with 0
The concept is supposed to generalize pointers and optional<>, but the latter has abandoned the comparison with 0 a long while ago.
2014-05-29 17:41:56 +02:00
036f6b9107 Merge branch 'develop' 2014-05-26 23:03:24 +01:00
da239df58d Fix base_from_member example.
See: https://svn.boost.org/trac/boost/ticket/10068
2014-05-26 22:57:58 +01:00
46b3739b79 Merge commit '5ce9683858f5ced8b0df665aad74271dc7c9648d' 2014-05-13 00:03:10 +04:00
c5fc075d07 Merge commit '991539725e5943b7f280f7ecd7a00aa7f3dc0582' 2014-05-13 00:01:31 +04:00
5ce9683858 Merge branch 'develop' of github.com:boostorg/utility into develop 2014-05-10 18:28:20 +04:00
991539725e Replaced left shift of signed integer values with multiplication to keep the expressions constant according to C++11. 2014-05-10 18:27:59 +04:00
df8e0c2dae Merge pull request #5 from Lastique/patch-1
Fix compilation with gcc 4.5 in C++11 mode
2014-05-10 08:59:10 +04:00
f5869d0f82 Merge pull request #6 from Lastique/develop
Added a new macro BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT
2014-05-10 08:57:32 +04:00
db7bba3259 Merge pull request #7 from ericniebler/develop
value_init and swap work on nvidia gpu's
2014-05-01 15:32:58 -07:00
379e2111e2 value_init and swap work on nvidia gpu's 2014-05-01 15:29:43 -07:00
d1bfa8e7b0 Added a new macro BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT, which implements a noexcept operator. Also added explicit noexcept specification for the constexpr macro. 2014-04-26 15:11:35 +04:00
de0e18ca0a work around nvcc bug by only defining has_result when it's needed 2014-04-23 15:54:27 -07:00
8ae3bfa961 Fix compilation with gcc 4.5 in C++11 mode
Gcc 4.5 does not allow non-public defaulted functions, so fall back to the C++03 version. Also replaced the deprecated macros with the new ones and adjusted formatting.
2014-04-10 00:27:41 +04:00
d4b5fde5a8 Remove assert from utility 2014-02-09 17:56:48 +02:00
9c4d2843da Merge commit 'ad61f347e4c0c5c3d9bec67f3ee69a3d7f7ac255' into develop 2013-12-12 02:58:12 +02:00
ad61f347e4 Revert incorrect reversion of adf57817ec 2013-12-11 23:28:32 +02:00
b434003b13 Revert incorrect reversion of adf57817ec 2013-12-11 23:28:13 +02:00
50eafe2027 Fix addressof for nullptr_t values. Fixes #5487. 2013-12-11 01:57:20 +02:00
87b8e03ca9 Merge branch 'develop' 2013-12-11 00:47:22 +02:00
d595357b41 Merge branch 'master' into develop 2013-12-11 00:47:00 +02:00
79d9d9f514 Revert "Ref: Remove obsolete MSVC version check."
This reverts commit adf57817ec.

Conflicts:
	include/boost/ref.hpp
2013-12-11 00:46:10 +02:00
c48f86c9e4 Ticket #7094, thanks 1czajnik
[SVN r79398]
2013-12-11 00:42:02 +02:00
514e5299ca Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#else...#endif blocks.

[SVN r86245]
2013-12-11 00:36:54 +02:00
3bac7b132a Fix #9169 - Add BOOST_FORCEINLINE on boost::ref for performance issue
[SVN r86124]

Conflicts:
	include/boost/ref.hpp
2013-12-11 00:35:46 +02:00
9382b69eb1 Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
[SVN r86248]
2013-12-11 00:28:35 +02:00
52a64d6aec Remove obsolete files.
[SVN r86242]
2013-12-11 00:24:32 +02:00
a292dba021 Detail: Remove obsolete MSVC version checks.
[SVN r86039]
2013-12-11 00:24:03 +02:00
e25bd18bd8 Fix #9170 - Add BOOST_FORCEINLINE in address_of for performance issues
[SVN r86125]
2013-12-11 00:21:27 +02:00
80895c071c Operators: Remove obsolete GCC version check.
[SVN r86114]
2013-12-11 00:19:24 +02:00
f90812f1d9 Revert "Remove check for obsolete DMC version."
This reverts commit 4dc9659097.
2013-12-11 00:18:49 +02:00
244c343efe Revert "Remove obsolete MSVC check from pragma guard"
This reverts commit 1fd5883b34.
2013-12-11 00:13:48 +02:00
14e9e95c17 Utility: Remove obsolete MSVC version check
[SVN r85932]
2013-12-11 00:12:51 +02:00
fd9f12b8f1 Remove use of obsolete BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE{,_SPEC} macro.
[SVN r85896]
2013-12-11 00:11:30 +02:00
96da5105ab Merge utility documentation.
- Fixed duplicate anchors.
- Add BOOST_EXPLICIT_OPERATOR_BOOL documentation.
- Rebuild some of the utility documentation.


[SVN r86797]
2013-11-23 14:23:45 +00:00
ad98ca9c3c Rebuild some of the utility documentation.
[SVN r86796]
2013-11-23 14:14:01 +00:00
dfad2950ea Add BOOST_EXPLICIT_OPERATOR_BOOL documentation.
[SVN r86739]
2013-11-17 17:13:08 +00:00
44a98b121b Merge r86524 (Correct broken links to C++ standard papers); fixes #9212
[SVN r86673]
2013-11-13 03:22:55 +00:00
d5e86bb576 Correct broken links to C++ standard papers. Refs #9212.
[SVN r86524]
2013-10-30 12:51:24 +00:00
65d9a78735 Regnerated string_ref docs. Fixed incorrect example. Fixes #8002
[SVN r86488]
2013-10-27 21:05:17 +00:00
12d17bc26d Fixed duplicate anchors
[SVN r86423]
2013-10-25 02:46:04 +00:00
03047e3f00 Simplify multi-component ifdefs containing BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
[SVN r86248]
2013-10-11 23:20:59 +00:00
468fb2dd5f Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#else...#endif blocks.

[SVN r86245]
2013-10-11 23:17:48 +00:00
e97577a0ae Remove obsolete files.
[SVN r86242]
2013-10-11 23:11:35 +00:00
a90bc68a7f Fix #9170 - Add BOOST_FORCEINLINE in address_of for performance issues
[SVN r86125]
2013-10-01 15:05:39 +00:00
b39e4e5aea Fix #9169 - Add BOOST_FORCEINLINE on boost::ref for performance issue
[SVN r86124]
2013-10-01 15:02:28 +00:00
37c8f45edc Operators: Remove obsolete GCC version check.
[SVN r86114]
2013-10-01 08:47:11 +00:00
4dc9659097 Remove check for obsolete DMC version.
[SVN r86043]
2013-09-30 00:36:13 +00:00
3d1646cf51 Detail: Remove obsolete MSVC version checks.
[SVN r86039]
2013-09-30 00:21:39 +00:00
adf57817ec Ref: Remove obsolete MSVC version check.
[SVN r86031]
2013-09-30 00:19:48 +00:00
1fd5883b34 Remove obsolete MSVC check from pragma guard
git grep -h -B1 "^#\s*pragma once" | grep -v pragma | sort | uniq

is now clean.

[SVN r85952]
2013-09-26 13:02:51 +00:00
fc4bc227b5 Utility: Remove obsolete MSVC version check
[SVN r85932]
2013-09-26 09:41:00 +00:00
bcd50e9105 Remove use of obsolete BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE{,_SPEC} macro.
[SVN r85896]
2013-09-25 10:29:44 +00:00
0f5ae0e73c Corrected comment.
[SVN r85624]
2013-09-09 18:43:27 +00:00
e33f8b0055 Merged new added components from trunk. Merged other sublibraries which tests are passing for a long time as well.
[SVN r85613]
2013-09-08 19:28:44 +00:00
497198c624 Made indents similar.
[SVN r85611]
2013-09-08 18:45:41 +00:00
9df000eece Extracted empty_deleter to Boost.Utility.
[SVN r85577]
2013-09-05 18:25:41 +00:00
8e4054467e Attempt to work around explicit_operator_bool_compile_fail_conv_pvoid test failure for VACPP.
[SVN r85570]
2013-09-05 08:28:24 +00:00
7ae5e14681 Extracted BOOST_EXPLICIT_OPERATOR_BOOL macro from Boost.Log.
[SVN r85543]
2013-09-01 16:31:16 +00:00
b051dd665b [utility] Fixes to value_init docs.
[SVN r85335]
2013-08-13 21:39:57 +00:00
eca8d9f1ef [utility] Fixes to value_init docs.
[SVN r85335]
2013-08-13 21:39:57 +00:00
b813232bba Merged recent changes from trunk.
[SVN r85088]
2013-07-20 17:17:10 +00:00
15021632dc added new result_of mode that uses TR1 with a decltype fallback as suggested by Nathan Crookston; fixes #7753
[SVN r84949]
2013-07-03 22:14:27 +00:00
9baf33dd16 Optimized BOOST_ASSERT_MSG so that it is more lightweight and doesn't prevent enclosing functions from inlining. Also added branching hints for the checked conditions.
[SVN r84682]
2013-06-07 20:21:24 +00:00
e02523e286 Merged changes from trunk. Fixes operator<< handling of width specification.
[SVN r84674]
2013-06-07 17:33:25 +00:00
6bb1ce9b7b Avoid using ios_base and streamsize, which are not defined in iosfwd.
[SVN r84636]
2013-06-04 18:41:39 +00:00
9092b9277b Added a test for long padding.
[SVN r84613]
2013-06-02 20:00:04 +00:00
d09b37d3ef More modifications according to the review.
[SVN r84611]
2013-06-02 19:16:50 +00:00
f3bb2a493c Modifications according to the review.
[SVN r84609]
2013-06-02 18:15:53 +00:00
71b501a0b0 Removed constexpr from substr() as it doesn't work with BOOST_THROW_EXCEPTION. Added a test for streaming.
[SVN r84518]
2013-05-26 19:23:52 +00:00
547c562464 Minor change (no need to create a sentry, it will be created by the stream methods).
[SVN r84513]
2013-05-26 15:52:16 +00:00
91aab126e1 1. Extracted forward declarations to a separate header so that it can be included by other libraries (Boost.Log, for instance).
2. Added a default value for char traits template parameter.
3. Added missing headers and removed unused ones.
4. Added inline specifiers to operators.
5. Fixed operator<< behaving incorrectly when particular width is requested (std::setw, etc.).
6. Replaced all throw statements with BOOST_THROW_EXCEPTION.


[SVN r84511]
2013-05-26 15:36:25 +00:00
0d605befd4 Merge bug fix in test to release
[SVN r84449]
2013-05-23 18:38:20 +00:00
4080fe22e3 utility/noncopyable : fix #6578.
[SVN r83869]
2013-04-13 13:49:52 +00:00
1057ff4d9e Utility/noncopyable: Make use of =delete #6578.
[SVN r83833]
2013-04-10 17:16:02 +00:00
2eda3f5299 Utility/address_off: fix #7079.
[SVN r83524]
2013-03-23 01:44:06 +00:00
9cb31aee6e Fix bug in test; thanks to AddressSanitizer for the heads-up
[SVN r83493]
2013-03-18 20:46:53 +00:00
2e4007413e Assert: rollback [82428].
[SVN r83431]
2013-03-14 22:27:04 +00:00
98bb9e6300 Utility: address_of take care of #7079.
[SVN r83429]
2013-03-14 17:48:06 +00:00
1cdb78c30a Assert: take care of #7028.
[SVN r83428]
2013-03-14 17:46:52 +00:00
1ab9131bca Utility: merge [68982] to fix #5213.
[SVN r83427]
2013-03-14 17:35:42 +00:00
d51799518b merge [82901], [82902], and [83147] from trunk
[SVN r83403]
2013-03-10 21:18:49 +00:00
f9540f360c merge [82960] to release, fixes #7663
[SVN r83381]
2013-03-09 22:55:05 +00:00
c1fdb477c1 Merged boost::algorithm::gather and updated tests for Utility, Algorithm and Utility libraries
[SVN r83154]
2013-02-25 18:43:26 +00:00
e0e16be802 fix breakage of string_ref logical ops, detabify, remove trailing whitespace
[SVN r83147]
2013-02-25 06:30:00 +00:00
9284a64936 disable annoying msvc warning, refs #7663
[SVN r82960]
2013-02-17 23:56:10 +00:00
6e2c1b6b53 Added to_string and better comparisons to Boost.StringRef
[SVN r82902]
2013-02-15 16:12:30 +00:00
e4d622019f Fixed bug in string_ref::find; Refs #8067
[SVN r82901]
2013-02-15 16:07:06 +00:00
05af0deaed Update Boost.StringRef tests to use newer Boost.Test features
[SVN r82825]
2013-02-11 21:49:56 +00:00
1b2cd6378b Merge doc typo; Fixes #8002
[SVN r82821]
2013-02-11 16:22:32 +00:00
9383bbc283 Merge typo in docs; Fixes 7974
[SVN r82819]
2013-02-11 16:10:24 +00:00
00d151828c Fixed typo; Refs #8002
[SVN r82771]
2013-02-07 14:14:53 +00:00
f0c62e9e00 Fix typo in docs; Refs #7974
[SVN r82729]
2013-02-04 14:14:42 +00:00
1730c1319b Merge string_ref doc changes to release
[SVN r82490]
2013-01-14 16:34:16 +00:00
71205b6e84 Updated the string_ref docs with a reference section; committed the generated HTML
[SVN r82489]
2013-01-14 16:25:56 +00:00
856b01240a Merge string_ref to release
[SVN r82047]
2012-12-17 14:36:31 +00:00
98d793152c Move string_ref to Boost.Utility; first crack at docs
[SVN r81972]
2012-12-15 16:38:07 +00:00
611395441e Merge deprecated macro change for Boost.Utility to release; no functionality change
[SVN r81855]
2012-12-11 16:41:54 +00:00
dc8ffe92b8 Removed use of deprecated macros
[SVN r81801]
2012-12-08 18:37:29 +00:00
c55d5ca7de Removed usage of deprecated macros in Boost.Utility; specifically result_of
[SVN r81574]
2012-11-26 20:32:24 +00:00
943af35553 Tweak comments (removing a non-ascii character, updating references to the C++11 standard, etc.) and rename the include guard macro.
[SVN r81112]
2012-10-30 16:51:16 +00:00
b35ef27b35 add missing close tag
[SVN r80835]
2012-10-03 23:09:58 +00:00
3cca2755cf add missing close tag
[SVN r80834]
2012-10-03 23:08:44 +00:00
124f4ea879 result_of: merge [80732] from trunk
[SVN r80746]
2012-09-28 22:21:32 +00:00
93f6e3473b friendlier wrt overloaded comma
[SVN r80732]
2012-09-28 08:47:35 +00:00
0f43c44e97 result_of: merge [80636],[80654],[80655],[80656],[80712] from trunk
[SVN r80713]
2012-09-26 18:52:08 +00:00
4a08e3d0bf remove workaround for gcc-4.4, boost.config is correct now
[SVN r80712]
2012-09-26 18:47:08 +00:00
3d650b7f92 nicer work-around for gcc warnings
[SVN r80656]
2012-09-23 02:08:32 +00:00
0568a114a8 supress warnings in result_of_iterate.hpp on gcc 4 and up.
[SVN r80655]
2012-09-23 01:44:39 +00:00
7148d6c95e gcc-4.4 doesn't have robust enough support for sfinae-for-expressions
[SVN r80654]
2012-09-23 01:11:00 +00:00
1cfe3145b4 sfinae-friendly result_of implementation for compilers that don't have extended sfinae for expressions
[SVN r80636]
2012-09-22 19:15:37 +00:00
7d8353f46a result_of: merge [80445], [80452], [80535], [80550], [80605], [80608] from trunk
[SVN r80621]
2012-09-21 18:49:46 +00:00
57d65d6a94 untab-ify
[SVN r80608]
2012-09-20 17:06:34 +00:00
ac9f617f7f SFINAE enabled result_of fixes [7343]
[SVN r80605]
2012-09-19 23:10:08 +00:00
1920623a4f merged [80550], allowing users to force result_of to use decltype
[SVN r80551]
2012-09-17 00:16:36 +00:00
b6a55f878c reverting [78195] in result_of_iterate.hpp to allow users to force result_of to use decltype
[SVN r80550]
2012-09-17 00:04:55 +00:00
a4e332c4c0 updated docs to include guidelines, changes and various suggestions from Andrey Semashev, JeffLee Hellrung and others
[SVN r80535]
2012-09-16 00:39:41 +00:00
e9bbb50eb4 reverting [80445] which is still under discussion on the mailing list
[SVN r80452]
2012-09-08 15:32:35 +00:00
e8440e8855 Added result_of usage guideline.
[SVN r80445]
2012-09-08 13:54:41 +00:00
c0cca9e8cc Merge changes from Trunk.
Fixes #5790.

[SVN r80433]
2012-09-07 08:49:11 +00:00
d63444f22e merge [77702] to release, fixes #6755
[SVN r80359]
2012-09-02 03:42:37 +00:00
1f23425baa result_of limit bumped to 16, merge [71769] from trunk
[SVN r80358]
2012-09-02 03:29:41 +00:00
a89b0101fc boost::result_of uses decltype on compilers that implement N3276, merges [77905], [78195], [80352] from trunk
[SVN r80355]
2012-09-01 23:12:32 +00:00
ff0cb36416 Fixes [6754]. Minor edits to documentation.
[SVN r80352]
2012-09-01 20:00:33 +00:00
37c5395e7a Ticket #7094, thanks 1czajnik
[SVN r79398]
2012-07-10 03:43:13 +00:00
fb2d391928 Merge documentation build fix from trunk.
[SVN r78888]
2012-06-11 07:23:17 +00:00
3558d61c51 Make the new pdf install rules explicit, and fix intrusive's.
[SVN r78877]
2012-06-11 01:33:10 +00:00
ad5cf8cf08 Update Jamfiles and build scripts for PDF generation.
Set local_function image DPI's for better PDF builds.

[SVN r78849]
2012-06-07 16:47:33 +00:00
a201cbe646 Changes required to build PDF versions of docs.
[SVN r78845]
2012-06-07 12:32:56 +00:00
2fc827ad23 Utility/declval: update history.
[SVN r78730]
2012-05-28 19:00:53 +00:00
8036d4370f Utility/declval: update history.
[SVN r78729]
2012-05-28 18:44:24 +00:00
88e7d86270 Marked some expected failures for release regression test compilers. Renamed a local function internal template parameter from Bn to Bindn (because B0 is defined as a macro from a Linux header to represent a baudrate). Added itdentity_type.hpp to utility.hpp. Made reference data members of LocalFunction Addable static (because they are not set in the constructor).
[SVN r78659]
2012-05-26 21:17:03 +00:00
5fe00c4322 Added identity_type.hpp to utility.hpp.
Added static to Addable data members because they are references.
Marked a couple of regression tests for release compilers.

[SVN r78653]
2012-05-26 20:39:22 +00:00
6b9f0103d5 Merged ScopeExit (improved), LocalFunction (new), Functional/OverloadedFunction (new), and Utility/IdentityType (new) from trunk into release branch.
[SVN r78564]
2012-05-24 01:35:04 +00:00
eb613e1b16 Resolved all LocalFunctions to-dos. Still trying to pin-point a VACPP internal error.
[SVN r78371]
2012-05-07 18:54:38 +00:00
923caf4410 Fix for GCC-4.3.x.
[SVN r78268]
2012-04-30 14:07:24 +00:00
36bc0a72ac Updated docs.
[SVN r78234]
2012-04-28 02:35:08 +00:00
d5cacff7c6 only use decltype when Boost.Config says it's ok
[SVN r78195]
2012-04-25 17:41:51 +00:00
b9411f807f Added Lorenzo Caminiti to maintainers.txt and libraries.htm.
[SVN r77945]
2012-04-13 01:02:02 +00:00
4111de6f68 result_of uses decltype on compilers that implement N3276
[SVN r77905]
2012-04-11 00:28:33 +00:00
df9315101e whoops
[SVN r77904]
2012-04-11 00:13:10 +00:00
2637dfcc59 result_of uses decltype on compilers that implement N3276
[SVN r77903]
2012-04-11 00:05:56 +00:00
a7e8d28621 Updated IdentityType docs.
[SVN r77902]
2012-04-10 21:53:28 +00:00
acf8b66a4f Applied patch from Michel Morin to fix #6755. Updated copyright to recognize contributors from the past several years.
[SVN r77702]
2012-04-01 20:38:36 +00:00
7aa68731b4 Utility: Fix #6570
[SVN r77699]
2012-04-01 20:16:57 +00:00
c11e08b6b7 Utility: Rollback unwanted commit while adding noexcept to boost::declval
[SVN r77562]
2012-03-26 17:07:17 +00:00
2cfe775694 Utility: Fix for Adding noexcept to boost::declval
[SVN r77552]
2012-03-25 23:17:39 +00:00
799b066e7d Utility: Added doc for Adding noexcept to boost::declval
[SVN r77543]
2012-03-25 18:28:24 +00:00
9fa5d63525 Utility: Apply patch for 6570: Adding noexcept to boost::declval
[SVN r77539]
2012-03-25 15:58:40 +00:00
2a6cd0c9c4 Split Utility/IdentityType and Functional/OverloadedFunction tests into smaller tests.
Updated docs for ScopeExit, LocalFunction, Utility/IdentityType, and Functional/OverloadedFunction.

[SVN r77484]
2012-03-22 20:54:20 +00:00
5825b6c329 Fixed test indentation and updated docs.
[SVN r77080]
2012-02-20 20:17:07 +00:00
54c78121c2 Updated ScopeExit "world" tests making person a struct instead of a class.
Added a code comment to Utility/IdentityType tmp_assert test.

[SVN r77071]
2012-02-18 19:29:35 +00:00
2891cb52d6 Added Boost.Utility/IdentityType and Boost.Functional/OverloadedFunction to status/Jamfile.v2 list of regression tests.
Updated Boost.ScopeExit documentation.

[SVN r77059]
2012-02-17 21:02:00 +00:00
0db9276e8c Fixed (hopefully) conflict between boost::base_from_member's C++11 constructor template and the automatically defined non-template copy- and/or move-constructors.
[SVN r77046]
2012-02-17 01:55:33 +00:00
d6cb9a9176 Fixed a bug in BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST: a typo VOId -> VOID.
Fixed a bug in scope_exit.hpp: An extra trailing \ in a macro definition (compiled only when BOOST_NO_VARIADIC_MACROS is defined).
Renamed LocalFunction and ScopeExit tests and examples from _err to _error.
Updated LocalFunction docs.

[SVN r77042]
2012-02-16 18:24:34 +00:00
ef0f82f62b Added Utility/IdentityType docs, tests, and examples to libs/.
[SVN r77029]
2012-02-15 01:16:00 +00:00
9a16aaa2b9 Added LocalFunction and Utility/IdentityType source files.
[SVN r77024]
2012-02-15 00:41:33 +00:00
e763315b55 Updated boost::base_from_member for C++2011.
[SVN r76982]
2012-02-11 18:27:02 +00:00
87b3643647 Merged doc updates and fix for #5098 from trunk
[SVN r76804]
2012-01-31 02:30:03 +00:00
c9d56eed6e Merge Boost.Config changes from Trunk - numerous small bug fixes plus a new Cray C++ config.
Fixes #5607.
Fixes #5941.
Fixes #5878.

[SVN r74889]
2011-10-10 11:50:55 +00:00
e36315c151 Merged in BGL, enable_if, and related changes from trunk: r67035, r57559, r72837, r73010, r73026, r72960, r73425, r73424, r73009, r73998, r73997, r73006, r73630, r73631, r73999, r73422, r73423, r73996, r71221
[SVN r74023]
2011-08-23 18:26:46 +00:00
fe653d0a9a Change call_traits to pass enum's by value.
Fixes #5790.

[SVN r73953]
2011-08-20 16:03:58 +00:00
26b39384e3 Apply patch from #5607.
Refs #5607.

[SVN r72580]
2011-06-14 08:27:14 +00:00
9525d062b3 added clarification to result_of doc
[SVN r72377]
2011-06-03 14:45:59 +00:00
6d196c4244 added tr1_result_of info to result_of doc
[SVN r72337]
2011-06-01 20:02:40 +00:00
e83682c091 updated result_of doc with decltype info
[SVN r72336]
2011-06-01 19:29:57 +00:00
1d146d010a upped BOOST_RESULT_OF_NUM_ARGS for Phoenix
[SVN r71769]
2011-05-06 19:55:35 +00:00
5684a2f2b3 Applied doc patches from Matt Calabrese
[SVN r71221]
2011-04-13 02:30:39 +00:00
95d2c38379 Fix doc errors reported by Rob Stewart. Fixes #5421.
[SVN r71047]
2011-04-06 20:21:51 +00:00
1aa48ea698 Utility/operators: [67268] Limit warning suppression to old versions of VC++, fixes #4432.
[SVN r70522]
2011-03-24 21:01:36 +00:00
7d23c75eef Revised the assertion_failed_msg function to use std::exit(-1) instead of std::abort() for Windows CE (since Windows CE does not have an abort() function in the CRT library)
[SVN r68982]
2011-02-18 03:46:55 +00:00
d01eb82fb7 Repair failed merge
[SVN r68914]
2011-02-15 16:18:51 +00:00
86791caf0e Merge trunk BOOST_ASSERT_MSG additions
[SVN r68912]
2011-02-15 14:54:16 +00:00
3279399fe3 Remove BOOST_ENABLE_ASSERT_MSG_HANDLER; use BOOST_ENABLE_ASSERT_HANDLER in its stead
[SVN r68423]
2011-01-24 20:15:36 +00:00
87875cadda Add BOOST_ASSERT_MSG. Add macros to configure output stream.
[SVN r68414]
2011-01-24 15:37:13 +00:00
c58748cfd9 use declval to fix #5098
[SVN r68373]
2011-01-22 22:18:48 +00:00
58bb88d4bd Revert [67111] (addition of boost/detail/iomanip.hpp) and all the commits that depend on it. ([68137], [68140], [68141], [68154], and [68165]).
[SVN r68168]
2011-01-15 08:11:51 +00:00
11d50ecb9f Replacing the use of <iomanip> with <boost/detail/iomanip.hpp> across Boost.
On Linux, GNU's libstdc++, which is the default stdlib for icc and clang,
cannot parse the <iomanip> header in version 4.5+ (which thankfully neither
compiler advises the use of yet), as it's original C++98-friendly
implementation has been replaced with a gnu++0x implementation.
<boost/detail/iomanip.hpp> is a portable implementation of <iomanip>, providing
boost::detail::setfill, boost::detail::setbase, boost::detail::setw,
boost::detail::setprecision, boost::detail::setiosflags and
boost::detail::resetiosflags. 



[SVN r68140]
2011-01-14 02:35:58 +00:00
636283d7c2 Limit warning suppression to old versions of VC++, fixes #4432
[SVN r67278]
2010-12-16 17:30:46 +00:00
1df0bf80bc Stop inspect complaining that assert is used in BOOST_ASSERT.
[SVN r66574]
2010-11-14 18:37:37 +00:00
8176af84e1 Merges changes from Trunk: refer to history.qbk for the details.
[SVN r65708]
2010-10-01 11:11:16 +00:00
71e78a0081 Add declval and common type from Vicente J. Botet Escriba.
Regenerate docs.

[SVN r65443]
2010-09-17 12:12:03 +00:00
f7e4b0e399 Make sure that utility/index.html has a complete list of components. Fixes #4629.
[SVN r65437]
2010-09-16 15:40:47 +00:00
b7d4b6edae merged [64695] and [64696] result_of docs from trunk
[SVN r64745]
2010-08-11 18:15:46 +00:00
fb1d2effef correction to result_of documentation
[SVN r64696]
2010-08-09 16:23:50 +00:00
94b91e8c92 updated result_of documentation
[SVN r64695]
2010-08-09 16:07:20 +00:00
d7cf3628f7 Merge some link fixes.
[64006] and [64059].


[SVN r64061]
2010-07-15 21:19:14 +00:00
a4b8043e68 Fix some header links.
[SVN r64006]
2010-07-14 08:15:33 +00:00
b273cd3914 Merged value_init fixes (extra tests + documentation) from trunk, see #3472, #3869.
[SVN r63638]
2010-07-04 21:56:44 +00:00
ca7db1f361 Merged value_init fixes from trunk, ref #3472, #3869.
[SVN r63637]
2010-07-04 21:50:38 +00:00
b4a08fc80e Added test for private_int_array_pair, hoping to (possibly) fix a minion-clang/darwin-4.2.1 failure at boost.org/development/tests/trunk/developer/utility_.html
[SVN r63045]
2010-06-17 16:53:55 +00:00
9da96d9737 Added value_init_workaround_test, reviewed by Fernando Cacciola, see #3869
[SVN r63014]
2010-06-16 08:45:43 +00:00
a991936c96 Made memset call in value_init conditional, see #3869. Updated the section "compiler issues" of its documentation.
[SVN r62307]
2010-05-30 09:19:09 +00:00
6239e685a2 value_init_test now uses lightweight_test by Peter Dimov; see #4246. Fernando Cacciola mailed me he agreed as well.
[SVN r62158]
2010-05-22 22:05:54 +00:00
2a7e81e07f Merged revisions 61248 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r61248 | eric_niebler | 2010-04-13 08:01:11 -0700 (Tue, 13 Apr 2010) | 1 line
  
  add tr1_result_of that always behaves as TR1 specifies, fix Boost.TR1's result_of to use tr1_result_of
........


[SVN r62137]
2010-05-22 05:35:51 +00:00
e601fcb9c9 Locally disabled a trivial MSVC warning in value_init.hpp (C4512, "assignment operator could not be generated")
[SVN r62030]
2010-05-16 11:08:00 +00:00
f29a5db08e Hopefully fixed value_initialized compile errors on clang and comeau (strict mode) reported by Christopher Jefferson, see #4213
[SVN r61947]
2010-05-13 14:36:06 +00:00
22743ee125 Added boost::initialized<T> as was agreed at http://lists.boost.org/Archives/boost/2010/04/164916.php -- see #3472
[SVN r61883]
2010-05-09 20:51:24 +00:00
e3c982287a add tr1_result_of that always behaves as TR1 specifies, fix Boost.TR1's result_of to use tr1_result_of
[SVN r61248]
2010-04-13 15:01:11 +00:00
13da21e7b1 Revert changes to result_of. Reopens #862, #1310, #1535.
[SVN r61149]
2010-04-08 21:59:33 +00:00
82e1111bb8 Revert [60052], as it causes other libraries to break.
[SVN r61097]
2010-04-06 07:56:54 +00:00
b3ffef536d Merged std_bitset.cpp (boost::swap test) from trunk r60292 through r60334 and r61065 through r61076, including #3984 fix.
[SVN r61077]
2010-04-05 19:21:12 +00:00
9339b32178 Updated copyright notice.
[SVN r61075]
2010-04-05 19:08:01 +00:00
3770221507 Hopefully fixed #3984 (std::bitset constructor issue). Tested by Juergen Hunold on msvc-10.0, msvc-9.0, and gcc-4.4. See thread starting at http://lists.boost.org/Archives/boost/2010/03/162690.php
[SVN r60331]
2010-03-07 21:42:22 +00:00
e2c98762db Revert [60052] as it isn't as uncontroversial as I thought.
[SVN r60314]
2010-03-07 16:22:34 +00:00
e6cb3a77ee Fix a couple of comments.
[SVN r60294]
2010-03-07 13:11:10 +00:00
bbccfbbab4 Remove use of deprecated macro in result_of test.
[SVN r60293]
2010-03-07 13:10:54 +00:00
8af4250c3c Suppress/fix some msvc and gcc compiler warnings ([57494]).
[SVN r60291]
2010-03-07 12:13:29 +00:00
e30889304c Merge some tests for unwrap ([47296], [47297])
[SVN r60290]
2010-03-07 12:11:44 +00:00
b4dee80e61 Merge various result_of changes.
- [42234] Reduce header dependencies, from Shunsuke Sogame. Fixes #1535
 - [45256] result_of implementation that makes use of C++0x decltype, from Daniel Walker. Fixes #862.
 - [48620] Fix result_of to work with const-qualified function pointers. Fixes #1310
 - [60052] Remove use of deprecated config macro in result_of.



[SVN r60289]
2010-03-07 12:08:00 +00:00
74a6a693d3 Remove use of deprecated config macro in result_of.
[SVN r60052]
2010-03-01 19:39:52 +00:00
bf713ad47a Revert unintentional reference to "noncopyable_adl_barrier" test that's not checked in.
[SVN r59332]
2010-01-28 14:41:16 +00:00
76b17c497b Support different MS calling conventions, thanks to Nicolas Lelong.
Closes #3833.


[SVN r59247]
2010-01-24 02:08:46 +00:00
a47dce770c Fix some whitespace differences between trunk and release.
[SVN r58878]
2010-01-10 19:17:23 +00:00
dab1e8e522 Merging changes from trunk.
[SVN r58421]
2009-12-16 22:26:57 +00:00
3de5974419 Suppressing warnings. Please report any problems (may have broken something!)
[SVN r58072]
2009-12-01 02:16:50 +00:00
7eb1536590 Suppress/fix some msvc and gcc compiler warnings.
[SVN r57494]
2009-11-08 18:53:59 +00:00
583422cda2 Add swap to utility index page.
Merged revisions 47093 via svnmerge from 
https://svn.boost.org/svn/boost/trunk


[SVN r57482]
2009-11-08 11:45:20 +00:00
9339431e03 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
ee146a02a1 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
c131cbd0b2 Merged value_init from the trunk, including fix of #2548, regarding "const value_initialized".
[SVN r56547]
2009-10-03 10:19:09 +00:00
f2349baf7d Updated value_init documentation, because the fix of #2548 was not yet included with Boost release 1.40.0.
[SVN r56544]
2009-10-03 09:18:26 +00:00
f8bef7ba95 Merged value_init_test from trunk, inc. [51356], anticipating the fix of ticket #2548, which will remove implicit conversion from const value_initialized<T> to non-const T&.
[SVN r56543]
2009-10-03 09:08:10 +00:00
e54cbf3053 Merged Swap documentation from trunk, including revision [56107] and [56108].
[SVN r56541]
2009-10-03 08:15:14 +00:00
8745ca628a Updated revision date of Boost Swap documentation
[SVN r56108]
2009-09-08 17:07:13 +00:00
ba61e9d796 Mentioned swap.hpp header, as requested by Thorsten Ottosen <http://lists.boost.org/Archives/boost/2009/06/153477.php> and David Abrahams <http://lists.boost.org/Archives/boost/2009/09/156064.php>
[SVN r56107]
2009-09-08 16:54:54 +00:00
d5291d08b8 Merged 52463
[SVN r55485]
2009-08-09 13:45:03 +00:00
afe74fffbc 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
61755605af Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
cd12e322bd Merging in changes trunk updates: adding standard error_info typedefs, updating the documentation.
[SVN r55094]
2009-07-22 20:55:50 +00:00
09a0137016 Reverted value_init revision [54502], intel_9_value_init_conversion-operator.patch from ticket #2548, as it only increased the number of compile errors at the regression page, and Fernando Cacciola also suggested me to leave it broken (without the patch), for this specific (old) compiler version.
[SVN r54832]
2009-07-09 08:06:19 +00:00
a1d3ec6c53 Documentation update
[SVN r54828]
2009-07-09 03:51:30 +00:00
5be3004e6c Added commonly used error_info typedefs.
Added boost/exception/all.hpp.
Removed tabs from source files.

[SVN r54825]
2009-07-08 23:44:28 +00:00
d387905150 Updated documentation of value_initialized, according to a remark by Daniel James at ticket #2548
[SVN r54503]
2009-06-29 18:04:24 +00:00
b514e40733 Worked around Intel 9 specific ambiguity w.r.t. value_initialized conversion operators, by applying intel_9_value_init_conversion-operator.patch, as discussed w/ Daniel James at ticket #2548
[SVN r54502]
2009-06-29 17:53:33 +00:00
8cb975feb7 Merge [47295] to release.
[SVN r53602]
2009-06-03 14:45:12 +00:00
ffe151458e Use local copy of the valid HTML 4.01 icon, and make sure all the pages
that use it are valid.

Merged revisions 53047-53048 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53047 | danieljames | 2009-05-16 15:17:20 +0100 (Sat, 16 May 2009) | 1 line
  
  Fix some validation errors.
........
  r53048 | danieljames | 2009-05-16 15:23:59 +0100 (Sat, 16 May 2009) | 1 line
  
  Use a local copy of the valid HTML 4.01 icon.
........


[SVN r53258]
2009-05-25 20:06:26 +00:00
4003a9f74a Merge [53060] from the trunk.
[SVN r53197]
2009-05-23 05:36:13 +00:00
211eb04f33 Merge [44151], [48025] to release. Closes #3064.
[SVN r53172]
2009-05-22 09:00:11 +00:00
e57213b298 Fixed almost all tab and min/max issues found by inspect tool
[SVN r53142]
2009-05-20 19:41:20 +00:00
b02677375f Fixed most tab and min/max issues from trunk inspection report
[SVN r53141]
2009-05-20 19:19:00 +00:00
61a6015b5a Replace aFactoty with aFactory. Fixes #3019
[SVN r53060]
2009-05-17 00:06:34 +00:00
51f9adbfa1 Merged revisions 52837 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r52837 | eric_niebler | 2009-05-07 10:47:08 -0700 (Thu, 07 May 2009) | 1 line
  
  eliminate noisy warning on msvc
........


[SVN r53054]
2009-05-16 18:15:17 +00:00
682032a340 Use a local copy of the valid HTML 4.01 icon.
[SVN r53048]
2009-05-16 14:23:59 +00:00
eaaf17a88f tuning up cmakefiles for unordered, utility
[SVN r53008]
2009-05-15 00:21:14 +00:00
48cfd42123 tune up ptr_container, utility tests in cmakeland
[SVN r53007]
2009-05-14 23:56:22 +00:00
76aa5d2f27 more cmakefile tweaks
[SVN r52999]
2009-05-14 19:58:42 +00:00
67afd7e315 eliminate noisy warning on msvc, fixes #2993
[SVN r52837]
2009-05-07 17:47:08 +00:00
75cf20cace primary operand type must be class type, see ticket #2938
[SVN r52463]
2009-04-18 09:06:31 +00:00
ce67dde4f0 Documentation update
[SVN r52091]
2009-03-31 22:16:49 +00:00
a69e872a91 Merge [51977], [51986], [52010] to release.
[SVN r52040]
2009-03-28 20:53:26 +00:00
91385ac627 Another try at the Sun workaround.
[SVN r52010]
2009-03-27 12:50:09 +00:00
61e9b93f7c Try the Sun workaround with int instead of size_t.
[SVN r51986]
2009-03-26 13:05:05 +00:00
d97b303777 Try to fix array addressof failures on Sun C++.
[SVN r51977]
2009-03-26 00:06:47 +00:00
e3640e45c2 Merge [51872], [51891] to release. Closes #2878.
[SVN r51907]
2009-03-22 20:05:02 +00:00
3900e8ece4 Disable new addressof code for all Borland versions. Refs #2878.
[SVN r51891]
2009-03-21 20:20:37 +00:00
e27fc4a853 Attempt to fix addressof in trunk to handle classes with conversion operators. Refs #2878.
[SVN r51872]
2009-03-20 17:14:00 +00:00
b7cd171b2b Merge [51512] to release. Closes #2128.
[SVN r51534]
2009-03-02 16:32:03 +00:00
f7aa9a8935 Refs #2128 (fixed in trunk.)
[SVN r51512]
2009-03-01 17:04:14 +00:00
0af1959b30 Updated value_initialized documentation and test following changeset [51355].
[SVN r51356]
2009-02-20 20:35:34 +00:00
5f0cf4f5de Fixed const issue of value_initialized according to ticket #2548. See also http://lists.boost.org/Archives/boost/2009/02/148489.php
[SVN r51355]
2009-02-20 20:28:54 +00:00
0282c8a141 added #error in headers incompatible with BOOST_NO_EXCEPTIONS
[SVN r50887]
2009-01-30 00:06:01 +00:00
b2e6a82adb This html was outdated; changed to forward to throw_exception.html documentation from Boost Exception
[SVN r50880]
2009-01-29 19:14:05 +00:00
6725719bd9 This html was outdated; changed to forward to throw_exception.html documentation from Boost Exception
[SVN r50879]
2009-01-29 19:13:08 +00:00
390372294a merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
ffbbf38e12 Merged new array-of-array tests of swap utility from trunk to release branch, following changeset [49954].
[SVN r50227]
2008-12-09 18:21:25 +00:00
9e73b2c6ae Merged value_initialized::swap from trunk [48424] and [48425], according to ticket #2243, as was agreed with Fernando Cacciola.
[SVN r49967]
2008-11-27 19:37:39 +00:00
97e11b024e [utility/swap] Distinguished between testing array-of-array-of-class and array-of-array-of-int, as the latter appears to succeed on CodeGear 6.10 while the former does not.
[SVN r49954]
2008-11-27 11:14:52 +00:00
118e473a3d [utility/swap] Added comment to various array swapping tests, added member typedef to swap_test_template, to make the test more realistic.
[SVN r49953]
2008-11-27 11:08:05 +00:00
d4b6193f94 Replaced swap/test/swap_arrays by more specific tests: array_of_array, array_of_class, and array_of_int.
[SVN r49916]
2008-11-24 17:41:15 +00:00
633832e872 Merged libs/utility/swap.html from trunk to release (r47094 through r49914)
[SVN r49915]
2008-11-24 16:50:22 +00:00
d420c98a53 Added array_of_template test, testing the boost::swap utility on an array of objects of a template class.
[SVN r49862]
2008-11-21 21:28:47 +00:00
862cb2a4e0 Merged revisions 49661-49662,49666,49669,49735,49756,49770,49811 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r49661 | danieljames | 2008-11-09 12:03:45 +0000 (Sun, 09 Nov 2008) | 1 line
  
  Move hash detail headers out of boost/functional/detail.
........
  r49662 | danieljames | 2008-11-09 12:11:50 +0000 (Sun, 09 Nov 2008) | 1 line
  
  Add a forwarding header for container_fwd.hpp
........
  r49666 | danieljames | 2008-11-09 19:12:05 +0000 (Sun, 09 Nov 2008) | 1 line
  
  Avoid comparing default initialised iterators in position_iterator.
........
  r49669 | danieljames | 2008-11-09 21:57:38 +0000 (Sun, 09 Nov 2008) | 2 lines
  
  Add link to the header to the synopsis in reference documentation.
  Refs #2214
........
  r49735 | danieljames | 2008-11-14 12:51:00 +0000 (Fri, 14 Nov 2008) | 1 line
  
  Explicitly specify the template parameters in the unordered container friend, in order to avoid some warnings.
........
  r49756 | danieljames | 2008-11-14 16:11:16 +0000 (Fri, 14 Nov 2008) | 1 line
  
  Use pragmas to suppress a Visual C++ warning.
........
  r49770 | danieljames | 2008-11-15 13:07:29 +0000 (Sat, 15 Nov 2008) | 1 line
  
  Use the new swap library.
........
  r49811 | danieljames | 2008-11-16 23:10:00 +0000 (Sun, 16 Nov 2008) | 1 line
  
  Fix a typo.
........


[SVN r49855]
2008-11-20 22:53:20 +00:00
d153ab4daa Fix a typo.
[SVN r49811]
2008-11-16 23:10:00 +00:00
561f83b991 Updated swap.html because LWG issue 809 is now accepted as a defect. Fixed some HTML formatting.
[SVN r49771]
2008-11-15 15:07:42 +00:00
b012f16ee5 Merged utility/swap documentation to release branch.
[SVN r49763]
2008-11-15 01:15:54 +00:00
3d96ab26d4 Merged utility/swap tests to release branch.
[SVN r49762]
2008-11-15 01:13:01 +00:00
8652bf51ec Merged utility/swap to release branch.
[SVN r49761]
2008-11-15 01:11:24 +00:00
57124703f9 Fixing include path to compile with modularized source tree.
[SVN r49685]
2008-11-11 17:22:34 +00:00
53f6d10652 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
ebe853ff2f 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
487a5c1ea5 Swap documentation: fixed a misspelling of the name of Steven Watanabe.
[SVN r49416]
2008-10-21 09:55:54 +00:00
9168cb9c61 CodeGear patch. Fixes #2341
[SVN r49319]
2008-10-13 19:21:03 +00:00
e1991374ae Merge quickbook workaround and fix some links.
Merged revisions 48987,49230-49231 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r48987 | danieljames | 2008-09-28 13:21:39 +0100 (Sun, 28 Sep 2008) | 1 line
  
  Clean up some link errors.
........
  r49230 | danieljames | 2008-10-09 23:13:48 +0100 (Thu, 09 Oct 2008) | 1 line
  
  position_iterator is meant to be a forward iterator, so avoid using operator+ with it.
........
  r49231 | danieljames | 2008-10-09 23:14:14 +0100 (Thu, 09 Oct 2008) | 4 lines
  
  Work around the problems with window newlines in position_iterator. (I'm
  about to fix them, but this will get quickbook working immediately).
  
  Fixes #2155
........


[SVN r49242]
2008-10-10 09:29:21 +00:00
c4338b1ce8 Clean up some link errors.
[SVN r48987]
2008-09-28 12:21:39 +00:00
ddd8a58ae0 Fixes #2341.
[SVN r48910]
2008-09-20 15:39:47 +00:00
d0ee9a7c28 Boost Exception major refactoring: works with or without RTTI, vastly improved boost::throw_exception integration.
[SVN r48905]
2008-09-19 20:29:26 +00:00
10e83b490b Merged BOOST_BINARY utility macro.
[SVN r48879]
2008-09-19 08:19:02 +00:00
4b24dba257 Replaced copyright symbols with (c) to match trunk
[SVN r48842]
2008-09-18 02:54:03 +00:00
28061ba3a8 Removed boost directory binary.hpp.
[SVN r48804]
2008-09-17 01:08:03 +00:00
5d53e3f837 Changed BOOST_BINARY docs.
[SVN r48641]
2008-09-06 21:51:53 +00:00
e86ce1cb1f Changed wording for BOOST_BINARY docs.
[SVN r48640]
2008-09-06 21:49:49 +00:00
f15c96ffb0 Adding binary literal utility.
[SVN r48637]
2008-09-06 21:11:48 +00:00
a487f72329 Fix result_of to work with const-qualified function pointers. Fixes #1310
[SVN r48620]
2008-09-05 19:58:30 +00:00
9f08ed6de0 minor change in boost/exception.hpp
[SVN r48546]
2008-09-02 21:25:47 +00:00
2077d0dace simplified further
[SVN r48485]
2008-08-31 02:40:42 +00:00
7f2348269b Boost Exception now works with BOOST_NO_RTTI and/or BOOST_NO_TYPEID.
[SVN r48429]
2008-08-28 23:49:55 +00:00
6b6e1c3252 Added value_initialized::swap documentation + test
[SVN r48425]
2008-08-28 19:00:20 +00:00
55f303baec Added value_initialized::swap according to ticket #2243, as agreed with Fernando Cacciola :-)
[SVN r48424]
2008-08-28 18:37:45 +00:00
d264005c11 Extended swap_arrays test, checking that boost::swap does correctly exchange the values of its arguments.
[SVN r48247]
2008-08-20 08:29:54 +00:00
2cde009bb1 Added extra checks, checking that boost::swap does correctly exchange the values of its arguments, as I mentioned at "Re: [boost] [swap] Renaming boost_swap_impl::swap_impl and/or its namespace?", http://lists.boost.org/Archives/boost/2008/08/141027.php
[SVN r48246]
2008-08-20 08:28:35 +00:00
7bfb7c8a61 Added a data member to swap_test_class and made it EqualityComparable, as I mentioned at "Re: [boost] [swap] Renaming boost_swap_impl::swap_impl and/or its namespace?", http://lists.boost.org/Archives/boost/2008/08/141027.php
[SVN r48245]
2008-08-20 08:25:23 +00:00
5c42397244 Added explanatory comments, requested by Isaac Dupree, "Re: [boost] [swap] Renaming boost_swap_impl::swap_impl and/or its namespace?", http://lists.boost.org/Archives/boost/2008/08/141007.php
[SVN r48171]
2008-08-16 08:56:19 +00:00
782c132d99 Fix Windows-1252 dash in UTF-8 document.
[SVN r48133]
2008-08-13 22:00:35 +00:00
36899afa3f added/switched "euclidean" spelling
[SVN r48025]
2008-08-07 20:47:58 +00:00
7e3e326faf Updated documentation to remove references to the 'ADL barrier'
[SVN r47973]
2008-08-04 18:25:45 +00:00
7019e18149 Renamed 'test_adl_barrier.cpp' to 'no_ambiguity_in_boost.cpp' and altered comments to reflect new disambiguation technique.
[SVN r47972]
2008-08-04 18:22:10 +00:00
49faf23433 Updated copyright info.
[SVN r47971]
2008-08-04 18:16:16 +00:00
62836f2928 Changed 'using std::swap;' to 'using namesapce std;' in swap_impl function to work around ADL bugs in some compilers.
[SVN r47967]
2008-08-04 11:21:02 +00:00
1ecf3ceb74 Added swap tests for std types, as discussed at "Re: [boost] [swap] Workaround for ADL failures of MSVC 7.1 and Borland okay?", http://lists.boost.org/Archives/boost/2008/08/140589.php
[SVN r47943]
2008-08-02 11:41:47 +00:00
2aa48414c9 Removed swap_adl_barrier namespace, as discussed at "Re: [boost] [swap] How to fix ADL barrier for XL, Intel, GCC, Sun and Como?", http://lists.boost.org/Archives/boost/2008/07/140511.php
[SVN r47920]
2008-07-31 20:18:04 +00:00
d215f2176c Applied "swap.hpp.patch" by Steven Watanabe, "Re: [boost] [swap] How to fix ADL barrier for XL, Intel, GCC, Sun and Como?", http://lists.boost.org/Archives/boost/2008/07/140482.php
[SVN r47877]
2008-07-30 08:04:34 +00:00
c286d62223 Fixed comment in swap/test/specialized_in_boost_and_other.cpp
[SVN r47840]
2008-07-27 12:46:45 +00:00
3fd0ea6e75 Added specialized_in_boost_and_other to swap/test, as discussed at "[boost] [swap] End-user allowed to add overloads to boost namespace?", http://lists.boost.org/Archives/boost/2008/07/140327.php
[SVN r47839]
2008-07-27 11:35:33 +00:00
b050431638 Added a newline to swap/test/lib_header_1.cpp, hoping to fix Sun 5.x compile issue, "Error: There is extra text on this line"
[SVN r47829]
2008-07-26 17:47:59 +00:00
b311fcefb2 Added test_adl_barrier to swap/test, as discussed with Joseph Gauterin.
[SVN r47808]
2008-07-25 18:48:09 +00:00
899c92420c Fixed silly little typo of mine, in test/swap_arrays.cpp
[SVN r47629]
2008-07-20 12:18:25 +00:00
64a0e0cb20 Added swap_test_class swap functions to test/swap_arrays.cpp. My fault, they should have been there already!
[SVN r47628]
2008-07-20 12:13:33 +00:00
ece6992540 Fixed silly little bug of mine in swap/test/swap_arrays.cpp
[SVN r47626]
2008-07-20 11:05:49 +00:00
6098304ea8 Corrected duplicated file contents
[SVN r47607]
2008-07-19 19:40:12 +00:00
28fff2d821 Remove duplicate content.
[SVN r47360]
2008-07-12 17:56:01 +00:00
0ce3885d59 Added an anonymous unwrapping test.
[SVN r47297]
2008-07-10 23:01:26 +00:00
1823481d96 Added tests for unwrap_ref.
[SVN r47296]
2008-07-10 19:29:02 +00:00
cce5d77d2b Added unwrap_ref.
[SVN r47295]
2008-07-10 19:28:49 +00:00
3c5c2bc107 Moved utility\swap to the trunk, as discussed in trac issue #2056.
[SVN r47093]
2008-07-05 11:16:38 +00:00
7a036f6f3a Merge some small fixes from trunk.
Merged revisions 46740,46742,47002,47040 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r46740 | danieljames | 2008-06-26 20:20:56 +0100 (Thu, 26 Jun 2008) | 1 line
  
  Fix a character encoding error.
........
  r46742 | danieljames | 2008-06-26 20:25:38 +0100 (Thu, 26 Jun 2008) | 6 lines
  
  Give the asio documentation its own target.
  
  The asio documentation is built with the rest of the combined documentation but
  is really separate. So give it its own target so that separate parts can be
  built separately.
........
  r47040 | danieljames | 2008-07-03 15:34:56 +0100 (Thu, 03 Jul 2008) | 1 line
  
  Workaround for some template syntax not supported in old versions of Visual C++ 6.5
........


[SVN r47078]
2008-07-04 17:04:47 +00:00
e632b0fb1f Boost Exception
In other libraries, watch for compile error referring to throw_exception_assert_compatibility in boost::throw_exception. Resolve by throwing an exception that derives from std::exception. This is not a new requirement but it is being enforced now.

[SVN r46818]
2008-06-28 18:29:40 +00:00
17bee9d43f With his kind permission, change Jaakko "Järvi" to "Jarvi"
[SVN r46809]
2008-06-28 13:57:20 +00:00
177ee78bbb With his kind permission, change Jaakko "Järvi" to "Jarvi"
[SVN r46808]
2008-06-28 13:45:21 +00:00
f1ec0c4d04 Fix a character encoding error.
[SVN r46740]
2008-06-26 19:20:56 +00:00
4a564744fe documentation update, added function exception::diagnostic_information, added std::exception to_string overload, removed tabs from source files
[SVN r46697]
2008-06-25 23:27:56 +00:00
492a8ad213 Merge of new boost.thread code along with required changes from boost.bind
[SVN r46474]
2008-06-18 13:01:08 +00:00
8827b8ed8b Merged value_init doc + test from trunk, including doc and test for boost::initialized_value, that was added with changeset [46464]
[SVN r46465]
2008-06-17 22:17:14 +00:00
8849fbc52d Merged value_init.hpp from trunk, including new boost::initialized_value object. (Was discussed beforehand with Fernando Cacciola.)
[SVN r46464]
2008-06-17 22:14:09 +00:00
67f3ca090a Fixed value_init test + doc, according to change of boost::initialized_value, revision [45685]
[SVN r45686]
2008-05-23 16:48:10 +00:00
8efae71f4a Changed boost::initialized_value from a class to an instance, to make its use more convenient, as discussed with Fernando.
[SVN r45685]
2008-05-23 16:46:43 +00:00
50bc75a802 Add minor documentation fixes to the release branch.
(I left out the changes to the hash library).

Merged via svnmerge from 
https://svn.boost.org/svn/boost/trunk

................
  r44807 | danieljames | 2008-04-27 08:39:49 +0100 (Sun, 27 Apr 2008) | 78 lines
  
  Merge in documentation fixes.  Apart from the change to optional's documenation
  Jamfile, which I included by mistake.
  
  I wrote about this at:
  
  http://lists.boost.org/Archives/boost/2008/04/136405.php
  
  Merged revisions 44585-44806 via svnmerge from 
  https://svn.boost.org/svn/boost/branches/doc
  
  ........
    r44585 | danieljames | 2008-04-19 16:25:27 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix broken link to vacpp in bjam docs.
  ........
    r44586 | danieljames | 2008-04-19 16:27:36 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix broken link to bcpp in bjam docs.
  ........
    r44587 | danieljames | 2008-04-19 16:33:58 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    DateTime documentation - Fix a link to the serialization library.
  ........
    r44588 | danieljames | 2008-04-19 16:35:36 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix some links in interprocess & intrusive.
  ........
    r44589 | danieljames | 2008-04-19 16:37:39 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix some links in the python docs.
  ........
    r44590 | danieljames | 2008-04-19 16:38:29 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Work around a quickbook bug which is affecting the python docs.
  ........
    r44591 | danieljames | 2008-04-19 16:39:34 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix a broken link in the numeric conversion docs.
  ........
    r44592 | danieljames | 2008-04-19 16:40:45 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix some links in the optional docs.
  ........
    r44593 | danieljames | 2008-04-19 16:42:09 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix link to the hash documentation from bimap.
  ........
    r44599 | danieljames | 2008-04-19 18:07:33 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix a typo in the format library.
  ........
    r44600 | danieljames | 2008-04-19 19:20:59 +0100 (Sat, 19 Apr 2008) | 1 line
    
    Initialise svnmerge.
  ........
    r44641 | danieljames | 2008-04-20 18:59:47 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix the lincense url in shared container iterator documentation.
  ........
    r44642 | danieljames | 2008-04-20 19:00:00 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix image link in the mpi documentation.
  ........
    r44643 | danieljames | 2008-04-20 19:00:11 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix a typo in the spirit docs.
  ........
    r44644 | danieljames | 2008-04-20 19:00:23 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Escape the slash so that quickbook doesn't think it the start of an italic section, and mess up the link. Refs #1844
  ........
    r44647 | danieljames | 2008-04-20 19:39:47 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix another typo in spirit docs.
  ........
................
  r45232 | danieljames | 2008-05-08 22:50:19 +0100 (Thu, 08 May 2008) | 1 line
  
  Fix some invalid xml by replacing ampersands with character entities.
................
  r45576 | danieljames | 2008-05-20 16:39:25 +0100 (Tue, 20 May 2008) | 20 lines
  
  Merge some small documentation fixes from the doc branch, and mark some
  previously merged changes as merged.
  
  Merged revisions 44811,45129,45142,45154,45281-45282,45365 via svnmerge from 
  https://svn.boost.org/svn/boost/branches/doc
  
  ........
    r45129 | danieljames | 2008-05-05 12:36:50 +0100 (Mon, 05 May 2008) | 2 lines
    
    Update navbar links in boostbook.
  ........
    r45282 | danieljames | 2008-05-11 14:15:31 +0100 (Sun, 11 May 2008) | 2 lines
    
    Group functions in the hash header - requires Frank's free-function-group fix.
    (not included in release branch).
  ........
    r45365 | danieljames | 2008-05-14 21:39:00 +0100 (Wed, 14 May 2008) | 2 lines
    
    Add boost.root to standalone hash documentation.
    (not included in release branch).
  ........
................


[SVN r45622]
2008-05-21 20:57:05 +00:00
ad0bcf4a00 result_of implementation that makes use of C++0x decltype, from Daniel Walker. Fixes #862.
[SVN r45256]
2008-05-09 22:08:46 +00:00
f1c86c35c4 Merge in documentation fixes. Apart from the change to optional's documenation
Jamfile, which I included by mistake.

Fixes #1659, #1661, #1684, #1685, 1687, #1690, #1801

I wrote about this at:

http://lists.boost.org/Archives/boost/2008/04/136405.php

Merged revisions 44585-44806 via svnmerge from 
https://svn.boost.org/svn/boost/branches/doc

........
  r44585 | danieljames | 2008-04-19 16:25:27 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix broken link to vacpp in bjam docs. Refs #1512
........
  r44586 | danieljames | 2008-04-19 16:27:36 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix broken link to bcpp in bjam docs. Refs #1513
........
  r44587 | danieljames | 2008-04-19 16:33:58 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  DateTime documentation - Fix a link to the serialization library. Refs #1659
........
  r44588 | danieljames | 2008-04-19 16:35:36 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix some links in interprocess & intrusive. Refs #1661
........
  r44589 | danieljames | 2008-04-19 16:37:39 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix some links in the python docs. Refs #1684.
........
  r44590 | danieljames | 2008-04-19 16:38:29 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Work around a quickbook bug which is affecting the python docs. Refs #1684.
........
  r44591 | danieljames | 2008-04-19 16:39:34 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix a broken link in the numeric conversion docs. Refs #1685
........
  r44592 | danieljames | 2008-04-19 16:40:45 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix some links in the optional docs. Refs #1687
........
  r44593 | danieljames | 2008-04-19 16:42:09 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix link to the hash documentation from bimap. Refs #1690
........
  r44599 | danieljames | 2008-04-19 18:07:33 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix a typo in the format library. Refs #1801
........
  r44600 | danieljames | 2008-04-19 19:20:59 +0100 (Sat, 19 Apr 2008) | 1 line
  
  Initialise svnmerge.
........
  r44641 | danieljames | 2008-04-20 18:59:47 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Fix the lincense url in shared container iterator documentation.
........
  r44642 | danieljames | 2008-04-20 19:00:00 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Fix image link in the mpi documentation.
........
  r44643 | danieljames | 2008-04-20 19:00:11 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Fix a typo in the spirit docs.
........
  r44644 | danieljames | 2008-04-20 19:00:23 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Escape the slash so that quickbook doesn't think it the start of an italic section, and mess up the link. Refs #1844
........
  r44647 | danieljames | 2008-04-20 19:39:47 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Fix another typo in spirit docs.
........


[SVN r44807]
2008-04-27 07:39:49 +00:00
a5b85eda07 Fix #1846.
[SVN r44705]
2008-04-21 21:42:29 +00:00
bafe37fdab Boost Exception header compilation tests added.
[SVN r44442]
2008-04-15 21:13:24 +00:00
be50b95508 Added test and fix for "convertible to bool" requirement
[SVN r44151]
2008-04-10 14:38:14 +00:00
96d573d6ca Replaced all occurrences of non-ASCII copyright symbol with '(c)' for people using non-ASCII code pages
[SVN r43992]
2008-04-02 01:42:32 +00:00
9b52e49fda Merge inspection failure fixes from Trunk.
[SVN r43634]
2008-03-15 18:45:28 +00:00
2412b864d6 Fix some inspection report issues.
[SVN r43633]
2008-03-15 18:41:51 +00:00
94865eabe6 boost exception
[SVN r43485]
2008-03-04 01:41:17 +00:00
50268d1b29 Tested the assignment of value_initialized<T>, for T being a C-style array. Related to the fix of changeset [43308]
[SVN r43309]
2008-02-18 22:13:21 +00:00
ad9108c1dc Fixed the assignment of value_initialized<T> for T being a C-style array. (The previous version would trigger a compile error in this case.)
[SVN r43308]
2008-02-18 22:11:19 +00:00
ab479794f3 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
691e4b6c34 Link to people pages on the website, as they've been removed from the download.
[SVN r43209]
2008-02-10 14:56:22 +00:00
28596e678d value_init: Removed aligned_storage::address() calls, to improve TR1 compatibility, as confirmed by John Maddock. Added internal helper function, wrapper_address(), as discussed with Fernando.
[SVN r43025]
2008-01-30 22:42:23 +00:00
1beca24dd8 Removed local named variable from value_initialized::operator=, as Fernando Cacciola suggested me to avoid unnecessary named variables.
[SVN r42869]
2008-01-19 20:52:04 +00:00
721764937f value_init_test now works around Borland 5.82 bug ("Error E2015: Ambiguity..." when using initialized_value), that is fixed with a newer compiler version
[SVN r42868]
2008-01-19 20:21:18 +00:00
a511007d0f Added test and documentation for convenience class initialized_value, that was added with changeset [42815]
[SVN r42816]
2008-01-16 09:37:25 +00:00
8ce58b1675 Added convenience class initialized_value, as announced at http://article.gmane.org/gmane.comp.lib.boost.devel/169833
[SVN r42815]
2008-01-16 09:35:12 +00:00
97b8966337 value_init doc + test: Merged from trunk changeset [42798] to release.
[SVN r42799]
2008-01-15 19:55:28 +00:00
9ed68b8321 value_init doc + test: Added revision date.
[SVN r42798]
2008-01-15 19:53:28 +00:00
79bbf71d0d Minor "beautifications" of value_init documentation, inc. placing references in order of appearance
[SVN r42779]
2008-01-14 21:46:20 +00:00
ac93de7c1b Documented value_init workaround to compiler issues, added new introduction, updated to 2003 edition of C++ Standard -- reviewed by Fernando Cacciola
[SVN r42771]
2008-01-14 18:17:30 +00:00
88099a882f Merged value_init.hpp from trunk [42277] to release branch, thereby resolving ticket #1459 and #1491. Fernando Cacciola (owner of value_init) encouraged me to do the commit.
[SVN r42501]
2008-01-05 22:38:50 +00:00
d731b8e1c5 Added value_init tests, testing copy construction and assignment.
[SVN r42278]
2007-12-24 22:00:37 +00:00
ac1567b3fc value_init now uses aligned_storage::address(), instead of "&x", as recommended by Fernando Cacciola (by mail)
[SVN r42277]
2007-12-24 20:42:16 +00:00
c1fd670480 Reduce header dependencies, from Shunsuke Sogame. Fixes #1535
[SVN r42234]
2007-12-21 21:18:17 +00:00
01274cf6ac value_init.hpp now no longer distinguished between workaround and non-workaround, because many compilers don't do value-initialization well. Fixed copy construction and assignment -- discussed with Fernando Cacciola
[SVN r41942]
2007-12-09 22:49:58 +00:00
8080673977 Added value_init tests if a copy function of T is called when value_initialized<T> is copied -- a case I hadn't thought of before...
[SVN r41919]
2007-12-09 11:53:08 +00:00
a470b591fb Added value_init test for an value_initialized<T> object allocated on the heap.
[SVN r41667]
2007-12-03 21:41:59 +00:00
e1a63495b6 Added missing #include to value_init_test.cpp. (My mistake!)
[SVN r41648]
2007-12-03 18:20:19 +00:00
7300ac83f1 Added value_init test for C style array of bytes
[SVN r41647]
2007-12-03 18:14:37 +00:00
882d38c2c7 Added value_init tests, based upon GCC bug report by Jonathan Wakely. Added URL to Borland bug report.
[SVN r41529]
2007-12-01 12:14:37 +00:00
33041ad664 Added tests for two more struct types to value_init_test -- discussed with Fernando Cacciola
[SVN r41436]
2007-11-28 17:19:37 +00:00
6a2aa822f8 Added value_init test for struct as used in MSVC bug report regarding value-initialization.
[SVN r41423]
2007-11-27 21:34:08 +00:00
d5554eb6d7 Pick up missing smart_ptr, utility, and type_traits files from full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41386]
2007-11-25 22:34:55 +00:00
13bdfb8bbd Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
74462349c2 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
09ab16bfc1 Checked the result of value_init test function, hoping to pinpoint exactly for what particular type T value_initialized<T> might fail, on some platforms
[SVN r41326]
2007-11-24 11:51:03 +00:00
ec46e40809 Code refactoring: removed private base classes of value_initialized, as suggested by Fernando Cacciola.
[SVN r41216]
2007-11-18 22:11:57 +00:00
b3a971e7e9 Copyright and/or License cleanup
[SVN r40890]
2007-11-07 16:08:09 +00:00
7ddb559887 Fix path to test case.
[SVN r40736]
2007-11-04 12:01:16 +00:00
ea8c99b1d5 Added a sentence with a brief explanation of the intended uses of BOOST_VERIFY.
[SVN r40731]
2007-11-03 22:47:17 +00:00
56b0846099 BOOST_VERIFY added.
[SVN r40728]
2007-11-03 20:55:22 +00:00
42e0001370 Added value_initialized<T> test, having T as aggregate POD struct. In the past, this would have triggered MSVC warning C4345; this warning is now disabled within value_init.hpp, changeset [40088]
[SVN r40089]
2007-10-16 17:06:39 +00:00
cd8f85afee Disabled MSVC warning C4345, in response to Gennadiy Rozental, Boost Developer mailing list, "[utility] value_init warning", October 14, 2007. Push'n'pop reminder from Paul A Bristow taken into account.
[SVN r40088]
2007-10-16 17:00:28 +00:00
bddd52c4b9 Fixed bug preventing compilation on Tru64/CXX.
[SVN r39918]
2007-10-11 07:36:41 +00:00
6aa648d315 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
8f03aeac4e Added unit test to make sure that Visual C++ 7.1 ICE reported by Ralf W. Grosse-Kunstleve (Boost Developers mailing list, subject "utility/value_init.hpp: VC 7.1 ICE & workaround") will not occur anymore.
[SVN r39309]
2007-09-16 09:48:28 +00:00
3bb2568fad Visual C++ 7.1 ICE workaround by Ralf W. Grosse-Kunstleve added to ~const_T_base() as well. See also Boost Developers mailing list, subject "utility/value_init.hpp: VC 7.1 ICE & workaround"
[SVN r39308]
2007-09-16 09:33:34 +00:00
01e91a3799 work around Visual C++ 7.1 internal compiler error
[SVN r39302]
2007-09-15 23:11:50 +00:00
55f3c351a3 Added MSVC workaround to value_initialized, as described by ticket #1217, proposed at the Boost Developers mailing list, and discussed with Fernando Cacciola.
[SVN r39157]
2007-09-07 17:17:09 +00:00
3f72b10182 Remove V1 Jamfiles
[SVN r38516]
2007-08-08 19:02:26 +00:00
71cb8cb574 broken msvc name look-up getting confused about which detail namespace
[SVN r38511]
2007-08-08 18:05:24 +00:00
9ff18c2c96 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
c950825ef4 - overloads apply for array construction
- adds support for zero arguments
- lets apply return the result of the new-expression
- revises the preprocessing code


[SVN r38101]
2007-06-26 23:07:25 +00:00
66ca84a45d Update result_of information
[SVN r38024]
2007-06-18 12:48:37 +00:00
d5ea07c737 Merged changes for ticket #979 from HEAD
[SVN r37920]
2007-06-06 20:57:40 +00:00
06404f7d39 Improved empty_base
[SVN r37754]
2007-05-23 22:48:42 +00:00
aa0096bf42 Testsuite for none_t added.
[SVN r37421]
2007-04-12 14:32:38 +00:00
2d860e2574 Fix result_of's handling of F(void).
[SVN r37140]
2007-03-05 15:25:16 +00:00
66514f61ff fix result_of ambiguity error for nullary functions
[SVN r36773]
2007-01-24 06:44:20 +00:00
63cde4d3fd slightly modified implementation works around msvc 7.1/8.0 compiler bugs
[SVN r36668]
2007-01-08 20:38:51 +00:00
1950f292df Merge fixed links from RC_1_34_0.
[SVN r36660]
2007-01-07 23:50:56 +00:00
005c2f3cc8 Fix a couple of links.
[SVN r36656]
2007-01-07 22:58:41 +00:00
09f7aab52d Merged L & C issue fixes & HTML conversions from trunk to branch.
[SVN r36281]
2006-12-05 22:33:21 +00:00
92a0602190 Fixed license & copyright issues and converted to HTML 4.01
[SVN r36280]
2006-12-05 21:11:21 +00:00
30a40f9f76 Linked to current_function.html
[SVN r36268]
2006-12-04 20:31:38 +00:00
c9a3ab1d04 Linked to current_function.html
[SVN r36268]
2006-12-04 20:31:38 +00:00
d9f8bae673 Merge from HEAD.
Allow building of shared versions of some Boost.Test libraries.
Adjust tests to use always use static linking to Boost.Test, since
linking to the shared version requires test changes.

Patch from Juergen Hunold.


[SVN r35990]
2006-11-10 19:59:52 +00:00
0782034333 Allow building of shared versions of some Boost.Test libraries.
Adjust tests to use always use static linking to Boost.Test, since
linking to the shared version requires test changes.

Patch from Juergen Hunold.


[SVN r35989]
2006-11-10 19:09:56 +00:00
3c7b409460 License/copyright edits
[SVN r35958]
2006-11-09 20:34:33 +00:00
0808883f3c License/copyright edits
[SVN r35958]
2006-11-09 20:34:33 +00:00
ee3551e8dc Merged copyright and license addition
[SVN r35907]
2006-11-07 19:27:00 +00:00
2f69501e55 Add copyright, license
[SVN r35905]
2006-11-07 19:11:57 +00:00
95da2e90de Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
5b83f641a8 Removed unneeded semicolon.
[SVN r35636]
2006-10-16 18:01:40 +00:00
6dd93ab916 Removed unneeded semicolon.
[SVN r35636]
2006-10-16 18:01:40 +00:00
c730ab4ffb Parameter library Workarounds for Borland and MSVC
Parameter library explicit markup for expected failures

value_init.hpp:
  Borland workarounds
  Use angle-includes consistently


[SVN r35084]
2006-09-13 03:00:18 +00:00
505d419a1b Resolved an ambiguity.
[SVN r35039]
2006-09-08 00:16:31 +00:00
d968b5f5b9 boost guidelines (mainly from inspect tool: tabs, license reference text, etc.); more to do...
[SVN r34753]
2006-07-27 11:48:49 +00:00
e55610a0d0 Some additional functions added to optional (being new there won't be regressions)
[SVN r34411]
2006-06-26 18:01:38 +00:00
bf968794c9 Fixed an ambiguity.
[SVN r34403]
2006-06-26 01:58:38 +00:00
ce6e9c6698 Digital Mars support (Pavel Vozenilek)
[SVN r34373]
2006-06-22 12:47:19 +00:00
7ac180ed54 Use forwarding to get SFINAE effect in some common use cases.
Rename detail::result_of to detail::result_of_impl to avoid surprises
when result_of is used from within boost::detail.


[SVN r33981]
2006-05-16 22:55:27 +00:00
d809d4e832 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
271ea9e901 Borland 5.81 fix (Alisdair Meredith)
[SVN r33161]
2006-02-27 21:57:38 +00:00
7cd572a326 VC++ warning suppression
[SVN r33001]
2006-02-18 23:03:14 +00:00
90c56ba2ce Update for BCB2006
[SVN r32865]
2006-02-12 20:16:31 +00:00
a5439500f5 Remove dead code, use Boost.Test rather than asserts.
[SVN r32861]
2006-02-12 18:58:08 +00:00
c0f0a4f51d Try again with DMC patch: last attempt broke Borland C++ Builder, so use implicit casts with protected rather than private bases.
[SVN r32524]
2006-02-03 11:00:23 +00:00
7594e00460 Added explicit static_casts when casting *this to a reference-to-base-class: it keeps Digital Mars happy apparently.
[SVN r32413]
2006-01-25 10:45:26 +00:00
f66e844ff1 Merged from Version_1_33_1
[SVN r31949]
2005-12-08 03:23:02 +00:00
62e8cc2b36 Attempted portability fix for Sun compilers
[SVN r31904]
2005-12-04 18:47:02 +00:00
30236f8915 Made the Boost logo link to the home page
[SVN r31112]
2005-09-25 21:54:19 +00:00
155e787ea3 Fix reporting of enable_if tests
[SVN r31060]
2005-09-20 18:35:26 +00:00
1d60d49136 Large patch from Ulrich Eckhardt to fix support for EVC++ 4.
[SVN r30670]
2005-08-25 16:27:28 +00:00
2dffdac9fe Disabiguated the detail namespace.
[SVN r30558]
2005-08-12 19:06:10 +00:00
ddf00eb29d Merged from 1.33.0 release
[SVN r30540]
2005-08-12 13:02:37 +00:00
0a6acd8ce8 Fix broken links
[SVN r30403]
2005-08-03 13:01:57 +00:00
745322e797 Fix broken links
[SVN r30401]
2005-08-03 12:25:30 +00:00
9f10fc03ce More Parameter library reference edits
[SVN r30276]
2005-07-28 04:19:28 +00:00
84fbb3c896 Fix mis-nested namespace scope/#ifdef
[SVN r30159]
2005-07-18 18:50:47 +00:00
865c707756 BOOST_NO_RESULT_OF support
[SVN r30040]
2005-07-13 12:35:37 +00:00
871f3a6779 Don't use the self contained include files for boost.test as this test is linked
with the boost.test library. We end up with multiple defined symbols, otherwise.


[SVN r29559]
2005-06-14 13:46:20 +00:00
aaca5ca871 Updated Borland workaround.
[SVN r29462]
2005-06-07 09:44:19 +00:00
5a4e19989f Workaround for nonconformance to CWG issue 298, checked in on behalf of John Maddock
[SVN r29415]
2005-06-03 19:11:54 +00:00
6ea398c446 Make it clear that POD's are not zero initialised.
[SVN r29254]
2005-05-28 11:51:04 +00:00
1bd83d43e8 Improvements in type_traits have gotten MSVC 7.0 and prior down to 12 failures here
[SVN r29170]
2005-05-24 14:53:49 +00:00
5ca5b4102b Optional's Assignment fixed
[SVN r28412]
2005-04-22 13:28:34 +00:00
aca7699046 Add V2 Jamfile
[SVN r28246]
2005-04-14 13:15:46 +00:00
e702a944ca Fixes to get the tests working with the latest type traits and Boost.Test versions.
[SVN r27864]
2005-03-29 11:21:53 +00:00
a157c345ee Updated is_convertible test cases to check polymorphic-type conversions.
Added more test types to testing header.
Changed utility code to use new test header.


[SVN r27807]
2005-03-24 18:20:18 +00:00
dcb2dd4736 Removed type_traits include, added more tests
[SVN r27712]
2005-03-16 22:02:22 +00:00
ae19cd6236 work-around for Borland addressof(array) bug and associated tests
[SVN r27656]
2005-03-14 23:03:42 +00:00
3ab4d38931 Apply typo fixes from Julio M. Merino Vidal
[SVN r27513]
2005-02-27 17:28:24 +00:00
18c7fb72b5 ADL problem (with VC7.1) fixed
[SVN r27495]
2005-02-24 16:04:49 +00:00
6bb092a9b1 Add comment explaining use of assert.h
[SVN r27473]
2005-02-21 12:32:20 +00:00
f721b8b28c replaced BOOST_TEST
[SVN r27054]
2005-02-03 13:48:49 +00:00
e5ba34472d merge RC_1_32_0 fixes
[SVN r26333]
2004-11-28 04:44:21 +00:00
082ae17eaf merge RC_1_32_0 fixes
[SVN r26328]
2004-11-28 03:35:12 +00:00
dd86e09ab4 merge RC_1_32_0 tab fixes
[SVN r26327]
2004-11-28 03:27:25 +00:00
baff23116e Fixed link to function_output_iterator
[SVN r25949]
2004-10-29 19:19:20 +00:00
e549baf93a move enable_if tests into their own subdirectory
[SVN r25649]
2004-10-10 16:15:58 +00:00
30d46adcb7 bad links fixed
added myself to people


[SVN r25610]
2004-10-07 16:01:24 +00:00
e854726be0 c++boost.gif -> boost.png replacement
[SVN r25573]
2004-10-05 15:45:52 +00:00
d198bd9d96 added explicit return to main
[SVN r25387]
2004-09-24 06:17:26 +00:00
5eb23cecd0 In-place factories moved from /detail to /utility
New value_initalized tests added


[SVN r25377]
2004-09-23 17:03:54 +00:00
eff2c75bba taken care of BOOST_NO_STDC_NAMESPACE
[SVN r25345]
2004-09-22 17:18:06 +00:00
325bd73df7 In-place factories moved from /detail to /utility
New value_initalized tests added


[SVN r25313]
2004-09-21 14:54:32 +00:00
0fcc554abd Initial commit
[SVN r25178]
2004-09-17 16:53:57 +00:00
b685784155 Added new types boost::long_long_type and boost::ulong_long_type in boost/config.hpp and applied these types in place of "long long" throughout. As a result, almost all of boost now compiles cleanly with -ansi -pedantic with gcc. Changes tested with gcc 3.3, 2.95, VC7.1 and Intel 8.
[SVN r24899]
2004-09-04 10:34:49 +00:00
ac90fdc611 merge new MPL version from 'mplbook' branch
[SVN r24874]
2004-09-02 15:41:37 +00:00
51077e49f5 Fixed CW problems and refactored fail cases
[SVN r24870]
2004-09-02 13:19:50 +00:00
0c3199f72d Added my long name
[SVN r24869]
2004-09-02 12:59:42 +00:00
62675a3bcd added copyright/license
[SVN r24814]
2004-08-30 01:31:40 +00:00
c26dbaa620 Updated copyright year list, since the interface changed
[SVN r24801]
2004-08-28 20:51:19 +00:00
8201624959 Moved a template argument default for base_from_member to primary header; removed forwarding header as it's not needed anymore
[SVN r24800]
2004-08-28 20:46:17 +00:00
f2116413d6 Changed constructor templates to be generated with the Preprocessor library; added a control macro for the maximum constructor argument length
[SVN r24799]
2004-08-28 20:24:17 +00:00
b0baebeb0a fix noncopyable, finally
[SVN r24618]
2004-08-20 17:17:06 +00:00
fb943b77d5 License updates
[SVN r24597]
2004-08-19 15:19:17 +00:00
b4b39510fc ADL protection
[SVN r24595]
2004-08-19 13:12:35 +00:00
6f0f05ba12 remove forward declaration for noncopyable
[SVN r24578]
2004-08-19 02:31:29 +00:00
f0b64b6229 ADL protection
[SVN r24564]
2004-08-18 17:01:11 +00:00
4229488989 Added redirection to fix old links.
[SVN r24558]
2004-08-18 13:55:35 +00:00
acd2e6ef2b Added Daryle Walker's copyrights as requested.
[SVN r24481]
2004-08-15 10:13:49 +00:00
c26aaed71f Moved to BSL
[SVN r24446]
2004-08-12 17:13:07 +00:00
326d7ad4d7 Removed boost.org copyright assignments, and reverted to orginal author (as based on cvs history).
[SVN r24402]
2004-08-11 10:59:33 +00:00
c76a2f4aab Add my license info
[SVN r24373]
2004-08-10 13:57:30 +00:00
d8b0ff2d7e Removed Boost.org copyrights and replaced with originating authors copyright instead.
[SVN r24372]
2004-08-10 12:53:34 +00:00
996ce2d307 Updated Beman Dawes' licence statement to use the new prefered form of words.
[SVN r24370]
2004-08-10 10:34:20 +00:00
167fa4154f Eliminated unreviewed, unused, noncompiling code
[SVN r24314]
2004-08-05 18:57:39 +00:00
0c7e7c3c39 half_open_range_test removed
[SVN r24313]
2004-08-05 18:46:55 +00:00
9d8f8f41dc Include for test library fixed
[SVN r24299]
2004-08-05 09:23:05 +00:00
39c4445b39 add missing tests, reorder tests by filename
[SVN r24216]
2004-08-01 05:40:21 +00:00
7819b022ad License update
[SVN r24180]
2004-07-30 04:46:56 +00:00
65d27e7f86 License update
[SVN r24175]
2004-07-30 01:47:08 +00:00
212a70bf77 Remove "and" from copyright
[SVN r24167]
2004-07-29 15:50:36 +00:00
6b5dc18a46 Converted to Boost Software License, Version 1.0
[SVN r24096]
2004-07-27 03:43:34 +00:00
0917f83b9c Converted to Boost Software License, Version 1.0
[SVN r24055]
2004-07-26 00:32:12 +00:00
7322bd3903 License update
[SVN r24048]
2004-07-25 19:13:06 +00:00
e998010184 Add license
[SVN r24021]
2004-07-25 03:57:20 +00:00
918a1c93e4 Doug Gregor -> Douglas Gregor
[SVN r24016]
2004-07-25 02:29:29 +00:00
14c87853c2 Needed to include cstddef to get std::size_t
[SVN r24000]
2004-07-23 18:42:30 +00:00
d5a5b84a40 Switch the test to use std::stringstream, not std::ostrstream, since
the latter is deprecated and gcc warns whenever one tries to use it.


[SVN r23896]
2004-07-21 12:28:18 +00:00
35d3c03d19 Update
[SVN r23085]
2004-06-11 11:18:50 +00:00
8933fbb254 The binary_search_test does not require Boost.Test all all, and does not
provide 'test_main' or 'unit_test_main', so don't link to Boost.Test.


[SVN r23073]
2004-06-10 11:49:39 +00:00
c320330cd5 fixed a typo
[SVN r22754]
2004-05-06 22:38:34 +00:00
822b46a3df Complain when compiler can't support result_of
[SVN r22749]
2004-05-06 17:29:54 +00:00
a821ef6e2c Added enable_if.hpp as an include
[SVN r22735]
2004-05-04 16:07:00 +00:00
491db15997 boost/utility/result_of.hpp, boost/utility/detail/result_of_iterate.hpp:
- result_of implementation

libs/utility/test/result_of_test.cpp:
  - result_of tests

libs/utility/test/Jamfile, libs/utility/test/Jamfile.v2:
  - run result_of tests

libs/utility/utility.htm:
  - document result_of

libs/libraries.htm:
  - list result_of

index.htm:
  - announce result_of


[SVN r22720]
2004-05-02 19:55:02 +00:00
b6c826a139 shared_container_iterator library:
- updated Copyright and License notices
 - Added shared_iterator_test to the iterator test suite.


[SVN r22140]
2004-02-02 22:16:36 +00:00
7b472a05ee Obsoleted old iterator adaptor docs
[SVN r22101]
2004-02-01 04:30:15 +00:00
9a07bc0d9b Added missing include <cstddef>
[SVN r21993]
2004-01-27 11:24:25 +00:00
154d6bb198 When we have a compressed pair of two types that are the same, and both empty, then we must still have two distict objects in the pair.
[SVN r21958]
2004-01-26 11:29:07 +00:00
0dde936e61 DM fixes
[SVN r21933]
2004-01-26 00:19:59 +00:00
918bf25039 Fixed documentation for less_pointees
[SVN r21737]
2004-01-14 20:22:00 +00:00
04fda4fb4e Use proper syntax to refer to Boost.Test.
[SVN r21566]
2004-01-09 13:03:16 +00:00
e14a250d6e pro9 workarounds; some ADL protection for is_xxx
[SVN r21529]
2004-01-07 14:07:21 +00:00
806745f24e Fix tabs in file.
[SVN r21399]
2003-12-26 23:26:49 +00:00
4231f774e4 fix next_prior_test.cpp directory
[SVN r21384]
2003-12-23 19:14:37 +00:00
dfc320124f Extended next/prior using patch from Daniel Walker (Daniel.Walker-at-bowneglobal.com)
[SVN r21382]
2003-12-23 14:59:59 +00:00
be43ba1569 Improved workarounds.
[SVN r21157]
2003-12-06 03:57:54 +00:00
f3f879555a Fixed result_type
[SVN r21155]
2003-12-05 22:03:33 +00:00
3155044abd added dummy versions of enable_if templates for platforms that
have BOOST_NO_SFINAE defined


[SVN r21154]
2003-12-05 21:38:43 +00:00
484d184de5 guarded enable_if definitions with BOOST_NO_SFINAE
[SVN r21149]
2003-12-05 16:31:38 +00:00
3305cf1592 Fixed a bug in the semantics of less_pointees() {again}
[SVN r21133]
2003-12-04 01:53:29 +00:00
ec36cd8c54 Fixed a bug in the semantics of less_pointees()
[SVN r21132]
2003-12-04 01:47:31 +00:00
61fb5a0b8f fix broken link to logo
[SVN r21122]
2003-12-03 14:36:38 +00:00
8024c3e9c7 Updated license terms
[SVN r21120]
2003-12-03 13:34:11 +00:00
2f5945d0cd Removed bool_testable, added note about portability of separate, explicit instantiation, changed license of documentation
[SVN r21110]
2003-12-03 07:01:28 +00:00
929517d6d7 Added enable_if library
[SVN r21090]
2003-12-02 21:41:15 +00:00
abcab174a5 _MSC_VER use clarified.
[SVN r20992]
2003-11-28 15:35:21 +00:00
801be90699 Moved from "utility" to "detail" until a Fast Track Review formalizes it.
[SVN r20983]
2003-11-28 14:36:21 +00:00
265c2348b8 Removed access category tags from iterator library, made corresponding
changes elsewhere.

boost/iterator and libs/iterator/test were updated from
branch "simplify"


[SVN r20905]
2003-11-22 01:18:37 +00:00
fb95bcc64c Moved some of my stuff to the Boost Software License, Version 1.0
[SVN r20681]
2003-11-05 07:04:53 +00:00
aedc410525 New License
[SVN r20607]
2003-11-03 02:59:08 +00:00
7fa440c154 *** empty log message ***
[SVN r20511]
2003-10-28 00:09:18 +00:00
746e0fad2b Changed email address to john@johnmaddock.co.uk
[SVN r20472]
2003-10-24 11:13:42 +00:00
1616f6f5a8 Update credits for R. Samuel Klatchko
[SVN r20325]
2003-10-09 14:16:15 +00:00
ca3e7d8530 Add V2 Jamfile
[SVN r20270]
2003-10-07 07:25:24 +00:00
f0f753ba6c Typed in place construction added
[SVN r20070]
2003-09-15 20:28:10 +00:00
532065b51b Change license message to reference Boost Software License
[SVN r20038]
2003-09-12 17:09:29 +00:00
4bfb534bae Added for new Boost.Optional functionality
[SVN r19995]
2003-09-10 15:40:47 +00:00
95ba7a4381 Use the import rule
[SVN r19968]
2003-09-08 17:38:49 +00:00
e92213431e Removed tie_example.cpp per Daniel's request
[SVN r19910]
2003-09-03 05:24:48 +00:00
7dd7daee1b Removed obsolete references to utility/tie
[SVN r19902]
2003-09-01 21:04:26 +00:00
953cc46220 Removed code-breaking change from boost/detail/iterator.hpp and
corresponding workarounds from tests.

Added permutation_iterator_test to the suite after fixing it up -- it
was riddled with bugs!


[SVN r19841]
2003-08-28 20:18:51 +00:00
b5ae0ad86b Moved to much cleaner system of using BOOST_TT_BROKEN_COMPILER_SPEC
for handling vc6/7 deficiencies with iterator_traits.

Fixed a bug in iterator_facade which was causing incomplete types to
be passed through is_convertible.

Reinstated libs/utility/iterator_traits_test.cpp


[SVN r19840]
2003-08-28 16:52:02 +00:00
c86fcbf456 Fix for Metrowerks CW
[SVN r19626]
2003-08-16 01:05:43 +00:00
6ded8b9ad6 Initial revision.
[SVN r19536]
2003-08-11 19:24:03 +00:00
bb6a6272e1 Updated shared_container_iterator to use the new iterator adaptors library.
Updated the documentation and examples as well to reflect the changes.


[SVN r19535]
2003-08-11 16:29:47 +00:00
242634b3fc Added safe_bool_testable_test
[SVN r19373]
2003-07-30 21:33:37 +00:00
662cf14bf6 Initial version
[SVN r19372]
2003-07-30 21:32:19 +00:00
fe3aaf62cd Undo overeager workarounding and safe_bool.
[SVN r19364]
2003-07-30 12:41:10 +00:00
cb189bd6be operators.hpp, operators_test.cpp - workaround for compilers not
supporting the PP lib, many workarounds for another problem which
   may be our bug.

linear_congruential.hpp - Borland workaround


[SVN r19350]
2003-07-30 01:11:14 +00:00
f57c914b8f Preparation for delivering nicely-formatted error messages in
Boost.Python.  The major change is that, instead of being
boost::function2<PyObject*,PyObject*,PyObject*>, py_function is now a
runtime-polymorphic wrapper for compile-time polymorphic
behavior (just like function) of our own which carries more
information/behaviors.  In particular, you can retrieve an array of
c-strings describing the types in the function signature.
Additionally, the minimum and maximum arity are stored in the
py_function object instead of in the 'function' object which wraps it.

* data_members.hpp -

     Adjustments for the new py_function.  Workarounds for CodeWarrior
     Pro 8.3 bugs in function template argument deduction with
     pointers-to-members.

* has_back_reference.hpp, test/back_reference.cpp,
  test/select_holder.cpp -

     Updated to follow the metafunction protocol

* init.hpp, detail/defaults_gen.hpp -

     Make Keywords a more-specific type in function signatures to
     prevent string literals that show up as char[N] from binding to
     the wrong argument (at least Intel 7.1 for Windows does this).

* make_function.hpp -

     Adjustments for the new py_function.  Arities are now computed
     by caller<>.

* opaque_pointer_converter.hpp, type_id.hpp -

     Use BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS facilities;
     generate specializations that all compilers can handle.

* raw_function.hpp -

     Adjustments for the new py_function.

* caller.hpp -

     Added arity and signature type name reporting.

* detail/config.hpp

     Enable __declspec(dllexport) for Cygwin, thereby fixing the
     recent horrible Cygwin linking problems.


* detail/msvc_typeinfo.hpp -

     Always pass boost::type<T>* explicitly, thereby working around
     incompatible notions of how to specialize function templates with
     default arguments on various compilers.

*   object/function.hpp
  , object/function_handle.hpp
  , object/function_object.hpp
  , object/function_object.cpp

     Adjustments for the new py_function.  Arities are carried by
     py_function.

* object/iterator.hpp, object/iterator.cpp

     Adjustments for the new py_function; we have to compute a
     signature of types to construct it with.

* object/py_function.hpp

     Removed dependency on boost::function; see the comment at the
     top of this entry for more details.

* object/select_holder.hpp

     Clean up to more closely follow MPL idioms.

* test/Jamfile -

     Adjust the embedding test for the new Cygwin use of declspec.
     Update bases and pointee tests with missing properties.

* test/input_iterator.cpp -

     Updates for the new iterator adaptors.

* test/opaque.py -

     Add Python encoding comment to suppress PendinDeprecationWarning
     with recent Python builds.

* test/str.cpp

     Pass a Python long instead of a float to string.expandtabs,
     suppressing a PendinDeprecationWarning with recent Python builds.

* libs/utility/counting_iterator_example.cpp

     Borland workaround

* libs/utility/indirect_iterator_example.cpp

     const-correctness fix.

*


[SVN r19247]
2003-07-22 00:06:41 +00:00
7cec198e14 Added missing algorithm include.
[SVN r19230]
2003-07-20 19:17:18 +00:00
52d3120528 Borland workaround
[SVN r19157]
2003-07-16 19:10:34 +00:00
f1aff5670c strict 2-phase ADL fixes.
[SVN r19152]
2003-07-16 15:16:21 +00:00
632f682292 Satisfy assignable requirement for output iterators.
[SVN r19150]
2003-07-16 14:30:47 +00:00
d1d0d6b788 Fixed Intel 7 issue (reported by Daniel Frey)
[SVN r19145]
2003-07-16 10:53:06 +00:00
3bd833c8ff avoid default parameters for function templates, they confuse SunCC
[SVN r19100]
2003-07-13 18:59:08 +00:00
1ef77b0853 fix cut-and-paste problem with subproject path
[SVN r19084]
2003-07-12 09:37:36 +00:00
074007ab8c Get examples working, mostly. Some interface expansion for a few of
the adaptors, allowing default construction of UnaryFunction and
Predicate arguments when they are class types.


[SVN r19081]
2003-07-12 04:15:13 +00:00
c4b7aaf281 Move to new iterator adaptors
[SVN r19074]
2003-07-11 22:18:58 +00:00
22b8494e9a Factored out separate utility/test Jamfile
[SVN r19068]
2003-07-11 17:24:18 +00:00
c1c8329403 Expanded base-from-member constructors to 10 arguments; did minor tweaks
[SVN r18791]
2003-06-15 01:16:49 +00:00
20a89040e1 -Wundef fixes.
[SVN r18788]
2003-06-12 17:09:24 +00:00
1c7a2a1476 IBM C++ support added.
[SVN r18587]
2003-05-28 13:45:58 +00:00
7c40cc0b63 Fixed bool_testable for compilers with BOOST_NO_OPERATORS_IN_NAMESPACE
[SVN r18521]
2003-05-23 23:09:21 +00:00
73a9e0d351 Intel support.
[SVN r18520]
2003-05-23 22:30:23 +00:00
dc9856744a Fixed tests for bool_testable
[SVN r18502]
2003-05-23 00:18:57 +00:00
88f4e47550 Added bool_testable by Sam Partington
[SVN r18413]
2003-05-15 22:40:33 +00:00
1be04eeec5 Fix a bug in preprocessor usage
[SVN r18231]
2003-04-11 06:56:52 +00:00
56acf9c325 Fixed shift-operators to respect BOOST_FORCE_SYMMETRIC_OPERATORS
[SVN r17664]
2003-02-26 21:26:57 +00:00
c6e3957efc MPL names/directory structure refactoring
[SVN r17651]
2003-02-25 23:11:41 +00:00
25e8284950 Qualified checked_delete calls to prevent ADL (reported by Daniel Frey)
[SVN r17636]
2003-02-25 13:00:22 +00:00
37a6537a5b fix metafunctions for MPL
[SVN r17621]
2003-02-25 00:57:33 +00:00
80df1d8f12 split utility.hpp header
[SVN r17472]
2003-02-17 06:20:57 +00:00
75afed7f17 Made operator()s const.
[SVN r17411]
2003-02-14 16:20:01 +00:00
1d7066aee1 __func__ is a predefined identifier, not a macro.
[SVN r17308]
2003-02-10 16:25:41 +00:00
12272a38d4 Initial Commit (was left out when the Optional Library was commited)
[SVN r17204]
2003-02-04 15:29:12 +00:00
04f901e52e fixed some typos
[SVN r17052]
2003-01-27 19:14:18 +00:00
fabfb31bf6 add value_init
[SVN r16826]
2003-01-09 13:26:13 +00:00
683701cd07 fix invalid bookmarks
[SVN r16823]
2003-01-09 13:03:37 +00:00
119c64be0b Workaround VC7 bug which strips const from nested classes
[SVN r16797]
2003-01-08 17:21:10 +00:00
d429c9a7d8 minor cleanup
[SVN r16709]
2002-12-27 16:58:27 +00:00
1e8216431b add or update See www.boost.org comments
[SVN r16708]
2002-12-27 16:51:53 +00:00
e45b2e2136 Doc link updated.
[SVN r16699]
2002-12-24 12:34:42 +00:00
9e6951009b Add /libs/lib-name to comment
[SVN r16685]
2002-12-23 02:43:12 +00:00
a009a209f1 Use BOOST_WORKAROUND
[SVN r16668]
2002-12-20 00:03:04 +00:00
97605056ed Added a note that throw_exception must not return (Beman Dawes)
[SVN r16471]
2002-12-02 12:12:42 +00:00
8fcfa33d33 Fix: Comeau with bcc32 as backend defines __BORLANDC__ as 1.
[SVN r16455]
2002-11-28 13:32:44 +00:00
aa65e3da3b sort_by_value(std::list<std::string>& l) is not declared inline anymore to make it compile with vacpp
[SVN r16407]
2002-11-25 15:54:37 +00:00
b4cfadb4d5 Metrowerks support (Bertolt Mildner)
[SVN r16263]
2002-11-15 19:44:18 +00:00
45a6249668 New BOOST_ASSERT, including documentation.
[SVN r16240]
2002-11-14 16:09:29 +00:00
1d601aef4d boost::throw_exception documentation added.
[SVN r16239]
2002-11-14 15:13:59 +00:00
32fb45eba9 checked_delete.hpp documentation added.
[SVN r16238]
2002-11-14 14:53:32 +00:00
2b7d10aceb BOOST_CURRENT_FUNCTION documentation added.
[SVN r16236]
2002-11-14 14:41:25 +00:00
5dc62711e1 Fix from Yitzhak Sapir <yitzhaks@actimize.com>
[SVN r16198]
2002-11-11 19:50:05 +00:00
252c02aca0 Works with MSVC and Intel5 now. Thanks, Aleksey!!
[SVN r16165]
2002-11-08 17:08:17 +00:00
9655beb7ba Cleanups on boost::iterator_traits<>
Broke MSVC though :(


[SVN r16157]
2002-11-08 06:57:31 +00:00
f0ea53e77e rip out illegal semicolons
[SVN r16134]
2002-11-06 18:20:38 +00:00
4755b42909 Daniel Frey's NRVO patches
[SVN r16084]
2002-11-04 01:59:32 +00:00
ef9af03c6c Changed typename to class; some libraries helpfully #define typename
[SVN r15970]
2002-10-23 13:55:18 +00:00
7439073cbf Merged from branch to trunk
[SVN r15572]
2002-09-30 16:54:26 +00:00
aff985a563 explicit "private" inheritance to avoid compiler warnings (MIPSpro)
[SVN r15422]
2002-09-17 21:06:32 +00:00
db425222d5 mpl_v2 branch checkin
[SVN r15258]
2002-09-11 05:35:41 +00:00
e20af510f7 Initial Revision
[SVN r15254]
2002-09-10 16:13:08 +00:00
d8230c6a73 Added Shared Container Iterator adaptor to iterator adaptor library.
[SVN r15169]
2002-09-05 14:05:29 +00:00
f5690787bf Distinguish between VC++ versions
[SVN r15127]
2002-09-01 14:57:40 +00:00
a4fd7b32dd Misc Kylix fixes
[SVN r15086]
2002-08-25 11:57:37 +00:00
f4336ec693 fixed typo.
[SVN r14798]
2002-08-12 20:47:54 +00:00
03d906976b Reduced probes from 10,000 to 1,000 to speed regression tests
[SVN r14789]
2002-08-12 15:05:23 +00:00
4ba6a96822 fix test_main signature
[SVN r14783]
2002-08-12 13:22:40 +00:00
1ea4140d56 Added tests for BOOST_NO_STD_ITERATOR_TRAITS
[SVN r14654]
2002-07-31 11:25:25 +00:00
351d4ecb15 Document policies() member of iterator_adaptor
[SVN r14613]
2002-07-26 00:03:24 +00:00
7fbf84dcc6 BaseType -> Base in one more place
[SVN r14605]
2002-07-25 19:10:05 +00:00
3ff49b272d fixup
[SVN r14598]
2002-07-25 14:16:54 +00:00
5b52e3d418 Fix doc based on Beman's feedback
[SVN r14596]
2002-07-25 13:52:48 +00:00
8c0eb498d3 Fix unversioned VC++ checks
[SVN r14436]
2002-07-13 12:26:19 +00:00
48a81ef7ea VC++ fixes
[SVN r14435]
2002-07-13 12:22:51 +00:00
f7610c9b26 fix link
[SVN r14318]
2002-07-05 23:51:20 +00:00
1755eaf019 Merged from RC_1_28_0
[SVN r13944]
2002-05-16 00:56:42 +00:00
6b8b218efb Removed tabs, fixed end of files.
[SVN r13803]
2002-05-10 11:35:38 +00:00
333d79b345 Add index.html so automatic tools work correctly
[SVN r13725]
2002-05-07 19:23:05 +00:00
f0fa436fe4 Added new config macro BOOST_HAS_MS_INT64 to detect presence of __int64 data type.
Modified boost source to use BOOST_HAS_LONG_LONG and BOOST_HAS_MS_INT64
   where appropriate to do so.


[SVN r13714]
2002-05-07 11:24:29 +00:00
13e6d78fa8 Fixes for Borland C++ Builder 6
[SVN r13662]
2002-05-04 11:03:42 +00:00
7126ea2685 Borland C++ Builder 6 fixes
[SVN r13659]
2002-05-04 10:55:15 +00:00
a37518cb4a Fixed broken links.
[SVN r13574]
2002-04-27 11:05:49 +00:00
64b3e8c3bd add missing #include <iterator>
[SVN r13554]
2002-04-23 19:52:11 +00:00
339937380e MSVC fixes.
[SVN r13476]
2002-04-13 13:19:57 +00:00
6156f0d302 Roll addressof() patch back in!
[SVN r13433]
2002-04-10 17:01:35 +00:00
00560e8e17 addressof.hpp:
- Peter Dimov suggested a fix to deal with those evil cv-qualifiers


[SVN r13431]
2002-04-10 14:47:32 +00:00
029ff9828f Roll back addressof() patch temporarily
[SVN r13428]
2002-04-10 09:48:30 +00:00
ec188c7c3e Make local classes nonlocal to silence annoying warnings from Borland C++
[SVN r13418]
2002-04-10 04:00:22 +00:00
0a0296a5d0 ref.hpp:
- Use addressof() instead of & operator


[SVN r13416]
2002-04-10 03:36:17 +00:00
6e26a5bbe7 boost/utility.hpp:
- Include boost/utility/addressof.hpp

boost/utility/addressof.hpp:
  - addressof() implementation

libs/utility/utility.htm:
  - Document addressof

libs/utility/addressof_test.cpp:
  - Test addressof()


[SVN r13414]
2002-04-10 03:31:18 +00:00
dc1b6246a0 boost/ref.hpp:
- Added get_pointer method to return a pointer (instead of a reference)

libs/bind/ref.html:
  - Document get_pointer


[SVN r13322]
2002-03-31 00:24:00 +00:00
15f69eaf14 Fixed new problem with Borland compile -
code clashes with some new type traits workarounds for some reason.


[SVN r13226]
2002-03-19 11:33:00 +00:00
4774a0d325 Added Copyright
[SVN r13145]
2002-03-09 20:34:06 +00:00
be78ab72c9 update expected failures for Sun CC
[SVN r13101]
2002-03-05 20:41:37 +00:00
0bc4a1b20d Warning suppressioni from Craig Rodrigues
[SVN r13098]
2002-03-05 18:55:49 +00:00
c8b674d105 Add missing paren.
[SVN r12997]
2002-03-01 17:43:00 +00:00
b421d4725a Fixed expected failures for gcc 3.1
[SVN r12994]
2002-03-01 12:27:01 +00:00
1662bb5713 use of "small" changed to "small_" to suppress confusion on some compilers
[SVN r12916]
2002-02-24 02:35:19 +00:00
ad79a21abd added portability note about using std::vector's as Base with VC++
[SVN r12875]
2002-02-21 12:09:46 +00:00
19645a52e6 Added a default constructor to shared_count and shared_ptr for incomplete types (void).
[SVN r12815]
2002-02-15 13:31:58 +00:00
74c3077c9a Added test cases for incomplete and abstract base class types.
[SVN r12803]
2002-02-14 12:57:32 +00:00
1f29191329 Modified call_traits to work with incomplete types.
[SVN r12800]
2002-02-14 12:54:57 +00:00
4b636a7680 Always say "private noncopyable" to avoid warnings.
[SVN r12762]
2002-02-08 20:08:15 +00:00
e6fc2555f3 removed tabs
[SVN r12707]
2002-02-04 20:29:35 +00:00
e27d0fcf2a New smart pointer documentation. Related clean-up of the smart pointer
library. Changing includes to include the new individual smart pointer
headers. Replacing old smart pointer library with an include of the new
smart pointer headers. Simplify ifdefs that involve the member templates
macros now that BOOST_MSVC6_MEMBER_TEMPLATES is also guaranteed to bet
set for platforms that have full member templates.


[SVN r12647]
2002-02-02 18:36:12 +00:00
2643c33b20 Doc fixes from Thomas Witt
[SVN r12621]
2002-02-01 13:03:21 +00:00
71af1e77c8 compile-time ref.hpp header test, initial checkin
[SVN r12525]
2002-01-27 13:39:06 +00:00
99e7406bd9 ref_ct_test.cpp
[SVN r12524]
2002-01-27 13:32:37 +00:00
413265f497 compile-time ref.hpp header test, initial checkin
[SVN r12522]
2002-01-27 13:07:20 +00:00
fe44cdf09b made 'reference_wrapper' Assignable
[SVN r12520]
2002-01-27 13:02:27 +00:00
e413428d71 Added tests for the new smart pointers.
[SVN r12500]
2002-01-25 13:54:30 +00:00
88b9822db7 Mark inline to avoid warning with "require prototypes" on.
[SVN r12490]
2002-01-24 19:15:30 +00:00
24045c0cd7 #included <boost/checked_delete.hpp>, removed unnecessary #includes.
[SVN r12488]
2002-01-24 17:47:08 +00:00
d2aa9f4a84 added missing #include of boost/config.hpp
[SVN r12483]
2002-01-24 16:55:41 +00:00
d2a5fd169f initial checkin
[SVN r12481]
2002-01-24 16:52:06 +00:00
4e350d9934 Modified is_reference_wrapper<> to work for reference types.
[SVN r12475]
2002-01-24 13:28:08 +00:00
f3f697bbc8 added is_reference_wrapper<>, unwrap_reference<>
[SVN r12470]
2002-01-23 21:19:14 +00:00
c7c09696db Tweak comments. Include <assert.h> and <boost/current_function.hpp> only
when needed.


[SVN r12446]
2002-01-22 18:28:33 +00:00
dbcc58d984 Smart pointer enhancements, initial commit
[SVN r12439]
2002-01-22 13:38:52 +00:00
8231310c4d initial checkin
[SVN r12390]
2002-01-21 01:29:06 +00:00
2988140430 tabs
[SVN r12360]
2002-01-19 16:07:28 +00:00
7387966005 Stripped tabs from source
[SVN r12351]
2002-01-19 12:38:14 +00:00
e0a5a61375 removed eroneous "detail::" prefix
[SVN r12326]
2002-01-15 19:14:53 +00:00
66ecd70689 removed std:: prefix from slist
[SVN r12310]
2002-01-14 14:57:20 +00:00
67f4f45653 Fixed violation of 'explicit' constructor
[SVN r12256]
2002-01-09 13:15:54 +00:00
1bf28b3de2 Fixes for Borland
[SVN r12254]
2002-01-09 12:11:37 +00:00
eb3c3435d7 Updated expected results
[SVN r12250]
2002-01-08 13:01:15 +00:00
8a81d8b16c Workarounds for MSVC
[SVN r12246]
2002-01-07 19:24:45 +00:00
bc9d8b13d0 converted some of the old terminology (OrderIterator) to the current
terminology (IndexIterator)


[SVN r12164]
2001-12-28 15:49:45 +00:00
4768b167ab Removed obsolete mentions of "less"; Added formalized Policies Concept description
[SVN r12056]
2001-12-14 12:54:21 +00:00
591ff70ed1 many fixes
[SVN r12054]
2001-12-13 19:43:35 +00:00
7bf2ad0b22 VC6 patch
[SVN r12045]
2001-12-13 18:24:29 +00:00
409c79b2e4 fix example (thanks to Michael Stevens)
[SVN r11979]
2001-12-08 08:39:27 +00:00
d0410691a1 removed calls to non-standard std::iota (SGI extension)
[SVN r11904]
2001-12-04 08:02:36 +00:00
64e5115138 Fixed spelling error ing gcc-3.0 bug workaround
[SVN r11888]
2001-12-03 21:48:54 +00:00
7ae912d83c Rolled in Helmut's fixes for random_access_iterable; rolled back
workarounds for that problem.


[SVN r11887]
2001-12-03 21:47:58 +00:00
2937f5876c changed std::iota call (SGI extension) to a manual loop
in permutation_iterator test


[SVN r11869]
2001-12-03 08:35:08 +00:00
8619c9b5c3 fix gcc looping (from Dave Abrahams)
[SVN r11839]
2001-11-30 17:55:39 +00:00
e4d5684f6b added test for permutation_iterator
[SVN r11825]
2001-11-30 11:10:07 +00:00
3d69cf95da added documentation for the permutation_iterator_adaptor
and linked to it from the iterator_adaptors documentation.


[SVN r11824]
2001-11-30 10:40:03 +00:00
18944572b7 committing Daryle and Helmut's changes
[SVN r11813]
2001-11-29 21:22:52 +00:00
3e9d0f80c2 add generator iterator adaptor
[SVN r11736]
2001-11-19 22:11:51 +00:00
a2c4d1990a add boost::generator_iterator_policies and convenience classes
[SVN r11725]
2001-11-18 17:56:43 +00:00
404261c6ee add definition for integral constants initialized in-class
[SVN r11723]
2001-11-18 17:32:19 +00:00
87abc59612 #undef BOOST_REF_CONST added
[SVN r11674]
2001-11-14 14:40:29 +00:00
cb98ddf7db Fixed a bug w/ adaptable function objects + nested binds, made ref<> return const
[SVN r11670]
2001-11-13 13:56:05 +00:00
7d2e6c9025 __stdcall support added.
[SVN r11649]
2001-11-10 19:18:58 +00:00
75eaa14a18 Removed defunct boost::tied (thanks, Daryle Walker)
[SVN r11622]
2001-11-07 10:35:12 +00:00
082d6e3b32 *** empty log message ***
[SVN r11614]
2001-11-06 16:09:14 +00:00
35b3770b6f *** empty log message ***
[SVN r11613]
2001-11-06 16:05:25 +00:00
5b9d20c7e2 *** empty log message ***
[SVN r11611]
2001-11-06 15:52:56 +00:00
5bbed2372e *** empty log message ***
[SVN r11602]
2001-11-05 21:03:59 +00:00
a9d407d239 update SunCC to 6.u2 (C++ 5.3)
[SVN r11601]
2001-11-05 21:00:53 +00:00
3ca4a33a65 updated for named parameters
[SVN r11566]
2001-11-04 16:21:51 +00:00
95197f427c remoeved #if 0
[SVN r11565]
2001-11-04 16:18:10 +00:00
84cdfb032c commit these changes
[SVN r11563]
2001-11-04 04:37:14 +00:00
ec2ceb9c96 no message
[SVN r11508]
2001-11-01 17:22:39 +00:00
6286c893fd Minor regression fixes for Borland and Sunpro tests.
[SVN r11470]
2001-10-30 11:41:35 +00:00
354aef0e8c changed named parameters doc to match new stuff
[SVN r11417]
2001-10-22 17:04:23 +00:00
139e33c36d Updated preprocessor logic to use BOOST_HAS_LONG_LONG
[SVN r11399]
2001-10-18 11:33:52 +00:00
e01de59cdd Made these actually compile
[SVN r11378]
2001-10-12 22:22:42 +00:00
686f822dea Fix spelling error: "occurances" -> "occurrences".
[SVN r11376]
2001-10-11 17:26:04 +00:00
9961d5c9af Last fix had broken preprocessor logic, now fixed.
[SVN r11373]
2001-10-11 12:04:00 +00:00
628be0d125 Fixes for Sunpro C++ 5.3 (code now works!)
[SVN r11368]
2001-10-09 11:24:56 +00:00
633e45f61a Fixed test to work with sunpro 5.3 (omits array specialisation tests)
[SVN r11359]
2001-10-08 11:35:05 +00:00
2f357c3805 Partial fixes for sunpro 5.3 - doesn't actually work yet though
[SVN r11355]
2001-10-08 11:31:29 +00:00
cda0894d0d Fix for sunpro 5.3 (array specialisations don't work)
[SVN r11354]
2001-10-08 11:30:53 +00:00
117720a8bc 1.25.0 Final runup
[SVN r11315]
2001-10-01 15:54:23 +00:00
a6f6c3613a Change comments to make it clear why forward declaration header is required.
[SVN r11314]
2001-10-01 14:15:44 +00:00
7914f5b931 Fixed unused variables that show up as warnings when doing regression
tests.


[SVN r11241]
2001-09-24 23:21:16 +00:00
a1add0a6f6 Intel C++ fixes: Added class copy constructor.
[SVN r11200]
2001-09-22 11:52:56 +00:00
c032b337c4 Fix broken links and other HTML changes related to new config system
[SVN r11142]
2001-09-18 21:24:51 +00:00
ec363261ae remove "explicit" on two- and three-argument constructors to avoid
error on HP aCC


[SVN r11097]
2001-09-11 18:42:25 +00:00
97cde2183d Initial base_from_member commit
[SVN r11086]
2001-09-10 14:04:28 +00:00
7f43c682db Fixed the pair_generator documentation. Order of parameters was wrong; reordered
the table to match the corrected order.


[SVN r11035]
2001-09-05 16:29:29 +00:00
0c9eee3c6b changed note about the move to the tuples library
[SVN r10972]
2001-08-30 19:45:19 +00:00
3b1afa3ba6 changed "empty-member" to "empty base-class"
[SVN r10966]
2001-08-30 10:58:19 +00:00
93e6a75125 changed #include for tie() to tuple.hpp
[SVN r10951]
2001-08-28 19:09:33 +00:00
52f8a7c0ca changed #include for tie()
[SVN r10950]
2001-08-28 19:07:51 +00:00
55bfeb646f removed tie() and class tied
[SVN r10938]
2001-08-26 19:55:49 +00:00
75c9dd3be1 added not about constness of operator* and operator[]
[SVN r10931]
2001-08-24 15:28:20 +00:00
6392e2788f Removed incorrect statics, added const
[SVN r10930]
2001-08-24 12:09:34 +00:00
6a97f3f9ba Tabs converted to spaces.
[SVN r10916]
2001-08-23 19:05:21 +00:00
6e5f52e279 initial commit
[SVN r10914]
2001-08-23 18:42:16 +00:00
7f92bed902 Fix some broken links. Fix order of constructor initializers.
[SVN r10913]
2001-08-23 17:42:07 +00:00
d68a11cc42 Misc; mostly fix links to hard disk locations
[SVN r10902]
2001-08-20 13:04:43 +00:00
328a81e194 Fix broken hyperlink
[SVN r10896]
2001-08-19 15:08:33 +00:00
31d0908b74 Add workaround for BOOST_NO_STDC_NAMESPACE
[SVN r10681]
2001-07-20 21:29:36 +00:00
32c77599f4 Fixes for ICL
[SVN r10613]
2001-07-14 12:51:59 +00:00
812ebf3562 Back out commit made in error
[SVN r10596]
2001-07-12 16:15:30 +00:00
37f476013d Change absolute URL's to relative
[SVN r10594]
2001-07-12 15:31:15 +00:00
9f3104166f output_iterator_helper changes: removed default template parameters, added
support for self-proxying, additional documentation and tests (Aleksey Gurtovoy)


[SVN r10576]
2001-07-09 23:51:49 +00:00
64cc0daf34 Integrate Aleksey's changes
[SVN r10575]
2001-07-09 23:50:55 +00:00
d5d64df124 Fix broken link
[SVN r10553]
2001-07-06 19:19:45 +00:00
0edcfcd5c1 Tuples library causes tie to be deprecated
[SVN r10552]
2001-07-06 19:16:39 +00:00
50ba2d419a Tweeked gcc workaround (gcc 3 still has same problem as gcc 2.9x), added tentative Metrowerks and Intel compiler workarounds.
[SVN r10422]
2001-06-25 11:31:14 +00:00
ff3a77ca5a Fixed problem with VC6 compilers - probably a temporary fix.
[SVN r10361]
2001-06-20 11:43:57 +00:00
4eaed6c23d remove superfluous, illegal "typename" (twice)
[SVN r10314]
2001-06-12 18:50:37 +00:00
4d0dd46471 meant to add as a branch
[SVN r10280]
2001-06-06 19:16:34 +00:00
9c2549bd00 files for the tmpw2001 paper about iterator adaptors
[SVN r10278]
2001-06-06 19:08:51 +00:00
b7c8e0c17f changes from Daryle Walker
[SVN r10264]
2001-06-04 11:57:37 +00:00
dd3cfe1837 removed old arg ordering, use defaults instead
[SVN r10258]
2001-06-03 20:00:24 +00:00
43f525298e Remove compiler workarounds no longer needed due to BOOST_STATIC_ASSERT fix. For stylistic reasons, change sizeof() test to sizeof() != 0
[SVN r10236]
2001-05-28 14:22:30 +00:00
1bb1898ab9 Dave says qualifiers weren't really needed
[SVN r10222]
2001-05-24 19:11:51 +00:00
9578f24be9 Workaround compiler problems while waiting to find out if BOOST_STATIC_ASSERT is broken
[SVN r10218]
2001-05-24 16:02:42 +00:00
46fae3aed2 added check_delete workaround for Sun CC
[SVN r10213]
2001-05-24 09:26:48 +00:00
e35f91a70a Smart pointer and utility changes related to adding checked_delere and checked_array_delete
[SVN r10189]
2001-05-22 18:58:21 +00:00
851052fcca Updated docs - added VC6 bug warning
[SVN r10062]
2001-05-08 11:17:44 +00:00
5ef81b2952 Updated/stricter test program
[SVN r10061]
2001-05-08 11:17:05 +00:00
ef2851c053 Fixes for Sun C++ 5.1
[SVN r10060]
2001-05-08 11:16:35 +00:00
0b4387cff5 reorganised tests to show up VC6 bugs
[SVN r10002]
2001-05-02 10:59:32 +00:00
a40cf11fbf Rewritten compressed_pair regression script to test everything in a more methodical way
[SVN r10000]
2001-05-01 11:17:02 +00:00
5c495cd223 Change all eGroups references to YahooGroups
[SVN r9979]
2001-04-25 00:24:50 +00:00
cf1296dff8 added stuff about Default Constructible needed for the function object
[SVN r9683]
2001-03-29 16:26:42 +00:00
d6d88db6e8 std::bind1st -> boost::bind1st
[SVN r9682]
2001-03-29 16:19:34 +00:00
85c2a35257 std::binder1st -> boost::binder1st
[SVN r9681]
2001-03-29 16:18:41 +00:00
836d8b1c64 added spaces in name
[SVN r9673]
2001-03-29 04:08:38 +00:00
98d8c8ab71 fixed broken link
[SVN r9645]
2001-03-27 10:54:12 +00:00
db45013339 fixed sgi stl link
[SVN r9631]
2001-03-22 16:06:15 +00:00
a55c37e7f6 fixed sgi stl links
[SVN r9630]
2001-03-22 16:05:48 +00:00
46a270fcca fixed link to sgi stl
[SVN r9629]
2001-03-22 16:02:11 +00:00
967856518e updated link to sgi stl
[SVN r9628]
2001-03-22 16:01:18 +00:00
7f93e739fe added documentation for initialize() policy function
[SVN r9592]
2001-03-19 21:46:14 +00:00
2cd1422514 added comment about abstract base classes as value_type
[SVN r9584]
2001-03-19 17:31:27 +00:00
feb370b201 1.21.0 run up including fixing broken links
[SVN r9523]
2001-03-09 14:36:41 +00:00
d1b34e64d8 Fixes for validator.w3.org
[SVN r9518]
2001-03-09 03:28:13 +00:00
b9a1eead40 Mostly clarification. Fix: changed "category" to "iterator_category" in one place.
[SVN r9517]
2001-03-09 03:10:32 +00:00
1e4bfac98c added named template parameter to table of contents
[SVN r9510]
2001-03-08 21:36:09 +00:00
3bb504fbf3 added revision history line
[SVN r9506]
2001-03-08 20:50:14 +00:00
5029791c90 split off indirect and transform tests into separate files
[SVN r9505]
2001-03-08 20:49:05 +00:00
a1a68f0970 1.21.0 run up
[SVN r9502]
2001-03-08 20:35:52 +00:00
f8543d79eb added more static asserts
[SVN r9500]
2001-03-08 20:02:00 +00:00
f353415136 added docs for iterator_traits_generator
[SVN r9498]
2001-03-08 19:19:46 +00:00
26240403b0 added a test to make sure that the type set by the generator is really the
type used


[SVN r9497]
2001-03-08 19:04:29 +00:00
3a39729b58 new file
[SVN r9488]
2001-03-08 16:33:40 +00:00
096c961d9a Patches for Intel C++
[SVN r9425]
2001-03-04 16:08:20 +00:00
01fe04a6a2 Workaround for Borland
[SVN r9424]
2001-03-04 16:07:11 +00:00
7ea4014993 Misc fixes that missed the last commit..
[SVN r9402]
2001-03-04 11:08:29 +00:00
d50b374f88 Boost Test Library initial commit
[SVN r9364]
2001-02-28 21:39:56 +00:00
27dfb25570 added function output iterator adaptor
[SVN r9351]
2001-02-27 05:50:51 +00:00
b5ed77985e added missing typename's to docs
[SVN r9324]
2001-02-25 12:04:48 +00:00
61243bd15f type_traits: more tentative EDG compiler fixes...
[SVN r9321]
2001-02-24 13:04:56 +00:00
368b94d804 Corrected numeric_limits<>::is_integral -> numeric_limits<>::is_integer
[SVN r9299]
2001-02-20 23:15:29 +00:00
a5adbbfd5f use filter_iter::policies_type instead of filter_gen::policies_type
[SVN r9292]
2001-02-20 16:01:00 +00:00
a19d13f123 More type_traits tweeks.
[SVN r9287]
2001-02-20 12:17:55 +00:00
78886ab383 Added cross-reference; improved policies documentation
[SVN r9286]
2001-02-20 03:49:26 +00:00
168012b465 Describe const/mutable interactions and give rationale for no
reverse_iterator_pair_generator.


[SVN r9285]
2001-02-20 03:04:03 +00:00
d9d58ea66e Take advantage of improved iterator_traits to do more tests on MSVC. Reordered
some #ifdefs for coherency.


[SVN r9281]
2001-02-19 22:36:22 +00:00
56f5f6e8d5 Take adavantage of improved iterator_traits to do more tests on MSVC. Hack
around an MSVC-with-STLport internal compiler error.


[SVN r9280]
2001-02-19 22:34:31 +00:00
3cb6420eda Roll back the reverse_iterator_pair_generator test
[SVN r9278]
2001-02-19 20:37:24 +00:00
60be2c1186 Added tests for reverse_iterator_pair_generator
[SVN r9273]
2001-02-19 16:21:12 +00:00
ed210f6b2c more type traits updates:
Header includes get BOOST_ prefix,
BOOST_DECL_MC dropped in favour of new BOOST_STATIC_CONSTANT (from config.hpp),
operator ! dropped in favour of boost::type_traits::ice_not template.


[SVN r9270]
2001-02-19 12:52:30 +00:00
029bc59d74 Added some missing 'explicit's
[SVN r9265]
2001-02-18 22:23:13 +00:00
961c08a82f Apply Jens' suggested fixes
[SVN r9263]
2001-02-18 21:50:57 +00:00
7ee484c614 fix minor typos
[SVN r9259]
2001-02-18 19:26:20 +00:00
05c6fbbf99 needs <boost/type_traits/same_traits.hpp>
[SVN r9253]
2001-02-18 15:19:23 +00:00
91078b7f7a type_traits: regression failure fixes from type traits changes...
[SVN r9249]
2001-02-18 11:43:01 +00:00
20d804afc4 changes to order of indirect_iterator template parameter list, and
fixed a typo


[SVN r9247]
2001-02-17 22:03:30 +00:00
c21f6d1cbf added Category parameter and made a few more edits with regards to type requirements
[SVN r9239]
2001-02-17 19:59:19 +00:00
393e79c1fd Added new type traits files.
[SVN r9238]
2001-02-17 12:25:45 +00:00
8b92c8a085 adjusted requirements for value type of the base iterator
[SVN r9236]
2001-02-17 01:51:45 +00:00
ff73dd94c9 made iterator_adaptor constructor explicit
[SVN r9235]
2001-02-17 01:50:40 +00:00
af43904f38 added "explicit" to iterator_adaptor constructor
[SVN r9234]
2001-02-17 01:44:41 +00:00
485074f265 Added a missing const. Made the tests run (somewhat) with plain MSVC again.
[SVN r9232]
2001-02-16 23:04:49 +00:00
2e0ee55b5e add missing my_int3::operator!=
[SVN r9231]
2001-02-16 21:28:59 +00:00
e9105d32cb background color and a whitespace edit
[SVN r9228]
2001-02-16 16:38:45 +00:00
964d23f68c Edits for clarity
[SVN r9224]
2001-02-16 05:51:37 +00:00
be5aaaae7b More edits for clarity. Added const/non-const example.
[SVN r9223]
2001-02-16 05:33:21 +00:00
bf13bd7b3f Massive edits
[SVN r9222]
2001-02-16 05:30:49 +00:00
352e392fcb Checked and cleaned using HTML TIDY.
[SVN r9220]
2001-02-16 02:36:36 +00:00
083b1b02df Bigtime edits
[SVN r9219]
2001-02-16 00:38:28 +00:00
648c6240a2 added another link to the generic_programming.html#policies
[SVN r9218]
2001-02-15 16:57:12 +00:00
60cab840cb removed strange ssh garbage
[SVN r9217]
2001-02-15 16:52:39 +00:00
83a4380dab added mention of traits requirement under Type Requirements section
[SVN r9216]
2001-02-15 16:49:16 +00:00
de84fe8d98 oops, meant to remove use of policies_type from filter_iterator_generator
in the last commit, but accidentally added it :(


[SVN r9215]
2001-02-15 16:43:54 +00:00
ed3cbfdb8e removed policies_type from filter_iterator_generator
[SVN r9214]
2001-02-15 16:41:48 +00:00
fda44ca17d General edits for clarity; some reorganization.
[SVN r9213]
2001-02-15 16:39:55 +00:00
272025bb07 fixed my_int::operator--
[SVN r9208]
2001-02-15 06:47:06 +00:00
8e92bcf1b2 removed policies_type from filter_iterator_generator
[SVN r9207]
2001-02-15 06:44:26 +00:00
84f1ffdefe added section on Members to cover constructors, etc. and added
a section on Operators


[SVN r9206]
2001-02-15 06:41:46 +00:00
7e25450054 added discusion of counting_iterator_traits, and added type requirements
for the Incrementable type.

added uses of user-defined types to the test


[SVN r9204]
2001-02-15 05:53:10 +00:00
4a563fa266 added missing boost::
[SVN r9199]
2001-02-14 20:35:39 +00:00
aa4c0ec000 Test new VC6 workarounds
[SVN r9198]
2001-02-13 23:32:19 +00:00
e1ecfbdc43 added output for the transform iterator example
[SVN r9187]
2001-02-13 04:38:59 +00:00
a4e122a82e changed template class to class template
[SVN r9186]
2001-02-13 04:34:44 +00:00
93216e8fb7 copyright
[SVN r9184]
2001-02-13 04:25:24 +00:00
16272c210d fixed typo
[SVN r9183]
2001-02-13 04:24:24 +00:00
e104b00da1 merged in Dave's additions and added a tutorial using the implementation
of transform iterator as the example


[SVN r9182]
2001-02-13 04:15:17 +00:00
ce5c6bcc08 removed use of istream_iterator for operator-> test, replaced with
use of concept archetypes


[SVN r9180]
2001-02-13 02:03:13 +00:00
8694ce31fe changed int* to std::vector<int>::iterator
[SVN r9178]
2001-02-12 21:59:25 +00:00
d960e5eadd added another example
[SVN r9177]
2001-02-12 21:57:19 +00:00
2dc71e87a3 new files
[SVN r9176]
2001-02-12 21:35:20 +00:00
6bf17edde2 updated url to the iterator_adaptor class
[SVN r9156]
2001-02-12 05:24:45 +00:00
88573d515d fixed Reference and Pointer template paremeter descriptions
[SVN r9155]
2001-02-12 05:20:09 +00:00
89b9f77823 obsolete and not needed
[SVN r9152]
2001-02-12 04:55:19 +00:00
765d9be17d small edit
[SVN r9151]
2001-02-12 04:53:39 +00:00
7135373008 various edits
[SVN r9150]
2001-02-12 04:52:24 +00:00
ee269884fc finished 1st draft of reverse iterator docs
[SVN r9149]
2001-02-12 04:51:56 +00:00
387540d5f1 using make_const_projection_iterator() for last example,
and a couple other minor edits


[SVN r9145]
2001-02-12 02:55:19 +00:00
2eba7b42a8 new files
[SVN r9144]
2001-02-12 02:52:26 +00:00
07115d26c7 finished 1st draft
[SVN r9143]
2001-02-12 01:50:50 +00:00
c43ed815a0 new files
[SVN r9137]
2001-02-11 20:05:00 +00:00
ff01e36d12 Compile with Borland, re-enable failing tests
[SVN r9136]
2001-02-11 19:53:56 +00:00
ac4798b16c Final fixes for Borland
[SVN r9135]
2001-02-11 19:50:14 +00:00
d4e14fed0e Fixed bugs in the iterator helpers which prevented explicitly supplied arguments from actually being used
[SVN r9128]
2001-02-11 19:31:21 +00:00
5f91259344 few edits
[SVN r9125]
2001-02-11 19:26:26 +00:00
20a9d9645d Added test of operator-> for forward and input iterators.
[SVN r9124]
2001-02-11 19:25:49 +00:00
c86f6b4abd Dave's suggested edits
[SVN r9122]
2001-02-11 18:27:40 +00:00
d66489b5b2 changed per Dave's comments
[SVN r9121]
2001-02-11 18:14:04 +00:00
b743ee9f0c #if 0'd out use of counting_iterator on non-numeric types in MSVC without STLport, so that the other tests may proceed
[SVN r9120]
2001-02-11 16:19:17 +00:00
95ba69c00a Borland fixes
[SVN r9119]
2001-02-11 16:16:53 +00:00
2ac273739c Update for compatibility with new iterator_adaptor interface
[SVN r9118]
2001-02-11 16:14:14 +00:00
5b4d28708c Fixes for Borland
[SVN r9117]
2001-02-11 16:13:38 +00:00
4cc4383488 Some fixes for Borland get it closer on that compiler
[SVN r9112]
2001-02-11 16:05:01 +00:00
8935232248 new files
[SVN r9109]
2001-02-11 05:25:19 +00:00
5c6dd2f172 various edits
[SVN r9108]
2001-02-11 04:34:32 +00:00
eeeb7ef5b9 Replaced some static_casts with explicit construction
[SVN r9107]
2001-02-11 03:12:04 +00:00
2efc9c1178 Use new adaptors interface
[SVN r9105]
2001-02-11 03:07:55 +00:00
a84c46f6e3 added another example
[SVN r9103]
2001-02-11 03:01:47 +00:00
a5c3dcdd02 redid docs for the template parameters
[SVN r9102]
2001-02-11 02:55:38 +00:00
46f7a75eb7 fixed bug in policy object constructor
[SVN r9101]
2001-02-11 02:40:02 +00:00
94b6710c5b fixed bug in policy object construction
[SVN r9100]
2001-02-11 02:39:35 +00:00
d8dd3da9ab small edit
[SVN r9099]
2001-02-11 02:38:08 +00:00
803ced004a finished 1st draft
[SVN r9098]
2001-02-11 02:35:09 +00:00
0ea7d36ad0 A fix for EDG
[SVN r9096]
2001-02-10 23:16:05 +00:00
87aafab759 new file
[SVN r9094]
2001-02-10 22:33:43 +00:00
994d310abd Use new filter_ interface.
[SVN r9090]
2001-02-10 20:11:42 +00:00
228cdcf05e All final 1.20.2 changes, including fixing broken hyperlinks
[SVN r9071]
2001-02-10 14:42:14 +00:00
42598e352c Use new reverse_ and indirect_ interfaces. Replace BOOST_NO_STD_ITERATOR_TRAITS
with BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION to prove we've normalized to core
compiler capabilities


[SVN r9067]
2001-02-10 00:38:08 +00:00
36a9e4d1da fixed usage of indirect_iterator_pair_generator
[SVN r9053]
2001-02-09 05:45:10 +00:00
456dfd0dea adjusted to changes in iterator_adaptors.hpp, added more
tests of make_xxx


[SVN r9051]
2001-02-09 05:26:48 +00:00
155457e2b5 more work on default args and explicit templat args
[SVN r9049]
2001-02-09 04:40:42 +00:00
b5c91485bf Use Jeremy's new make_reverse_iterator form; add more comprehensive
testing. Force-decay array function arguments to pointers.


[SVN r9047]
2001-02-09 03:32:59 +00:00
c959cf7870 bug fixes
[SVN r9031]
2001-02-08 04:46:41 +00:00
5878c88636 added indirect_iterator_pair_generator back in
[SVN r9026]
2001-02-08 03:35:03 +00:00
ddcef2fb19 Added tests for the make_xxx_iterator() helper functions
[SVN r9025]
2001-02-08 03:08:09 +00:00
493d124c07 rename counting_iterator() -> make_counting_iterator()
[SVN r9015]
2001-02-07 22:27:02 +00:00
f42060c616 add missing "typename"
[SVN r9005]
2001-02-07 17:51:55 +00:00
834facc932 trivial flotsam cleanup
[SVN r9004]
2001-02-07 17:23:52 +00:00
f82d0b76ee More comprehensive testing; factored out static tests for better reuse
[SVN r9001]
2001-02-07 16:38:41 +00:00
c25d225275 Replaced use of xxx_pair_generator with xxx_generator where
possible (which was all but the projection iterator).


[SVN r8996]
2001-02-07 06:36:12 +00:00
c503a274b5 Removed now-defaulted template arguments where possible
Updated names to correspond to new generator naming convention.
Added a trivial test for make_transform_iterator().
Gave traits for const iterators a mutable value_type, per std.
Resurrected my original tests for indirect iterators.


[SVN r8995]
2001-02-07 05:37:08 +00:00
087069d215 added concept check for the default iterator policy
[SVN r8990]
2001-02-07 02:44:18 +00:00
826a6dd114 changed test for transform iterator to use input_iterator instead of
random access iterator


[SVN r8937]
2001-02-04 23:46:31 +00:00
f31483838d Fix for compilers without standard iterator_traits
[SVN r8929]
2001-02-04 20:11:30 +00:00
d8a9b633d9 Fix for newly-corrected bidirectional_iterator_test requirements.
[SVN r8926]
2001-02-04 19:09:46 +00:00
c060e4466a Added use of iterator_tests.hpp
[SVN r8923]
2001-02-04 18:26:43 +00:00
a9951376f4 removed UDT -> int is_convertible test because the noncopyable -> int
test already brings out the g++ warning


[SVN r8834]
2001-01-31 19:08:27 +00:00
bda0c8f5e3 added some more tests and fixed signature of main() so this will link
with MSVC


[SVN r8833]
2001-01-31 18:54:29 +00:00
71902f23a2 Added test case for is_convertible with UDT that brings out the
warning message bug with g++.


[SVN r8821]
2001-01-31 02:12:08 +00:00
dfd6c85569 Inital checkin
[SVN r8813]
2001-01-30 16:00:37 +00:00
0e41b2cc1a Removed not_an_iterator detritus
[SVN r8808]
2001-01-29 02:14:44 +00:00
e5c81d0702 fixed very strange VC++ bug that was showing up in graph/test/graph.cpp
Something about the code gen for compressed_pair_1::operator=
was going wrong. Writing it explicitly, and playing with some ordering
fixed the problem, don't ask my why.


[SVN r8765]
2001-01-25 04:45:52 +00:00
6caf7d4d5a Initial checkin
[SVN r8757]
2001-01-24 18:36:52 +00:00
98e87c8afb Added test for wchar_t
[SVN r8748]
2001-01-24 01:48:01 +00:00
d9e0f80d50 Now statically selecting a test for signed numbers to avoid warnings with fancy
compilers. Added commentary and additional dumping of traits data for tested
types.


[SVN r8746]
2001-01-24 01:40:22 +00:00
6396fdb5ff added filter iterator test
[SVN r8736]
2001-01-23 19:10:03 +00:00
2470b53373 minor fix: move "static" storage specifier to the front of a declaration
[SVN r8714]
2001-01-22 21:11:35 +00:00
16334e92ca added KAI C++ type for std::list::difference_type
[SVN r8709]
2001-01-22 16:52:36 +00:00
c22d98a8ec Quick fix to my_iterator, which wasn't returning a reference type from operator*
[SVN r8705]
2001-01-22 05:03:48 +00:00
28617afbb9 Initial checkin
[SVN r8702]
2001-01-22 04:08:29 +00:00
0c3bc42bec new files
[SVN r8685]
2001-01-21 20:12:32 +00:00
e3d9745df1 Initial Checkin
[SVN r8676]
2001-01-21 06:02:08 +00:00
b8471c1015 Suppress an expected warning for MSVC
Added a test to prove that we can use void with is_same<>
      Removed "press any key to exit" as it interferes with testing in large
      batches.


[SVN r8673]
2001-01-21 05:56:57 +00:00
045b09c9ef A first attempt at clarifying the documentation
[SVN r8672]
2001-01-21 05:48:55 +00:00
4ac07b97d3 Fixed what seemed like glaring bugs (illegal access to private members, missing template parameters).
[SVN r8658]
2001-01-20 21:59:55 +00:00
34c847c17f moved global variables in front of reference in test_align
[SVN r8648]
2001-01-19 19:27:09 +00:00
f694e557e1 compressed pair fixes for VC6
[SVN r8543]
2001-01-10 12:21:30 +00:00
6a0c3e92a0 Initial commit after public review (note change in library name per review)
[SVN r8516]
2001-01-06 16:47:36 +00:00
cba48df8e3 VC6 fixes for compressed_pair
[SVN r8485]
2000-12-21 12:27:22 +00:00
a0e8d1bf36 a C++ standard version of LessThanComparable
[SVN r8435]
2000-12-09 22:39:50 +00:00
912dedaca7 added #include boost/config.hpp at top to remove truncation warning on VC++
[SVN r8434]
2000-12-09 20:28:48 +00:00
7dd90c3919 CVS says it needs a commit; who knows why?
[SVN r8405]
2000-12-08 17:35:43 +00:00
7c3a25a377 various changes, almost forgot to check in
[SVN r8379]
2000-12-03 06:20:23 +00:00
c8fbca2d44 added docs for projection iterator
[SVN r8322]
2000-11-24 21:31:43 +00:00
f7ed0aaeed added std:: to unary_function
[SVN r8321]
2000-11-24 20:48:02 +00:00
6e78270140 added projection iterator to the test
[SVN r8320]
2000-11-24 20:45:26 +00:00
ba354377d5 updated docs for indirect iterators
[SVN r8319]
2000-11-24 20:22:23 +00:00
353c030918 simplified version of iterator_adaptor, plus fix to indirect iterator
and addition of projection iterator


[SVN r8317]
2000-11-24 19:40:51 +00:00
331a2b8282 Fixed regex memory leak, and type_traits bad test case
[SVN r8273]
2000-11-21 12:39:09 +00:00
4bd6909ea1 *** empty log message ***
[SVN r8158]
2000-11-07 23:05:04 +00:00
26119613e1 BeOS5 (intel) fixes
[SVN r8133]
2000-11-04 11:16:12 +00:00
45bfe0b607 HTML change for 1.18.2 reflecting separation of old utility library
[SVN r8118]
2000-11-03 19:22:26 +00:00
ce2f573ab2 new file, based on the C++ standard, not SGI STL's definition of Assignable
[SVN r8062]
2000-10-29 21:35:59 +00:00
66d5cc43f3 added BeOS5 support to test script (not finished yet though...)
[SVN r8037]
2000-10-28 10:54:12 +00:00
e8265e09a3 Add trivial numeric_cast tests for floating types.
[SVN r8007]
2000-10-19 19:12:53 +00:00
860cf0b321 Fix broken HTML links
[SVN r7951]
2000-10-15 17:08:00 +00:00
89c74708d7 misc minor fixes
[SVN r7938]
2000-10-14 12:03:10 +00:00
74c8680350 Add missing "typename" that Metrowerks compiler is picky about
[SVN r7929]
2000-10-12 21:01:49 +00:00
3cd9f5b623 MWCW fix: added std:: qualifier to memset
[SVN r7923]
2000-10-10 11:40:19 +00:00
0936110741 minor typo fixes
[SVN r7922]
2000-10-10 10:40:58 +00:00
6161ce15c7 more VC6 type-traits and compressed pair fixes
[SVN r7921]
2000-10-07 10:53:47 +00:00
28594a22f1 More VC6 fixes for is_pointer/is_array/is_same
[SVN r7896]
2000-10-03 11:53:39 +00:00
656517b059 More VC6 fixes for compressed_pair and type_traits.
[SVN r7895]
2000-10-03 11:47:24 +00:00
ad576863b4 fix typo: compressed_pait->compressed_pair
[SVN r7894]
2000-10-03 08:06:19 +00:00
775be75366 updated call_traits and type_traits test programs for VC6
[SVN r7883]
2000-10-01 11:57:00 +00:00
7ae6e5bac9 call_traits and type_traits updates for VC6
[SVN r7882]
2000-10-01 11:48:27 +00:00
c5915c23e7 Fix broken link
[SVN r7870]
2000-09-28 17:47:29 +00:00
1f2a827df3 Integrate Tie with other HTML files
[SVN r7866]
2000-09-28 12:35:46 +00:00
f51ee4ef2e Initial Graph and Regex HTML integration
[SVN r7849]
2000-09-26 19:02:50 +00:00
75aadf0509 removed tabs
[SVN r7835]
2000-09-25 21:19:29 +00:00
4f9b0bcb9b disabled warning about operator-> not returning a UDT. If operator->
does not get called, it should not be checked for this error. This
showed up when using an iterator with value_type=int.


[SVN r7813]
2000-09-25 05:36:21 +00:00
9628e5adb0 Fix broken links
[SVN r7770]
2000-09-22 18:09:04 +00:00
104 changed files with 18594 additions and 5548 deletions

109
Assignable.html Normal file
View File

@ -0,0 +1,109 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<title>Assignable</title>
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86"><br clear="none">
<h1>Assignable</h1>
<h3>Description</h3>
<p>A type is Assignable if it is possible to assign one object of the type
to another object of that type.</p>
<h3>Notation</h3>
<table summary="">
<tr>
<td valign="top"><tt>T</tt></td>
<td valign="top">is type that is a model of Assignable</td>
</tr>
<tr>
<td valign="top"><tt>t</tt></td>
<td valign="top">is an object of type <tt>T</tt></td>
</tr>
<tr>
<td valign="top"><tt>u</tt></td>
<td valign="top">is an object of type <tt>T</tt> or possibly <tt>const
T</tt></td>
</tr>
</table>
<h3>Definitions</h3>
<h3>Valid expressions</h3>
<table border summary="">
<tr>
<th>Name</th>
<th>Expression</th>
<th>Return type</th>
<th>Semantics</th>
</tr>
<tr>
<td valign="top">Assignment</td>
<td valign="top"><tt>t = u</tt></td>
<td valign="top"><tt>T&amp;</tt></td>
<td valign="top"><tt>t</tt> is equivalent to <tt>u</tt></td>
</tr>
</table>
<h3>Models</h3>
<ul>
<li><tt>int</tt></li>
<li><tt>std::pair</tt></li>
</ul>
<h3>See also</h3>
<p><a href=
"http://www.sgi.com/tech/stl/DefaultConstructible.html">DefaultConstructible</a>
and <a href="./CopyConstructible.html">CopyConstructible</a><br></p>
<hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
height="31" width="88"></a></p>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
<table summary="">
<tr valign="top">
<td nowrap><i>Copyright &copy; 2000</i></td>
<td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of
Notre Dame (<a href=
"mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td>
</tr>
</table>
<p><i>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href=
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
</body>
</html>

534
Collection.html Normal file
View File

@ -0,0 +1,534 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<title>Collection</title>
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<h1><img src="../../boost.png" alt="boost logo" width="277" align="middle"
height="86"><br>
Collection</h1>
<h3>Description</h3>
<p>A Collection is a <i>concept</i> similar to the STL <a href=
"http://www.sgi.com/tech/stl/Container.html">Container</a> concept. A
Collection provides iterators for accessing a range of elements and
provides information about the number of elements in the Collection.
However, a Collection has fewer requirements than a Container. The
motivation for the Collection concept is that there are many useful
Container-like types that do not meet the full requirements of Container,
and many algorithms that can be written with this reduced set of
requirements. To summarize the reduction in requirements:</p>
<ul>
<li>It is not required to "own" its elements: the lifetime of an element
in a Collection does not have to match the lifetime of the Collection
object, though the lifetime of the element should cover the lifetime of
the Collection object.</li>
<li>The semantics of copying a Collection object is not defined (it could
be a deep or shallow copy or not even support copying).</li>
<li>The associated reference type of a Collection does not have to be a
real C++ reference.</li>
</ul>Because of the reduced requirements, some care must be taken when
writing code that is meant to be generic for all Collection types. In
particular, a Collection object should be passed by-reference since
assumptions can not be made about the behaviour of the copy constructor.
<h3>Associated types</h3>
<table border summary="">
<tr>
<td valign="top">Value type</td>
<td valign="top"><tt>X::value_type</tt></td>
<td valign="top">The type of the object stored in a Collection. If the
Collection is <i>mutable</i> then the value type must be <a href=
"http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>. Otherwise
the value type must be <a href=
"./CopyConstructible.html">CopyConstructible</a>.</td>
</tr>
<tr>
<td valign="top">Iterator type</td>
<td valign="top"><tt>X::iterator</tt></td>
<td valign="top">The type of iterator used to iterate through a
Collection's elements. The iterator's value type is expected to be the
Collection's value type. A conversion from the iterator type to the
const iterator type must exist. The iterator type must be an <a href=
"http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.</td>
</tr>
<tr>
<td valign="top">Const iterator type</td>
<td valign="top"><tt>X::const_iterator</tt></td>
<td valign="top">A type of iterator that may be used to examine, but
not to modify, a Collection's elements.</td>
</tr>
<tr>
<td valign="top">Reference type</td>
<td valign="top"><tt>X::reference</tt></td>
<td valign="top">A type that behaves like a reference to the
Collection's value type. <a href="#n1">[1]</a></td>
</tr>
<tr>
<td valign="top">Const reference type</td>
<td valign="top"><tt>X::const_reference</tt></td>
<td valign="top">A type that behaves like a const reference to the
Collection's value type.</td>
</tr>
<tr>
<td valign="top">Pointer type</td>
<td valign="top"><tt>X::pointer</tt></td>
<td valign="top">A type that behaves as a pointer to the Collection's
value type.</td>
</tr>
<tr>
<td valign="top">Distance type</td>
<td valign="top"><tt>X::difference_type</tt></td>
<td valign="top">A signed integral type used to represent the distance
between two of the Collection's iterators. This type must be the same
as the iterator's distance type.</td>
</tr>
<tr>
<td valign="top">Size type</td>
<td valign="top"><tt>X::size_type</tt></td>
<td valign="top">An unsigned integral type that can represent any
nonnegative value of the Collection's distance type.</td>
</tr>
</table>
<h3>Notation</h3>
<table summary="">
<tr>
<td valign="top"><tt>X</tt></td>
<td valign="top">A type that is a model of Collection.</td>
</tr>
<tr>
<td valign="top"><tt>a</tt>, <tt>b</tt></td>
<td valign="top">Object of type <tt>X</tt>.</td>
</tr>
<tr>
<td valign="top"><tt>T</tt></td>
<td valign="top">The value type of <tt>X</tt>.</td>
</tr>
</table>
<h3>Valid expressions</h3>
<p>The following expressions must be valid.</p>
<table border summary="">
<tr>
<th>Name</th>
<th>Expression</th>
<th>Return type</th>
</tr>
<tr>
<td valign="top">Beginning of range</td>
<td valign="top"><tt>a.begin()</tt></td>
<td valign="top"><tt>iterator</tt> if <tt>a</tt> is mutable,
<tt>const_iterator</tt> otherwise</td>
</tr>
<tr>
<td valign="top">End of range</td>
<td valign="top"><tt>a.end()</tt></td>
<td valign="top"><tt>iterator</tt> if <tt>a</tt> is mutable,
<tt>const_iterator</tt> otherwise</td>
</tr>
<tr>
<td valign="top">Size</td>
<td valign="top"><tt>a.size()</tt></td>
<td valign="top"><tt>size_type</tt></td>
</tr><!--
<TR>
<TD VAlign=top>
Maximum size
</TD>
<TD VAlign=top>
<tt>a.max_size()</tt>
</TD>
<TD VAlign=top>
<tt>size_type</tt>
</TD>
</TR>
-->
<tr>
<td valign="top">Empty Collection</td>
<td valign="top"><tt>a.empty()</tt></td>
<td valign="top">Convertible to <tt>bool</tt></td>
</tr>
<tr>
<td valign="top">Swap</td>
<td valign="top"><tt>a.swap(b)</tt></td>
<td valign="top"><tt>void</tt></td>
</tr>
</table>
<h3>Expression semantics</h3>
<table border summary="">
<tr>
<th>Name</th>
<th>Expression</th>
<th>Semantics</th>
<th>Postcondition</th>
</tr>
<tr>
<td valign="top">Beginning of range</td>
<td valign="top"><tt>a.begin()</tt></td>
<td valign="top">Returns an iterator pointing to the first element in
the Collection.</td>
<td valign="top"><tt>a.begin()</tt> is either dereferenceable or
past-the-end. It is past-the-end if and only if <tt>a.size() ==
0</tt>.</td>
</tr>
<tr>
<td valign="top">End of range</td>
<td valign="top"><tt>a.end()</tt></td>
<td valign="top">Returns an iterator pointing one past the last element
in the Collection.</td>
<td valign="top"><tt>a.end()</tt> is past-the-end.</td>
</tr>
<tr>
<td valign="top">Size</td>
<td valign="top"><tt>a.size()</tt></td>
<td valign="top">Returns the size of the Collection, that is, its
number of elements.</td>
<td valign="top"><tt>a.size() &gt;= 0</tt></td>
</tr><!--
<TR>
<TD VAlign=top>
Maximum size
</TD>
<TD VAlign=top>
<tt>a.max_size()</tt>
</TD>
<TD VAlign=top>
&nbsp;
</TD>
<TD VAlign=top>
Returns the largest size that this Collection can ever have. <A href="#8">[8]</A>
</TD>
<TD VAlign=top>
<tt>a.max_size() &gt;= 0 &amp;&amp; a.max_size() &gt;= a.size()</tt>
</TD>
</TR>
-->
<tr>
<td valign="top">Empty Collection</td>
<td valign="top"><tt>a.empty()</tt></td>
<td valign="top">Equivalent to <tt>a.size() == 0</tt>. (But possibly
faster.)</td>
<td valign="top">&nbsp;</td>
</tr>
<tr>
<td valign="top">Swap</td>
<td valign="top"><tt>a.swap(b)</tt></td>
<td valign="top">Equivalent to <tt>swap(a,b)</tt></td>
<td valign="top">&nbsp;</td>
</tr>
</table>
<h3>Complexity guarantees</h3>
<p><tt>begin()</tt> and <tt>end()</tt> are amortized constant time.</p>
<p><tt>size()</tt> is at most linear in the Collection's size.
<tt>empty()</tt> is amortized constant time.</p>
<p><tt>swap()</tt> is at most linear in the size of the two
collections.</p>
<h3>Invariants</h3>
<table border summary="">
<tr>
<td valign="top">Valid range</td>
<td valign="top">For any Collection <tt>a</tt>, <tt>[a.begin(),
a.end())</tt> is a valid range.</td>
</tr>
<tr>
<td valign="top">Range size</td>
<td valign="top"><tt>a.size()</tt> is equal to the distance from
<tt>a.begin()</tt> to <tt>a.end()</tt>.</td>
</tr>
<tr>
<td valign="top">Completeness</td>
<td valign="top">An algorithm that iterates through the range
<tt>[a.begin(), a.end())</tt> will pass through every element of
<tt>a</tt>.</td>
</tr>
</table>
<h3>Models</h3>
<ul>
<li><tt>array</tt></li>
<li><tt>array_ptr</tt></li>
<li><tt>vector&lt;bool&gt;</tt></li>
</ul>
<h3>Collection Refinements</h3>
<p>There are quite a few concepts that refine the Collection concept,
similar to the concepts that refine the Container concept. Here is a brief
overview of the refining concepts.</p>
<h4>ForwardCollection</h4>
<p>The elements are arranged in some order that does not change
spontaneously from one iteration to the next. As a result, a
ForwardCollection is <a href=
"http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</a>
and <a href=
"http://www.sgi.com/tech/stl/LessThanComparable.html">LessThanComparable</a>.
In addition, the iterator type of a ForwardCollection is a
MultiPassInputIterator which is just an InputIterator with the added
requirements that the iterator can be used to make multiple passes through
a range, and that if <tt>it1 == it2</tt> and <tt>it1</tt> is
dereferenceable then <tt>++it1 == ++it2</tt>. The ForwardCollection also
has a <tt>front()</tt> method.</p>
<table border summary="">
<tr>
<th>Name</th>
<th>Expression</th>
<th>Return type</th>
<th>Semantics</th>
</tr>
<tr>
<td valign="top">Front</td>
<td valign="top"><tt>a.front()</tt></td>
<td valign="top"><tt>reference</tt> if <tt>a</tt> is mutable,<br>
<tt>const_reference</tt> otherwise.</td>
<td valign="top">Equivalent to <tt>*(a.begin())</tt>.</td>
</tr>
</table>
<h4>ReversibleCollection</h4>
<p>The container provides access to iterators that traverse in both
directions (forward and reverse). The iterator type must meet all of the
requirements of <a href=
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>
except that the reference type does not have to be a real C++ reference.
The ReversibleCollection adds the following requirements to those of
ForwardCollection.</p>
<table border summary="">
<tr>
<th>Name</th>
<th>Expression</th>
<th>Return type</th>
<th>Semantics</th>
</tr>
<tr>
<td valign="top">Beginning of range</td>
<td valign="top"><tt>a.rbegin()</tt></td>
<td valign="top"><tt>reverse_iterator</tt> if <tt>a</tt> is mutable,
<tt>const_reverse_iterator</tt> otherwise.</td>
<td valign="top">Equivalent to
<tt>X::reverse_iterator(a.end())</tt>.</td>
</tr>
<tr>
<td valign="top">End of range</td>
<td valign="top"><tt>a.rend()</tt></td>
<td valign="top"><tt>reverse_iterator</tt> if <tt>a</tt> is mutable,
<tt>const_reverse_iterator</tt> otherwise.</td>
<td valign="top">Equivalent to
<tt>X::reverse_iterator(a.begin())</tt>.</td>
</tr>
<tr>
<td valign="top">Back</td>
<td valign="top"><tt>a.back()</tt></td>
<td valign="top"><tt>reference</tt> if <tt>a</tt> is mutable,<br>
<tt>const_reference</tt> otherwise.</td>
<td valign="top">Equivalent to <tt>*(--a.end())</tt>.</td>
</tr>
</table>
<h4>SequentialCollection</h4>
<p>The elements are arranged in a strict linear order. No extra methods are
required.</p>
<h4>RandomAccessCollection</h4>
<p>The iterators of a RandomAccessCollection satisfy all of the
requirements of <a href=
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>
except that the reference type does not have to be a real C++ reference. In
addition, a RandomAccessCollection provides an element access operator.</p>
<table border summary="">
<tr>
<th>Name</th>
<th>Expression</th>
<th>Return type</th>
<th>Semantics</th>
</tr>
<tr>
<td valign="top">Element Access</td>
<td valign="top"><tt>a[n]</tt></td>
<td valign="top"><tt>reference</tt> if <tt>a</tt> is mutable,
<tt>const_reference</tt> otherwise.</td>
<td valign="top">Returns the nth element of the Collection. <tt>n</tt>
must be convertible to <tt>size_type</tt>. Precondition: <tt>0 &lt;= n
&lt; a.size()</tt>.</td>
</tr>
</table>
<h3>Notes</h3>
<p><a name="n1" id="n1">[1]</a> The reference type does not have to be a
real C++ reference. The requirements of the reference type depend on the
context within which the Collection is being used. Specifically it depends
on the requirements the context places on the value type of the Collection.
The reference type of the Collection must meet the same requirements as the
value type. In addition, the reference objects must be equivalent to the
value type objects in the collection (which is trivially true if they are
the same object). Also, in a mutable Collection, an assignment to the
reference object must result in an assignment to the object in the
Collection (again, which is trivially true if they are the same object, but
non-trivial if the reference type is a proxy class).</p>
<h3>See also</h3>
<p><a href=
"http://www.sgi.com/tech/stl/Container.html">Container</a><br></p>
<hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
height="31" width="88"></a></p>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05
December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
<table summary="">
<tr valign="top">
<td nowrap><i>Copyright &copy; 2000</i></td>
<td><i><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy
Siek</a>, Univ.of Notre Dame and C++ Library &amp; Compiler Group/SGI
(<a href="mailto:jsiek@engr.sgi.com">jsiek@engr.sgi.com</a>)</i></td>
</tr>
</table>
<p><i>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href=
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
</body>
</html>

View File

@ -1,188 +1,185 @@
<HTML>
<!--
-- Copyright (c) Jeremy Siek 2000
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. Silicon Graphics makes no
-- representations about the suitability of this software for any
-- purpose. It is provided "as is" without express or implied warranty.
-->
<Head>
<Title>CopyConstructible</Title>
</HEAD>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../c++boost.gif"
ALT="C++ Boost">
<!--end header-->
<BR Clear>
<H1>CopyConstructible</H1>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<h3>Description</h3>
A type is CopyConstructible if it is possible to copy objects of that
type.
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<h3>Notation</h3>
<Table>
<TR>
<TD VAlign=top>
<tt>T</tt>
</TD>
<TD VAlign=top>
is type that is a model of CopyConstructible
</TD>
</TR>
<title>Copy Constructible</title>
</head>
<TR>
<TD VAlign=top>
<tt>t</tt>
</TD>
<TD VAlign=top>
is an object of type <tt>T</tt>
</TD>
</tr>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86"><br clear="none">
<TR>
<TD VAlign=top>
<tt>u</tt>
</TD>
<TD VAlign=top>
is an object of type <tt>const T</tt>
</TD>
</tr>
<h1>Copy Constructible</h1>
</table>
<h3>Definitions</h3>
<h3>Valid expressions</h3>
<Table border>
<TR>
<TH>
Name
</TH>
<TH>
Expression
</TH>
<TH>
Return type
</TH>
<TH>
Semantics
</TH>
</TR>
<TR>
<TD VAlign=top>
Copy constructor
</TD>
<TD VAlign=top>
<tt>T(t)</tt>
</TD>
<TD VAlign=top>
<tt>T</tt>
</TD>
<TD VAlign=top>
<tt>t</tt> is equivalent to <tt>T(t)</tt>
</TD>
</TR>
<h3>Description</h3>
<p>A type is Copy Constructible if it is possible to copy objects of that
type.</p>
<TR>
<TD VAlign=top>
Copy constructor
</TD>
<TD VAlign=top>
<pre>
<h3>Notation</h3>
<table summary="">
<tr>
<td valign="top"><tt>T</tt></td>
<td valign="top">is type that is a model of Copy Constructible</td>
</tr>
<tr>
<td valign="top"><tt>t</tt></td>
<td valign="top">is an object of type <tt>T</tt></td>
</tr>
<tr>
<td valign="top"><tt>u</tt></td>
<td valign="top">is an object of type <tt>const T</tt></td>
</tr>
</table>
<h3>Definitions</h3>
<h3>Valid expressions</h3>
<table border summary="">
<tr>
<th>Name</th>
<th>Expression</th>
<th>Return type</th>
<th>Semantics</th>
</tr>
<tr>
<td valign="top">Copy constructor</td>
<td valign="top"><tt>T(t)</tt></td>
<td valign="top"><tt>T</tt></td>
<td valign="top"><tt>t</tt> is equivalent to <tt>T(t)</tt></td>
</tr>
<tr>
<td valign="top">Copy constructor</td>
<td valign="top">
<pre>
T(u)
</pre>
</TD>
<TD VAlign=top>
<tt>T</tt>
</TD>
<TD VAlign=top>
<tt>u</tt> is equivalent to <tt>T(u)</tt>
</TD>
</TR>
</td>
<td valign="top"><tt>T</tt></td>
<TR>
<TD VAlign=top>
Destructor
</TD>
<TD VAlign=top>
<pre>
<td valign="top"><tt>u</tt> is equivalent to <tt>T(u)</tt></td>
</tr>
<tr>
<td valign="top">Destructor</td>
<td valign="top">
<pre>
t.~T()
</pre>
</TD>
<TD VAlign=top>
<tt>T</tt>
</TD>
<TD VAlign=top>
&nbsp;
</TD>
</TR>
</td>
<TR>
<TD VAlign=top>
Address Operator
</TD>
<TD VAlign=top>
<pre>
<td valign="top"><tt>T</tt></td>
<td valign="top">&nbsp;</td>
</tr>
<tr>
<td valign="top">Address Operator</td>
<td valign="top">
<pre>
&amp;t
</pre>
</TD>
<TD VAlign=top>
<tt>T*</tt>
</TD>
<TD VAlign=top>
denotes the address of <tt>t</tt>
</TD>
</TR>
</td>
<TR>
<TD VAlign=top>
Address Operator
</TD>
<TD VAlign=top>
<pre>
<td valign="top"><tt>T*</tt></td>
<td valign="top">denotes the address of <tt>t</tt></td>
</tr>
<tr>
<td valign="top">Address Operator</td>
<td valign="top">
<pre>
&amp;u
</pre>
</TD>
<TD VAlign=top>
<tt>T*</tt>
</TD>
<TD VAlign=top>
denotes the address of <tt>u</tt>
</TD>
</TR>
</td>
<td valign="top"><tt>T*</tt></td>
<td valign="top">denotes the address of <tt>u</tt></td>
</tr>
</table>
</table>
<h3>Models</h3>
<ul>
<li><tt>int</tt></li>
</table>
<h3>Models</h3>
<li><tt>std::pair</tt></li>
</ul>
<UL>
<LI><tt>int</tt>
<LI><tt>std::pair</tt>
</UL>
<h3>Concept Checking Class</h3>
<pre>
template &lt;class T&gt;
struct CopyConstructibleConcept
{
void constraints() {
T a(b); // require copy constructor
T* ptr = &amp;a; // require address of operator
const_constraints(a);
ignore_unused_variable_warning(ptr);
}
void const_constraints(const T&amp; a) {
T c(a); // require const copy constructor
const T* ptr = &amp;a; // require const address of operator
ignore_unused_variable_warning(c);
ignore_unused_variable_warning(ptr);
}
T b;
};
</pre>
<h3>See also</h3>
<A
href="http://www.sgi.com/Technology/STL/DefaultConstructible.html">DefaultConstructible</A>
and
<A href="http://www.sgi.com/Technology/STL/Assignable.html">Assignable</A>
<h3>See also</h3>
<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2000</TD><TD>
<A HREF=http://www.lsc.nd.edu/~jsiek>Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
</TD></TR></TABLE>
<p><a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default
Constructible</a> and <a href="./Assignable.html">Assignable</a><br></p>
<hr>
</BODY>
</HTML>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
height="31" width="88"></a></p>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05
December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
<table summary="">
<tr valign="top">
<td nowrap><i>Copyright &copy; 2000</i></td>
<td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of
Notre Dame (<a href=
"mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td>
</tr>
</table>
<p><i>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href=
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
</body>
</html>

210
LessThanComparable.html Normal file
View File

@ -0,0 +1,210 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!--
== Copyright (c) 1996-1999
== Silicon Graphics Computer Systems, Inc.
==
== Permission to use, copy, modify, distribute and sell this software
== and its documentation for any purpose is hereby granted without fee,
== provided that the above copyright notice appears in all copies and
== that both that copyright notice and this permission notice appear
== in supporting documentation. Silicon Graphics makes no
== representations about the suitability of this software for any
== purpose. It is provided "as is" without express or implied warranty.
==
== Copyright (c) 1994
== Hewlett-Packard Company
==
== Permission to use, copy, modify, distribute and sell this software
== and its documentation for any purpose is hereby granted without fee,
== provided that the above copyright notice appears in all copies and
== that both that copyright notice and this permission notice appear
== in supporting documentation. Hewlett-Packard Company makes no
== representations about the suitability of this software for any
== purpose. It is provided "as is" without express or implied warranty.
==
-->
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<title>LessThanComparable</title>
</head>
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86"><br clear="none">
<h1>LessThanComparable</h1>
<h3>Description</h3>
<p>A type is LessThanComparable if it is ordered: it must be possible to
compare two objects of that type using <tt>operator&lt;</tt>, and
<tt>operator&lt;</tt> must be a strict weak ordering relation.</p>
<h3>Refinement of</h3>
<h3>Associated types</h3>
<h3>Notation</h3>
<table summary="">
<tr>
<td valign="top"><tt>X</tt></td>
<td valign="top">A type that is a model of LessThanComparable</td>
</tr>
<tr>
<td valign="top"><tt>x</tt>, <tt>y</tt>, <tt>z</tt></td>
<td valign="top">Object of type <tt>X</tt></td>
</tr>
</table>
<h3>Definitions</h3>
<p>Consider the relation <tt>!(x &lt; y) &amp;&amp; !(y &lt; x)</tt>. If
this relation is transitive (that is, if <tt>!(x &lt; y) &amp;&amp; !(y
&lt; x) &amp;&amp; !(y &lt; z) &amp;&amp; !(z &lt; y)</tt> implies <tt>!(x
&lt; z) &amp;&amp; !(z &lt; x)</tt>), then it satisfies the mathematical
definition of an equivalence relation. In this case, <tt>operator&lt;</tt>
is a <i>strict weak ordering</i>.</p>
<p>If <tt>operator&lt;</tt> is a strict weak ordering, and if each
equivalence class has only a single element, then <tt>operator&lt;</tt> is
a <i>total ordering</i>.</p>
<h3>Valid expressions</h3>
<table border summary="">
<tr>
<th>Name</th>
<th>Expression</th>
<th>Type requirements</th>
<th>Return type</th>
</tr>
<tr>
<td valign="top">Less</td>
<td valign="top"><tt>x &lt; y</tt></td>
<td valign="top">&nbsp;</td>
<td valign="top">Convertible to <tt>bool</tt></td>
</tr>
</table>
<h3>Expression semantics</h3>
<table border summary="">
<tr>
<th>Name</th>
<th>Expression</th>
<th>Precondition</th>
<th>Semantics</th>
<th>Postcondition</th>
</tr>
<tr>
<td valign="top">Less</td>
<td valign="top"><tt>x &lt; y</tt></td>
<td valign="top"><tt>x</tt> and <tt>y</tt> are in the domain of
<tt>&lt;</tt></td>
<td valign="top">&nbsp;</td>
</tr>
</table>
<h3>Complexity guarantees</h3>
<h3>Invariants</h3>
<table border summary="">
<tr>
<td valign="top">Irreflexivity</td>
<td valign="top"><tt>x &lt; x</tt> must be false.</td>
</tr>
<tr>
<td valign="top">Antisymmetry</td>
<td valign="top"><tt>x &lt; y</tt> implies !(y &lt; x) <a href=
"#n2">[2]</a></td>
</tr>
<tr>
<td valign="top">Transitivity</td>
<td valign="top"><tt>x &lt; y</tt> and <tt>y &lt; z</tt> implies <tt>x
&lt; z</tt> <a href="#n3">[3]</a></td>
</tr>
</table>
<h3>Models</h3>
<ul>
<li>int</li>
</ul>
<h3>Notes</h3>
<p><a name="n1" id="n1">[1]</a> Only <tt>operator&lt;</tt> is fundamental;
the other inequality operators are essentially syntactic sugar.</p>
<p><a name="n2" id="n2">[2]</a> Antisymmetry is a theorem, not an axiom: it
follows from irreflexivity and transitivity.</p>
<p><a name="n3" id="n3">[3]</a> Because of irreflexivity and transitivity,
<tt>operator&lt;</tt> always satisfies the definition of a <i>partial
ordering</i>. The definition of a <i>strict weak ordering</i> is stricter,
and the definition of a <i>total ordering</i> is stricter still.</p>
<h3>See also</h3>
<p><a href=
"http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</a>,
<a href=
"http://www.sgi.com/tech/stl/StrictWeakOrdering.html">StrictWeakOrdering</a><br>
</p>
<hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
height="31" width="88"></a></p>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05
December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
<table summary="">
<tr valign="top">
<td nowrap><i>Copyright &copy; 2000</i></td>
<td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of
Notre Dame (<a href=
"mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td>
</tr>
</table>
<p><i>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href=
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
</body>
</html>

View File

@ -1,92 +1,95 @@
<HTML>
<!--
-- Copyright (c) Jeremy Siek 2000
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. Silicon Graphics makes no
-- representations about the suitability of this software for any
-- purpose. It is provided "as is" without express or implied warranty.
-->
<Head>
<Title>MultiPassInputIterator</Title>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../c++boost.gif"
ALT="C++ Boost">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<BR Clear>
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<H2>
<A NAME="concept:MultiPassInputIterator"></A>
MultiPassInputIterator
</H2>
<title>MultiPassInputIterator</title>
</head>
This concept is a refinement of <a
href="http://www.sgi.com/Technology/STL/InputIterator.html">InputIterator</a>,
adding the requirements that the iterator can be used to make multiple
passes through a range, and that if <TT>it1 == it2</TT> and
<TT>it1</TT> is dereferenceable then <TT>++it1 == ++it2</TT>. The
MultiPassInputIterator is very similar to the <a
href="http://www.sgi.com/Technology/STL/ForwardIterator.hmtl">ForwardIterator</a>. The
only difference is that a <a
href="http://www.sgi.com/Technology/STL/ForwardIterator.hmtl">ForwardIterator</a>
requires the <TT>reference</TT> type to be <TT>value_type&amp;</TT>, whereas
MultiPassInputIterator is like <a
href="http://www.sgi.com/Technology/STL/InputIterator.html">InputIterator</a>
in that the <TT>reference</TT> type merely has to be convertible to
<TT>value_type</TT>.
<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
"#FF0000">
<img src="../../boost.png" alt="C++ Boost" width="277" height=
"86"><br clear="none">
<h2><a name="concept:MultiPassInputIterator" id=
"concept:MultiPassInputIterator"></a> Multi-Pass Input Iterator</h2>
<h3>Design Notes</h3>
<p>This concept is a refinement of <a href=
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>, adding
the requirements that the iterator can be used to make multiple passes
through a range, and that if <tt>it1 == it2</tt> and <tt>it1</tt> is
dereferenceable then <tt>++it1 == ++it2</tt>. The Multi-Pass Input Iterator
is very similar to the <a href=
"http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>.
The only difference is that a <a href=
"http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>
requires the <tt>reference</tt> type to be <tt>value_type&amp;</tt>,
whereas MultiPassInputIterator is like <a href=
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a> in that
the <tt>reference</tt> type merely has to be convertible to
<tt>value_type</tt>.</p>
comments by Valentin Bonnard:
<h3>Design Notes</h3>
<p> I think that introducing MultiPassInputIterator isn't the right
solution. Do you also want to define MultiPassBidirectionnalIterator
and MultiPassRandomAccessIterator ? I don't, definitly. It only
confuses the issue. The problem lies into the existing hierarchy of
iterators, which mixes movabillity, modifiabillity and lvalue-ness,
and these are clearly independant.
<p>comments by Valentin Bonnard:</p>
<p> The terms Forward, Bidirectionnal and RandomAccess are about
movabillity and shouldn't be used to mean anything else. In a
completly orthogonal way, iterators can be immutable, mutable, or
neither. Lvalueness of iterators is also orthogonal with
immutabillity. With these clean concepts, your MultiPassInputIterator
is just called a ForwardIterator.
<p>I think that introducing Multi-Pass Input Iterator isn't the right
solution. Do you also want to define Multi-Pass Bidirectionnal Iterator and
Multi-Pass Random Access Iterator ? I don't, definitly. It only confuses
the issue. The problem lies into the existing hierarchy of iterators, which
mixes movabillity, modifiabillity and lvalue-ness, and these are clearly
independant.</p>
<p>
Other translations are:<br>
std::ForwardIterator -> ForwardIterator & LvalueIterator<br>
std::BidirectionnalIterator -> BidirectionnalIterator & LvalueIterator<br>
std::RandomAccessIterator -> RandomAccessIterator & LvalueIterator<br>
<p>The terms Forward, Bidirectionnal and Random Access are about
movabillity and shouldn't be used to mean anything else. In a completly
orthogonal way, iterators can be immutable, mutable, or neither. Lvalueness
of iterators is also orthogonal with immutabillity. With these clean
concepts, your Multi-Pass Input Iterator is just called a Forward
Iterator.</p>
<p>
Note that in practice the only operation not allowed on my
ForwardIterator which is allowed on std::ForwardIterator is
<tt>&*it</tt>. I think that <tt>&*</tt> is rarely needed in generic code.
<p>Other translations are:<br>
std::Forward Iterator -&gt; ForwardIterator &amp; Lvalue Iterator<br>
std::Bidirectionnal Iterator -&gt; Bidirectionnal Iterator &amp; Lvalue
Iterator<br>
std::Random Access Iterator -&gt; Random Access Iterator &amp; Lvalue
Iterator<br></p>
<p>
reply by Jeremy Siek:
<p>Note that in practice the only operation not allowed on my Forward
Iterator which is allowed on std::Forward Iterator is <tt>&amp;*it</tt>. I
think that <tt>&amp;*</tt> is rarely needed in generic code.</p>
<p>
The above analysis by Valentin is right on. Of course, there is
the problem with backward compatibility. The current STL implementations
are based on the old definition of ForwardIterator. The right course
of action is to get ForwardIterator, etc. changed in the C++ standard.
Once that is done we can drop MultiPassInputIterator.
<p>reply by Jeremy Siek:</p>
<p>The above analysis by Valentin is right on. Of course, there is the
problem with backward compatibility. The current STL implementations are
based on the old definition of Forward Iterator. The right course of action
is to get Forward Iterator, etc. changed in the C++ standard. Once that is
done we can drop Multi-Pass Input Iterator.<br></p>
<hr>
<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2000</TD><TD>
<A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
</TD></TR></TABLE>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
height="31" width="88"></a></p>
</BODY>
</HTML>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05
December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
<table summary="">
<tr valign="top">
<td nowrap><i>Copyright &copy; 2000</i></td>
<td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of
Notre Dame (<a href=
"mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td>
</tr>
</table>
<p><i>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href=
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
</body>
</html>

159
OptionalPointee.html Normal file
View File

@ -0,0 +1,159 @@
<HTML>
<Head>
<Title>OptionalPointee Concept</Title>
</HEAD>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../boost.png"
ALT="C++ Boost" width="277" height="86">
<!--end header-->
<BR Clear>
<H1>Concept: OptionalPointee</H1>
<h3>Description</h3>
A type is a model of <i>OptionalPointee</i> if it points to (or refers to) a value
that may not exist. That is, if it has a <b>pointee</b> which might be <b>valid</b>
(existent) or <b>invalid</b> (inexistent); and it is possible to test whether the
pointee is valid or not.
This model does <u>not</u> imply pointer semantics: i.e., it does not imply shallow copy nor
aliasing.
<h3>Notation</h3>
<Table>
<TR>
<TD VAlign=top> <tt>T</tt> </TD>
<TD VAlign=top> is a type that is a model of OptionalPointee</TD>
</TR>
<TR>
<TD VAlign=top> <tt>t</tt> </TD>
<TD VAlign=top> is an object of type <tt>T</tt> or possibly <tt>const T</tt></TD>
</tr>
</table>
<h3>Definitions</h3>
<h3>Valid expressions</h3>
<Table border>
<TR>
<TH> Name </TH>
<TH> Expression </TH>
<TH> Return type </TH>
<TH> Semantics </TH>
</TR>
<TR>
<TD VAlign=top>Value Access</TD>
<TD VAlign=top>&nbsp;<tt>*t</tt></TD>
<TD VAlign=top>&nbsp;<tt>T&amp;</tt></TD>
<TD VAlign=top>If the pointee is valid returns a reference to
the pointee.<br>
If the pointee is invalid the result is <i>undefined</i>.</TD>
<TD VAlign=top> </TD>
</TR>
<TR>
<TD VAlign=top>Value Access</TD>
<TD VAlign=top>&nbsp;<tt>t-><i>xyz</i></tt></TD>
<TD VAlign=top>&nbsp;<tt>T*</tt></TD>
<TD VAlign=top>If the pointee is valid returns a builtin pointer to the pointee.<br>
If the pointee is invalid the result is <i>undefined</i> (It might not even return NULL).<br>
</TD>
<TD VAlign=top> </TD>
</TR>
<TR>
<TD VAlign=top>Validity Test</TD>
<TD VAlign=top>&nbsp;<tt>bool(t)</tt></TD>
<TD VAlign=top>&nbsp;bool </TD>
<TD VAlign=top>If the pointee is valid returns true.<br>
If the pointee is invalid returns false.</TD>
<TD VAlign=top></TD>
</TR>
<TR>
<TD VAlign=top>Invalidity Test</TD>
<TD VAlign=top>&nbsp;<tt>!t</tt></TD>
<TD VAlign=top>&nbsp;bool </TD>
<TD VAlign=top>If the pointee is valid returns false.<br>
If the pointee is invalid returns true.</TD>
<TD VAlign=top></TD>
</TR>
</table>
<h3>Models</h3>
<UL>
<LI><tt>pointers, both builtin and smart.</tt>
<LI><tt>boost::optional&lt;&gt;</tt>
</UL>
<HR>
<h3>OptionalPointee and relational operations</h3>
<p>This concept does not define any particular semantic for relational operations, therefore,
a type which models this concept might have either shallow or deep relational semantics.<br>
For instance, pointers, which are models of OptionalPointee, have shallow relational operators:
comparisons of pointers do not involve comparisons of pointees.
This makes sense for pointers because they have shallow copy semantics.<br>
But boost::optional&lt;T&gt;, on the other hand, which is also a model of OptionalPointee, has
deep-copy and deep-relational semantics.<br>
If generic code is written for this concept, it is important not to use relational
operators directly because the semantics might be different depending on the actual type.<br>
Still, the concept itsef can be used to define <i>deep</i> relational tests that can
be used in generic code with any type which models OptionalPointee:</p>
<a name="equal"></a>
<p><u>Equivalence relation:</u></p>
<pre>template&lt;class OptionalPointee&gt;
inline
bool equal_pointees ( OptionalPointee const&amp; x, OptionalPointee const&amp; y )
{
return (!x) != (!y) ? false : ( !x ? true : (*x) == (*y) ) ;
}
template&lt;class OptionalPointee&gt;
struct equal_pointees_t : std::binary_function&lt;OptionalPointee,OptionalPointee,bool&gt;
{
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
{ return equal_pointees(x,y) ; }
} ;
</pre>
<p>The preceding generic function and function object have the following semantics:<br>
If both <b>x</b> and <b>y</b> have valid pointees, it compares values via <code>(*x == *y)</code>.<br>
If only one has a valid pointee, returns <code>false</code>.<br>
If both have invalid pointees, returns <code>true</code>.</p>
<a name="less"></a>
<p><u>Less-than relation:</u></p>
<pre>template&lt;class OptionalPointee&gt;
inline
bool less_pointees ( OptionalPointee const&amp; x, OptionalPointee const&amp; y )
{
return !y ? false : ( !x ? true : (*x) < (*y) ) ;
}
template&lt;class OptionalPointee&gt;
struct less_pointees_t : std::binary_function&lt;OptionalPointee,OptionalPointee,bool&gt;
{
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
{ return less_pointees(x,y) ; }
} ;
</pre>
<p>The preceding generic function and function object have the following semantics:<br>
If <b>y</b> has an invalid pointee, returns <code>false</code>.<br>
Else, if <b>x</b> has an invalid pointee, returns <code>true</code>.<br>
Else, ( <b>x</b> and <b>y</b> have valid pointees), compares values via <code>(*x &lt;
*y).</code></p>
<p><br>
All these functions and function
objects are is implemented in <a href="../../boost/utility/compare_pointees.hpp">compare_pointees.hpp</a></p>
<p>Notice that OptionalPointee does not imply aliasing (and optional&lt;&gt; for instance does not alias);
so direct usage of relational operators with the implied aliasing of shallow semantics
-as with pointers- should not be used with generic code written for this concept.</p>
<h3>Acknowledgements</h3>
<p>Based on the original concept developed by Augustus Saunders.
<br>
</p>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2003</TD><TD>
<A HREF="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</A>
</TD></TR></TABLE>
<p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
</BODY>
</HTML>

View File

@ -1,423 +0,0 @@
/*
*
* Copyright (c) 1999
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* This file provides some example of type_traits usage -
* by "optimising" various algorithms:
*
* opt::copy - optimised for trivial copy (cf std::copy)
* opt::fill - optimised for trivial copy/small types (cf std::fill)
* opt::destroy_array - an example of optimisation based upon omitted destructor calls
* opt::iter_swap - uses type_traits to determine whether the iterator is a proxy
* in which case it uses a "safe" approach, otherwise calls swap
* on the assumption that swap may be specialised for the pointed-to type.
*
*/
/* Release notes:
23rd July 2000:
Added explicit failure for broken compilers that don't support these examples.
Fixed broken gcc support (broken using directive).
Reordered tests slightly.
*/
#include <iostream>
#include <typeinfo>
#include <algorithm>
#include <iterator>
#include <vector>
#include <memory>
#include <boost/timer.hpp>
#include <boost/type_traits.hpp>
#include <boost/call_traits.hpp>
using std::cout;
using std::endl;
using std::cin;
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#error "Sorry, without template partial specialisation support there isn't anything to test here..."
#endif
namespace opt{
//
// algorithm destroy_array:
// The reverse of std::unitialized_copy, takes a block of
// unitialized memory and calls destructors on all objects therein.
//
namespace detail{
template <bool>
struct array_destroyer
{
template <class T>
static void destroy_array(T* i, T* j){ do_destroy_array(i, j); }
};
template <>
struct array_destroyer<true>
{
template <class T>
static void destroy_array(T*, T*){}
};
template <class T>
void do_destroy_array(T* first, T* last)
{
while(first != last)
{
first->~T();
++first;
}
}
}; // namespace detail
template <class T>
inline void destroy_array(T* p1, T* p2)
{
detail::array_destroyer<boost::has_trivial_destructor<T>::value>::destroy_array(p1, p2);
}
//
// unoptimised versions of destroy_array:
//
template <class T>
void destroy_array1(T* first, T* last)
{
while(first != last)
{
first->~T();
++first;
}
}
template <class T>
void destroy_array2(T* first, T* last)
{
for(; first != last; ++first) first->~T();
}
//
// opt::copy
// same semantics as std::copy
// calls memcpy where appropiate.
//
namespace detail{
template <bool b>
struct copier
{
template<typename I1, typename I2>
static I2 do_copy(I1 first, I1 last, I2 out);
};
template <bool b>
template<typename I1, typename I2>
I2 copier<b>::do_copy(I1 first, I1 last, I2 out)
{
while(first != last)
{
*out = *first;
++out;
++first;
}
return out;
}
template <>
struct copier<true>
{
template<typename I1, typename I2>
static I2* do_copy(I1* first, I1* last, I2* out)
{
memcpy(out, first, (last-first)*sizeof(I2));
return out+(last-first);
}
};
}
template<typename I1, typename I2>
inline I2 copy(I1 first, I1 last, I2 out)
{
typedef typename boost::remove_cv<typename std::iterator_traits<I1>::value_type>::type v1_t;
typedef typename boost::remove_cv<typename std::iterator_traits<I2>::value_type>::type v2_t;
enum{ can_opt = boost::is_same<v1_t, v2_t>::value
&& boost::is_pointer<I1>::value
&& boost::is_pointer<I2>::value
&& boost::has_trivial_assign<v1_t>::value };
return detail::copier<can_opt>::do_copy(first, last, out);
}
//
// fill
// same as std::fill, uses memset where appropriate, along with call_traits
// to "optimise" parameter passing.
//
namespace detail{
template <bool opt>
struct filler
{
template <typename I, typename T>
static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val);
};
template <bool b>
template <typename I, typename T>
void filler<b>::do_fill(I first, I last, typename boost::call_traits<T>::param_type val)
{
while(first != last)
{
*first = val;
++first;
}
}
template <>
struct filler<true>
{
template <typename I, typename T>
static void do_fill(I first, I last, T val)
{
memset(first, val, last-first);
}
};
}
template <class I, class T>
inline void fill(I first, I last, const T& val)
{
enum{ can_opt = boost::is_pointer<I>::value
&& boost::is_arithmetic<T>::value
&& (sizeof(T) == 1) };
typedef detail::filler<can_opt> filler_t;
filler_t::template do_fill<I,T>(first, last, val);
}
//
// iter_swap:
// tests whether iterator is a proxying iterator or not, and
// uses optimal form accordingly:
//
namespace detail{
template <bool b>
struct swapper
{
template <typename I>
static void do_swap(I one, I two)
{
typedef typename std::iterator_traits<I>::value_type v_t;
v_t v = *one;
*one = *two;
*two = v;
}
};
#ifdef __GNUC__
using std::swap;
#endif
template <>
struct swapper<true>
{
template <typename I>
static void do_swap(I one, I two)
{
using std::swap;
swap(*one, *two);
}
};
}
template <typename I1, typename I2>
inline void iter_swap(I1 one, I2 two)
{
typedef typename std::iterator_traits<I1>::reference r1_t;
typedef typename std::iterator_traits<I2>::reference r2_t;
enum{ can_opt = boost::is_reference<r1_t>::value && boost::is_reference<r2_t>::value && boost::is_same<r1_t, r2_t>::value };
detail::swapper<can_opt>::do_swap(one, two);
}
}; // namespace opt
//
// define some global data:
//
const int array_size = 1000;
int i_array[array_size] = {0,};
const int ci_array[array_size] = {0,};
char c_array[array_size] = {0,};
const char cc_array[array_size] = { 0,};
const int iter_count = 1000000;
int main()
{
//
// test destroy_array,
// compare destruction time of an array of ints
// with unoptimised form.
//
cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
cout << "testing destroy_array...\n"
"[Some compilers may be able to optimise the \"unoptimised\"\n versions as well as type_traits does.]" << endl;
/*cache load*/ opt::destroy_array(i_array, i_array + array_size);
boost::timer t;
double result;
int i;
for(i = 0; i < iter_count; ++i)
{
opt::destroy_array(i_array, i_array + array_size);
}
result = t.elapsed();
cout << "destroy_array<int>: " << result << endl;
/*cache load*/ opt::destroy_array1(i_array, i_array + array_size);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::destroy_array1(i_array, i_array + array_size);
}
result = t.elapsed();
cout << "destroy_array<int>(unoptimised#1): " << result << endl;
/*cache load*/ opt::destroy_array2(i_array, i_array + array_size);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::destroy_array2(i_array, i_array + array_size);
}
result = t.elapsed();
cout << "destroy_array<int>(unoptimised#2): " << result << endl << endl;
cout << "testing fill(char)...\n"
"[Some standard library versions may already perform this optimisation.]" << endl;
/*cache load*/ opt::fill<char*, char>(c_array, c_array + array_size, (char)3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::fill<char*, char>(c_array, c_array + array_size, (char)3);
}
result = t.elapsed();
cout << "opt::fill<char*, char>: " << result << endl;
/*cache load*/ std::fill(c_array, c_array + array_size, (char)3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
std::fill(c_array, c_array + array_size, (char)3);
}
result = t.elapsed();
cout << "std::fill<char*, char>: " << result << endl << endl;
cout << "testing fill(int)...\n"
"[Tests the effect of call_traits pass-by-value optimisation -\nthe value of this optimisation may depend upon hardware characteristics.]" << endl;
/*cache load*/ opt::fill<int*, int>(i_array, i_array + array_size, 3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::fill<int*, int>(i_array, i_array + array_size, 3);
}
result = t.elapsed();
cout << "opt::fill<int*, int>: " << result << endl;
/*cache load*/ std::fill(i_array, i_array + array_size, 3);
t.restart();
for(i = 0; i < iter_count; ++i)
{
std::fill(i_array, i_array + array_size, 3);
}
result = t.elapsed();
cout << "std::fill<int*, int>: " << result << endl << endl;
cout << "testing copy...\n"
"[Some standard library versions may already perform this optimisation.]" << endl;
/*cache load*/ opt::copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
}
result = t.elapsed();
cout << "opt::copy<const int*, int*>: " << result << endl;
/*cache load*/ std::copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
t.restart();
for(i = 0; i < iter_count; ++i)
{
std::copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
}
result = t.elapsed();
cout << "std::copy<const int*, int*>: " << result << endl;
/*cache load*/ opt::detail::copier<false>::template do_copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::detail::copier<false>::template do_copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
}
result = t.elapsed();
cout << "standard \"unoptimised\" copy: " << result << endl << endl;
/*cache load*/ opt::copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
}
result = t.elapsed();
cout << "opt::copy<const char*, char*>: " << result << endl;
/*cache load*/ std::copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
t.restart();
for(i = 0; i < iter_count; ++i)
{
std::copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
}
result = t.elapsed();
cout << "std::copy<const char*, char*>: " << result << endl;
/*cache load*/ opt::detail::copier<false>::template do_copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
t.restart();
for(i = 0; i < iter_count; ++i)
{
opt::detail::copier<false>::template do_copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
}
result = t.elapsed();
cout << "standard \"unoptimised\" copy: " << result << endl << endl;
//
// testing iter_swap
// really just a check that it does in fact compile...
std::vector<int> v1;
v1.push_back(0);
v1.push_back(1);
std::vector<bool> v2;
v2.push_back(0);
v2.push_back(1);
opt::iter_swap(v1.begin(), v1.begin()+1);
opt::iter_swap(v2.begin(), v2.begin()+1);
cout << "Press any key to exit...";
cin.get();
}

View File

@ -0,0 +1,29 @@
//
// Test that a base_from_member<T&> can be properly constructed
//
// Copyright 2014 Agustin Berge
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/utility/base_from_member.hpp>
#include <boost/detail/lightweight_test.hpp>
struct foo : boost::base_from_member<int&>
{
explicit foo(int& ref) : boost::base_from_member<int&>(ref)
{
BOOST_TEST(&member == &ref);
}
};
int main()
{
int i = 0;
foo f(i);
return boost::report_errors();
}

595
base_from_member_test.cpp Normal file
View File

@ -0,0 +1,595 @@
// Boost test program for base-from-member class templates -----------------//
// Copyright 2001, 2003 Daryle Walker. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
// See <http://www.boost.org/libs/utility/> for the library's home page.
// Revision History
// 14 Jun 2003 Adjusted code for Boost.Test changes (Daryle Walker)
// 29 Aug 2001 Initial Version (Daryle Walker)
#include <boost/test/minimal.hpp> // for BOOST_CHECK, main
#include <boost/config.hpp> // for BOOST_NO_MEMBER_TEMPLATES
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/noncopyable.hpp> // for boost::noncopyable
#include <boost/utility/base_from_member.hpp> // for boost::base_from_member
#include <functional> // for std::binary_function, std::less
#include <iostream> // for std::cout (std::ostream, std::endl indirectly)
#include <set> // for std::set
#include <typeinfo> // for std::type_info
#include <utility> // for std::pair, std::make_pair
#include <vector> // for std::vector
// Control if extra information is printed
#ifndef CONTROL_EXTRA_PRINTING
#define CONTROL_EXTRA_PRINTING 1
#endif
// A (sub)object can be identified by its memory location and its type.
// Both are needed since an object can start at the same place as its
// first base class subobject and/or contained subobject.
typedef std::pair< void *, std::type_info const * > object_id;
// Object IDs need to be printed
std::ostream & operator <<( std::ostream &os, object_id const &oi );
// A way to generate an object ID
template < typename T >
object_id identify( T &obj );
// A custom comparison type is needed
struct object_id_compare
: std::binary_function<object_id, object_id, bool>
{
bool operator ()( object_id const &a, object_id const &b ) const;
}; // object_id_compare
// A singleton of this type coordinates the acknowledgements
// of objects being created and used.
class object_registrar
: private boost::noncopyable
{
public:
#ifndef BOOST_NO_MEMBER_TEMPLATES
template < typename T >
void register_object( T &obj )
{ this->register_object_imp( identify(obj) ); }
template < typename T, typename U >
void register_use( T &owner, U &owned )
{ this->register_use_imp( identify(owner), identify(owned) ); }
template < typename T, typename U >
void unregister_use( T &owner, U &owned )
{ this->unregister_use_imp( identify(owner), identify(owned) ); }
template < typename T >
void unregister_object( T &obj )
{ this->unregister_object_imp( identify(obj) ); }
#endif
void register_object_imp( object_id obj );
void register_use_imp( object_id owner, object_id owned );
void unregister_use_imp( object_id owner, object_id owned );
void unregister_object_imp( object_id obj );
typedef std::set<object_id, object_id_compare> set_type;
typedef std::vector<object_id> error_record_type;
typedef std::vector< std::pair<object_id, object_id> > error_pair_type;
set_type db_;
error_pair_type defrauders_in_, defrauders_out_;
error_record_type overeager_, overkilled_;
}; // object_registrar
// A sample type to be used by containing types
class base_or_member
{
public:
explicit base_or_member( int x = 1, double y = -0.25 );
~base_or_member();
}; // base_or_member
// A sample type that uses base_or_member, used
// as a base for the main demonstration classes
class base_class
{
public:
explicit base_class( base_or_member &x, base_or_member *y = 0,
base_or_member *z = 0 );
~base_class();
private:
base_or_member *x_, *y_, *z_;
}; // base_class
// This bad class demonstrates the direct method of a base class needing
// to be initialized by a member. This is improper since the member
// isn't initialized until after the base class.
class bad_class
: public base_class
{
public:
bad_class();
~bad_class();
private:
base_or_member x_;
}; // bad_class
// The first good class demonstrates the correct way to initialize a
// base class with a member. The member is changed to another base
// class, one that is initialized before the base that needs it.
class good_class_1
: private boost::base_from_member<base_or_member>
, public base_class
{
typedef boost::base_from_member<base_or_member> pbase_type;
typedef base_class base_type;
public:
good_class_1();
~good_class_1();
}; // good_class_1
// The second good class also demonstrates the correct way to initialize
// base classes with other subobjects. This class uses the other helpers
// in the library, and shows the technique of using two base subobjects
// of the "same" type.
class good_class_2
: private boost::base_from_member<base_or_member, 0>
, private boost::base_from_member<base_or_member, 1>
, private boost::base_from_member<base_or_member, 2>
, public base_class
{
typedef boost::base_from_member<base_or_member, 0> pbase_type0;
typedef boost::base_from_member<base_or_member, 1> pbase_type1;
typedef boost::base_from_member<base_or_member, 2> pbase_type2;
typedef base_class base_type;
public:
good_class_2();
~good_class_2();
}; // good_class_2
// Declare/define the single object registrar
object_registrar obj_reg;
// Main functionality
int
test_main( int , char * [] )
{
BOOST_CHECK( obj_reg.db_.empty() );
BOOST_CHECK( obj_reg.defrauders_in_.empty() );
BOOST_CHECK( obj_reg.defrauders_out_.empty() );
BOOST_CHECK( obj_reg.overeager_.empty() );
BOOST_CHECK( obj_reg.overkilled_.empty() );
// Make a separate block to examine pre- and post-effects
{
using std::cout;
using std::endl;
bad_class bc;
BOOST_CHECK( obj_reg.db_.size() == 3 );
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
good_class_1 gc1;
BOOST_CHECK( obj_reg.db_.size() == 6 );
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
good_class_2 gc2;
BOOST_CHECK( obj_reg.db_.size() == 11 );
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
BOOST_CHECK( obj_reg.defrauders_out_.empty() );
BOOST_CHECK( obj_reg.overeager_.empty() );
BOOST_CHECK( obj_reg.overkilled_.empty() );
// Getting the addresses of the objects ensure
// that they're used, and not optimized away.
cout << "Object 'bc' is at " << &bc << '.' << endl;
cout << "Object 'gc1' is at " << &gc1 << '.' << endl;
cout << "Object 'gc2' is at " << &gc2 << '.' << endl;
}
BOOST_CHECK( obj_reg.db_.empty() );
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
BOOST_CHECK( obj_reg.defrauders_out_.size() == 1 );
BOOST_CHECK( obj_reg.overeager_.empty() );
BOOST_CHECK( obj_reg.overkilled_.empty() );
return boost::exit_success;
}
// Print an object's ID
std::ostream &
operator <<
(
std::ostream & os,
object_id const & oi
)
{
// I had an std::ostringstream to help, but I did not need it since
// the program never screws around with formatting. Worse, using
// std::ostringstream is an issue with some compilers.
return os << '[' << ( oi.second ? oi.second->name() : "NOTHING" )
<< " at " << oi.first << ']';
}
// Get an object ID given an object
template < typename T >
inline
object_id
identify
(
T & obj
)
{
return std::make_pair( static_cast<void *>(&obj), &(typeid( obj )) );
}
// Compare two object IDs
bool
object_id_compare::operator ()
(
object_id const & a,
object_id const & b
) const
{
std::less<void *> vp_cmp;
if ( vp_cmp(a.first, b.first) )
{
return true;
}
else if ( vp_cmp(b.first, a.first) )
{
return false;
}
else
{
// object pointers are equal, compare the types
if ( a.second == b.second )
{
return false;
}
else if ( !a.second )
{
return true; // NULL preceeds anything else
}
else if ( !b.second )
{
return false; // NULL preceeds anything else
}
else
{
return a.second->before( *b.second ) != 0;
}
}
}
// Let an object register its existence
void
object_registrar::register_object_imp
(
object_id obj
)
{
if ( db_.count(obj) <= 0 )
{
db_.insert( obj );
#if CONTROL_EXTRA_PRINTING
std::cout << "Registered " << obj << '.' << std::endl;
#endif
}
else
{
overeager_.push_back( obj );
#if CONTROL_EXTRA_PRINTING
std::cout << "Attempted to register a non-existant " << obj
<< '.' << std::endl;
#endif
}
}
// Let an object register its use of another object
void
object_registrar::register_use_imp
(
object_id owner,
object_id owned
)
{
if ( db_.count(owned) > 0 )
{
// We don't care to record usage registrations
}
else
{
defrauders_in_.push_back( std::make_pair(owner, owned) );
#if CONTROL_EXTRA_PRINTING
std::cout << "Attempted to own a non-existant " << owned
<< " by " << owner << '.' << std::endl;
#endif
}
}
// Let an object un-register its use of another object
void
object_registrar::unregister_use_imp
(
object_id owner,
object_id owned
)
{
if ( db_.count(owned) > 0 )
{
// We don't care to record usage un-registrations
}
else
{
defrauders_out_.push_back( std::make_pair(owner, owned) );
#if CONTROL_EXTRA_PRINTING
std::cout << "Attempted to disown a non-existant " << owned
<< " by " << owner << '.' << std::endl;
#endif
}
}
// Let an object un-register its existence
void
object_registrar::unregister_object_imp
(
object_id obj
)
{
set_type::iterator const i = db_.find( obj );
if ( i != db_.end() )
{
db_.erase( i );
#if CONTROL_EXTRA_PRINTING
std::cout << "Unregistered " << obj << '.' << std::endl;
#endif
}
else
{
overkilled_.push_back( obj );
#if CONTROL_EXTRA_PRINTING
std::cout << "Attempted to unregister a non-existant " << obj
<< '.' << std::endl;
#endif
}
}
// Macros to abstract the registration of objects
#ifndef BOOST_NO_MEMBER_TEMPLATES
#define PRIVATE_REGISTER_BIRTH(o) obj_reg.register_object( (o) )
#define PRIVATE_REGISTER_DEATH(o) obj_reg.unregister_object( (o) )
#define PRIVATE_REGISTER_USE(o, w) obj_reg.register_use( (o), (w) )
#define PRIVATE_UNREGISTER_USE(o, w) obj_reg.unregister_use( (o), (w) )
#else
#define PRIVATE_REGISTER_BIRTH(o) obj_reg.register_object_imp( \
identify((o)) )
#define PRIVATE_REGISTER_DEATH(o) obj_reg.unregister_object_imp( \
identify((o)) )
#define PRIVATE_REGISTER_USE(o, w) obj_reg.register_use_imp( identify((o)), \
identify((w)) )
#define PRIVATE_UNREGISTER_USE(o, w) obj_reg.unregister_use_imp( \
identify((o)), identify((w)) )
#endif
// Create a base_or_member, with arguments to simulate member initializations
base_or_member::base_or_member
(
int x, // = 1
double y // = -0.25
)
{
PRIVATE_REGISTER_BIRTH( *this );
#if CONTROL_EXTRA_PRINTING
std::cout << "\tMy x-factor is " << x << " and my y-factor is " << y
<< '.' << std::endl;
#endif
}
// Destroy a base_or_member
inline
base_or_member::~base_or_member
(
)
{
PRIVATE_REGISTER_DEATH( *this );
}
// Create a base_class, registering any objects used
base_class::base_class
(
base_or_member & x,
base_or_member * y, // = 0
base_or_member * z // = 0
)
: x_( &x ), y_( y ), z_( z )
{
PRIVATE_REGISTER_BIRTH( *this );
#if CONTROL_EXTRA_PRINTING
std::cout << "\tMy x-factor is " << x_;
#endif
PRIVATE_REGISTER_USE( *this, *x_ );
if ( y_ )
{
#if CONTROL_EXTRA_PRINTING
std::cout << ", my y-factor is " << y_;
#endif
PRIVATE_REGISTER_USE( *this, *y_ );
}
if ( z_ )
{
#if CONTROL_EXTRA_PRINTING
std::cout << ", my z-factor is " << z_;
#endif
PRIVATE_REGISTER_USE( *this, *z_ );
}
#if CONTROL_EXTRA_PRINTING
std::cout << '.' << std::endl;
#endif
}
// Destroy a base_class, unregistering the objects it uses
base_class::~base_class
(
)
{
PRIVATE_REGISTER_DEATH( *this );
#if CONTROL_EXTRA_PRINTING
std::cout << "\tMy x-factor was " << x_;
#endif
PRIVATE_UNREGISTER_USE( *this, *x_ );
if ( y_ )
{
#if CONTROL_EXTRA_PRINTING
std::cout << ", my y-factor was " << y_;
#endif
PRIVATE_UNREGISTER_USE( *this, *y_ );
}
if ( z_ )
{
#if CONTROL_EXTRA_PRINTING
std::cout << ", my z-factor was " << z_;
#endif
PRIVATE_UNREGISTER_USE( *this, *z_ );
}
#if CONTROL_EXTRA_PRINTING
std::cout << '.' << std::endl;
#endif
}
// Create a bad_class, noting the improper construction order
bad_class::bad_class
(
)
: x_( -7, 16.75 ), base_class( x_ ) // this order doesn't matter
{
PRIVATE_REGISTER_BIRTH( *this );
#if CONTROL_EXTRA_PRINTING
std::cout << "\tMy factor is at " << &x_
<< " and my base is at " << static_cast<base_class *>(this) << '.'
<< std::endl;
#endif
}
// Destroy a bad_class, noting the improper destruction order
bad_class::~bad_class
(
)
{
PRIVATE_REGISTER_DEATH( *this );
#if CONTROL_EXTRA_PRINTING
std::cout << "\tMy factor was at " << &x_
<< " and my base was at " << static_cast<base_class *>(this)
<< '.' << std::endl;
#endif
}
// Create a good_class_1, noting the proper construction order
good_class_1::good_class_1
(
)
: pbase_type( 8 ), base_type( member )
{
PRIVATE_REGISTER_BIRTH( *this );
#if CONTROL_EXTRA_PRINTING
std::cout << "\tMy factor is at " << &member
<< " and my base is at " << static_cast<base_class *>(this) << '.'
<< std::endl;
#endif
}
// Destroy a good_class_1, noting the proper destruction order
good_class_1::~good_class_1
(
)
{
PRIVATE_REGISTER_DEATH( *this );
#if CONTROL_EXTRA_PRINTING
std::cout << "\tMy factor was at " << &member
<< " and my base was at " << static_cast<base_class *>(this)
<< '.' << std::endl;
#endif
}
// Create a good_class_2, noting the proper construction order
good_class_2::good_class_2
(
)
: pbase_type0(), pbase_type1(-16, 0.125), pbase_type2(2, -3)
, base_type( pbase_type1::member, &this->pbase_type0::member,
&this->pbase_type2::member )
{
PRIVATE_REGISTER_BIRTH( *this );
#if CONTROL_EXTRA_PRINTING
std::cout << "\tMy factors are at " << &this->pbase_type0::member
<< ", " << &this->pbase_type1::member << ", "
<< &this->pbase_type2::member << ", and my base is at "
<< static_cast<base_class *>(this) << '.' << std::endl;
#endif
}
// Destroy a good_class_2, noting the proper destruction order
good_class_2::~good_class_2
(
)
{
PRIVATE_REGISTER_DEATH( *this );
#if CONTROL_EXTRA_PRINTING
std::cout << "\tMy factors were at " << &this->pbase_type0::member
<< ", " << &this->pbase_type1::member << ", "
<< &this->pbase_type2::member << ", and my base was at "
<< static_cast<base_class *>(this) << '.' << std::endl;
#endif
}

647
binary_test.cpp Normal file
View File

@ -0,0 +1,647 @@
/*=============================================================================
Copyright (c) 2006, 2007 Matthew Calabrese
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#include <boost/test/minimal.hpp>
#include <boost/utility/binary.hpp>
#include <algorithm>
#include <cstddef>
#ifdef BOOST_MSVC
#pragma warning(disable:4996) // warning C4996: 'std::equal': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
#endif
/*
Note: This file tests every single valid bit-grouping on its own, and some
random combinations of bit-groupings.
*/
std::size_t const num_random_test_values = 32;
// Note: These hex values should all correspond with the binary array below
unsigned int const random_unsigned_ints_hex[num_random_test_values]
= { 0x0103u, 0x77ebu, 0x5f36u, 0x1f18u, 0xc530u, 0xa73au, 0xd6f8u, 0x0919u
, 0xfbb0u, 0x3e7cu, 0xd0e9u, 0x22c8u, 0x724eu, 0x14fau, 0xd98eu, 0x40b5
, 0xeba0u, 0xfe50u, 0x688au, 0x1b05u, 0x5f9cu, 0xe4fcu, 0xa7b8u, 0xd3acu
, 0x1dddu, 0xbf04u, 0x8352u, 0xe89cu, 0x7506u, 0xe767u, 0xf489u, 0xe167
};
unsigned int const random_unsigned_ints_binary[num_random_test_values]
= { BOOST_BINARY( 0 00010000 0011 ), BOOST_BINARY( 0 11101 1111 101011 )
, BOOST_BINARY( 010111 1100110 1 1 0 ), BOOST_BINARY( 000 1 11110 00 11000 )
, BOOST_BINARY( 110 001010 0110 000 ), BOOST_BINARY( 1010 01110011 1010 )
, BOOST_BINARY( 11 010 1 101111 1000 ), BOOST_BINARY( 0000 100100 0110 01 )
, BOOST_BINARY( 1111 101110 11 0000 ), BOOST_BINARY( 00111110 01111100 )
, BOOST_BINARY( 11 010 000111 01001 ), BOOST_BINARY( 00100 010110 01000 )
, BOOST_BINARY( 01 11001001 001110 ), BOOST_BINARY( 0010 1001111 1010 )
, BOOST_BINARY( 1101 1 00110 0 01110 ), BOOST_BINARY( 100 000 01011010 1 )
, BOOST_BINARY( 11 1010 1110 1000 00 ), BOOST_BINARY( 11111 110010 10000 )
, BOOST_BINARY( 01101 00010 001010 ), BOOST_BINARY( 000 11011 000001 01 )
, BOOST_BINARY( 01 01111 1100111 00 ), BOOST_BINARY( 1 110010 0111111 00 )
, BOOST_BINARY( 101 0011 11 01110 00 ), BOOST_BINARY( 110100 1 110101 100 )
, BOOST_BINARY( 00 1110111 011 101 ), BOOST_BINARY( 1011 1111 00000 100 )
, BOOST_BINARY( 1000 00110 101 0010 ), BOOST_BINARY( 1110 10001 001110 0 )
, BOOST_BINARY( 011 1010100 000 110 ), BOOST_BINARY( 1110 0111 01100 111 )
, BOOST_BINARY( 11110 10010 001001 ), BOOST_BINARY( 11 1000010 1100 111 )
};
unsigned int const unsigned_ints_1_bit[2] =
{ BOOST_BINARY( 0 )
, BOOST_BINARY( 1 )
};
unsigned int const unsigned_ints_2_bits[4] =
{ BOOST_BINARY( 00 )
, BOOST_BINARY( 01 )
, BOOST_BINARY( 10 )
, BOOST_BINARY( 11 )
};
unsigned int const unsigned_ints_3_bits[8] =
{ BOOST_BINARY( 000 )
, BOOST_BINARY( 001 )
, BOOST_BINARY( 010 )
, BOOST_BINARY( 011 )
, BOOST_BINARY( 100 )
, BOOST_BINARY( 101 )
, BOOST_BINARY( 110 )
, BOOST_BINARY( 111 )
};
unsigned int const unsigned_ints_4_bits[16] =
{ BOOST_BINARY( 0000 )
, BOOST_BINARY( 0001 )
, BOOST_BINARY( 0010 )
, BOOST_BINARY( 0011 )
, BOOST_BINARY( 0100 )
, BOOST_BINARY( 0101 )
, BOOST_BINARY( 0110 )
, BOOST_BINARY( 0111 )
, BOOST_BINARY( 1000 )
, BOOST_BINARY( 1001 )
, BOOST_BINARY( 1010 )
, BOOST_BINARY( 1011 )
, BOOST_BINARY( 1100 )
, BOOST_BINARY( 1101 )
, BOOST_BINARY( 1110 )
, BOOST_BINARY( 1111 )
};
unsigned int const unsigned_ints_5_bits[32] =
{ BOOST_BINARY( 00000 )
, BOOST_BINARY( 00001 )
, BOOST_BINARY( 00010 )
, BOOST_BINARY( 00011 )
, BOOST_BINARY( 00100 )
, BOOST_BINARY( 00101 )
, BOOST_BINARY( 00110 )
, BOOST_BINARY( 00111 )
, BOOST_BINARY( 01000 )
, BOOST_BINARY( 01001 )
, BOOST_BINARY( 01010 )
, BOOST_BINARY( 01011 )
, BOOST_BINARY( 01100 )
, BOOST_BINARY( 01101 )
, BOOST_BINARY( 01110 )
, BOOST_BINARY( 01111 )
, BOOST_BINARY( 10000 )
, BOOST_BINARY( 10001 )
, BOOST_BINARY( 10010 )
, BOOST_BINARY( 10011 )
, BOOST_BINARY( 10100 )
, BOOST_BINARY( 10101 )
, BOOST_BINARY( 10110 )
, BOOST_BINARY( 10111 )
, BOOST_BINARY( 11000 )
, BOOST_BINARY( 11001 )
, BOOST_BINARY( 11010 )
, BOOST_BINARY( 11011 )
, BOOST_BINARY( 11100 )
, BOOST_BINARY( 11101 )
, BOOST_BINARY( 11110 )
, BOOST_BINARY( 11111 )
};
unsigned int const unsigned_ints_6_bits[64] =
{ BOOST_BINARY( 000000 )
, BOOST_BINARY( 000001 )
, BOOST_BINARY( 000010 )
, BOOST_BINARY( 000011 )
, BOOST_BINARY( 000100 )
, BOOST_BINARY( 000101 )
, BOOST_BINARY( 000110 )
, BOOST_BINARY( 000111 )
, BOOST_BINARY( 001000 )
, BOOST_BINARY( 001001 )
, BOOST_BINARY( 001010 )
, BOOST_BINARY( 001011 )
, BOOST_BINARY( 001100 )
, BOOST_BINARY( 001101 )
, BOOST_BINARY( 001110 )
, BOOST_BINARY( 001111 )
, BOOST_BINARY( 010000 )
, BOOST_BINARY( 010001 )
, BOOST_BINARY( 010010 )
, BOOST_BINARY( 010011 )
, BOOST_BINARY( 010100 )
, BOOST_BINARY( 010101 )
, BOOST_BINARY( 010110 )
, BOOST_BINARY( 010111 )
, BOOST_BINARY( 011000 )
, BOOST_BINARY( 011001 )
, BOOST_BINARY( 011010 )
, BOOST_BINARY( 011011 )
, BOOST_BINARY( 011100 )
, BOOST_BINARY( 011101 )
, BOOST_BINARY( 011110 )
, BOOST_BINARY( 011111 )
, BOOST_BINARY( 100000 )
, BOOST_BINARY( 100001 )
, BOOST_BINARY( 100010 )
, BOOST_BINARY( 100011 )
, BOOST_BINARY( 100100 )
, BOOST_BINARY( 100101 )
, BOOST_BINARY( 100110 )
, BOOST_BINARY( 100111 )
, BOOST_BINARY( 101000 )
, BOOST_BINARY( 101001 )
, BOOST_BINARY( 101010 )
, BOOST_BINARY( 101011 )
, BOOST_BINARY( 101100 )
, BOOST_BINARY( 101101 )
, BOOST_BINARY( 101110 )
, BOOST_BINARY( 101111 )
, BOOST_BINARY( 110000 )
, BOOST_BINARY( 110001 )
, BOOST_BINARY( 110010 )
, BOOST_BINARY( 110011 )
, BOOST_BINARY( 110100 )
, BOOST_BINARY( 110101 )
, BOOST_BINARY( 110110 )
, BOOST_BINARY( 110111 )
, BOOST_BINARY( 111000 )
, BOOST_BINARY( 111001 )
, BOOST_BINARY( 111010 )
, BOOST_BINARY( 111011 )
, BOOST_BINARY( 111100 )
, BOOST_BINARY( 111101 )
, BOOST_BINARY( 111110 )
, BOOST_BINARY( 111111 )
};
unsigned int const unsigned_ints_7_bits[128] =
{ BOOST_BINARY( 0000000 )
, BOOST_BINARY( 0000001 )
, BOOST_BINARY( 0000010 )
, BOOST_BINARY( 0000011 )
, BOOST_BINARY( 0000100 )
, BOOST_BINARY( 0000101 )
, BOOST_BINARY( 0000110 )
, BOOST_BINARY( 0000111 )
, BOOST_BINARY( 0001000 )
, BOOST_BINARY( 0001001 )
, BOOST_BINARY( 0001010 )
, BOOST_BINARY( 0001011 )
, BOOST_BINARY( 0001100 )
, BOOST_BINARY( 0001101 )
, BOOST_BINARY( 0001110 )
, BOOST_BINARY( 0001111 )
, BOOST_BINARY( 0010000 )
, BOOST_BINARY( 0010001 )
, BOOST_BINARY( 0010010 )
, BOOST_BINARY( 0010011 )
, BOOST_BINARY( 0010100 )
, BOOST_BINARY( 0010101 )
, BOOST_BINARY( 0010110 )
, BOOST_BINARY( 0010111 )
, BOOST_BINARY( 0011000 )
, BOOST_BINARY( 0011001 )
, BOOST_BINARY( 0011010 )
, BOOST_BINARY( 0011011 )
, BOOST_BINARY( 0011100 )
, BOOST_BINARY( 0011101 )
, BOOST_BINARY( 0011110 )
, BOOST_BINARY( 0011111 )
, BOOST_BINARY( 0100000 )
, BOOST_BINARY( 0100001 )
, BOOST_BINARY( 0100010 )
, BOOST_BINARY( 0100011 )
, BOOST_BINARY( 0100100 )
, BOOST_BINARY( 0100101 )
, BOOST_BINARY( 0100110 )
, BOOST_BINARY( 0100111 )
, BOOST_BINARY( 0101000 )
, BOOST_BINARY( 0101001 )
, BOOST_BINARY( 0101010 )
, BOOST_BINARY( 0101011 )
, BOOST_BINARY( 0101100 )
, BOOST_BINARY( 0101101 )
, BOOST_BINARY( 0101110 )
, BOOST_BINARY( 0101111 )
, BOOST_BINARY( 0110000 )
, BOOST_BINARY( 0110001 )
, BOOST_BINARY( 0110010 )
, BOOST_BINARY( 0110011 )
, BOOST_BINARY( 0110100 )
, BOOST_BINARY( 0110101 )
, BOOST_BINARY( 0110110 )
, BOOST_BINARY( 0110111 )
, BOOST_BINARY( 0111000 )
, BOOST_BINARY( 0111001 )
, BOOST_BINARY( 0111010 )
, BOOST_BINARY( 0111011 )
, BOOST_BINARY( 0111100 )
, BOOST_BINARY( 0111101 )
, BOOST_BINARY( 0111110 )
, BOOST_BINARY( 0111111 )
, BOOST_BINARY( 1000000 )
, BOOST_BINARY( 1000001 )
, BOOST_BINARY( 1000010 )
, BOOST_BINARY( 1000011 )
, BOOST_BINARY( 1000100 )
, BOOST_BINARY( 1000101 )
, BOOST_BINARY( 1000110 )
, BOOST_BINARY( 1000111 )
, BOOST_BINARY( 1001000 )
, BOOST_BINARY( 1001001 )
, BOOST_BINARY( 1001010 )
, BOOST_BINARY( 1001011 )
, BOOST_BINARY( 1001100 )
, BOOST_BINARY( 1001101 )
, BOOST_BINARY( 1001110 )
, BOOST_BINARY( 1001111 )
, BOOST_BINARY( 1010000 )
, BOOST_BINARY( 1010001 )
, BOOST_BINARY( 1010010 )
, BOOST_BINARY( 1010011 )
, BOOST_BINARY( 1010100 )
, BOOST_BINARY( 1010101 )
, BOOST_BINARY( 1010110 )
, BOOST_BINARY( 1010111 )
, BOOST_BINARY( 1011000 )
, BOOST_BINARY( 1011001 )
, BOOST_BINARY( 1011010 )
, BOOST_BINARY( 1011011 )
, BOOST_BINARY( 1011100 )
, BOOST_BINARY( 1011101 )
, BOOST_BINARY( 1011110 )
, BOOST_BINARY( 1011111 )
, BOOST_BINARY( 1100000 )
, BOOST_BINARY( 1100001 )
, BOOST_BINARY( 1100010 )
, BOOST_BINARY( 1100011 )
, BOOST_BINARY( 1100100 )
, BOOST_BINARY( 1100101 )
, BOOST_BINARY( 1100110 )
, BOOST_BINARY( 1100111 )
, BOOST_BINARY( 1101000 )
, BOOST_BINARY( 1101001 )
, BOOST_BINARY( 1101010 )
, BOOST_BINARY( 1101011 )
, BOOST_BINARY( 1101100 )
, BOOST_BINARY( 1101101 )
, BOOST_BINARY( 1101110 )
, BOOST_BINARY( 1101111 )
, BOOST_BINARY( 1110000 )
, BOOST_BINARY( 1110001 )
, BOOST_BINARY( 1110010 )
, BOOST_BINARY( 1110011 )
, BOOST_BINARY( 1110100 )
, BOOST_BINARY( 1110101 )
, BOOST_BINARY( 1110110 )
, BOOST_BINARY( 1110111 )
, BOOST_BINARY( 1111000 )
, BOOST_BINARY( 1111001 )
, BOOST_BINARY( 1111010 )
, BOOST_BINARY( 1111011 )
, BOOST_BINARY( 1111100 )
, BOOST_BINARY( 1111101 )
, BOOST_BINARY( 1111110 )
, BOOST_BINARY( 1111111 )
};
unsigned int const unsigned_ints_8_bits[256] =
{ BOOST_BINARY( 00000000 )
, BOOST_BINARY( 00000001 )
, BOOST_BINARY( 00000010 )
, BOOST_BINARY( 00000011 )
, BOOST_BINARY( 00000100 )
, BOOST_BINARY( 00000101 )
, BOOST_BINARY( 00000110 )
, BOOST_BINARY( 00000111 )
, BOOST_BINARY( 00001000 )
, BOOST_BINARY( 00001001 )
, BOOST_BINARY( 00001010 )
, BOOST_BINARY( 00001011 )
, BOOST_BINARY( 00001100 )
, BOOST_BINARY( 00001101 )
, BOOST_BINARY( 00001110 )
, BOOST_BINARY( 00001111 )
, BOOST_BINARY( 00010000 )
, BOOST_BINARY( 00010001 )
, BOOST_BINARY( 00010010 )
, BOOST_BINARY( 00010011 )
, BOOST_BINARY( 00010100 )
, BOOST_BINARY( 00010101 )
, BOOST_BINARY( 00010110 )
, BOOST_BINARY( 00010111 )
, BOOST_BINARY( 00011000 )
, BOOST_BINARY( 00011001 )
, BOOST_BINARY( 00011010 )
, BOOST_BINARY( 00011011 )
, BOOST_BINARY( 00011100 )
, BOOST_BINARY( 00011101 )
, BOOST_BINARY( 00011110 )
, BOOST_BINARY( 00011111 )
, BOOST_BINARY( 00100000 )
, BOOST_BINARY( 00100001 )
, BOOST_BINARY( 00100010 )
, BOOST_BINARY( 00100011 )
, BOOST_BINARY( 00100100 )
, BOOST_BINARY( 00100101 )
, BOOST_BINARY( 00100110 )
, BOOST_BINARY( 00100111 )
, BOOST_BINARY( 00101000 )
, BOOST_BINARY( 00101001 )
, BOOST_BINARY( 00101010 )
, BOOST_BINARY( 00101011 )
, BOOST_BINARY( 00101100 )
, BOOST_BINARY( 00101101 )
, BOOST_BINARY( 00101110 )
, BOOST_BINARY( 00101111 )
, BOOST_BINARY( 00110000 )
, BOOST_BINARY( 00110001 )
, BOOST_BINARY( 00110010 )
, BOOST_BINARY( 00110011 )
, BOOST_BINARY( 00110100 )
, BOOST_BINARY( 00110101 )
, BOOST_BINARY( 00110110 )
, BOOST_BINARY( 00110111 )
, BOOST_BINARY( 00111000 )
, BOOST_BINARY( 00111001 )
, BOOST_BINARY( 00111010 )
, BOOST_BINARY( 00111011 )
, BOOST_BINARY( 00111100 )
, BOOST_BINARY( 00111101 )
, BOOST_BINARY( 00111110 )
, BOOST_BINARY( 00111111 )
, BOOST_BINARY( 01000000 )
, BOOST_BINARY( 01000001 )
, BOOST_BINARY( 01000010 )
, BOOST_BINARY( 01000011 )
, BOOST_BINARY( 01000100 )
, BOOST_BINARY( 01000101 )
, BOOST_BINARY( 01000110 )
, BOOST_BINARY( 01000111 )
, BOOST_BINARY( 01001000 )
, BOOST_BINARY( 01001001 )
, BOOST_BINARY( 01001010 )
, BOOST_BINARY( 01001011 )
, BOOST_BINARY( 01001100 )
, BOOST_BINARY( 01001101 )
, BOOST_BINARY( 01001110 )
, BOOST_BINARY( 01001111 )
, BOOST_BINARY( 01010000 )
, BOOST_BINARY( 01010001 )
, BOOST_BINARY( 01010010 )
, BOOST_BINARY( 01010011 )
, BOOST_BINARY( 01010100 )
, BOOST_BINARY( 01010101 )
, BOOST_BINARY( 01010110 )
, BOOST_BINARY( 01010111 )
, BOOST_BINARY( 01011000 )
, BOOST_BINARY( 01011001 )
, BOOST_BINARY( 01011010 )
, BOOST_BINARY( 01011011 )
, BOOST_BINARY( 01011100 )
, BOOST_BINARY( 01011101 )
, BOOST_BINARY( 01011110 )
, BOOST_BINARY( 01011111 )
, BOOST_BINARY( 01100000 )
, BOOST_BINARY( 01100001 )
, BOOST_BINARY( 01100010 )
, BOOST_BINARY( 01100011 )
, BOOST_BINARY( 01100100 )
, BOOST_BINARY( 01100101 )
, BOOST_BINARY( 01100110 )
, BOOST_BINARY( 01100111 )
, BOOST_BINARY( 01101000 )
, BOOST_BINARY( 01101001 )
, BOOST_BINARY( 01101010 )
, BOOST_BINARY( 01101011 )
, BOOST_BINARY( 01101100 )
, BOOST_BINARY( 01101101 )
, BOOST_BINARY( 01101110 )
, BOOST_BINARY( 01101111 )
, BOOST_BINARY( 01110000 )
, BOOST_BINARY( 01110001 )
, BOOST_BINARY( 01110010 )
, BOOST_BINARY( 01110011 )
, BOOST_BINARY( 01110100 )
, BOOST_BINARY( 01110101 )
, BOOST_BINARY( 01110110 )
, BOOST_BINARY( 01110111 )
, BOOST_BINARY( 01111000 )
, BOOST_BINARY( 01111001 )
, BOOST_BINARY( 01111010 )
, BOOST_BINARY( 01111011 )
, BOOST_BINARY( 01111100 )
, BOOST_BINARY( 01111101 )
, BOOST_BINARY( 01111110 )
, BOOST_BINARY( 01111111 )
, BOOST_BINARY( 10000000 )
, BOOST_BINARY( 10000001 )
, BOOST_BINARY( 10000010 )
, BOOST_BINARY( 10000011 )
, BOOST_BINARY( 10000100 )
, BOOST_BINARY( 10000101 )
, BOOST_BINARY( 10000110 )
, BOOST_BINARY( 10000111 )
, BOOST_BINARY( 10001000 )
, BOOST_BINARY( 10001001 )
, BOOST_BINARY( 10001010 )
, BOOST_BINARY( 10001011 )
, BOOST_BINARY( 10001100 )
, BOOST_BINARY( 10001101 )
, BOOST_BINARY( 10001110 )
, BOOST_BINARY( 10001111 )
, BOOST_BINARY( 10010000 )
, BOOST_BINARY( 10010001 )
, BOOST_BINARY( 10010010 )
, BOOST_BINARY( 10010011 )
, BOOST_BINARY( 10010100 )
, BOOST_BINARY( 10010101 )
, BOOST_BINARY( 10010110 )
, BOOST_BINARY( 10010111 )
, BOOST_BINARY( 10011000 )
, BOOST_BINARY( 10011001 )
, BOOST_BINARY( 10011010 )
, BOOST_BINARY( 10011011 )
, BOOST_BINARY( 10011100 )
, BOOST_BINARY( 10011101 )
, BOOST_BINARY( 10011110 )
, BOOST_BINARY( 10011111 )
, BOOST_BINARY( 10100000 )
, BOOST_BINARY( 10100001 )
, BOOST_BINARY( 10100010 )
, BOOST_BINARY( 10100011 )
, BOOST_BINARY( 10100100 )
, BOOST_BINARY( 10100101 )
, BOOST_BINARY( 10100110 )
, BOOST_BINARY( 10100111 )
, BOOST_BINARY( 10101000 )
, BOOST_BINARY( 10101001 )
, BOOST_BINARY( 10101010 )
, BOOST_BINARY( 10101011 )
, BOOST_BINARY( 10101100 )
, BOOST_BINARY( 10101101 )
, BOOST_BINARY( 10101110 )
, BOOST_BINARY( 10101111 )
, BOOST_BINARY( 10110000 )
, BOOST_BINARY( 10110001 )
, BOOST_BINARY( 10110010 )
, BOOST_BINARY( 10110011 )
, BOOST_BINARY( 10110100 )
, BOOST_BINARY( 10110101 )
, BOOST_BINARY( 10110110 )
, BOOST_BINARY( 10110111 )
, BOOST_BINARY( 10111000 )
, BOOST_BINARY( 10111001 )
, BOOST_BINARY( 10111010 )
, BOOST_BINARY( 10111011 )
, BOOST_BINARY( 10111100 )
, BOOST_BINARY( 10111101 )
, BOOST_BINARY( 10111110 )
, BOOST_BINARY( 10111111 )
, BOOST_BINARY( 11000000 )
, BOOST_BINARY( 11000001 )
, BOOST_BINARY( 11000010 )
, BOOST_BINARY( 11000011 )
, BOOST_BINARY( 11000100 )
, BOOST_BINARY( 11000101 )
, BOOST_BINARY( 11000110 )
, BOOST_BINARY( 11000111 )
, BOOST_BINARY( 11001000 )
, BOOST_BINARY( 11001001 )
, BOOST_BINARY( 11001010 )
, BOOST_BINARY( 11001011 )
, BOOST_BINARY( 11001100 )
, BOOST_BINARY( 11001101 )
, BOOST_BINARY( 11001110 )
, BOOST_BINARY( 11001111 )
, BOOST_BINARY( 11010000 )
, BOOST_BINARY( 11010001 )
, BOOST_BINARY( 11010010 )
, BOOST_BINARY( 11010011 )
, BOOST_BINARY( 11010100 )
, BOOST_BINARY( 11010101 )
, BOOST_BINARY( 11010110 )
, BOOST_BINARY( 11010111 )
, BOOST_BINARY( 11011000 )
, BOOST_BINARY( 11011001 )
, BOOST_BINARY( 11011010 )
, BOOST_BINARY( 11011011 )
, BOOST_BINARY( 11011100 )
, BOOST_BINARY( 11011101 )
, BOOST_BINARY( 11011110 )
, BOOST_BINARY( 11011111 )
, BOOST_BINARY( 11100000 )
, BOOST_BINARY( 11100001 )
, BOOST_BINARY( 11100010 )
, BOOST_BINARY( 11100011 )
, BOOST_BINARY( 11100100 )
, BOOST_BINARY( 11100101 )
, BOOST_BINARY( 11100110 )
, BOOST_BINARY( 11100111 )
, BOOST_BINARY( 11101000 )
, BOOST_BINARY( 11101001 )
, BOOST_BINARY( 11101010 )
, BOOST_BINARY( 11101011 )
, BOOST_BINARY( 11101100 )
, BOOST_BINARY( 11101101 )
, BOOST_BINARY( 11101110 )
, BOOST_BINARY( 11101111 )
, BOOST_BINARY( 11110000 )
, BOOST_BINARY( 11110001 )
, BOOST_BINARY( 11110010 )
, BOOST_BINARY( 11110011 )
, BOOST_BINARY( 11110100 )
, BOOST_BINARY( 11110101 )
, BOOST_BINARY( 11110110 )
, BOOST_BINARY( 11110111 )
, BOOST_BINARY( 11111000 )
, BOOST_BINARY( 11111001 )
, BOOST_BINARY( 11111010 )
, BOOST_BINARY( 11111011 )
, BOOST_BINARY( 11111100 )
, BOOST_BINARY( 11111101 )
, BOOST_BINARY( 11111110 )
, BOOST_BINARY( 11111111 )
};
struct left_is_not_one_less_than_right
{
bool operator ()( unsigned int left, unsigned int right ) const
{
return right != left + 1;
}
};
template< std::size_t Size >
bool is_ascending_from_0_array( unsigned int const (&array)[Size] )
{
unsigned int const* const curr = array,
* const end = array + Size;
return ( *curr == 0 )
&& ( std::adjacent_find( curr, end
, left_is_not_one_less_than_right()
)
== end
);
}
std::size_t const unsigned_int_id = 1,
unsigned_long_int_id = 2;
typedef char (&unsigned_int_id_type)[unsigned_int_id];
typedef char (&unsigned_long_int_id_type)[unsigned_long_int_id];
// Note: Functions only used for type checking
unsigned_int_id_type binary_type_checker( unsigned int );
unsigned_long_int_id_type binary_type_checker( unsigned long int );
int test_main( int, char *[] )
{
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_1_bit ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_2_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_3_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_4_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_5_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_6_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_7_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_8_bits ) );
BOOST_CHECK( std::equal( &random_unsigned_ints_hex[0]
, random_unsigned_ints_hex + num_random_test_values
, &random_unsigned_ints_binary[0]
)
);
BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) )
== unsigned_int_id
);
BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) )
== unsigned_long_int_id
);
BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) )
== unsigned_long_int_id
);
return 0;
}

View File

@ -1,489 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>C++ Type traits</title>
</head>
<body bgcolor="#FFFFFF" link="#0000FF" vlink="#800080">
<h2 align="center">C++ Type traits</h2>
<p align="center"><em>by John Maddock and Steve Cleary</em></p>
<p align="center"><em>This is a draft of an article that will appear in a future
issue of </em><a href="http://www.ddj.com"><em>Dr Dobb's Journal</em></a></p>
<p>Generic programming (writing code which works with any data type meeting a
set of requirements) has become the method of choice for providing reusable
code. However, there are times in generic programming when &quot;generic&quot;
just isn't good enough - sometimes the differences between types are too large
for an efficient generic implementation. This is when the traits technique
becomes important - by encapsulating those properties that need to be considered
on a type by type basis inside a traits class, we can minimise the amount of
code that has to differ from one type to another, and maximise the amount of
generic code.</p>
<p>Consider an example: when working with character strings, one common
operation is to determine the length of a null terminated string. Clearly it's
possible to write generic code that can do this, but it turns out that there are
much more efficient methods available: for example, the C library functions <font size="2" face="Courier New">strlen</font>
and <font size="2" face="Courier New">wcslen</font> are usually written in
assembler, and with suitable hardware support can be considerably faster than a
generic version written in C++. The authors of the C++ standard library realised
this, and abstracted the properties of <font size="2" face="Courier New">char</font>
and <font size="2" face="Courier New">wchar_t</font> into the class <font size="2" face="Courier New">char_traits</font>.
Generic code that works with character strings can simply use <font size="2" face="Courier New">char_traits&lt;&gt;::length</font>
to determine the length of a null terminated string, safe in the knowledge that
specialisations of <font size="2" face="Courier New">char_traits</font> will use
the most appropriate method available to them.</p>
<h4>Type traits</h4>
<p>Class <font size="2" face="Courier New">char_traits</font> is a classic
example of a collection of type specific properties wrapped up in a single class
- what Nathan Myers termed a <i>baggage class</i>[1]. In the Boost type-traits
library, we[2] have written a set of very specific traits classes, each of which
encapsulate a single trait from the C++ type system; for example, is a type a
pointer or a reference type? Or does a type have a trivial constructor, or a
const-qualifier? The type-traits classes share a unified design: each class has
a single member <i>value</i>, a compile-time constant that is true if the type
has the specified property, and false otherwise. As we will show, these classes
can be used in generic programming to determine the properties of a given type
and introduce optimisations that are appropriate for that case.</p>
<p>The type-traits library also contains a set of classes that perform a
specific transformation on a type; for example, they can remove a top-level
const or volatile qualifier from a type. Each class that performs a
transformation defines a single typedef-member <i>type</i> that is the result of
the transformation. All of the type-traits classes are defined inside namespace <font size="2" face="Courier New">boost</font>;
for brevity, namespace-qualification is omitted in most of the code samples
given.</p>
<h4>Implementation</h4>
<p>There are far too many separate classes contained in the type-traits library
to give a full implementation here - see the source code in the Boost library
for the full details - however, most of the implementation is fairly repetitive
anyway, so here we will just give you a flavour for how some of the classes are
implemented. Beginning with possibly the simplest class in the library, is_void&lt;T&gt;
has a member <i>value</i> that is true only if T is void.</p>
<pre>template &lt;typename T&gt;
struct is_void
{ static const bool value = false; };
template &lt;&gt;
struct is_void&lt;void&gt;
{ static const bool value = true; };</pre>
<p>Here we define a primary version of the template class <font size="2" face="Courier New">is_void</font>,
and provide a full-specialisation when T is void. While full specialisation of a
template class is an important technique, sometimes we need a solution that is
halfway between a fully generic solution, and a full specialisation. This is
exactly the situation for which the standards committee defined partial
template-class specialisation. As an example, consider the class
boost::is_pointer&lt;T&gt;: here we needed a primary version that handles all
the cases where T is not a pointer, and a partial specialisation to handle all
the cases where T is a pointer:</p>
<pre>template &lt;typename T&gt;
struct is_pointer
{ static const bool value = false; };
template &lt;typename T&gt;
struct is_pointer&lt;T*&gt;
{ static const bool value = true; };</pre>
<p>The syntax for partial specialisation is somewhat arcane and could easily
occupy an article in its own right; like full specialisation, in order to write
a partial specialisation for a class, you must first declare the primary
template. The partial specialisation contains an extra &lt;<EFBFBD>&gt; after the
class name that contains the partial specialisation parameters; these define the
types that will bind to that partial specialisation rather than the default
template. The rules for what can appear in a partial specialisation are somewhat
convoluted, but as a rule of thumb if you can legally write two function
overloads of the form:</p>
<pre>void foo(T);
void foo(U);</pre>
<p>Then you can also write a partial specialisation of the form:</p>
<pre>template &lt;typename T&gt;
class c{ /*details*/ };
template &lt;typename T&gt;
class c&lt;U&gt;{ /*details*/ };</pre>
<p>This rule is by no means foolproof, but it is reasonably simple to remember
and close enough to the actual rule to be useful for everyday use.</p>
<p>As a more complex example of partial specialisation consider the class
remove_bounds&lt;T&gt;. This class defines a single typedef-member <i>type</i>
that is the same type as T but with any top-level array bounds removed; this is
an example of a traits class that performs a transformation on a type:</p>
<pre>template &lt;typename T&gt;
struct remove_bounds
{ typedef T type; };
template &lt;typename T, std::size_t N&gt;
struct remove_bounds&lt;T[N]&gt;
{ typedef T type; };</pre>
<p>The aim of remove_bounds is this: imagine a generic algorithm that is passed
an array type as a template parameter, <font size="2" face="Courier New">remove_bounds</font>
provides a means of determining the underlying type of the array. For example <code>remove_bounds&lt;int[4][5]&gt;::type</code>
would evaluate to the type <code>int[5]</code>. This example also shows that the
number of template parameters in a partial specialisation does not have to match
the number in the default template. However, the number of parameters that
appear after the class name do have to match the number and type of the
parameters in the default template.</p>
<h4>Optimised copy</h4>
<p>As an example of how the type traits classes can be used, consider the
standard library algorithm copy:</p>
<pre>template&lt;typename Iter1, typename Iter2&gt;
Iter2 copy(Iter1 first, Iter1 last, Iter2 out);</pre>
<p>Obviously, there's no problem writing a generic version of copy that works
for all iterator types Iter1 and Iter2; however, there are some circumstances
when the copy operation can best be performed by a call to <font size="2" face="Courier New">memcpy</font>.
In order to implement copy in terms of <font size="2" face="Courier New">memcpy</font>
all of the following conditions need to be met:</p>
<ul>
<li>Both of the iterator types Iter1 and Iter2 must be pointers.</li>
<li>Both Iter1 and Iter2 must point to the same type - excluding <font size="2" face="Courier New">const</font>
and <font size="2" face="Courier New">volatile</font>-qualifiers.</li>
<li>The type pointed to by Iter1 must have a trivial assignment operator.</li>
</ul>
<p>By trivial assignment operator we mean that the type is either a scalar
type[3] or:</p>
<ul>
<li>The type has no user defined assignment operator.</li>
<li>The type does not have any data members that are references.</li>
<li>All base classes, and all data member objects must have trivial assignment
operators.</li>
</ul>
<p>If all these conditions are met then a type can be copied using <font size="2" face="Courier New">memcpy</font>
rather than using a compiler generated assignment operator. The type-traits
library provides a class <i>has_trivial_assign</i>, such that <code>has_trivial_assign&lt;T&gt;::value</code>
is true only if T has a trivial assignment operator. This class &quot;just
works&quot; for scalar types, but has to be explicitly specialised for
class/struct types that also happen to have a trivial assignment operator. In
other words if <i>has_trivial_assign</i> gives the wrong answer, it will give
the &quot;safe&quot; wrong answer - that trivial assignment is not allowable.</p>
<p>The code for an optimised version of copy that uses <font size="2" face="Courier New">memcpy</font>
where appropriate is given in listing 1. The code begins by defining a template
class <i>copier</i>, that takes a single Boolean template parameter, and has a
static template member function <font size="2" face="Courier New">do_copy</font>
which performs the generic version of <font size="2">copy</font> (in other words
the &quot;slow but safe version&quot;). Following that there is a specialisation
for <i>copier&lt;true&gt;</i>: again this defines a static template member
function <font size="2" face="Courier New">do_copy</font>, but this version uses
memcpy to perform an &quot;optimised&quot; copy.</p>
<p>In order to complete the implementation, what we need now is a version of
copy, that calls <code>copier&lt;true&gt;::do_copy</code> if it is safe to use <font size="2" face="Courier New">memcpy</font>,
and otherwise calls <code>copier&lt;false&gt;::do_copy</code> to do a
&quot;generic&quot; copy. This is what the version in listing 1 does. To
understand how the code works look at the code for <font size="2" face="Courier New">copy</font>
and consider first the two typedefs <i>v1_t</i> and <i>v2_t</i>. These use <code>std::iterator_traits&lt;Iter1&gt;::value_type</code>
to determine what type the two iterators point to, and then feed the result into
another type-traits class <i>remove_cv</i> that removes the top-level
const-volatile-qualifiers: this will allow copy to compare the two types without
regard to const- or volatile-qualifiers. Next, <font size="2" face="Courier New">copy</font>
declares an enumerated value <i>can_opt</i> that will become the template
parameter to copier - declaring this here as a constant is really just a
convenience - the value could be passed directly to class <font size="2" face="Courier New">copier</font>.
The value of <i>can_opt</i> is computed by verifying that all of the following
are true:</p>
<ul>
<li>first that the two iterators point to the same type by using a type-traits
class <i>is_same</i>.</li>
<li>Then that both iterators are real pointers - using the class <i>is_pointer</i>
described above.</li>
<li>Finally that the pointed-to types have a trivial assignment operator using
<i>has_trivial_assign</i>.</li>
</ul>
<p>Finally we can use the value of <i>can_opt</i> as the template argument to
copier - this version of copy will now adapt to whatever parameters are passed
to it, if its possible to use <font size="2" face="Courier New">memcpy</font>,
then it will do so, otherwise it will use a generic copy.</p>
<h4>Was it worth it?</h4>
<p>It has often been repeated in these columns that &quot;premature optimisation
is the root of all evil&quot; [4]. So the question must be asked: was our
optimisation premature? To put this in perspective the timings for our version
of copy compared a conventional generic copy[5] are shown in table 1.</p>
<p>Clearly the optimisation makes a difference in this case; but, to be fair,
the timings are loaded to exclude cache miss effects - without this accurate
comparison between algorithms becomes difficult. However, perhaps we can add a
couple of caveats to the premature optimisation rule:</p>
<ul>
<li>If you use the right algorithm for the job in the first place then
optimisation will not be required; in some cases, <font size="2" face="Courier New">memcpy</font>
is the right algorithm.</li>
<li>If a component is going to be reused in many places by many people then
optimisations may well be worthwhile where they would not be so for a single
case - in other words, the likelihood that the optimisation will be
absolutely necessary somewhere, sometime is that much higher. Just as
importantly the perceived value of the stock implementation will be higher:
there is no point standardising an algorithm if users reject it on the
grounds that there are better, more heavily optimised versions available.</li>
</ul>
<h4>Table 1: Time taken to copy 1000 elements using copy&lt;const T*, T*&gt;
(times in micro-seconds)</h4>
<table border="1" cellpadding="7" cellspacing="1" width="529">
<tr>
<td valign="top" width="33%">
<p align="center">Version</p>
</td>
<td valign="top" width="33%">
<p align="center">T</p>
</td>
<td valign="top" width="33%">
<p align="center">Time</p>
</td>
</tr>
<tr>
<td valign="top" width="33%">&quot;Optimised&quot; copy</td>
<td valign="top" width="33%">char</td>
<td valign="top" width="33%">0.99</td>
</tr>
<tr>
<td valign="top" width="33%">Conventional copy</td>
<td valign="top" width="33%">char</td>
<td valign="top" width="33%">8.07</td>
</tr>
<tr>
<td valign="top" width="33%">&quot;Optimised&quot; copy</td>
<td valign="top" width="33%">int</td>
<td valign="top" width="33%">2.52</td>
</tr>
<tr>
<td valign="top" width="33%">Conventional copy</td>
<td valign="top" width="33%">int</td>
<td valign="top" width="33%">8.02</td>
</tr>
</table>
<p>&nbsp;</p>
<h4>Pair of References</h4>
<p>The optimised copy example shows how type traits may be used to perform
optimisation decisions at compile-time. Another important usage of type traits
is to allow code to compile that otherwise would not do so unless excessive
partial specialization is used. This is possible by delegating partial
specialization to the type traits classes. Our example for this form of usage is
a pair that can hold references [6].</p>
<p>First, let us examine the definition of &quot;std::pair&quot;, omitting the
comparision operators, default constructor, and template copy constructor for
simplicity:</p>
<pre>template &lt;typename T1, typename T2&gt;
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair(const T1 &amp; nfirst, const T2 &amp; nsecond)
:first(nfirst), second(nsecond) { }
};</pre>
<p>Now, this &quot;pair&quot; cannot hold references as it currently stands,
because the constructor would require taking a reference to a reference, which
is currently illegal [7]. Let us consider what the constructor's parameters
would have to be in order to allow &quot;pair&quot; to hold non-reference types,
references, and constant references:</p>
<table border="1" cellpadding="7" cellspacing="1" width="638">
<tr>
<td valign="top" width="50%">Type of &quot;T1&quot;</td>
<td valign="top" width="50%">Type of parameter to initializing constructor</td>
</tr>
<tr>
<td valign="top" width="50%">
<pre>T</pre>
</td>
<td valign="top" width="50%">
<pre>const T &amp;</pre>
</td>
</tr>
<tr>
<td valign="top" width="50%">
<pre>T &amp;</pre>
</td>
<td valign="top" width="50%">
<pre>T &amp;</pre>
</td>
</tr>
<tr>
<td valign="top" width="50%">
<pre>const T &amp;</pre>
</td>
<td valign="top" width="50%">
<pre>const T &amp;</pre>
</td>
</tr>
</table>
<p>A little familiarity with the type traits classes allows us to construct a
single mapping that allows us to determine the type of parameter from the type
of the contained class. The type traits classes provide a transformation &quot;add_reference&quot;,
which adds a reference to its type, unless it is already a reference.</p>
<table border="1" cellpadding="7" cellspacing="1" width="580">
<tr>
<td valign="top" width="21%">Type of &quot;T1&quot;</td>
<td valign="top" width="27%">Type of &quot;const T1&quot;</td>
<td valign="top" width="53%">Type of &quot;add_reference&lt;const
T1&gt;::type&quot;</td>
</tr>
<tr>
<td valign="top" width="21%">
<pre>T</pre>
</td>
<td valign="top" width="27%">
<pre>const T</pre>
</td>
<td valign="top" width="53%">
<pre>const T &amp;</pre>
</td>
</tr>
<tr>
<td valign="top" width="21%">
<pre>T &amp;</pre>
</td>
<td valign="top" width="27%">
<pre>T &amp; [8]</pre>
</td>
<td valign="top" width="53%">
<pre>T &amp;</pre>
</td>
</tr>
<tr>
<td valign="top" width="21%">
<pre>const T &amp;</pre>
</td>
<td valign="top" width="27%">
<pre>const T &amp;</pre>
</td>
<td valign="top" width="53%">
<pre>const T &amp;</pre>
</td>
</tr>
</table>
<p>This allows us to build a primary template definition for &quot;pair&quot;
that can contain non-reference types, reference types, and constant reference
types:</p>
<pre>template &lt;typename T1, typename T2&gt;
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair(boost::add_reference&lt;const T1&gt;::type nfirst,
boost::add_reference&lt;const T2&gt;::type nsecond)
:first(nfirst), second(nsecond) { }
};</pre>
<p>Add back in the standard comparision operators, default constructor, and
template copy constructor (which are all the same), and you have a std::pair
that can hold reference types!</p>
<p>This same extension <i>could</i> have been done using partial template
specialization of &quot;pair&quot;, but to specialize &quot;pair&quot; in this
way would require three partial specializations, plus the primary template. Type
traits allows us to define a single primary template that adjusts itself
auto-magically to any of these partial specializations, instead of a brute-force
partial specialization approach. Using type traits in this fashion allows
programmers to delegate partial specialization to the type traits classes,
resulting in code that is easier to maintain and easier to understand.</p>
<h4>Conclusion</h4>
<p>We hope that in this article we have been able to give you some idea of what
type-traits are all about. A more complete listing of the available classes are
in the boost documentation, along with further examples using type traits.
Templates have enabled C++ uses to take the advantage of the code reuse that
generic programming brings; hopefully this article has shown that generic
programming does not have to sink to the lowest common denominator, and that
templates can be optimal as well as generic.</p>
<h4>Acknowledgements</h4>
<p>The authors would like to thank Beman Dawes and Howard Hinnant for their
helpful comments when preparing this article.</p>
<h4>References</h4>
<ol>
<li>Nathan C. Myers, C++ Report, June 1995.</li>
<li>The type traits library is based upon contributions by Steve Cleary, Beman
Dawes, Howard Hinnant and John Maddock: it can be found at www.boost.org.</li>
<li>A scalar type is an arithmetic type (i.e. a built-in integer or floating
point type), an enumeration type, a pointer, a pointer to member, or a
const- or volatile-qualified version of one of these types.</li>
<li>This quote is from Donald Knuth, ACM Computing Surveys, December 1974, pg
268.</li>
<li>The test code is available as part of the boost utility library (see
algo_opt_examples.cpp), the code was compiled with gcc 2.95 with all
optimisations turned on, tests were conducted on a 400MHz Pentium II machine
running Microsoft Windows 98.</li>
<li>John Maddock and Howard Hinnant have submitted a &quot;compressed_pair&quot;
library to Boost, which uses a technique similar to the one described here
to hold references. Their pair also uses type traits to determine if any of
the types are empty, and will derive instead of contain to conserve space --
hence the name &quot;compressed&quot;.</li>
<li>This is actually an issue with the C++ Core Language Working Group (issue
#106), submitted by Bjarne Stroustrup. The tentative resolution is to allow
a &quot;reference to a reference to T&quot; to mean the same thing as a
&quot;reference to T&quot;, but only in template instantiation, in a method
similar to multiple cv-qualifiers.</li>
<li>For those of you who are wondering why this shouldn't be const-qualified,
remember that references are always implicitly constant (for example, you
can't re-assign a reference). Remember also that &quot;const T &amp;&quot;
is something completely different. For this reason, cv-qualifiers on
template type arguments that are references are ignored.</li>
</ol>
<h2>Listing 1</h2>
<pre>namespace detail{
template &lt;bool b&gt;
struct copier
{
template&lt;typename I1, typename I2&gt;
static I2 do_copy(I1 first,
I1 last, I2 out);
};
template &lt;bool b&gt;
template&lt;typename I1, typename I2&gt;
I2 copier&lt;b&gt;::do_copy(I1 first,
I1 last,
I2 out)
{
while(first != last)
{
*out = *first;
++out;
++first;
}
return out;
}
template &lt;&gt;
struct copier&lt;true&gt;
{
template&lt;typename I1, typename I2&gt;
static I2* do_copy(I1* first, I1* last, I2* out)
{
memcpy(out, first, (last-first)*sizeof(I2));
return out+(last-first);
}
};
}
template&lt;typename I1, typename I2&gt;
inline I2 copy(I1 first, I1 last, I2 out)
{
typedef typename
boost::remove_cv&lt;
typename std::iterator_traits&lt;I1&gt;
::value_type&gt;::type v1_t;
typedef typename
boost::remove_cv&lt;
typename std::iterator_traits&lt;I2&gt;
::value_type&gt;::type v2_t;
enum{ can_opt =
boost::is_same&lt;v1_t, v2_t&gt;::value
&amp;&amp; boost::is_pointer&lt;I1&gt;::value
&amp;&amp; boost::is_pointer&lt;I2&gt;::value
&amp;&amp; boost::
has_trivial_assign&lt;v1_t&gt;::value
};
return detail::copier&lt;can_opt&gt;::
do_copy(first, last, out);
}</pre>
<hr>
<p><EFBFBD> Copyright John Maddock and Steve Cleary, 2000</p>
</body>
</html>

View File

@ -12,7 +12,7 @@ content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
vlink="#800080">
<h1><img src="../../c++boost.gif" width="276" height="86">Header
<h1><img src="../../boost.png" width="276" height="86">Header
&lt;<a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a>&gt;</h1>
<p>All of the contents of &lt;boost/call_traits.hpp&gt; are
@ -27,10 +27,16 @@ never occur, and that parameters are passed in the most efficient
manner possible (see <a href="#examples">examples</a>). In each
case if your existing practice is to use the type defined on the
left, then replace it with the call_traits defined type on the
right. Note that for compilers that do not support partial
specialization, no benefit will occur from using call_traits: the
call_traits defined types will always be the same as the existing
practice in this case.</p>
right. </p>
<p>Note that for compilers that do not support either partial
specialization or member templates, no benefit will occur from
using call_traits: the call_traits defined types will always be
the same as the existing practice in this case. In addition if
only member templates and not partial template specialisation is
support by the compiler (for example Visual C++ 6) then
call_traits can not be used with array types (although it can be
used to solve the reference to reference problem).</p>
<table border="0" cellpadding="7" cellspacing="1" width="797">
<tr>
@ -73,7 +79,8 @@ practice in this case.</p>
</td>
</tr>
<tr>
<td valign="top" width="17%"><p align="center">const T&amp;<br>
<td valign="top" width="17%"><p align="center">const
T&amp;<br>
(return value)</p>
</td>
<td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::const_reference</code></p>
@ -85,7 +92,8 @@ practice in this case.</p>
</td>
</tr>
<tr>
<td valign="top" width="17%"><p align="center">const T&amp;<br>
<td valign="top" width="17%"><p align="center">const
T&amp;<br>
(function parameter)</p>
</td>
<td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::param_type</code></p>
@ -326,8 +334,8 @@ possible:</p>
<p>The following table shows the effect that call_traits has on
various types, the table assumes that the compiler supports
partial specialization: if it doesn't then all types behave in
the same way as the entry for &quot;myclass&quot;, and call_traits
can not be used with reference or array types.</p>
the same way as the entry for &quot;myclass&quot;, and
call_traits can not be used with reference or array types.</p>
<table border="0" cellpadding="7" cellspacing="1" width="766">
<tr>
@ -382,7 +390,8 @@ can not be used with reference or array types.</p>
</td>
<td valign="top" width="17%"><p align="center">int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">int const</p>
</td>
@ -414,7 +423,8 @@ can not be used with reference or array types.</p>
</td>
<td valign="top" width="17%"><p align="center">int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">int&amp;</p>
</td>
@ -426,13 +436,17 @@ can not be used with reference or array types.</p>
<td valign="top" width="17%" bgcolor="#C0C0C0"><p
align="center">const int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">const int&amp;</p>
<td valign="top" width="17%"><p align="center">const
int&amp;</p>
</td>
<td valign="top" width="17%"><p align="center">All
constant-references.</p>
@ -480,8 +494,8 @@ can not be used with reference or array types.</p>
<p>The following class is a trivial class that stores some type T
by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a>
file), the aim is to illustrate how each of the available call_traits
typedefs may be used:</p>
file), the aim is to illustrate how each of the available
call_traits typedefs may be used:</p>
<pre>template &lt;class T&gt;
struct contained
@ -517,14 +531,14 @@ problem):</h4>
<pre>template &lt;class Operation&gt;
class binder1st :
public unary_function&lt;Operation::second_argument_type, Operation::result_type&gt;
public unary_function&lt;typename Operation::second_argument_type, typename Operation::result_type&gt;
{
protected:
Operation op;
Operation::first_argument_type value;
typename Operation::first_argument_type value;
public:
binder1st(const Operation&amp; x, const Operation::first_argument_type&amp; y);
Operation::result_type operator()(const Operation::second_argument_type&amp; x) const;
binder1st(const Operation&amp; x, const typename Operation::first_argument_type&amp; y);
typename Operation::result_type operator()(const typename Operation::second_argument_type&amp; x) const;
}; </pre>
<p>Now consider what happens in the relatively common case that
@ -535,7 +549,7 @@ reference to a reference as an argument, and that is not
currently legal. The solution here is to modify <code>operator()</code>
to use call_traits:</p>
<pre>Operation::result_type operator()(call_traits&lt;Operation::second_argument_type&gt;::param_type x) const;</pre>
<pre>typename Operation::result_type operator()(typename call_traits&lt;typename Operation::second_argument_type&gt;::param_type x) const;</pre>
<p>Now in the case that <code>Operation::second_argument_type</code>
is a reference type, the argument is passed as a reference, and
@ -569,14 +583,17 @@ std::pair&lt;
degraded to pointers if the deduced types are arrays, similar
situations occur in the standard binders and adapters: in
principle in any function that &quot;wraps&quot; a temporary
whose type is deduced.</p>
whose type is deduced. Note that the function arguments to
make_pair are not expressed in terms of call_traits: doing so
would prevent template argument deduction from functioning.</p>
<h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
<p>The call_traits template will &quot;optimize&quot; the passing
of a small built-in type as a function parameter, this mainly has
an effect when the parameter is used within a loop body. In the
following example (see <a href="algo_opt_examples.cpp">algo_opt_examples.cpp</a>),
following example (see <a
href="../type_traits/examples/fill_example.cpp">fill_example.cpp</a>),
a version of std::fill is optimized in two ways: if the type
passed is a single byte built-in type then std::memset is used to
effect the fill, otherwise a conventional C++ implemention is
@ -589,7 +606,7 @@ template &lt;bool opt&gt;
struct filler
{
template &lt;typename I, typename T&gt;
static void do_fill(I first, I last, typename boost::call_traits&lt;T&gt;::param_type val);
static void do_fill(I first, I last, typename boost::call_traits&lt;T&gt;::param_type val)
{
while(first != last)
{
@ -632,6 +649,14 @@ Exactly how much mileage you will get from this depends upon your
compiler - we could really use some accurate benchmarking
software as part of boost for cases like this.</p>
<p>Note that the function arguments to fill are not expressed in
terms of call_traits: doing so would prevent template argument
deduction from functioning. Instead fill acts as a &quot;thin
wrapper&quot; that is there to perform template argument
deduction, the compiler will optimise away the call to fill all
together, replacing it with the call to filler&lt;&gt;::do_fill,
which does use call_traits.</p>
<h3>Rationale</h3>
<p>The following notes are intended to briefly describe the
@ -650,10 +675,10 @@ be any worse than existing practice.</p>
<p>Pointers follow the same rational as small built-in types.</p>
<p>For reference types the rational follows <a href="#refs">Example
2</a> - references to references are not allowed, so the call_traits
members must be defined such that these problems do not occur.
There is a proposal to modify the language such that &quot;a
reference to a reference is a reference&quot; (issue #106,
2</a> - references to references are not allowed, so the
call_traits members must be defined such that these problems do
not occur. There is a proposal to modify the language such that
&quot;a reference to a reference is a reference&quot; (issue #106,
submitted by Bjarne Stroustrup), call_traits&lt;T&gt;::value_type
and call_traits&lt;T&gt;::param_type both provide the same effect
as that proposal, without the need for a language change (in
@ -671,11 +696,11 @@ struct A
void foo(T t);
};</pre>
<p><font face="Times New Roman">In this case if we instantiate A&lt;int[2]&gt;
then the declared type of the parameter passed to member function
foo is int[2], but it's actual type is const int*, if we try to
use the type T within the function body, then there is a strong
likelyhood that our code will not compile:</font></p>
<p><font face="Times New Roman">In this case if we instantiate
A&lt;int[2]&gt; then the declared type of the parameter passed to
member function foo is int[2], but it's actual type is const int*,
if we try to use the type T within the function body, then there
is a strong likelyhood that our code will not compile:</font></p>
<pre>template &lt;class T&gt;
void A&lt;T&gt;::foo(T t)
@ -690,13 +715,13 @@ declared type:</p>
<pre>template &lt;class T&gt;
struct A
{
void foo(call_traits&lt;T&gt;::value_type t);
void foo(typename call_traits&lt;T&gt;::value_type t);
};
template &lt;class T&gt;
void A&lt;T&gt;::foo(call_traits&lt;T&gt;::value_type t)
void A&lt;T&gt;::foo(typename call_traits&lt;T&gt;::value_type t)
{
call_traits&lt;T&gt;::value_type dup(t); // OK even if T is an array type.
typename call_traits&lt;T&gt;::value_type dup(t); // OK even if T is an array type.
}</pre>
<p>For value_type (return by value), again only a pointer may be
@ -713,26 +738,18 @@ specialisation).</p>
<hr>
<p>Revised 18 June 2000</p>
<p>Revised 01 September 2000</p>
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this
copyright notice appears in all copies. This document is provided
&quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose.</p>
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
Hinnant and John Maddock.</p>
<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John
Maddock</a>, the latest version of this file can be found at <a
href="http://www.boost.org/">www.boost.org</a>, and the boost
discussion list at <a href="http://www.egroups.com/list/boost">www.egroups.com/list/boost</a>.</p>
<p>.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>
Copyright 2000 Steve Cleary, Beman Dawes, Howard
Hinnant and John Maddock. <br/>
Use, modification and distribution are subject to the
Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt
or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
http://www.boost.org/LICENSE_1_0.txt
</a>).
</p>
</body>
</html>

View File

@ -1,20 +1,33 @@
// boost::compressed_pair test program
// boost::compressed_pair test program
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// (C) Copyright John Maddock 2000.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
// standalone test program for <boost/call_traits.hpp>
// 18 Mar 2002:
// Changed some names to prevent conflicts with some new type_traits additions.
// 03 Oct 2000:
// Enabled extra tests for VC6.
#include <cassert>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <typeinfo>
#include <boost/call_traits.hpp>
#include "type_traits_test.hpp"
#include <libs/type_traits/test/test.hpp>
#include <libs/type_traits/test/check_type.hpp>
#ifdef BOOST_MSVC
#pragma warning(disable:4181) // : warning C4181: qualifier applied to reference type; ignored
#endif
// a way prevent warnings for unused variables
template<class T> inline void unused_variable(const T&) {}
//
// struct contained models a type that contains a type (for example std::pair)
// arrays are contained by value, and have to be treated as a special case:
@ -42,8 +55,9 @@ struct contained
reference get() { return v_; }
const_reference const_get()const { return v_; }
// pass value:
void call(param_type p){}
void call(param_type){}
private:
contained& operator=(const contained&);
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
@ -67,12 +81,14 @@ struct contained<T[N]>
// return by_ref:
reference get() { return v_; }
const_reference const_get()const { return v_; }
void call(param_type p){}
void call(param_type){}
private:
contained& operator=(const contained&);
};
#endif
template <class T>
contained<typename boost::call_traits<T>::value_type> wrap(const T& t)
contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t)
{
typedef typename boost::call_traits<T>::value_type ct;
return contained<ct>(t);
@ -96,37 +112,38 @@ std::pair<
using namespace std;
//
// struct checker:
// struct call_traits_checker:
// verifies behaviour of contained example:
//
template <class T>
struct checker
struct call_traits_checker
{
typedef typename boost::call_traits<T>::param_type param_type;
void operator()(param_type);
};
template <class T>
void checker<T>::operator()(param_type p)
void call_traits_checker<T>::operator()(param_type p)
{
T t(p);
contained<T> c(t);
cout << "checking contained<" << typeid(T).name() << ">..." << endl;
assert(t == c.value());
assert(t == c.get());
assert(t == c.const_get());
cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl;
BOOST_CHECK(t == c.value());
BOOST_CHECK(t == c.get());
BOOST_CHECK(t == c.const_get());
#ifndef __ICL
//cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl;
cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained<T>::value).name() << endl;
cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained<T>::get).name() << endl;
cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained<T>::const_get).name() << endl;
cout << "typeof contained<" << typeid(T).name() << ">::call() is: " << typeid(&contained<T>::call).name() << endl;
cout << endl;
#endif
}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, std::size_t N>
struct checker<T[N]>
struct call_traits_checker<T[N]>
{
typedef typename boost::call_traits<T[N]>::param_type param_type;
void operator()(param_type t)
@ -135,11 +152,11 @@ struct checker<T[N]>
cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl;
unsigned int i = 0;
for(i = 0; i < N; ++i)
assert(t[i] == c.value()[i]);
BOOST_CHECK(t[i] == c.value()[i]);
for(i = 0; i < N; ++i)
assert(t[i] == c.get()[i]);
BOOST_CHECK(t[i] == c.get()[i]);
for(i = 0; i < N; ++i)
assert(t[i] == c.const_get()[i]);
BOOST_CHECK(t[i] == c.const_get()[i]);
cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained<T[N]>::v_).name() << endl;
cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained<T[N]>::value).name() << endl;
@ -153,11 +170,11 @@ struct checker<T[N]>
//
// check_wrap:
template <class T, class U>
void check_wrap(const contained<T>& w, const U& u)
template <class W, class U>
void check_wrap(const W& w, const U& u)
{
cout << "checking contained<" << typeid(T).name() << ">..." << endl;
assert(w.value() == u);
cout << "checking " << typeid(W).name() << "..." << endl;
BOOST_CHECK(w.value() == u);
}
//
@ -168,47 +185,53 @@ template <class T, class U, class V>
void check_make_pair(T c, U u, V v)
{
cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl;
assert(c.first == u);
assert(c.second == v);
BOOST_CHECK(c.first == u);
BOOST_CHECK(c.second == v);
cout << endl;
}
struct UDT
struct comparible_UDT
{
int i_;
UDT() : i_(2){}
bool operator == (const UDT& v){ return v.i_ == i_; }
comparible_UDT() : i_(2){}
comparible_UDT(const comparible_UDT& other) : i_(other.i_){}
comparible_UDT& operator=(const comparible_UDT& other)
{
i_ = other.i_;
return *this;
}
bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
};
int main()
{
checker<UDT> c1;
UDT u;
call_traits_checker<comparible_UDT> c1;
comparible_UDT u;
c1(u);
checker<int> c2;
call_traits_checker<int> c2;
call_traits_checker<enum_UDT> c2b;
int i = 2;
c2(i);
c2b(one);
int* pi = &i;
checker<int*> c3;
c3(pi);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
checker<int&> c4;
c4(i);
checker<const int&> c5;
c5(i);
int a[2] = {1,2};
checker<int[2]> c6;
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
call_traits_checker<int*> c3;
c3(pi);
call_traits_checker<int&> c4;
c4(i);
call_traits_checker<const int&> c5;
c5(i);
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC)
call_traits_checker<int[2]> c6;
c6(a);
#endif
#endif
check_wrap(wrap(2), 2);
const char ca[4] = "abc";
// compiler can't deduce this for some reason:
//check_wrap(wrap(ca), ca);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
check_wrap(wrap(a), a);
check_wrap(test_wrap_type(2), 2);
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
check_wrap(test_wrap_type(a), a);
check_make_pair(test::make_pair(a, a), a, a);
#endif
@ -217,59 +240,71 @@ int main()
typedef int& r_type;
typedef const r_type cr_type;
type_test(UDT, boost::call_traits<UDT>::value_type)
type_test(UDT&, boost::call_traits<UDT>::reference)
type_test(const UDT&, boost::call_traits<UDT>::const_reference)
type_test(const UDT&, boost::call_traits<UDT>::param_type)
type_test(int, boost::call_traits<int>::value_type)
type_test(int&, boost::call_traits<int>::reference)
type_test(const int&, boost::call_traits<int>::const_reference)
type_test(const int, boost::call_traits<int>::param_type)
type_test(int*, boost::call_traits<int*>::value_type)
type_test(int*&, boost::call_traits<int*>::reference)
type_test(int*const&, boost::call_traits<int*>::const_reference)
type_test(int*const, boost::call_traits<int*>::param_type)
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
type_test(int&, boost::call_traits<int&>::value_type)
type_test(int&, boost::call_traits<int&>::reference)
type_test(const int&, boost::call_traits<int&>::const_reference)
type_test(int&, boost::call_traits<int&>::param_type)
#if !(defined(__GNUC__) && (__GNUC__ < 3))
type_test(int&, boost::call_traits<cr_type>::value_type)
type_test(int&, boost::call_traits<cr_type>::reference)
type_test(const int&, boost::call_traits<cr_type>::const_reference)
type_test(int&, boost::call_traits<cr_type>::param_type)
BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type);
BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference);
BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference);
BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type);
BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type);
BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference);
BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference);
BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type);
BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type);
BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference);
BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference);
BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type);
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type);
BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference);
BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference);
BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type);
#if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)))
BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type);
BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference);
BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference);
BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type);
#else
std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl;
failures += 4;
test_count += 4;
#endif
type_test(const int&, boost::call_traits<const int&>::value_type)
type_test(const int&, boost::call_traits<const int&>::reference)
type_test(const int&, boost::call_traits<const int&>::const_reference)
type_test(const int&, boost::call_traits<const int&>::param_type)
type_test(const int*, boost::call_traits<int[3]>::value_type)
type_test(int(&)[3], boost::call_traits<int[3]>::reference)
type_test(const int(&)[3], boost::call_traits<int[3]>::const_reference)
type_test(const int*const, boost::call_traits<int[3]>::param_type)
type_test(const int*, boost::call_traits<const int[3]>::value_type)
type_test(const int(&)[3], boost::call_traits<const int[3]>::reference)
type_test(const int(&)[3], boost::call_traits<const int[3]>::const_reference)
type_test(const int*const, boost::call_traits<const int[3]>::param_type)
BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type);
BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference);
BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference);
BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type);
BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference);
BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference);
BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type);
BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type);
BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference);
BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference);
BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type);
// test with abstract base class:
BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type);
BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference);
BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference);
BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type);
#else
std::cout << "You're compiler does not support partial template instantiation, skipping 20 tests (20 errors)" << std::endl;
failures += 20;
test_count += 20;
std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl;
#endif
std::cout << std::endl << test_count << " tests completed (" << failures << " failures)... press any key to exit";
std::cin.get();
return failures;
#else
std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl;
#endif
// test with an incomplete type:
BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type);
BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference);
BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference);
BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type);
// test enum:
BOOST_CHECK_TYPE(enum_UDT, boost::call_traits<enum_UDT>::value_type);
BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits<enum_UDT>::reference);
BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits<enum_UDT>::const_reference);
BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits<enum_UDT>::param_type);
return 0;
}
//
// define call_traits tests to check that the assertions in the docs do actually work
// this is an instantiate only set of tests:
// this is an compile-time only set of tests:
//
template <typename T, bool isarray = false>
struct call_traits_test
@ -304,6 +339,19 @@ void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T,
param_type p2(v);
param_type p3(r);
param_type p4(p);
unused_variable(v2);
unused_variable(v3);
unused_variable(v4);
unused_variable(r2);
unused_variable(r3);
unused_variable(cr2);
unused_variable(cr3);
unused_variable(cr4);
unused_variable(cr5);
unused_variable(p2);
unused_variable(p3);
unused_variable(p4);
}
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <typename T>
@ -318,7 +366,7 @@ struct call_traits_test<T, true>
};
template <typename T>
void call_traits_test<T, true>::assert_construct(boost::call_traits<T>::param_type val)
void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val)
{
//
// this is to check that the call_traits assertions are valid:
@ -340,6 +388,19 @@ void call_traits_test<T, true>::assert_construct(boost::call_traits<T>::param_ty
param_type p2(v);
param_type p3(r);
param_type p4(p);
unused_variable(v2);
unused_variable(v3);
unused_variable(v4);
unused_variable(v5);
#ifndef __BORLANDC__
unused_variable(r2);
unused_variable(cr2);
#endif
unused_variable(cr3);
unused_variable(p2);
unused_variable(p3);
unused_variable(p4);
}
#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//
@ -347,9 +408,11 @@ void call_traits_test<T, true>::assert_construct(boost::call_traits<T>::param_ty
template struct call_traits_test<int>;
template struct call_traits_test<const int>;
template struct call_traits_test<int*>;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template struct call_traits_test<int&>;
template struct call_traits_test<const int&>;
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
template struct call_traits_test<int[2], true>;
#endif
#endif

148
cast.htm
View File

@ -1,148 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Header boost/cast.hpp Documentation</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" width="277" height="86">Header
<a href="../../boost/cast.hpp">boost/cast.hpp</a></h1>
<h2><a name="Cast Functions">Cast Functions</a></h2>
<p>The <code>header <a href="../../boost/cast.hpp">boost/cast.hpp</a></code>
provides <a href="#Polymorphic_cast"><b>polymorphic_cast</b></a>, <a href="#Polymorphic_cast"><b>polymorphic_downcast</b></a>,
and <a href="#numeric_cast"><b>numeric_cast</b></a> template functions designed
to complement the C++ Standard's built-in casts.</p>
<p>The program&nbsp;<a href="cast_test.cpp">cast_test.cpp</a> can be used to
verify these function templates work as expected.</p>
<p><b>polymorphic_cast</b> was suggested by Bjarne Stroustrup in &quot;The C++
Programming Language&quot;.<br>
<b>polymorphic_downcast</b> was contributed by <a href="../../people/dave_abrahams.htm">Dave
Abrahams</a>.<b><br>
numeric_cast</b> was contributed by <a href="../../people/kevlin_henney.htm">Kevlin
Henney</a>.</p>
<h3>Namespace synopsis</h3>
<blockquote>
<pre>namespace boost {
namespace cast {
// all synopsis below included here
}
using ::boost::cast::polymorphic_cast;
using ::boost::cast::polymorphic_downcast;
using ::boost::cast::bad_numeric_cast;
using ::boost::cast::numeric_cast;
}</pre>
</blockquote>
<h3><a name="Polymorphic_cast">Polymorphic casts</a></h3>
<p>Pointers to polymorphic objects (objects of classes which define at least one
virtual function) are sometimes downcast or crosscast.&nbsp; Downcasting means
casting from a base class to a derived class.&nbsp; Crosscasting means casting
across an inheritance hierarchy diagram, such as from one base to the other in a
<b>Y</b> diagram hierarchy.</p>
<p>Such casts can be done with old-style casts, but this approach is never to be
recommended.&nbsp; Old-style casts are sorely lacking in type safety, suffer
poor readability, and are difficult to locate with search tools.</p>
<p>The C++ built-in <b>static_cast</b> can be used for efficiently downcasting
pointers to polymorphic objects, but provides no error detection for the case
where the pointer being cast actually points to the wrong derived class. The <b>polymorphic_downcast</b>
template retains the efficiency of <b>static_cast</b> for non-debug
compilations, but for debug compilations adds safety via an assert() that a <b>dynamic_cast</b>
succeeds.&nbsp;<b>&nbsp;</b></p>
<p>The C++ built-in <b>dynamic_cast</b> can be used for downcasts and crosscasts
of pointers to polymorphic objects, but error notification in the form of a
returned value of 0 is inconvenient to test, or worse yet, easy to forget to
test.&nbsp; The <b>polymorphic_cast</b> template performs a <b>dynamic_cast</b>,
and throws an exception if the <b>dynamic_cast</b> returns 0.</p>
<p>A <b>polymorphic_downcast</b> is preferred when debug-mode tests will cover
100% of the object types possibly cast and when non-debug-mode efficiency is an
issue. If these two conditions are not present, <b>polymorphic_cast</b> is
preferred.&nbsp; It must also be used for crosscasts.&nbsp; It does an assert(
dynamic_cast&lt;Derived&gt;(x) == x ) where x is the base pointer, ensuring that
not only is a non-zero pointer returned, but also that it correct in the
presence of multiple inheritance. .<b> Warning:</b>: Because <b>polymorphic_downcast</b>
uses assert(), it violates the One Definition Rule if NDEBUG is inconsistently
defined across translation units.</p>
<p>The C++ built-in <b>dynamic_cast</b> must be used to cast references rather
than pointers.&nbsp; It is also the only cast that can be used to check whether
a given interface is supported; in that case a return of 0 isn't an error
condition.</p>
<h3>polymorphic_cast and polymorphic_downcast synopsis</h3>
<blockquote>
<pre>template &lt;class Derived, class Base&gt;
inline Derived polymorphic_cast(Base* x);
// Throws: std::bad_cast if ( dynamic_cast&lt;Derived&gt;(x) == 0 )
// Returns: dynamic_cast&lt;Derived&gt;(x)
template &lt;class Derived, class Base&gt;
inline Derived polymorphic_downcast(Base* x);
// Effects: assert( dynamic_cast&lt;Derived&gt;(x) == x );
// Returns: static_cast&lt;Derived&gt;(x)</pre>
</blockquote>
<h3>polymorphic_downcast example</h3>
<blockquote>
<pre>#include &lt;boost/cast.hpp&gt;
...
class Fruit { public: virtual ~Fruit(){}; ... };
class Banana : public Fruit { ... };
...
void f( Fruit * fruit ) {
// ... logic which leads us to believe it is a Banana
Banana * banana = boost::polymorphic_downcast&lt;Banana*&gt;(fruit);
...</pre>
</blockquote>
<h3><a name="numeric_cast">numeric_cast</a></h3>
<p>A <b>static_cast</b>, <b>implicit_cast</b> or implicit conversion will not
detect failure to preserve range for numeric casts. The <b>numeric_cast</b>
template function are similar to <b>static_cast</b> and certain (dubious)
implicit conversions in this respect, except that they detect loss of numeric
range. An exception is thrown when a runtime value preservation check fails.</p>
<p>The requirements on the argument and result types are:</p>
<blockquote>
<ul>
<li>Both argument and result types are CopyConstructible [20.1.3].</li>
<li>Both argument and result types are Numeric, defined by <code>std::numeric_limits&lt;&gt;::is_specialized</code>
being true.</li>
<li>The argument can be converted to the result type using <b>static_cast</b>.</li>
</ul>
</blockquote>
<h3>numeric_cast synopsis</h3>
<blockquote>
<pre>class bad_numeric_cast : public std::bad_cast {...};
template&lt;typename Target, typename Source&gt;
inline Target numeric_cast(Source arg);
// Throws: bad_numeric_cast unless, in converting arg from Source to Target,
// there is no loss of negative range, and no underflow, and no
// overflow, as determined by std::numeric_limits
// Returns: static_cast&lt;Target&gt;(arg)</pre>
</blockquote>
<h3>numeric_cast example</h3>
<blockquote>
<pre>#include &lt;boost/cast.hpp&gt;
using namespace boost::cast;
void ariane(double vx)
{
...
unsigned short dx = numeric_cast&lt;unsigned short&gt;(vx);
...
}</pre>
</blockquote>
<h3>numeric_cast rationale</h3>
<p>The form of the throws condition is specified so that != is not a required
operation.</p>
<hr>
<p>Revised&nbsp; <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan
-->28 June, 2000<!--webbot bot="Timestamp" endspan i-checksum="19846"
--></p>
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
distribute this document is granted provided this copyright notice appears in
all copies. This document is provided &quot;as is&quot; without express or
implied warranty, and with no claim as to its suitability for any purpose.</p>
</body>
</html>

View File

@ -1,149 +0,0 @@
// boost utility cast test program -----------------------------------------//
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
// and distribute this software is granted provided this copyright
// notice appears in all copies. This software is provided "as is" without
// express or implied warranty, and with no claim as to its suitability for
// any purpose.
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 28 Jun 00 implicit_cast removed (Beman Dawes)
// 30 Aug 99 value_cast replaced by numeric_cast
// 3 Aug 99 Initial Version
#include <iostream>
#include <climits>
#include <limits>
#include <boost/cast.hpp>
# if SCHAR_MAX == LONG_MAX
# error "This test program doesn't work if SCHAR_MAX == LONG_MAX"
# endif
using namespace boost;
using std::cout;
namespace
{
struct Base
{
virtual char kind() { return 'B'; }
};
struct Base2
{
virtual char kind2() { return '2'; }
};
struct Derived : public Base, Base2
{
virtual char kind() { return 'D'; }
};
}
int main( int argc, char * argv[] )
{
cout << "Usage: test_casts [n], where n omitted or is:\n"
" 1 = execute #1 assert failure (#ifndef NDEBUG)\n"
" 2 = execute #2 assert failure (#ifndef NDEBUG)\n"
"Example: test_casts 2\n\n";
# ifdef NDEBUG
cout << "NDEBUG is defined\n";
# else
cout << "NDEBUG is not defined\n";
# endif
cout << "\nBeginning tests...\n";
// test polymorphic_cast ---------------------------------------------------//
// tests which should succeed
Base * base = new Derived;
Base2 * base2 = 0;
Derived * derived = 0;
derived = polymorphic_downcast<Derived*>( base ); // downcast
assert( derived->kind() == 'D' );
derived = 0;
derived = polymorphic_cast<Derived*>( base ); // downcast, throw on error
assert( derived->kind() == 'D' );
base2 = polymorphic_cast<Base2*>( base ); // crosscast
assert( base2->kind2() == '2' );
// tests which should result in errors being detected
int err_count = 0;
base = new Base;
if ( argc > 1 && *argv[1] == '1' )
{ derived = polymorphic_downcast<Derived*>( base ); } // #1 assert failure
bool caught_exception = false;
try { derived = polymorphic_cast<Derived*>( base ); }
catch (std::bad_cast)
{ cout<<"caught bad_cast\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
// the following is just so generated code can be inspected
if ( derived->kind() == 'B' ) ++err_count;
// test implicit_cast and numeric_cast -------------------------------------//
// tests which should succeed
long small_value = 1;
long small_negative_value = -1;
long large_value = std::numeric_limits<long>::max();
long large_negative_value = std::numeric_limits<long>::min();
signed char c = 0;
c = large_value; // see if compiler generates warning
c = numeric_cast<signed char>( small_value );
assert( c == 1 );
c = 0;
c = numeric_cast<signed char>( small_value );
assert( c == 1 );
c = 0;
c = numeric_cast<signed char>( small_negative_value );
assert( c == -1 );
// tests which should result in errors being detected
caught_exception = false;
try { c = numeric_cast<signed char>( large_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #1\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
caught_exception = false;
try { c = numeric_cast<signed char>( large_negative_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #2\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
unsigned long ul;
caught_exception = false;
try { ul = numeric_cast<unsigned long>( large_negative_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #3\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
caught_exception = false;
try { ul = numeric_cast<unsigned long>( small_negative_value ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #4\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
caught_exception = false;
try { numeric_cast<int>( std::numeric_limits<double>::max() ); }
catch (bad_numeric_cast)
{ cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; }
if ( !caught_exception ) ++err_count;
cout << err_count << " errors detected\nTest "
<< (err_count==0 ? "passed\n" : "failed\n");
return err_count;
} // main

15
checked_delete.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=refresh content="0; URL=../core/doc/html/core/checked_delete.html">
<title>Automatic redirection</title>
</head>
<body>
Automatic redirection failed, please go to
<a href="../core/doc/html/core/checked_delete.html">checked_delete.html</a>.&nbsp;<hr>
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

View File

@ -1,92 +1,16 @@
<!--
Copyright 2014 Daniel James.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-->
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<meta name="Template"
content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Header <boost/compressed_pair.hpp></title>
<meta http-equiv="refresh" content="0; URL=doc/html/compressed_pair.html">
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
vlink="#800080">
<h2><img src="../../c++boost.gif" width="276" height="86">Header
&lt;<a href="../../boost/detail/call_traits.hpp">boost/compressed_pair.hpp</a>&gt;</h2>
<p>All of the contents of &lt;boost/compressed_pair.hpp&gt; are
defined inside namespace boost.</p>
<p>The class compressed pair is very similar to std::pair, but if
either of the template arguments are empty classes, then the
&quot;empty member optimisation&quot; is applied to compress the
size of the pair.</p>
<pre>template &lt;class T1, class T2&gt;
class compressed_pair
{
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits&lt;first_type&gt;::param_type first_param_type;
typedef typename call_traits&lt;second_type&gt;::param_type second_param_type;
typedef typename call_traits&lt;first_type&gt;::reference first_reference;
typedef typename call_traits&lt;second_type&gt;::reference second_reference;
typedef typename call_traits&lt;first_type&gt;::const_reference first_const_reference;
typedef typename call_traits&lt;second_type&gt;::const_reference second_const_reference;
compressed_pair() : base() {}
compressed_pair(first_param_type x, second_param_type y);
explicit compressed_pair(first_param_type x);
explicit compressed_pair(second_param_type y);
first_reference first();
first_const_reference first() const;
second_reference second();
second_const_reference second() const;
void swap(compressed_pair&amp; y);
};</pre>
<p>The two members of the pair can be accessed using the member
functions first() and second(). Note that not all member
functions can be instantiated for all template parameter types.
In particular compressed_pair can be instantiated for reference
and array types, however in these cases the range of constructors
that can be used are limited. If types T1 and T2 are the same
type, then there is only one version of the single-argument
constructor, and this constructor initialises both values in the
pair to the passed value.</p>
<p>Note that compressed_pair can not be instantiated if either of
the template arguments is an enumerator type, unless there is
compiler support for boost::is_enum, or if boost::is_enum is
specialised for the enumerator type.</p>
<p>Finally, compressed_pair requires compiler support for partial
specialisation of class templates - without that support
compressed_pair behaves just like std::pair.</p>
<hr>
<p>Revised 08 March 2000</p>
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this
copyright notice appears in all copies. This document is provided
&quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose.</p>
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
Hinnant and John Maddock.</p>
<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John
Maddock</a>, the latest version of this file can be found at <a
href="http://www.boost.org">www.boost.org</a>, and the boost
discussion list at <a href="http://www.egroups.com/list/boost">www.egroups.com/list/boost</a>.</p>
<p>&nbsp;</p>
<body>
Automatic redirection failed, please go to
<a href="doc/html/compressed_pair.html">doc/html/compressed_pair.html</a>
</body>
</html>

View File

@ -1,125 +1,393 @@
// boost::compressed_pair test program
// boost::compressed_pair test program
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// (C) Copyright John Maddock 2000.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
// standalone test program for <boost/compressed_pair.hpp>
// Revised 03 Oct 2000:
// Enabled tests for VC6.
#include <iostream>
#include <typeinfo>
#include <cassert>
#include <boost/compressed_pair.hpp>
#include "type_traits_test.hpp"
#include <boost/test/test_tools.hpp>
using namespace boost;
struct empty_POD_UDT{};
struct empty_UDT
{
~empty_UDT(){};
~empty_UDT(){};
empty_UDT& operator=(const empty_UDT&){ return *this; }
bool operator==(const empty_UDT&)const
{ return true; }
};
namespace boost {
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
template <> struct is_empty<empty_UDT>
{ static const bool value = true; };
template <> struct is_empty<empty_POD_UDT>
{ static const bool value = true; };
template <> struct is_POD<empty_POD_UDT>
{ static const bool value = true; };
#else
template <> struct is_empty<empty_UDT>
{ enum{ value = true }; };
template <> struct is_empty<empty_POD_UDT>
{ enum{ value = true }; };
template <> struct is_POD<empty_POD_UDT>
{ enum{ value = true }; };
#endif
}
int main()
struct empty_POD_UDT
{
compressed_pair<int, double> cp1(1, 1.3);
assert(cp1.first() == 1);
assert(cp1.second() == 1.3);
compressed_pair<int, double> cp1b(2, 2.3);
assert(cp1b.first() == 2);
assert(cp1b.second() == 2.3);
swap(cp1, cp1b);
assert(cp1b.first() == 1);
assert(cp1b.second() == 1.3);
assert(cp1.first() == 2);
assert(cp1.second() == 2.3);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
compressed_pair<empty_UDT, int> cp2(2);
assert(cp2.second() == 2);
#endif
compressed_pair<int, empty_UDT> cp3(1);
assert(cp3.first() ==1);
compressed_pair<empty_UDT, empty_UDT> cp4;
compressed_pair<empty_UDT, empty_POD_UDT> cp5;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
int i = 0;
compressed_pair<int&, int&> cp6(i,i);
assert(cp6.first() == i);
assert(cp6.second() == i);
assert(&cp6.first() == &i);
assert(&cp6.second() == &i);
compressed_pair<int, double[2]> cp7;
cp7.first();
double* pd = cp7.second();
#endif
value_test(true, (sizeof(compressed_pair<empty_UDT, int>) < sizeof(std::pair<empty_UDT, int>)))
value_test(true, (sizeof(compressed_pair<int, empty_UDT>) < sizeof(std::pair<int, empty_UDT>)))
value_test(true, (sizeof(compressed_pair<empty_UDT, empty_UDT>) < sizeof(std::pair<empty_UDT, empty_UDT>)))
value_test(true, (sizeof(compressed_pair<empty_UDT, empty_POD_UDT>) < sizeof(std::pair<empty_UDT, empty_POD_UDT>)))
value_test(true, (sizeof(compressed_pair<empty_UDT, compressed_pair<empty_POD_UDT, int> >) < sizeof(std::pair<empty_UDT, std::pair<empty_POD_UDT, int> >)))
empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; }
bool operator==(const empty_POD_UDT&)const
{ return true; }
};
std::cout << std::endl << test_count << " tests completed (" << failures << " failures)... press any key to exit";
std::cin.get();
return failures;
struct non_empty1
{
int i;
non_empty1() : i(1){}
non_empty1(int v) : i(v){}
friend bool operator==(const non_empty1& a, const non_empty1& b)
{ return a.i == b.i; }
};
struct non_empty2
{
int i;
non_empty2() : i(3){}
non_empty2(int v) : i(v){}
friend bool operator==(const non_empty2& a, const non_empty2& b)
{ return a.i == b.i; }
};
#ifdef __GNUC__
using std::swap;
#endif
template <class T1, class T2>
struct compressed_pair_tester
{
// define the types we need:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
// define our test proc:
static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
};
template <class T1, class T2>
void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
{
#ifndef __GNUC__
// gcc 2.90 can't cope with function scope using
// declarations, and generates an internal compiler error...
using std::swap;
#endif
// default construct:
boost::compressed_pair<T1,T2> cp1;
// first param construct:
boost::compressed_pair<T1,T2> cp2(p1);
cp2.second() = p2;
BOOST_CHECK(cp2.first() == p1);
BOOST_CHECK(cp2.second() == p2);
// second param construct:
boost::compressed_pair<T1,T2> cp3(p2);
cp3.first() = p1;
BOOST_CHECK(cp3.second() == p2);
BOOST_CHECK(cp3.first() == p1);
// both param construct:
boost::compressed_pair<T1,T2> cp4(p1, p2);
BOOST_CHECK(cp4.first() == p1);
BOOST_CHECK(cp4.second() == p2);
boost::compressed_pair<T1,T2> cp5(p3, p4);
BOOST_CHECK(cp5.first() == p3);
BOOST_CHECK(cp5.second() == p4);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
BOOST_CHECK(cpr1.first() == p1);
BOOST_CHECK(cpr1.second() == p2);
// copy construct:
boost::compressed_pair<T1,T2> cp6(cp4);
BOOST_CHECK(cp6.first() == p1);
BOOST_CHECK(cp6.second() == p2);
// assignment:
cp1 = cp4;
BOOST_CHECK(cp1.first() == p1);
BOOST_CHECK(cp1.second() == p2);
cp1 = cp5;
BOOST_CHECK(cp1.first() == p3);
BOOST_CHECK(cp1.second() == p4);
// swap:
cp4.swap(cp5);
BOOST_CHECK(cp4.first() == p3);
BOOST_CHECK(cp4.second() == p4);
BOOST_CHECK(cp5.first() == p1);
BOOST_CHECK(cp5.second() == p2);
swap(cp4,cp5);
BOOST_CHECK(cp4.first() == p1);
BOOST_CHECK(cp4.second() == p2);
BOOST_CHECK(cp5.first() == p3);
BOOST_CHECK(cp5.second() == p4);
}
//
// instanciate some compressed pairs:
#ifdef __MWERKS__
template class compressed_pair<int, double>;
template class compressed_pair<int, int>;
template class compressed_pair<empty_UDT, int>;
template class compressed_pair<int, empty_UDT>;
template class compressed_pair<empty_UDT, empty_UDT>;
template class compressed_pair<empty_UDT, empty_POD_UDT>;
#else
template class boost::compressed_pair<int, double>;
template class boost::compressed_pair<int, int>;
template class boost::compressed_pair<empty_UDT, int>;
template class boost::compressed_pair<int, empty_UDT>;
template class boost::compressed_pair<empty_UDT, empty_UDT>;
template class boost::compressed_pair<empty_UDT, empty_POD_UDT>;
#endif
// tests for case where one or both
// parameters are reference types:
//
template <class T1, class T2>
struct compressed_pair_reference_tester
{
// define the types we need:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
// define our test proc:
static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
};
template <class T1, class T2>
void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
{
#ifndef __GNUC__
// gcc 2.90 can't cope with function scope using
// declarations, and generates an internal compiler error...
using std::swap;
#endif
// both param construct:
boost::compressed_pair<T1,T2> cp4(p1, p2);
BOOST_CHECK(cp4.first() == p1);
BOOST_CHECK(cp4.second() == p2);
boost::compressed_pair<T1,T2> cp5(p3, p4);
BOOST_CHECK(cp5.first() == p3);
BOOST_CHECK(cp5.second() == p4);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
BOOST_CHECK(cpr1.first() == p1);
BOOST_CHECK(cpr1.second() == p2);
// copy construct:
boost::compressed_pair<T1,T2> cp6(cp4);
BOOST_CHECK(cp6.first() == p1);
BOOST_CHECK(cp6.second() == p2);
// assignment:
// VC6 bug:
// When second() is an empty class, VC6 performs the
// assignment by doing a memcpy - even though the empty
// class is really a zero sized base class, the result
// is that the memory of first() gets trampled over.
// Similar arguments apply to the case that first() is
// an empty base class.
// Strangely the problem is dependent upon the compiler
// settings - some generate the problem others do not.
cp4.first() = p3;
cp4.second() = p4;
BOOST_CHECK(cp4.first() == p3);
BOOST_CHECK(cp4.second() == p4);
}
//
// supplimentary tests for case where first arg only is a reference type:
//
template <class T1, class T2>
struct compressed_pair_reference1_tester
{
// define the types we need:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
// define our test proc:
static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
};
template <class T1, class T2>
void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
{
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//
// now some for which only a few specific members can be instantiated,
// first references:
template double& compressed_pair<double, int&>::first();
template int& compressed_pair<double, int&>::second();
template compressed_pair<double, int&>::compressed_pair(int&);
template compressed_pair<double, int&>::compressed_pair(call_traits<double>::param_type,int&);
//
// and then arrays:
#ifndef __MWERKS__
#ifndef __BORLANDC__
template call_traits<int[2]>::reference compressed_pair<double, int[2]>::second();
// first param construct:
boost::compressed_pair<T1,T2> cp2(p1);
cp2.second() = p2;
BOOST_CHECK(cp2.first() == p1);
BOOST_CHECK(cp2.second() == p2);
#endif
template call_traits<double>::reference compressed_pair<double, int[2]>::first();
template compressed_pair<double, int[2]>::compressed_pair(const double&);
template compressed_pair<double, int[2]>::compressed_pair();
#endif // __MWERKS__
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}
//
// supplimentary tests for case where second arg only is a reference type:
//
template <class T1, class T2>
struct compressed_pair_reference2_tester
{
// define the types we need:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
// define our test proc:
static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
};
template <class T1, class T2>
void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
{
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// second param construct:
boost::compressed_pair<T1,T2> cp3(p2);
cp3.first() = p1;
BOOST_CHECK(cp3.second() == p2);
BOOST_CHECK(cp3.first() == p1);
#endif
}
//
// tests for where one or the other parameter is an array:
//
template <class T1, class T2>
struct compressed_pair_array1_tester
{
// define the types we need:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
// define our test proc:
static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
};
template <class T1, class T2>
void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
{
// default construct:
boost::compressed_pair<T1,T2> cp1;
// second param construct:
boost::compressed_pair<T1,T2> cp3(p2);
cp3.first()[0] = p1[0];
BOOST_CHECK(cp3.second() == p2);
BOOST_CHECK(cp3.first()[0] == p1[0]);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp3;
BOOST_CHECK(cpr1.first()[0] == p1[0]);
BOOST_CHECK(cpr1.second() == p2);
BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
}
template <class T1, class T2>
struct compressed_pair_array2_tester
{
// define the types we need:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
// define our test proc:
static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
};
template <class T1, class T2>
void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
{
// default construct:
boost::compressed_pair<T1,T2> cp1;
// first param construct:
boost::compressed_pair<T1,T2> cp2(p1);
cp2.second()[0] = p2[0];
BOOST_CHECK(cp2.first() == p1);
BOOST_CHECK(cp2.second()[0] == p2[0]);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp2;
BOOST_CHECK(cpr1.first() == p1);
BOOST_CHECK(cpr1.second()[0] == p2[0]);
BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
}
template <class T1, class T2>
struct compressed_pair_array_tester
{
// define the types we need:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
// define our test proc:
static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
};
template <class T1, class T2>
void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
{
// default construct:
boost::compressed_pair<T1,T2> cp1;
cp1.first()[0] = p1[0];
cp1.second()[0] = p2[0];
BOOST_CHECK(cp1.first()[0] == p1[0]);
BOOST_CHECK(cp1.second()[0] == p2[0]);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp1;
BOOST_CHECK(cpr1.first()[0] == p1[0]);
BOOST_CHECK(cpr1.second()[0] == p2[0]);
BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
}
int test_main(int, char *[])
{
// declare some variables to pass to the tester:
non_empty1 ne1(2);
non_empty1 ne2(3);
non_empty2 ne3(4);
non_empty2 ne4(5);
empty_POD_UDT e1;
empty_UDT e2;
// T1 != T2, both non-empty
compressed_pair_tester<non_empty1,non_empty2>::test(ne1, ne3, ne2, ne4);
// T1 != T2, T2 empty
compressed_pair_tester<non_empty1,empty_POD_UDT>::test(ne1, e1, ne2, e1);
// T1 != T2, T1 empty
compressed_pair_tester<empty_POD_UDT,non_empty2>::test(e1, ne3, e1, ne4);
// T1 != T2, both empty
compressed_pair_tester<empty_POD_UDT,empty_UDT>::test(e1, e2, e1, e2);
// T1 == T2, both non-empty
compressed_pair_tester<non_empty1,non_empty1>::test(ne1, ne1, ne2, ne2);
// T1 == T2, both empty
compressed_pair_tester<empty_UDT,empty_UDT>::test(e2, e2, e2, e2);
// test references:
// T1 != T2, both non-empty
compressed_pair_reference_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4);
compressed_pair_reference_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4);
compressed_pair_reference1_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4);
compressed_pair_reference2_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4);
// T1 != T2, T2 empty
compressed_pair_reference_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1);
compressed_pair_reference1_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1);
// T1 != T2, T1 empty
compressed_pair_reference_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4);
compressed_pair_reference2_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4);
// T1 == T2, both non-empty
compressed_pair_reference_tester<non_empty1&,non_empty1&>::test(ne1, ne1, ne2, ne2);
// tests arrays:
non_empty1 nea1[2];
non_empty1 nea2[2];
non_empty2 nea3[2];
non_empty2 nea4[2];
nea1[0] = non_empty1(5);
nea2[0] = non_empty1(6);
nea3[0] = non_empty2(7);
nea4[0] = non_empty2(8);
// T1 != T2, both non-empty
compressed_pair_array1_tester<non_empty1[2],non_empty2>::test(nea1, ne3, nea2, ne4);
compressed_pair_array2_tester<non_empty1,non_empty2[2]>::test(ne1, nea3, ne2, nea4);
compressed_pair_array_tester<non_empty1[2],non_empty2[2]>::test(nea1, nea3, nea2, nea4);
// T1 != T2, T2 empty
compressed_pair_array1_tester<non_empty1[2],empty_POD_UDT>::test(nea1, e1, nea2, e1);
// T1 != T2, T1 empty
compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4);
// T1 == T2, both non-empty
compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2);
return 0;
}
unsigned int expected_failures = 0;

119
doc/Jamfile.v2 Normal file
View File

@ -0,0 +1,119 @@
# Copyright John Maddock 2005. Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
project : requirements
# Path for links to Boost:
<xsl:param>boost.root=../../../..
# Some general style settings:
<xsl:param>table.footnote.number.format=1
<xsl:param>footnote.number.format=1
# HTML options first:
# Use graphics not text for navigation:
<xsl:param>navig.graphics=1
# PDF Options:
# TOC Generation: this is needed for FOP-0.9 and later:
<xsl:param>fop1.extensions=0
<xsl:param>xep.extensions=1
# TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
<xsl:param>fop.extensions=0
# No indent on body text:
<xsl:param>body.start.indent=0pt
# Margin size:
<xsl:param>page.margin.inner=0.5in
# Margin size:
<xsl:param>page.margin.outer=0.5in
# Paper type = A4
<xsl:param>paper.type=A4
# Yes, we want graphics for admonishments:
<xsl:param>admon.graphics=1
# Set this one for PDF generation *only*:
# default pnd graphics are awful in PDF form,
# better use SVG's instead:
<format>pdf:<xsl:param>admon.graphics.extension=".svg"
<format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/utility/doc/html
;
using quickbook ;
path-constant boost-images : ../../../doc/src/images ;
xml base_from_member : base_from_member.qbk ;
boostbook standalone_base_from_member
:
base_from_member
:
# File name of HTML output:
<xsl:param>root.filename=base_from_member
# How far down we chunk nested sections, basically all of them:
<xsl:param>chunk.section.depth=0
# Don't put the first section on the same page as the TOC:
<xsl:param>chunk.first.sections=0
# How far down sections get TOC's
<xsl:param>toc.section.depth=1
# Max depth in each TOC:
<xsl:param>toc.max.depth=1
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=1
;
xml compressed_pair : compressed_pair.qbk ;
boostbook standalone_compressed_pair
:
compressed_pair
:
# File name of HTML output:
<xsl:param>root.filename=compressed_pair
# How far down we chunk nested sections, basically all of them:
<xsl:param>chunk.section.depth=0
# Don't put the first section on the same page as the TOC:
<xsl:param>chunk.first.sections=0
# How far down sections get TOC's
<xsl:param>toc.section.depth=1
# Max depth in each TOC:
<xsl:param>toc.max.depth=1
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=1
;
xml declval : declval.qbk ;
boostbook standalone_declval
:
declval
:
# File name of HTML output:
<xsl:param>root.filename=declval
# How far down we chunk nested sections, basically all of them:
<xsl:param>chunk.section.depth=0
# Don't put the first section on the same page as the TOC:
<xsl:param>chunk.first.sections=0
# How far down sections get TOC's
<xsl:param>toc.section.depth=1
# Max depth in each TOC:
<xsl:param>toc.max.depth=1
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=1
;
xml string_ref : string_ref.qbk ;
boostbook standalone_string_ref
:
string_ref
:
# File name of HTML output:
<xsl:param>root.filename=string_ref
# How far down we chunk nested sections, basically all of them:
<xsl:param>chunk.section.depth=0
# Don't put the first section on the same page as the TOC:
<xsl:param>chunk.first.sections=0
# How far down sections get TOC's
<xsl:param>toc.section.depth=1
# Max depth in each TOC:
<xsl:param>toc.max.depth=1
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=1
;

363
doc/base_from_member.qbk Normal file
View File

@ -0,0 +1,363 @@
[/
Copyright 2001, 2003, 2004, 2012 Daryle Walker.
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
]
[article Base_From_Member
[quickbook 1.5]
[authors [Walker, Daryle]]
[copyright 2001, 2003, 2004, 2012 Daryle Walker]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
]
[section Rationale]
When developing a class, sometimes a base class needs to be initialized
with a member of the current class. As a na\u00EFve example:
#include <streambuf> /* for std::streambuf */
#include <ostream> /* for std::ostream */
class fdoutbuf
: public std::streambuf
{
public:
explicit fdoutbuf( int fd );
//...
};
class fdostream
: public std::ostream
{
protected:
fdoutbuf buf;
public:
explicit fdostream( int fd )
: buf( fd ), std::ostream( &buf ) {}
//...
};
This is undefined because C++'s initialization order mandates that the base
class is initialized before the member it uses. [@http://www.moocat.org R.
Samuel Klatchko] developed a way around this by using the initialization
order in his favor. Base classes are intialized in order of declaration, so
moving the desired member to another base class, that is initialized before
the desired base class, can ensure proper initialization.
A custom base class can be made for this idiom:
#include <streambuf> /* for std::streambuf */
#include <ostream> /* for std::ostream */
class fdoutbuf
: public std::streambuf
{
public:
explicit fdoutbuf( int fd );
//...
};
struct fdostream_pbase
{
fdoutbuf sbuffer;
explicit fdostream_pbase( int fd )
: sbuffer( fd ) {}
};
class fdostream
: private fdostream_pbase
, public std::ostream
{
typedef fdostream_pbase pbase_type;
typedef std::ostream base_type;
public:
explicit fdostream( int fd )
: pbase_type( fd ), base_type( &sbuffer ) {}
//...
};
Other projects can use similar custom base classes. The technique is basic
enough to make a template, with a sample template class in this library.
The main template parameter is the type of the enclosed member. The
template class has several (explicit) constructor member templates, which
implicitly type the constructor arguments and pass them to the member. The
template class uses implicit copy construction and assignment, cancelling
them if the enclosed member is non-copyable.
Manually coding a base class may be better if the construction and/or
copying needs are too complex for the supplied template class, or if the
compiler is not advanced enough to use it.
Since base classes are unnamed, a class cannot have multiple (direct) base
classes of the same type. The supplied template class has an extra template
parameter, an integer, that exists solely to provide type differentiation.
This parameter has a default value so a single use of a particular member
type does not need to concern itself with the integer.
[endsect]
[section Synopsis]
#include <type_traits> /* exposition only */
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
#endif
template < typename MemberType, int UniqueID = 0 >
class boost::base_from_member
{
protected:
MemberType member;
#if ``['C++11 is in use]``
template< typename ...T >
explicit constexpr base_from_member( T&& ...x )
noexcept( std::is_nothrow_constructible<MemberType, T...>::value );
#else
base_from_member();
template< typename T1 >
explicit base_from_member( T1 x1 );
template< typename T1, typename T2 >
base_from_member( T1 x1, T2 x2 );
//...
template< typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10 >
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
T8 x8, T9 x9, T10 x10 );
#endif
};
template < typename MemberType, int UniqueID >
class base_from_member<MemberType&, UniqueID>
{
protected:
MemberType& member;
explicit constexpr base_from_member( MemberType& x )
noexcept;
};
The class template has a first template parameter `MemberType` representing
the type of the based-member. It has a last template parameter `UniqueID`,
that is an `int`, to differentiate between multiple base classes that use
the same based-member type. The last template parameter has a default value
of zero if it is omitted. The class template has a protected data member
called `member` that the derived class can use for later base classes (or
itself).
If the appropriate features of C++11 are present, there will be a single
constructor template. It implements ['perfect forwarding] to the best
constructor call of `member` (if any). The constructor template is marked
both `constexpr` and `explicit`. The former will be ignored if the
corresponding inner constructor call (of `member`) does not have the marker.
The latter binds the other way; always taking effect, even when the inner
constructor call does not have the marker. The constructor template
propagates the `noexcept` status of the inner constructor call. (The
constructor template has a trailing parameter with a default value that
disables the template when its signature is too close to the signatures of
the automatically-defined non-template copy- and/or move-constructors of
`base_from_member`.)
On earlier-standard compilers, there is a default constructor and several
constructor member templates. These constructor templates can take as many
arguments (currently up to ten) as possible and pass them to a constructor
of the data member.
A specialization for member references offers a single constructor taking
a `MemberType&`, which is the only way to initialize a reference.
Since C++ does not allow any way to explicitly state the template parameters
of a templated constructor, make sure that the arguments are already close
as possible to the actual type used in the data member's desired constructor.
Explicit conversions may be necessary.
The `BOOST_BASE_FROM_MEMBER_MAX_ARITY` macro constant specifies the maximum
argument length for the constructor templates. The constant may be overridden
if more (or less) argument configurations are needed. The constant may be
read for code that is expandable like the class template and needs to
maintain the same maximum size. (Example code would be a class that uses
this class template as a base class for a member with a flexible set of
constructors.) This constant is ignored when C++11 features are present.
[endsect]
[section Usage]
With the starting example, the `fdoutbuf` sub-object needs to be
encapsulated in a base class that is inheirited before `std::ostream`.
#include <boost/utility/base_from_member.hpp>
#include <streambuf> // for std::streambuf
#include <ostream> // for std::ostream
class fdoutbuf
: public std::streambuf
{
public:
explicit fdoutbuf( int fd );
//...
};
class fdostream
: private boost::base_from_member<fdoutbuf>
, public std::ostream
{
// Helper typedef's
typedef boost::base_from_member<fdoutbuf> pbase_type;
typedef std::ostream base_type;
public:
explicit fdostream( int fd )
: pbase_type( fd ), base_type( &member ){}
//...
};
The base-from-member idiom is an implementation detail, so it should not
be visible to the clients (or any derived classes) of `fdostream`. Due to
the initialization order, the `fdoutbuf` sub-object will get initialized
before the `std::ostream` sub-object does, making the former sub-object
safe to use in the latter sub-object's construction. Since the `fdoutbuf`
sub-object of the final type is the only sub-object with the name `member`
that name can be used unqualified within the final class.
[endsect]
[section Example]
The base-from-member class templates should commonly involve only one
base-from-member sub-object, usually for attaching a stream-buffer to an
I/O stream. The next example demonstrates how to use multiple
base-from-member sub-objects and the resulting qualification issues.
#include <boost/utility/base_from_member.hpp>
#include <cstddef> /* for NULL */
struct an_int
{
int y;
an_int( float yf );
};
class switcher
{
public:
switcher();
switcher( double, int * );
//...
};
class flow_regulator
{
public:
flow_regulator( switcher &, switcher & );
//...
};
template < unsigned Size >
class fan
{
public:
explicit fan( switcher );
//...
};
class system
: private boost::base_from_member<an_int>
, private boost::base_from_member<switcher>
, private boost::base_from_member<switcher, 1>
, private boost::base_from_member<switcher, 2>
, protected flow_regulator
, public fan<6>
{
// Helper typedef's
typedef boost::base_from_member<an_int> pbase0_type;
typedef boost::base_from_member<switcher> pbase1_type;
typedef boost::base_from_member<switcher, 1> pbase2_type;
typedef boost::base_from_member<switcher, 2> pbase3_type;
typedef flow_regulator base1_type;
typedef fan<6> base2_type;
public:
system( double x );
//...
};
system::system( double x )
: pbase0_type( 0.2 )
, pbase1_type()
, pbase2_type( -16, &this->pbase0_type::member.y )
, pbase3_type( x, static_cast<int *>(NULL) )
, base1_type( pbase3_type::member, pbase1_type::member )
, base2_type( pbase2_type::member )
{
//...
}
The final class has multiple sub-objects with the name `member`, so any
use of that name needs qualification by a name of the appropriate base
type. (Using `typedef`s ease mentioning the base types.) However, the fix
introduces a new problem when a pointer is needed. Using the address
operator with a sub-object qualified with its class's name results in a
pointer-to-member (here, having a type of `an_int boost::base_from_member<
an_int, 0> :: *`) instead of a pointer to the member (having a type of
`an_int *`). The new problem is fixed by qualifying the sub-object with
`this->` and is needed just for pointers, and not for references or values.
There are some argument conversions in the initialization. The constructor
argument for `pbase0_type` is converted from `double` to `float`. The first
constructor argument for `pbase2_type` is converted from `int` to `double`.
The second constructor argument for `pbase3_type` is a special case of
necessary conversion; all forms of the null-pointer literal in C++ (except
`nullptr` from C++11) also look like compile-time integral expressions, so
C++ always interprets such code as an integer when it has overloads that can
take either an integer or a pointer. The last conversion is necessary for the
compiler to call a constructor form with the exact pointer type used in
`switcher`'s constructor. (If C++11's `nullptr` is used, it still needs a
conversion if multiple pointer types can be accepted in a constructor call
but `std::nullptr_t` cannot.)
[endsect]
[section Acknowledgments]
* [@http://www.boost.org/people/ed_brey.htm Ed Brey] suggested some interface
changes.
* [@http://www.moocat.org R. Samuel Klatchko] ([@mailto:rsk@moocat.org
rsk@moocat.org], [@mailto:rsk@brightmail.com rsk@brightmail.com]) invented
the idiom of how to use a class member for initializing a base class.
* [@http://www.boost.org/people/dietmar_kuehl.htm Dietmar Kuehl] popularized the
base-from-member idiom in his [@http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/
IOStream example classes].
* Jonathan Turkanis supplied an implementation of generating the constructor
templates that can be controlled and automated with macros. The
implementation uses the [@../../../preprocessor/index.html Preprocessor library].
* [@http://www.boost.org/people/daryle_walker.html">Daryle Walker] started the
library. Contributed the test file [@../../base_from_member_test.cpp
base_from_member_test.cpp].
[endsect]

99
doc/compressed_pair.qbk Normal file
View File

@ -0,0 +1,99 @@
[/
Copyright 2000 Beman Dawes & John Maddock.
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
]
[article Compressed_Pair
[quickbook 1.5]
[authors [Cleary, Steve]]
[authors [Dawes, Beman]]
[authors [Hinnant, Howard]]
[authors [Maddock, John]]
[copyright 2000 Steve Cleary, Beman Dawes, Howard Hinnant &amp; John Maddock]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
]
[section Overview]
All of the contents of `<boost/compressed_pair.hpp>` are defined inside
`namespace boost`.
The class `compressed_pair` is very similar to `std::pair`, but if either of
the template arguments are empty classes, then the ['empty base-class
optimisation] is applied to compress the size of the pair.
[endsect]
[section Synopsis]
template <class T1, class T2>
class compressed_pair
{
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair() : base() {}
compressed_pair(first_param_type x, second_param_type y);
explicit compressed_pair(first_param_type x);
explicit compressed_pair(second_param_type y);
compressed_pair& operator=(const compressed_pair&);
first_reference first();
first_const_reference first() const;
second_reference second();
second_const_reference second() const;
void swap(compressed_pair& y);
};
The two members of the pair can be accessed using the member functions
`first()` and `second()`. Note that not all member functions can be
instantiated for all template parameter types. In particular
`compressed_pair` can be instantiated for reference and array types,
however in these cases the range of constructors that can be used are
limited. If types `T1` and `T2` are the same type, then there is only
one version of the single-argument constructor, and this constructor
initialises both values in the pair to the passed value.
Note that if either member is a POD type, then that member is not
zero-initialized by the `compressed_pair` default constructor: it's up
to you to supply an initial value for these types if you want them to have
a default value.
Note that `compressed_pair` can not be instantiated if either of the
template arguments is a union type, unless there is compiler support for
`boost::is_union`, or if `boost::is_union` is specialised for the union
type.
Finally, a word of caution for Visual C++ 6 users: if either argument is an
empty type, then assigning to that member will produce memory corruption,
unless the empty type has a "do nothing" assignment operator defined. This
is due to a bug in the way VC6 generates implicit assignment operators.
[endsect]
[section Acknowledgments]
Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and
John Maddock.
Maintained by [@mailto:john@johnmaddock.co.uk John Maddock].
[endsect]

114
doc/declval.qbk Normal file
View File

@ -0,0 +1,114 @@
[/
/ Copyright (c) 2008 Howard Hinnant
/ Copyright (c) 2009-20012 Vicente J. Botet Escriba
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[article Declval
[quickbook 1.5]
[authors [Hinnant, Howard]]
[authors [Botet Escriba, Vicente J.]]
[copyright 2008 Howard Hinnant]
[copyright 2009-2012 Vicente J. Botet Escriba]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
]
[/===============]
[section Overview]
[/===============]
The motivation for `declval` was introduced in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value N2958:
Moving Swap Forward]. Here follows a rewording of this chapter.
With the provision of decltype, late-specified return types, and default template-arguments for function templates a
new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale.
Using this technique, it is sometimes necessary to obtain an object of a known type in a non-using context, e.g. given the declaration
template<class T>
T&& declval(); // not used
as part of the function template declaration
template<class To, class From>
decltype(static_cast<To>(declval<From>())) convert(From&&);
or as part of a class template definition
template<class> class result_of;
template<class Fn, class... ArgTypes>
struct result_of<Fn(ArgTypes...)>
{
typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) type;
};
The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function.
The name is supposed to direct the reader's attention to the fact that the expression `declval<T>()` is an lvalue if and only if
T is an lvalue-reference, otherwise an rvalue. To extend the domain of this function we can do a bit better by changing its declaration to
template<class T>
typename std::add_rvalue_reference<T>::type declval(); // not used
which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()`
already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C++0x standard.
The provision of a new library component that allows the production of values in unevaluated expressions is considered
important to realize constrained templates in C++0x where concepts are not available.
This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer.
[endsect]
[/=================]
[section:reference Reference ]
[/=================]
`#include <boost/utility/declval.hpp>`
namespace boost {
template <typename T>
typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand
} // namespace boost
The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands.
template <typename T>
typename add_rvalue_reference<T>::type declval();
[*Remarks:] If this function is used, the program is ill-formed.
[*Remarks:] The template parameter T of declval may be an incomplete type.
[*Example:]
template <class To, class From>
decltype(static_cast<To>(declval<From>())) convert(From&&);
Declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To.
[endsect]
[/===============]
[section History]
[/===============]
[heading boost 1.50]
Fixes:
* [@http://svn.boost.org/trac/boost/ticket/6570 #6570] Adding noexcept to boost::declval.
[endsect]

167
doc/string_ref.qbk Normal file
View File

@ -0,0 +1,167 @@
[/
/ Copyright (c) 2012 Marshall Clow
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[article String_Ref
[quickbook 1.5]
[authors [Clow, Marshall]]
[copyright 2012 Marshall Clow]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
]
[/===============]
[section Overview]
[/===============]
Boost.StringRef is an implementation of Jeffrey Yaskin's [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html N3442:
string_ref: a non-owning reference to a string].
When you are parsing/processing strings from some external source, frequently you want to pass a piece of text to a procedure for specialized processing. The canonical way to do this is as a `std::string`, but that has certain drawbacks:
1) If you are processing a buffer of text (say a HTTP response or the contents of a file), then you have to create the string from the text you want to pass, which involves memory allocation and copying of data.
2) if a routine receives a constant `std::string` and wants to pass a portion of that string to another routine, then it must create a new string of that substring.
3) A routine receives a constant `std::string` and wants to return a portion of the string, then it must create a new string to return.
`string_ref` is designed to solve these efficiency problems. A `string_ref` is a read-only reference to a contiguous sequence of characters, and provides much of the functionality of `std::string`. A `string_ref` is cheap to create, copy and pass by value, because it does not actually own the storage that it points to.
A `string_ref` is implemented as a small struct that contains a pointer to the start of the character data and a count. A `string_ref` is cheap to create and cheap to copy.
`string_ref` acts as a container; it includes all the methods that you would expect in a container, including iteration support, `operator []`, `at` and `size`. It can be used with any of the iterator-based algorithms in the STL - as long as you don't need to change the underlying data (`sort` and `remove`, for example, will not work)
Besides generic container functionality, `string_ref` provides a subset of the interface of `std::string`. This makes it easy to replace parameters of type `const std::string &` with `boost::string_ref`. Like `std::string`, `string_ref` has a static member variable named `npos` to denote the result of failed searches, and to mean "the end".
Because a `string_ref` does not own the data that it "points to", it introduces lifetime issues into code that uses it. The programmer must ensure that the data that a `string_ref` refers to exists as long as the `string_ref` does.
[endsect]
[/===============]
[section Examples]
[/===============]
Integrating `string_ref` into your code is fairly simple. Wherever you pass a `const std::string &` or `std::string` as a parameter, that's a candidate for passing a `boost::string_ref`.
std::string extract_part ( const std::string &bar ) {
return bar.substr ( 2, 3 );
}
if ( extract_part ( "ABCDEFG" ).front() == 'C' ) { /* do something */ }
Let's figure out what happens in this (contrived) example.
First, a temporary string is created from the string literal `"ABCDEFG"`, and it is passed (by reference) to the routine `extract_part`. Then a second string is created in the call `std::string::substr` and returned to `extract_part` (this copy may be elided by RVO). Then `extract_part` returns that string back to the caller (again this copy may be elided). The first temporary string is deallocated, and `front` is called on the second string, and then it is deallocated as well.
Two `std::string`s are created, and two copy operations. That's (potentially) four memory allocations and deallocations, and the associated copying of data.
Now let's look at the same code with `string_ref`:
boost::string_ref extract_part ( boost::string_ref bar ) {
return bar.substr ( 2, 3 );
}
if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ }
No memory allocations. No copying of character data. No changes to the code other than the types. There are two `string_ref`s created, and two `string_ref`s copied, but those are cheap operations.
[endsect]
[/=================]
[section:reference Reference ]
[/=================]
The header file "string_ref.hpp" defines a template `boost::basic_string_ref`, and four specializations - for `char` / `wchar_t` / `char16_t` / `char32_t` .
`#include <boost/utility/string_ref.hpp>`
Construction and copying:
BOOST_CONSTEXPR basic_string_ref (); // Constructs an empty string_ref
BOOST_CONSTEXPR basic_string_ref(const charT* str); // Constructs from a NULL-terminated string
BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len); // Constructs from a pointer, length pair
template<typename Allocator>
basic_string_ref(const std::basic_string<charT, traits, Allocator>& str); // Constructs from a std::string
basic_string_ref (const basic_string_ref &rhs);
basic_string_ref& operator=(const basic_string_ref &rhs);
`string_ref` does not define a move constructor nor a move-assignment operator because copying a `string_ref` is just a cheap as moving one.
Basic container-like functions:
BOOST_CONSTEXPR size_type size() const ;
BOOST_CONSTEXPR size_type length() const ;
BOOST_CONSTEXPR size_type max_size() const ;
BOOST_CONSTEXPR bool empty() const ;
// All iterators are const_iterators
BOOST_CONSTEXPR const_iterator begin() const ;
BOOST_CONSTEXPR const_iterator cbegin() const ;
BOOST_CONSTEXPR const_iterator end() const ;
BOOST_CONSTEXPR const_iterator cend() const ;
const_reverse_iterator rbegin() const ;
const_reverse_iterator crbegin() const ;
const_reverse_iterator rend() const ;
const_reverse_iterator crend() const ;
Access to the individual elements (all of which are const):
BOOST_CONSTEXPR const charT& operator[](size_type pos) const ;
const charT& at(size_t pos) const ;
BOOST_CONSTEXPR const charT& front() const ;
BOOST_CONSTEXPR const charT& back() const ;
BOOST_CONSTEXPR const charT* data() const ;
Modifying the `string_ref` (but not the underlying data):
void clear();
void remove_prefix(size_type n);
void remove_suffix(size_type n);
Searching:
size_type find(basic_string_ref s) const ;
size_type find(charT c) const ;
size_type rfind(basic_string_ref s) const ;
size_type rfind(charT c) const ;
size_type find_first_of(charT c) const ;
size_type find_last_of (charT c) const ;
size_type find_first_of(basic_string_ref s) const ;
size_type find_last_of(basic_string_ref s) const ;
size_type find_first_not_of(basic_string_ref s) const ;
size_type find_first_not_of(charT c) const ;
size_type find_last_not_of(basic_string_ref s) const ;
size_type find_last_not_of(charT c) const ;
String-like operations:
BOOST_CONSTEXPR basic_string_ref substr(size_type pos, size_type n=npos) const ; // Creates a new string_ref
bool starts_with(charT c) const ;
bool starts_with(basic_string_ref x) const ;
bool ends_with(charT c) const ;
bool ends_with(basic_string_ref x) const ;
[endsect]
[/===============]
[section History]
[/===============]
[heading boost 1.53]
* Introduced
[endsect]

15
enable_if.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=refresh content="0; URL=../core/doc/html/core/enable_if.html">
<title>Automatic redirection</title>
</head>
<body>
Automatic redirection failed, please go to
<a href="../core/doc/html/core/enable_if.html">enable_if.html</a>.&nbsp;<hr>
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

163
generator_iterator.htm Normal file
View File

@ -0,0 +1,163 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<title>Generator Iterator Adaptor Documentation</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle"
width="277" height="86">
<h1>Generator Iterator Adaptor</h1>
<p>Defined in header <a href=
"../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a></p>
<p>The generator iterator adaptor makes it easier to create custom input
iterators from 0-ary functions and function objects. The adaptor takes a
<a href="http://www.sgi.com/tech/stl/Generator.html">Generator</a> and
creates a model of <a href=
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>. Each
increment retrieves an item from the generator and makes it available to be
retrieved by dereferencing. The motivation for this iterator is that some
concepts can be more naturally expressed as a generator, while most STL
algorithms expect an iterator. An example is the <a href=
"../random/index.html">Random Number</a> library.</p>
<h2>Synopsis</h2>
<blockquote>
<pre>
namespace boost {
template &lt;class Generator&gt;
class generator_iterator_policies;
template &lt;class Generator&gt;
class generator_iterator_generator;
template &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; gen);
}
</pre>
</blockquote>
<hr>
<h2>The Generator Iterator Generator Class</h2>
<p>The class generator_iterator_generator is a helper class whose purpose
is to construct a generator iterator type. The template parameter for this
class is the Generator function object type that is being wrapped. The
generator iterator adaptor only holds a reference (or pointer) to the
function object, therefore the function object must outlive the generator
iterator adaptor constructed from it.</p>
<pre>
template &lt;class Generator&gt;
class generator_iterator_generator
{
public:
typedef <i>unspecified</i> type; // the resulting generator iterator type
}
</pre>
<h3>Template Parameters</h3>
<table border summary="">
<tr>
<th>Parameter</th>
<th>Description</th>
</tr>
<tr>
<td><tt><a href=
"http://www.sgi.com/tech/stl/Generator.html">Generator</a></tt></td>
<td>The generator (0-ary function object) type being wrapped. The
return type of the function must be defined as
<tt>Generator::result_type</tt>. The function object must be a model of
<a href=
"http://www.sgi.com/tech/stl/Generator.html">Generator</a>.</td>
</tr>
</table>
<h3>Concept Model</h3>
<p>The generator iterator class is a model of <a href=
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.</p>
<h3>Members</h3>
<p>The generator iterator implements the member functions and operators
required of the <a href=
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>
concept.<br></p>
<hr>
<h2><a name="make_generator_iterator" id="make_generator_iterator">The
Generator Iterator Object Generator</a></h2>
<p>The <tt>make_generator_iterator()</tt> function provides a convenient
way to create generator iterator objects. The function saves the user the
trouble of explicitly writing out the iterator types.</p>
<blockquote>
<pre>
template &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; gen);
</pre>
</blockquote>
<hr>
<h3>Example</h3>
<p>The following program shows how <code>generator_iterator</code>
transforms a generator into an input iterator.</p>
<blockquote>
<pre>
#include &lt;iostream&gt;
#include &lt;boost/generator_iterator.hpp&gt;
class my_generator
{
public:
typedef int result_type;
my_generator() : state(0) { }
int operator()() { return ++state; }
private:
int state;
};
int main()
{
my_generator gen;
boost::generator_iterator_generator&lt;my_generator&gt;::type it = boost::make_generator_iterator(gen);
for(int i = 0; i &lt; 10; ++i, ++it)
std::cout &lt;&lt; *it &lt;&lt; std::endl;
}
</pre>
</blockquote>
<hr>
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
height="31" width="88"></a></p>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
<p><i>Copyright &copy; 2001 <a href=
"http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a></i></p>
<p><i>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href=
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
</body>
</html>

View File

@ -0,0 +1,63 @@
//
// Copyright 2014 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
#include <boost/generator_iterator.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <algorithm>
class X
{
private:
int v;
public:
typedef int result_type;
X(): v( 0 )
{
}
int operator()()
{
return ++v;
}
};
template<class InputIterator, class Size, class OutputIterator> OutputIterator copy_n( InputIterator first, Size n, OutputIterator result )
{
while( n-- > 0 )
{
*result++ = *first++;
}
return result;
}
void copy_test()
{
X x;
boost::generator_iterator<X> in( &x );
int const N = 4;
int v[ N ] = { 0 };
::copy_n( in, 4, v );
BOOST_TEST_EQ( v[0], 1 );
BOOST_TEST_EQ( v[1], 2 );
BOOST_TEST_EQ( v[2], 3 );
BOOST_TEST_EQ( v[3], 4 );
}
int main()
{
copy_test();
return boost::report_errors();
}

View File

@ -0,0 +1,44 @@
# Copyright (C) 2009-2012 Lorenzo Caminiti
# Distributed under the Boost Software License, Version 1.0
# (see accompanying file LICENSE_1_0.txt or a copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Home at http://www.boost.org/libs/utility/identity_type
import quickbook ;
using boostbook ;
doxygen reference : ../../../../boost/utility/identity_type.hpp
: <reftitle>"Reference"
<doxygen:param>PREDEFINED="DOXYGEN"
<doxygen:param>QUIET=YES
<doxygen:param>WARN_IF_UNDOCUMENTED=NO
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>HIDE_UNDOC_CLASSES=YES
<doxygen:param>ALIASES=" Params=\"<b>Parameters:</b> <table border="0">\" Param{2}=\"<tr><td><b><tt>\\1</tt></b></td><td>\\2</td></tr>\" EndParams=\"</table>\" Returns=\"<b>Returns:</b>\" Note=\"<b>Note:</b>\" Warning=\"<b>Warning:</b>\" See=\"<b>See:</b>\" RefSect{2}=\"\\xmlonly<link linkend='boost_utility_identitytype.\\1'>\\2</link>\\endxmlonly\" RefClass{1}=\"\\xmlonly<computeroutput><classname alt='\\1'>\\1</classname></computeroutput>\\endxmlonly\" RefFunc{1}=\"\\xmlonly<computeroutput><functionname alt='\\1'>\\1</functionname></computeroutput>\\endxmlonly\" RefMacro{1}=\"\\xmlonly<computeroutput><macroname alt='\\1'>\\1</macroname></computeroutput>\\endxmlonly\" "
;
# This target must be called "index" so to generate "index.html" file.
xml index : identity_type.qbk : <dependency>reference ;
boostbook doc : index
: <location>html
<format>onehtml
<xsl:param>toc.section.depth=0
<xsl:param>html.stylesheet=../../../../../doc/src/boostbook.css
<xsl:param>boost.root=../../../../..
;
#
# This is very imperfect - it results in both html and pdf docs being built,
# for some reason I can't get the "onehtml" format specified above to play nice
# with the usual incantations for mixed pdf/html builds. JM 06/2012.
#
boostbook pdf_doc : index
:
<format>pdf
<format>html:<build>no
;
install pdf_doc_install : pdf_doc : <location>. <name>identity_type.pdf <install-type>PDF ;
explicit pdf_doc_install ;

View File

@ -0,0 +1,252 @@
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Boost.Utility/IdentityType 1.0.0</title><link rel="stylesheet" type="text/css" href="../../../../../doc/src/boostbook.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter" title="Boost.Utility/IdentityType 1.0.0"><div class="titlepage"><div><div><h2 class="title"><a name="boost_utility_identitytype"></a>Boost.Utility/IdentityType 1.0.0</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Lorenzo</span> <span class="surname">Caminiti <code class="email">&lt;<a class="email" href="mailto:lorcaminiti@gmail.com">lorcaminiti@gmail.com</a>&gt;</code></span></h3></div></div><div><p class="copyright">Copyright © 2009-2012 Lorenzo
Caminiti</p></div><div><div class="legalnotice" title="Legal Notice"><a name="boost_utility_identitytype.legal"></a><p>
Distributed under the Boost Software License, Version 1.0 (see accompanying
file LICENSE_1_0.txt or a copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p></div></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#boost_utility_identitytype.motivation">Motivation</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.solution">Solution</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.templates">Templates</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.abstract_types">Abstract Types</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.annex__usage">Annex: Usage</a></span></dt><dt><span class="section"><a href="#boost_utility_identitytype.annex__implementation">Annex:
Implementation</a></span></dt><dt><span class="section"><a href="#reference">Reference</a></span></dt></dl></div><p>
This library allows to wrap types within round parenthesis so they can always
be passed as macro parameters.
</p><div class="section boost_utility_identitytype_motivation" title="Motivation"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.motivation"></a><a class="link" href="#boost_utility_identitytype.motivation" title="Motivation">Motivation</a></h2></div></div></div><p>
Consider the following macro which declares a variable named <code class="computeroutput"><span class="identifier">var</span></code><code class="literal"><span class="emphasis"><em>n</em></span></code>
with the specified <code class="literal"><span class="emphasis"><em>type</em></span></code> (see also
<a href="../../test/var_error.cpp" target="_top"><code class="literal">var_error.cpp</code></a>):
</p><p>
</p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">VAR</span><span class="special">(</span><span class="identifier">type</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span> <span class="identifier">type</span> <span class="identifier">var</span> <span class="error">#</span><span class="preprocessor"># n</span>
<span class="identifier">VAR</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="number">1</span><span class="special">);</span> <span class="comment">// OK.</span>
<span class="identifier">VAR</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;,</span> <span class="number">2</span><span class="special">);</span> <span class="comment">// Error.</span>
</pre><p>
</p><p>
The first macro invocation works correctly declaring a variable named <code class="computeroutput"><span class="identifier">var1</span></code> of type <code class="computeroutput"><span class="keyword">int</span></code>.
However, the second macro invocation fails generating a preprocessor error
similar to the following:
</p><pre class="programlisting">error: macro "VAR" passed 3 arguments, but takes just 2
</pre><p>
That is because the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code> type passed as the first macro parameter
contains a comma <code class="computeroutput"><span class="special">,</span></code> not wrapped
by round parenthesis <code class="computeroutput"><span class="special">()</span></code>. The preprocessor
interprets that unwrapped comma as a separation between macro parameters concluding
that a total of three (and not two) parameters are passed to the macro in the
following order:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span></code>
</li><li class="listitem">
<code class="computeroutput"><span class="keyword">char</span><span class="special">&gt;</span></code>
</li><li class="listitem">
<code class="computeroutput"><span class="number">2</span></code>
</li></ol></div><p>
Note that, differently from the compiler, the preprocessor only recognizes
round parenthesis <code class="computeroutput"><span class="special">()</span></code>. Angular
<code class="computeroutput"><span class="special">&lt;&gt;</span></code> and squared <code class="computeroutput"><span class="special">[]</span></code> parenthesis are not recognized by the preprocessor
when parsing macro parameters.
</p></div><div class="section boost_utility_identitytype_solution" title="Solution"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.solution"></a><a class="link" href="#boost_utility_identitytype.solution" title="Solution">Solution</a></h2></div></div></div><p>
In some cases, it might be possible to workaround this issue by avoiding to
pass the type expression to the macro all together. For example, in the case
above a <code class="computeroutput"><span class="keyword">typedef</span></code> could have been
used to specify the type expression with the commas outside the macro (see
also <a href="../../test/var.cpp" target="_top"><code class="literal">var.cpp</code></a>):
</p><p>
</p><pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">map_type</span><span class="special">;</span>
<span class="identifier">VAR</span><span class="special">(</span><span class="identifier">map_type</span><span class="special">,</span> <span class="number">3</span><span class="special">);</span> <span class="comment">// OK.</span>
</pre><p>
</p><p>
When this is neither possible nor desired (e.g., see the function template
<code class="computeroutput"><span class="identifier">f</span></code> in the section below), this
library header <code class="computeroutput"><a class="link" href="#header.boost.utility.identity_type_hpp" title="Header &lt;boost/utility/identity_type.hpp&gt;">boost/utility/identity_type.hpp</a></code>
defines a macro <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
which can be used to workaround the issue while keeping the type expression
as one of the macro parameters (see also <a href="../../test/var.cpp" target="_top"><code class="literal">var.cpp</code></a>).
</p><p>
</p><pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">identity_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="identifier">VAR</span><span class="special">(</span><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;)),</span> <span class="number">4</span><span class="special">);</span> <span class="comment">// OK.</span>
</pre><p>
</p><p>
The <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro
expands to an expression that evaluates (at compile-time) to the specified
type. The specified type is never split into multiple macro parameters because
it is always wrapped by a set of extra round parenthesis <code class="computeroutput"><span class="special">()</span></code>.
In fact, a total of two sets of round parenthesis must be used: The parenthesis
to invoke the macro <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(...)</span></code> plus the inner parenthesis to wrap the
type passed to the macro <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((...))</span></code>.
</p><p>
This macro works on any <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
compiler (and it does not use <a href="http://en.wikipedia.org/wiki/Variadic_macro" target="_top">variadic
macros</a>). <sup>[<a name="boost_utility_identitytype.solution.f0" href="#ftn.boost_utility_identitytype.solution.f0" class="footnote">1</a>]</sup> The authors originally developed and tested this library using
GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled
<code class="computeroutput"><span class="special">-</span><span class="identifier">std</span><span class="special">=</span><span class="identifier">c</span><span class="special">++</span><span class="number">0</span><span class="identifier">x</span></code>) on Cygwin
and Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7. See the library <a href="http://www.boost.org/development/tests/release/developer/utility-identity_type.html" target="_top">regressions
test results</a> for more information on supported compilers and platforms.
</p></div><div class="section boost_utility_identitytype_templates" title="Templates"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.templates"></a><a class="link" href="#boost_utility_identitytype.templates" title="Templates">Templates</a></h2></div></div></div><p>
This macro must be prefixed by <code class="computeroutput"><span class="keyword">typename</span></code>
when used within templates. For example, let's program a macro that declares
a function parameter named <code class="computeroutput"><span class="identifier">arg</span></code><code class="literal"><span class="emphasis"><em>n</em></span></code>
with the specified <code class="literal"><span class="emphasis"><em>type</em></span></code> (see also
<a href="../../test/template.cpp" target="_top"><code class="literal">template.cpp</code></a>):
</p><p>
</p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">ARG</span><span class="special">(</span><span class="identifier">type</span><span class="special">,</span> <span class="identifier">n</span><span class="special">)</span> <span class="identifier">type</span> <span class="identifier">arg</span> <span class="error">#</span><span class="preprocessor"># n</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span> <span class="comment">// Prefix macro with `typename` in templates.</span>
<span class="identifier">ARG</span><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;)),</span> <span class="number">1</span><span class="special">)</span>
<span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">arg1</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre><p>
</p><p>
</p><pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">a</span><span class="special">;</span>
<span class="identifier">a</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="char">'a'</span><span class="special">;</span>
<span class="identifier">f</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// OK...</span>
<span class="comment">// f(a); // ... but error.</span>
</pre><p>
</p><p>
However, note that the template parameter <code class="computeroutput"><span class="keyword">char</span></code>
must be manually specified when invoking the function as in <code class="computeroutput"><span class="identifier">f</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">a</span><span class="special">)</span></code>. In fact,
when the <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
macro is used to wrap a function template parameter, the template parameter
can no longer be automatically deduced by the compiler form the function call
as <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a</span><span class="special">)</span></code> would
have done. <sup>[<a name="boost_utility_identitytype.templates.f0" href="#ftn.boost_utility_identitytype.templates.f0" class="footnote">2</a>]</sup> (This limitation does not apply to class templates because class
template parameters must always be explicitly specified.) In other words, without
using the <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
macro, C++ would normally be able to automatically deduce the function template
parameter as shown below:
</p><p>
</p><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">g</span><span class="special">(</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">arg1</span>
<span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">arg1</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre><p>
</p><p>
</p><pre class="programlisting"><span class="identifier">g</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// OK...</span>
<span class="identifier">g</span><span class="special">(</span><span class="identifier">a</span><span class="special">);</span> <span class="comment">// ... and also OK.</span>
</pre><p>
</p></div><div class="section boost_utility_identitytype_abstract_types" title="Abstract Types"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.abstract_types"></a><a class="link" href="#boost_utility_identitytype.abstract_types" title="Abstract Types">Abstract Types</a></h2></div></div></div><p>
On some compilers (e.g., GCC), using this macro on abstract types (i.e., classes
with one or more pure virtual functions) generates a compiler error. This can
be avoided by manipulating the type adding and removing a reference to it.
</p><p>
Let's program a macro that performs a static assertion on a <a href="http://en.wikipedia.org/wiki/Template_metaprogramming" target="_top">Template
Meta-Programming</a> (TMP) meta-function (similarly to Boost.MPL <a href="http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/assert.html" target="_top"><code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span></code></a>). The <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro can be used
to pass a meta-function with multiple template parameters to the assert macro
(so to handle the commas separating the template parameters). In this case,
if the meta-function is an abstract type, it needs to be manipulated adding
and removing a reference to it (see also <a href="../../test/abstract.cpp" target="_top"><code class="literal">abstract.cpp</code></a>):
</p><p>
</p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TMP_ASSERT</span><span class="special">(</span><span class="identifier">metafunction</span><span class="special">)</span> <span class="special">\</span>
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">metafunction</span><span class="special">::</span><span class="identifier">value</span><span class="special">)</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">b</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">abstract</span> <span class="special">{</span>
<span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">b</span><span class="special">;</span>
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// Pure virtual function.</span>
<span class="special">};</span>
<span class="identifier">TMP_ASSERT</span><span class="special">(</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special">&lt;</span> <span class="comment">// Add and remove</span>
<span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span> <span class="comment">// reference for</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">add_reference</span><span class="special">&lt;</span> <span class="comment">// abstract type.</span>
<span class="identifier">abstract</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">true</span><span class="special">&gt;</span>
<span class="special">&gt;::</span><span class="identifier">type</span>
<span class="special">))</span>
<span class="special">&gt;::</span><span class="identifier">type</span>
<span class="special">);</span>
</pre><p>
</p></div><div class="section boost_utility_identitytype_annex__usage" title="Annex: Usage"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.annex__usage"></a><a class="link" href="#boost_utility_identitytype.annex__usage" title="Annex: Usage">Annex: Usage</a></h2></div></div></div><p>
The <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> macro
can be used either when calling a user-defined macro (as shown by the examples
so far), or internally when implementing a user-defined macro (as shown below).
When <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code> is
used in the implementation of the user-defined macro, the caller of the user
macro will have to specify the extra parenthesis (see also <a href="../../test/paren.cpp" target="_top"><code class="literal">paren.cpp</code></a>):
</p><p>
</p><pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">TMP_ASSERT_PAREN</span><span class="special">(</span><span class="identifier">parenthesized_metafunction</span><span class="special">)</span> <span class="special">\</span>
<span class="comment">/* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */</span> <span class="special">\</span>
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span><span class="identifier">parenthesized_metafunction</span><span class="special">)::</span><span class="identifier">value</span><span class="special">)</span>
<span class="preprocessor">#define</span> <span class="identifier">TMP_ASSERT</span><span class="special">(</span><span class="identifier">metafunction</span><span class="special">)</span> <span class="special">\</span>
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">metafunction</span><span class="special">::</span><span class="identifier">value</span><span class="special">)</span>
<span class="comment">// Specify only extra parenthesis `((...))`.</span>
<span class="identifier">TMP_ASSERT_PAREN</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&gt;));</span>
<span class="comment">// Specify both the extra parenthesis `((...))` and `BOOST_IDENTITY_TYPE` macro.</span>
<span class="identifier">TMP_ASSERT</span><span class="special">(</span><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&gt;)));</span>
</pre><p>
</p><p>
However, note that the caller will <span class="emphasis"><em>always</em></span> have to specify
the extra parenthesis even when the macro parameters contain no comma:
</p><p>
</p><pre class="programlisting"><span class="identifier">TMP_ASSERT_PAREN</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&gt;));</span> <span class="comment">// Always extra `((...))`.</span>
<span class="identifier">TMP_ASSERT</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&gt;);</span> <span class="comment">// No extra `((...))` and no macro.</span>
</pre><p>
</p><p>
In some cases, using <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
in the implementation of the user-defined macro might provide the best syntax
for the caller. For example, this is the case for <code class="computeroutput"><span class="identifier">BOOST_MPL_ASSERT</span></code>
because the majority of template meta-programming expressions contain unwrapped
commas so it is less confusing for the user to always specify the extra parenthesis
<code class="computeroutput"><span class="special">((...))</span></code> instead of using <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>:
</p><pre class="programlisting"><span class="identifier">BOOST_MPL_ASSERT</span><span class="special">((</span> <span class="comment">// Natural syntax.</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">and_</span><span class="special">&lt;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_const</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span>
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_reference</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span>
<span class="special">&gt;</span>
<span class="special">));</span>
</pre><p>
However, in other situations it might be preferable to not require the extra
parenthesis in the common cases and handle commas as special cases using <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>. For example, this
is the case for <a href="http://www.boost.org/libs/local_function" target="_top"><code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION</span></code></a> for which always
requiring the extra parenthesis <code class="computeroutput"><span class="special">((...))</span></code>
around the types would lead to an unnatural syntax for the local function signature:
</p><pre class="programlisting"><span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> <span class="special">((</span><span class="keyword">int</span><span class="special">&amp;))</span> <span class="identifier">x</span><span class="special">,</span> <span class="special">((</span><span class="keyword">int</span><span class="special">&amp;))</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">{</span> <span class="comment">// Unnatural syntax.</span>
<span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span>
<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span>
</pre><p>
Instead requiring the user to specify <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
only when needed allows for the more natural syntax <code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span>
<span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span></code> in the common cases when the parameter types
contain no comma (while still allowing to specify parameter types with commas
as special cases using <code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;))&amp;</span>
<span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span></code>).
</p></div><div class="section boost_utility_identitytype_annex__implementation" title="Annex: Implementation"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="boost_utility_identitytype.annex__implementation"></a><a class="link" href="#boost_utility_identitytype.annex__implementation" title="Annex: Implementation">Annex:
Implementation</a></h2></div></div></div><p>
The implementation of this library macro is equivalent to the following: <sup>[<a name="boost_utility_identitytype.annex__implementation.f0" href="#ftn.boost_utility_identitytype.annex__implementation.f0" class="footnote">3</a>]</sup>
</p><pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">function_traits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span><span class="identifier">parenthesized_type</span><span class="special">)</span> <span class="special">\</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">function_traits</span><span class="special">&lt;</span><span class="keyword">void</span> <span class="identifier">parenthesized_type</span><span class="special">&gt;::</span><span class="identifier">arg1_type</span>
</pre><p>
Essentially, the type is wrapped between round parenthesis <code class="computeroutput"><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span>
<span class="keyword">char</span><span class="special">&gt;)</span></code>
so it can be passed as a single macro parameter even if it contains commas.
Then the parenthesized type is transformed into the type of a function returning
<code class="computeroutput"><span class="keyword">void</span></code> and with the specified type
as the type of the first and only argument <code class="computeroutput"><span class="keyword">void</span>
<span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">&gt;)</span></code>. Finally, the type of the first argument
<code class="computeroutput"><span class="identifier">arg1_type</span></code> is extracted at compile-time
using the <code class="computeroutput"><span class="identifier">function_traits</span></code> meta-function
therefore obtaining the original type from the parenthesized type (effectively
stripping the extra parenthesis from around the specified type).
</p></div><div class="section reference" title="Reference"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="reference"></a>Reference</h2></div></div></div><div class="section header_boost_utility_identity_type_hpp" title="Header &lt;boost/utility/identity_type.hpp&gt;"><div class="titlepage"><div><div><h3 class="title"><a name="header.boost.utility.identity_type_hpp"></a>Header &lt;<a href="../../../../../boost/utility/identity_type.hpp" target="_top">boost/utility/identity_type.hpp</a>&gt;</h3></div></div></div><p>Wrap type expressions with round parenthesis so they can be passed to macros even if they contain commas. </p><pre class="synopsis">
<a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a>(parenthesized_type)</pre><div class="refentry" title="Macro BOOST_IDENTITY_TYPE"><a name="BOOST_IDENTITY_TYPE"></a><div class="titlepage"></div><div class="refnamediv"><h2><span class="refentrytitle">Macro BOOST_IDENTITY_TYPE</span></h2><p>BOOST_IDENTITY_TYPE — This macro allows to wrap the specified type expression within extra round parenthesis so the type can be passed as a single macro parameter even if it contains commas (not already wrapped within round parenthesis). </p></div><h2 class="refsynopsisdiv-title">Synopsis</h2><div class="refsynopsisdiv"><pre class="synopsis"><span class="comment">// In header: &lt;<a class="link" href="#header.boost.utility.identity_type_hpp" title="Header &lt;boost/utility/identity_type.hpp&gt;">boost/utility/identity_type.hpp</a>&gt;
</span>BOOST_IDENTITY_TYPE(parenthesized_type)</pre></div><div class="refsect1" title="Description"><a name="id554262"></a><h2>Description</h2><p><span class="bold"><strong>Parameters:</strong></span> </p><div class="informaltable"><table class="table"><colgroup><col><col></colgroup><tbody><tr><td><span class="bold"><strong><code class="computeroutput">parenthesized_type</code></strong></span></td><td>The type expression to be passed as macro parameter wrapped by a single set of round parenthesis <code class="computeroutput">(...)</code>. This type expression can contain an arbitrary number of commas. </td></tr></tbody></table></div><p>
</p><p>This macro works on any C++03 compiler (it does not use variadic macros).</p><p>This macro must be prefixed by <code class="computeroutput">typename</code> when used within templates. Note that the compiler will not be able to automatically determine function template parameters when they are wrapped with this macro (these parameters need to be explicitly specified when calling the function template).</p><p>On some compilers (like GCC), using this macro on abstract types requires to add and remove a reference to the specified type. </p></div></div></div></div><div class="footnotes"><br><hr width="100" align="left"><div class="footnote"><p><sup>[<a id="ftn.boost_utility_identitytype.solution.f0" href="#boost_utility_identitytype.solution.f0" class="para">1</a>] </sup>
Using variadic macros, it would be possible to require a single set of extra
parenthesis <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>type</em></span></code><code class="computeroutput"><span class="special">)</span></code> instead of two <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span></code><code class="literal"><span class="emphasis"><em>type</em></span></code><code class="computeroutput"><span class="special">))</span></code> but variadic macros are not part of C++03
(even if nowadays they are supported by most modern compilers and they are
also part of C++11).
</p></div><div class="footnote"><p><sup>[<a id="ftn.boost_utility_identitytype.templates.f0" href="#boost_utility_identitytype.templates.f0" class="para">2</a>] </sup>
This is because the implementation of <code class="computeroutput"><a class="link" href="#BOOST_IDENTITY_TYPE" title="Macro BOOST_IDENTITY_TYPE">BOOST_IDENTITY_TYPE</a></code>
wraps the specified type within a meta-function.
</p></div><div class="footnote"><p><sup>[<a id="ftn.boost_utility_identitytype.annex__implementation.f0" href="#boost_utility_identitytype.annex__implementation.f0" class="para">3</a>] </sup>
There is absolutely no guarantee that the macro is actually implemented using
the code listed in this documentation. The listed code is for explanatory
purposes only.
</p></div></div></div></body></html>

View File

@ -0,0 +1,165 @@
[/ Copyright (C) 2009-2012 Lorenzo Caminiti ]
[/ Distributed under the Boost Software License, Version 1.0 ]
[/ (see accompanying file LICENSE_1_0.txt or a copy at ]
[/ http://www.boost.org/LICENSE_1_0.txt) ]
[/ Home at http://www.boost.org/libs/utility/identity_type ]
[library Boost.Utility/IdentityType
[quickbook 1.5]
[version 1.0.0]
[copyright 2009-2012 Lorenzo Caminiti]
[purpose wraps types with round parenthesis]
[license
Distributed under the Boost Software License, Version 1.0
(see accompanying file LICENSE_1_0.txt or a copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
[authors [Caminiti <email>lorcaminiti@gmail.com</email>, Lorenzo]]
[category Utilities]
]
This library allows to wrap types within round parenthesis so they can always be passed as macro parameters.
[import ../test/var_error.cpp]
[import ../test/var.cpp]
[import ../test/template.cpp]
[import ../test/abstract.cpp]
[import ../test/paren.cpp]
[section Motivation]
Consider the following macro which declares a variable named `var`[^['n]] with the specified [^['type]] (see also [@../../test/var_error.cpp =var_error.cpp=]):
[var_error]
The first macro invocation works correctly declaring a variable named `var1` of type `int`.
However, the second macro invocation fails generating a preprocessor error similar to the following:
[pre
error: macro "VAR" passed 3 arguments, but takes just 2
]
That is because the `std::map` type passed as the first macro parameter contains a comma `,` not wrapped by round parenthesis `()`.
The preprocessor interprets that unwrapped comma as a separation between macro parameters concluding that a total of three (and not two) parameters are passed to the macro in the following order:
# `std::map<int`
# `char>`
# `2`
Note that, differently from the compiler, the preprocessor only recognizes round parenthesis `()`.
Angular `<>` and squared `[]` parenthesis are not recognized by the preprocessor when parsing macro parameters.
[endsect]
[section Solution]
In some cases, it might be possible to workaround this issue by avoiding to pass the type expression to the macro all together.
For example, in the case above a `typedef` could have been used to specify the type expression with the commas outside the macro (see also [@../../test/var.cpp =var.cpp=]):
[var_typedef]
When this is neither possible nor desired (e.g., see the function template `f` in the section below), this library header [headerref boost/utility/identity_type.hpp] defines a macro [macroref BOOST_IDENTITY_TYPE] which can be used to workaround the issue while keeping the type expression as one of the macro parameters (see also [@../../test/var.cpp =var.cpp=]).
[var_ok]
The [macroref BOOST_IDENTITY_TYPE] macro expands to an expression that evaluates (at compile-time) to the specified type.
The specified type is never split into multiple macro parameters because it is always wrapped by a set of extra round parenthesis `()`.
In fact, a total of two sets of round parenthesis must be used: The parenthesis to invoke the macro `BOOST_IDENTITY_TYPE(...)` plus the inner parenthesis to wrap the type passed to the macro `BOOST_IDENTITY_TYPE((...))`.
This macro works on any [@http://www.open-std.org/JTC1/SC22/WG21/docs/standards C++03] compiler (and it does not use [@http://en.wikipedia.org/wiki/Variadic_macro variadic macros]).
[footnote
Using variadic macros, it would be possible to require a single set of extra parenthesis `BOOST_IDENTITY_TYPE(`[^['type]]`)` instead of two `BOOST_IDENTITY_TYPE((`[^['type]]`))` but variadic macros are not part of C++03 (even if nowadays they are supported by most modern compilers and they are also part of C++11).
]
The authors originally developed and tested this library using GNU Compiler Collection (GCC) C++ 4.5.3 (with and without C++11 features enabled `-std=c++0x`) on Cygwin and Miscrosoft Visual C++ (MSVC) 8.0 on Windows 7.
See the library [@http://www.boost.org/development/tests/release/developer/utility-identity_type.html regressions test results] for more information on supported compilers and platforms.
[endsect]
[section Templates]
This macro must be prefixed by `typename` when used within templates.
For example, let's program a macro that declares a function parameter named `arg`[^['n]] with the specified [^['type]] (see also [@../../test/template.cpp =template.cpp=]):
[template_f_decl]
[template_f_call]
However, note that the template parameter `char` must be manually specified when invoking the function as in `f<char>(a)`.
In fact, when the [macroref BOOST_IDENTITY_TYPE] macro is used to wrap a function template parameter, the template parameter can no longer be automatically deduced by the compiler form the function call as `f(a)` would have done.
[footnote
This is because the implementation of [macroref BOOST_IDENTITY_TYPE] wraps the specified type within a meta-function.
]
(This limitation does not apply to class templates because class template parameters must always be explicitly specified.)
In other words, without using the [macroref BOOST_IDENTITY_TYPE] macro, C++ would normally be able to automatically deduce the function template parameter as shown below:
[template_g_decl]
[template_g_call]
[endsect]
[section Abstract Types]
On some compilers (e.g., GCC), using this macro on abstract types (i.e., classes with one or more pure virtual functions) generates a compiler error.
This can be avoided by manipulating the type adding and removing a reference to it.
Let's program a macro that performs a static assertion on a [@http://en.wikipedia.org/wiki/Template_metaprogramming Template Meta-Programming] (TMP) meta-function (similarly to Boost.MPL [@http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/refmanual/assert.html `BOOST_MPL_ASSERT`]).
The [macroref BOOST_IDENTITY_TYPE] macro can be used to pass a meta-function with multiple template parameters to the assert macro (so to handle the commas separating the template parameters).
In this case, if the meta-function is an abstract type, it needs to be manipulated adding and removing a reference to it (see also [@../../test/abstract.cpp =abstract.cpp=]):
[abstract]
[endsect]
[section Annex: Usage]
The [macroref BOOST_IDENTITY_TYPE] macro can be used either when calling a user-defined macro (as shown by the examples so far), or internally when implementing a user-defined macro (as shown below).
When [macroref BOOST_IDENTITY_TYPE] is used in the implementation of the user-defined macro, the caller of the user macro will have to specify the extra parenthesis (see also [@../../test/paren.cpp =paren.cpp=]):
[paren]
However, note that the caller will /always/ have to specify the extra parenthesis even when the macro parameters contain no comma:
[paren_always]
In some cases, using [macroref BOOST_IDENTITY_TYPE] in the implementation of the user-defined macro might provide the best syntax for the caller.
For example, this is the case for `BOOST_MPL_ASSERT` because the majority of template meta-programming expressions contain unwrapped commas so it is less confusing for the user to always specify the extra parenthesis `((...))` instead of using [macroref BOOST_IDENTITY_TYPE]:
BOOST_MPL_ASSERT(( // Natural syntax.
boost::mpl::and_<
boost::is_const<T>
, boost::is_reference<T>
>
));
However, in other situations it might be preferable to not require the extra parenthesis in the common cases and handle commas as special cases using [macroref BOOST_IDENTITY_TYPE].
For example, this is the case for [@http://www.boost.org/libs/local_function `BOOST_LOCAL_FUNCTION`] for which always requiring the extra parenthesis `((...))` around the types would lead to an unnatural syntax for the local function signature:
int BOOST_LOCAL_FUNCTION( ((int&)) x, ((int&)) y ) { // Unnatural syntax.
return x + y;
} BOOST_LOCAL_FUNCTION_NAME(add)
Instead requiring the user to specify [macroref BOOST_IDENTITY_TYPE] only when needed allows for the more natural syntax `BOOST_LOCAL_FUNCTION(int& x, int& y)` in the common cases when the parameter types contain no comma (while still allowing to specify parameter types with commas as special cases using `BOOST_LOCAL_FUNCTION(BOOST_IDENTITY_TYPE((std::map<int, char>))& x, int& y)`).
[endsect]
[section Annex: Implementation]
The implementation of this library macro is equivalent to the following:
[footnote
There is absolutely no guarantee that the macro is actually implemented using the code listed in this documentation.
The listed code is for explanatory purposes only.
]
#include <boost/type_traits/function_traits.hpp>
#define BOOST_IDENTITY_TYPE(parenthesized_type) \
boost::function_traits<void parenthesized_type>::arg1_type
Essentially, the type is wrapped between round parenthesis `(std::map<int, char>)` so it can be passed as a single macro parameter even if it contains commas.
Then the parenthesized type is transformed into the type of a function returning `void` and with the specified type as the type of the first and only argument `void (std::map<int, char>)`.
Finally, the type of the first argument `arg1_type` is extracted at compile-time using the `function_traits` meta-function therefore obtaining the original type from the parenthesized type (effectively stripping the extra parenthesis from around the specified type).
[endsect]
[xinclude reference.xml]

15
identity_type/index.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatic redirection failed, click this
<a href="doc/html/index.html">link</a> &nbsp;<hr>
<p><EFBFBD> Copyright Lorenzo Caminiti, 2009-2012</p>
<p>Distributed under the Boost Software License, Version 1.0 (see
accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or a copy at
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

View File

@ -0,0 +1,16 @@
# Copyright (C) 2009-2012 Lorenzo Caminiti
# Distributed under the Boost Software License, Version 1.0
# (see accompanying file LICENSE_1_0.txt or a copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Home at http://www.boost.org/libs/utility/identity_type
import testing ;
compile-fail var_error.cpp ;
run var.cpp ;
run template.cpp ;
run abstract.cpp ;
run noncopyable.cpp ;
run paren.cpp ;

View File

@ -0,0 +1,35 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/utility/identity_type
#include <boost/utility/identity_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/remove_reference.hpp>
//[abstract
#define TMP_ASSERT(metafunction) \
BOOST_STATIC_ASSERT(metafunction::value)
template<typename T, bool b>
struct abstract {
static const bool value = b;
virtual void f(T const& x) = 0; // Pure virtual function.
};
TMP_ASSERT(
boost::remove_reference< // Add and remove
BOOST_IDENTITY_TYPE(( // reference for
boost::add_reference< // abstract type.
abstract<int, true>
>::type
))
>::type
);
//]
int main() { return 0; }

View File

@ -0,0 +1,25 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/utility/identity_type
#include <boost/utility/identity_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
//[noncopyable
#define TMP_ASSERT(metafunction) \
BOOST_STATIC_ASSERT(metafunction::value)
template<typename T, T init>
struct noncopyable : boost::noncopyable {
static const T value = init;
};
TMP_ASSERT(BOOST_IDENTITY_TYPE((noncopyable<bool, true>)));
//]
int main() { return 0; }

View File

@ -0,0 +1,35 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/utility/identity_type
#include <boost/utility/identity_type.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_const.hpp>
#include <map>
//[paren
#define TMP_ASSERT_PAREN(parenthesized_metafunction) \
/* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */ \
BOOST_STATIC_ASSERT(BOOST_IDENTITY_TYPE(parenthesized_metafunction)::value)
#define TMP_ASSERT(metafunction) \
BOOST_STATIC_ASSERT(metafunction::value)
// Specify only extra parenthesis `((...))`.
TMP_ASSERT_PAREN((boost::is_const<std::map<int, char> const>));
// Specify both the extra parenthesis `((...))` and `BOOST_IDENTITY_TYPE` macro.
TMP_ASSERT(BOOST_IDENTITY_TYPE((boost::is_const<std::map<int, char> const>)));
//]
//[paren_always
TMP_ASSERT_PAREN((boost::is_const<int const>)); // Always extra `((...))`.
TMP_ASSERT(boost::is_const<int const>); // No extra `((...))` and no macro.
//]
int main() { return 0; }

View File

@ -0,0 +1,48 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/utility/identity_type
#include <boost/utility/identity_type.hpp>
#include <map>
#include <iostream>
//[template_f_decl
#define ARG(type, n) type arg ## n
template<typename T>
void f( // Prefix macro with `typename` in templates.
ARG(typename BOOST_IDENTITY_TYPE((std::map<int, T>)), 1)
) {
std::cout << arg1[0] << std::endl;
}
//]
//[template_g_decl
template<typename T>
void g(
std::map<int, T> arg1
) {
std::cout << arg1[0] << std::endl;
}
//]
int main() {
//[template_f_call
std::map<int, char> a;
a[0] = 'a';
f<char>(a); // OK...
// f(a); // ... but error.
//]
//[template_g_call
g<char>(a); // OK...
g(a); // ... and also OK.
//]
return 0;
}

View File

@ -0,0 +1,26 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/utility/identity_type
#include <map>
#define VAR(type, n) type var ## n
VAR(int, 1); // OK.
//[var_typedef
typedef std::map<int, char> map_type;
VAR(map_type, 3); // OK.
//]
//[var_ok
#include <boost/utility/identity_type.hpp>
VAR(BOOST_IDENTITY_TYPE((std::map<int, char>)), 4); // OK.
//]
int main() { return 0; }

View File

@ -0,0 +1,18 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/utility/identity_type
#include <map>
//[var_error
#define VAR(type, n) type var ## n
VAR(int, 1); // OK.
VAR(std::map<int, char>, 2); // Error.
//]
int main() { return 0; }

296
in_place_factories.html Normal file
View File

@ -0,0 +1,296 @@
<!DOCTYPE HTML PUBLIC "-//SoftQuad Software//DTD HoTMetaL PRO 5.0::19981217::extensions to HTML 4.0//EN" "hmpro5.dtd">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<TITLE>In_place_factory Documentation</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080">
<H2 align="left"><IMG SRC="../../boost.png" WIDTH="276" HEIGHT="86"></H2>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<blockquote>
<H2 align="left">Header &lt;<A
HREF="../../boost/utility/in_place_factory.hpp">boost/utility/in_place_factory.hpp</A>&gt; </H2>
<H2 align="left">Header &lt;<A
HREF="../../boost/utility/typed_in_place_factory.hpp">boost/utility/typed_in_place_factory.hpp</A>&gt; </H2>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
<p>&nbsp;</p>
<H2>Contents</H2>
<DL CLASS="page-index">
<DT><A HREF="#mot">Motivation</A></DT>
<DT><A HREF="#framework">Framework</A></DT>
<DT><A HREF="#specification">Specification</A></DT>
<DT><A HREF="#container-usage">Container-side Usage</A></DT>
<DT><A HREF="#user-usage">User-side Usage</A></DT>
</DL>
<HR>
<H2><A NAME="mot"></A>Motivation</H2>
<p>Suppose we have a class</p>
<pre>struct X
{
X ( int, std::string ) ;
} ;</pre>
<p>And a container for it which supports an empty state (that is, which can contain zero objects):</p>
<pre>struct C
{
C() : contained_(0) {}
~C() { delete contained_ ; }
X* contained_ ;
} ;</pre>
<p>A container designed to support an empty state typically doesn't require the contained type to be DefaultConstructible,
but it typically requires it to be CopyConstructible as a mechanism to
initialize the object to store:</p>
<pre>struct C
{
C() : contained_(0) {}
C ( X const& v ) : contained_ ( new X(v) ) {}
~C() { delete contained_ ; }
X* contained_ ;
} ;</pre>
<p>There is a subtle problem with this: since the mechanism used to initialize the stored object is copy construction,
there must exist a previously constructed source object to copy from. This
object is likely to be temporary and serve no purpose besides being the source</p>
<pre>void foo()
{
// Temporary object created.
C c( X(123,"hello") ) ;
}
</pre>
<p>A solution to this problem is to support direct construction of the contained
object right in the container's storage.<br>
In this scheme, the user supplies the arguments for the X constructor
directly to the container:</p>
<pre>struct C
{
C() : contained_(0) {}
C ( X const& v ) : contained_ ( new X(v) ) {}
C ( int a0, std::string a1 ) : contained_ ( new X(a0,a1) ) {}
~C() { delete contained_ ; }
X* contained_ ;
} ;</pre>
<pre>void foo()
{
// Wrapped object constructed in-place
// No temporary created.
C c(123,"hello") ;
}
</pre>
<p>Clearly, this solution doesn't scale well since the container must duplicate all the constructor overloads from the contained type
(at least all those which are to be supported directly in the container).</p>
<H2><A NAME="framework"></A>Framework</H2>
<p>
This library proposes a framework to allow some containers to directly contruct contained objects in-place without requiring
the entire set of constructor overloads from the contained type. It also allows the container to remove the CopyConstuctible
requirement from the contained type since objects can be directly constructed in-place without need of a copy.<br>
The only requirement on the container is that it must provide proper storage (that is, correctly aligned and sized).
Naturally, the container will typically support uninitialized storage to avoid the in-place construction to override
a fully-constructed object (as this would defeat the purpose of in-place construction)
</p>
<p>For this purpose, the framework provides two families of classes collectively called: InPlaceFactories and TypedInPlaceFactories.<br>
Essentially, these classes hold a sequence of actual parameters and a method to contruct an object in place using these parameters.
Each member of the family differs only in the number (and type) of the parameter list. The first family
takes the type of the object to construct directly in method provided for that
purpose, whereas the second family incorporates that type in the factory class
itself..</p>
<p>From the container POV, using the framework amounts to calling the factory's method to contruct the object in place.
From the user POV, it amounts to creating the right factory object to hold the parameters and pass it to the container.<br>
The following simplified example shows the basic idea. A complete example follows the formal specification of the framework:</p>
<pre>struct C
{
template&lt;class InPlaceFactory&gt;
C ( InPlaceFactory const& aFactory )
:
contained_ ( uninitialized_storage() )
{
aFactory.template apply&lt;X&gt;(contained_);
}
~C()
{
contained_ -> X::~X();
delete[] contained_ ;
}
char* uninitialized_storage() { return new char[sizeof(X)] ; }
char* contained_ ;
} ;
void foo()
{
C c( in_place(123,"hello") ) ;
}
</pre>
<HR>
<H2><A NAME="specification">Specification</A></H2>
<p>The following is the first member of the family of 'in_place_factory' classes, along with its corresponding helper template function.
The rest of the family varies only in the number and type of template (and constructor) parameters.</p>
<PRE>namespace boost {
struct in_place_factory_base {} ;
template&lt;class A0&gt;
class in_place_factory : public in_place_factory_base
{
public:</PRE>
<PRE> in_place_factory ( A0 const& a0 ) : m_a0(a0) {}
template&lt; class T &gt;
void apply ( void* address ) const
{
new (address) T(m_a0);
}
private:</PRE>
<PRE> A0 const& m_a0 ;
} ;
template&lt;class A0&gt;
in_place_factory&lt;A0&gt; in_place ( A0 const& a0 )
{
return in_place_factory&lt;A0&gt;(a0);
}
</PRE>
<p>Similarly, the following is the first member of the family of 'typed_in_place_factory' classes, along with its corresponding
helper template function. The rest of the family varies only in the number and type of template (and constructor) parameters.</p>
<PRE>namespace boost {
struct typed_in_place_factory_base {} ;
template&lt;class T, class A0&gt;
class typed_in_place_factory : public typed_in_place_factory_base
{
public:</PRE>
<PRE> typed_in_place_factory ( A0 const& a0 ) : m_a0(a0) {}
void apply ( void* address ) const
{
new (address) T(m_a0);
}
private:</PRE>
<PRE> A0 const& m_a0 ;
} ;
template&lt;class T, class A0&gt;
typed_in_place_factory&lt;A0&gt; in_place ( A0 const& a0 )
{
return typed_in_place_factory&lt;T,A0&gt;(a0);
}</PRE>
<PRE>}
</PRE>
<p>As you can see, the 'in_place_factory' and 'typed_in_place_factory' template classes varies only in the way they specify
the target type: in the first family, the type is given as a template argument to the apply member function while in the
second it is given directly as part of the factory class.<br>
When the container holds a unique non-polymorphic type (such as the case of Boost.Optional), it knows the exact dynamic-type
of the contained object and can pass it to the apply() method of a (non-typed) factory.
In this case, end users can use an 'in_place_factory' instance which can be constructed without the type of the object to construct.<br>
However, if the container holds heterogeneous or polymorphic objects (such as the case of Boost.Variant), the dynamic-type
of the object to be constructed must be known by the factory itslef. In this case, end users must use a 'typed_in_place_factory'
instead.</p>
<HR>
<h2><A NAME="container-usage">Container-side Usage</a></h2>
<p>As shown in the introductory simplified example, the container class must
contain methods that accept an instance of
these factories and pass the object's storage to the factory's apply method.<br>
However, the type of the factory class cannot be completly specified in the container class because that would
defeat the whole purpose of the factories which is to allow the container to accept a variadic argument list
for the constructor of its contained object.<br>
The correct function overload must be based on the only distinctive and common
characteristic of all the classes in each family, the base class.<br>
Depending on the container class, you can use 'enable_if' to generate the right overload, or use the following
dispatch technique (used in the Boost.Optional class):
</p>
<pre>struct C
{
C() : contained_(0) {}
C ( X const& v ) : contained_ ( new X(v) ) {}
template&lt;class Expr&gt
C ( Expr const& expr )
:
contained_ ( uninitialized_storage() )
{
construct(expr,&expr)
}
~C() { delete contained_ ; }
template&lt;class InPlaceFactory&gt;
void construct ( InPlaceFactory const& aFactory, boost::in_place_factory_base* )
{
aFactory.template apply&lt;X&gt;(contained_);
}
template&lt;class TypedInPlaceFactory&gt;
void construct ( TypedInPlaceFactory const& aFactory, boost::typed_in_place_factory_base* )
{
aFactory.apply(contained_);
}
X* uninitialized_storage() { return static_cast&lt;X*&gt;(new char[sizeof(X)]) ; }
X* contained_ ;
} ;
</pre>
<hr>
<h2><A NAME="user-usage">User-side Usage</a></h2>
<p>End users pass to the container an instance of a factory object holding the actual parameters needed to construct the
contained object directly within the container. For this, the helper template function 'in_place' is used.<br>
The call 'in_place(a0,a1,a2,...,an)' constructs a (non-typed) 'in_place_factory' instance with the given argument list.<br>
The call 'in_place&lt;T&gt;(a0,a1,a2,...,an)' constructs a 'typed_in_place_factory' instance with the given argument list for the
type 'T'.</p>
<pre>void foo()
{
C a( in_place(123,"hello") ) ; // in_place_factory passed
C b( in_place&lt;X&gt;(456,"world") ) ; // typed_in_place_factory passed
}
</pre>
<P>Revised September 17, 2004</P>
<p><EFBFBD> Copyright Fernando Luis Cacciola Carballal, 2004</p>
<p> Use, modification, and distribution are subject to the Boost Software
License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
www.boost.org/LICENSE_1_0.txt</a>)</p>
<P>Developed by <A HREF="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</A>,
the latest version of this file can be found at <A
HREF="http://www.boost.org">www.boost.org</A>, and the boost
<A HREF="http://www.boost.org/more/mailing_lists.htm#main">discussion lists</A></P>
</BODY>
</HTML>

View File

@ -1,10 +1,11 @@
// (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// See http://www.boost.org/libs/utility for most recent version including documentation.
// See http://www.boost.org for most recent version including documentation.
// See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp
// See boost/detail/call_traits.hpp
// for full copyright notices.
#ifndef BOOST_CALL_TRAITS_HPP
@ -14,10 +15,6 @@
#include <boost/config.hpp>
#endif
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/detail/ob_call_traits.hpp>
#else
#include <boost/detail/call_traits.hpp>
#endif
#endif // BOOST_CALL_TRAITS_HPP

View File

@ -1,10 +1,11 @@
// (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// See http://www.boost.org/libs/utility for most recent version including documentation.
// See http://www.boost.org for most recent version including documentation.
// See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp
// See boost/detail/compressed_pair.hpp
// for full copyright notices.
#ifndef BOOST_COMPRESSED_PAIR_HPP
@ -14,10 +15,6 @@
#include <boost/config.hpp>
#endif
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/detail/ob_compressed_pair.hpp>
#else
#include <boost/detail/compressed_pair.hpp>
#endif
#endif // BOOST_COMPRESSED_PAIR_HPP

View File

@ -1,10 +1,9 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// See http://www.boost.org/libs/utility for most recent version including documentation.
// call_traits: defines typedefs for function usage
// (see libs/utility/call_traits.htm)
@ -22,31 +21,51 @@
#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
#include <cstddef>
#ifndef BOOST_TYPE_TRAITS_HPP
#include <boost/type_traits.hpp>
#endif
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/detail/workaround.hpp>
namespace boost{
namespace detail{
template <typename T, bool small_>
struct ct_imp2
{
typedef const T& param_type;
};
template <typename T>
struct ct_imp2<T, true>
{
typedef const T param_type;
};
template <typename T, bool isp, bool b1, bool b2>
struct ct_imp
{
typedef const T& param_type;
};
template <typename T, bool isp>
struct ct_imp<T, isp, true, true>
template <typename T, bool isp, bool b2>
struct ct_imp<T, isp, true, b2>
{
typedef T const param_type;
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
};
template <typename T, bool isp, bool b1>
struct ct_imp<T, isp, b1, true>
{
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
};
template <typename T, bool b1, bool b2>
struct ct_imp<T, true, b1, b2>
{
typedef T const param_type;
typedef const T param_type;
};
}
@ -64,7 +83,12 @@ public:
// however compiler bugs prevent this - instead pass three bool's to
// ct_imp<T,bool,bool,bool> and add an extra partial specialisation
// of ct_imp to handle the logic. (JM)
typedef typename detail::ct_imp<T, ::boost::is_pointer<typename remove_const<T>::type>::value, ::boost::is_arithmetic<typename remove_const<T>::type>::value, sizeof(T) <= sizeof(void*)>::param_type param_type;
typedef typename boost::detail::ct_imp<
T,
::boost::is_pointer<T>::value,
::boost::is_arithmetic<T>::value,
::boost::is_enum<T>::value
>::param_type param_type;
};
template <typename T>
@ -76,7 +100,7 @@ struct call_traits<T&>
typedef T& param_type; // hh removed const
};
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
#if BOOST_WORKAROUND( __BORLANDC__, < 0x5A0 )
// these are illegal specialisations; cv-qualifies applied to
// references have no effect according to [8.3.2p1],
// C++ Builder requires them though as it treats cv-qualified
@ -105,8 +129,17 @@ struct call_traits<T&const volatile>
typedef const T& const_reference;
typedef T& param_type; // hh removed const
};
#endif
template <typename T>
struct call_traits< T * >
{
typedef T * value_type;
typedef T * & reference;
typedef T * const & const_reference;
typedef T * const param_type; // hh removed const
};
#endif
#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
template <typename T, std::size_t N>
struct call_traits<T [N]>
{
@ -132,6 +165,7 @@ public:
typedef const array_type& const_reference;
typedef const T* const param_type;
};
#endif
}

View File

@ -1,14 +1,16 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// See http://www.boost.org/libs/utility for most recent version including documentation.
// compressed_pair: pair that "compresses" empty members
// (see libs/utility/compressed_pair.htm)
// (see libs/utility/doc/html/compressed_pair.html)
//
// JM changes 25 Jan 2004:
// For the case where T1 == T2 and both are empty, then first() and second()
// should return different objects.
// JM changes 25 Jan 2000:
// Removed default arguments from compressed_pair_switch to get
// C++ Builder 4 to accept them
@ -19,16 +21,23 @@
#define BOOST_DETAIL_COMPRESSED_PAIR_HPP
#include <algorithm>
#ifndef BOOST_TYPE_TRAITS_HPP
#include <boost/type_traits.hpp>
#endif
#ifndef BOOST_CALL_TRAITS_HPP
#include <boost/call_traits.hpp>
#endif
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/is_empty.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/call_traits.hpp>
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable:4512)
#endif
namespace boost
{
template <class T1, class T2>
class compressed_pair;
// compressed_pair
namespace details
@ -75,7 +84,9 @@ namespace details
template <typename T>
inline void cp_swap(T& t1, T& t2)
{
#ifndef __GNUC__
using std::swap;
#endif
swap(t1, t2);
}
@ -99,10 +110,10 @@ namespace details
compressed_pair_imp(first_param_type x, second_param_type y)
: first_(x), second_(y) {}
explicit compressed_pair_imp(first_param_type x)
compressed_pair_imp(first_param_type x)
: first_(x) {}
explicit compressed_pair_imp(second_param_type y)
compressed_pair_imp(second_param_type y)
: second_(y) {}
first_reference first() {return first_;}
@ -111,10 +122,10 @@ namespace details
second_reference second() {return second_;}
second_const_reference second() const {return second_;}
void swap(compressed_pair_imp& y)
void swap(::boost::compressed_pair<T1, T2>& y)
{
cp_swap(first_, y.first_);
cp_swap(second_, y.second_);
cp_swap(first_, y.first());
cp_swap(second_, y.second());
}
private:
first_type first_;
@ -125,7 +136,7 @@ namespace details
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 1>
: private T1
: protected ::boost::remove_cv<T1>::type
{
public:
typedef T1 first_type;
@ -142,10 +153,10 @@ namespace details
compressed_pair_imp(first_param_type x, second_param_type y)
: first_type(x), second_(y) {}
explicit compressed_pair_imp(first_param_type x)
compressed_pair_imp(first_param_type x)
: first_type(x) {}
explicit compressed_pair_imp(second_param_type y)
compressed_pair_imp(second_param_type y)
: second_(y) {}
first_reference first() {return *this;}
@ -154,10 +165,10 @@ namespace details
second_reference second() {return second_;}
second_const_reference second() const {return second_;}
void swap(compressed_pair_imp& y)
void swap(::boost::compressed_pair<T1,T2>& y)
{
// no need to swap empty base class:
cp_swap(second_, y.second_);
cp_swap(second_, y.second());
}
private:
second_type second_;
@ -167,7 +178,7 @@ namespace details
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 2>
: private T2
: protected ::boost::remove_cv<T2>::type
{
public:
typedef T1 first_type;
@ -184,10 +195,10 @@ namespace details
compressed_pair_imp(first_param_type x, second_param_type y)
: second_type(y), first_(x) {}
explicit compressed_pair_imp(first_param_type x)
compressed_pair_imp(first_param_type x)
: first_(x) {}
explicit compressed_pair_imp(second_param_type y)
compressed_pair_imp(second_param_type y)
: second_type(y) {}
first_reference first() {return first_;}
@ -196,10 +207,10 @@ namespace details
second_reference second() {return *this;}
second_const_reference second() const {return *this;}
void swap(compressed_pair_imp& y)
void swap(::boost::compressed_pair<T1,T2>& y)
{
// no need to swap empty base class:
cp_swap(first_, y.first_);
cp_swap(first_, y.first());
}
private:
@ -210,8 +221,8 @@ namespace details
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 3>
: private T1,
private T2
: protected ::boost::remove_cv<T1>::type,
protected ::boost::remove_cv<T2>::type
{
public:
typedef T1 first_type;
@ -228,10 +239,10 @@ namespace details
compressed_pair_imp(first_param_type x, second_param_type y)
: first_type(x), second_type(y) {}
explicit compressed_pair_imp(first_param_type x)
compressed_pair_imp(first_param_type x)
: first_type(x) {}
explicit compressed_pair_imp(second_param_type y)
compressed_pair_imp(second_param_type y)
: second_type(y) {}
first_reference first() {return *this;}
@ -241,16 +252,19 @@ namespace details
second_const_reference second() const {return *this;}
//
// no need to swap empty bases:
void swap(compressed_pair_imp&) {}
void swap(::boost::compressed_pair<T1,T2>&) {}
};
// JM
// 4 T1 == T2, T1 and T2 both empty
// Note does not actually store an instance of T2 at all -
// but reuses T1 base class for both first() and second().
// Originally this did not store an instance of T2 at all
// but that led to problems beause it meant &x.first() == &x.second()
// which is not true for any other kind of pair, so now we store an instance
// of T2 just in case the user is relying on first() and second() returning
// different objects (albeit both empty).
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 4>
: private T1
: protected ::boost::remove_cv<T1>::type
{
public:
typedef T1 first_type;
@ -264,20 +278,21 @@ namespace details
compressed_pair_imp() {}
compressed_pair_imp(first_param_type x, second_param_type)
: first_type(x) {}
compressed_pair_imp(first_param_type x, second_param_type y)
: first_type(x), m_second(y) {}
explicit compressed_pair_imp(first_param_type x)
: first_type(x) {}
compressed_pair_imp(first_param_type x)
: first_type(x), m_second(x) {}
first_reference first() {return *this;}
first_const_reference first() const {return *this;}
second_reference second() {return *this;}
second_const_reference second() const {return *this;}
second_reference second() {return m_second;}
second_const_reference second() const {return m_second;}
void swap(compressed_pair_imp&) {}
void swap(::boost::compressed_pair<T1,T2>&) {}
private:
T2 m_second;
};
// 5 T1 == T2 and are not empty: //JM
@ -300,7 +315,7 @@ namespace details
compressed_pair_imp(first_param_type x, second_param_type y)
: first_(x), second_(y) {}
explicit compressed_pair_imp(first_param_type x)
compressed_pair_imp(first_param_type x)
: first_(x), second_(x) {}
first_reference first() {return first_;}
@ -309,10 +324,10 @@ namespace details
second_reference second() {return second_;}
second_const_reference second() const {return second_;}
void swap(compressed_pair_imp<T1, T2, 5>& y)
void swap(::boost::compressed_pair<T1, T2>& y)
{
cp_swap(first_, y.first_);
cp_swap(second_, y.second_);
cp_swap(first_, y.first());
cp_swap(second_, y.second());
}
private:
first_type first_;
@ -396,7 +411,10 @@ public:
compressed_pair() : base() {}
compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
explicit compressed_pair(first_param_type x) : base(x) {}
#if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530))
explicit
#endif
compressed_pair(first_param_type x) : base(x) {}
first_reference first() {return base::first();}
first_const_reference first() const {return base::first();}
@ -404,7 +422,7 @@ public:
second_reference second() {return base::second();}
second_const_reference second() const {return base::second();}
void swap(compressed_pair& y) { base::swap(y); }
void swap(::boost::compressed_pair<T,T>& y) { base::swap(y); }
};
template <class T1, class T2>
@ -417,6 +435,9 @@ swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
} // boost
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP

View File

@ -1,36 +0,0 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
//
// Crippled version for crippled compilers:
// see libs/utility/call_traits.htm
//
#ifndef BOOST_OB_CALL_TRAITS_HPP
#define BOOST_OB_CALL_TRAITS_HPP
#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
#ifndef BOOST_TYPE_TRAITS_HPP
#include <boost/type_traits.hpp>
#endif
namespace boost{
template <typename T>
struct call_traits
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T& param_type;
};
}
#endif // BOOST_OB_CALL_TRAITS_HPP

View File

@ -1,13 +1,18 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// See http://www.boost.org/libs/utility for most recent version including documentation.
// see libs/utility/compressed_pair.hpp
//
/* Release notes:
20 Jan 2001:
Fixed obvious bugs (David Abrahams)
07 Oct 2000:
Added better single argument constructor support.
03 Oct 2000:
Added VC6 support (JM).
23rd July 2000:
Additional comments added. (JM)
Jan 2000:
@ -20,8 +25,11 @@
#define BOOST_OB_COMPRESSED_PAIR_HPP
#include <algorithm>
#ifndef BOOST_TYPE_TRAITS_HPP
#include <boost/type_traits.hpp>
#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
#include <boost/type_traits/object_traits.hpp>
#endif
#ifndef BOOST_SAME_TRAITS_HPP
#include <boost/type_traits/same_traits.hpp>
#endif
#ifndef BOOST_CALL_TRAITS_HPP
#include <boost/call_traits.hpp>
@ -29,6 +37,415 @@
namespace boost
{
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
//
// use member templates to emulate
// partial specialisation. Note that due to
// problems with overload resolution with VC6
// each of the compressed_pair versions that follow
// have one template single-argument constructor
// in place of two specific constructors:
//
template <class T1, class T2>
class compressed_pair;
namespace detail{
template <class A, class T1, class T2>
struct best_conversion_traits
{
typedef char one;
typedef char (&two)[2];
static A a;
static one test(T1);
static two test(T2);
enum { value = sizeof(test(a)) };
};
template <int>
struct init_one;
template <>
struct init_one<1>
{
template <class A, class T1, class T2>
static void init(const A& a, T1* p1, T2*)
{
*p1 = a;
}
};
template <>
struct init_one<2>
{
template <class A, class T1, class T2>
static void init(const A& a, T1*, T2* p2)
{
*p2 = a;
}
};
// T1 != T2, both non-empty
template <class T1, class T2>
class compressed_pair_0
{
private:
T1 _first;
T2 _second;
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_0() : _first(), _second() {}
compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
template <class A>
explicit compressed_pair_0(const A& val)
{
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
}
compressed_pair_0(const ::boost::compressed_pair<T1,T2>& x)
: _first(x.first()), _second(x.second()) {}
#if 0
compressed_pair_0& operator=(const compressed_pair_0& x) {
cout << "assigning compressed pair 0" << endl;
_first = x._first;
_second = x._second;
cout << "finished assigning compressed pair 0" << endl;
return *this;
}
#endif
first_reference first() { return _first; }
first_const_reference first() const { return _first; }
second_reference second() { return _second; }
second_const_reference second() const { return _second; }
void swap(compressed_pair_0& y)
{
using std::swap;
swap(_first, y._first);
swap(_second, y._second);
}
};
// T1 != T2, T2 empty
template <class T1, class T2>
class compressed_pair_1 : T2
{
private:
T1 _first;
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_1() : T2(), _first() {}
compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}
template <class A>
explicit compressed_pair_1(const A& val)
{
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
}
compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
: T2(x.second()), _first(x.first()) {}
first_reference first() { return _first; }
first_const_reference first() const { return _first; }
second_reference second() { return *this; }
second_const_reference second() const { return *this; }
void swap(compressed_pair_1& y)
{
// no need to swap empty base class:
using std::swap;
swap(_first, y._first);
}
};
// T1 != T2, T1 empty
template <class T1, class T2>
class compressed_pair_2 : T1
{
private:
T2 _second;
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_2() : T1(), _second() {}
compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
template <class A>
explicit compressed_pair_2(const A& val)
{
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
}
compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
: T1(x.first()), _second(x.second()) {}
#if 0
compressed_pair_2& operator=(const compressed_pair_2& x) {
cout << "assigning compressed pair 2" << endl;
T1::operator=(x);
_second = x._second;
cout << "finished assigning compressed pair 2" << endl;
return *this;
}
#endif
first_reference first() { return *this; }
first_const_reference first() const { return *this; }
second_reference second() { return _second; }
second_const_reference second() const { return _second; }
void swap(compressed_pair_2& y)
{
// no need to swap empty base class:
using std::swap;
swap(_second, y._second);
}
};
// T1 != T2, both empty
template <class T1, class T2>
class compressed_pair_3 : T1, T2
{
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_3() : T1(), T2() {}
compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
template <class A>
explicit compressed_pair_3(const A& val)
{
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
}
compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
: T1(x.first()), T2(x.second()) {}
first_reference first() { return *this; }
first_const_reference first() const { return *this; }
second_reference second() { return *this; }
second_const_reference second() const { return *this; }
void swap(compressed_pair_3& y)
{
// no need to swap empty base classes:
}
};
// T1 == T2, and empty
template <class T1, class T2>
class compressed_pair_4 : T1
{
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_4() : T1() {}
compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
// only one single argument constructor since T1 == T2
explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
: T1(x.first()), m_second(x.second()) {}
first_reference first() { return *this; }
first_const_reference first() const { return *this; }
second_reference second() { return m_second; }
second_const_reference second() const { return m_second; }
void swap(compressed_pair_4& y)
{
// no need to swap empty base classes:
}
private:
T2 m_second;
};
// T1 == T2, not empty
template <class T1, class T2>
class compressed_pair_5
{
private:
T1 _first;
T2 _second;
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_5() : _first(), _second() {}
compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
// only one single argument constructor since T1 == T2
explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c)
: _first(c.first()), _second(c.second()) {}
first_reference first() { return _first; }
first_const_reference first() const { return _first; }
second_reference second() { return _second; }
second_const_reference second() const { return _second; }
void swap(compressed_pair_5& y)
{
using std::swap;
swap(_first, y._first);
swap(_second, y._second);
}
};
template <bool e1, bool e2, bool same>
struct compressed_pair_chooser
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_0<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<false, true, false>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_1<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<true, false, false>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_2<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<true, true, false>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_3<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<true, true, true>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_4<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<false, false, true>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_5<T1, T2> type;
};
};
template <class T1, class T2>
struct compressed_pair_traits
{
private:
typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
typedef typename chooser::template rebind<T1, T2> bound_type;
public:
typedef typename bound_type::type type;
};
} // namespace detail
template <class T1, class T2>
class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
{
private:
typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
public:
typedef T1 first_type;
typedef T2 second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair() : base_type() {}
compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
template <class A>
explicit compressed_pair(const A& x) : base_type(x){}
first_reference first() { return base_type::first(); }
first_const_reference first() const { return base_type::first(); }
second_reference second() { return base_type::second(); }
second_const_reference second() const { return base_type::second(); }
};
template <class T1, class T2>
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
{
x.swap(y);
}
#else
// no partial specialisation, no member templates:
template <class T1, class T2>
class compressed_pair
@ -72,7 +489,11 @@ inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
x.swap(y);
}
#endif
} // boost
#endif // BOOST_OB_COMPRESSED_PAIR_HPP

View File

@ -0,0 +1,165 @@
// Boost next_prior.hpp header file ---------------------------------------//
// (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/utility for documentation.
// Revision History
// 13 Dec 2003 Added next(x, n) and prior(x, n) (Daniel Walker)
#ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED
#define BOOST_NEXT_PRIOR_HPP_INCLUDED
#include <iterator>
#if defined(_MSC_VER) && _MSC_VER <= 1310
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_integral.hpp>
#endif
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/type_traits/integral_promotion.hpp>
#include <boost/type_traits/make_signed.hpp>
#include <boost/type_traits/has_plus.hpp>
#include <boost/type_traits/has_plus_assign.hpp>
#include <boost/type_traits/has_minus.hpp>
#include <boost/type_traits/has_minus_assign.hpp>
namespace boost {
// Helper functions for classes like bidirectional iterators not supporting
// operator+ and operator-
//
// Usage:
// const std::list<T>::iterator p = get_some_iterator();
// const std::list<T>::iterator prev = boost::prior(p);
// const std::list<T>::iterator next = boost::next(prev, 2);
// Contributed by Dave Abrahams
namespace next_prior_detail {
template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value >
struct next_impl2
{
static T call(T x, Distance n)
{
std::advance(x, n);
return x;
}
};
template< typename T, typename Distance >
struct next_impl2< T, Distance, true >
{
static T call(T x, Distance n)
{
return x + n;
}
};
template< typename T, typename Distance, bool HasPlusAssign = has_plus_assign< T, Distance >::value >
struct next_impl1 :
public next_impl2< T, Distance >
{
};
template< typename T, typename Distance >
struct next_impl1< T, Distance, true >
{
static T call(T x, Distance n)
{
x += n;
return x;
}
};
template<
typename T,
typename Distance,
typename PromotedDistance = typename integral_promotion< Distance >::type,
#if !defined(_MSC_VER) || _MSC_VER > 1310
bool IsUInt = is_unsigned< PromotedDistance >::value
#else
// MSVC 7.1 has problems with applying is_unsigned to non-integral types
bool IsUInt = mpl::and_< is_integral< PromotedDistance >, is_unsigned< PromotedDistance > >::value
#endif
>
struct prior_impl3
{
static T call(T x, Distance n)
{
std::advance(x, -n);
return x;
}
};
template< typename T, typename Distance, typename PromotedDistance >
struct prior_impl3< T, Distance, PromotedDistance, true >
{
static T call(T x, Distance n)
{
typedef typename make_signed< PromotedDistance >::type signed_distance;
std::advance(x, -static_cast< signed_distance >(static_cast< PromotedDistance >(n)));
return x;
}
};
template< typename T, typename Distance, bool HasMinus = has_minus< T, Distance >::value >
struct prior_impl2 :
public prior_impl3< T, Distance >
{
};
template< typename T, typename Distance >
struct prior_impl2< T, Distance, true >
{
static T call(T x, Distance n)
{
return x - n;
}
};
template< typename T, typename Distance, bool HasMinusAssign = has_minus_assign< T, Distance >::value >
struct prior_impl1 :
public prior_impl2< T, Distance >
{
};
template< typename T, typename Distance >
struct prior_impl1< T, Distance, true >
{
static T call(T x, Distance n)
{
x -= n;
return x;
}
};
} // namespace next_prior_detail
template <class T>
inline T next(T x) { return ++x; }
template <class T, class Distance>
inline T next(T x, Distance n)
{
return next_prior_detail::next_impl1< T, Distance >::call(x, n);
}
template <class T>
inline T prior(T x) { return --x; }
template <class T, class Distance>
inline T prior(T x, Distance n)
{
return next_prior_detail::prior_impl1< T, Distance >::call(x, n);
}
} // namespace boost
#endif // BOOST_NEXT_PRIOR_HPP_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,951 @@
// Boost operators.hpp header file ----------------------------------------//
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/utility/operators.htm for documentation.
// Revision History
// 22 Feb 16 Preserve old work-arounds. (Daniel Frey)
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
// (Matthew Bradbury, fixes #4432)
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
// 03 Apr 08 Make sure "convertible to bool" is sufficient
// for T::operator<, etc. (Daniel Frey)
// 24 May 07 Changed empty_base to depend on T, see
// http://svn.boost.org/trac/boost/ticket/979
// 21 Oct 02 Modified implementation of operators to allow compilers with a
// correct named return value optimization (NRVO) to produce optimal
// code. (Daniel Frey)
// 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
// 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
// 27 Aug 01 'left' form for non commutative operators added;
// additional classes for groups of related operators added;
// workaround for empty base class optimization
// bug of GCC 3.0 (Helmut Zeisel)
// 25 Jun 01 output_iterator_helper changes: removed default template
// parameters, added support for self-proxying, additional
// documentation and tests (Aleksey Gurtovoy)
// 29 May 01 Added operator classes for << and >>. Added input and output
// iterator helper classes. Added classes to connect equality and
// relational operators. Added classes for groups of related
// operators. Reimplemented example operator and iterator helper
// classes in terms of the new groups. (Daryle Walker, with help
// from Alexy Gurtovoy)
// 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
// supplied arguments from actually being used (Dave Abrahams)
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
// refactoring of compiler workarounds, additional documentation
// (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
// Dave Abrahams)
// 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
// Jeremy Siek (Dave Abrahams)
// 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
// (Mark Rodgers)
// 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
// 10 Jun 00 Support for the base class chaining technique was added
// (Aleksey Gurtovoy). See documentation and the comments below
// for the details.
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
// 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
// specializations of dividable, subtractable, modable (Ed Brey)
// 17 Nov 99 Add comments (Beman Dawes)
// Remove unnecessary specialization of operators<> (Ed Brey)
// 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
// operators.(Beman Dawes)
// 12 Nov 99 Add operators templates (Ed Brey)
// 11 Nov 99 Add single template parameter version for compilers without
// partial specialization (Beman Dawes)
// 10 Nov 99 Initial version
// 10 Jun 00:
// An additional optional template parameter was added to most of
// operator templates to support the base class chaining technique (see
// documentation for the details). Unfortunately, a straightforward
// implementation of this change would have broken compatibility with the
// previous version of the library by making it impossible to use the same
// template name (e.g. 'addable') for both the 1- and 2-argument versions of
// an operator template. This implementation solves the backward-compatibility
// issue at the cost of some simplicity.
//
// One of the complications is an existence of special auxiliary class template
// 'is_chained_base<>' (see 'detail' namespace below), which is used
// to determine whether its template parameter is a library's operator template
// or not. You have to specialize 'is_chained_base<>' for each new
// operator template you add to the library.
//
// However, most of the non-trivial implementation details are hidden behind
// several local macros defined below, and as soon as you understand them,
// you understand the whole library implementation.
#ifndef BOOST_OPERATORS_V1_HPP
#define BOOST_OPERATORS_V1_HPP
#include <cstddef>
#include <iterator>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#if defined(__sgi) && !defined(__GNUC__)
# pragma set woff 1234
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
# pragma warning( disable : 4284 ) // complaint about return type of
#endif // operator-> not begin a UDT
namespace boost {
namespace detail {
template <typename T> class empty_base {};
} // namespace detail
} // namespace boost
// In this section we supply the xxxx1 and xxxx2 forms of the operator
// templates, which are explicitly targeted at the 1-type-argument and
// 2-type-argument operator forms, respectively. Some compilers get confused
// when inline friend functions are overloaded in namespaces other than the
// global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
// these templates must go in the global namespace.
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
namespace boost
{
#endif
// Basic operator classes (contributed by Dave Abrahams) ------------------//
// Note that friend functions defined in a class are implicitly inline.
// See the C++ std, 11.4 [class.friend] paragraph 5
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct less_than_comparable2 : B
{
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
friend bool operator>(const U& x, const T& y) { return y < x; }
friend bool operator<(const U& x, const T& y) { return y > x; }
friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
};
template <class T, class B = ::boost::detail::empty_base<T> >
struct less_than_comparable1 : B
{
friend bool operator>(const T& x, const T& y) { return y < x; }
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct equality_comparable2 : B
{
friend bool operator==(const U& y, const T& x) { return x == y; }
friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
};
template <class T, class B = ::boost::detail::empty_base<T> >
struct equality_comparable1 : B
{
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
};
// A macro which produces "name_2left" from "name".
#define BOOST_OPERATOR2_LEFT(name) name##2##_##left
// NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
// This is the optimal implementation for ISO/ANSI C++,
// but it requires the compiler to implement the NRVO.
// If the compiler has no NRVO, this is the best symmetric
// implementation available.
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
struct NAME##2 : B \
{ \
friend T operator OP( const T& lhs, const U& rhs ) \
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
friend T operator OP( const U& lhs, const T& rhs ) \
{ T nrv( rhs ); nrv OP##= lhs; return nrv; } \
}; \
\
template <class T, class B = ::boost::detail::empty_base<T> > \
struct NAME##1 : B \
{ \
friend T operator OP( const T& lhs, const T& rhs ) \
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
};
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
struct NAME##2 : B \
{ \
friend T operator OP( const T& lhs, const U& rhs ) \
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
}; \
\
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
struct BOOST_OPERATOR2_LEFT(NAME) : B \
{ \
friend T operator OP( const U& lhs, const T& rhs ) \
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
}; \
\
template <class T, class B = ::boost::detail::empty_base<T> > \
struct NAME##1 : B \
{ \
friend T operator OP( const T& lhs, const T& rhs ) \
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
};
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
// For compilers without NRVO the following code is optimal, but not
// symmetric! Note that the implementation of
// BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
// optimization opportunities to the compiler :)
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
struct NAME##2 : B \
{ \
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
}; \
\
template <class T, class B = ::boost::detail::empty_base<T> > \
struct NAME##1 : B \
{ \
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
};
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
struct NAME##2 : B \
{ \
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
}; \
\
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
struct BOOST_OPERATOR2_LEFT(NAME) : B \
{ \
friend T operator OP( const U& lhs, const T& rhs ) \
{ return T( lhs ) OP##= rhs; } \
}; \
\
template <class T, class B = ::boost::detail::empty_base<T> > \
struct NAME##1 : B \
{ \
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
};
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
#undef BOOST_BINARY_OPERATOR_COMMUTATIVE
#undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
#undef BOOST_OPERATOR2_LEFT
// incrementable and decrementable contributed by Jeremy Siek
template <class T, class B = ::boost::detail::empty_base<T> >
struct incrementable : B
{
friend T operator++(T& x, int)
{
incrementable_type nrv(x);
++x;
return nrv;
}
private: // The use of this typedef works around a Borland bug
typedef T incrementable_type;
};
template <class T, class B = ::boost::detail::empty_base<T> >
struct decrementable : B
{
friend T operator--(T& x, int)
{
decrementable_type nrv(x);
--x;
return nrv;
}
private: // The use of this typedef works around a Borland bug
typedef T decrementable_type;
};
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
template <class T, class P, class B = ::boost::detail::empty_base<T> >
struct dereferenceable : B
{
P operator->() const
{
return &*static_cast<const T&>(*this);
}
};
template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
struct indexable : B
{
R operator[](I n) const
{
return *(static_cast<const T&>(*this) + n);
}
};
// More operator classes (contributed by Daryle Walker) --------------------//
// (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
struct NAME##2 : B \
{ \
friend T operator OP( const T& lhs, const U& rhs ) \
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
}; \
\
template <class T, class B = ::boost::detail::empty_base<T> > \
struct NAME##1 : B \
{ \
friend T operator OP( const T& lhs, const T& rhs ) \
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
};
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
struct NAME##2 : B \
{ \
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
}; \
\
template <class T, class B = ::boost::detail::empty_base<T> > \
struct NAME##1 : B \
{ \
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
};
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
BOOST_BINARY_OPERATOR( left_shiftable, << )
BOOST_BINARY_OPERATOR( right_shiftable, >> )
#undef BOOST_BINARY_OPERATOR
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct equivalent2 : B
{
friend bool operator==(const T& x, const U& y)
{
return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
}
};
template <class T, class B = ::boost::detail::empty_base<T> >
struct equivalent1 : B
{
friend bool operator==(const T&x, const T&y)
{
return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
}
};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct partially_ordered2 : B
{
friend bool operator<=(const T& x, const U& y)
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
friend bool operator>=(const T& x, const U& y)
{ return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
friend bool operator>(const U& x, const T& y)
{ return y < x; }
friend bool operator<(const U& x, const T& y)
{ return y > x; }
friend bool operator<=(const U& x, const T& y)
{ return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
friend bool operator>=(const U& x, const T& y)
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
};
template <class T, class B = ::boost::detail::empty_base<T> >
struct partially_ordered1 : B
{
friend bool operator>(const T& x, const T& y)
{ return y < x; }
friend bool operator<=(const T& x, const T& y)
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
friend bool operator>=(const T& x, const T& y)
{ return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
};
// Combined operator classes (contributed by Daryle Walker) ----------------//
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct totally_ordered2
: less_than_comparable2<T, U
, equality_comparable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct totally_ordered1
: less_than_comparable1<T
, equality_comparable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct additive2
: addable2<T, U
, subtractable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct additive1
: addable1<T
, subtractable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct multiplicative2
: multipliable2<T, U
, dividable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct multiplicative1
: multipliable1<T
, dividable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct integer_multiplicative2
: multiplicative2<T, U
, modable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct integer_multiplicative1
: multiplicative1<T
, modable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct arithmetic2
: additive2<T, U
, multiplicative2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct arithmetic1
: additive1<T
, multiplicative1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct integer_arithmetic2
: additive2<T, U
, integer_multiplicative2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct integer_arithmetic1
: additive1<T
, integer_multiplicative1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct bitwise2
: xorable2<T, U
, andable2<T, U
, orable2<T, U, B
> > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct bitwise1
: xorable1<T
, andable1<T
, orable1<T, B
> > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct unit_steppable
: incrementable<T
, decrementable<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct shiftable2
: left_shiftable2<T, U
, right_shiftable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct shiftable1
: left_shiftable1<T
, right_shiftable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct ring_operators2
: additive2<T, U
, subtractable2_left<T, U
, multipliable2<T, U, B
> > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct ring_operators1
: additive1<T
, multipliable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct ordered_ring_operators2
: ring_operators2<T, U
, totally_ordered2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct ordered_ring_operators1
: ring_operators1<T
, totally_ordered1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct field_operators2
: ring_operators2<T, U
, dividable2<T, U
, dividable2_left<T, U, B
> > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct field_operators1
: ring_operators1<T
, dividable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct ordered_field_operators2
: field_operators2<T, U
, totally_ordered2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct ordered_field_operators1
: field_operators1<T
, totally_ordered1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct euclidian_ring_operators2
: ring_operators2<T, U
, dividable2<T, U
, dividable2_left<T, U
, modable2<T, U
, modable2_left<T, U, B
> > > > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct euclidian_ring_operators1
: ring_operators1<T
, dividable1<T
, modable1<T, B
> > > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct ordered_euclidian_ring_operators2
: totally_ordered2<T, U
, euclidian_ring_operators2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct ordered_euclidian_ring_operators1
: totally_ordered1<T
, euclidian_ring_operators1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct euclidean_ring_operators2
: ring_operators2<T, U
, dividable2<T, U
, dividable2_left<T, U
, modable2<T, U
, modable2_left<T, U, B
> > > > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct euclidean_ring_operators1
: ring_operators1<T
, dividable1<T
, modable1<T, B
> > > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
struct ordered_euclidean_ring_operators2
: totally_ordered2<T, U
, euclidean_ring_operators2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct ordered_euclidean_ring_operators1
: totally_ordered1<T
, euclidean_ring_operators1<T, B
> > {};
template <class T, class P, class B = ::boost::detail::empty_base<T> >
struct input_iteratable
: equality_comparable1<T
, incrementable<T
, dereferenceable<T, P, B
> > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
struct output_iteratable
: incrementable<T, B
> {};
template <class T, class P, class B = ::boost::detail::empty_base<T> >
struct forward_iteratable
: input_iteratable<T, P, B
> {};
template <class T, class P, class B = ::boost::detail::empty_base<T> >
struct bidirectional_iteratable
: forward_iteratable<T, P
, decrementable<T, B
> > {};
// To avoid repeated derivation from equality_comparable,
// which is an indirect base class of bidirectional_iterable,
// random_access_iteratable must not be derived from totally_ordered1
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> >
struct random_access_iteratable
: bidirectional_iteratable<T, P
, less_than_comparable1<T
, additive2<T, D
, indexable<T, D, R, B
> > > > {};
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
} // namespace boost
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
//
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
// for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
// two-argument forms. Note that these macros expect to be invoked from within
// boost.
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
// The template is already in boost so we have nothing to do.
# define BOOST_IMPORT_TEMPLATE4(template_name)
# define BOOST_IMPORT_TEMPLATE3(template_name)
# define BOOST_IMPORT_TEMPLATE2(template_name)
# define BOOST_IMPORT_TEMPLATE1(template_name)
#else // BOOST_NO_OPERATORS_IN_NAMESPACE
# ifndef BOOST_NO_USING_TEMPLATE
// Bring the names in with a using-declaration
// to avoid stressing the compiler.
# define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
# define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
# else
// Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
// from working, we are forced to use inheritance for that compiler.
# define BOOST_IMPORT_TEMPLATE4(template_name) \
template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \
struct template_name : ::template_name<T, U, V, W, B> {};
# define BOOST_IMPORT_TEMPLATE3(template_name) \
template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \
struct template_name : ::template_name<T, U, V, B> {};
# define BOOST_IMPORT_TEMPLATE2(template_name) \
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
struct template_name : ::template_name<T, U, B> {};
# define BOOST_IMPORT_TEMPLATE1(template_name) \
template <class T, class B = ::boost::detail::empty_base<T> > \
struct template_name : ::template_name<T, B> {};
# endif // BOOST_NO_USING_TEMPLATE
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
//
// Here's where we put it all together, defining the xxxx forms of the templates
// in namespace boost. We also define specializations of is_chained_base<> for
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
// necessary.
//
// is_chained_base<> - a traits class used to distinguish whether an operator
// template argument is being used for base class chaining, or is specifying a
// 2nd argument type.
namespace boost {
// A type parameter is used instead of a plain bool because Borland's compiler
// didn't cope well with the more obvious non-type template parameter.
namespace detail {
struct true_t {};
struct false_t {};
} // namespace detail
// Unspecialized version assumes that most types are not being used for base
// class chaining. We specialize for the operator templates defined in this
// library.
template<class T> struct is_chained_base {
typedef ::boost::detail::false_t value;
};
} // namespace boost
// Import a 4-type-argument operator template into boost (if necessary) and
// provide a specialization of 'is_chained_base<>' for it.
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
BOOST_IMPORT_TEMPLATE4(template_name4) \
template<class T, class U, class V, class W, class B> \
struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
typedef ::boost::detail::true_t value; \
};
// Import a 3-type-argument operator template into boost (if necessary) and
// provide a specialization of 'is_chained_base<>' for it.
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
BOOST_IMPORT_TEMPLATE3(template_name3) \
template<class T, class U, class V, class B> \
struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
typedef ::boost::detail::true_t value; \
};
// Import a 2-type-argument operator template into boost (if necessary) and
// provide a specialization of 'is_chained_base<>' for it.
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
BOOST_IMPORT_TEMPLATE2(template_name2) \
template<class T, class U, class B> \
struct is_chained_base< ::boost::template_name2<T, U, B> > { \
typedef ::boost::detail::true_t value; \
};
// Import a 1-type-argument operator template into boost (if necessary) and
// provide a specialization of 'is_chained_base<>' for it.
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
BOOST_IMPORT_TEMPLATE1(template_name1) \
template<class T, class B> \
struct is_chained_base< ::boost::template_name1<T, B> > { \
typedef ::boost::detail::true_t value; \
};
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
// can be used for specifying both 1-argument and 2-argument forms. Requires the
// existence of two previously defined class templates named '<template_name>1'
// and '<template_name>2' which must implement the corresponding 1- and 2-
// argument forms.
//
// The template type parameter O == is_chained_base<U>::value is used to
// distinguish whether the 2nd argument to <template_name> is being used for
// base class chaining from another boost operator template or is describing a
// 2nd operand type. O == true_t only when U is actually an another operator
// template from the library. Partial specialization is used to select an
// implementation in terms of either '<template_name>1' or '<template_name>2'.
//
# define BOOST_OPERATOR_TEMPLATE(template_name) \
template <class T \
,class U = T \
,class B = ::boost::detail::empty_base<T> \
,class O = typename is_chained_base<U>::value \
> \
struct template_name : template_name##2<T, U, B> {}; \
\
template<class T, class U, class B> \
struct template_name<T, U, B, ::boost::detail::true_t> \
: template_name##1<T, U> {}; \
\
template <class T, class B> \
struct template_name<T, T, B, ::boost::detail::false_t> \
: template_name##1<T, B> {}; \
\
template<class T, class U, class B, class O> \
struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
typedef ::boost::detail::true_t value; \
}; \
\
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
BOOST_OPERATOR_TEMPLATE1(template_name##1)
namespace boost {
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
BOOST_OPERATOR_TEMPLATE(equality_comparable)
BOOST_OPERATOR_TEMPLATE(multipliable)
BOOST_OPERATOR_TEMPLATE(addable)
BOOST_OPERATOR_TEMPLATE(subtractable)
BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
BOOST_OPERATOR_TEMPLATE(dividable)
BOOST_OPERATOR_TEMPLATE2(dividable2_left)
BOOST_OPERATOR_TEMPLATE(modable)
BOOST_OPERATOR_TEMPLATE2(modable2_left)
BOOST_OPERATOR_TEMPLATE(xorable)
BOOST_OPERATOR_TEMPLATE(andable)
BOOST_OPERATOR_TEMPLATE(orable)
BOOST_OPERATOR_TEMPLATE1(incrementable)
BOOST_OPERATOR_TEMPLATE1(decrementable)
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
BOOST_OPERATOR_TEMPLATE3(indexable)
BOOST_OPERATOR_TEMPLATE(left_shiftable)
BOOST_OPERATOR_TEMPLATE(right_shiftable)
BOOST_OPERATOR_TEMPLATE(equivalent)
BOOST_OPERATOR_TEMPLATE(partially_ordered)
BOOST_OPERATOR_TEMPLATE(totally_ordered)
BOOST_OPERATOR_TEMPLATE(additive)
BOOST_OPERATOR_TEMPLATE(multiplicative)
BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
BOOST_OPERATOR_TEMPLATE(arithmetic)
BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
BOOST_OPERATOR_TEMPLATE(bitwise)
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
BOOST_OPERATOR_TEMPLATE(shiftable)
BOOST_OPERATOR_TEMPLATE(ring_operators)
BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
BOOST_OPERATOR_TEMPLATE(field_operators)
BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
BOOST_OPERATOR_TEMPLATE(euclidean_ring_operators)
BOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators)
BOOST_OPERATOR_TEMPLATE2(input_iteratable)
BOOST_OPERATOR_TEMPLATE1(output_iteratable)
BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
#undef BOOST_OPERATOR_TEMPLATE
#undef BOOST_OPERATOR_TEMPLATE4
#undef BOOST_OPERATOR_TEMPLATE3
#undef BOOST_OPERATOR_TEMPLATE2
#undef BOOST_OPERATOR_TEMPLATE1
#undef BOOST_IMPORT_TEMPLATE1
#undef BOOST_IMPORT_TEMPLATE2
#undef BOOST_IMPORT_TEMPLATE3
#undef BOOST_IMPORT_TEMPLATE4
// The following 'operators' classes can only be used portably if the derived class
// declares ALL of the required member operators.
template <class T, class U>
struct operators2
: totally_ordered2<T,U
, integer_arithmetic2<T,U
, bitwise2<T,U
> > > {};
template <class T, class U = T>
struct operators : operators2<T, U> {};
template <class T> struct operators<T, T>
: totally_ordered<T
, integer_arithmetic<T
, bitwise<T
, unit_steppable<T
> > > > {};
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
// (Input and output iterator helpers contributed by Daryle Walker) -------//
// (Changed to use combined operator classes by Daryle Walker) ------------//
template <class T,
class V,
class D = std::ptrdiff_t,
class P = V const *,
class R = V const &>
struct input_iterator_helper
: input_iteratable<T, P
, std::iterator<std::input_iterator_tag, V, D, P, R
> > {};
template<class T>
struct output_iterator_helper
: output_iteratable<T
, std::iterator<std::output_iterator_tag, void, void, void, void
> >
{
T& operator*() { return static_cast<T&>(*this); }
T& operator++() { return static_cast<T&>(*this); }
};
template <class T,
class V,
class D = std::ptrdiff_t,
class P = V*,
class R = V&>
struct forward_iterator_helper
: forward_iteratable<T, P
, std::iterator<std::forward_iterator_tag, V, D, P, R
> > {};
template <class T,
class V,
class D = std::ptrdiff_t,
class P = V*,
class R = V&>
struct bidirectional_iterator_helper
: bidirectional_iteratable<T, P
, std::iterator<std::bidirectional_iterator_tag, V, D, P, R
> > {};
template <class T,
class V,
class D = std::ptrdiff_t,
class P = V*,
class R = V&>
struct random_access_iterator_helper
: random_access_iteratable<T, P, D, R
, std::iterator<std::random_access_iterator_tag, V, D, P, R
> >
{
friend D requires_difference_operator(const T& x, const T& y) {
return x - y;
}
}; // random_access_iterator_helper
} // namespace boost
#if defined(__sgi) && !defined(__GNUC__)
#pragma reset woff 1234
#endif
#endif // BOOST_OPERATORS_V1_HPP

View File

@ -1,96 +1,21 @@
// boost utility.hpp header file -------------------------------------------//
// Boost utility.hpp header file -------------------------------------------//
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
// and distribute this software is granted provided this copyright
// notice appears in all copies. This software is provided "as is" without
// express or implied warranty, and with no claim as to its suitability for
// any purpose.
// Copyright 1999-2003 Aleksey Gurtovoy. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
// See http://www.boost.org for most recent version including documentation.
// Classes appear in alphabetical order
// Revision History
// 26 Jan 00 protected noncopyable destructor added (Miki Jovanovic)
// 10 Dec 99 next() and prior() templates added (Dave Abrahams)
// 30 Aug 99 moved cast templates to cast.hpp (Beman Dawes)
// 3 Aug 99 cast templates added
// 20 Jul 99 name changed to utility.hpp
// 9 Jun 99 protected noncopyable default ctor
// 2 Jun 99 Initial Version. Class noncopyable only contents (Dave Abrahams)
// See <http://www.boost.org/libs/utility/> for the library's home page.
#ifndef BOOST_UTILITY_HPP
#define BOOST_UTILITY_HPP
#include <boost/config.hpp>
#include <cstddef> // for size_t
#include <utility> // for std::pair
namespace boost
{
// next() and prior() template functions -----------------------------------//
// Helper functions for classes like bidirectional iterators not supporting
// operator+ and operator-.
//
// Usage:
// const std::list<T>::iterator p = get_some_iterator();
// const std::list<T>::iterator prev = boost::prior(p);
// Contributed by Dave Abrahams
template <class T>
T next(T x) { return ++x; }
template <class T>
T prior(T x) { return --x; }
// class noncopyable -------------------------------------------------------//
// Private copy constructor and copy assignment ensure classes derived from
// class noncopyable cannot be copied.
// Contributed by Dave Abrahams
class noncopyable
{
protected:
noncopyable(){}
~noncopyable(){}
private: // emphasize the following members are private
noncopyable( const noncopyable& );
const noncopyable& operator=( const noncopyable& );
}; // noncopyable
// class tied -------------------------------------------------------//
// A helper for conveniently assigning the two values from a pair
// into separate variables. The idea for this comes from Jaakko J<>rvi's
// Binder/Lambda Library.
// Constributed by Jeremy Siek
template <class A, class B>
class tied {
public:
inline tied(A& a, B& b) : _a(a), _b(b) { }
template <class U, class V>
inline tied& operator=(const std::pair<U,V>& p) {
_a = p.first;
_b = p.second;
return *this;
}
protected:
A& _a;
B& _b;
};
template <class A, class B>
inline tied<A,B> tie(A& a, B& b) { return tied<A,B>(a, b); }
} // namespace boost
#include <boost/utility/addressof.hpp>
#include <boost/utility/base_from_member.hpp>
#include <boost/utility/binary.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/identity_type.hpp>
#include <boost/checked_delete.hpp>
#include <boost/next_prior.hpp>
#include <boost/noncopyable.hpp>
#endif // BOOST_UTILITY_HPP

View File

@ -0,0 +1,172 @@
// boost utility/base_from_member.hpp header file --------------------------//
// Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and
// distribution are subject to the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or a copy at
// <http://www.boost.org/LICENSE_1_0.txt>.)
// See <http://www.boost.org/libs/utility/> for the library's home page.
#ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP
#define BOOST_UTILITY_BASE_FROM_MEMBER_HPP
#include <boost/config.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
// Base-from-member arity configuration macro ------------------------------//
// The following macro determines how many arguments will be in the largest
// constructor template of base_from_member. Constructor templates will be
// generated from one argument to this maximum. Code from other files can read
// this number if they need to always match the exact maximum base_from_member
// uses. The maximum constructor length can be changed by overriding the
// #defined constant. Make sure to apply the override, if any, for all source
// files during project compiling for consistency.
// Contributed by Jonathan Turkanis
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
#endif
// An iteration of a constructor template for base_from_member -------------//
// A macro that should expand to:
// template < typename T1, ..., typename Tn >
// base_from_member( T1 x1, ..., Tn xn )
// : member( x1, ..., xn )
// {}
// This macro should only persist within this file.
#define BOOST_PRIVATE_CTR_DEF( z, n, data ) \
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
: member( BOOST_PP_ENUM_PARAMS(n, x) ) \
{} \
/**/
namespace boost
{
namespace detail
{
// Type-unmarking class template -------------------------------------------//
// Type-trait to get the raw type, i.e. the type without top-level reference nor
// cv-qualification, from a type expression. Mainly for function arguments, any
// reference part is stripped first.
// Contributed by Daryle Walker
template < typename T >
struct remove_cv_ref
{
typedef typename ::boost::remove_cv<typename
::boost::remove_reference<T>::type>::type type;
}; // boost::detail::remove_cv_ref
// Unmarked-type comparison class template ---------------------------------//
// Type-trait to check if two type expressions have the same raw type.
// Contributed by Daryle Walker, based on a work-around by Luc Danton
template < typename T, typename U >
struct is_related
: public ::boost::is_same<
typename ::boost::detail::remove_cv_ref<T>::type,
typename ::boost::detail::remove_cv_ref<U>::type >
{};
// Enable-if-on-unidentical-unmarked-type class template -------------------//
// Enable-if on the first two type expressions NOT having the same raw type.
// Contributed by Daryle Walker, based on a work-around by Luc Danton
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
template<typename ...T>
struct enable_if_unrelated
: public ::boost::enable_if_c<true>
{};
template<typename T, typename U, typename ...U2>
struct enable_if_unrelated<T, U, U2...>
: public ::boost::disable_if< ::boost::detail::is_related<T, U> >
{};
#endif
} // namespace boost::detail
// Base-from-member class template -----------------------------------------//
// Helper to initialize a base object so a derived class can use this
// object in the initialization of another base class. Used by
// Dietmar Kuehl from ideas by Ron Klatcho to solve the problem of a
// base class needing to be initialized by a member.
// Contributed by Daryle Walker
template < typename MemberType, int UniqueID = 0 >
class base_from_member
{
protected:
MemberType member;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
!defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && \
!(defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4))
template <typename ...T, typename EnableIf = typename
::boost::detail::enable_if_unrelated<base_from_member, T...>::type>
explicit BOOST_CONSTEXPR base_from_member( T&& ...x )
BOOST_NOEXCEPT_IF( BOOST_NOEXCEPT_EXPR(::new ((void*) 0) MemberType(
static_cast<T&&>(x)... )) ) // no std::is_nothrow_constructible...
: member( static_cast<T&&>(x)... ) // ...nor std::forward needed
{}
#else
base_from_member()
: member()
{}
template < typename T0 > explicit base_from_member( T0 x0 ) : member( x0 ) {}
BOOST_PP_REPEAT_FROM_TO( 2, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
BOOST_PRIVATE_CTR_DEF, _ )
#endif
}; // boost::base_from_member
template < typename MemberType, int UniqueID >
class base_from_member<MemberType&, UniqueID>
{
protected:
MemberType& member;
explicit BOOST_CONSTEXPR base_from_member( MemberType& x )
BOOST_NOEXCEPT
: member( x )
{}
}; // boost::base_from_member
} // namespace boost
// Undo any private macros
#undef BOOST_PRIVATE_CTR_DEF
#endif // BOOST_UTILITY_BASE_FROM_MEMBER_HPP

View File

@ -0,0 +1,708 @@
/*=============================================================================
Copyright (c) 2005 Matthew Calabrese
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_UTILITY_BINARY_HPP
#define BOOST_UTILITY_BINARY_HPP
/*=============================================================================
Binary Literal Utility
______________________
The following code works by converting the input bit pattern into a
Boost.Preprocessor sequence, then converting groupings of 3 bits each into
the corresponding octal digit, and finally concatenating all of the digits
together along with a leading zero. This yields a standard octal literal
with the desired value as specified in bits.
==============================================================================*/
#include <boost/preprocessor/control/deduce_d.hpp>
#include <boost/preprocessor/facilities/identity.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/seq/cat.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/arithmetic/mod.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/control/while.hpp>
#define BOOST_BINARY( bit_groupings ) \
BOOST_BINARY_LITERAL_D( BOOST_PP_DEDUCE_D(), bit_groupings )
#define BOOST_BINARY_U( bit_groupings ) \
BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, U )
#define BOOST_BINARY_L( bit_groupings ) \
BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, L )
#define BOOST_BINARY_UL( bit_groupings ) \
BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, UL )
#define BOOST_BINARY_LU( bit_groupings ) \
BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, LU )
#define BOOST_BINARY_LL( bit_groupings ) \
BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, LL )
#define BOOST_BINARY_ULL( bit_groupings ) \
BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, ULL )
#define BOOST_BINARY_LLU( bit_groupings ) \
BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, LLU )
#define BOOST_SUFFIXED_BINARY_LITERAL( bit_groupings, suffix ) \
BOOST_SUFFIXED_BINARY_LITERAL_D( BOOST_PP_DEDUCE_D(), bit_groupings, suffix )
#define BOOST_SUFFIXED_BINARY_LITERAL_D( d, bit_groupings, suffix ) \
BOOST_PP_CAT( BOOST_BINARY_LITERAL_D( d, bit_groupings ), suffix )
#define BOOST_BINARY_LITERAL_D( d, bit_groupings ) \
BOOST_PP_SEQ_CAT \
( (0) BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings ) \
)
#define BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings ) \
BOOST_PP_SEQ_TRANSFORM \
( BOOST_DETAIL_TRIPLE_TO_OCTAL_OPERATION \
, BOOST_PP_NIL \
, BOOST_PP_IDENTITY( BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_TRIPLE_SEQUENCE )()\
( BOOST_DETAIL_COMPLETE_TRIPLE_SEQUENCE \
( \
d \
, BOOST_DETAIL_CREATE_BINARY_LITERAL_BIT_SEQUENCE( d, bit_groupings ) \
) \
) \
)
#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_TRIPLE_SEQUENCE( bit_sequence ) \
BOOST_PP_CAT \
( BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1 bit_sequence \
, END_BIT \
)
#define BOOST_DETAIL_BITS_PER_OCTIT 3
#define BOOST_DETAIL_COMPLETE_TRIPLE_SEQUENCE( d, incomplete_nibble_sequence ) \
BOOST_PP_CAT \
( BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_ \
, BOOST_PP_MOD_D( d \
, BOOST_PP_SEQ_SIZE( incomplete_nibble_sequence ) \
, BOOST_DETAIL_BITS_PER_OCTIT \
) \
) \
incomplete_nibble_sequence
#define BOOST_DETAIL_FIXED_COMPL( bit ) \
BOOST_PP_CAT( BOOST_DETAIL_FIXED_COMPL_, bit )
#define BOOST_DETAIL_FIXED_COMPL_0 1
#define BOOST_DETAIL_FIXED_COMPL_1 0
#define BOOST_DETAIL_CREATE_BINARY_LITERAL_BIT_SEQUENCE( d, bit_groupings ) \
BOOST_PP_EMPTY \
BOOST_PP_CAT( BOOST_PP_WHILE_, d ) \
( BOOST_DETAIL_BINARY_LITERAL_PREDICATE \
, BOOST_DETAIL_BINARY_LITERAL_OPERATION \
, bit_groupings () \
)
#define BOOST_DETAIL_BINARY_LITERAL_PREDICATE( d, state ) \
BOOST_DETAIL_FIXED_COMPL( BOOST_DETAIL_IS_NULLARY_ARGS( state ) )
#define BOOST_DETAIL_BINARY_LITERAL_OPERATION( d, state ) \
BOOST_DETAIL_SPLIT_AND_SWAP \
( BOOST_PP_CAT( BOOST_DETAIL_BINARY_LITERAL_ELEMENT_, state ) )
#define BOOST_DETAIL_TRIPLE_TO_OCTAL_OPERATION( s, dummy_param, tuple ) \
BOOST_DETAIL_TERNARY_TRIPLE_TO_OCTAL tuple
#define BOOST_DETAIL_TERNARY_TRIPLE_TO_OCTAL( bit2, bit1, bit0 ) \
BOOST_DETAIL_TRIPLE_TO_OCTAL_ ## bit2 ## bit1 ## bit0
#define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_1 (0)(0)
#define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_2 (0)
#define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_0
#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1END_BIT
#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1( bit ) \
( ( bit, BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_2
#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_2( bit ) \
bit, BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_3
#define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_3( bit ) \
bit ) ) BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1
#define BOOST_DETAIL_SPLIT_AND_SWAP( params ) \
BOOST_PP_IDENTITY( BOOST_DETAIL_SPLIT_AND_SWAP_PARAMS )()( params )
#define BOOST_DETAIL_SPLIT_AND_SWAP_PARAMS( first_param, second_param ) \
second_param first_param
#define BOOST_DETAIL_LEFT_OF_COMMA( params ) \
BOOST_PP_IDENTITY( BOOST_DETAIL_FIRST_MACRO_PARAM )()( params )
#define BOOST_DETAIL_FIRST_MACRO_PARAM( first_param, second_param ) \
first_param
/* Begin derived concepts from Chaos by Paul Mensonides */
#define BOOST_DETAIL_IS_NULLARY_ARGS( param ) \
BOOST_DETAIL_LEFT_OF_COMMA \
( BOOST_PP_CAT( BOOST_DETAIL_IS_NULLARY_ARGS_R_ \
, BOOST_DETAIL_IS_NULLARY_ARGS_C param \
) \
)
#define BOOST_DETAIL_IS_NULLARY_ARGS_C() \
1
#define BOOST_DETAIL_IS_NULLARY_ARGS_R_1 \
1, BOOST_PP_NIL
#define BOOST_DETAIL_IS_NULLARY_ARGS_R_BOOST_DETAIL_IS_NULLARY_ARGS_C \
0, BOOST_PP_NIL
/* End derived concepts from Chaos by Paul Mensonides */
#define BOOST_DETAIL_TRIPLE_TO_OCTAL_000 0
#define BOOST_DETAIL_TRIPLE_TO_OCTAL_001 1
#define BOOST_DETAIL_TRIPLE_TO_OCTAL_010 2
#define BOOST_DETAIL_TRIPLE_TO_OCTAL_011 3
#define BOOST_DETAIL_TRIPLE_TO_OCTAL_100 4
#define BOOST_DETAIL_TRIPLE_TO_OCTAL_101 5
#define BOOST_DETAIL_TRIPLE_TO_OCTAL_110 6
#define BOOST_DETAIL_TRIPLE_TO_OCTAL_111 7
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0 (0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1 (1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00 (0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01 (0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10 (1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11 (1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00 (0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01 (0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10 (1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11 (1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000 (0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001 (0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010 (0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011 (0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100 (1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101 (1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110 (1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111 (1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000 (0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001 (0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010 (0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011 (0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100 (0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101 (0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110 (0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111 (0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000 (1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001 (1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010 (1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011 (1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100 (1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101 (1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110 (1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111 (1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000 (0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001 (0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010 (0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011 (0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100 (0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101 (0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110 (0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111 (0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000 (0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001 (0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010 (0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011 (0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100 (0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101 (0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110 (0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111 (0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000 (1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001 (1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010 (1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011 (1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100 (1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101 (1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110 (1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111 (1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000 (1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001 (1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010 (1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011 (1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100 (1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101 (1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110 (1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111 (1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000000 (0)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000001 (0)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000010 (0)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000011 (0)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000100 (0)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000101 (0)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000110 (0)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_000111 (0)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001000 (0)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001001 (0)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001010 (0)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001011 (0)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001100 (0)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001101 (0)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001110 (0)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_001111 (0)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010000 (0)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010001 (0)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010010 (0)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010011 (0)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010100 (0)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010101 (0)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010110 (0)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_010111 (0)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011000 (0)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011001 (0)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011010 (0)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011011 (0)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011100 (0)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011101 (0)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011110 (0)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_011111 (0)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100000 (1)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100001 (1)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100010 (1)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100011 (1)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100100 (1)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100101 (1)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100110 (1)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_100111 (1)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101000 (1)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101001 (1)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101010 (1)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101011 (1)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101100 (1)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101101 (1)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101110 (1)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_101111 (1)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110000 (1)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110001 (1)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110010 (1)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110011 (1)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110100 (1)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110101 (1)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110110 (1)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_110111 (1)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111000 (1)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111001 (1)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111010 (1)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111011 (1)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111100 (1)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111101 (1)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111110 (1)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_111111 (1)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000000 (0)(0)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000001 (0)(0)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000010 (0)(0)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000011 (0)(0)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000100 (0)(0)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000101 (0)(0)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000110 (0)(0)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0000111 (0)(0)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001000 (0)(0)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001001 (0)(0)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001010 (0)(0)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001011 (0)(0)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001100 (0)(0)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001101 (0)(0)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001110 (0)(0)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0001111 (0)(0)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010000 (0)(0)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010001 (0)(0)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010010 (0)(0)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010011 (0)(0)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010100 (0)(0)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010101 (0)(0)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010110 (0)(0)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0010111 (0)(0)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011000 (0)(0)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011001 (0)(0)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011010 (0)(0)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011011 (0)(0)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011100 (0)(0)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011101 (0)(0)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011110 (0)(0)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0011111 (0)(0)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100000 (0)(1)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100001 (0)(1)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100010 (0)(1)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100011 (0)(1)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100100 (0)(1)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100101 (0)(1)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100110 (0)(1)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0100111 (0)(1)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101000 (0)(1)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101001 (0)(1)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101010 (0)(1)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101011 (0)(1)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101100 (0)(1)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101101 (0)(1)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101110 (0)(1)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0101111 (0)(1)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110000 (0)(1)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110001 (0)(1)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110010 (0)(1)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110011 (0)(1)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110100 (0)(1)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110101 (0)(1)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110110 (0)(1)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0110111 (0)(1)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111000 (0)(1)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111001 (0)(1)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111010 (0)(1)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111011 (0)(1)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111100 (0)(1)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111101 (0)(1)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111110 (0)(1)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0111111 (0)(1)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000000 (1)(0)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000001 (1)(0)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000010 (1)(0)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000011 (1)(0)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000100 (1)(0)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000101 (1)(0)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000110 (1)(0)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1000111 (1)(0)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001000 (1)(0)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001001 (1)(0)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001010 (1)(0)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001011 (1)(0)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001100 (1)(0)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001101 (1)(0)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001110 (1)(0)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1001111 (1)(0)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010000 (1)(0)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010001 (1)(0)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010010 (1)(0)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010011 (1)(0)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010100 (1)(0)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010101 (1)(0)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010110 (1)(0)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1010111 (1)(0)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011000 (1)(0)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011001 (1)(0)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011010 (1)(0)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011011 (1)(0)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011100 (1)(0)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011101 (1)(0)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011110 (1)(0)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1011111 (1)(0)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100000 (1)(1)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100001 (1)(1)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100010 (1)(1)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100011 (1)(1)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100100 (1)(1)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100101 (1)(1)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100110 (1)(1)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1100111 (1)(1)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101000 (1)(1)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101001 (1)(1)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101010 (1)(1)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101011 (1)(1)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101100 (1)(1)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101101 (1)(1)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101110 (1)(1)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1101111 (1)(1)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110000 (1)(1)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110001 (1)(1)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110010 (1)(1)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110011 (1)(1)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110100 (1)(1)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110101 (1)(1)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110110 (1)(1)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1110111 (1)(1)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111000 (1)(1)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111001 (1)(1)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111010 (1)(1)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111011 (1)(1)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111100 (1)(1)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111101 (1)(1)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111110 (1)(1)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1111111 (1)(1)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000000 (0)(0)(0)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000001 (0)(0)(0)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000010 (0)(0)(0)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000011 (0)(0)(0)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000100 (0)(0)(0)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000101 (0)(0)(0)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000110 (0)(0)(0)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00000111 (0)(0)(0)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001000 (0)(0)(0)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001001 (0)(0)(0)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001010 (0)(0)(0)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001011 (0)(0)(0)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001100 (0)(0)(0)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001101 (0)(0)(0)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001110 (0)(0)(0)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00001111 (0)(0)(0)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010000 (0)(0)(0)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010001 (0)(0)(0)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010010 (0)(0)(0)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010011 (0)(0)(0)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010100 (0)(0)(0)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010101 (0)(0)(0)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010110 (0)(0)(0)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00010111 (0)(0)(0)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011000 (0)(0)(0)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011001 (0)(0)(0)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011010 (0)(0)(0)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011011 (0)(0)(0)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011100 (0)(0)(0)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011101 (0)(0)(0)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011110 (0)(0)(0)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00011111 (0)(0)(0)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100000 (0)(0)(1)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100001 (0)(0)(1)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100010 (0)(0)(1)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100011 (0)(0)(1)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100100 (0)(0)(1)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100101 (0)(0)(1)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100110 (0)(0)(1)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00100111 (0)(0)(1)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101000 (0)(0)(1)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101001 (0)(0)(1)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101010 (0)(0)(1)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101011 (0)(0)(1)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101100 (0)(0)(1)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101101 (0)(0)(1)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101110 (0)(0)(1)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00101111 (0)(0)(1)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110000 (0)(0)(1)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110001 (0)(0)(1)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110010 (0)(0)(1)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110011 (0)(0)(1)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110100 (0)(0)(1)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110101 (0)(0)(1)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110110 (0)(0)(1)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00110111 (0)(0)(1)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111000 (0)(0)(1)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111001 (0)(0)(1)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111010 (0)(0)(1)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111011 (0)(0)(1)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111100 (0)(0)(1)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111101 (0)(0)(1)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111110 (0)(0)(1)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00111111 (0)(0)(1)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000000 (0)(1)(0)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000001 (0)(1)(0)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000010 (0)(1)(0)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000011 (0)(1)(0)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000100 (0)(1)(0)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000101 (0)(1)(0)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000110 (0)(1)(0)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01000111 (0)(1)(0)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001000 (0)(1)(0)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001001 (0)(1)(0)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001010 (0)(1)(0)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001011 (0)(1)(0)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001100 (0)(1)(0)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001101 (0)(1)(0)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001110 (0)(1)(0)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01001111 (0)(1)(0)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010000 (0)(1)(0)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010001 (0)(1)(0)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010010 (0)(1)(0)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010011 (0)(1)(0)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010100 (0)(1)(0)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010101 (0)(1)(0)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010110 (0)(1)(0)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01010111 (0)(1)(0)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011000 (0)(1)(0)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011001 (0)(1)(0)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011010 (0)(1)(0)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011011 (0)(1)(0)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011100 (0)(1)(0)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011101 (0)(1)(0)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011110 (0)(1)(0)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01011111 (0)(1)(0)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100000 (0)(1)(1)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100001 (0)(1)(1)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100010 (0)(1)(1)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100011 (0)(1)(1)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100100 (0)(1)(1)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100101 (0)(1)(1)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100110 (0)(1)(1)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01100111 (0)(1)(1)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101000 (0)(1)(1)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101001 (0)(1)(1)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101010 (0)(1)(1)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101011 (0)(1)(1)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101100 (0)(1)(1)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101101 (0)(1)(1)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101110 (0)(1)(1)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01101111 (0)(1)(1)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110000 (0)(1)(1)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110001 (0)(1)(1)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110010 (0)(1)(1)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110011 (0)(1)(1)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110100 (0)(1)(1)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110101 (0)(1)(1)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110110 (0)(1)(1)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01110111 (0)(1)(1)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111000 (0)(1)(1)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111001 (0)(1)(1)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111010 (0)(1)(1)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111011 (0)(1)(1)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111100 (0)(1)(1)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111101 (0)(1)(1)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111110 (0)(1)(1)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01111111 (0)(1)(1)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000000 (1)(0)(0)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000001 (1)(0)(0)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000010 (1)(0)(0)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000011 (1)(0)(0)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000100 (1)(0)(0)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000101 (1)(0)(0)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000110 (1)(0)(0)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10000111 (1)(0)(0)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001000 (1)(0)(0)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001001 (1)(0)(0)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001010 (1)(0)(0)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001011 (1)(0)(0)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001100 (1)(0)(0)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001101 (1)(0)(0)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001110 (1)(0)(0)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10001111 (1)(0)(0)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010000 (1)(0)(0)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010001 (1)(0)(0)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010010 (1)(0)(0)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010011 (1)(0)(0)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010100 (1)(0)(0)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010101 (1)(0)(0)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010110 (1)(0)(0)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10010111 (1)(0)(0)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011000 (1)(0)(0)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011001 (1)(0)(0)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011010 (1)(0)(0)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011011 (1)(0)(0)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011100 (1)(0)(0)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011101 (1)(0)(0)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011110 (1)(0)(0)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10011111 (1)(0)(0)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100000 (1)(0)(1)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100001 (1)(0)(1)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100010 (1)(0)(1)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100011 (1)(0)(1)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100100 (1)(0)(1)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100101 (1)(0)(1)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100110 (1)(0)(1)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10100111 (1)(0)(1)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101000 (1)(0)(1)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101001 (1)(0)(1)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101010 (1)(0)(1)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101011 (1)(0)(1)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101100 (1)(0)(1)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101101 (1)(0)(1)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101110 (1)(0)(1)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10101111 (1)(0)(1)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110000 (1)(0)(1)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110001 (1)(0)(1)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110010 (1)(0)(1)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110011 (1)(0)(1)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110100 (1)(0)(1)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110101 (1)(0)(1)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110110 (1)(0)(1)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10110111 (1)(0)(1)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111000 (1)(0)(1)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111001 (1)(0)(1)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111010 (1)(0)(1)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111011 (1)(0)(1)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111100 (1)(0)(1)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111101 (1)(0)(1)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111110 (1)(0)(1)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_10111111 (1)(0)(1)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000000 (1)(1)(0)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000001 (1)(1)(0)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000010 (1)(1)(0)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000011 (1)(1)(0)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000100 (1)(1)(0)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000101 (1)(1)(0)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000110 (1)(1)(0)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11000111 (1)(1)(0)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001000 (1)(1)(0)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001001 (1)(1)(0)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001010 (1)(1)(0)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001011 (1)(1)(0)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001100 (1)(1)(0)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001101 (1)(1)(0)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001110 (1)(1)(0)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11001111 (1)(1)(0)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010000 (1)(1)(0)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010001 (1)(1)(0)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010010 (1)(1)(0)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010011 (1)(1)(0)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010100 (1)(1)(0)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010101 (1)(1)(0)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010110 (1)(1)(0)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11010111 (1)(1)(0)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011000 (1)(1)(0)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011001 (1)(1)(0)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011010 (1)(1)(0)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011011 (1)(1)(0)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011100 (1)(1)(0)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011101 (1)(1)(0)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011110 (1)(1)(0)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11011111 (1)(1)(0)(1)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100000 (1)(1)(1)(0)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100001 (1)(1)(1)(0)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100010 (1)(1)(1)(0)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100011 (1)(1)(1)(0)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100100 (1)(1)(1)(0)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100101 (1)(1)(1)(0)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100110 (1)(1)(1)(0)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11100111 (1)(1)(1)(0)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101000 (1)(1)(1)(0)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101001 (1)(1)(1)(0)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101010 (1)(1)(1)(0)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101011 (1)(1)(1)(0)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101100 (1)(1)(1)(0)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101101 (1)(1)(1)(0)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101110 (1)(1)(1)(0)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11101111 (1)(1)(1)(0)(1)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110000 (1)(1)(1)(1)(0)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110001 (1)(1)(1)(1)(0)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110010 (1)(1)(1)(1)(0)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110011 (1)(1)(1)(1)(0)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110100 (1)(1)(1)(1)(0)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110101 (1)(1)(1)(1)(0)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110110 (1)(1)(1)(1)(0)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11110111 (1)(1)(1)(1)(0)(1)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111000 (1)(1)(1)(1)(1)(0)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111001 (1)(1)(1)(1)(1)(0)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111010 (1)(1)(1)(1)(1)(0)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111011 (1)(1)(1)(1)(1)(0)(1)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111100 (1)(1)(1)(1)(1)(1)(0)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111101 (1)(1)(1)(1)(1)(1)(0)(1),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111110 (1)(1)(1)(1)(1)(1)(1)(0),
#define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111111 (1)(1)(1)(1)(1)(1)(1)(1),
#endif

View File

@ -0,0 +1,68 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#ifndef BOOST_UTILITY_COMPARE_POINTEES_25AGO2003_HPP
#define BOOST_UTILITY_COMPARE_POINTEES_25AGO2003_HPP
#include<functional>
namespace boost {
// template<class OP> bool equal_pointees(OP const& x, OP const& y);
// template<class OP> struct equal_pointees_t;
//
// Being OP a model of OptionalPointee (either a pointer or an optional):
//
// If both x and y have valid pointees, returns the result of (*x == *y)
// If only one has a valid pointee, returns false.
// If none have valid pointees, returns true.
// No-throw
template<class OptionalPointee>
inline
bool equal_pointees ( OptionalPointee const& x, OptionalPointee const& y )
{
return (!x) != (!y) ? false : ( !x ? true : (*x) == (*y) ) ;
}
template<class OptionalPointee>
struct equal_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
{
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
{ return equal_pointees(x,y) ; }
} ;
// template<class OP> bool less_pointees(OP const& x, OP const& y);
// template<class OP> struct less_pointees_t;
//
// Being OP a model of OptionalPointee (either a pointer or an optional):
//
// If y has not a valid pointee, returns false.
// ElseIf x has not a valid pointee, returns true.
// ElseIf both x and y have valid pointees, returns the result of (*x < *y)
// No-throw
template<class OptionalPointee>
inline
bool less_pointees ( OptionalPointee const& x, OptionalPointee const& y )
{
return !y ? false : ( !x ? true : (*x) < (*y) ) ;
}
template<class OptionalPointee>
struct less_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
{
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
{ return less_pointees(x,y) ; }
} ;
} // namespace boost
#endif

View File

@ -0,0 +1,36 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2007, Tobias Schwinger.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#ifndef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_04APR2007_HPP
#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_04APR2007_HPP
#include <new>
#include <cstddef>
#include <boost/config.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/punctuation/paren.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT(z,n,_) BOOST_PP_CAT(m_a,n) BOOST_PP_LPAREN() BOOST_PP_CAT(a,n) BOOST_PP_RPAREN()
#define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL(z,n,_) BOOST_PP_CAT(A,n) const& BOOST_PP_CAT(m_a,n);
#define BOOST_MAX_INPLACE_FACTORY_ARITY 10
#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_04APR2007_HPP
#endif

View File

@ -0,0 +1,23 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2007, Tobias Schwinger.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#ifndef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_04APR2007_HPP
#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_04APR2007_HPP
#undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT
#undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL
#undef BOOST_MAX_INPLACE_FACTORY_ARITY
#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_04APR2007_HPP
#endif

View File

@ -0,0 +1,221 @@
// Boost result_of library
// Copyright Douglas Gregor 2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel Walker, Eric Niebler, Michel Morin 2008-2012.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or
// copy at http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org/libs/utility
#if !defined(BOOST_PP_IS_ITERATING)
# error Boost result_of - do not include this file!
#endif
// CWPro8 requires an argument in a function type specialization
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0
# define BOOST_RESULT_OF_ARGS void
#else
# define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)
#endif
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
: mpl::if_<
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
, boost::detail::tr1_result_of_impl<
typename remove_cv<F>::type,
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
(boost::detail::has_result_type<F>::value)>
, boost::detail::tr1_result_of_impl<
F,
F(BOOST_RESULT_OF_ARGS),
(boost::detail::has_result_type<F>::value)> >::type { };
#endif
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of<F(BOOST_RESULT_OF_ARGS)>
: detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> { };
#endif // BOOST_RESULT_OF_USE_DECLTYPE
#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of<F(BOOST_RESULT_OF_ARGS)>
: mpl::if_<mpl::or_<detail::has_result_type<F>, detail::has_result<F> >,
tr1_result_of<F(BOOST_RESULT_OF_ARGS)>,
detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> >::type { };
#endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
namespace detail {
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
: mpl::if_<
is_member_function_pointer<F>
, detail::tr1_result_of_impl<
typename remove_cv<F>::type,
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
>
, detail::cpp0x_result_of_impl<
F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))
>
>::type
{};
#ifdef BOOST_NO_SFINAE_EXPR
template<typename F>
struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION());
template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)>
struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<R(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))> {
R operator()(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const;
typedef result_of_private_type const &(*pfn_t)(...);
operator pfn_t() const volatile;
};
template<typename F>
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION());
template<typename F>
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F *>
: BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
{};
template<typename F>
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F &>
: BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
{};
template<typename F>
struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())
: mpl::eval_if<
is_class<typename remove_reference<F>::type>,
result_of_wrap_callable_class<F>,
mpl::identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<F>::type> >
>
{};
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)>
struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) {
typedef typename BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())<F>::type wrapper_t;
static const bool value = (
sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_type(
(boost::declval<wrapper_t>()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)), result_of_weird_type())
))
);
typedef mpl::bool_<value> type;
};
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), true>
: lazy_enable_if<
BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION())<F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), T)>
, cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false>
>
{};
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false>
{
typedef decltype(
boost::declval<F>()(
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)
)
) type;
};
#else // BOOST_NO_SFINAE_EXPR
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)),
typename result_of_always_void<decltype(
boost::declval<F>()(
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)
)
)>::type> {
typedef decltype(
boost::declval<F>()(
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)
)
) type;
};
#endif // BOOST_NO_SFINAE_EXPR
} // namespace detail
#else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of<F(BOOST_RESULT_OF_ARGS)>
: tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { };
#endif
#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE)
#undef BOOST_RESULT_OF_ARGS
#if BOOST_PP_ITERATION() >= 1
namespace detail {
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
{
typedef R type;
};
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
{
typedef R type;
};
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
FArgs, false>
{
typedef R type;
};
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
const,
FArgs, false>
{
typedef R type;
};
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
volatile,
FArgs, false>
{
typedef R type;
};
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
const volatile,
FArgs, false>
{
typedef R type;
};
#endif
}
#endif

View File

@ -0,0 +1,46 @@
// Copyright (C) 2009-2012 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0
// (see accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Home at http://www.boost.org/libs/utility/identity_type
/** @file
Wrap type expressions with round parenthesis so they can be passed to macros
even if they contain commas.
*/
#ifndef BOOST_IDENTITY_TYPE_HPP_
#define BOOST_IDENTITY_TYPE_HPP_
#include <boost/type_traits/function_traits.hpp>
/**
@brief This macro allows to wrap the specified type expression within extra
round parenthesis so the type can be passed as a single macro parameter even if
it contains commas (not already wrapped within round parenthesis).
@Params
@Param{parenthesized_type,
The type expression to be passed as macro parameter wrapped by a single set
of round parenthesis <c>(...)</c>.
This type expression can contain an arbitrary number of commas.
}
@EndParams
This macro works on any C++03 compiler (it does not use variadic macros).
This macro must be prefixed by <c>typename</c> when used within templates.
Note that the compiler will not be able to automatically determine function
template parameters when they are wrapped with this macro (these parameters
need to be explicitly specified when calling the function template).
On some compilers (like GCC), using this macro on abstract types requires to
add and remove a reference to the specified type.
*/
#define BOOST_IDENTITY_TYPE(parenthesized_type) \
/* must NOT prefix this with `::` to work with parenthesized syntax */ \
boost::function_traits< void parenthesized_type >::arg1_type
#endif // #include guard

View File

@ -0,0 +1,86 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2007, Tobias Schwinger.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#ifndef BOOST_UTILITY_INPLACE_FACTORY_04APR2007_HPP
#ifndef BOOST_PP_IS_ITERATING
#include <boost/utility/detail/in_place_factory_prefix.hpp>
namespace boost {
class in_place_factory_base {} ;
#define BOOST_PP_ITERATION_LIMITS (0, BOOST_MAX_INPLACE_FACTORY_ARITY)
#define BOOST_PP_FILENAME_1 <boost/utility/in_place_factory.hpp>
#include BOOST_PP_ITERATE()
} // namespace boost
#include <boost/utility/detail/in_place_factory_suffix.hpp>
#define BOOST_UTILITY_INPLACE_FACTORY_04APR2007_HPP
#else
#define N BOOST_PP_ITERATION()
#if N
template< BOOST_PP_ENUM_PARAMS(N, class A) >
#endif
class BOOST_PP_CAT(in_place_factory,N)
:
public in_place_factory_base
{
public:
explicit BOOST_PP_CAT(in_place_factory,N)
( BOOST_PP_ENUM_BINARY_PARAMS(N,A,const& a) )
#if N > 0
: BOOST_PP_ENUM(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _)
#endif
{}
template<class T>
void* apply(void* address) const
{
return new(address) T( BOOST_PP_ENUM_PARAMS(N, m_a) );
}
template<class T>
void* apply(void* address, std::size_t n) const
{
for(char* next = address = this->BOOST_NESTED_TEMPLATE apply<T>(address);
!! --n;)
this->BOOST_NESTED_TEMPLATE apply<T>(next = next+sizeof(T));
return address;
}
BOOST_PP_REPEAT(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _)
};
#if N > 0
template< BOOST_PP_ENUM_PARAMS(N, class A) >
inline BOOST_PP_CAT(in_place_factory,N)< BOOST_PP_ENUM_PARAMS(N, A) >
in_place( BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a) )
{
return BOOST_PP_CAT(in_place_factory,N)< BOOST_PP_ENUM_PARAMS(N, A) >
( BOOST_PP_ENUM_PARAMS(N, a) );
}
#else
inline in_place_factory0 in_place()
{
return in_place_factory0();
}
#endif
#undef N
#endif
#endif

View File

@ -0,0 +1,210 @@
// Boost result_of library
// Copyright Douglas Gregor 2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org/libs/utility
#ifndef BOOST_RESULT_OF_HPP
#define BOOST_RESULT_OF_HPP
#include <boost/config.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/declval.hpp>
#include <boost/utility/enable_if.hpp>
#ifndef BOOST_RESULT_OF_NUM_ARGS
# define BOOST_RESULT_OF_NUM_ARGS 16
#endif
// Use the decltype-based version of result_of by default if the compiler
// supports N3276 <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf>.
// The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE,
// BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one!
#if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \
(defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \
(defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK))
# error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \
BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time.
#endif
#if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
# error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined.
#endif
#ifndef BOOST_RESULT_OF_USE_TR1
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
# define BOOST_RESULT_OF_USE_DECLTYPE
# else
# define BOOST_RESULT_OF_USE_TR1
# endif
# endif
# endif
#endif
namespace boost {
template<typename F> struct result_of;
template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of
#if !defined(BOOST_NO_SFINAE)
namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
// Work around a nvcc bug by only defining has_result when it's needed.
#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result)
#endif
template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
template<typename F> struct cpp0x_result_of;
#ifdef BOOST_NO_SFINAE_EXPR
// There doesn't seem to be any other way to turn this off such that the presence of
// the user-defined operator,() below doesn't cause spurious warning all over the place,
// so unconditionally turn it off.
#if BOOST_MSVC
# pragma warning(disable: 4913) // user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used
#endif
struct result_of_private_type {};
struct result_of_weird_type {
friend result_of_private_type operator,(result_of_private_type, result_of_weird_type);
};
typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1
typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2
template<typename T>
result_of_no_type result_of_is_private_type(T const &);
result_of_yes_type result_of_is_private_type(result_of_private_type);
template<typename C>
struct result_of_callable_class : C {
result_of_callable_class();
typedef result_of_private_type const &(*pfn_t)(...);
operator pfn_t() const volatile;
};
template<typename C>
struct result_of_wrap_callable_class {
typedef result_of_callable_class<C> type;
};
template<typename C>
struct result_of_wrap_callable_class<C const> {
typedef result_of_callable_class<C> const type;
};
template<typename C>
struct result_of_wrap_callable_class<C volatile> {
typedef result_of_callable_class<C> volatile type;
};
template<typename C>
struct result_of_wrap_callable_class<C const volatile> {
typedef result_of_callable_class<C> const volatile type;
};
template<typename C>
struct result_of_wrap_callable_class<C &> {
typedef typename result_of_wrap_callable_class<C>::type &type;
};
template<typename F, bool TestCallability = true> struct cpp0x_result_of_impl;
#else // BOOST_NO_SFINAE_EXPR
template<typename T>
struct result_of_always_void
{
typedef void type;
};
template<typename F, typename Enable = void> struct cpp0x_result_of_impl {};
#endif // BOOST_NO_SFINAE_EXPR
template<typename F>
struct result_of_void_impl
{
typedef void type;
};
template<typename R>
struct result_of_void_impl<R (*)(void)>
{
typedef R type;
};
template<typename R>
struct result_of_void_impl<R (&)(void)>
{
typedef R type;
};
// Determine the return type of a function pointer or pointer to member.
template<typename F, typename FArgs>
struct result_of_pointer
: tr1_result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
template<typename F, typename FArgs>
struct tr1_result_of_impl<F, FArgs, true>
{
typedef typename F::result_type type;
};
template<typename FArgs>
struct is_function_with_no_args : mpl::false_ {};
template<typename F>
struct is_function_with_no_args<F(void)> : mpl::true_ {};
template<typename F, typename FArgs>
struct result_of_nested_result : F::template result<FArgs>
{};
template<typename F, typename FArgs>
struct tr1_result_of_impl<F, FArgs, false>
: mpl::if_<is_function_with_no_args<FArgs>,
result_of_void_impl<F>,
result_of_nested_result<F, FArgs> >::type
{};
} // end namespace detail
#define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))
#include BOOST_PP_ITERATE()
#else
# define BOOST_NO_RESULT_OF 1
#endif
}
#endif // BOOST_RESULT_OF_HPP

View File

@ -0,0 +1,548 @@
/*
Copyright (c) Marshall Clow 2012-2015.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
Based on the StringRef implementation in LLVM (http://llvm.org) and
N3422 by Jeffrey Yasskin
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
*/
#ifndef BOOST_STRING_REF_HPP
#define BOOST_STRING_REF_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/string_ref_fwd.hpp>
#include <boost/throw_exception.hpp>
#include <cstddef>
#include <stdexcept>
#include <algorithm>
#include <iterator>
#include <string>
#include <iosfwd>
#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
// GCC 4.6 cannot handle a defaulted function with noexcept specifier
#define BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
#endif
namespace boost {
namespace detail {
// A helper functor because sometimes we don't have lambdas
template <typename charT, typename traits>
class string_ref_traits_eq {
public:
string_ref_traits_eq ( charT ch ) : ch_(ch) {}
bool operator () ( charT val ) const { return traits::eq ( ch_, val ); }
charT ch_;
};
}
template<typename charT, typename traits>
class basic_string_ref {
public:
// types
typedef charT value_type;
typedef const charT* pointer;
typedef const charT& reference;
typedef const charT& const_reference;
typedef pointer const_iterator; // impl-defined
typedef const_iterator iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef const_reverse_iterator reverse_iterator;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
// construct/copy
BOOST_CONSTEXPR basic_string_ref () BOOST_NOEXCEPT
: ptr_(NULL), len_(0) {}
// by defaulting these functions, basic_string_ref becomes
// trivially copy/move constructible.
BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs) BOOST_NOEXCEPT
#ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
= default;
#else
: ptr_(rhs.ptr_), len_(rhs.len_) {}
#endif
basic_string_ref& operator=(const basic_string_ref &rhs) BOOST_NOEXCEPT
#ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
= default;
#else
{
ptr_ = rhs.ptr_;
len_ = rhs.len_;
return *this;
}
#endif
basic_string_ref(const charT* str) BOOST_NOEXCEPT
: ptr_(str), len_(traits::length(str)) {}
template<typename Allocator>
basic_string_ref(const std::basic_string<charT, traits, Allocator>& str)
: ptr_(str.data()), len_(str.length()) {}
BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) BOOST_NOEXCEPT
: ptr_(str), len_(len) {}
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
template<typename Allocator>
explicit operator std::basic_string<charT, traits, Allocator>() const {
return std::basic_string<charT, traits, Allocator> ( begin(), end());
}
#endif
std::basic_string<charT, traits> to_string () const {
return std::basic_string<charT, traits> ( begin(), end());
}
// iterators
BOOST_CONSTEXPR const_iterator begin() const { return ptr_; }
BOOST_CONSTEXPR const_iterator cbegin() const { return ptr_; }
BOOST_CONSTEXPR const_iterator end() const { return ptr_ + len_; }
BOOST_CONSTEXPR const_iterator cend() const { return ptr_ + len_; }
const_reverse_iterator rbegin() const { return const_reverse_iterator (end()); }
const_reverse_iterator crbegin() const { return const_reverse_iterator (end()); }
const_reverse_iterator rend() const { return const_reverse_iterator (begin()); }
const_reverse_iterator crend() const { return const_reverse_iterator (begin()); }
// capacity
BOOST_CONSTEXPR size_type size() const { return len_; }
BOOST_CONSTEXPR size_type length() const { return len_; }
BOOST_CONSTEXPR size_type max_size() const { return len_; }
BOOST_CONSTEXPR bool empty() const { return len_ == 0; }
// element access
BOOST_CONSTEXPR const charT& operator[](size_type pos) const { return ptr_[pos]; }
const charT& at(size_t pos) const {
if ( pos >= len_ )
BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_ref::at" ) );
return ptr_[pos];
}
BOOST_CONSTEXPR const charT& front() const { return ptr_[0]; }
BOOST_CONSTEXPR const charT& back() const { return ptr_[len_-1]; }
BOOST_CONSTEXPR const charT* data() const { return ptr_; }
// modifiers
void clear() { len_ = 0; }
void remove_prefix(size_type n) {
if ( n > len_ )
n = len_;
ptr_ += n;
len_ -= n;
}
void remove_suffix(size_type n) {
if ( n > len_ )
n = len_;
len_ -= n;
}
// basic_string_ref string operations
basic_string_ref substr(size_type pos, size_type n=npos) const {
if ( pos > size())
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) );
if ( n == npos || pos + n > size())
n = size () - pos;
return basic_string_ref ( data() + pos, n );
}
int compare(basic_string_ref x) const {
const int cmp = traits::compare ( ptr_, x.ptr_, (std::min)(len_, x.len_));
return cmp != 0 ? cmp : ( len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1 );
}
bool starts_with(charT c) const { return !empty() && traits::eq ( c, front()); }
bool starts_with(basic_string_ref x) const {
return len_ >= x.len_ && traits::compare ( ptr_, x.ptr_, x.len_ ) == 0;
}
bool ends_with(charT c) const { return !empty() && traits::eq ( c, back()); }
bool ends_with(basic_string_ref x) const {
return len_ >= x.len_ && traits::compare ( ptr_ + len_ - x.len_, x.ptr_, x.len_ ) == 0;
}
size_type find(basic_string_ref s) const {
const_iterator iter = std::search ( this->cbegin (), this->cend (),
s.cbegin (), s.cend (), traits::eq );
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
}
size_type find(charT c) const {
const_iterator iter = std::find_if ( this->cbegin (), this->cend (),
detail::string_ref_traits_eq<charT, traits> ( c ));
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
}
size_type rfind(basic_string_ref s) const {
const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (),
s.crbegin (), s.crend (), traits::eq );
return iter == this->crend () ? npos : (std::distance(iter, this->crend()) - s.size());
}
size_type rfind(charT c) const {
const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (),
detail::string_ref_traits_eq<charT, traits> ( c ));
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
}
size_type find_first_of(charT c) const { return find (c); }
size_type find_last_of (charT c) const { return rfind (c); }
size_type find_first_of(basic_string_ref s) const {
const_iterator iter = std::find_first_of
( this->cbegin (), this->cend (), s.cbegin (), s.cend (), traits::eq );
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
}
size_type find_last_of(basic_string_ref s) const {
const_reverse_iterator iter = std::find_first_of
( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq );
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
}
size_type find_first_not_of(basic_string_ref s) const {
const_iterator iter = find_not_of ( this->cbegin (), this->cend (), s );
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
}
size_type find_first_not_of(charT c) const {
for ( const_iterator iter = this->cbegin (); iter != this->cend (); ++iter )
if ( !traits::eq ( c, *iter ))
return std::distance ( this->cbegin (), iter );
return npos;
}
size_type find_last_not_of(basic_string_ref s) const {
const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
}
size_type find_last_not_of(charT c) const {
for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter )
if ( !traits::eq ( c, *iter ))
return this->size() - 1 - std::distance(this->crbegin(), iter);
return npos;
}
private:
template <typename Iterator>
Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
for ( ; first != last ; ++first )
if ( 0 == traits::find ( s.ptr_, s.len_, *first ))
return first;
return last;
}
const charT *ptr_;
std::size_t len_;
};
// Comparison operators
// Equality
template<typename charT, typename traits>
inline bool operator==(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
if ( x.size () != y.size ()) return false;
return x.compare(y) == 0;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator==(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x == basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator==(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) == y;
}
template<typename charT, typename traits>
inline bool operator==(basic_string_ref<charT, traits> x, const charT * y) {
return x == basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator==(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) == y;
}
// Inequality
template<typename charT, typename traits>
inline bool operator!=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
if ( x.size () != y.size ()) return true;
return x.compare(y) != 0;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator!=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x != basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator!=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) != y;
}
template<typename charT, typename traits>
inline bool operator!=(basic_string_ref<charT, traits> x, const charT * y) {
return x != basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator!=(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) != y;
}
// Less than
template<typename charT, typename traits>
inline bool operator<(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
return x.compare(y) < 0;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator<(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x < basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator<(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) < y;
}
template<typename charT, typename traits>
inline bool operator<(basic_string_ref<charT, traits> x, const charT * y) {
return x < basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator<(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) < y;
}
// Greater than
template<typename charT, typename traits>
inline bool operator>(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
return x.compare(y) > 0;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator>(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x > basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator>(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) > y;
}
template<typename charT, typename traits>
inline bool operator>(basic_string_ref<charT, traits> x, const charT * y) {
return x > basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator>(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) > y;
}
// Less than or equal to
template<typename charT, typename traits>
inline bool operator<=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
return x.compare(y) <= 0;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator<=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x <= basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator<=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) <= y;
}
template<typename charT, typename traits>
inline bool operator<=(basic_string_ref<charT, traits> x, const charT * y) {
return x <= basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator<=(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) <= y;
}
// Greater than or equal to
template<typename charT, typename traits>
inline bool operator>=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
return x.compare(y) >= 0;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator>=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x >= basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator>=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) >= y;
}
template<typename charT, typename traits>
inline bool operator>=(basic_string_ref<charT, traits> x, const charT * y) {
return x >= basic_string_ref<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator>=(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) >= y;
}
namespace detail {
template<class charT, class traits>
inline void sr_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
enum { chunk_size = 8 };
charT fill_chars[chunk_size];
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
for (; n >= chunk_size && os.good(); n -= chunk_size)
os.write(fill_chars, static_cast< std::size_t >(chunk_size));
if (n > 0 && os.good())
os.write(fill_chars, n);
}
template<class charT, class traits>
void sr_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
const std::size_t size = str.size();
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
if (!align_left) {
detail::sr_insert_fill_chars(os, alignment_size);
if (os.good())
os.write(str.data(), size);
}
else {
os.write(str.data(), size);
if (os.good())
detail::sr_insert_fill_chars(os, alignment_size);
}
}
} // namespace detail
// Inserter
template<class charT, class traits>
inline std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
if (os.good()) {
const std::size_t size = str.size();
const std::size_t w = static_cast< std::size_t >(os.width());
if (w <= size)
os.write(str.data(), size);
else
detail::sr_insert_aligned(os, str);
os.width(0);
}
return os;
}
#if 0
// numeric conversions
//
// These are short-term implementations.
// In a production environment, I would rather avoid the copying.
//
inline int stoi (string_ref str, size_t* idx=0, int base=10) {
return std::stoi ( std::string(str), idx, base );
}
inline long stol (string_ref str, size_t* idx=0, int base=10) {
return std::stol ( std::string(str), idx, base );
}
inline unsigned long stoul (string_ref str, size_t* idx=0, int base=10) {
return std::stoul ( std::string(str), idx, base );
}
inline long long stoll (string_ref str, size_t* idx=0, int base=10) {
return std::stoll ( std::string(str), idx, base );
}
inline unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) {
return std::stoull ( std::string(str), idx, base );
}
inline float stof (string_ref str, size_t* idx=0) {
return std::stof ( std::string(str), idx );
}
inline double stod (string_ref str, size_t* idx=0) {
return std::stod ( std::string(str), idx );
}
inline long double stold (string_ref str, size_t* idx=0) {
return std::stold ( std::string(str), idx );
}
inline int stoi (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoi ( std::wstring(str), idx, base );
}
inline long stol (wstring_ref str, size_t* idx=0, int base=10) {
return std::stol ( std::wstring(str), idx, base );
}
inline unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoul ( std::wstring(str), idx, base );
}
inline long long stoll (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoll ( std::wstring(str), idx, base );
}
inline unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoull ( std::wstring(str), idx, base );
}
inline float stof (wstring_ref str, size_t* idx=0) {
return std::stof ( std::wstring(str), idx );
}
inline double stod (wstring_ref str, size_t* idx=0) {
return std::stod ( std::wstring(str), idx );
}
inline long double stold (wstring_ref str, size_t* idx=0) {
return std::stold ( std::wstring(str), idx );
}
#endif
}
#if 0
namespace std {
// Hashing
template<> struct hash<boost::string_ref>;
template<> struct hash<boost::u16string_ref>;
template<> struct hash<boost::u32string_ref>;
template<> struct hash<boost::wstring_ref>;
}
#endif
#endif

View File

@ -0,0 +1,37 @@
/*
Copyright (c) Marshall Clow 2012-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
Based on the StringRef implementation in LLVM (http://llvm.org) and
N3422 by Jeffrey Yasskin
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
*/
#ifndef BOOST_STRING_REF_FWD_HPP
#define BOOST_STRING_REF_FWD_HPP
#include <boost/config.hpp>
#include <string>
namespace boost {
template<typename charT, typename traits = std::char_traits<charT> > class basic_string_ref;
typedef basic_string_ref<char, std::char_traits<char> > string_ref;
typedef basic_string_ref<wchar_t, std::char_traits<wchar_t> > wstring_ref;
#ifndef BOOST_NO_CXX11_CHAR16_T
typedef basic_string_ref<char16_t, std::char_traits<char16_t> > u16string_ref;
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
typedef basic_string_ref<char32_t, std::char_traits<char32_t> > u32string_ref;
#endif
}
#endif

View File

@ -0,0 +1,691 @@
/*
<20> Copyright (c) Marshall Clow 2012-2015.
<20> Copyright Beman Dawes 2015
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
Based on the StringRef implementation in LLVM (http://llvm.org) and
N3422 by Jeffrey Yasskin
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
Updated July 2015 to reflect the Library Fundamentals TS
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html
*/
#ifndef BOOST_STRING_VIEW_HPP
#define BOOST_STRING_VIEW_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/string_view_fwd.hpp>
#include <boost/throw_exception.hpp>
#include <cstddef>
#include <stdexcept>
#include <algorithm>
#include <iterator>
#include <string>
#include <cstring>
#include <iosfwd>
#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
// GCC 4.6 cannot handle a defaulted function with noexcept specifier
#define BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
#endif
namespace boost {
namespace detail {
// A helper functor because sometimes we don't have lambdas
template <typename charT, typename traits>
class string_view_traits_eq {
public:
string_view_traits_eq ( charT ch ) : ch_(ch) {}
bool operator()( charT val ) const { return traits::eq (ch_, val); }
charT ch_;
};
}
template<typename charT, typename traits> // traits defaulted in string_view_fwd.hpp
class basic_string_view {
public:
// types
typedef traits traits_type;
typedef charT value_type;
typedef charT* pointer;
typedef const charT* const_pointer;
typedef charT& reference;
typedef const charT& const_reference;
typedef const_pointer const_iterator; // impl-defined
typedef const_iterator iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef const_reverse_iterator reverse_iterator;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
// construct/copy
BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT
: ptr_(NULL), len_(0) {}
// by defaulting these functions, basic_string_ref becomes
// trivially copy/move constructible.
BOOST_CONSTEXPR basic_string_view(const basic_string_view &rhs) BOOST_NOEXCEPT
#ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
= default;
#else
: ptr_(rhs.ptr_), len_(rhs.len_) {}
#endif
basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT
#ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
= default;
#else
{
ptr_ = rhs.ptr_;
len_ = rhs.len_;
return *this;
}
#endif
template<typename Allocator>
basic_string_view(const std::basic_string<charT, traits,
Allocator>& str) BOOST_NOEXCEPT
: ptr_(str.data()), len_(str.length()) {}
BOOST_CONSTEXPR basic_string_view(const charT* str)
: ptr_(str), len_(traits::length(str)) {}
BOOST_CONSTEXPR basic_string_view(const charT* str, size_type len)
: ptr_(str), len_(len) {}
// iterators
BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return ptr_; }
BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return ptr_; }
BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return ptr_ + len_; }
BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return ptr_ + len_; }
const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
// capacity
BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return len_; }
BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return len_; }
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return len_; }
BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT { return len_ == 0; }
// element access
BOOST_CONSTEXPR const_reference operator[](size_type pos) const BOOST_NOEXCEPT { return ptr_[pos]; }
BOOST_CONSTEXPR const_reference at(size_t pos) const {
return pos >= len_ ? BOOST_THROW_EXCEPTION(std::out_of_range("boost::string_view::at")) : ptr_[pos];
// if ( pos >= len_ )
// BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_view::at" ) );
// return ptr_[pos];
}
BOOST_CONSTEXPR const_reference front() const { return ptr_[0]; }
BOOST_CONSTEXPR const_reference back() const { return ptr_[len_-1]; }
BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return ptr_; }
// modifiers
void clear() BOOST_NOEXCEPT { len_ = 0; } // Boost extension
BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n) {
if ( n > len_ )
n = len_;
ptr_ += n;
len_ -= n;
}
BOOST_CXX14_CONSTEXPR void remove_suffix(size_type n) {
if ( n > len_ )
n = len_;
len_ -= n;
}
BOOST_CXX14_CONSTEXPR void swap(basic_string_view& s) BOOST_NOEXCEPT {
std::swap(ptr_, s.ptr_);
std::swap(len_, s.len_);
}
// basic_string_view string operations
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
template<typename Allocator>
explicit operator std::basic_string<charT, traits, Allocator>() const {
return std::basic_string<charT, traits, Allocator>(begin(), end());
}
#endif
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
template<typename Allocator = std::allocator<charT> >
std::basic_string<charT, traits, Allocator> to_string(const Allocator& a = Allocator()) const {
return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
}
#else
std::basic_string<charT, traits> to_string() const {
return std::basic_string<charT, traits>(begin(), end());
}
template<typename Allocator>
std::basic_string<charT, traits, Allocator> to_string(const Allocator& a) const {
return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
}
#endif
size_type copy(charT* s, size_type n, size_type pos=0) const {
if (pos > size())
BOOST_THROW_EXCEPTION(std::out_of_range("string_view::copy" ));
size_type rlen = (std::min)(n, len_ - pos);
// use std::copy(begin() + pos, begin() + pos + rlen, s) rather than
// std::copy_n(begin() + pos, rlen, s) to support pre-C++11 standard libraries
std::copy(begin() + pos, begin() + pos + rlen, s);
return rlen;
}
BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const {
if ( pos > size())
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) );
if (n == npos || pos + n > size())
n = size () - pos;
return basic_string_view(data() + pos, n);
}
BOOST_CXX14_CONSTEXPR int compare(basic_string_view x) const BOOST_NOEXCEPT {
const int cmp = traits::compare(ptr_, x.ptr_, (std::min)(len_, x.len_));
return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1);
}
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view x)
const BOOST_NOEXCEPT {
return substr(pos1, n1).compare(x);
}
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
basic_string_view x, size_type pos2, size_type n2) const {
return substr(pos1, n1).compare(x.substr(pos2, n2));
}
BOOST_CXX14_CONSTEXPR int compare(const charT* x) const {
return compare(basic_string_view(x));
}
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, const charT* x) const {
return substr(pos1, n1).compare(basic_string_view(x));
}
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
const charT* x, size_type n2) const {
return substr(pos1, n1).compare(basic_string_view(x, n2));
}
// Searches
BOOST_CONSTEXPR bool starts_with(charT c) const BOOST_NOEXCEPT { // Boost extension
return !empty() && traits::eq(c, front());
}
BOOST_CONSTEXPR bool starts_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
return len_ >= x.len_ && traits::compare(ptr_, x.ptr_, x.len_) == 0;
}
BOOST_CONSTEXPR bool ends_with(charT c) const BOOST_NOEXCEPT { // Boost extension
return !empty() && traits::eq(c, back());
}
BOOST_CONSTEXPR bool ends_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
return len_ >= x.len_ &&
traits::compare(ptr_ + len_ - x.len_, x.ptr_, x.len_) == 0;
}
// find
BOOST_CXX14_CONSTEXPR size_type find(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
if (pos > size())
return npos;
if (s.empty())
return pos;
const_iterator iter = std::search(this->cbegin() + pos, this->cend(),
s.cbegin (), s.cend (), traits::eq);
return iter == this->cend () ? npos : std::distance(this->cbegin (), iter);
}
BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT
{ return find(basic_string_view(&c, 1), pos); }
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
{ return find(basic_string_view(s, n), pos); }
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
{ return find(basic_string_view(s), pos); }
// rfind
BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
if (len_ < s.len_)
return npos;
if (pos > len_ - s.len_)
pos = len_ - s.len_;
if (s.len_ == 0u) // an empty string is always found
return pos;
for (const charT* cur = ptr_ + pos; ; --cur) {
if (traits::compare(cur, s.ptr_, s.len_) == 0)
return cur - ptr_;
if (cur == ptr_)
return npos;
};
}
BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT
{ return rfind(basic_string_view(&c, 1), pos); }
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
{ return rfind(basic_string_view(s, n), pos); }
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
{ return rfind(basic_string_view(s), pos); }
// find_first_of
BOOST_CXX14_CONSTEXPR size_type find_first_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
if (pos >= len_ || s.len_ == 0)
return npos;
const_iterator iter = std::find_first_of
(this->cbegin () + pos, this->cend (), s.cbegin (), s.cend (), traits::eq);
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
}
BOOST_CXX14_CONSTEXPR size_type find_first_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
{ return find_first_of(basic_string_view(&c, 1), pos); }
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
{ return find_first_of(basic_string_view(s, n), pos); }
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
{ return find_first_of(basic_string_view(s), pos); }
// find_last_of
BOOST_CXX14_CONSTEXPR size_type find_last_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
if (s.len_ == 0u)
return npos;
if (pos >= len_)
pos = 0;
else
pos = len_ - (pos+1);
const_reverse_iterator iter = std::find_first_of
( this->crbegin () + pos, this->crend (), s.cbegin (), s.cend (), traits::eq );
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
}
BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
{ return find_last_of(basic_string_view(&c, 1), pos); }
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
{ return find_last_of(basic_string_view(s, n), pos); }
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
{ return find_last_of(basic_string_view(s), pos); }
// find_first_not_of
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
if (pos >= len_)
return npos;
if (s.len_ == 0)
return pos;
const_iterator iter = find_not_of ( this->cbegin () + pos, this->cend (), s );
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
}
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
{ return find_first_not_of(basic_string_view(&c, 1), pos); }
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
{ return find_first_not_of(basic_string_view(s, n), pos); }
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
{ return find_first_not_of(basic_string_view(s), pos); }
// find_last_not_of
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
if (pos >= len_)
pos = len_ - 1;
if (s.len_ == 0u)
return pos;
pos = len_ - (pos+1);
const_reverse_iterator iter = find_not_of ( this->crbegin () + pos, this->crend (), s );
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
}
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
{ return find_last_not_of(basic_string_view(&c, 1), pos); }
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
{ return find_last_not_of(basic_string_view(s, n), pos); }
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
{ return find_last_not_of(basic_string_view(s), pos); }
private:
template <typename r_iter>
size_type reverse_distance(r_iter first, r_iter last) const BOOST_NOEXCEPT {
// Portability note here: std::distance is not NOEXCEPT, but calling it with a string_view::reverse_iterator will not throw.
return len_ - 1 - std::distance ( first, last );
}
template <typename Iterator>
Iterator find_not_of(Iterator first, Iterator last, basic_string_view s) const BOOST_NOEXCEPT {
for (; first != last ; ++first)
if ( 0 == traits::find(s.ptr_, s.len_, *first))
return first;
return last;
}
const charT *ptr_;
std::size_t len_;
};
// Comparison operators
// Equality
template<typename charT, typename traits>
inline bool operator==(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
if (x.size () != y.size ()) return false;
return x.compare(y) == 0;
}
// Inequality
template<typename charT, typename traits>
inline bool operator!=(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
if ( x.size () != y.size ()) return true;
return x.compare(y) != 0;
}
// Less than
template<typename charT, typename traits>
inline bool operator<(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return x.compare(y) < 0;
}
// Greater than
template<typename charT, typename traits>
inline bool operator>(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return x.compare(y) > 0;
}
// Less than or equal to
template<typename charT, typename traits>
inline bool operator<=(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return x.compare(y) <= 0;
}
// Greater than or equal to
template<typename charT, typename traits>
inline bool operator>=(basic_string_view<charT, traits> x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return x.compare(y) >= 0;
}
// "sufficient additional overloads of comparison functions"
template<typename charT, typename traits, typename Allocator>
inline bool operator==(basic_string_view<charT, traits> x,
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
return x == basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator==(const std::basic_string<charT, traits, Allocator> & x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) == y;
}
template<typename charT, typename traits>
inline bool operator==(basic_string_view<charT, traits> x,
const charT * y) BOOST_NOEXCEPT {
return x == basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator==(const charT * x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) == y;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator!=(basic_string_view<charT, traits> x,
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
return x != basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator!=(const std::basic_string<charT, traits, Allocator> & x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) != y;
}
template<typename charT, typename traits>
inline bool operator!=(basic_string_view<charT, traits> x,
const charT * y) BOOST_NOEXCEPT {
return x != basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator!=(const charT * x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) != y;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator<(basic_string_view<charT, traits> x,
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
return x < basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator<(const std::basic_string<charT, traits, Allocator> & x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) < y;
}
template<typename charT, typename traits>
inline bool operator<(basic_string_view<charT, traits> x,
const charT * y) BOOST_NOEXCEPT {
return x < basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator<(const charT * x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) < y;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator>(basic_string_view<charT, traits> x,
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
return x > basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator>(const std::basic_string<charT, traits, Allocator> & x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) > y;
}
template<typename charT, typename traits>
inline bool operator>(basic_string_view<charT, traits> x,
const charT * y) BOOST_NOEXCEPT {
return x > basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator>(const charT * x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) > y;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator<=(basic_string_view<charT, traits> x,
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
return x <= basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator<=(const std::basic_string<charT, traits, Allocator> & x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) <= y;
}
template<typename charT, typename traits>
inline bool operator<=(basic_string_view<charT, traits> x,
const charT * y) BOOST_NOEXCEPT {
return x <= basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator<=(const charT * x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) <= y;
}
template<typename charT, typename traits, typename Allocator>
inline bool operator>=(basic_string_view<charT, traits> x,
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
return x >= basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits, typename Allocator>
inline bool operator>=(const std::basic_string<charT, traits, Allocator> & x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) >= y;
}
template<typename charT, typename traits>
inline bool operator>=(basic_string_view<charT, traits> x,
const charT * y) BOOST_NOEXCEPT {
return x >= basic_string_view<charT, traits>(y);
}
template<typename charT, typename traits>
inline bool operator>=(const charT * x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) >= y;
}
namespace detail {
template<class charT, class traits>
inline void sv_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
enum { chunk_size = 8 };
charT fill_chars[chunk_size];
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
for (; n >= chunk_size && os.good(); n -= chunk_size)
os.write(fill_chars, static_cast< std::size_t >(chunk_size));
if (n > 0 && os.good())
os.write(fill_chars, n);
}
template<class charT, class traits>
void sv_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_view<charT,traits>& str) {
const std::size_t size = str.size();
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
if (!align_left) {
detail::sv_insert_fill_chars(os, alignment_size);
if (os.good())
os.write(str.data(), size);
}
else {
os.write(str.data(), size);
if (os.good())
detail::sv_insert_fill_chars(os, alignment_size);
}
}
} // namespace detail
// Inserter
template<class charT, class traits>
inline std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const basic_string_view<charT,traits>& str) {
if (os.good()) {
const std::size_t size = str.size();
const std::size_t w = static_cast< std::size_t >(os.width());
if (w <= size)
os.write(str.data(), size);
else
detail::sv_insert_aligned(os, str);
os.width(0);
}
return os;
}
#if 0
// numeric conversions
//
// These are short-term implementations.
// In a production environment, I would rather avoid the copying.
//
inline int stoi (string_view str, size_t* idx=0, int base=10) {
return std::stoi ( std::string(str), idx, base );
}
inline long stol (string_view str, size_t* idx=0, int base=10) {
return std::stol ( std::string(str), idx, base );
}
inline unsigned long stoul (string_view str, size_t* idx=0, int base=10) {
return std::stoul ( std::string(str), idx, base );
}
inline long long stoll (string_view str, size_t* idx=0, int base=10) {
return std::stoll ( std::string(str), idx, base );
}
inline unsigned long long stoull (string_view str, size_t* idx=0, int base=10) {
return std::stoull ( std::string(str), idx, base );
}
inline float stof (string_view str, size_t* idx=0) {
return std::stof ( std::string(str), idx );
}
inline double stod (string_view str, size_t* idx=0) {
return std::stod ( std::string(str), idx );
}
inline long double stold (string_view str, size_t* idx=0) {
return std::stold ( std::string(str), idx );
}
inline int stoi (wstring_view str, size_t* idx=0, int base=10) {
return std::stoi ( std::wstring(str), idx, base );
}
inline long stol (wstring_view str, size_t* idx=0, int base=10) {
return std::stol ( std::wstring(str), idx, base );
}
inline unsigned long stoul (wstring_view str, size_t* idx=0, int base=10) {
return std::stoul ( std::wstring(str), idx, base );
}
inline long long stoll (wstring_view str, size_t* idx=0, int base=10) {
return std::stoll ( std::wstring(str), idx, base );
}
inline unsigned long long stoull (wstring_view str, size_t* idx=0, int base=10) {
return std::stoull ( std::wstring(str), idx, base );
}
inline float stof (wstring_view str, size_t* idx=0) {
return std::stof ( std::wstring(str), idx );
}
inline double stod (wstring_view str, size_t* idx=0) {
return std::stod ( std::wstring(str), idx );
}
inline long double stold (wstring_view str, size_t* idx=0) {
return std::stold ( std::wstring(str), idx );
}
#endif
}
#if 0
namespace std {
// Hashing
template<> struct hash<boost::string_view>;
template<> struct hash<boost::u16string_view>;
template<> struct hash<boost::u32string_view>;
template<> struct hash<boost::wstring_view>;
}
#endif
#endif

View File

@ -0,0 +1,39 @@
/*
Copyright (c) Marshall Clow 2012-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
Based on the StringRef implementation in LLVM (http://llvm.org) and
N3422 by Jeffrey Yasskin
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
Updated July 2015 to reflect the Library Fundamentals TS
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html
*/
#ifndef BOOST_STRING_VIEW_FWD_HPP
#define BOOST_STRING_VIEW_FWD_HPP
#include <boost/config.hpp>
#include <string>
namespace boost {
template<typename charT, typename traits = std::char_traits<charT> > class basic_string_view;
typedef basic_string_view<char, std::char_traits<char> > string_view;
typedef basic_string_view<wchar_t, std::char_traits<wchar_t> > wstring_view;
#ifndef BOOST_NO_CXX11_CHAR16_T
typedef basic_string_view<char16_t, std::char_traits<char16_t> > u16string_view;
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
typedef basic_string_view<char32_t, std::char_traits<char32_t> > u32string_view;
#endif
}
#endif

View File

@ -0,0 +1,77 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2007, Tobias Schwinger.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#ifndef BOOST_UTILITY_TYPED_INPLACE_FACTORY_04APR2007_HPP
#ifndef BOOST_PP_IS_ITERATING
#include <boost/utility/detail/in_place_factory_prefix.hpp>
namespace boost {
class typed_in_place_factory_base {} ;
#define BOOST_PP_ITERATION_LIMITS (0, BOOST_MAX_INPLACE_FACTORY_ARITY)
#define BOOST_PP_FILENAME_1 <boost/utility/typed_in_place_factory.hpp>
#include BOOST_PP_ITERATE()
} // namespace boost
#include <boost/utility/detail/in_place_factory_suffix.hpp>
#define BOOST_UTILITY_TYPED_INPLACE_FACTORY_04APR2007_HPP
#else
#define N BOOST_PP_ITERATION()
template< class T BOOST_PP_ENUM_TRAILING_PARAMS(N,class A) >
class BOOST_PP_CAT(typed_in_place_factory,N)
:
public typed_in_place_factory_base
{
public:
typedef T value_type;
explicit BOOST_PP_CAT(typed_in_place_factory,N)
( BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a) )
#if N > 0
: BOOST_PP_ENUM(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _)
#endif
{}
void* apply (void* address) const
{
return new(address) T( BOOST_PP_ENUM_PARAMS(N, m_a) );
}
void* apply (void* address, std::size_t n) const
{
for(void* next = address = this->apply(address); !! --n;)
this->apply(next = static_cast<char *>(next) + sizeof(T));
return address;
}
BOOST_PP_REPEAT(N, BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _)
};
template< class T BOOST_PP_ENUM_TRAILING_PARAMS(N, class A) >
inline BOOST_PP_CAT(typed_in_place_factory,N)<
T BOOST_PP_ENUM_TRAILING_PARAMS(N, A) >
in_place( BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a) )
{
return BOOST_PP_CAT(typed_in_place_factory,N)<
T BOOST_PP_ENUM_TRAILING_PARAMS(N, A) >( BOOST_PP_ENUM_PARAMS(N, a) );
}
#undef N
#endif
#endif

View File

@ -0,0 +1,281 @@
// (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal.
//
// 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)
//
// 21 Ago 2002 (Created) Fernando Cacciola
// 24 Dec 2007 (Refactored and worked around various compiler bugs) Fernando Cacciola, Niels Dekker
// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
// 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola
// 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola
// 03 Apr 2010 (Added initialized<T>, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker
// 30 May 2010 (Made memset call conditional, fixing #3869) Niels Dekker
//
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
#define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
// Note: The implementation of boost::value_initialized had to deal with the
// fact that various compilers haven't fully implemented value-initialization.
// The constructor of boost::value_initialized<T> works around these compiler
// issues, by clearing the bytes of T, before constructing the T object it
// contains. More details on these issues are at libs/utility/value_init.htm
#include <boost/aligned_storage.hpp>
#include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
#include <boost/detail/workaround.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/cv_traits.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/swap.hpp>
#include <cstring>
#include <new>
#ifdef BOOST_MSVC
#pragma warning(push)
// It is safe to ignore the following warning from MSVC 7.1 or higher:
// "warning C4351: new behavior: elements of array will be default initialized"
#pragma warning(disable: 4351)
// It is safe to ignore the following MSVC warning, which may pop up when T is
// a const type: "warning C4512: assignment operator could not be generated".
#pragma warning(disable: 4512)
#endif
#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
// suggests that a workaround should be applied, because of compiler issues
// regarding value-initialization.
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
#endif
// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND
// switches the value-initialization workaround either on or off.
#ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND
#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1
#else
#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
#endif
#endif
namespace boost {
template<class T>
class initialized
{
private :
struct wrapper
{
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
typename
#endif
remove_const<T>::type data;
BOOST_GPU_ENABLED
wrapper()
:
data()
{
}
BOOST_GPU_ENABLED
wrapper(T const & arg)
:
data(arg)
{
}
};
mutable
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
typename
#endif
aligned_storage<sizeof(wrapper), alignment_of<wrapper>::value>::type x;
BOOST_GPU_ENABLED
wrapper * wrapper_address() const
{
return static_cast<wrapper *>( static_cast<void*>(&x));
}
public :
BOOST_GPU_ENABLED
initialized()
{
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
std::memset(&x, 0, sizeof(x));
#endif
new (wrapper_address()) wrapper();
}
BOOST_GPU_ENABLED
initialized(initialized const & arg)
{
new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
}
BOOST_GPU_ENABLED
explicit initialized(T const & arg)
{
new (wrapper_address()) wrapper(arg);
}
BOOST_GPU_ENABLED
initialized & operator=(initialized const & arg)
{
// Assignment is only allowed when T is non-const.
BOOST_STATIC_ASSERT( ! is_const<T>::value );
*wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address()));
return *this;
}
BOOST_GPU_ENABLED
~initialized()
{
wrapper_address()->wrapper::~wrapper();
}
BOOST_GPU_ENABLED
T const & data() const
{
return wrapper_address()->data;
}
BOOST_GPU_ENABLED
T& data()
{
return wrapper_address()->data;
}
BOOST_GPU_ENABLED
void swap(initialized & arg)
{
::boost::swap( this->data(), arg.data() );
}
BOOST_GPU_ENABLED
operator T const &() const
{
return wrapper_address()->data;
}
BOOST_GPU_ENABLED
operator T&()
{
return wrapper_address()->data;
}
} ;
template<class T>
BOOST_GPU_ENABLED
T const& get ( initialized<T> const& x )
{
return x.data() ;
}
template<class T>
BOOST_GPU_ENABLED
T& get ( initialized<T>& x )
{
return x.data() ;
}
template<class T>
BOOST_GPU_ENABLED
void swap ( initialized<T> & lhs, initialized<T> & rhs )
{
lhs.swap(rhs) ;
}
template<class T>
class value_initialized
{
private :
// initialized<T> does value-initialization by default.
initialized<T> m_data;
public :
BOOST_GPU_ENABLED
value_initialized()
:
m_data()
{ }
BOOST_GPU_ENABLED
T const & data() const
{
return m_data.data();
}
BOOST_GPU_ENABLED
T& data()
{
return m_data.data();
}
BOOST_GPU_ENABLED
void swap(value_initialized & arg)
{
m_data.swap(arg.m_data);
}
BOOST_GPU_ENABLED
operator T const &() const
{
return m_data;
}
BOOST_GPU_ENABLED
operator T&()
{
return m_data;
}
} ;
template<class T>
BOOST_GPU_ENABLED
T const& get ( value_initialized<T> const& x )
{
return x.data() ;
}
template<class T>
BOOST_GPU_ENABLED
T& get ( value_initialized<T>& x )
{
return x.data() ;
}
template<class T>
BOOST_GPU_ENABLED
void swap ( value_initialized<T> & lhs, value_initialized<T> & rhs )
{
lhs.swap(rhs) ;
}
class initialized_value_t
{
public :
template <class T> BOOST_GPU_ENABLED operator T() const
{
return initialized<T>().data();
}
};
initialized_value_t const initialized_value = {} ;
} // namespace boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#endif

View File

@ -1,72 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Boost Utility Library</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" cellpadding="2" bgcolor="#007F7F">
<tr>
<td bgcolor="#FFFFFF"><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86"></td>
<td><a href="../../index.htm"><font color="#FFFFFF" size="4" face="Arial">Home</font></a></td>
<td><a href="../../libraries.htm"><font color="#FFFFFF" size="4" face="Arial">Libraries</font></a></td>
<td><a href="../../people.htm"><font color="#FFFFFF" size="4" face="Arial">People</font></a></td>
<td><a href="../../more/faq.htm"><font color="#FFFFFF" size="4" face="Arial">FAQ</font></a></td>
<td><a href="../../more/index.htm"><font color="#FFFFFF" size="4" face="Arial">More</font></a></td>
</tr>
</table>
<h1>Boost Utility Library</h1>
<table border="1" cellpadding="5">
<tr>
<td><b><i>Header</i></b></td>
<td><b><i>Contents</i></b></td>
</tr>
<tr>
<td><a href="../../boost/utility.hpp"><code>boost/utility.hpp<br>
</code></a><a href="utility.htm">[Documentation]</a></td>
<td>Class <b>noncopyable</b> plus <b>next()</b> and <b>prior()</b> template
functions.</td>
</tr>
<tr>
<td><a href="../../boost/cast.hpp"><code>boost/cast.hpp</code></a><br>
<a href="cast.htm">[Documentation]</a></td>
<td><b>polymorphic_cast</b>, <b>implicit_cast</b>, and <b>numeric_cast</b>
function templates.
<p><i>[Beta.]</i></p>
</td>
</tr>
<tr>
<td><a href="../../boost/operators.hpp">boost/operators.hpp</a><br>
<a href="operators.htm">[Documentation]</a></td>
<td>Templates <b>equality_comparable</b>, <b>less_than_comparable</b>, <b>addable</b>,
and the like ease the task of defining comparison and arithmetic
operators, and iterators.</td>
</tr>
<tr>
<td><a href="../../boost/detail/type_traits.hpp">boost/type_traits.hpp</a><br>
[<a href="type_traits.htm">Documentation</a>]</td>
<td>Template classes that describe the fundamental properties of a type. [<a href="c++_type_traits.htm">DDJ
Article &quot;C++ type traits&quot;</a>]</td>
</tr>
<tr>
<td><a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a><br>
[<a href="call_traits.htm">Documentation</a>]</td>
<td>Template class call_traits&lt;T&gt;, that defines types used for passing
parameters to and from a proceedure.</td>
</tr>
<tr>
<td><a href="../../boost/detail/compressed_pair.hpp">boost/compressed_pair.hpp</a><br>
[<a href="compressed_pair.htm">Documentation</a>]</td>
<td>Template class compressed_pait&lt;T1, T2&gt; which pairs two values
using the empty member optimisation where appropriate.</td>
</tr>
</table>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->27 July 2000<!--webbot bot="Timestamp" endspan i-checksum="18770" --></p>
</body>
</html>

48
index.html Normal file
View File

@ -0,0 +1,48 @@
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Boost Utility Library</title>
</head>
<body bgcolor="#FFFFFF">
<h1><IMG SRC="../../boost.png" WIDTH="276" HEIGHT="86" align="center">Boost
Utility Library</h1>
<p>The Boost Utility Library isn't really a single library at all. It is just a
collection for components too small to be called libraries in their own right.</p>
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
<blockquote>
<p>
<a href="../core/doc/html/core/addressof.html">addressof</a> (moved to the Boost.Core library)<br>
<a href="doc/html/base_from_member.html">base_from_member</a><br>
<a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a><br>
<a href="call_traits.htm">call_traits</a><br>
<a href="../core/doc/html/core/checked_delete.html">checked_delete</a> (moved to the Boost.Core library)<br>
<a href="doc/html/compressed_pair.html">compressed_pair</a><br>
<a href="doc/html/declval.html">declval</a><br>
<a href="../core/doc/html/core/enable_if.html">enable_if</a> (moved to the Boost.Core library)<br>
<a href="in_place_factories.html">in_place_factory</a><br>
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
<a href="utility.htm#functions_next_prior">next/prior</a><br>
<a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)<br>
<a href="operators.htm">operators</a><br>
<a href="utility.htm#result_of">result_of</a><br>
<a href="throw_exception.html">throw_exception</a><br>
<a href="utility.htm">utility</a><br>
<a href="doc/html/string_ref.html">string_ref</a><br>
<a href="value_init.htm">value_init</a><br>
</p>
</blockquote>
<hr>
<p>&copy; Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at
<a href="http://www.boost.org/LICENSE_1_0.txt">
www.boost.org/LICENSE_1_0.txt</a>)</p>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p>
</body>
</html>

116
initialized_test.cpp Normal file
View File

@ -0,0 +1,116 @@
// Copyright 2010, Niels Dekker.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Test program for boost::initialized<T>.
//
// 2 May 2010 (Created) Niels Dekker
#include <boost/utility/value_init.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <string>
namespace
{
// Typical use case for boost::initialized<T>: A generic class that
// holds a value of type T, which must be initialized by either
// value-initialization or direct-initialization.
template <class T> class key_value_pair
{
std::string m_key;
boost::initialized<T> m_value;
public:
// Value-initializes the object held by m_value.
key_value_pair() { }
// Value-initializes the object held by m_value.
explicit key_value_pair(const std::string& key)
:
m_key(key)
{
}
// Direct-initializes the object held by m_value.
key_value_pair(const std::string& key, const T& value)
:
m_key(key), m_value(value)
{
}
const T& get_value() const
{
return m_value;
}
};
// Tells whether the argument is value-initialized.
bool is_value_initialized(const int& arg)
{
return arg == 0;
}
// Tells whether the argument is value-initialized.
bool is_value_initialized(const std::string& arg)
{
return arg.empty();
}
struct foo
{
int data;
};
bool operator==(const foo& lhs, const foo& rhs)
{
return lhs.data == rhs.data;
}
// Tells whether the argument is value-initialized.
bool is_value_initialized(const foo& arg)
{
return arg.data == 0;
}
template <class T>
void test_key_value_pair(const T& magic_value)
{
// The value component of a default key_value_pair must be value-initialized.
key_value_pair<T> default_key_value_pair;
BOOST_TEST( is_value_initialized(default_key_value_pair.get_value() ) );
// The value component of a key_value_pair that only has its key explicitly specified
// must also be value-initialized.
BOOST_TEST( is_value_initialized(key_value_pair<T>("key").get_value()) );
// However, the value component of the following key_value_pair must be
// "magic_value", as it must be direct-initialized.
BOOST_TEST( key_value_pair<T>("key", magic_value).get_value() == magic_value );
}
}
// Tests boost::initialize for a fundamental type, a type with a
// user-defined constructor, and a user-defined type without
// a user-defined constructor.
int main()
{
const int magic_number = 42;
test_key_value_pair(magic_number);
const std::string magic_string = "magic value";
test_key_value_pair(magic_string);
const foo magic_foo = { 42 };
test_key_value_pair(magic_foo);
return boost::report_errors();
}

View File

@ -0,0 +1,33 @@
// Copyright 2010, Niels Dekker.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Test program for boost::initialized<T>. Must fail to compile.
//
// Initial: 2 May 2010
#include <boost/utility/value_init.hpp>
namespace
{
void direct_initialize_from_int()
{
// Okay: initialized<T> supports direct-initialization from T.
boost::initialized<int> direct_initialized_int(1);
}
void copy_initialize_from_int()
{
// The following line should not compile, because initialized<T>
// was not intended to supports copy-initialization from T.
boost::initialized<int> copy_initialized_int = 1;
}
}
int main()
{
// This should fail to compile, so there is no need to call any function.
return 0;
}

View File

@ -0,0 +1,37 @@
// Copyright 2010, Niels Dekker.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Test program for boost::initialized<T>. Must fail to compile.
//
// Initial: 2 May 2010
#include <boost/utility/value_init.hpp>
namespace
{
void from_value_initialized_to_initialized()
{
boost::value_initialized<int> value_initialized_int;
// Okay: initialized<T> can be initialized by value_initialized<T>.
boost::initialized<int> initialized_int(value_initialized_int);
}
void from_initialized_to_value_initialized()
{
boost::initialized<int> initialized_int(13);
// The following line should not compile, because initialized<T>
// should not be convertible to value_initialized<T>.
boost::value_initialized<int> value_initialized_int(initialized_int);
}
}
int main()
{
// This should fail to compile, so there is no need to call any function.
return 0;
}

View File

@ -1,45 +0,0 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#include <functional>
#include <algorithm>
#include <iostream>
#include <boost/iterator_adaptors.hpp>
int
main(int, char*[])
{
// This is a simple example of using the transform_iterators class to
// generate iterators that multiply the value returned by dereferencing
// the iterator. In this case we are multiplying by 2.
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
typedef std::binder1st< std::multiplies<int> > Function;
typedef boost::transform_iterator<Function, int*,
boost::iterator<std::random_access_iterator_tag, int>
>::type doubling_iterator;
doubling_iterator i(x, std::bind1st(std::multiplies<int>(), 2)),
i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies<int>(), 2));
std::cout << "multiplying the array by 2:" << std::endl;
while (i != i_end)
std::cout << *i++ << " ";
std::cout << std::endl;
// Here is an example of counting from 0 to 5 using the integer_range class.
boost::integer_range<int> r(0,5);
std::cout << "counting to from 0 to 4:" << std::endl;
std::copy(r.begin(), r.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}

View File

@ -1,629 +1,11 @@
<!-- Copyright David Abrahams 2004. Distributed under the Boost -->
<!-- Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Header boost/iterator_adaptors.hpp Documentation</title>
<meta http-equiv="refresh" content="0; URL=../iterator/doc/index.html">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
align="center" width="277" height="86">
<h1>Header
<a href="../../boost/pending/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a></h1>
<p>The file <tt>boost/iterator_adaptors.hpp</tt>
includes the main <tt>iterator_adaptors</tt> class and several other classes
for constructing commonly used iterator adaptors.</p>
<ul>
<li><a href="#iterator_adaptors"><tt>iterator_adaptors</tt></a>.
<li><a href="#iterator_adaptor"><tt>iterator_adaptor</tt></a>.
<li><a href="#transform_iterator"><tt>transform_iterator</tt></a>
<li><a href="#indirect_iterators"><tt>indirect_iterators</tt></a>
<li><a href="#reverse_iterators"><tt>reverse_iterators</tt></a>
<li><a href="#integer_range"><tt>integer_range</tt></a>
</ul>
<!-- put in something about Andrei Alexandrescu's contribution? -->
<p><a href="http://www.boost.org/people/dave_abrahams.htm">Dave
Abrahams</a> started the library, coming up with the idea to use
policy classes and how to handle the const/non-const iterator
interactions. He also contributed the <tt>indirect_iterators</tt> and
<tt>reverse_iterators</tt> classes.<br>
<a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>
contributed <tt>transform_iterator</tt>, <tt>integer_range</tt>,
and this documentation.
<h3><a name="iterator_adaptors">The Iterator Adaptors Class</a></h3>
Implementing standard conforming iterators is a non-trivial task.
There are some fine-points such as iterator/const_iterator
interactions and there are the myriad of operators that should be
implemented but are easily forgotten such as
<tt>operator-&gt;()</tt>. The purpose of the
<tt>iterator_adaptors</tt> class is to make it easier to implement an
iterator class, and even easier to extend and adapt existing iterator
types. The <tt>iterator_adaptors</tt> class itself is not an adaptor
class but a <i>type generator</i>. It generates a pair of adaptor classes,
one class for the mutable iterator and one class for the const
iterator. The definition of the <tt>iterator_adaptors</tt> class is as
follows:
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
template &lt;class Iterator,
class ConstIterator,
class Traits = std::iterator_traits&lt;Iterator&gt;,
class ConstTraits = std::iterator_traits&lt;ConstIterator&gt;,
class Policies = default_iterator_policies&gt;
struct iterator_adaptors
{
typedef ... iterator;
typedef ... const_iterator;
};
</PRE></TD></TABLE>
<p>The <tt>Iterator</tt> and <tt>ConstIterator</tt> template parameters
are the iterator types that you want to adapt. The <tt>Traits</tt> and
<tt>ConstTraits</tt> must be iterator traits classes. The traits
parameters default to the specialization of the
<tt>std::iterator_traits</tt> class for the adapted iterators. If you
want the traits for your new iterator adaptor (<tt>value_type</tt>,
<tt>iterator_category</tt>, etc.) to be the same as the adapted
iterator then use the default, otherwise create your own traits
classes and pass them in <a href="#1">[1]</a>.
<p>The <tt>Policies</tt> class that you pass in will become the heart of
the iterator adaptor. The policy class determines how your new adaptor
class will behave. The <tt>Policies</tt> class must implement 3, 4, or
7 of the core iterator operations depending on whether you wish the
new iterator adaptor class to be a
<a href="http://www.sgi.com/Technology/STL/ForwardIterator.html">
ForwardIterator</a>,
<a href="http://www.sgi.com/Technology/STL/BidirectionalIterator.html">
BidirectionalIterator</a>, or <a
href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">
RandomAccessIterator</a>. Make sure that the
<tt>iterator_category</tt> type of the traits class you pass in
matches the category of iterator that you want to create. The default
policy class, <tt>default_iterator_policies</tt>, implements all 7 of
the core operations in the usual way. If you wish to create an
iterator adaptor that only changes a few of the iterator's behaviors,
then you can have your new policy class inherit from
<tt>default_iterator_policies</tt> to avoid retyping the usual
behaviours. You should also look at <tt>default_iterator_policies</tt>
as the &quot;boiler-plate&quot; for your own policy classes. The
following is definition of the <tt>default_iterator_policies</tt>
class:
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
struct default_iterator_policies
{
// required for a ForwardIterator
template &lt;class Reference, class Iterator&gt;
Reference dereference(type&lt;Reference&gt;, const Iterator& x) const
{ return *x; }
template &lt;class Iterator&gt;
void increment(Iterator& x) const
{ ++x; }
template &lt;class Iterator1, class Iterator2&gt;
bool equal(Iterator1& x, Iterator2& y) const
{ return x == y; }
// required for a BidirectionalIterator
template &lt;class Iterator&gt;
void decrement(Iterator& x) const
{ --x; }
// required for a RandomAccessIterator
template &lt;class Iterator, class DifferenceType&gt;
void advance(Iterator& x, DifferenceType n) const
{ x += n; }
template &lt;class Difference, class Iterator1, class Iterator2&gt;
Difference distance(type&lt;Difference&gt;, Iterator1& x, Iterator2& y) const
{ return y - x; }
template &lt;class Iterator1, class Iterator2&gt;
bool less(Iterator1& x, Iterator2& y) const
{ return x &lt; y; }
};
</PRE></TD></TABLE>
<p>
The generated iterator adaptor types will have the following
constructors.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
<i>iterator</i>(const Iterator& i, const Policies& p = Policies())
<i>const_iterator</i>(const ConstIterator& i, const Policies& p = Policies())
</PRE></TD></TABLE>
<h3><a name="iterator_adaptor">The Iterator Adaptor Class</a></h3>
This is the class used inside of the <tt>iterator_adaptors</tt> type
generator. Use this class directly (instead of using
<tt>iterator_adaptors</tt>) when there is no difference between the
const and non-const versions of the iterator type. Often this is
because there is only a const (read-only) version of the iterator, as
is the case for <tt>std::set</tt>'s iterators. Use the same type for
the <tt>Iterator</tt> and <tt>NonconstIterator</tt> template
arguments.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
template &lt;class Iterator,
class Policies = default_iterator_policies,
class NonconstIterator = Iterator,
class Traits = std::iterator_traits&lt;Iterator&gt; &gt;
struct iterator_adaptor;
</PRE></TD></TABLE>
<p>
Next we will look at some iterator adaptors that are examples of how
to use the iterator adaptors class, and that are useful iterator
adaptors in their own right.
<h3><a name="transform_iterator">The Transform Iterator Class</a></h3>
It is often useful to automatically apply some function to the value
returned by dereferencing (<tt>operator*()</tt>) an iterator. The
<tt>transform_iterators</tt> class makes it easy to create an iterator
adaptor that does just that.
First let us consider what the <tt>Policies</tt> class for the transform
iterator should look like. We are only changing one of the iterator
behaviours, so we will inherit from
<tt>default_iterator_policies</tt>. In addition, we will need a
function object to apply, so we will have a template parameter and a
data member for the function object. The function will take one
argument (the dereferenced value) and we will need to know the
<tt>result_type</tt> of the function, so <a
href="http://www.sgi.com/Technology/STL/AdaptableUnaryFunction.html">
AdaptableUnaryFunction</a> is the corrent concept to choose for the
function object type. Now for the heart of our iterator adaptor, we
implement the <tt>dereference</tt> method, applying the function
object to <tt>*i</tt>. The <tt>type&lt;Reference&gt;</tt> class is
there to tell you what the reference type of the iterator is, which is
handy when writing generic iterator adaptors such as this one <a
href="#2">[2]</a>.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
template &lt;class AdaptableUnaryFunction&gt;
struct transform_iterator_policies : public default_iterator_policies
{
transform_iterator_policies(const AdaptableUnaryFunction& f) : m_f(f) { }
template &lt;class Reference, class Iterator&gt;
Reference dereference(type&lt;Reference&gt;, const Iterator& i) const
{ return m_f(*i); }
AdaptableUnaryFunction m_f;
};
</PRE></TD></TABLE>
Next we need to create the traits class for our new iterator. In some
situations you may need to create a separate traits class for the
const and non-const iterator types, but here a single traits class
will do. The <tt>value_type</tt> and <tt>reference</tt> type of our
transform iterator will be the <tt>result_type</tt> of the function
object. The <tt>difference_type</tt> and <tt>iterator_category</tt>
will be the same as the adapted iterator.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
template &lt;class AdaptableUnaryFunction, class IteratorTraits&gt;
struct transform_iterator_traits {
typedef typename AdaptableUnaryFunction::result_type value_type;
typedef value_type reference;
typedef value_type* pointer;
typedef typename IteratorTraits::difference_type difference_type;
typedef typename IteratorTraits::iterator_category iterator_category;
};
</PRE></TD></TABLE>
The final step is to use the <tt>iterator_adaptor</tt> class to
construct our transform iterator. We will use the single iterator
adaptor version because we will not need to create both a mutable and
const version of the transform iterator. The transform iterator is
inherently a read-only iterator. The nicest way to package up our new
transform iterator is to create a type generator similar to
<tt>iterator_adaptor</tt>. The first template parameter will be the
type of the function object. The second parameter will be the adapted
iterator type. The third parameter is the trait class for
the adapted iterator. Inside the <tt>transform_iterators</tt> class
we use the <tt>transform_iterator_traits</tt> class defined above to
create the traits class for the new transform iterator. We then use
the <tt>iterator_adaptor</tt> class to extract the generated
iterator adaptor type.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
template &lt;class AdaptableUnaryFunction,
class Iterator,
class Traits = std::iterator_traits&lt;Iterator&gt;
&gt;
struct transform_iterator
{
typedef transform_iterator_traits&lt;AdaptableUnaryFunction,Traits&gt;
TransTraits;
typedef iterator_adaptor&lt;Iterator, TransTraits,
transform_iterator_policies&lt;AdaptableUnaryFunction&gt; &gt;::type type;
};
</PRE></TD></TABLE>
<p>
The following is a simple example of how to use the
<tt>transform_iterators</tt> class to iterate through a range of
numbers, multiplying each of them by 2 when they are dereferenced.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
#include &lt;functional&gt;
#include &lt;iostream&gt;
#include &lt;boost/iterator_adaptors.hpp&gt;
int
main(int, char*[])
{
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
typedef std::binder1st&lt; std::multiplies&lt;int&gt; &gt; Function;
typedef boost::transform_iterator&lt;Function, int*,
boost::iterator&lt;std::random_access_iterator_tag, int&gt;
&gt;::type doubling_iterator;
doubling_iterator i(x, std::bind1st(std::multiplies&lt;int&gt;(), 2)),
i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies&lt;int&gt;(), 2));
std::cout &lt;&lt; "multiplying the array by 2:" &lt;&lt; std::endl;
while (i != i_end)
std::cout &lt;&lt; *i++ &lt;&lt; " ";
std::cout &lt;&lt; std::endl;
return 0;
}
</PRE></TD></TABLE>
<h3><a name="indirect_iterators">The Indirect Iterators Class</a></h3>
It is not all that uncommon to create data structures that consist of
pointers to pointers. For such a structure it might be nice to have an
iterator that applies a double-dereference inside the
<tt>operator*()</tt>. The implementation of this is similar to the
<tt>transform_iterators</tt><a href="#3">[3]</a>. We first create a
policies class which does a double-dereference in the
<tt>dereference()</tt> method. We then create a traits class, this
time also including a template parameter for the traits of the second
level iterators as well as the first. Lastly we wrap this up in the
type generator <tt>indirect_iterators</tt>, using
<tt>iterator_adaptors</tt> to do most of the work.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
struct indirect_iterator_policies : public default_iterator_policies
{
template &lt;class Reference, class Iterator&gt;
Reference dereference(type&lt;Reference&gt;, const Iterator& x) const
{ return **x; }
};
template &lt;class IndirectIterator,
class IndirectTraits = std::iterator_traits&lt;IndirectIterator&gt;,
class Traits =
std::iterator_traits&lt;typename IndirectTraits::value_type&gt;
&gt;
struct indirect_traits
{
typedef typename IndirectTraits::difference_type difference_type;
typedef typename Traits::value_type value_type;
typedef typename Traits::pointer pointer;
typedef typename Traits::reference reference;
typedef typename IndirectTraits::iterator_category iterator_category;
};
template &lt;class IndirectIterator, class ConstIndirectIterator,
class IndirectTraits =
std::iterator_traits&lt;IndirectIterator&gt;,
class ConstIndirectTraits =
std::iterator_traits&lt;ConstIndirectIterator&gt;,
class Traits =
std::iterator_traits&lt;typename IndirectTraits::value_type&gt;
&gt;
struct indirect_iterators
{
typedef typename IndirectTraits::value_type Iterator;
typedef typename Traits::value_type ValueType;
typedef iterator_adaptors&lt;IndirectIterator, ConstIndirectIterator,
indirect_traits&lt;IndirectIterator, IndirectTraits, Traits&gt;,
indirect_traits&lt;ConstIndirectIterator, ConstIndirectTraits, Traits&gt;,
indirect_iterator_policies
&gt; Adaptors;
typedef typename Adaptors::iterator iterator;
typedef typename Adaptors::const_iterator const_iterator;
};
</PRE></TD></TABLE>
<h3><a name="reverse_iterators">The Reverse Iterators Class</a></h3>
<p>
Yes, there is already a <tt>reverse_iterator</tt> adaptor class
defined in the C++ Standard, but using the <tt>iterator_adaptors</tt>
class we can re-implement this classic adaptor in a more succinct and
elegant fashion. Also, this makes for a good example of using
<tt>iterator_adaptors</tt> that is in familiar territory.
<p>
The first step is to create the <tt>Policies</tt> class. As in the
<tt>std::reverse_iterator</tt> class, we need to flip all the
operations of the iterator. Increment will become decrement, advancing
by <tt>n</tt> will become retreating by <tt>n</tt>, etc.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
struct reverse_iterator_policies
{
template &lt;class Reference, class Iterator&gt;
Reference dereference(type&lt;Reference&gt;, const Iterator& x) const
{ return *boost::prior(x); }
// this is equivalent to { Iterator tmp = x; return *--tmp; }
template &lt;class Iterator&gt;
void increment(Iterator& x) const
{ --x; }
template &lt;class Iterator&gt;
void decrement(Iterator& x) const
{ ++x; }
template &lt;class Iterator, class DifferenceType&gt;
void advance(Iterator& x, DifferenceType n) const
{ x -= n; }
template &lt;class Difference, class Iterator1, class Iterator2&gt;
Difference distance(type&lt;Difference&gt;, Iterator1& x, Iterator2& y) const
{ return x - y; }
template &lt;class Iterator1, class Iterator2&gt;
bool equal(Iterator1& x, Iterator2& y) const
{ return x == y; }
template &lt;class Iterator1, class Iterator2&gt;
bool less(Iterator1& x, Iterator2& y) const
{ return y &lt; x; }
};
</PRE></TD></TABLE>
Since the traits of the reverse iterator adaptor will be the same as
the adapted iterator's traits, we do not need to create new traits
classes as was the case for <tt>transform_iterator</tt>. We can skip to
the final stage of creating a type generator class for our reverse
iterators using the <tt>iterator_adaptor</tt> class.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
template &lt;class Iterator, class ConstIterator,
class Traits = std::iterator_traits&lt;Iterator&gt;,
class ConstTraits = std::iterator_traits&lt;ConstIterator&gt;
&gt;
struct reverse_iterators
{
typedef iterator_adaptors&lt;Iterator,ConstIterator,Traits,ConstTraits,
reverse_iterator_policies&gt; Adaptor;
typedef typename Adaptor::iterator iterator;
typedef typename Adaptor::const_iterator const_iterator;
};
</PRE></TD></TABLE>
A typical use of the <tt>reverse_iterators</tt> class is in
user-defined container types. You can use the
<tt>reverse_iterators</tt> class to generate the reverse iterators for
your container.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
class my_container {
...
typedef ... iterator;
typedef ... const_iterator;
typedef reverse_iterators&lt;iterator, const_iterator&gt; RevIters;
typedef typename RevIters::iterator reverse_iterator;
typedef typename RevIters::const_iterator const_reverse_iterator;
...
};
</PRE></TD></TABLE>
<h3><a name="integer_range">The Integer Range Class</a></h3>
The <tt>iterator_adaptors</tt> class can not only be used for adapting
iterators, but it can also be used to take a non-iterator type and use
it to build an iterator. An especially simple example of this is
turning an integer type into an iterator, a counting iterator. The
builtin integer types of C++ are almost iterators. They have
<tt>operator++()</tt>, <tt>operator--()</tt>, etc. The one operator
they are lacking is the <tt>operator*()</tt>, which we will want to
simply return the current value of the integer. The following few
lines of code implement the policy and traits class for the counting
iterator.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
struct counting_iterator_policies : public default_iterator_policies
{
template &lt;class IntegerType&gt;
IntegerType dereference(type&lt;IntegerType&gt;, const IntegerType& i) const
{ return i; }
};
template &lt;class IntegerType&gt;
struct counting_iterator_traits {
typedef IntegerType value_type;
typedef IntegerType reference;
typedef value_type* pointer;
typedef std::ptrdiff_t difference_type;
typedef std::random_access_iterator_tag iterator_category;
};
</PRE></TD></TABLE>
Typically we will want to count the integers in some range, so a nice
interface would be to have a fake container that represents the range
of integers. The following is the definition of such a class called
<tt>integer_range</tt>.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
template &lt;class IntegerType&gt;
struct integer_range {
typedef typename iterator_adaptor&lt;IntegerType,
counting_iterator_traits&lt;IntegerType&gt;,
counting_iterator_policies &gt;::type iterator;
typedef iterator const_iterator;
typedef IntegerType value_type;
typedef std::ptrdiff_t difference_type;
typedef IntegerType reference;
typedef IntegerType* pointer;
typedef IntegerType size_type;
integer_range(IntegerType start, IntegerType finish)
: m_start(start), m_finish(finish) { }
iterator begin() const { return iterator(m_start); }
iterator end() const { return iterator(m_finish); }
size_type size() const { return m_finish - m_start; }
bool empty() const { return m_finish == m_start; }
void swap(integer_range& x) {
std::swap(m_start, x.m_start);
std::swap(m_finish, x.m_finish);
}
protected:
IntegerType m_start, m_finish;
};
</PRE></TD></TABLE>
<p>
The following is an example of how to use the
<tt>integer_range</tt> class to count from 0 to 4.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
boost::integer_range&lt;int&gt; r(0,5);
cout &lt;&lt; "counting to from 0 to 4:" &lt;&lt; endl;
std::copy(r.begin(), r.end(), ostream_iterator&lt;int&gt;(cout, " "));
cout &lt;&lt; endl;
</PRE></TD></TABLE>
<h3>Challenge</h3>
<p>
There is an unlimited number of ways the the
<tt>iterator_adaptors</tt> class can be used to create iterators. One
interesting exercise would be to re-implement the iterators of
<tt>std::list</tt> and <tt>std::slist</tt> using
<tt>iterator_adaptors</tt>, where the adapted <tt>Iterator</tt> types
would be node pointers.
<h3>Notes</h3>
<p>
<a name="1">[1]</a>
If your compiler does not support partial specialization and hence
does not have a working <tt>std::iterator_traits</tt> class, you will
not be able to use the defaults and will need to supply your own
<tt>Traits</tt> and <tt>ConstTraits</tt> classes.
<p>
<a name="2">[2]</a>
The reference type could also be obtained from
<tt>std::iterator_traits</tt>, but that is not portable on compilers
that do not support partial specialization.
<p>
<a name="3">[3]</a>
It would have been more elegant to implement <tt>indirect_iterators</tt>
using <tt>transform_iterators</tt>, but for subtle reasons that would require
the use of <tt>boost::remove_cv</tt> which is not portable.
<h3>Implementation Notes</h3>
The code is somewhat complicated because there are three iterator
adaptor class: <tt>forward_iterator_adaptor</tt>,
<tt>bidirectional_iterator_adaptor</tt>, and
<tt>random_access_iterator_adaptor</tt>. The alternative would be to
just have one iterator adaptor equivalent to the
<tt>random_access_iterator_adaptor</tt>. The reason for going with
the three adaptors is that according to 14.5.3p5 in the C++ Standard,
friend functions defined inside a template class body are instantiated
when the template class is instantiated. This means that if we only
used the one iterator adaptor, then if the adapted iterator did not
meet all of the requirements for a
<a href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">
RandomAccessIterator</a> then a compiler error should occur. Many
current compilers in fact do not instantiate the friend functions
unless used, so we could get away with the one iterator adaptor in
most cases. However, out of respect for the standard this implementation
uses the three adaptors.
<hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->17 Jun 2000<!--webbot bot="Timestamp" endspan i-checksum="15055" --></p>
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
modify, sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided &quot;as is&quot;
without express or implied warranty, and with no claim as to its suitability for
any purpose.</p>
<body>
This documentation moved to <a href="../iterator/doc/index.html">../iterator/doc/index.html</a>.
</body>
</html>

View File

@ -1,24 +1,36 @@
// Demonstrate and test boost/operators.hpp on std::iterators --------------//
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
// (C) Copyright Jeremy Siek 1999.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 29 May 01 Factored implementation, added comparison tests, use Test Tools
// library (Daryle Walker)
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
#include <string>
#include <iostream>
using namespace std;
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp> // for main
#include <boost/operators.hpp>
using namespace boost;
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/operators.hpp> // for boost::random_access_iterator_helper
#include <cstddef> // for std::ptrdiff_t, std::size_t
#include <cstring> // for std::strcmp
#include <iostream> // for std::cout (std::endl, ends, and flush indirectly)
#include <string> // for std::string
#include <sstream> // for std::stringstream
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::strcmp; }
# endif
// Iterator test class
template <class T, class R, class P>
struct test_iter
: public boost::random_access_iterator_helper<
@ -29,7 +41,7 @@ struct test_iter
typedef std::ptrdiff_t Distance;
public:
test_iter(T* i) : _i(i) { }
explicit test_iter(T* i =0) : _i(i) { }
test_iter(const self& x) : _i(x._i) { }
self& operator=(const self& x) { _i = x._i; return *this; }
Reference operator*() const { return *_i; }
@ -43,127 +55,270 @@ public:
return x._i - y._i;
}
protected:
T* _i;
P _i;
};
int
main()
// Iterator operator testing classes
class test_opr_base
{
string array[] = { "apple", "orange", "pear", "peach", "grape", "plum" };
{
test_iter<string,string&,string*> i = array,
ie = array + sizeof(array)/sizeof(string);
protected:
// Test data and types
BOOST_STATIC_CONSTANT( std::size_t, fruit_length = 6u );
// Tests for all of the operators added by random_access_iterator_helper
typedef std::string fruit_array_type[ fruit_length ];
// test i++
while (i != ie)
cout << *i++ << " ";
cout << endl;
i = array;
static fruit_array_type fruit;
// test i--
while (ie != i) {
ie--;
cout << *ie << " ";
}
cout << endl;
ie = array + sizeof(array)/sizeof(string);
}; // test_opr_base
// test i->m
while (i != ie) {
cout << i->size() << " ";
++i;
}
cout << endl;
i = array;
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
const std::size_t test_opr_base::fruit_length;
#endif
// test i + n
while (i < ie) {
cout << *i << " ";
i = i + 2;
}
cout << endl;
i = array;
template <typename T, typename R = T&, typename P = T*>
class test_opr
: public test_opr_base
{
typedef test_opr<T, R, P> self_type;
// test n + i
while (i < ie) {
cout << *i << " ";
i = ptrdiff_t(2) + i;
}
cout << endl;
i = array;
public:
// Types
typedef T value_type;
typedef R reference;
typedef P pointer;
// test i - n
while (ie > i) {
ie = ie - 2;
cout << *ie << " ";
}
cout << endl;
ie = array + sizeof(array)/sizeof(string);
typedef test_iter<T, R, P> iter_type;
// test i[n]
for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j)
cout << i[j] << " ";
cout << endl;
}
{
test_iter<string, const string&, const string*> i = array,
ie = array + sizeof(array)/sizeof(string);
// Test controller
static void master_test( char const name[] );
// Tests for all of the operators added by random_access_iterator_helper
private:
// Test data
static iter_type const fruit_begin;
static iter_type const fruit_end;
// test i++
while (i != ie)
cout << *i++ << " ";
cout << endl;
i = array;
// Test parts
static void post_increment_test();
static void post_decrement_test();
static void indirect_referral_test();
static void offset_addition_test();
static void reverse_offset_addition_test();
static void offset_subtraction_test();
static void comparison_test();
static void indexing_test();
// test i--
while (ie != i) {
ie--;
cout << *ie << " ";
}
cout << endl;
ie = array + sizeof(array)/sizeof(string);
}; // test_opr
// test i->m
while (i != ie) {
cout << i->size() << " ";
++i;
}
cout << endl;
i = array;
// test i + n
while (i < ie) {
cout << *i << " ";
i = i + 2;
}
cout << endl;
i = array;
// Class-static data definitions
test_opr_base::fruit_array_type
test_opr_base::fruit = { "apple", "orange", "pear", "peach", "grape", "plum" };
// test n + i
while (i < ie) {
cout << *i << " ";
i = ptrdiff_t(2) + i;
}
cout << endl;
i = array;
template <typename T, typename R, typename P>
typename test_opr<T, R, P>::iter_type const
test_opr<T, R, P>::fruit_begin = test_iter<T,R,P>( fruit );
// test i - n
while (ie > i) {
ie = ie - 2;
cout << *ie << " ";
}
cout << endl;
ie = array + sizeof(array)/sizeof(string);
template <typename T, typename R, typename P>
typename test_opr<T, R, P>::iter_type const
test_opr<T, R, P>::fruit_end = test_iter<T,R,P>( fruit + fruit_length );
// test i[n]
for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j)
cout << i[j] << " ";
cout << endl;
}
return 0;
// Main testing function
int
test_main( int , char * [] )
{
using std::string;
typedef test_opr<string, string &, string *> test1_type;
typedef test_opr<string, string const &, string const *> test2_type;
test1_type::master_test( "non-const string" );
test2_type::master_test( "const string" );
return boost::exit_success;
}
// Tests for all of the operators added by random_access_iterator_helper
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::master_test
(
char const name[]
)
{
std::cout << "Doing test run for " << name << '.' << std::endl;
post_increment_test();
post_decrement_test();
indirect_referral_test();
offset_addition_test();
reverse_offset_addition_test();
offset_subtraction_test();
comparison_test();
indexing_test();
}
// Test post-increment
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::post_increment_test
(
)
{
std::cout << "\tDoing post-increment test." << std::endl;
std::stringstream oss;
for ( iter_type i = fruit_begin ; i != fruit_end ; )
{
oss << *i++ << ' ';
}
BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
}
// Test post-decrement
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::post_decrement_test
(
)
{
std::cout << "\tDoing post-decrement test." << std::endl;
std::stringstream oss;
for ( iter_type i = fruit_end ; i != fruit_begin ; )
{
i--;
oss << *i << ' ';
}
BOOST_CHECK( oss.str() == "plum grape peach pear orange apple ");
}
// Test indirect structure referral
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::indirect_referral_test
(
)
{
std::cout << "\tDoing indirect reference test." << std::endl;
std::stringstream oss;
for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
{
oss << i->size() << ' ';
}
BOOST_CHECK( oss.str() == "5 6 4 5 5 4 ");
}
// Test offset addition
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::offset_addition_test
(
)
{
std::cout << "\tDoing offset addition test." << std::endl;
std::ptrdiff_t const two = 2;
std::stringstream oss;
for ( iter_type i = fruit_begin ; i != fruit_end ; i = i + two )
{
oss << *i << ' ';
}
BOOST_CHECK( oss.str() == "apple pear grape ");
}
// Test offset addition, in reverse order
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::reverse_offset_addition_test
(
)
{
std::cout << "\tDoing reverse offset addition test." << std::endl;
std::ptrdiff_t const two = 2;
std::stringstream oss;
for ( iter_type i = fruit_begin ; i != fruit_end ; i = two + i )
{
oss << *i << ' ';
}
BOOST_CHECK( oss.str() == "apple pear grape ");
}
// Test offset subtraction
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::offset_subtraction_test
(
)
{
std::cout << "\tDoing offset subtraction test." << std::endl;
std::ptrdiff_t const two = 2;
std::stringstream oss;
for ( iter_type i = fruit_end ; fruit_begin < i ; )
{
i = i - two;
if ( (fruit_begin < i) || (fruit_begin == i) )
{
oss << *i << ' ';
}
}
BOOST_CHECK( oss.str() == "grape pear apple ");
}
// Test comparisons
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::comparison_test
(
)
{
using std::cout;
using std::ptrdiff_t;
cout << "\tDoing comparison tests.\n\t\tPass:";
for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
{
ptrdiff_t const i_offset = i - fruit_begin;
cout << ' ' << *i << std::flush;
for ( iter_type j = fruit_begin ; j != fruit_end ; ++j )
{
ptrdiff_t const j_offset = j - fruit_begin;
BOOST_CHECK( (i != j) == (i_offset != j_offset) );
BOOST_CHECK( (i > j) == (i_offset > j_offset) );
BOOST_CHECK( (i <= j) == (i_offset <= j_offset) );
BOOST_CHECK( (i >= j) == (i_offset >= j_offset) );
}
}
cout << std::endl;
}
// Test indexing
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::indexing_test
(
)
{
std::cout << "\tDoing indexing test." << std::endl;
std::stringstream oss;
for ( std::size_t k = 0u ; k < fruit_length ; ++k )
{
oss << fruit_begin[ k ] << ' ';
}
BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
}

113
meta/libraries.json Normal file
View File

@ -0,0 +1,113 @@
[
{
"key": "utility",
"name": "Utility",
"authors": [
"Dave Abrahams and others"
],
"description": "Class noncopyable plus checked_delete(), checked_array_delete(), next(), prior() function templates, plus base-from-member idiom.",
"documentation": "utility.htm",
"category": [
"Algorithms",
"Function-objects",
"Memory",
"Miscellaneous",
"Patterns"
]
},
{
"key": "utility/call_traits",
"name": "Call Traits",
"authors": [
"John Maddock, Howard Hinnant, et al"
],
"description": "Defines types for passing parameters.",
"documentation": "call_traits.htm",
"category": [
"Generic"
]
},
{
"key": "utility/compressed_pair",
"name": "Compressed Pair",
"authors": [
"John Maddock, Howard Hinnant, et al"
],
"description": "Empty member optimization.",
"documentation": "compressed_pair.htm",
"category": [
"Data",
"Patterns"
]
},
{
"key": "utility/identity_type",
"name": "Identity Type",
"authors": [
"Lorenzo Caminiti"
],
"description": "Wrap types within round parenthesis so they can always be passed as macro parameters.",
"documentation": "identity_type/",
"category": [
"Preprocessor"
],
"maintainers": [
"Lorenzo Caminiti <lorcaminiti -at- gmail.com>"
]
},
{
"key": "utility/in_place_factories",
"name": "In Place Factory, Typed In Place Factory",
"authors": [
"Fernando Cacciola"
],
"description": "Generic in-place construction of contained objects with a variadic argument-list.",
"documentation": "in_place_factories.html",
"category": [
"Generic"
]
},
{
"key": "utility/operators",
"name": "Operators",
"authors": [
"Dave Abrahams",
"Jeremy Siek"
],
"description": "Templates ease arithmetic classes and iterators.",
"documentation": "operators.htm",
"category": [
"Generic",
"Iterators",
"Math"
],
"maintainers": [
"Daniel Frey <d.frey -at- gmx.de>"
]
},
{
"key": "utility/result_of",
"name": "Result Of",
"description": "Determines the type of a function call expression.",
"documentation": "utility.htm#result_of",
"category": [
"Function-objects"
],
"authors": "",
"maintainers": [
"Daniel Walker <daniel.j.walker -at- gmail.com>"
]
},
{
"key": "utility/value_initialized",
"name": "Value Initialized",
"authors": [
"Fernando Cacciola"
],
"description": "Wrapper for uniform-syntax value initialization, based on the original idea of David Abrahams.",
"documentation": "value_init.htm",
"category": [
"Miscellaneous"
]
}
]

View File

@ -1,38 +0,0 @@
// boost class noncopyable test program ------------------------------------//
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
// and distribute this software is granted provided this copyright
// notice appears in all copies. This software is provided "as is" without
// express or implied warranty, and with no claim as to its suitability for
// any purpose.
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 9 Jun 99 Add unnamed namespace
// 2 Jun 99 Initial Version
#include <boost/utility.hpp>
#include <iostream>
// This program demonstrates compiler errors resulting from trying to copy
// construct or copy assign a class object derived from class noncopyable.
namespace
{
class DontTreadOnMe : boost::noncopyable
{
public:
DontTreadOnMe() { std::cout << "defanged!" << std::endl; }
}; // DontTreadOnMe
} // unnamed namespace
int main()
{
DontTreadOnMe object1;
DontTreadOnMe object2(object1);
object1 = object2;
return 0;
} // main

406
numeric_traits_test.cpp Normal file
View File

@ -0,0 +1,406 @@
// (C) Copyright David Abrahams 2001.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 1 Apr 2001 Fixes for ICL; use BOOST_STATIC_CONSTANT
// 11 Feb 2001 Fixes for Borland (David Abrahams)
// 23 Jan 2001 Added test for wchar_t (David Abrahams)
// 23 Jan 2001 Now statically selecting a test for signed numbers to avoid
// warnings with fancy compilers. Added commentary and
// additional dumping of traits data for tested types (David
// Abrahams).
// 21 Jan 2001 Initial version (David Abrahams)
#include <boost/detail/numeric_traits.hpp>
#include <cassert>
#include <boost/type_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/utility.hpp>
#include <boost/lexical_cast.hpp>
#include <climits>
#include <typeinfo>
#include <iostream>
#include <string>
#ifndef BOOST_NO_LIMITS
# include <limits>
#endif
// =================================================================================
// template class complement_traits<Number> --
//
// statically computes the max and min for 1s and 2s-complement binary
// numbers. This helps on platforms without <limits> support. It also shows
// an example of a recursive template that works with MSVC!
//
template <unsigned size> struct complement; // forward
// The template complement, below, does all the real work, using "poor man's
// partial specialization". We need complement_traits_aux<> so that MSVC doesn't
// complain about undefined min/max as we're trying to recursively define them.
template <class Number, unsigned size>
struct complement_traits_aux
{
BOOST_STATIC_CONSTANT(Number, max = complement<size>::template traits<Number>::max);
BOOST_STATIC_CONSTANT(Number, min = complement<size>::template traits<Number>::min);
};
template <unsigned size>
struct complement
{
template <class Number>
struct traits
{
private:
// indirection through complement_traits_aux necessary to keep MSVC happy
typedef complement_traits_aux<Number, size - 1> prev;
public:
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
// GCC 4.0.2 ICEs on these C-style casts
BOOST_STATIC_CONSTANT(Number, max =
Number((prev::max) << CHAR_BIT)
+ Number(UCHAR_MAX));
BOOST_STATIC_CONSTANT(Number, min = Number((prev::min) << CHAR_BIT));
#else
// Avoid left shifting negative integers, use multiplication instead
BOOST_STATIC_CONSTANT(Number, shift = 1u << CHAR_BIT);
BOOST_STATIC_CONSTANT(Number, max =
Number(Number(prev::max) * shift)
+ Number(UCHAR_MAX));
BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) * shift));
#endif
};
};
// Template class complement_base<> -- defines values for min and max for
// complement<1>, at the deepest level of recursion. Uses "poor man's partial
// specialization" again.
template <bool is_signed> struct complement_base;
template <> struct complement_base<false>
{
template <class Number>
struct values
{
BOOST_STATIC_CONSTANT(Number, min = 0);
BOOST_STATIC_CONSTANT(Number, max = UCHAR_MAX);
};
};
template <> struct complement_base<true>
{
template <class Number>
struct values
{
BOOST_STATIC_CONSTANT(Number, min = SCHAR_MIN);
BOOST_STATIC_CONSTANT(Number, max = SCHAR_MAX);
};
};
// Base specialization of complement, puts an end to the recursion.
template <>
struct complement<1>
{
template <class Number>
struct traits
{
BOOST_STATIC_CONSTANT(bool, is_signed = boost::detail::is_signed<Number>::value);
BOOST_STATIC_CONSTANT(Number, min =
complement_base<is_signed>::template values<Number>::min);
BOOST_STATIC_CONSTANT(Number, max =
complement_base<is_signed>::template values<Number>::max);
};
};
// Now here's the "pretty" template you're intended to actually use.
// complement_traits<Number>::min, complement_traits<Number>::max are the
// minimum and maximum values of Number if Number is a built-in integer type.
template <class Number>
struct complement_traits
{
BOOST_STATIC_CONSTANT(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max));
BOOST_STATIC_CONSTANT(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min));
};
// =================================================================================
// Support for streaming various numeric types in exactly the format I want. I
// needed this in addition to all the assertions so that I could see exactly
// what was going on.
//
// Numbers go through a 2-stage conversion process (by default, though, no real
// conversion).
//
template <class T> struct stream_as {
typedef T t1;
typedef T t2;
};
// char types first get converted to unsigned char, then to unsigned.
template <> struct stream_as<char> {
typedef unsigned char t1;
typedef unsigned t2;
};
template <> struct stream_as<unsigned char> {
typedef unsigned char t1; typedef unsigned t2;
};
template <> struct stream_as<signed char> {
typedef unsigned char t1; typedef unsigned t2;
};
#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
// With this library implementation, __int64 and __uint64 get streamed as strings
template <> struct stream_as<boost::uintmax_t> {
typedef std::string t1;
typedef std::string t2;
};
template <> struct stream_as<boost::intmax_t> {
typedef std::string t1;
typedef std::string t2;
};
#endif
// Standard promotion process for streaming
template <class T> struct promote
{
static typename stream_as<T>::t1 from(T x) {
typedef typename stream_as<T>::t1 t1;
return t1(x);
}
};
#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
// On this platform, stream them as long/unsigned long if they fit.
// Otherwise, write a string.
template <> struct promote<boost::uintmax_t> {
std::string static from(const boost::uintmax_t x) {
if (x > ULONG_MAX)
return std::string("large unsigned value");
else
return boost::lexical_cast<std::string>((unsigned long)x);
}
};
template <> struct promote<boost::intmax_t> {
std::string static from(const boost::intmax_t x) {
if (x > boost::intmax_t(ULONG_MAX))
return std::string("large positive signed value");
else if (x >= 0)
return boost::lexical_cast<std::string>((unsigned long)x);
if (x < boost::intmax_t(LONG_MIN))
return std::string("large negative signed value");
else
return boost::lexical_cast<std::string>((long)x);
}
};
#endif
// This is the function which converts types to the form I want to stream them in.
template <class T>
typename stream_as<T>::t2 stream_number(T x)
{
return promote<T>::from(x);
}
// =================================================================================
//
// Tests for built-in signed and unsigned types
//
// Tag types for selecting tests
struct unsigned_tag {};
struct signed_tag {};
// Tests for unsigned numbers. The extra default Number parameter works around
// an MSVC bug.
template <class Number>
void test_aux(unsigned_tag, Number*)
{
typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
BOOST_STATIC_ASSERT(!boost::detail::is_signed<Number>::value);
BOOST_STATIC_ASSERT(
(sizeof(Number) < sizeof(boost::intmax_t))
| (boost::is_same<difference_type, boost::intmax_t>::value));
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
// GCC 4.0.2 ICEs on this C-style cases
BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0));
BOOST_STATIC_ASSERT((complement_traits<Number>::min) == Number(0));
#else
// Force casting to Number here to work around the fact that it's an enum on MSVC
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0));
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) == Number(0));
#endif
const Number max = complement_traits<Number>::max;
const Number min = complement_traits<Number>::min;
const Number test_max = (sizeof(Number) < sizeof(boost::intmax_t))
? max
: max / 2 - 1;
std::cout << std::hex << "(unsigned) min = " << stream_number(min) << ", max = "
<< stream_number(max) << "..." << std::flush;
std::cout << "difference_type = " << typeid(difference_type).name() << "..."
<< std::flush;
difference_type d1 = boost::detail::numeric_distance(Number(0), test_max);
difference_type d2 = boost::detail::numeric_distance(test_max, Number(0));
std::cout << "0->" << stream_number(test_max) << "==" << std::dec << stream_number(d1) << "; "
<< std::hex << stream_number(test_max) << "->0==" << std::dec << stream_number(d2) << "..." << std::flush;
assert(d1 == difference_type(test_max));
assert(d2 == -difference_type(test_max));
}
// Tests for signed numbers. The extra default Number parameter works around an
// MSVC bug.
struct out_of_range_tag {};
struct in_range_tag {};
// This test morsel gets executed for numbers whose difference will always be
// representable in intmax_t
template <class Number>
void signed_test(in_range_tag, Number*)
{
BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
const Number max = complement_traits<Number>::max;
const Number min = complement_traits<Number>::min;
difference_type d1 = boost::detail::numeric_distance(min, max);
difference_type d2 = boost::detail::numeric_distance(max, min);
std::cout << stream_number(min) << "->" << stream_number(max) << "==";
std::cout << std::dec << stream_number(d1) << "; ";
std::cout << std::hex << stream_number(max) << "->" << stream_number(min)
<< "==" << std::dec << stream_number(d2) << "..." << std::flush;
assert(d1 == difference_type(max) - difference_type(min));
assert(d2 == difference_type(min) - difference_type(max));
}
// This test morsel gets executed for numbers whose difference may exceed the
// capacity of intmax_t.
template <class Number>
void signed_test(out_of_range_tag, Number*)
{
BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
const Number max = complement_traits<Number>::max;
const Number min = complement_traits<Number>::min;
difference_type min_distance = complement_traits<difference_type>::min;
difference_type max_distance = complement_traits<difference_type>::max;
const Number n1 = Number(min + max_distance);
const Number n2 = Number(max + min_distance);
difference_type d1 = boost::detail::numeric_distance(min, n1);
difference_type d2 = boost::detail::numeric_distance(max, n2);
std::cout << stream_number(min) << "->" << stream_number(n1) << "==";
std::cout << std::dec << stream_number(d1) << "; ";
std::cout << std::hex << stream_number(max) << "->" << stream_number(n2)
<< "==" << std::dec << stream_number(d2) << "..." << std::flush;
assert(d1 == max_distance);
assert(d2 == min_distance);
}
template <class Number>
void test_aux(signed_tag, Number*)
{
typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
BOOST_STATIC_ASSERT(
(sizeof(Number) < sizeof(boost::intmax_t))
| (boost::is_same<difference_type, Number>::value));
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
// GCC 4.0.2 ICEs on this cast
BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0));
BOOST_STATIC_ASSERT((complement_traits<Number>::min) < Number(0));
#else
// Force casting to Number here to work around the fact that it's an enum on MSVC
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0));
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) < Number(0));
#endif
const Number max = complement_traits<Number>::max;
const Number min = complement_traits<Number>::min;
std::cout << std::hex << "min = " << stream_number(min) << ", max = "
<< stream_number(max) << "..." << std::flush;
std::cout << "difference_type = " << typeid(difference_type).name() << "..."
<< std::flush;
typedef typename boost::detail::if_true<
(sizeof(Number) < sizeof(boost::intmax_t))>
::template then<
in_range_tag,
out_of_range_tag
>::type
range_tag;
signed_test<Number>(range_tag(), 0);
}
// Test for all numbers. The extra default Number parameter works around an MSVC
// bug.
template <class Number>
void test(Number* = 0)
{
std::cout << "testing " << typeid(Number).name() << ":\n"
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
<< "is_signed: " << (std::numeric_limits<Number>::is_signed ? "true\n" : "false\n")
<< "is_bounded: " << (std::numeric_limits<Number>::is_bounded ? "true\n" : "false\n")
<< "digits: " << std::numeric_limits<Number>::digits << "\n"
#endif
<< "..." << std::flush;
// factoring out difference_type for the assert below confused Borland :(
typedef boost::detail::is_signed<
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
typename
#endif
boost::detail::numeric_traits<Number>::difference_type
> is_signed;
BOOST_STATIC_ASSERT(is_signed::value);
typedef typename boost::detail::if_true<
boost::detail::is_signed<Number>::value
>::template then<signed_tag, unsigned_tag>::type signedness;
test_aux<Number>(signedness(), 0);
std::cout << "passed" << std::endl;
}
int main()
{
test<char>();
test<unsigned char>();
test<signed char>();
test<wchar_t>();
test<short>();
test<unsigned short>();
test<int>();
test<unsigned int>();
test<long>();
test<unsigned long>();
#if defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_INTEGRAL_INT64_T)
test< ::boost::long_long_type>();
test< ::boost::ulong_long_type>();
#elif defined(BOOST_MSVC)
// The problem of not having compile-time static class constants other than
// enums prevents this from working, since values get truncated.
// test<boost::uintmax_t>();
// test<boost::intmax_t>();
#endif
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,322 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Shared Container Iterator Documentation</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<img src="../../boost.png" alt="boost.png (6897 bytes)"
align="center" width="277" height="86">
<h1>Shared Container Iterator</h1>
Defined in header
<a href="../../boost/shared_container_iterator.hpp">boost/shared_container_iterator.hpp</a>
<p>
The purpose of the shared container iterator is to attach the lifetime
of a container to the lifetime of its iterators. In other words, the
container will not be deleted until after all its iterators are
destroyed. The shared container iterator is typically used to
implement functions that return iterators over a range of objects that
only need to exist for the lifetime of the iterators. By returning a
pair of shared iterators from a function, the callee can return a
heap-allocated range of objects whose lifetime is automatically managed.
<p>
The shared container iterator augments an iterator over a shared
container. It maintains a reference count on the shared
container. If only shared container iterators hold references to
the container, the container's lifetime will end when the last shared
container iterator over it is destroyed. In any case, the shared
container is guaranteed to persist beyond the lifetime of all
the iterators. In all other ways, the
shared container iterator behaves the same as its base iterator.
<h2>Synopsis</h2>
<pre>
namespace boost {
template &lt;typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>&gt;
class shared_container_iterator;
template &lt;typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>&gt;
shared_container_iterator&lt;Container&gt;
make_shared_container_iterator(typename Container::iterator base,
boost::shared_ptr&lt;Container&gt; const&amp; container);
std::pair&lt;
typename shared_container_iterator&lt;Container&gt;,
typename shared_container_iterator&lt;Container&gt;
&gt;
make_shared_container_range(boost::shared_ptr&lt;Container&gt; const&amp; container);
}
</pre>
<hr>
<h2><a name="generator">The Shared Container Iterator Type</a></h2>
<pre>
template &lt;typename Container&gt; class shared_container_iterator;
</pre>
The class template <tt>shared_container_iterator</tt>
is the shared container iterator type. The <tt>Container</tt> template
type argument must model the
<a href="http://www.sgi.com/tech/stl/Container.html">Container</a>
concept.
<h3>Example</h3>
<p>
The following example illustrates how to create an iterator that
regulates the lifetime of a reference counted <tt>std::vector</tt>.
Though the original shared pointer <tt>ints</tt> ceases to exist
after <tt>set_range()</tt> returns, the
<tt>shared_counter_iterator</tt> objects maintain references to the
underlying vector and thereby extend the container's lifetime.
<p>
<a href="./shared_iterator_example1.cpp">shared_iterator_example1.cpp</a>:
<PRE>
<font color="#008040">#include "shared_container_iterator.hpp"</font>
<font color="#008040">#include "boost/shared_ptr.hpp"</font>
<font color="#008040">#include &lt;algorithm&gt;</font>
<font color="#008040">#include &lt;iostream&gt;</font>
<font color="#008040">#include &lt;vector&gt;</font>
<B>typedef</B> boost::shared_container_iterator&lt; std::vector&lt;<B>int</B>&gt; &gt; iterator;
<B>void</B> set_range(iterator& i, iterator& end) {
boost::shared_ptr&lt; std::vector&lt;<B>int</B>&gt; &gt; ints(<B>new</B> std::vector&lt;<B>int</B>&gt;());
ints-&gt;push_back(<font color="#0000A0">0</font>);
ints-&gt;push_back(<font color="#0000A0">1</font>);
ints-&gt;push_back(<font color="#0000A0">2</font>);
ints-&gt;push_back(<font color="#0000A0">3</font>);
ints-&gt;push_back(<font color="#0000A0">4</font>);
ints-&gt;push_back(<font color="#0000A0">5</font>);
i = iterator(ints-&gt;begin(),ints);
end = iterator(ints-&gt;end(),ints);
}
<B>int</B> main() {
iterator i,end;
set_range(i,end);
std::copy(i,end,std::ostream_iterator&lt;<B>int</B>&gt;(std::cout,<font color="#0000FF">","</font>));
std::cout.put(<font color="#0000FF">'\n'</font>);
<B>return</B> <font color="#0000A0">0</font>;
}
</PRE>
The output from this part is:
<pre>
0,1,2,3,4,5,
</pre>
<h3>Template Parameters</h3>
<Table border>
<TR>
<TH>Parameter</TH><TH>Description</TH>
</TR>
<TR>
<TD><a
href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a></TD>
<TD>The type of the container that we wish to iterate over. It must be
a model of the
<a href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a>
concept.
</TD>
</TR>
</Table>
<h3>Model of</h3>
The <tt>shared_container_iterator<Container></tt> type models the
same iterator concept as the base iterator
(<tt>Container::iterator</tt>).
<h3>Members</h3>
The shared container iterator type implements the member functions and
operators required of the <a
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a>
concept, though only operations defined for the base iterator will be valid.
In addition it has the following constructor:
<pre>
shared_container_iterator(Container::iterator const&amp; it,
boost::shared_ptr&lt;Container&gt; const&amp; container)
</pre>
<p>
<hr>
<p>
<h2><a name="make_iterator">The Shared Container Iterator Object Generator</a></h2>
<pre>
template &lt;typename Container&gt;
shared_container_iterator&lt;Container&gt;
make_shared_container_iterator(Container::iterator base,
boost::shared_ptr&lt;Container&gt; const&amp; container)
</pre>
This function provides an alternative to directly constructing a
shared container iterator. Using the object generator, a shared
container iterator can be created and passed to a function without
explicitly specifying its type.
<h3>Example</h3>
This example, similar to the previous, uses
<tt>make_shared_container_iterator()</tt> to create the iterators.
<p>
<a href="./shared_iterator_example2.cpp">shared_iterator_example2.cpp</a>:
<PRE>
<font color="#008040">#include "shared_container_iterator.hpp"</font>
<font color="#008040">#include "boost/shared_ptr.hpp"</font>
<font color="#008040">#include &lt;algorithm&gt;</font>
<font color="#008040">#include &lt;iterator&gt;</font>
<font color="#008040">#include &lt;iostream&gt;</font>
<font color="#008040">#include &lt;vector&gt;</font>
<B>template</B> &lt;<B>typename</B> Iterator&gt;
<B>void</B> print_range_nl (Iterator begin, Iterator end) {
<B>typedef</B> <B>typename</B> std::iterator_traits&lt;Iterator&gt;::value_type val;
std::copy(begin,end,std::ostream_iterator&lt;val&gt;(std::cout,<font color="#0000FF">","</font>));
std::cout.put(<font color="#0000FF">'\n'</font>);
}
<B>int</B> main() {
<B>typedef</B> boost::shared_ptr&lt; std::vector&lt;<B>int</B>&gt; &gt; ints_t;
{
ints_t ints(<B>new</B> std::vector&lt;<B>int</B>&gt;());
ints-&gt;push_back(<font color="#0000A0">0</font>);
ints-&gt;push_back(<font color="#0000A0">1</font>);
ints-&gt;push_back(<font color="#0000A0">2</font>);
ints-&gt;push_back(<font color="#0000A0">3</font>);
ints-&gt;push_back(<font color="#0000A0">4</font>);
ints-&gt;push_back(<font color="#0000A0">5</font>);
print_range_nl(boost::make_shared_container_iterator(ints-&gt;begin(),ints),
boost::make_shared_container_iterator(ints-&gt;end(),ints));
}
<B>return</B> <font color="#0000A0">0</font>;
}
</PRE>
Observe that the <tt>shared_container_iterator</tt> type is never
explicitly named. The output from this example is the same as the previous.
<h2><a name="make_range">The Shared Container Iterator Range Generator</a></h2>
<pre>
template &lt;typename Container&gt;
std::pair&lt
shared_container_iterator&lt;Container&gt;,
shared_container_iterator&lt;Container&gt;
&gt;
make_shared_container_range(boost::shared_ptr&lt;Container&gt; const&amp; container);
</pre>
Class <tt>shared_container_iterator</tt> is meant primarily to return,
using iterators, a range of values that we can guarantee will be alive as
long as the iterators are. This is a convenience
function to do just that. It is equivalent to
<pre>
std::make_pair(make_shared_container_iterator(container-&gt;begin(),container),
make_shared_container_iterator(container-&gt;end(),container));
</pre>
<h3>Example</h3>
In the following example, a range of values is returned as a pair of
<tt>shared_container_iterator</tt> objects.
<p>
<a href="./shared_iterator_example3.cpp">shared_iterator_example3.cpp</a>:
<PRE>
<font color="#008040">#include "shared_container_iterator.hpp"</font>
<font color="#008040">#include "boost/shared_ptr.hpp"</font>
<font color="#008040">#include "boost/tuple/tuple.hpp" // for boost::tie</font>
<font color="#008040">#include &lt;algorithm&gt; // for std::copy</font>
<font color="#008040">#include &lt;iostream&gt; </font>
<font color="#008040">#include &lt;vector&gt;</font>
<B>typedef</B> boost::shared_container_iterator&lt; std::vector&lt;<B>int</B>&gt; &gt; iterator;
std::pair&lt;iterator,iterator&gt;
return_range() {
boost::shared_ptr&lt; std::vector&lt;<B>int</B>&gt; &gt; range(<B>new</B> std::vector&lt;<B>int</B>&gt;());
range-&gt;push_back(<font color="#0000A0">0</font>);
range-&gt;push_back(<font color="#0000A0">1</font>);
range-&gt;push_back(<font color="#0000A0">2</font>);
range-&gt;push_back(<font color="#0000A0">3</font>);
range-&gt;push_back(<font color="#0000A0">4</font>);
range-&gt;push_back(<font color="#0000A0">5</font>);
<B>return</B> boost::make_shared_container_range(range);
}
<B>int</B> main() {
iterator i,end;
boost::tie(i,end) = return_range();
std::copy(i,end,std::ostream_iterator&lt;<B>int</B>&gt;(std::cout,<font color="#0000FF">","</font>));
std::cout.put(<font color="#0000FF">'\n'</font>);
<B>return</B> <font color="#0000A0">0</font>;
}
</PRE>
Though the <tt>range</tt> object only lives for the duration of the
<tt>return_range</tt> call, the reference counted
<tt>std::vector</tt> will live until <tt>i</tt> and <tt>end</tt>
are both destroyed. The output from this example is the same as
the previous two.
<hr>
<!-- hhmts start -->
Last modified: Mon Aug 11 11:27:03 EST 2003
<!-- hhmts end -->
<p><EFBFBD> Copyright 2003 The Trustees of Indiana University.
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)</p>
</body>
</html>

View File

@ -0,0 +1,42 @@
// Copyright 2003 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <algorithm>
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
void set_range(iterator& i, iterator& end) {
boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
i = iterator(ints->begin(),ints);
end = iterator(ints->end(),ints);
}
int main() {
iterator i,end;
set_range(i,end);
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}

View File

@ -0,0 +1,43 @@
// Copyright 2003 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
template <typename Iterator>
void print_range_nl (Iterator begin, Iterator end) {
typedef typename std::iterator_traits<Iterator>::value_type val;
std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
std::cout.put('\n');
}
int main() {
typedef boost::shared_ptr< std::vector<int> > ints_t;
{
ints_t ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
boost::make_shared_container_iterator(ints->end(),ints));
}
return 0;
}

View File

@ -0,0 +1,41 @@
// Copyright 2003 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "boost/shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/tuple/tuple.hpp" // for boost::tie
#include <algorithm> // for std::copy
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
std::pair<iterator,iterator>
return_range() {
boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
range->push_back(0);
range->push_back(1);
range->push_back(2);
range->push_back(3);
range->push_back(4);
range->push_back(5);
return boost::make_shared_container_range(range);
}
int main() {
iterator i,end;
boost::tie(i,end) = return_range();
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}

64
shared_iterator_test.cpp Normal file
View File

@ -0,0 +1,64 @@
// Copyright 2003 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Shared container iterator adaptor
// Author: Ronald Garcia
// See http://boost.org/libs/utility/shared_container_iterator.html
// for documentation.
//
// shared_iterator_test.cpp - Regression tests for shared_container_iterator.
//
#include "boost/shared_container_iterator.hpp"
#include "boost/shared_ptr.hpp"
#include <vector>
#include <cassert>
struct resource {
static int count;
resource() { ++count; }
resource(resource const&) { ++count; }
~resource() { --count; }
};
int resource::count = 0;
typedef std::vector<resource> resources_t;
typedef boost::shared_container_iterator< resources_t > iterator;
void set_range(iterator& i, iterator& end) {
boost::shared_ptr< resources_t > objs(new resources_t());
for (int j = 0; j != 6; ++j)
objs->push_back(resource());
i = iterator(objs->begin(),objs);
end = iterator(objs->end(),objs);
assert(resource::count == 6);
}
int main() {
assert(resource::count == 0);
{
iterator i;
{
iterator end;
set_range(i,end);
assert(resource::count == 6);
}
assert(resource::count == 6);
}
assert(resource::count == 0);
return 0;
}

1
sublibs Normal file
View File

@ -0,0 +1 @@
The existance of this file tells the regression reporting programs that the directory contains sub-directories which are libraries.

47
test/Jamfile.v2 Normal file
View File

@ -0,0 +1,47 @@
# Copyright David Abrahams 2003.
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
# For more information, see http://www.boost.org/
# bring in rules for testing
import testing ;
alias unit_test_framework
: # sources
/boost//unit_test_framework
;
# Please keep the tests ordered by filename
test-suite utility
:
[ run ../base_from_member_test.cpp ]
[ run ../base_from_member_ref_test.cpp ]
[ run ../binary_test.cpp ]
[ run ../call_traits_test.cpp : -u ]
[ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
[ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
[ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
[ run ../numeric_traits_test.cpp ]
[ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
[ compile result_of_test.cpp ]
[ run ../shared_iterator_test.cpp ]
[ run string_ref_test1.cpp unit_test_framework ]
[ run string_ref_test2.cpp unit_test_framework ]
[ run string_ref_test_io.cpp unit_test_framework ]
[ run string_view_test1.cpp unit_test_framework ]
[ run string_view_test2.cpp unit_test_framework ]
[ run string_view_test_io.cpp unit_test_framework ]
[ run ../value_init_test.cpp ]
[ run ../value_init_workaround_test.cpp ]
[ run ../initialized_test.cpp ]
[ compile-fail ../value_init_test_fail1.cpp ]
[ compile-fail ../value_init_test_fail2.cpp ]
[ compile-fail ../value_init_test_fail3.cpp ]
[ compile-fail ../initialized_test_fail1.cpp ]
[ compile-fail ../initialized_test_fail2.cpp ]
[ run ../generator_iterator_test.cpp ]
;

97
test/next_prior_test.cpp Normal file
View File

@ -0,0 +1,97 @@
// Boost test program for next() and prior() utilities.
// Copyright 2003 Daniel Walker. Use, modification, and distribution
// are subject to the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or a copy at
// http://www.boost.org/LICENSE_1_0.txt.)
// See http://www.boost.org/libs/utility for documentation.
// Revision History 13 Dec 2003 Initial Version (Daniel Walker)
// next() and prior() are replacements for operator+ and operator- for
// non-random-access iterators. The semantics of these operators are
// such that after executing j = i + n, std::distance(i, j) equals
// n. Tests are provided to ensure next() has the same
// result. Parallel tests are provided for prior(). The tests call
// next() and prior() several times. next() and prior() are very
// simple functions, though, and it would be very strange if these
// tests were to fail.
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <list>
#include <vector>
#include <boost/next_prior.hpp>
template<class RandomAccessIterator, class ForwardIterator>
bool plus_one_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2)
{
RandomAccessIterator i = first;
ForwardIterator j = first2;
while(i != last)
i = i + 1, j = boost::next(j);
return std::distance(first, i) == std::distance(first2, j);
}
template<class RandomAccessIterator, class ForwardIterator>
bool plus_n_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2)
{
RandomAccessIterator i = first;
ForwardIterator j = first2;
for(int n = 0; i != last; ++n)
i = first + n, j = boost::next(first2, n);
return std::distance(first, i) == std::distance(first2, j);
}
template<class RandomAccessIterator, class BidirectionalIterator>
bool minus_one_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2)
{
RandomAccessIterator i = last;
BidirectionalIterator j = last2;
while(i != first)
i = i - 1, j = boost::prior(j);
return std::distance(i, last) == std::distance(j, last2);
}
template<class RandomAccessIterator, class BidirectionalIterator>
bool minus_n_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2)
{
RandomAccessIterator i = last;
BidirectionalIterator j = last2;
for(int n = 0; i != first; ++n)
i = last - n, j = boost::prior(last2, n);
return std::distance(i, last) == std::distance(j, last2);
}
template<class Iterator, class Distance>
bool minus_n_unsigned_test(Iterator first, Iterator last, Distance size)
{
Iterator i = boost::prior(last, size);
return i == first;
}
int test_main(int, char*[])
{
std::vector<int> x(8);
std::list<int> y(x.begin(), x.end());
// Tests with iterators
BOOST_REQUIRE(plus_one_test(x.begin(), x.end(), y.begin()));
BOOST_REQUIRE(plus_n_test(x.begin(), x.end(), y.begin()));
BOOST_REQUIRE(minus_one_test(x.begin(), x.end(), y.end()));
BOOST_REQUIRE(minus_n_test(x.begin(), x.end(), y.end()));
BOOST_REQUIRE(minus_n_unsigned_test(x.begin(), x.end(), x.size()));
BOOST_REQUIRE(minus_n_unsigned_test(y.begin(), y.end(), y.size()));
// Tests with integers
BOOST_REQUIRE(boost::next(5) == 6);
BOOST_REQUIRE(boost::next(5, 7) == 12);
BOOST_REQUIRE(boost::prior(5) == 4);
BOOST_REQUIRE(boost::prior(5, 7) == -2);
BOOST_REQUIRE(boost::prior(5, 7u) == -2);
return 0;
}

316
test/result_of_test.cpp Normal file
View File

@ -0,0 +1,316 @@
// Boost result_of library
// Copyright Douglas Gregor 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Examples:
// To run the default test:
// $ cd libs/utility/test && bjam
// To test decltype on g++ 2.7:
// $ cd libs/utility/test && bjam cxxflags="-std=c++11 -D BOOST_RESULT_OF_USE_DECLTYPE"
#include <boost/config.hpp>
// For more information, see http://www.boost.org/libs/utility
#include <boost/utility/result_of.hpp>
#include <utility>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
struct int_result_type
{
typedef int result_type;
result_type operator()(float);
};
struct int_result_of
{
template<typename F> struct result { typedef int type; };
result<int_result_of(double)>::type operator()(double);
result<const int_result_of(double)>::type operator()(double) const;
result<int_result_of()>::type operator()();
result<volatile int_result_of()>::type operator()() volatile;
};
struct int_result_type_and_float_result_of_and_char_return
{
typedef int result_type;
template<typename F> struct result { typedef float type; };
char operator()(char);
};
template<typename T>
struct int_result_type_template
{
typedef int result_type;
result_type operator()(float);
};
template<typename T>
struct int_result_of_template
{
template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef int type; };
typename result<int_result_of_template<T>(double)>::type operator()(double);
typename result<const int_result_of_template<T>(double)>::type operator()(double) const;
typename result<int_result_of_template<T>(double)>::type operator()();
typename result<volatile int_result_of_template<T>(double)>::type operator()() volatile;
};
template<typename T>
struct int_result_type_and_float_result_of_and_char_return_template
{
typedef int result_type;
template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef float type; };
char operator()(char);
};
template<typename T>
struct cv_overload_check {};
struct result_of_member_function_template
{
template<typename F> struct result;
template<typename This, typename That> struct result<This(That)> { typedef That type; };
template<class T> typename result<result_of_member_function_template(T)>::type operator()(T);
template<typename This, typename That> struct result<const This(That)> { typedef cv_overload_check<const That> type; };
template<class T> typename result<const result_of_member_function_template(T)>::type operator()(T) const;
template<typename This, typename That> struct result<volatile This(That)> { typedef cv_overload_check<volatile That> type; };
template<class T> typename result<volatile result_of_member_function_template(T)>::type operator()(T) volatile;
template<typename This, typename That> struct result<const volatile This(That)> { typedef cv_overload_check<const volatile That> type; };
template<class T> typename result<const volatile result_of_member_function_template(T)>::type operator()(T) const volatile;
template<typename This, typename That> struct result<This(That &, That)> { typedef That & type; };
template<class T> typename result<result_of_member_function_template(T &, T)>::type operator()(T &, T);
template<typename This, typename That> struct result<This(That const &, That)> { typedef That const & type; };
template<class T> typename result<result_of_member_function_template(T const &, T)>::type operator()(T const &, T);
template<typename This, typename That> struct result<This(That volatile &, That)> { typedef That volatile & type; };
template<class T> typename result<result_of_member_function_template(T volatile &, T)>::type operator()(T volatile &, T);
template<typename This, typename That> struct result<This(That const volatile &, That)> { typedef That const volatile & type; };
template<class T> typename result<result_of_member_function_template(T const volatile &, T)>::type operator()(T const volatile &, T);
};
struct no_result_type_or_result
{
short operator()(double);
cv_overload_check<const short> operator()(double) const;
cv_overload_check<volatile short> operator()(double) volatile;
cv_overload_check<const volatile short> operator()(double) const volatile;
int operator()();
cv_overload_check<const int> operator()() const;
cv_overload_check<volatile int> operator()() volatile;
cv_overload_check<const volatile int> operator()() const volatile;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
short operator()(int&&);
int operator()(int&);
long operator()(int const&);
#endif
};
template<typename T>
struct no_result_type_or_result_template
{
short operator()(double);
cv_overload_check<const short> operator()(double) const;
cv_overload_check<volatile short> operator()(double) volatile;
cv_overload_check<const volatile short> operator()(double) const volatile;
int operator()();
cv_overload_check<const int> operator()() const;
cv_overload_check<volatile int> operator()() volatile;
cv_overload_check<const volatile int> operator()() const volatile;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
short operator()(int&&);
int operator()(int&);
long operator()(int const&);
#endif
};
// sfinae_tests are derived from example code from Joel de Guzman,
// which demonstrated the interaction between result_of and SFINAE.
template <typename F, typename Arg>
typename boost::result_of<F(Arg const&)>::type
sfinae_test(F f, Arg const& arg)
{
return f(arg);
}
template <typename F, typename Arg>
typename boost::result_of<F(Arg&)>::type
sfinae_test(F f, Arg& arg)
{
return f(arg);
}
int sfinae_test_f(int& i)
{
return i;
}
struct X {};
int main()
{
using namespace boost;
typedef int (*func_ptr)(float, double);
typedef int (&func_ref)(float, double);
typedef int (*func_ptr_0)();
typedef int (&func_ref_0)();
typedef void (*func_ptr_void)(float, double);
typedef void (&func_ref_void)(float, double);
typedef void (*func_ptr_void_0)();
typedef void (&func_ref_void_0)();
typedef int (X::*mem_func_ptr)(float);
typedef int (X::*mem_func_ptr_c)(float) const;
typedef int (X::*mem_func_ptr_v)(float) volatile;
typedef int (X::*mem_func_ptr_cv)(float) const volatile;
typedef int (X::*mem_func_ptr_0)();
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_template<void>(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_template<void>(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of_template<void>(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
// Prior to decltype, result_of could not deduce the return type
// of nullary function objects unless they exposed a result_type.
#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, int>::value));
#else
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
#endif
// Prior to decltype, result_of ignored a nested result<> if
// result_type was defined. After decltype, result_of deduces the
// actual return type of the function object, ignoring both
// result<> and result_type.
#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value));
#else
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
#endif
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ref_0()>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void(char, float)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void(char, float)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void_0()>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void_0()>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_c(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_0()>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_0()>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void(char, float)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void(char, float)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void_0()>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void_0()>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_c(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_v(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_0(X)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
typedef int (*pf_t)(int);
BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(double)>::type, cv_overload_check<const volatile short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(void)>::type, cv_overload_check<const int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(void)>::type, cv_overload_check<volatile int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(void)>::type, cv_overload_check<const volatile int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(double)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<volatile short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const volatile short> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(void)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<volatile int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const volatile int> >::value));
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&&)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int const&)>::type, long>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&&)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int const&)>::type, long>::value));
#endif
#endif
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
int i = 123;
sfinae_test(sfinae_test_f, i);
#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
return 0;
}

109
test/string_ref_test1.cpp Normal file
View File

@ -0,0 +1,109 @@
/*
Copyright (c) Marshall Clow 2012-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <algorithm>
#include <string>
#include <boost/utility/string_ref.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
typedef boost::string_ref string_ref;
// Should be equal
void interop ( const std::string &str, string_ref ref ) {
// BOOST_CHECK ( str == ref );
BOOST_CHECK ( str.size () == ref.size ());
BOOST_CHECK ( std::equal ( str.begin (), str.end (), ref.begin ()));
BOOST_CHECK ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
}
void null_tests ( const char *p ) {
// All zero-length string-refs should be equal
string_ref sr1; // NULL, 0
string_ref sr2 ( NULL, 0 );
string_ref sr3 ( p, 0 );
string_ref sr4 ( p );
sr4.clear ();
BOOST_CHECK ( sr1 == sr2 );
BOOST_CHECK ( sr1 == sr3 );
BOOST_CHECK ( sr2 == sr3 );
BOOST_CHECK ( sr1 == sr4 );
}
// make sure that substrings work just like strings
void test_substr ( const std::string &str ) {
const size_t sz = str.size ();
string_ref ref ( str );
// Substrings at the end
for ( size_t i = 0; i <= sz; ++ i )
interop ( str.substr ( i ), ref.substr ( i ));
// Substrings at the beginning
for ( size_t i = 0; i <= sz; ++ i )
interop ( str.substr ( 0, i ), ref.substr ( 0, i ));
// All possible substrings
for ( size_t i = 0; i < sz; ++i )
for ( size_t j = i; j < sz; ++j )
interop ( str.substr ( i, j ), ref.substr ( i, j ));
}
// make sure that removing prefixes and suffixes work just like strings
void test_remove ( const std::string &str ) {
const size_t sz = str.size ();
std::string work;
string_ref ref;
for ( size_t i = 1; i <= sz; ++i ) {
work = str;
ref = str;
while ( ref.size () >= i ) {
interop ( work, ref );
work.erase ( 0, i );
ref.remove_prefix (i);
}
}
for ( size_t i = 1; i < sz; ++ i ) {
work = str;
ref = str;
while ( ref.size () >= i ) {
interop ( work, ref );
work.erase ( work.size () - i, i );
ref.remove_suffix (i);
}
}
}
const char *test_strings [] = {
"",
"1",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789",
NULL
};
BOOST_AUTO_TEST_CASE( test_main )
{
const char **p = &test_strings[0];
while ( *p != NULL ) {
interop ( *p, *p );
test_substr ( *p );
test_remove ( *p );
null_tests ( *p );
p++;
}
}

318
test/string_ref_test2.cpp Normal file
View File

@ -0,0 +1,318 @@
/*
Copyright (c) Marshall Clow 2012-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <cstring> // for std::strchr
#include <boost/utility/string_ref.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
typedef boost::string_ref string_ref;
void ends_with ( const char *arg ) {
const size_t sz = std::strlen ( arg );
string_ref sr ( arg );
string_ref sr2 ( arg );
const char *p = arg;
while ( *p ) {
BOOST_CHECK ( sr.ends_with ( p ));
++p;
}
while ( !sr2.empty ()) {
BOOST_CHECK ( sr.ends_with ( sr2 ));
sr2.remove_prefix (1);
}
sr2 = arg;
while ( !sr2.empty ()) {
BOOST_CHECK ( sr.ends_with ( sr2 ));
sr2.remove_prefix (1);
}
char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
sr2 = arg;
if ( sz > 0 )
BOOST_CHECK ( sr2.ends_with ( ch ));
BOOST_CHECK ( !sr2.ends_with ( ++ch ));
BOOST_CHECK ( sr2.ends_with ( string_ref ()));
}
void starts_with ( const char *arg ) {
const size_t sz = std::strlen ( arg );
string_ref sr ( arg );
string_ref sr2 ( arg );
const char *p = arg + std::strlen ( arg ) - 1;
while ( p >= arg ) {
std::string foo ( arg, p + 1 );
BOOST_CHECK ( sr.starts_with ( foo ));
--p;
}
while ( !sr2.empty ()) {
BOOST_CHECK ( sr.starts_with ( sr2 ));
sr2.remove_suffix (1);
}
char ch = *arg;
sr2 = arg;
if ( sz > 0 )
BOOST_CHECK ( sr2.starts_with ( ch ));
BOOST_CHECK ( !sr2.starts_with ( ++ch ));
BOOST_CHECK ( sr2.starts_with ( string_ref ()));
}
void reverse ( const char *arg ) {
// Round trip
string_ref sr1 ( arg );
std::string string1 ( sr1.rbegin (), sr1.rend ());
string_ref sr2 ( string1 );
std::string string2 ( sr2.rbegin (), sr2.rend ());
BOOST_CHECK ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
BOOST_CHECK ( string2 == arg );
BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
}
// This helper function eliminates signed vs. unsigned warnings
string_ref::size_type ptr_diff ( const char *res, const char *base ) {
BOOST_CHECK ( res >= base );
return static_cast<string_ref::size_type> ( res - base );
}
void find ( const char *arg ) {
string_ref sr1;
string_ref sr2;
const char *p;
// Look for each character in the string(searching from the start)
p = arg;
sr1 = arg;
while ( *p ) {
string_ref::size_type pos = sr1.find(*p);
BOOST_CHECK ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg )));
++p;
}
// Look for each character in the string (searching from the end)
p = arg;
sr1 = arg;
while ( *p ) {
string_ref::size_type pos = sr1.rfind(*p);
BOOST_CHECK ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
++p;
}
// Look for pairs on characters (searching from the start)
sr1 = arg;
p = arg;
while ( *p && *(p+1)) {
string_ref sr3 ( p, 2 );
string_ref::size_type pos = sr1.find ( sr3 );
BOOST_CHECK ( pos != string_ref::npos && pos <= static_cast<string_ref::size_type>( p - arg ));
p++;
}
sr1 = arg;
p = arg;
// for all possible chars, see if we find them in the right place.
// Note that strchr will/might do the _wrong_ thing if we search for NULL
for ( int ch = 1; ch < 256; ++ch ) {
string_ref::size_type pos = sr1.find(ch);
const char *strp = std::strchr ( arg, ch );
BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
if ( strp != NULL )
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
}
sr1 = arg;
p = arg;
// for all possible chars, see if we find them in the right place.
// Note that strchr will/might do the _wrong_ thing if we search for NULL
for ( int ch = 1; ch < 256; ++ch ) {
string_ref::size_type pos = sr1.rfind(ch);
const char *strp = std::strrchr ( arg, ch );
BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
if ( strp != NULL )
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
}
// Find everything at the start
p = arg;
sr1 = arg;
while ( !sr1.empty ()) {
string_ref::size_type pos = sr1.find(*p);
BOOST_CHECK ( pos == 0 );
sr1.remove_prefix (1);
++p;
}
// Find everything at the end
sr1 = arg;
p = arg + std::strlen ( arg ) - 1;
while ( !sr1.empty ()) {
string_ref::size_type pos = sr1.rfind(*p);
BOOST_CHECK ( pos == sr1.size () - 1 );
sr1.remove_suffix (1);
--p;
}
// Find everything at the start
sr1 = arg;
p = arg;
while ( !sr1.empty ()) {
string_ref::size_type pos = sr1.find_first_of(*p);
BOOST_CHECK ( pos == 0 );
sr1.remove_prefix (1);
++p;
}
// Find everything at the end
sr1 = arg;
p = arg + std::strlen ( arg ) - 1;
while ( !sr1.empty ()) {
string_ref::size_type pos = sr1.find_last_of(*p);
BOOST_CHECK ( pos == sr1.size () - 1 );
sr1.remove_suffix (1);
--p;
}
// Basic sanity checking for "find_first_of / find_first_not_of"
sr1 = arg;
sr2 = arg;
while ( !sr1.empty() ) {
BOOST_CHECK ( sr1.find_first_of ( sr2 ) == 0 );
BOOST_CHECK ( sr1.find_first_not_of ( sr2 ) == string_ref::npos );
sr1.remove_prefix ( 1 );
}
p = arg;
sr1 = arg;
while ( *p ) {
string_ref::size_type pos1 = sr1.find_first_of(*p);
string_ref::size_type pos2 = sr1.find_first_not_of(*p);
BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
if ( pos2 != string_ref::npos ) {
for ( size_t i = 0 ; i < pos2; ++i )
BOOST_CHECK ( sr1[i] == *p );
BOOST_CHECK ( sr1 [ pos2 ] != *p );
}
BOOST_CHECK ( pos2 != pos1 );
++p;
}
// Basic sanity checking for "find_last_of / find_last_not_of"
sr1 = arg;
sr2 = arg;
while ( !sr1.empty() ) {
BOOST_CHECK ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
BOOST_CHECK ( sr1.find_last_not_of ( sr2 ) == string_ref::npos );
sr1.remove_suffix ( 1 );
}
p = arg;
sr1 = arg;
while ( *p ) {
string_ref::size_type pos1 = sr1.find_last_of(*p);
string_ref::size_type pos2 = sr1.find_last_not_of(*p);
BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
BOOST_CHECK ( pos2 == string_ref::npos || pos1 < sr1.size ());
if ( pos2 != string_ref::npos ) {
for ( size_t i = sr1.size () -1 ; i > pos2; --i )
BOOST_CHECK ( sr1[i] == *p );
BOOST_CHECK ( sr1 [ pos2 ] != *p );
}
BOOST_CHECK ( pos2 != pos1 );
++p;
}
}
void to_string ( const char *arg ) {
string_ref sr1;
std::string str1;
std::string str2;
str1.assign ( arg );
sr1 = arg;
// str2 = sr1.to_string<std::allocator<char> > ();
str2 = sr1.to_string ();
BOOST_CHECK ( str1 == str2 );
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
std::string str3 = static_cast<std::string> ( sr1 );
BOOST_CHECK ( str1 == str3 );
#endif
}
void compare ( const char *arg ) {
string_ref sr1;
std::string str1;
std::string str2 = str1;
str1.assign ( arg );
sr1 = arg;
BOOST_CHECK ( sr1 == sr1); // compare string_ref and string_ref
BOOST_CHECK ( sr1 == str1); // compare string and string_ref
BOOST_CHECK ( str1 == sr1 ); // compare string_ref and string
BOOST_CHECK ( sr1 == arg ); // compare string_ref and pointer
BOOST_CHECK ( arg == sr1 ); // compare pointer and string_ref
if ( sr1.size () > 0 ) {
(*str1.rbegin())++;
BOOST_CHECK ( sr1 != str1 );
BOOST_CHECK ( str1 != sr1 );
BOOST_CHECK ( sr1 < str1 );
BOOST_CHECK ( sr1 <= str1 );
BOOST_CHECK ( str1 > sr1 );
BOOST_CHECK ( str1 >= sr1 );
(*str1.rbegin()) -= 2;
BOOST_CHECK ( sr1 != str1 );
BOOST_CHECK ( str1 != sr1 );
BOOST_CHECK ( sr1 > str1 );
BOOST_CHECK ( sr1 >= str1 );
BOOST_CHECK ( str1 < sr1 );
BOOST_CHECK ( str1 <= sr1 );
}
}
const char *test_strings [] = {
"",
"0",
"abc",
"AAA", // all the same
"adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf",
"abc\0asdfadsfasf",
NULL
};
BOOST_AUTO_TEST_CASE( test_main )
{
const char **p = &test_strings[0];
while ( *p != NULL ) {
starts_with ( *p );
ends_with ( *p );
reverse ( *p );
find ( *p );
to_string ( *p );
compare ( *p );
p++;
}
}

179
test/string_ref_test_io.cpp Normal file
View File

@ -0,0 +1,179 @@
/*
* Copyright Andrey Semashev 2013.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file string_ref_test_io.cpp
* \author Andrey Semashev
* \date 26.05.2013
*
* \brief This header contains tests for stream operations of \c basic_string_ref.
*/
#define BOOST_TEST_MODULE string_ref_test_io
#include <boost/utility/string_ref.hpp>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <string>
#include <boost/config.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/test/unit_test.hpp>
typedef boost::mpl::vector<
char
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
, wchar_t
#endif
/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available.
#if !defined(BOOST_NO_CXX11_CHAR16_T)
, char16_t
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
, char32_t
#endif
*/
>::type char_types;
static const char* test_strings[] =
{
"begin",
"abcd",
"end"
};
//! The context with test data for particular character type
template< typename CharT >
struct context
{
typedef CharT char_type;
typedef std::basic_string< char_type > string_type;
typedef std::basic_ostringstream< char_type > ostream_type;
string_type begin, abcd, end;
context()
{
boost::string_ref str = test_strings[0];
std::copy(str.begin(), str.end(), std::back_inserter(begin));
str = test_strings[1];
std::copy(str.begin(), str.end(), std::back_inserter(abcd));
str = test_strings[2];
std::copy(str.begin(), str.end(), std::back_inserter(end));
}
};
// Test regular output
BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types)
{
typedef CharT char_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_ref< char_type > string_ref_type;
context< char_type > ctx;
ostream_type strm;
strm << string_ref_type(ctx.abcd);
BOOST_CHECK(strm.str() == ctx.abcd);
}
// Test support for padding
BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
{
typedef CharT char_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_ref< char_type > string_ref_type;
context< char_type > ctx;
// Test for padding
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
// Test for long padding
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::setw(100) << string_ref_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
// Test that short width does not truncate the string
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::setw(1) << string_ref_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
}
// Test support for padding fill
BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
{
typedef CharT char_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_ref< char_type > string_ref_type;
context< char_type > ctx;
ostream_type strm_ref;
strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
// Test support for alignment
BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
{
typedef CharT char_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_ref< char_type > string_ref_type;
context< char_type > ctx;
// Left alignment
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::left << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
// Right alignment
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::right << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
}

109
test/string_view_test1.cpp Normal file
View File

@ -0,0 +1,109 @@
/*
Copyright (c) Marshall Clow 2012-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <algorithm>
#include <string>
#include <boost/utility/string_view.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
typedef boost::string_view string_view;
// Should be equal
void interop ( const std::string &str, string_view ref ) {
// BOOST_CHECK ( str == ref );
BOOST_CHECK ( str.size () == ref.size ());
BOOST_CHECK ( std::equal ( str.begin (), str.end (), ref.begin ()));
BOOST_CHECK ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
}
void null_tests ( const char *p ) {
// All zero-length string-refs should be equal
string_view sr1; // NULL, 0
string_view sr2 ( NULL, 0 );
string_view sr3 ( p, 0 );
string_view sr4 ( p );
sr4.clear ();
BOOST_CHECK ( sr1 == sr2 );
BOOST_CHECK ( sr1 == sr3 );
BOOST_CHECK ( sr2 == sr3 );
BOOST_CHECK ( sr1 == sr4 );
}
// make sure that substrings work just like strings
void test_substr ( const std::string &str ) {
const size_t sz = str.size ();
string_view ref ( str );
// Substrings at the end
for ( size_t i = 0; i <= sz; ++ i )
interop ( str.substr ( i ), ref.substr ( i ));
// Substrings at the beginning
for ( size_t i = 0; i <= sz; ++ i )
interop ( str.substr ( 0, i ), ref.substr ( 0, i ));
// All possible substrings
for ( size_t i = 0; i < sz; ++i )
for ( size_t j = i; j < sz; ++j )
interop ( str.substr ( i, j ), ref.substr ( i, j ));
}
// make sure that removing prefixes and suffixes work just like strings
void test_remove ( const std::string &str ) {
const size_t sz = str.size ();
std::string work;
string_view ref;
for ( size_t i = 1; i <= sz; ++i ) {
work = str;
ref = str;
while ( ref.size () >= i ) {
interop ( work, ref );
work.erase ( 0, i );
ref.remove_prefix (i);
}
}
for ( size_t i = 1; i < sz; ++ i ) {
work = str;
ref = str;
while ( ref.size () >= i ) {
interop ( work, ref );
work.erase ( work.size () - i, i );
ref.remove_suffix (i);
}
}
}
const char *test_strings [] = {
"",
"1",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789",
NULL
};
BOOST_AUTO_TEST_CASE( test_main )
{
const char **p = &test_strings[0];
while ( *p != NULL ) {
interop ( *p, *p );
test_substr ( *p );
test_remove ( *p );
null_tests ( *p );
p++;
}
}

405
test/string_view_test2.cpp Normal file
View File

@ -0,0 +1,405 @@
/*
Copyright (c) Marshall Clow 2012-2012.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#include <new> // for placement new
#include <iostream>
#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
#include <cstring> // for std::strchr and std::strcmp
#include <cstdlib> // for std::malloc and std::free
#include <boost/utility/string_view.hpp>
#include <boost/config.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
typedef boost::string_view string_view;
void ends_with ( const char *arg ) {
const size_t sz = std::strlen ( arg );
string_view sr ( arg );
string_view sr2 ( arg );
const char *p = arg;
while ( *p ) {
BOOST_CHECK ( sr.ends_with ( p ));
++p;
}
while ( !sr2.empty ()) {
BOOST_CHECK ( sr.ends_with ( sr2 ));
sr2.remove_prefix (1);
}
sr2 = arg;
while ( !sr2.empty ()) {
BOOST_CHECK ( sr.ends_with ( sr2 ));
sr2.remove_prefix (1);
}
char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
sr2 = arg;
if ( sz > 0 )
BOOST_CHECK ( sr2.ends_with ( ch ));
BOOST_CHECK ( !sr2.ends_with ( ++ch ));
BOOST_CHECK ( sr2.ends_with ( string_view()));
}
void starts_with ( const char *arg ) {
const size_t sz = std::strlen ( arg );
string_view sr ( arg );
string_view sr2 ( arg );
const char *p = arg + std::strlen ( arg ) - 1;
while ( p >= arg ) {
std::string foo ( arg, p + 1 );
BOOST_CHECK ( sr.starts_with ( foo ));
--p;
}
while ( !sr2.empty ()) {
BOOST_CHECK ( sr.starts_with ( sr2 ));
sr2.remove_suffix (1);
}
char ch = *arg;
sr2 = arg;
if ( sz > 0 )
BOOST_CHECK ( sr2.starts_with ( ch ));
BOOST_CHECK ( !sr2.starts_with ( ++ch ));
BOOST_CHECK ( sr2.starts_with ( string_view ()));
}
void reverse ( const char *arg ) {
// Round trip
string_view sr1 ( arg );
std::string string1 ( sr1.rbegin (), sr1.rend ());
string_view sr2 ( string1 );
std::string string2 ( sr2.rbegin (), sr2.rend ());
BOOST_CHECK ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
BOOST_CHECK ( string2 == arg );
BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
}
// This helper function eliminates signed vs. unsigned warnings
string_view::size_type ptr_diff ( const char *res, const char *base ) {
BOOST_CHECK ( res >= base );
return static_cast<string_view::size_type> ( res - base );
}
void find ( const char *arg ) {
string_view sr1;
string_view sr2;
const char *p;
// Look for each character in the string(searching from the start)
p = arg;
sr1 = arg;
while ( *p ) {
string_view::size_type pos = sr1.find(*p);
BOOST_CHECK ( pos != string_view::npos && ( pos <= ptr_diff ( p, arg )));
++p;
}
// Look for each character in the string (searching from the end)
p = arg;
sr1 = arg;
while ( *p ) {
string_view::size_type pos = sr1.rfind(*p);
BOOST_CHECK ( pos != string_view::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
++p;
}
// Look for pairs on characters (searching from the start)
sr1 = arg;
p = arg;
while ( *p && *(p+1)) {
string_view sr3 ( p, 2 );
string_view::size_type pos = sr1.find ( sr3 );
BOOST_CHECK ( pos != string_view::npos && pos <= static_cast<string_view::size_type>( p - arg ));
p++;
}
sr1 = arg;
p = arg;
// for all possible chars, see if we find them in the right place.
// Note that strchr will/might do the _wrong_ thing if we search for NULL
for ( int ch = 1; ch < 256; ++ch ) {
string_view::size_type pos = sr1.find(ch);
const char *strp = std::strchr ( arg, ch );
BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos ));
if ( strp != NULL )
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
}
sr1 = arg;
p = arg;
// for all possible chars, see if we find them in the right place.
// Note that strchr will/might do the _wrong_ thing if we search for NULL
for ( int ch = 1; ch < 256; ++ch ) {
string_view::size_type pos = sr1.rfind(ch);
const char *strp = std::strrchr ( arg, ch );
BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos ));
if ( strp != NULL )
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
}
// Find everything at the start
p = arg;
sr1 = arg;
while ( !sr1.empty ()) {
string_view::size_type pos = sr1.find(*p);
BOOST_CHECK ( pos == 0 );
sr1.remove_prefix (1);
++p;
}
// Find everything at the end
sr1 = arg;
p = arg + std::strlen ( arg ) - 1;
while ( !sr1.empty ()) {
string_view::size_type pos = sr1.rfind(*p);
BOOST_CHECK ( pos == sr1.size () - 1 );
sr1.remove_suffix (1);
--p;
}
// Find everything at the start
sr1 = arg;
p = arg;
while ( !sr1.empty ()) {
string_view::size_type pos = sr1.find_first_of(*p);
BOOST_CHECK ( pos == 0 );
sr1.remove_prefix (1);
++p;
}
// Find everything at the end
sr1 = arg;
p = arg + std::strlen ( arg ) - 1;
while ( !sr1.empty ()) {
string_view::size_type pos = sr1.find_last_of(*p);
BOOST_CHECK ( pos == sr1.size () - 1 );
sr1.remove_suffix (1);
--p;
}
// Basic sanity checking for "find_first_of / find_first_not_of"
sr1 = arg;
sr2 = arg;
while ( !sr1.empty() ) {
BOOST_CHECK ( sr1.find_first_of ( sr2 ) == 0 );
BOOST_CHECK ( sr1.find_first_not_of ( sr2 ) == string_view::npos );
sr1.remove_prefix ( 1 );
}
p = arg;
sr1 = arg;
while ( *p ) {
string_view::size_type pos1 = sr1.find_first_of(*p);
string_view::size_type pos2 = sr1.find_first_not_of(*p);
BOOST_CHECK ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
if ( pos2 != string_view::npos ) {
for ( size_t i = 0 ; i < pos2; ++i )
BOOST_CHECK ( sr1[i] == *p );
BOOST_CHECK ( sr1 [ pos2 ] != *p );
}
BOOST_CHECK ( pos2 != pos1 );
++p;
}
// Basic sanity checking for "find_last_of / find_last_not_of"
sr1 = arg;
sr2 = arg;
while ( !sr1.empty() ) {
BOOST_CHECK ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
BOOST_CHECK ( sr1.find_last_not_of ( sr2 ) == string_view::npos );
sr1.remove_suffix ( 1 );
}
p = arg;
sr1 = arg;
while ( *p ) {
string_view::size_type pos1 = sr1.find_last_of(*p);
string_view::size_type pos2 = sr1.find_last_not_of(*p);
BOOST_CHECK ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
BOOST_CHECK ( pos2 == string_view::npos || pos1 < sr1.size ());
if ( pos2 != string_view::npos ) {
for ( size_t i = sr1.size () -1 ; i > pos2; --i )
BOOST_CHECK ( sr1[i] == *p );
BOOST_CHECK ( sr1 [ pos2 ] != *p );
}
BOOST_CHECK ( pos2 != pos1 );
++p;
}
}
template <typename T>
class custom_allocator {
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef void* void_pointer;
typedef const void* const_void_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T& reference;
typedef const T& const_reference;
template<class U>
struct rebind {
typedef custom_allocator<U> other;
};
custom_allocator() BOOST_NOEXCEPT {}
template <typename U>
custom_allocator(custom_allocator<U> const&) BOOST_NOEXCEPT {}
pointer allocate(size_type n) const {
return static_cast<pointer>(std::malloc(sizeof(value_type) * n));
}
void deallocate(pointer p, size_type) const BOOST_NOEXCEPT {
std::free(p);
}
pointer address(reference value) const BOOST_NOEXCEPT {
return &value;
}
const_pointer address(const_reference value) const BOOST_NOEXCEPT {
return &value;
}
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {
return (~(size_type)0u) / sizeof(value_type);
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class U, class... Args>
void construct(U* ptr, Args&&... args) const {
::new((void*)ptr) U(static_cast<Args&&>(args)...);
}
#else
template <class U, class V>
void construct(U* ptr, V&& value) const {
::new((void*)ptr) U(static_cast<V&&>(value));
}
#endif
#else
template <class U, class V>
void construct(U* ptr, const V& value) const {
::new((void*)ptr) U(value);
}
#endif
template <class U>
void construct(U* ptr) const {
::new((void*)ptr) U();
}
template <class U>
void destroy(U* ptr) const {
(void)ptr;
ptr->~U();
}
};
template <typename T, typename U>
BOOST_CONSTEXPR bool operator==(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
return true;
}
template <typename T, typename U>
BOOST_CONSTEXPR bool operator!=(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
return false;
}
void to_string ( const char *arg ) {
string_view sr1;
std::string str1;
std::string str2;
str1.assign ( arg );
sr1 = arg;
// str2 = sr1.to_string<std::allocator<char> > ();
str2 = sr1.to_string ();
BOOST_CHECK ( str1 == str2 );
std::basic_string<char, std::char_traits<char>, custom_allocator<char> > str3 = sr1.to_string(custom_allocator<char>());
BOOST_CHECK ( std::strcmp(str1.c_str(), str3.c_str()) == 0 );
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
std::string str4 = static_cast<std::string> ( sr1 );
BOOST_CHECK ( str1 == str4 );
#endif
}
void compare ( const char *arg ) {
string_view sr1;
std::string str1;
std::string str2 = str1;
str1.assign ( arg );
sr1 = arg;
BOOST_CHECK ( sr1 == sr1); // compare string_view and string_view
BOOST_CHECK ( sr1 == str1); // compare string and string_view
BOOST_CHECK ( str1 == sr1 ); // compare string_view and string
BOOST_CHECK ( sr1 == arg ); // compare string_view and pointer
BOOST_CHECK ( arg == sr1 ); // compare pointer and string_view
if ( sr1.size () > 0 ) {
(*str1.rbegin())++;
BOOST_CHECK ( sr1 != str1 );
BOOST_CHECK ( str1 != sr1 );
BOOST_CHECK ( sr1 < str1 );
BOOST_CHECK ( sr1 <= str1 );
BOOST_CHECK ( str1 > sr1 );
BOOST_CHECK ( str1 >= sr1 );
(*str1.rbegin()) -= 2;
BOOST_CHECK ( sr1 != str1 );
BOOST_CHECK ( str1 != sr1 );
BOOST_CHECK ( sr1 > str1 );
BOOST_CHECK ( sr1 >= str1 );
BOOST_CHECK ( str1 < sr1 );
BOOST_CHECK ( str1 <= sr1 );
}
}
const char *test_strings [] = {
"",
"0",
"abc",
"AAA", // all the same
"adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf",
"abc\0asdfadsfasf",
NULL
};
BOOST_AUTO_TEST_CASE( test_main )
{
const char **p = &test_strings[0];
while ( *p != NULL ) {
starts_with ( *p );
ends_with ( *p );
reverse ( *p );
find ( *p );
to_string ( *p );
compare ( *p );
p++;
}
}

View File

@ -0,0 +1,179 @@
/*
* Copyright Andrey Semashev 2013.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file string_ref_test_io.cpp
* \author Andrey Semashev
* \date 26.05.2013
*
* \brief This header contains tests for stream operations of \c basic_string_ref.
*/
#define BOOST_TEST_MODULE string_ref_test_io
#include <boost/utility/string_view.hpp>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <string>
#include <boost/config.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/test/unit_test.hpp>
typedef boost::mpl::vector<
char
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
, wchar_t
#endif
/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available.
#if !defined(BOOST_NO_CXX11_CHAR16_T)
, char16_t
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
, char32_t
#endif
*/
>::type char_types;
static const char* test_strings[] =
{
"begin",
"abcd",
"end"
};
//! The context with test data for particular character type
template< typename CharT >
struct context
{
typedef CharT char_type;
typedef std::basic_string< char_type > string_type;
typedef std::basic_ostringstream< char_type > ostream_type;
string_type begin, abcd, end;
context()
{
boost::string_view str = test_strings[0];
std::copy(str.begin(), str.end(), std::back_inserter(begin));
str = test_strings[1];
std::copy(str.begin(), str.end(), std::back_inserter(abcd));
str = test_strings[2];
std::copy(str.begin(), str.end(), std::back_inserter(end));
}
};
// Test regular output
BOOST_AUTO_TEST_CASE_TEMPLATE(string_view_output, CharT, char_types)
{
typedef CharT char_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_view< char_type > string_view_type;
context< char_type > ctx;
ostream_type strm;
strm << string_view_type(ctx.abcd);
BOOST_CHECK(strm.str() == ctx.abcd);
}
// Test support for padding
BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
{
typedef CharT char_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_view< char_type > string_view_type;
context< char_type > ctx;
// Test for padding
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
// Test for long padding
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::setw(100) << string_view_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
// Test that short width does not truncate the string
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::setw(1) << string_view_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
}
// Test support for padding fill
BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
{
typedef CharT char_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_view< char_type > string_view_type;
context< char_type > ctx;
ostream_type strm_ref;
strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
// Test support for alignment
BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
{
typedef CharT char_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_view< char_type > string_view_type;
context< char_type > ctx;
// Left alignment
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::left << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
// Right alignment
{
ostream_type strm_ref;
strm_ref << ctx.begin << std::right << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
ostream_type strm_correct;
strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
}
}

15
throw_exception.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=refresh content="0; URL=../exception/doc/throw_exception.html">
<title>Automatic redirection</title>
</head>
<body>
Automatic redirection failed, please go to
<a href="../exception/doc/throw_exception.html">throw_exception.html</a>.&nbsp;<hr>
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

138
tie.html
View File

@ -1,138 +0,0 @@
<HTML>
<!--
-- Copyright (c) Jeremy Siek, Lie-Quan Lee, and Andrew Lumsdaine 2000
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. We make no
-- representations about the suitability of this software for any
-- purpose. It is provided "as is" without express or implied warranty.
-->
<Head>
<Title>Boost Tie</Title>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../c++boost.gif"
ALT="C++ Boost">
<BR Clear>
<H1><A NAME="sec:tie"></A>
<TT>tie</TT>
</H1>
<P>
<PRE>
template &lt;class A, class B&gt;
tied&lt;A,B&gt; tie(A&amp; a, B&amp; b);
</PRE>
<P>
This is a utility function that makes it more convenient to work with
a function which returns a pair. The effect of the <TT>tie()</TT>
function is to allow the assignment of the two values of the pair to
two separate variables. The idea for this comes from Jaakko
J&#228;rvi's Binders&nbsp;[<A
HREF="bibliography.html#jaakko_tuple_assign">1</A>].
<P>
<H3>Where Defined</H3>
<P>
<a href="../../boost/utility.hpp"><TT>boost/utility.hpp</TT></a>
<P>
<H3>Example</H3>
<P>
An example of using the <TT>tie()</TT> function with the
<TT>vertices()</TT> function, which returns a pair of
type <TT>std::pair&lt;vertex_iterator,vertex_iterator&gt;</TT>. The
pair of iterators is assigned to the iterator variables <TT>i</TT> and
<TT>end</TT>.
<P>
<PRE>
graph_traits&lt; adjacency_list&lt;&gt; &gt;::vertex_iterator i, end;
for(tie(i,end) = vertices(G); i != end; ++i)
// ...
</PRE>
<P>
Here is another example that uses <TT>tie()</TT> for handling
operaitons with <a
href="http://www.sgi.com/Technology/STL/set.html"><TT>std::set</TT></a>.
<P>
<PRE>
#include &lt;set&gt;
#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;boost/utility.hpp&gt;
int
main(int, char*[])
{
{
typedef std::set&lt;int&gt; SetT;
SetT::iterator i, end;
bool inserted;
int vals[5] = { 5, 2, 4, 9, 1 };
SetT s(vals, vals + 5);
// Using tie() with a return value of pair&lt;iterator,bool&gt;
int new_vals[2] = { 3, 9 };
for (int k = 0; k &lt; 2; ++k) {
boost::tie(i,inserted) = s.insert(new_vals[k]);
if (!inserted)
std::cout &lt;&lt; *i &lt;&lt; " was already in the set." &lt;&lt; std::endl;
else
std::cout &lt;&lt; *i &lt;&lt; " successfully inserted." &lt;&lt; std::endl;
}
}
{
int* i, *end;
int vals[6] = { 5, 2, 4, 4, 9, 1 };
std::sort(vals, vals + 6);
// Using tie() with a return value of pair&lt;iterator,iterator&gt;
boost::tie(i,end) = std::equal_range(vals, vals + 6, 4);
std::cout &lt;&lt; "There were " &lt;&lt; std::distance(i,end)
&lt;&lt; " occurances of " &lt;&lt; *i &lt;&lt; "." &lt;&lt; std::endl;
// Footnote: of course one would normally just use std::count()
// to get this information, but that would spoil the example :)
}
return 0;
}
</PRE>
The output is:
<PRE>
3 successfully inserted.
9 was already in the set.
There were 2 occurances of 4.
</PRE>
<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2000</TD><TD>
<A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>,
Univ.of Notre Dame (<A
HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)<br>
<A HREF=http://www.lsc.nd.edu/~llee1>Lie-Quan Lee</A>, Univ.of Notre Dame (<A HREF="mailto:llee1@lsc.nd.edu">llee1@lsc.nd.edu</A>)<br>
<A HREF=http://www.lsc.nd.edu/~lums>Andrew Lumsdaine</A>,
Univ.of Notre Dame (<A
HREF="mailto:lums@lsc.nd.edu">lums@lsc.nd.edu</A>)
</TD></TR></TABLE>
</BODY>
</HTML>

View File

@ -1,61 +0,0 @@
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
//
// This is an example demonstrating how to use the tie() function.
// The purpose of tie() is to make it easiery to deal with std::pair
// return values.
//
// Contributed by Jeremy Siek
//
// Sample output
//
// 3 successfully inserted.
// 9 was already in the set.
// There were 2 occurances of 4.
#include <set>
#include <algorithm>
#include <iostream>
#include <boost/utility.hpp>
int
main(int, char*[])
{
{
typedef std::set<int> SetT;
SetT::iterator i, end;
bool inserted;
int vals[5] = { 5, 2, 4, 9, 1 };
SetT s(vals, vals + 5);
// Using tie() with a return value of pair<iterator,bool>
int new_vals[2] = { 3, 9 };
for (int k = 0; k < 2; ++k) {
boost::tie(i,inserted) = s.insert(new_vals[k]);
if (!inserted)
std::cout << *i << " was already in the set." << std::endl;
else
std::cout << *i << " successfully inserted." << std::endl;
}
}
{
int* i, *end;
int vals[6] = { 5, 2, 4, 4, 9, 1 };
std::sort(vals, vals + 6);
// Using tie() with a return value of pair<iterator,iterator>
boost::tie(i,end) = std::equal_range(vals, vals + 6, 4);
std::cout << "There were " << std::distance(i,end)
<< " occurances of " << *i << "." << std::endl;
// Footnote: of course one would normally just use std::count()
// to get this information, but that would spoil the example :)
}
return 0;
}

View File

@ -1,626 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<meta name="Template"
content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Type Traits</title>
</head>
<body bgcolor="#FFFFFF" link="#0000FF" vlink="#800080">
<h1><img src="../../c++boost.gif" width="276" height="86">Header
&lt;<a href="../../boost/detail/type_traits.hpp">boost/type_traits.hpp</a>&gt;</h1>
<p>The contents of &lt;boost/type_traits.hpp&gt; are declared in
namespace boost.</p>
<p>The file &lt;<a href="../../boost/detail/type_traits.hpp">boost/type_traits.hpp</a>&gt;
contains various template classes that describe the fundamental
properties of a type; each class represents a single type
property or a single type transformation. This documentation is
divided up into the following sections:</p>
<pre><a href="#fop">Fundamental type operations</a>
<a href="#fp">Fundamental type properties</a>
<a href="#misc">Miscellaneous</a>
<code> </code><a href="#cv">cv-Qualifiers</a>
<code> </code><a href="#ft">Fundamental Types</a>
<code> </code><a href="#ct">Compound Types</a>
<code> </code><a href="#ot">Object/Scalar Types</a>
<a href="#cs">Compiler Support Information</a>
<a href="#ec">Example Code</a></pre>
<h2><a name="fop"></a>Fundamental type operations</h2>
<p>Usage: &quot;class_name&lt;T&gt;::type&quot; performs
indicated transformation on type T.</p>
<table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr>
<td valign="top" width="45%"><p align="center">Expression.</p>
</td>
<td valign="top" width="45%"><p align="center">Description.</p>
</td>
<td valign="top" width="33%"><p align="center">Compiler.</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>remove_volatile&lt;T&gt;::type</code></td>
<td valign="top" width="45%">Creates a type the same as T
but with any top level volatile qualifier removed. For
example &quot;volatile int&quot; would become &quot;int&quot;.</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>remove_const&lt;T&gt;::type</code></td>
<td valign="top" width="45%">Creates a type the same as T
but with any top level const qualifier removed. For
example &quot;const int&quot; would become &quot;int&quot;.</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>remove_cv&lt;T&gt;::type</code></td>
<td valign="top" width="45%">Creates a type the same as T
but with any top level cv-qualifiers removed. For example
&quot;const int&quot; would become &quot;int&quot;, and
&quot;volatile double&quot; would become &quot;double&quot;.</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>remove_reference&lt;T&gt;::type</code></td>
<td valign="top" width="45%">If T is a reference type
then removes the reference, otherwise leaves T unchanged.
For example &quot;int&amp;&quot; becomes &quot;int&quot;
but &quot;int*&quot; remains unchanged.</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>add_reference&lt;T&gt;::type</code></td>
<td valign="top" width="45%">If T is a reference type
then leaves T unchanged, otherwise converts T to a
reference type. For example &quot;int&amp;&quot; remains
unchanged, but &quot;double&quot; becomes &quot;double&amp;&quot;.</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>remove_bounds&lt;T&gt;::type</code></td>
<td valign="top" width="45%">If T is an array type then
removes the top level array qualifier from T, otherwise
leaves T unchanged. For example &quot;int[2][3]&quot;
becomes &quot;int[3]&quot;.</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
</table>
<p>&nbsp;</p>
<h2><a name="fp"></a>Fundamental type properties</h2>
<p>Usage: &quot;class_name&lt;T&gt;::value&quot; is true if
indicated property is true, false otherwise. (Note that class_name&lt;T&gt;::value
is always defined as a compile time constant).</p>
<h3><a name="misc"></a>Miscellaneous</h3>
<table border="1" cellspacing="1" width="100%">
<tr>
<td width="37%"><p align="center">Expression</p>
</td>
<td width="36%"><p align="center">Description</p>
</td>
<td width="27%"><p align="center">Compiler</p>
</td>
</tr>
<tr>
<td width="37%"><div align="center"><center><pre><code>is_same&lt;T,U&gt;::value</code></pre>
</center></div></td>
<td width="36%"><p align="center">True if T and U are the
same type.</p>
</td>
<td width="27%"><p align="center">P</p>
</td>
</tr>
<tr>
<td width="37%"><div align="center"><center><pre>is_convertible&lt;T,U&gt;::value</pre>
</center></div></td>
<td width="36%"><p align="center">True if type T is
convertible to type U.</p>
</td>
<td width="27%">&nbsp;</td>
</tr>
<tr>
<td width="37%"><div align="center"><center><pre>alignment_of&lt;T&gt;::value</pre>
</center></div></td>
<td width="36%"><p align="center">An integral value
representing the minimum alignment requirements of type T
(strictly speaking defines a multiple of the type's
alignment requirement; for all compilers tested so far
however it does return the actual alignment).</p>
</td>
<td width="27%">&nbsp;</td>
</tr>
</table>
<p>&nbsp;</p>
<h3><a name="cv"></a>cv-Qualifiers</h3>
<p>The following classes determine what cv-qualifiers are present
on a type (see 3.93).</p>
<table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr>
<td valign="top" width="37%"><p align="center">Expression.</p>
</td>
<td valign="top" width="37%"><p align="center">Description.</p>
</td>
<td valign="top" width="27%"><p align="center">Compiler.</p>
</td>
</tr>
<tr>
<td valign="top" width="37%"><code>is_const&lt;T&gt;::value</code></td>
<td valign="top" width="37%">True if type T is top-level
const qualified.</td>
<td valign="top" width="27%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="37%"><code>is_volatile&lt;T&gt;::value</code></td>
<td valign="top" width="37%">True if type T is top-level
volatile qualified.</td>
<td valign="top" width="27%"><p align="center">P</p>
</td>
</tr>
</table>
<p>&nbsp;</p>
<h3><a name="ft"></a>Fundamental Types</h3>
<p>The following will only ever be true for cv-unqualified types;
these are closely based on the section 3.9 of the C++ Standard.</p>
<table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr>
<td valign="top" width="45%"><p align="center">Expression.</p>
</td>
<td valign="top" width="45%"><p align="center">Description.</p>
</td>
<td valign="top" width="33%"><p align="center">Compiler.</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_void&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True only if T is void.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_standard_unsigned_integral&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True only if T is one of the
standard unsigned integral types (3.9.1 p3) - unsigned
char, unsigned short, unsigned int, and unsigned long.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_standard_signed_integral&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True only if T is one of the
standard signed integral types (3.9.1 p2) - signed char,
short, int, and long.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_standard_integral&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a standard
integral type(3.9.1 p7) - T is either char, wchar_t, bool
or either is_standard_signed_integral&lt;T&gt;::value or
is_standard_integral&lt;T&gt;::value is true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_standard_float&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is one of the
standard floating point types(3.9.1 p8) - float, double
or long double.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_standard_arithmetic&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a standard
arithmetic type(3.9.1 p8) - implies is_standard_integral
or is_standard_float is true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_standard_fundamental&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a standard
arithmetic type or if T is void.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_extension_unsigned_integral&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True for compiler specific
unsigned integral types.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_extension_signed_integral&lt;T&gt;&gt;:value</code></td>
<td valign="top" width="45%">True for compiler specific
signed integral types.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_extension_integral&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if either is_extension_unsigned_integral&lt;T&gt;::value
or is_extension_signed_integral&lt;T&gt;::value is true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_extension_float&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True for compiler specific
floating point types.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_extension_arithmetic&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if either is_extension_integral&lt;T&gt;::value
or is_extension_float&lt;T&gt;::value are true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>&nbsp;is_extension_fundamental&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if either is_extension_arithmetic&lt;T&gt;::value
or is_void&lt;T&gt;::value are true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>&nbsp;is_unsigned_integral&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if either is_standard_unsigned_integral&lt;T&gt;::value
or is_extention_unsigned_integral&lt;T&gt;::value are
true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_signed_integral&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if either is_standard_signed_integral&lt;T&gt;::value
or is_extention_signed_integral&lt;T&gt;&gt;::value are
true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_integral&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if either is_standard_integral&lt;T&gt;::value
or is_extention_integral&lt;T&gt;::value are true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_float&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if either is_standard_float&lt;T&gt;::value
or is_extention_float&lt;T&gt;::value are true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_arithmetic&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if either is_integral&lt;T&gt;::value
or is_float&lt;T&gt;::value are true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_fundamental&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if either is_arithmetic&lt;T&gt;::value
or is_void&lt;T&gt;::value are true.</td>
<td valign="top" width="33%">&nbsp;</td>
</tr>
</table>
<p>&nbsp;</p>
<h3><a name="ct"></a>Compound Types</h3>
<p>The following will only ever be true for cv-unqualified types,
as defined by the Standard.&nbsp;</p>
<table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr>
<td valign="top" width="45%"><p align="center">Expression</p>
</td>
<td valign="top" width="45%"><p align="center">Description</p>
</td>
<td valign="top" width="33%"><p align="center">Compiler</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_array&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is an array type.</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_pointer&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a regular
pointer type - including function pointers - but
excluding pointers to member functions (3.9.2 p1 and 8.3.1).</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_member_pointer&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a pointer to a
non-static class member (3.9.2 p1 and 8.3.1).</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_reference&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a reference
type (3.9.2 p1 and 8.3.2).</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_class&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a class or
struct type.</td>
<td valign="top" width="33%"><p align="center">PD</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_union&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a union type.</td>
<td valign="top" width="33%"><p align="center">C</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_enum&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is an enumerator
type.</td>
<td valign="top" width="33%"><p align="center">C</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_compound&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is any of the
above compound types.</td>
<td valign="top" width="33%"><p align="center">PD</p>
</td>
</tr>
</table>
<p>&nbsp;</p>
<h3><a name="ot"></a>Object/Scalar Types</h3>
<p>The following ignore any top level cv-qualifiers: if <code>class_name&lt;T&gt;::value</code>
is true then <code>class_name&lt;cv-qualified-T&gt;::value</code>
will also be true.</p>
<table border="1" cellpadding="7" cellspacing="1" width="100%">
<tr>
<td valign="top" width="45%"><p align="center">Expression</p>
</td>
<td valign="top" width="45%"><p align="center">Description</p>
</td>
<td valign="top" width="33%"><p align="center">Compiler</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_object&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is not a reference
type, or a (possibly cv-qualified) void type.</td>
<td valign="top" width="33%"><p align="center">P</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_standard_scalar&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a standard
arithmetic type, an enumerated type, a pointer or a
member pointer.</td>
<td valign="top" width="33%"><p align="center">PD</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_extension_scalar&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is an extentions
arithmetic type, an enumerated type, a pointer or a
member pointer.</td>
<td valign="top" width="33%"><p align="center">PD</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_scalar&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is an arithmetic
type, an enumerated type, a pointer or a member pointer.</td>
<td valign="top" width="33%"><p align="center">PD</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_POD&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is a &quot;Plain
Old Data&quot; type (see 3.9 p2&amp;p3). Note that
although this requires compiler support to be correct in
all cases, if T is a scalar or an array of scalars then
we can correctly define T as a POD.</td>
<td valign="top" width="33%"><p align="center">PC</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>is_empty&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T is an empty struct
or class. If the compiler implements the &quot;zero sized
empty base classes&quot; optimisation, then is_empty will
correctly guess whether T is empty. Relies upon is_class
to determine whether T is a class type. Screens out enum
types by using is_convertible&lt;T,int&gt;, this means
that empty classes that overload operator int(), will not
be classified as empty.</td>
<td valign="top" width="33%"><p align="center">PCD</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>has_trivial_constructor&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T has a trivial
default constructor - that is T() is equivalent to memset.</td>
<td valign="top" width="33%"><p align="center">PC</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>has_trivial_copy&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T has a trivial copy
constructor - that is T(const T&amp;) is equivalent to
memcpy.</td>
<td valign="top" width="33%"><p align="center">PC</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>has_trivial_assign&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T has a trivial
assignment operator - that is if T::operator=(const T&amp;)
is equivalent to memcpy.</td>
<td valign="top" width="33%"><p align="center">PC</p>
</td>
</tr>
<tr>
<td valign="top" width="45%"><code>has_trivial_destructor&lt;T&gt;::value</code></td>
<td valign="top" width="45%">True if T has a trivial
destructor - that is if T::~T() has no effect.</td>
<td valign="top" width="33%"><p align="center">PC</p>
</td>
</tr>
</table>
<p>&nbsp;</p>
<h2><a name="cs"></a>Compiler Support Information</h2>
<p>The legends used in the tables above have the following
meanings:</p>
<table border="0" cellpadding="7" cellspacing="0" width="480">
<tr>
<td valign="top" width="50%"><p align="center">P</p>
</td>
<td valign="top" width="90%">Denotes that the class
requires support for partial specialisation of class
templates to work correctly.</td>
</tr>
<tr>
<td valign="top" width="50%"><p align="center">C</p>
</td>
<td valign="top" width="90%">Denotes that direct compiler
support for that traits class is required.</td>
</tr>
<tr>
<td valign="top" width="50%"><p align="center">D</p>
</td>
<td valign="top" width="90%">Denotes that the traits
class is dependent upon a class that requires direct
compiler support.</td>
</tr>
</table>
<p>&nbsp;</p>
<p>For those classes that are marked with a D or C, if compiler
support is not provided, this type trait may return &quot;false&quot;
when the correct value is actually &quot;true&quot;. The single
exception to this rule is &quot;is_class&quot;, which attempts to
guess whether or not T is really a class, and may return &quot;true&quot;
when the correct value is actually &quot;false&quot;. This can
happen if: T is a union, T is an enum, or T is a compiler-supplied
scalar type that is not specialised for in these type traits.</p>
<p><i>If there is no compiler support</i>, to ensure that these
traits <i>always</i> return the correct values, specialise 'is_enum'
for each user-defined enumeration type, 'is_union' for each user-defined
union type, 'is_empty' for each user-defined empty composite type,
and 'is_POD' for each user-defined POD type. The 'has_*' traits
should also be specialized if the user-defined type has those
traits and is <i>not</i> a POD.</p>
<p>The following rules are automatically enforced:</p>
<p>is_enum implies is_POD</p>
<p>is_POD implies has_*</p>
<p>This means, for example, if you have an empty POD-struct, just
specialize is_empty and is_POD, which will cause all the has_* to
also return true.</p>
<h2><a name="ec"></a>Example code</h2>
<p>Type-traits comes with two sample programs: <a
href="type_traits_test.cpp">type_traits_test.cpp</a> tests the
type traits classes - mostly this is a test of your compiler's
support for the concepts used in the type traits implementation,
while <a href="algo_opt_examples.cpp">algo_opt_examples.cpp</a>
uses the type traits classes to &quot;optimise&quot; some
familiar standard library algorithms.</p>
<p>There are four algorithm examples in algo_opt_examples.cpp:</p>
<table border="0" cellpadding="7" cellspacing="0" width="638">
<tr>
<td valign="top" width="50%"><pre>opt::copy</pre>
</td>
<td valign="top" width="50%">If the copy operation can be
performed using memcpy then does so, otherwise uses a
regular element by element copy (<i>c.f.</i> std::copy).</td>
</tr>
<tr>
<td valign="top" width="50%"><pre>opt::fill</pre>
</td>
<td valign="top" width="50%">If the fill operation can be
performed by memset, then does so, otherwise uses a
regular element by element assign. Also uses call_traits
to optimise how the parameters can be passed (<i>c.f.</i>
std::fill).</td>
</tr>
<tr>
<td valign="top" width="50%"><pre>opt::destroy_array</pre>
</td>
<td valign="top" width="50%">If the type in the array has
a trivial destructor then does nothing, otherwise calls
destructors for all elements in the array - this
algorithm is the reverse of std::uninitialized_copy / std::uninitialized_fill.</td>
</tr>
<tr>
<td valign="top" width="50%"><pre>opt::iter_swap</pre>
</td>
<td valign="top" width="50%">Determines whether the
iterator is a proxy-iterator: if it is then does a &quot;slow
and safe&quot; swap, otherwise calls std::swap on the
assumption that std::swap may be specialised for the
iterated type.</td>
</tr>
</table>
<p>&nbsp;</p>
<hr>
<p>Revised 08<sup>th</sup> March 2000</p>
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this
copyright notice appears in all copies. This document is provided
&quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose.</p>
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
Hinnant and John Maddock.</p>
<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John
Maddock</a>, the latest version of this file can be found at <a
href="http://www.boost.org/">www.boost.org</a>, and the boost
discussion list at <a href="http://www.egroups.com/list/boost">www.egroups.com/list/boost</a>.</p>
</body>
</html>

View File

@ -1,595 +0,0 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// standalone test program for <boost/type_traits.hpp>
/* Release notes:
31st July 2000:
Added extra tests for is_empty, is_convertible, alignment_of.
23rd July 2000:
Removed all call_traits tests to call_traits_test.cpp
Removed all compressed_pair tests to compressed_pair_tests.cpp
Improved tests macros
Tidied up specialistions of type_types classes for test cases.
*/
#include <iostream>
#include <typeinfo>
#include <boost/type_traits.hpp>
#include "type_traits_test.hpp"
using namespace boost;
// Since there is no compiler support, we should specialize:
// is_enum for all enumerations (is_enum implies is_POD)
// is_union for all unions
// is_empty for all empty composites
// is_POD for all PODs (except enums) (is_POD implies has_*)
// has_* for any UDT that has that trait and is not POD
enum enum_UDT{ one, two, three };
struct UDT
{
UDT();
~UDT();
UDT(const UDT&);
UDT& operator=(const UDT&);
int i;
void f1();
int f2();
int f3(int);
int f4(int, float);
};
struct POD_UDT { int x; };
struct empty_UDT{ ~empty_UDT(){}; };
struct empty_POD_UDT{};
union union_UDT
{
int x;
double y;
~union_UDT();
};
union POD_union_UDT
{
int x;
double y;
};
union empty_union_UDT
{
~empty_union_UDT();
};
union empty_POD_union_UDT{};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
namespace boost {
template <> struct is_enum<enum_UDT>
{ static const bool value = true; };
template <> struct is_POD<POD_UDT>
{ static const bool value = true; };
// this type is not POD, so we have to specialize the has_* individually
template <> struct has_trivial_constructor<empty_UDT>
{ static const bool value = true; };
template <> struct has_trivial_copy<empty_UDT>
{ static const bool value = true; };
template <> struct has_trivial_assign<empty_UDT>
{ static const bool value = true; };
template <> struct is_POD<empty_POD_UDT>
{ static const bool value = true; };
template <> struct is_union<union_UDT>
{ static const bool value = true; };
template <> struct is_union<POD_union_UDT>
{ static const bool value = true; };
template <> struct is_POD<POD_union_UDT>
{ static const bool value = true; };
template <> struct is_union<empty_union_UDT>
{ static const bool value = true; };
// this type is not POD, so we have to specialize the has_* individually
template <> struct has_trivial_constructor<empty_union_UDT>
{ static const bool value = true; };
template <> struct has_trivial_copy<empty_union_UDT>
{ static const bool value = true; };
template <> struct has_trivial_assign<empty_union_UDT>
{ static const bool value = true; };
template <> struct is_union<empty_POD_union_UDT>
{ static const bool value = true; };
template <> struct is_POD<empty_POD_union_UDT>
{ static const bool value = true; };
}
#else
namespace boost {
template <> struct is_enum<enum_UDT>
{ enum{ value = true }; };
template <> struct is_POD<POD_UDT>
{ enum{ value = true }; };
// this type is not POD, so we have to specialize the has_* individually
template <> struct has_trivial_constructor<empty_UDT>
{ enum{ value = true }; };
template <> struct has_trivial_copy<empty_UDT>
{ enum{ value = true }; };
template <> struct has_trivial_assign<empty_UDT>
{ enum{ value = true }; };
template <> struct is_POD<empty_POD_UDT>
{ enum{ value = true }; };
template <> struct is_union<union_UDT>
{ enum{ value = true }; };
template <> struct is_union<POD_union_UDT>
{ enum{ value = true }; };
template <> struct is_POD<POD_union_UDT>
{ enum{ value = true }; };
template <> struct is_union<empty_union_UDT>
{ enum{ value = true }; };
// this type is not POD, so we have to specialize the has_* individually
template <> struct has_trivial_constructor<empty_union_UDT>
{ enum{ value = true }; };
template <> struct has_trivial_copy<empty_union_UDT>
{ enum{ value = true }; };
template <> struct has_trivial_assign<empty_union_UDT>
{ enum{ value = true }; };
template <> struct is_union<empty_POD_union_UDT>
{ enum{ value = true }; };
template <> struct is_POD<empty_POD_union_UDT>
{ enum{ value = true }; };
}
#endif
class Base { };
class Deriverd : public Base { };
class NonDerived { };
enum enum1
{
one_,two_
};
enum enum2
{
three_,four_
};
struct VB
{
virtual ~VB(){};
};
struct VD : VB
{
~VD(){};
};
// Steve: All comments that I (Steve Cleary) have added below are prefixed with
// "Steve:" The failures that BCB4 has on the tests are due to Borland's
// not considering cv-qual's as a part of the type -- they are considered
// compiler hints only. These failures should be fixed before long.
int main()
{
std::cout << "Checking type operations..." << std::endl << std::endl;
// cv-qualifiers applied to reference types should have no effect
// declare these here for later use with is_reference and remove_reference:
typedef int& r_type;
typedef const r_type cr_type;
type_test(int, remove_reference<int>::type)
type_test(const int, remove_reference<const int>::type)
type_test(int, remove_reference<int&>::type)
type_test(const int, remove_reference<const int&>::type)
type_test(volatile int, remove_reference<volatile int&>::type)
type_test(int, remove_reference<cr_type>::type)
type_test(int, remove_const<const int>::type)
// Steve: fails on BCB4
type_test(volatile int, remove_const<volatile int>::type)
// Steve: fails on BCB4
type_test(volatile int, remove_const<const volatile int>::type)
type_test(int, remove_const<int>::type)
type_test(int*, remove_const<int* const>::type)
type_test(int, remove_volatile<volatile int>::type)
// Steve: fails on BCB4
type_test(const int, remove_volatile<const int>::type)
// Steve: fails on BCB4
type_test(const int, remove_volatile<const volatile int>::type)
type_test(int, remove_volatile<int>::type)
type_test(int*, remove_volatile<int* volatile>::type)
type_test(int, remove_cv<volatile int>::type)
type_test(int, remove_cv<const int>::type)
type_test(int, remove_cv<const volatile int>::type)
type_test(int, remove_cv<int>::type)
type_test(int*, remove_cv<int* volatile>::type)
type_test(int*, remove_cv<int* const>::type)
type_test(int*, remove_cv<int* const volatile>::type)
type_test(const int *, remove_cv<const int * const>::type)
type_test(int, remove_bounds<int>::type)
type_test(int*, remove_bounds<int*>::type)
type_test(int, remove_bounds<int[3]>::type)
type_test(int[3], remove_bounds<int[2][3]>::type)
std::cout << std::endl << "Checking type properties..." << std::endl << std::endl;
value_test(true, (is_same<int, int>::value))
value_test(false, (is_same<int, const int>::value))
value_test(false, (is_same<int, int&>::value))
value_test(false, (is_same<int*, const int*>::value))
value_test(false, (is_same<int*, int*const>::value))
value_test(false, (is_same<int, int[2]>::value))
value_test(false, is_const<int>::value)
value_test(true, is_const<const int>::value)
value_test(false, is_const<volatile int>::value)
value_test(true, is_const<const volatile int>::value)
value_test(false, is_volatile<int>::value)
value_test(false, is_volatile<const int>::value)
value_test(true, is_volatile<volatile int>::value)
value_test(true, is_volatile<const volatile int>::value)
value_test(true, is_void<void>::value)
// Steve: fails on BCB4
// JM: but looks as though it should according to [3.9.3p1]?
//value_test(false, is_void<const void>::value)
value_test(false, is_void<int>::value)
value_test(false, is_standard_unsigned_integral<UDT>::value)
value_test(false, is_standard_unsigned_integral<void>::value)
value_test(false, is_standard_unsigned_integral<bool>::value)
value_test(false, is_standard_unsigned_integral<char>::value)
value_test(false, is_standard_unsigned_integral<signed char>::value)
value_test(true, is_standard_unsigned_integral<unsigned char>::value)
value_test(false, is_standard_unsigned_integral<wchar_t>::value)
value_test(false, is_standard_unsigned_integral<short>::value)
value_test(true, is_standard_unsigned_integral<unsigned short>::value)
value_test(false, is_standard_unsigned_integral<int>::value)
value_test(true, is_standard_unsigned_integral<unsigned int>::value)
value_test(false, is_standard_unsigned_integral<long>::value)
value_test(true, is_standard_unsigned_integral<unsigned long>::value)
value_test(false, is_standard_unsigned_integral<float>::value)
value_test(false, is_standard_unsigned_integral<double>::value)
value_test(false, is_standard_unsigned_integral<long double>::value)
#ifdef ULLONG_MAX
value_test(false, is_standard_unsigned_integral<long long>::value)
value_test(false, is_standard_unsigned_integral<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(false, is_standard_unsigned_integral<__int64>::value)
value_test(false, is_standard_unsigned_integral<unsigned __int64>::value)
#endif
value_test(false, is_standard_signed_integral<UDT>::value)
value_test(false, is_standard_signed_integral<void>::value)
value_test(false, is_standard_signed_integral<bool>::value)
value_test(false, is_standard_signed_integral<char>::value)
value_test(true, is_standard_signed_integral<signed char>::value)
value_test(false, is_standard_signed_integral<unsigned char>::value)
value_test(false, is_standard_signed_integral<wchar_t>::value)
value_test(true, is_standard_signed_integral<short>::value)
value_test(false, is_standard_signed_integral<unsigned short>::value)
value_test(true, is_standard_signed_integral<int>::value)
value_test(false, is_standard_signed_integral<unsigned int>::value)
value_test(true, is_standard_signed_integral<long>::value)
value_test(false, is_standard_signed_integral<unsigned long>::value)
value_test(false, is_standard_signed_integral<float>::value)
value_test(false, is_standard_signed_integral<double>::value)
value_test(false, is_standard_signed_integral<long double>::value)
#ifdef ULLONG_MAX
value_test(false, is_standard_signed_integral<long long>::value)
value_test(false, is_standard_signed_integral<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(false, is_standard_signed_integral<__int64>::value)
value_test(false, is_standard_signed_integral<unsigned __int64>::value)
#endif
value_test(false, is_standard_arithmetic<UDT>::value)
value_test(false, is_standard_arithmetic<void>::value)
value_test(true, is_standard_arithmetic<bool>::value)
value_test(true, is_standard_arithmetic<char>::value)
value_test(true, is_standard_arithmetic<signed char>::value)
value_test(true, is_standard_arithmetic<unsigned char>::value)
value_test(true, is_standard_arithmetic<wchar_t>::value)
value_test(true, is_standard_arithmetic<short>::value)
value_test(true, is_standard_arithmetic<unsigned short>::value)
value_test(true, is_standard_arithmetic<int>::value)
value_test(true, is_standard_arithmetic<unsigned int>::value)
value_test(true, is_standard_arithmetic<long>::value)
value_test(true, is_standard_arithmetic<unsigned long>::value)
value_test(true, is_standard_arithmetic<float>::value)
value_test(true, is_standard_arithmetic<double>::value)
value_test(true, is_standard_arithmetic<long double>::value)
#ifdef ULLONG_MAX
value_test(false, is_standard_arithmetic<long long>::value)
value_test(false, is_standard_arithmetic<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(false, is_standard_arithmetic<__int64>::value)
value_test(false, is_standard_arithmetic<unsigned __int64>::value)
#endif
value_test(false, is_standard_fundamental<UDT>::value)
value_test(true, is_standard_fundamental<void>::value)
value_test(true, is_standard_fundamental<bool>::value)
value_test(true, is_standard_fundamental<char>::value)
value_test(true, is_standard_fundamental<signed char>::value)
value_test(true, is_standard_fundamental<unsigned char>::value)
value_test(true, is_standard_fundamental<wchar_t>::value)
value_test(true, is_standard_fundamental<short>::value)
value_test(true, is_standard_fundamental<unsigned short>::value)
value_test(true, is_standard_fundamental<int>::value)
value_test(true, is_standard_fundamental<unsigned int>::value)
value_test(true, is_standard_fundamental<long>::value)
value_test(true, is_standard_fundamental<unsigned long>::value)
value_test(true, is_standard_fundamental<float>::value)
value_test(true, is_standard_fundamental<double>::value)
value_test(true, is_standard_fundamental<long double>::value)
#ifdef ULLONG_MAX
value_test(false, is_standard_fundamental<long long>::value)
value_test(false, is_standard_fundamental<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(false, is_standard_fundamental<__int64>::value)
value_test(false, is_standard_fundamental<unsigned __int64>::value)
#endif
value_test(false, is_arithmetic<UDT>::value)
value_test(true, is_arithmetic<char>::value)
value_test(true, is_arithmetic<signed char>::value)
value_test(true, is_arithmetic<unsigned char>::value)
value_test(true, is_arithmetic<wchar_t>::value)
value_test(true, is_arithmetic<short>::value)
value_test(true, is_arithmetic<unsigned short>::value)
value_test(true, is_arithmetic<int>::value)
value_test(true, is_arithmetic<unsigned int>::value)
value_test(true, is_arithmetic<long>::value)
value_test(true, is_arithmetic<unsigned long>::value)
value_test(true, is_arithmetic<float>::value)
value_test(true, is_arithmetic<double>::value)
value_test(true, is_arithmetic<long double>::value)
value_test(true, is_arithmetic<bool>::value)
#ifdef ULLONG_MAX
value_test(true, is_arithmetic<long long>::value)
value_test(true, is_arithmetic<unsigned long long>::value)
#endif
#if defined(__BORLANDC__) || defined(_MSC_VER)
value_test(true, is_arithmetic<__int64>::value)
value_test(true, is_arithmetic<unsigned __int64>::value)
#endif
value_test(false, is_array<int>::value)
value_test(false, is_array<int*>::value)
value_test(true, is_array<int[2]>::value)
value_test(true, is_array<int[2][3]>::value)
value_test(true, is_array<UDT[2]>::value)
typedef void(*f1)();
typedef int(*f2)(int);
typedef int(*f3)(int, bool);
typedef void (UDT::*mf1)();
typedef int (UDT::*mf2)();
typedef int (UDT::*mf3)(int);
typedef int (UDT::*mf4)(int, float);
value_test(false, is_pointer<int>::value)
value_test(false, is_pointer<int&>::value)
value_test(true, is_pointer<int*>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
value_test(false, is_pointer<int*const>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
value_test(false, is_pointer<int*volatile>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
value_test(false, is_pointer<int*const volatile>::value)
value_test(true, is_pointer<f1>::value)
value_test(true, is_pointer<f2>::value)
value_test(true, is_pointer<f3>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3
value_test(false, is_pointer<mf1>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3
value_test(false, is_pointer<mf2>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3
value_test(false, is_pointer<mf3>::value)
// Steve: was 'true', should be 'false', via 3.9.2p3
value_test(false, is_pointer<mf4>::value)
value_test(false, is_reference<bool>::value)
value_test(true, is_reference<int&>::value)
value_test(true, is_reference<const int&>::value)
value_test(true, is_reference<volatile int &>::value)
value_test(true, is_reference<r_type>::value)
value_test(true, is_reference<cr_type>::value)
value_test(false, is_class<int>::value)
value_test(false, is_class<const int>::value)
value_test(false, is_class<volatile int>::value)
value_test(false, is_class<int*>::value)
value_test(false, is_class<int* const>::value)
value_test(false, is_class<int[2]>::value)
value_test(false, is_class<int&>::value)
value_test(false, is_class<mf4>::value)
value_test(false, is_class<f1>::value)
value_test(false, is_class<enum_UDT>::value)
value_test(true, is_class<UDT>::value)
value_test(true, is_class<UDT const>::value)
value_test(true, is_class<UDT volatile>::value)
value_test(true, is_class<empty_UDT>::value)
value_test(true, is_class<std::iostream>::value)
value_test(false, is_class<UDT*>::value)
value_test(false, is_class<UDT[2]>::value)
value_test(false, is_class<UDT&>::value)
value_test(true, is_object<int>::value)
value_test(true, is_object<UDT>::value)
value_test(false, is_object<int&>::value)
value_test(false, is_object<void>::value)
value_test(true, is_standard_scalar<int>::value)
value_test(true, is_extension_scalar<void*>::value)
value_test(false, is_enum<int>::value)
value_test(true, is_enum<enum_UDT>::value)
value_test(false, is_member_pointer<f1>::value)
value_test(false, is_member_pointer<f2>::value)
value_test(false, is_member_pointer<f3>::value)
value_test(true, is_member_pointer<mf1>::value)
value_test(true, is_member_pointer<mf2>::value)
value_test(true, is_member_pointer<mf3>::value)
value_test(true, is_member_pointer<mf4>::value)
value_test(false, is_empty<int>::value)
value_test(false, is_empty<int*>::value)
value_test(false, is_empty<int&>::value)
#ifdef __MWERKS__
// apparent compiler bug causes this to fail to compile:
value_fail(false, is_empty<int[2]>::value)
#else
value_test(false, is_empty<int[2]>::value)
#endif
value_test(false, is_empty<f1>::value)
value_test(false, is_empty<mf1>::value)
value_test(false, is_empty<UDT>::value)
value_test(true, is_empty<empty_UDT>::value)
value_test(true, is_empty<empty_POD_UDT>::value)
value_test(true, is_empty<empty_union_UDT>::value)
value_test(false, is_empty<enum_UDT>::value)
value_test(true, has_trivial_constructor<int>::value)
value_test(true, has_trivial_constructor<int*>::value)
value_test(true, has_trivial_constructor<int*const>::value)
value_test(true, has_trivial_constructor<const int>::value)
value_test(true, has_trivial_constructor<volatile int>::value)
value_test(true, has_trivial_constructor<int[2]>::value)
value_test(true, has_trivial_constructor<int[3][2]>::value)
value_test(true, has_trivial_constructor<int[2][4][5][6][3]>::value)
value_test(true, has_trivial_constructor<f1>::value)
value_test(true, has_trivial_constructor<mf2>::value)
value_test(false, has_trivial_constructor<UDT>::value)
value_test(true, has_trivial_constructor<empty_UDT>::value)
value_test(true, has_trivial_constructor<enum_UDT>::value)
value_test(true, has_trivial_copy<int>::value)
value_test(true, has_trivial_copy<int*>::value)
value_test(true, has_trivial_copy<int*const>::value)
value_test(true, has_trivial_copy<const int>::value)
// Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
value_test(true, has_trivial_copy<volatile int>::value)
value_test(true, has_trivial_copy<int[2]>::value)
value_test(true, has_trivial_copy<int[3][2]>::value)
value_test(true, has_trivial_copy<int[2][4][5][6][3]>::value)
value_test(true, has_trivial_copy<f1>::value)
value_test(true, has_trivial_copy<mf2>::value)
value_test(false, has_trivial_copy<UDT>::value)
value_test(true, has_trivial_copy<empty_UDT>::value)
value_test(true, has_trivial_copy<enum_UDT>::value)
value_test(true, has_trivial_assign<int>::value)
value_test(true, has_trivial_assign<int*>::value)
value_test(true, has_trivial_assign<int*const>::value)
value_test(true, has_trivial_assign<const int>::value)
// Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
value_test(true, has_trivial_assign<volatile int>::value)
value_test(true, has_trivial_assign<int[2]>::value)
value_test(true, has_trivial_assign<int[3][2]>::value)
value_test(true, has_trivial_assign<int[2][4][5][6][3]>::value)
value_test(true, has_trivial_assign<f1>::value)
value_test(true, has_trivial_assign<mf2>::value)
value_test(false, has_trivial_assign<UDT>::value)
value_test(true, has_trivial_assign<empty_UDT>::value)
value_test(true, has_trivial_assign<enum_UDT>::value)
value_test(true, has_trivial_destructor<int>::value)
value_test(true, has_trivial_destructor<int*>::value)
value_test(true, has_trivial_destructor<int*const>::value)
value_test(true, has_trivial_destructor<const int>::value)
value_test(true, has_trivial_destructor<volatile int>::value)
value_test(true, has_trivial_destructor<int[2]>::value)
value_test(true, has_trivial_destructor<int[3][2]>::value)
value_test(true, has_trivial_destructor<int[2][4][5][6][3]>::value)
value_test(true, has_trivial_destructor<f1>::value)
value_test(true, has_trivial_destructor<mf2>::value)
value_test(false, has_trivial_destructor<UDT>::value)
value_test(false, has_trivial_destructor<empty_UDT>::value)
value_test(true, has_trivial_destructor<enum_UDT>::value)
value_test(true, is_POD<int>::value)
value_test(true, is_POD<int*>::value)
// Steve: was 'true', should be 'false', via 3.9p10
value_test(false, is_POD<int&>::value)
value_test(true, is_POD<int*const>::value)
value_test(true, is_POD<const int>::value)
// Steve: was 'false', should be 'true', via 3.9p10
value_test(true, is_POD<volatile int>::value)
// Steve: was 'true', should be 'false', via 3.9p10
value_test(false, is_POD<const int&>::value)
value_test(true, is_POD<int[2]>::value)
value_test(true, is_POD<int[3][2]>::value)
value_test(true, is_POD<int[2][4][5][6][3]>::value)
value_test(true, is_POD<f1>::value)
value_test(true, is_POD<mf2>::value)
value_test(false, is_POD<UDT>::value)
value_test(false, is_POD<empty_UDT>::value)
value_test(true, is_POD<enum_UDT>::value)
value_test(true, (boost::is_convertible<Deriverd,Base>::value));
value_test(true, (boost::is_convertible<Deriverd,Deriverd>::value));
value_test(true, (boost::is_convertible<Base,Base>::value));
value_test(false, (boost::is_convertible<Base,Deriverd>::value));
value_test(true, (boost::is_convertible<Deriverd,Deriverd>::value));
value_test(false, (boost::is_convertible<NonDerived,Base>::value));
//value_test(false, (boost::is_convertible<boost::noncopyable, boost::noncopyable>::value));
value_test(true, (boost::is_convertible<float,int>::value));
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
value_test(false, (boost::is_convertible<float,void>::value));
value_test(false, (boost::is_convertible<void,float>::value));
value_test(true, (boost::is_convertible<void,void>::value));
#endif
value_test(true, (boost::is_convertible<enum1, int>::value));
value_test(true, (boost::is_convertible<Deriverd*, Base*>::value));
value_test(false, (boost::is_convertible<Base*, Deriverd*>::value));
value_test(true, (boost::is_convertible<Deriverd&, Base&>::value));
value_test(false, (boost::is_convertible<Base&, Deriverd&>::value));
value_test(true, (boost::is_convertible<const Deriverd*, const Base*>::value));
value_test(false, (boost::is_convertible<const Base*, const Deriverd*>::value));
value_test(true, (boost::is_convertible<const Deriverd&, const Base&>::value));
value_test(false, (boost::is_convertible<const Base&, const Deriverd&>::value));
value_test(false, (boost::is_convertible<const int *, int*>::value));
value_test(false, (boost::is_convertible<const int&, int&>::value));
value_test(false, (boost::is_convertible<int*, int[2]>::value));
value_test(false, (boost::is_convertible<const int*, int[3]>::value));
value_test(true, (boost::is_convertible<const int&, int>::value));
value_test(true, (boost::is_convertible<int(&)[4], const int*>::value));
value_test(true, (boost::is_convertible<int(&)(int), int(*)(int)>::value));
value_test(true, (boost::is_convertible<int *, const int*>::value));
value_test(true, (boost::is_convertible<int&, const int&>::value));
value_test(true, (boost::is_convertible<int[2], int*>::value));
value_test(true, (boost::is_convertible<int[2], const int*>::value));
value_test(false, (boost::is_convertible<const int[2], int*>::value));
align_test(int);
align_test(char);
align_test(double);
align_test(int[4]);
align_test(int(*)(int));
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
align_test(char&);
align_test(char (&)(int));
align_test(char(&)[4]);
#endif
align_test(int*);
//align_test(const int);
align_test(VB);
align_test(VD);
std::cout << std::endl << test_count << " tests completed (" << failures << " failures)... press any key to exit";
std::cin.get();
return failures;
}

View File

@ -1,106 +0,0 @@
// boost::compressed_pair test program
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// common test code for type_traits_test.cpp/call_traits_test.cpp/compressed_pair_test.cpp
#ifndef BOOST_TYPE_TRAITS_TEST_HPP
#define BOOST_TYPE_TRAITS_TEST_HPP
//
// this one is here just to suppress warnings:
//
template <class T>
bool do_compare(T i, T j)
{
return i == j;
}
//
// this one is to verify that a constant is indeed a
// constant-integral-expression:
//
template <int>
struct ct_checker
{
};
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
#define BOOST_DO_JOIN2(X, Y) X ## Y
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
#define value_test(v, x) ++test_count;\
typedef ct_checker<(x)> BOOST_JOIN(this_is_a_compile_time_check_, __LINE__);\
if(!do_compare((int)v,(int)x)){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;}
#define value_fail(v, x) ++test_count; ++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#define type_test(v, x) ++test_count;\
if(do_compare(boost::is_same<v, x>::value, false)){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << typeid(boost::is_same<v, x>).name() << "::value is false" << std::endl; }
#else
#define type_test(v, x) ++test_count;\
if(typeid(v) != typeid(x)){\
++failures; \
std::cout << "checking type of " << #x << "...failed" << std::endl; \
std::cout << " expected type was " << #v << std::endl; \
std::cout << " " << "typeid(" #v ") != typeid(" #x ")" << std::endl; }
#endif
template <class T>
struct test_align
{
struct padded
{
char c;
T t;
};
static void do_it()
{
padded p;
unsigned a = reinterpret_cast<char*>(&(p.t)) - reinterpret_cast<char*>(&p);
value_test(a, boost::alignment_of<T>::value);
}
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T>
struct test_align<T&>
{
static void do_it()
{
//
// we can't do the usual test because we can't take the address
// of a reference, so check that the result is the same as for a
// pointer type instead:
value_test(boost::alignment_of<T*>::value, boost::alignment_of<T&>::value);
}
};
#endif
#define align_test(T) test_align<T>::do_it()
//
// define tests here
unsigned failures = 0;
unsigned test_count = 0;
//
// turn off some warnings:
#ifdef __BORLANDC__
#pragma option -w-8004
#endif
#ifdef BOOST_MSVC
#pragma warning (disable: 4018)
#endif
#endif // BOOST_TYPE_TRAITS_TEST_HPP

View File

@ -1,103 +1,622 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Header boost/utility.hpp Documentation</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" WIDTH="277" HEIGHT="86">Header
<a href="../../boost/utility.hpp">boost/utility.hpp</a></h1>
<p>The entire contents of the header <code><a href="../../boost/utility.hpp">&lt;boost/utility.hpp&gt;</a></code>
are in <code>namespace boost</code>.</p>
<h2>Contents</h2>
<ul>
<li>Template functions <a href="#functions next">next() and prior()</a></li>
<li>Class <a href="#Class noncopyable">noncopyable</a></li>
</ul>
<h2>Template <a name="functions next">functions next</a>() and prior()</h2>
<p>Certain data types, such as the C++ Standard Library's forward and
bidirectional iterators, do not provide addition and subtraction via operator+()
or operator-().&nbsp; This means that non-modifying computation of the next or
prior value requires a temporary, even though operator++() or operator--() is
provided.&nbsp; It also means that writing code like <code>itr+1</code> inside a
template restricts the iterator category to random access iterators.</p>
<p>The next() and prior() functions provide a simple way around these problems:</p>
<blockquote>
<pre>template &lt;class T&gt;
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Header boost/utility.hpp Documentation</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" WIDTH="277" HEIGHT="86">Header
<a href="../../boost/utility.hpp">boost/utility.hpp</a></h1>
<p>The entire contents of the header <code><a href="../../boost/utility.hpp">&lt;boost/utility.hpp&gt;</a></code>
are in <code>namespace boost</code>.</p>
<h2>Contents</h2>
<ul>
<li>
Class templates supporting the <a href="doc/html/base_from_member.html">
base-from-member idiom</a></li>
<li>
Function templates <a href="../core/doc/html/core/checked_delete.html">checked_delete() and
checked_array_delete()</a> (moved to the Boost.Core library)</li>
<li>
Function templates <a href="#functions_next_prior">next() and prior()</a></li>
<li>
Class <a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)</li>
<li>
Function template <a href="../core/doc/html/core/addressof.html">addressof()</a> (moved to the Boost.Core library)</li>
<li>Class template <a href="#result_of">result_of</a></li>
<li>
Macro <a href="#BOOST_BINARY">BOOST_BINARY</a></li>
<li><a href="index.html">Other utilities not part of <code>utility.hpp</code></a></li>
</ul>
<h2>
<a name="functions_next_prior">Function</a> templates next() and prior()</h2>
<p>Certain data types, such as the C++ Standard Library's forward and bidirectional
iterators, do not provide addition and subtraction via operator+() or
operator-().&nbsp; This means that non-modifying computation of the next or
prior value requires a temporary, even though operator++() or operator--() is
provided.&nbsp; It also means that writing code like <code>itr+1</code> inside
a template restricts the iterator category to random access iterators.</p>
<p>The next() and prior() functions provide a simple way around these problems:</p>
<blockquote>
<pre>template &lt;class T&gt;
T next(T x) { return ++x; }
template &lt;class X&gt;
T prior(T x) { return --x; }</pre>
template &lt;class T, class Distance&gt;
T next(T x, Distance n)
{
std::advance(x, n);
return x;
}
</blockquote>
template &lt;class T&gt;
T prior(T x) { return --x; }
<p>Usage is simple:</p>
template &lt;class T, class Distance&gt;
T prior(T x, Distance n)
{
std::advance(x, -n);
return x;
}</pre>
</blockquote>
<p>Usage is simple:</p>
<blockquote>
<pre>const std::list&lt;T&gt;::iterator p = get_some_iterator();
const std::list&lt;T&gt;::iterator prev = boost::prior(p);
const std::list&lt;T&gt;::iterator next = boost::next(prev, 2);</pre>
</blockquote>
<p>The distance from the given iterator should be supplied as an absolute value. For
example, the iterator four iterators prior to the given iterator <code>p</code>
may be obtained by <code>prior(p, 4)</code>.</p>
<p>Contributed by <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>. Two-argument versions by Daniel Walker.</p>
<blockquote>
<h2><a name="result_of">Class template
result_of</a></h2> <p>The class template
<code>result_of</code> helps determine the type of a
call expression. For example, given an lvalue <code>f</code> of
type <code>F</code> and lvalues <code>t1</code>,
<code>t2</code>, ..., <code>t<em>N</em></code> of
types <code>T1</code>, <code>T2</code>, ...,
<code>T<em>N</em></code>, respectively, the type
<code>result_of&lt;F(T1, T2, ...,
T<em>N</em>)&gt;::type</code> defines the result type
of the expression <code>f(t1, t2,
...,t<em>N</em>)</code>. This implementation permits
the type <code>F</code> to be a function pointer,
function reference, member function pointer, or class
type. By default, <em>N</em> may be any value between 0 and
16. To change the upper limit, define the macro
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
value for <em>N</em>. Class template <code>result_of</code>
resides in the header <code>&lt;<a
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>&gt;</code>.</p>
<pre>const std::list&lt;T&gt;::iterator p = get_some_iterator();
const std::list&lt;T&gt;::iterator prev = boost::prior(p);</pre>
<p>If your compiler's support for <code>decltype</code> is
adequate, <code>result_of</code> automatically uses it to
deduce the type of the call expression, in which case
<code>result_of&lt;F(T1, T2, ...,
T<em>N</em>)&gt;::type</code> names the type
<code>decltype(boost::declval&lt;F&gt;()(boost::declval&lt;T1&gt;(),
boost::declval&lt;T2&gt;(), ...,
boost::declval&lt;T<em>N</em>&gt;()))</code>, as in the
following example.</p>
</blockquote>
<blockquote>
<pre>struct functor {
template&lt;class T&gt;
T operator()(T x)
{
return x;
}
};
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>.</p>
typedef boost::result_of&lt;
functor(int)
&gt;::type type; // type is int</pre>
</blockquote>
<h2><a name="Class noncopyable">Class noncopyable</a></h2>
<p>You can test whether <code>result_of</code> is using
<code>decltype</code> by checking if the macro
<code>BOOST_RESULT_OF_USE_DECLTYPE</code> is defined after
including <code>result_of.hpp</code>. You can also force
<code>result_of</code> to use <code>decltype</code> by
defining <code>BOOST_RESULT_OF_USE_DECLTYPE</code> prior
to including <code>result_of.hpp</code>.</p>
<p>Class <strong>noncopyable</strong> is a base class.&nbsp; Derive your own class from <strong>noncopyable</strong>
when you want to prohibit copy construction and copy assignment.</p>
<p>If <code>decltype</code> is not used,
then automatic result type deduction of function
objects is not possible. Instead, <code>result_of</code>
uses the following protocol to allow the programmer to
specify a type. When <code>F</code> is a class type with a
member type <code>result_type</code>,
<code>result_of&lt;F(T1, T2, ...,
T<em>N</em>)&gt;::type</code> is
<code>F::result_type</code>. When <code>F</code> does
not contain <code>result_type</code>,
<code>result_of&lt;F(T1, T2, ...,
T<em>N</em>)&gt;::type</code> is <code>F::result&lt;F(T1,
T2, ..., T<em>N</em>)&gt;::type</code> when
<code><em>N</em> &gt; 0</code> or <code>void</code>
when <code><em>N</em> = 0</code>. Note that it is the
responsibility of the programmer to ensure that
function objects accurately advertise their result
type via this protocol, as in the following
example.</p>
<p>Some objects, particularly those which hold complex resources like files or
network connections, have no sensible copy semantics.&nbsp; Sometimes there are
possible copy semantics, but these would be of very limited usefulness and be
very difficult to implement correctly.&nbsp; Sometimes you're implementing a class that doesn't need to be copied
just yet and you don't want to take the time to write the appropriate functions.&nbsp;
Deriving from <b> noncopyable</b> will prevent the otherwise implicitly-generated
functions (which don't have the proper semantics) from becoming a trap for other programmers.</p>
<blockquote>
<pre>struct functor {
template&lt;class&gt; struct result;
<p>The traditional way to deal with these is to declare a private copy constructor and copy assignment, and then
document why this is done.&nbsp; But deriving from <b>noncopyable</b> is simpler
and clearer, and doesn't require additional documentation.</p>
template&lt;class F, class T&gt;
struct result&lt;F(T)&gt; {
typedef T type;
};
<p>The program <a href="noncopyable_test.cpp">noncopyable_test.cpp</a> can be
used to verify class <b>noncopyable</b> works as expected. It has have been run successfully under
GCC 2.95, Metrowerks
CodeWarrior 5.0, and Microsoft Visual C++ 6.0 sp 3.</p>
template&lt;class T&gt;
T operator()(T x)
{
return x;
}
};
<p>Contributed by <a href="../../people/dave_abrahams.htm">Dave Abrahams</a>.</p>
typedef boost::result_of&lt;
functor(int)
&gt;::type type; // type is int</pre>
</blockquote>
<h3>Example</h3>
<blockquote>
<pre>// inside one of your own headers ...
#include &lt;boost/utility.hpp&gt;
<p>Since <code>decltype</code> is a new language
feature recently standardized in C++11,
if you are writing a function object
to be used with <code>result_of</code>, for
maximum portability, you might consider following
the above protocol even if your compiler has
proper <code>decltype</code> support. If you wish to continue to
use the protocol on compilers that
support <code>decltype</code>, there are two options:
You can use <code>boost::tr1_result_of</code>, which is also
defined in <code>&lt;<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>&gt;</code>.
Alternatively, you can define the macro
<code>BOOST_RESULT_OF_USE_TR1</code>, which causes
<code>result_of</code> to use the protocol described
above instead of <code>decltype</code>. If you choose to
follow the protocol, take care to ensure that the
<code>result_type</code> and
<code>result&lt;&gt;</code> members accurately
represent the return type of
<code>operator()</code> given a call expression.</p>
class ResourceLadenFileSystem : noncopyable {
...</pre>
</blockquote>
<p>Additionally, <code>boost::result_of</code>
provides a third mode of operation, which some users
may find convenient. When
<code>BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK</code>
is defined, <code>boost::result_of</code> behaves as
follows. If the function object has a member
type <code>result_type</code> or member
template <code>result&lt;&gt;</code>, then
<code>boost::result_of</code> will use the TR1
protocol. Otherwise,
<code>boost::result_of</code> will
use <code>decltype</code>. Using TR1 with
a <code>declytpe</code> fallback may workaround
certain problems at the cost of portability. For
example:
<ul>
<li>Deficient compiler: If your code
requires <code>boost::result_of</code> to work
with incomplete return types but your
compiler's <code>decltype</code> implementation
does not support incomplete return types, then you
can use the TR1 protocol as a workaround. Support
for incomplete return types was added late in the
C++11 standardization process
(see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf">N3276</a>)
and is not implemented by some compilers.</li>
<h3>Rationale</h3>
<p>Class noncopyable has protected constructor and destructor members to
emphasize that it is to be used only as a base class.&nbsp; Dave Abrahams notes
concern about the effect on compiler optimization of adding (even trivial inline)
destructor declarations. He says &quot;Probably this concern is misplaced, because
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics.&quot;</p>
<hr>
<p>Revised&nbsp; <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
-->26 January, 2000<!--webbot bot="Timestamp" endspan i-checksum="38194"
<li>Deficient legacy code: If your existing TR1
function object advertises a different type than
the actual result type deduced
by <code>decltype</code>, then using TR1 with a
<code>decltype</code> fallback will allow you to
work with both your existing TR1 function objects
and new C++11 function object. This situation
could occur if your legacy function objects
misused the TR1 protocol. See the documentation on
known <a href="#result_of_tr1_diff">differences</a>
between <code>boost::result_of</code> and TR1.</li>
</ul>
<a name="BOOST_NO_RESULT_OF"></a>
<p>This implementation of <code>result_of</code>
requires class template partial specialization, the
ability to parse function types properly, and support
for SFINAE. If <code>result_of</code> is not supported
by your compiler, including the header
<code>boost/utility/result_of.hpp</code> will
define the macro <code>BOOST_NO_RESULT_OF</code>.</p>
<p>For additional information
about <code>result_of</code>, see the C++ Library
Technical Report,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
or, for motivation and design rationale,
the <code>result_of</code> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
<a name="result_of_guidelines">
<h3>Usage guidelines for boost::result_of</h3>
</a>
<p>The following are general suggestions about when
and how to use <code>boost::result_of</code>.</p>
<ol>
<li> If you are targeting C++11 and are not concerned
about portability to non-compliant compilers or
previous versions of the standard, then use
<code>std::result_of</code>. If <code>std::result_of</code>
meets your needs, then there's no reason to stop using
it.</li>
<li> If you are targeting C++11 but may port your code
to legacy compilers at some time in the future, then
use <code>boost::result_of</code> with
<code>decltype</code>. When <code>decltype</code> is
used <code>boost::result_of</code>
and <code>std::result_of</code> are usually
interchangeable. See the documentation on
known <a href="#result_of_cxx11_diff">differences</a>
between boost::result_of and C++11 result_of.</li>
<li> If compiler portability is required,
use <code>boost::result_of</code> with the TR1 protocol.</li>
</ol>
<p>Regardless of how you
configure <code>boost::result_of</code>, it is
important to bear in mind that the return type of a
function may change depending on its arguments, and
additionally, the return type of a member function may
change depending on the cv-qualification of the
object. <code>boost::result_of</code> must be passed
the appropriately cv-qualified types in order to
deduce the corresponding return type. For example:
<blockquote>
<pre>struct functor {
int& operator()(int);
int const& operator()(int) const;
float& operator()(float&);
float const& operator()(float const&);
};
typedef boost::result_of&lt;
functor(int)
&gt;::type type1; // type1 is int &
typedef boost::result_of&lt;
const functor(int)
&gt;::type type2; // type2 is int const &
typedef boost::result_of&lt;
functor(float&)
&gt;::type type3; // type3 is float &
typedef boost::result_of&lt;
functor(float const&)
&gt;::type type4; // type4 is float const &</pre>
</blockquote>
<a name="result_of_tr1_protocol_guidelines">
<h3>Usage guidelines for the TR1 result_of protocol</h3>
</a>
<p>On compliant C++11
compilers, <code>boost::result_of</code> can
use <code>decltype</code> to deduce the type of any
call expression, including calls to function
objects. However, on pre-C++11 compilers or on
compilers without adequate decltype support,
additional scaffolding is needed from function
objects as described above. The following are
suggestions about how to use the TR1 protocol.</p>
<ul>
<li>When the return type does not depend on the
argument types or the cv-qualification of the
function object, simply
define <code>result_type</code>. There is no need
to use the <code>result</code> template unless the
return type varies.</li>
<li>Use the protocol specified type when defining
function prototypes. This can help ensure the
actual return type does not get out of sync with
the protocol specification. For example:
<blockquote>
<pre>struct functor {
typedef int result_type;
result_type operator()(int);
};</pre>
</blockquote> </li>
<li>Always specify the <code>result</code>
specialization near the corresponding
<code>operator()</code> overload. This can make it
easier to keep the specializations in sync with the
overloads. For example:
<blockquote>
<pre>struct functor {
template&lt;class&gt; struct result;
template&lt;class F&gt;
struct result&lt;F(int)&gt; {
typedef int& type;
};
result&lt;functor(int)&gt;::type operator()(int);
template&lt;class F&gt;
struct result&lt;const F(int)&gt; {
typedef int const& type;
};
result&lt;const functor(int)&gt;::type operator()(int) const;
};</pre>
</blockquote> </li>
<li>Use type transformations to simplify
the <code>result</code> template specialization. For
example, the following uses
<a href="../type_traits/doc/html/index.html">Boost.TypeTraits</a>
to specialize the <code>result</code> template for
a single <code>operator()</code> that can be called on
both a const and non-const function object with
either an lvalue or rvalue argument.
<blockquote>
<pre>struct functor {
template&lt;class&gt; struct result;
template&lt;class F, class T&gt;
struct result&lt;F(T)&gt;
: boost::remove_cv&lt;
typename boost::remove_reference&lt;T&gt;::type
&gt;
{};
template&lt;class T&gt;
T operator()(T const&amp; x) const;
};</pre>
</blockquote></li>
</ul>
<a name="result_of_tr1_diff">
<h3>Known differences between boost::result_of and TR1 result_of</h3>
</a>
When using <code>decltype</code>, <code>boost::result_of</code>
ignores the TR1 protocol and instead deduces the
return type of function objects directly
via <code>decltype</code>. In most situations, users
will not notice a difference, so long as they use the
protocol correctly. The following are situations in
which the type deduced
by <code>boost::result_of</code> is known to differ depending on
whether <code>decltype</code> or the TR1 protocol is
used.
<ul>
<li> TR1 protocol misusage
<p>When using the TR1
protocol, <code>boost::result_of</code> cannot
detect whether the actual type of a call to a
function object is the same as the type specified
by the protocol, which allows for the possibility
of inadvertent mismatches between the specified
type and the actual type. When
using <code>decltype</code>, these subtle bugs
may result in compilation errors. For example:</p>
<blockquote>
<pre>struct functor {
typedef short result_type;
int operator()(short);
};
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
BOOST_STATIC_ASSERT((
boost::is_same&lt;boost::result_of&lt;functor(short)&gt;::type, int&gt;::value
));
#else
BOOST_STATIC_ASSERT((
boost::is_same&lt;boost::result_of&lt;functor(short)&gt;::type, short&gt;::value
));
#endif</pre>
</blockquote>
<p>Note that the user can
force <code>boost::result_of</code> to use the TR1
protocol even on platforms that
support <code>decltype</code> by
defining <code>BOOST_RESULT_OF_USE_TR1</code>.</p></li>
<li> Nullary function objects
<p>When using the TR1 protocol, <code>boost::result_of</code>
cannot always deduce the type of calls to
nullary function objects, in which case the
type defaults to void. When using <code>decltype</code>,
<code>boost::result_of</code> always gives the actual type of the
call expression. For example:</p>
<blockquote>
<pre>struct functor {
template&lt;class&gt; struct result {
typedef int type;
};
int operator()();
};
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
BOOST_STATIC_ASSERT((
boost::is_same&lt;boost::result_of&lt;functor()&gt;::type, int&gt;::value
));
#else
BOOST_STATIC_ASSERT((
boost::is_same&lt;boost::result_of&lt;functor()&gt;::type, void&gt;::value
));
#endif</pre>
</blockquote>
<p>Note that there are some workarounds for the
nullary function problem. So long as the return
type does not vary,
<code>result_type</code> can always be used to
specify the return type regardless of arity. If the
return type does vary, then the user can
specialize <code>boost::result_of</code> itself for
nullary calls.</p></li>
<li> Non-class prvalues and cv-qualification
<p>When using the TR1
protocol, <code>boost::result_of</code> will
report the cv-qualified type specified
by <code>result_type</code> or
the <code>result</code> template regardless of
the actual cv-qualification of the call
expression. When using
<code>decltype</code>, <code>boost::result_of</code>
will report the actual type of the call expression,
which is not cv-qualified when the expression is a
non-class prvalue. For example:</p>
<blockquote>
<pre>struct functor {
template&lt;class&gt; struct result;
template&lt;class F, class T&gt; struct result&lt;F(const T)&gt; {
typedef const T type;
};
const short operator()(const short);
int const & operator()(int const &);
};
// Non-prvalue call expressions work the same with or without decltype.
BOOST_STATIC_ASSERT((
boost::is_same&lt;
boost::result_of&lt;functor(int const &)&gt;::type,
int const &
::value
));
// Non-class prvalue call expressions are not actually cv-qualified,
// but only the decltype-based result_of reports this accurately.
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
BOOST_STATIC_ASSERT((
boost::is_same&lt;
boost::result_of&lt;functor(const short)&gt;::type,
short
::value
));
#else
BOOST_STATIC_ASSERT((
boost::is_same&lt;
boost::result_of&lt;functor(const short)&gt;::type,
const short
::value
));
#endif</pre>
</blockquote></li>
</ul>
<a name="result_of_cxx11_diff">
<h3>Known differences between boost::result_of and C++11 result_of</h3>
</a>
<p>When using <code>decltype</code>, <code>boost::result_of</code>
implements most of the C++11 result_of
specification. One known exception is that
<code>boost::result_of</code> does not implement the
requirements regarding pointers to member data.</p>
<p>Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others</p>
<h2><a name="BOOST_BINARY">Macro BOOST_BINARY</a></h2>
<p>The macro <code>BOOST_BINARY</code> is used for the
representation of binary literals. It takes as an argument
a binary number arranged as an arbitrary amount of 1s and 0s in
groupings of length 1 to 8, with groups separated
by spaces. The type of the literal yielded is determined by
the same rules as those of hex and octal
literals (<i>2.13.1p1</i>). By implementation, this macro
expands directly to an octal literal during preprocessing, so
there is no overhead at runtime and the result is useable in
any place that an octal literal would be.</p>
<p>In order to directly support binary literals with suffixes,
additional macros of the form BOOST_BINARY_XXX are also
provided, where XXX is a standard integer suffix in all capital
letters. In addition, LL and ULL suffixes may be used for representing
long long and unsigned long long types in compilers which provide
them as an extension.</p>
<p>The BOOST_BINARY family of macros resides in the header
<a
href="../../boost/utility/binary.hpp">&lt;boost/utility/binary.hpp&gt;</a>
which is automatically included by
<a
href="../../boost/utility.hpp">&lt;boost/utility.hpp&gt;</a>.
<p>Contributed by Matt Calabrese.</p><p>
</p><h3>Example</h3>
<blockquote>
<pre>
void foo( int );
void foo( unsigned long );
void bar()
{
int value1 = BOOST_BINARY( 100 111000 01 1 110 );
unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned long
long long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported
assert( BOOST_BINARY( 10010 )
& BOOST_BINARY( 11000 )
== BOOST_BINARY( 10000 )
);
foo( BOOST_BINARY( 1010 ) ); // calls the first foo
foo( BOOST_BINARY_LU( 1010 ) ); // calls the second foo
}
</pre></blockquote>
<hr>
<p>Revised&nbsp; <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
-->04 September, 2008<!--webbot bot="Timestamp" endspan i-checksum="39369"
-->
</p>
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
distribute this document is granted provided this copyright notice appears in
all copies. This document is provided &quot;as is&quot; without express or
implied warranty, and with no claim as to its suitability for any purpose.</p>
</body>
</p>
<p>&copy; Copyright Beman Dawes 1999-2003.</p>
<p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
</body>
</html>

514
value_init.htm Normal file
View File

@ -0,0 +1,514 @@
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>value_initialized</title>
</head>
<body vlink="#800080" link="#0000ff" text="#000000" bgcolor="#ffffff">
<h2><img src="../../boost.png" width="276" height="86">
Header &lt;<a href="../../boost/utility/value_init.hpp">boost/utility/value_init.hpp</a>&gt;
</h2>
<h2>Contents</h2>
<dl>
<dt><a href="#rationale">Rationale</a></dt>
<dt><a href="#intro">Introduction</a></dt>
<dt><a href="#details">Details</a></dt>
</dl>
<ul>
<li><a href="#valueinit">value-initialization</a></li>
<li><a href="#valueinitsyn">value-initialization syntax</a></li>
<li><a href="#compiler_issues">compiler issues</a></li>
</ul>
<dl class="page-index">
<dt><a href="#types">Types and objects</a></dt>
</dl>
<ul>
<li><a href="#val_init"><code>template class value_initialized&lt;T&gt;</code></a></li>
<li><a href="#initialized"><code>template class initialized&lt;T&gt;</code></a></li>
<li><a href="#initialized_value"><code>initialized_value</code></a></li>
</ul>
<a href="#acknowledgements">Acknowledgements</a><br>
<br>
<hr>
<h2><a name="rationale"></a>Rationale</h2>
<p>Constructing and initializing objects in a generic way is difficult in
C++. The problem is that there are several different rules that apply
for initialization. Depending on the type, the value of a newly constructed
object can be zero-initialized (logically 0), default-constructed (using
the default constructor), or indeterminate. When writing generic code,
this problem must be addressed. The template <code>value_initialized</code> provides
a solution with consistent syntax for value initialization of scalar,
union and class types.
Moreover, <code>value_initialized</code> offers a workaround to various
compiler issues regarding value-initialization.
Furthermore, a <code>const</code> object, <code>initialized_value</code> is provided,
to avoid repeating the type name when retrieving the value from a
<code>value_initialized&lt;T&gt;</code> object.
<br>
</p>
<h2><a name="intro"></a>Introduction</h2>
<p>
There are various ways to initialize a variable, in C++. The following
declarations all <em>may</em> have a local variable initialized to its default
value:
<pre>
T1 var1;
T2 var2 = 0;
T3 var3 = {};
T4 var4 = T4();
</pre>
Unfortunately, whether or not any of those declarations correctly
initialize the variable very much depends on its type. The first
declaration is valid for any <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
DefaultConstructible</a> type (by definition).
However, it does not always do an initialization!
It correctly initializes the variable when it's an instance of a
class, and the author of the class has provided a proper default
constructor. On the other hand, the value of <code>var1</code> is <em>indeterminate</em> when
its type is an arithmetic type, like <code>int</code>, <code>float</code>, or <code>char</code>.
An arithmetic variable
is of course initialized properly by the second declaration, <code>T2
var2 = 0</code>. But this initialization form usually won't work for a
class type (unless the class was especially written to support being
initialized that way). The third form, <code>T3 var3 = {}</code>
initializes an aggregate, typically a "C-style" <code>struct</code> or a "C-style" array.
However, the syntax is not allowed for a class that has an explicitly declared
constructor. (But watch out for an upcoming C++ language change,
by Bjarne Stroustrup et al [<a href="#references">1</a>]!)
The fourth form is the most generic form of them, as it
can be used to initialize arithmetic types, class types, aggregates, pointers, and
other types. The declaration, <code>T4 var4 = T4()</code>, should be read
as follows: First a temporary object is created, by <code>T4()</code>.
This object is <a href="#valueinit">value-initialized</a>. Next the temporary
object is copied to the named variable, <code>var4</code>. Afterwards, the temporary
is destroyed. While the copying and the destruction are likely to
be optimized away, C++ still requires the type <code>T4</code> to be
<a href="CopyConstructible.html">CopyConstructible</a>.
(So <code>T4</code> needs to be <em>both</em> DefaultConstructible <em>and</em> CopyConstructible.)
A class may not be CopyConstructible, for example because it may have a
private and undefined copy constructor,
or because it may be derived from <a href="utility.htm#Class_noncopyable">boost::noncopyable</a>.
Scott Meyers [<a href="#references">2</a>] explains why a class would be defined like that.
</p>
<p>
There is another, less obvious disadvantage to the fourth form, <code>T4 var4 = T4()</code>:
It suffers from various <a href="#compiler_issues">compiler issues</a>, causing
a variable to be left uninitialized in some compiler specific cases.
</p>
<p>
The template <a href="#val_init"><code>value_initialized</code></a>
offers a generic way to initialize
an object, like <code>T4 var4 = T4()</code>, but without requiring its type
to be CopyConstructible. And it offers a workaround to those compiler issues
regarding value-initialization as well! It allows getting an initialized
variable of any type; it <em>only</em> requires the type to be DefaultConstructible.
A properly <em>value-initialized</em> object of type <code>T</code> is
constructed by the following declaration:
<pre>
value_initialized&lt;T&gt; var;
</pre>
</p>
<p>
The template <a href="#initialized"><code>initialized</code></a>
offers both value-initialization and direct-initialization.
It is especially useful as a data member type, allowing the very same object
to be either direct-initialized or value-initialized.
</p>
<p>
The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
allows value-initializing a variable as follows:
<pre>
T var = initialized_value ;
</pre>
This form of initialization is semantically equivalent to <code>T4 var4 = T4()</code>,
but robust against the aforementioned compiler issues.
</p>
<h2><a name="details"></a>Details</h2>
<p>The C++ standard [<a href="#references">3</a>] contains the definitions
of <code>zero-initialization</code> and <code>default-initialization</code>.
Informally, zero-initialization means that the object is given the initial
value 0 (converted to the type) and default-initialization means that
POD [<a href="#references">4</a>] types are zero-initialized, while non-POD class
types are initialized with their corresponding default constructors. A
<i>declaration</i> can contain an <i>initializer</i>, which specifies the
object's initial value. The initializer can be just '()', which states that
the object shall be value-initialized (but see below). However, if a <i>declaration</i>
has no <i>initializer</i> and it is of a non-<code>const</code>, non-<code>static</code>
POD type, the initial value is indeterminate: <cite>(see &sect;8.5, [dcl.init], for the
accurate definitions).</cite></p>
<pre>int x ; // no initializer. x value is indeterminate.<br>std::string s ; // no initializer, s is default-constructed.<br><br>int y = int() ; <br>// y is initialized using copy-initialization<br>// but the temporary uses an empty set of parentheses as the initializer,<br>// so it is default-constructed.<br>// A default constructed POD type is zero-initialized,<br>// therefore, y == 0.<br><br>void foo ( std::string ) ;<br>foo ( std::string() ) ; <br>// the temporary string is default constructed <br>// as indicated by the initializer () </pre>
<h3><a name="valueinit">value-initialization</a></h3>
<p>The first <a
href="http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html">Technical
Corrigendum for the C++ Standard</a> (TC1), whose draft was released to
the public in November 2001, introduced <a
href="http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#178">Core
Issue 178</a> (among many other issues, of course).</p>
<p> That issue introduced the new concept of <code>value-initialization</code>
(it also fixed the wording for zero-initialization). Informally, value-initialization
is similar to default-initialization with the exception that in some cases
non-static data members and base class sub-objects are also value-initialized.
The difference is that an object that is value-initialized won't have
(or at least is less likely to have) indeterminate values for data members
and base class sub-objects; unlike the case of an object default constructed.
(see Core Issue 178 for a normative description).</p>
<p>In order to specify value-initialization of an object we need to use the
empty-set initializer: (). </p>
<p>As before, a declaration with no intializer specifies default-initialization,
and a declaration with a non-empty initializer specifies copy (=xxx) or
direct (xxx) initialization. </p>
<pre>template&lt;class T&gt; void eat(T);<br>int x ; // indeterminate initial value.<br>std::string s; // default-initialized.<br>eat ( int() ) ; // value-initialized<br>eat ( std::string() ) ; // value-initialized</pre>
<h4><a name="valueinitsyn">value-initialization</a> syntax</h4>
<p>Value initialization is specified using (). However, the empty set of
parentheses is not permitted by the syntax of initializers because it is
parsed as the declaration of a function taking no arguments: </p>
<pre>int x() ; // declares function int(*)()</pre>
<p>Thus, the empty () must be put in some other initialization context.</p>
<p>One alternative is to use copy-initialization syntax:</p>
<pre>int x = int() ;</pre>
<p>This works perfectly fine for POD types. But for non-POD class types,
copy-initialization searches for a suitable constructor, which could be,
for instance, the copy-constructor (it also searches for a suitable conversion
sequence but this doesn't apply in this context). For an arbitrary unknown
type, using this syntax may not have the value-initialization effect intended
because we don't know if a copy from a default constructed object is exactly
the same as a default constructed object, and the compiler is allowed (in
some cases), but never required to, optimize the copy away.</p>
<p>One possible generic solution is to use value-initialization of a non static
data member:</p>
<pre>template&lt;class T&gt; <br>struct W <br>{<br> // value-initialization of 'data' here.<br> W() : data() {}<br> T data ;<br>} ;<br>W&lt;int&gt; w ;<br>// w.data is value-initialized for any type. </pre>
<p>This is the solution as it was supplied by earlier versions of the
<code>value_initialized&lt;T&gt;</code> template
class. Unfortunately this approach suffered from various compiler issues.</p>
<h4><a name="compiler_issues">compiler issues</a> </h4>
Various compilers haven't yet fully implemented value-initialization.
So when an object should be <em>value-initialized</em> (according to the C++ Standard),
it <em>may</em> in practice still be left uninitialized, because of those
compiler issues! It's hard to make a general statement on what those issues
are like, because they depend on the compiler you are using, its version number,
and the type of object you would like to have value-initialized.
All compilers we have tested so far support value-initialization for arithmetic types properly.
However, various compilers may leave some types of <em>aggregates</em> uninitialized, when they
should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
go wrong on various compilers.
</p>
<p>
At the moment of writing, May 2010, the following reported issues regarding
value-initialization are still there in current compiler releases:
<ul>
<li>
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/100744">
Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression</a>
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005
</li><li>
<a href="http://connect.microsoft.com/VisualStudio/feedback/details/484295">
Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor</a>
<br>Reported by Sylvester Hesp, 2009
</li><li>
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/499606">
Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization</a>
<br>Reported by Alex Vakulenko, 2009
</li><li>
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83751">
Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized</a>
<br>Reported by Niels Dekker (LKEB), 2010
</li><li>
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83851">
Embarcadero/C++Builder Report 83851, Value-initialized temporary triggers internal backend error C1798</a>
<br>Reported by Niels Dekker, 2010
</li><li>
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=84279">
Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"</a>
<br>Reported by Niels Dekker, 2010
</li><li>
Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate.
<br>Reported to Steve Clamage by Niels Dekker, 2010
</li><li>
IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate.
<br>Reported to Michael Wong by Niels Dekker, 2010
</li><li>
Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error
on Intel 11.1.
<br>Reported by John Maddock, 2010
</li>
</ul>
Note that all known GCC issues regarding value-initialization are
fixed with GCC version 4.4, including
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">GCC Bug 30111</a>.
Clang also has completely implemented value-initialization, as far as we know,
now that <a href="http://llvm.org/bugs/show_bug.cgi?id=7139">Clang Bug 7139</a> is fixed.
</p><p>
New versions of <code>value_initialized</code>
(Boost release version 1.35 or higher)
offer a workaround to these issues: <code>value_initialized</code> may now clear
its internal data, prior to constructing the object that it contains. It will do
so for those compilers that need to have such a workaround, based on the
<a href="../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_defects"
>compiler defect macro</a> BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
</p>
<h2><a name="types"></a>Types and objects</h2>
<h2><a name="val_init"><code>template class value_initialized&lt;T&gt;</code></a></h2>
<pre>namespace boost {<br><br>template&lt;class T&gt;<br>class value_initialized<br>{
<br> public :
<br> value_initialized() : x() {}
<br> operator T const &amp;() const { return x ; }
<br> operator T&amp;() { return x ; }
<br> T const &amp;data() const { return x ; }
<br> T&amp; data() { return x ; }
<br> void swap( value_initialized&amp; );
<br>
<br> private :
<br> <i>unspecified</i> x ;
<br>} ;
<br>
<br>template&lt;class T&gt;
<br>T const&amp; get ( value_initialized&lt;T&gt; const&amp; x )
<br>{
<br> return x.data() ;
<br>}
<br>
<br>template&lt;class T&gt;
<br>T&amp; get ( value_initialized&lt;T&gt;&amp; x )
<br>{
<br> return x.data() ;
<br>}
<br>
<br>template&lt;class T&gt;
<br>void swap ( value_initialized&lt;T&gt;&amp; lhs, value_initialized&lt;T&gt;&amp; rhs )
<br>{
<br> lhs.swap(rhs) ;
<br>}
<br>
<br>} // namespace boost
<br></pre>
<p>An object of this template class is a <code>T</code>-wrapper convertible
to <code>'T&amp;'</code> whose wrapped object (data member of type <code>T</code>)
is <a href="#valueinit">value-initialized</a> upon default-initialization
of this wrapper class: </p>
<pre>int zero = 0 ;<br>value_initialized&lt;int&gt; x ;<br>assert ( x == zero ) ;<br><br>std::string def ;<br>value_initialized&lt; std::string &gt; y ;<br>assert ( y == def ) ;<br></pre>
<p>The purpose of this wrapper is to provide a consistent syntax for value
initialization of scalar, union and class types (POD and non-POD) since
the correct syntax for value initialization varies (see <a
href="#valueinitsyn">value-initialization syntax</a>)</p>
<p>The wrapped object can be accessed either through the conversion operator
<code>T&amp;</code>, the member function <code>data()</code>, or the
non-member function <code>get()</code>: </p>
<pre>void watch(int);<br>value_initialized&lt;int&gt; x;
<br><br>watch(x) ; // operator T&amp; used.<br>watch(x.data());<br>watch( get(x) ) // function get() used</pre>
<p>Both <code>const</code> and non-<code>const</code> objects can be wrapped.
Mutable objects can be modified directly from within the wrapper but constant
objects cannot:</p>
<p>When <code>T</code> is a <em>Swappable</em> type, <code>value_initialized&lt;T&gt;</code>
is swappable as well, by calling its <code>swap</code> member function
as well as by calling <code>boost::swap</code>.</p>
<pre>value_initialized&lt;int&gt; x ; <br>static_cast&lt;int&amp;&gt;(x) = 1 ; // OK<br>get(x) = 1 ; // OK
<br><br>value_initialized&lt;int const&gt; y ; <br>static_cast&lt;int&amp;&gt;(y) = 1 ; // ERROR: cannot cast to int&amp;<br>static_cast&lt;int const&amp;&gt;(y) = 1 ; // ERROR: cannot modify a const value<br>get(y) = 1 ; // ERROR: cannot modify a const value</pre>
<h3>Warning:</h3>
<p>The <code>value_initialized</code> implementation of Boost version 1.40.0 and older
allowed <i>non-const</i> access to the wrapped object, from a constant wrapper,
both by its conversion operator and its <code>data()</code> member function. For example:</p>
<pre>value_initialized&lt;int&gt; const x_c ;<br>int&amp; xr = x_c ; // OK, conversion to int&amp; available even though x_c is itself const.
<br>xr = 2 ; </pre>
<p>The reason for this obscure behavior was that some compilers
didn't accept the following valid code:</p>
<pre>struct X<br>{<br> operator int&amp;() ;<br> operator int const&amp;() const ; <br>};<br>X x ;<br>(x == 1 ) ; // ERROR HERE!</pre>
<p>The current version of <code>value_initialized</code> no longer has this obscure behavior.
As compilers nowadays widely support overloading the conversion operator by having a <code>const</code> and a <code>non-const</code> version, we have decided to fix the issue accordingly. So the current version supports the idea of logical constness.
<br>
</p>
<h3>Recommended practice: The non-member get() idiom</h3>
<p>The obscure behavior of being able to modify a non-<code>const</code>
wrapped object from within a constant wrapper (as was supported by previous
versions of <code>value_initialized</code>)
can be avoided if access to
the wrapped object is always performed with the <code>get()</code> idiom:</p>
<pre>value_initialized&lt;int&gt; x ;<br>get(x) = 1 ; // OK<br><br>value_initialized&lt;int const&gt; cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int&gt; const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int const&gt; const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
<h2><a name="initialized"><code>template class initialized&lt;T&gt;</code></a></h2>
<pre>namespace boost {<br><br>template&lt;class T&gt;<br>class initialized<br>{
<br> public :
<br> initialized() : x() {}
<br> explicit initialized(T const &amp; arg) : x(arg) {}
<br> operator T const &amp;() const;
<br> operator T&amp;();
<br> T const &amp;data() const;
<br> T&amp; data();
<br> void swap( initialized&amp; );
<br>
<br> private :
<br> <i>unspecified</i> x ;
<br>} ;
<br>
<br>template&lt;class T&gt;
<br>T const&amp; get ( initialized&lt;T&gt; const&amp; x );
<br>
<br>template&lt;class T&gt;
<br>T&amp; get ( initialized&lt;T&gt;&amp; x );
<br>
<br>template&lt;class T&gt;
<br>void swap ( initialized&lt;T&gt;&amp; lhs, initialized&lt;T&gt;&amp; rhs );
<br>
<br>} // namespace boost
<br></pre>
The template class <code>boost::initialized&lt;T&gt;</code> supports both value-initialization
and direct-initialization, so its interface is a superset of the interface
of <code>value_initialized&lt;T&gt;</code>: Its default-constructor
value-initializes the wrapped object just like the default-constructor of
<code>value_initialized&lt;T&gt;</code>, but <code>boost::initialized&lt;T&gt;</code>
also offers an extra <code>explicit</code>
constructor, which direct-initializes the wrapped object by the specified value.
<p>
<code>initialized&lt;T&gt;</code> is especially useful when the wrapped
object must be either value-initialized or direct-initialized, depending on
runtime conditions. For example, <code>initialized&lt;T&gt;</code> could
hold the value of a data member that may be value-initialized by some
constructors, and direct-initialized by others.
On the other hand, if it is known beforehand that the
object must <i>always</i> be value-initialized, <code>value_initialized&lt;T&gt;</code>
may be preferable. And if the object must always be
direct-initialized, none of the two wrappers really needs to be used.
</p>
<h2><a name="initialized_value"><code>initialized_value</code></a></h2>
<pre>
namespace boost {
class initialized_value_t
{
public :
template &lt;class T&gt; operator T() const ;
};
initialized_value_t const initialized_value = {} ;
} // namespace boost
</pre>
<code>initialized_value</code> provides a convenient way to get
an initialized value: its conversion operator provides an appropriate
<em>value-initialized</em> object for any CopyConstructible type.
Suppose you need to have an initialized variable of type <code>T</code>.
You could do it as follows:
<pre>
T var = T();
</pre>
But as mentioned before, this form suffers from various compiler issues.
The template <code>value_initialized</code> offers a workaround:
<pre>
T var = get( value_initialized&lt;T&gt;() );
</pre>
Unfortunately both forms repeat the type name, which
is rather short now (<code>T</code>), but could of course be
more like <code>Namespace::Template&lt;Arg&gt;::Type</code>.
Instead, one could use <code>initialized_value</code> as follows:
<pre>
T var = initialized_value ;
</pre>
<h3><a name="references">References</a></h3>
[1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote
various papers, proposing to extend the support for brace-enclosed <em>initializer lists</em>
in the next version of C++.
This would allow a variable <code>var</code> of any DefaultConstructible type
<code>T</code> to be <em>value-initialized</em> by doing <code>T var = {}</code>.
The papers are listed at Bjarne's web page,
<a href="http://www.research.att.com/~bs/WG21.html">My C++ Standards committee papers</a> <br>
[2] Scott Meyers, Effective C++, Third Edition, item 6,
<em>Explicitly disallow the use of compiler-generated functions you do not want</em>,
<a href="http://www.aristeia.com/books.html">Scott Meyers: Books and CDs</a> <br>
[3] The C++ Standard, Second edition (2003), ISO/IEC 14882:2003 <br>
[4] POD stands for "Plain Old Data"
<h3><a name="acknowledgements"></a>Acknowledgements</h3>
value_initialized was developed by Fernando Cacciola, with help and
suggestions from David Abrahams and Darin Adler.<br>
Special thanks to Bj&ouml;rn Karlsson who carefully edited and completed this documentation.
<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
</p>
<p><code>boost::initialized</code> was very much inspired by feedback from Edward Diener and
Jeffrey Hellrung.
</p>
<p>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
</p>
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
the latest version of this file can be found at <a
href="http://www.boost.org">www.boost.org</a>.
</p>
<hr>
<p>Revised 30 May 2010</p>
<p>&copy; Copyright Fernando Cacciola, 2002 - 2010.</p>
<p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
<br>
<br>
</body>
</html>

369
value_init_test.cpp Normal file
View File

@ -0,0 +1,369 @@
// Copyright 2002-2008, Fernando Luis Cacciola Carballal.
//
// 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)
//
// Test program for "boost/utility/value_init.hpp"
//
// 21 Ago 2002 (Created) Fernando Cacciola
// 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker
// 23 May 2008 (Added tests regarding initialized_value) Niels Dekker
// 21 Ago 2008 (Added swap test) Niels Dekker
#include <cstring> // For memcmp.
#include <iostream>
#include <string>
#include "boost/utility/value_init.hpp"
#include <boost/shared_ptr.hpp>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include <boost/detail/lightweight_test.hpp>
//
// Sample POD type
//
struct POD
{
POD () : f(0), c(0), i(0){}
POD ( char c_, int i_, float f_ ) : f(f_), c(c_), i(i_) {}
friend std::ostream& operator << ( std::ostream& os, POD const& pod )
{ return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; }
friend bool operator == ( POD const& lhs, POD const& rhs )
{ return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; }
float f;
char c;
int i;
} ;
//
// Sample non POD type
//
struct NonPODBase
{
virtual ~NonPODBase() {}
} ;
struct NonPOD : NonPODBase
{
NonPOD () : id() {}
explicit NonPOD ( std::string const& id_) : id(id_) {}
friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod )
{ return os << '(' << npod.id << ')' ; }
friend bool operator == ( NonPOD const& lhs, NonPOD const& rhs )
{ return lhs.id == rhs.id ; }
std::string id ;
} ;
//
// Sample aggregate POD struct type
// Some compilers do not correctly value-initialize such a struct, for example:
// Borland C++ Report #51854, "Value-initialization: POD struct should be zero-initialized "
// http://qc.codegear.com/wc/qcmain.aspx?d=51854
//
struct AggregatePODStruct
{
float f;
char c;
int i;
};
bool operator == ( AggregatePODStruct const& lhs, AggregatePODStruct const& rhs )
{ return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; }
//
// An aggregate struct that contains an std::string and an int.
// Pavel Kuznetsov (MetaCommunications Engineering) used a struct like
// this to reproduce the Microsoft Visual C++ compiler bug, reported as
// Feedback ID 100744, "Value-initialization in new-expression"
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
//
struct StringAndInt
{
std::string s;
int i;
};
bool operator == ( StringAndInt const& lhs, StringAndInt const& rhs )
{ return lhs.s == rhs.s && lhs.i == rhs.i ; }
//
// A struct that has an explicit (user defined) destructor.
// Some compilers do not correctly value-initialize such a struct, for example:
// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression"
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
//
struct StructWithDestructor
{
int i;
~StructWithDestructor() {}
};
bool operator == ( StructWithDestructor const& lhs, StructWithDestructor const& rhs )
{ return lhs.i == rhs.i ; }
//
// A struct that has a virtual function.
// Some compilers do not correctly value-initialize such a struct either, for example:
// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression"
// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
//
struct StructWithVirtualFunction
{
int i;
virtual void VirtualFunction();
};
void StructWithVirtualFunction::VirtualFunction()
{
}
bool operator == ( StructWithVirtualFunction const& lhs, StructWithVirtualFunction const& rhs )
{ return lhs.i == rhs.i ; }
//
// A struct that is derived from an aggregate POD struct.
// Some compilers do not correctly value-initialize such a struct, for example:
// GCC Bugzilla Bug 30111, "Value-initialization of POD base class doesn't initialize members",
// reported by Jonathan Wakely, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111
//
struct DerivedFromAggregatePODStruct : AggregatePODStruct
{
DerivedFromAggregatePODStruct() : AggregatePODStruct() {}
};
//
// A struct that wraps an aggregate POD struct as data member.
//
struct AggregatePODStructWrapper
{
AggregatePODStructWrapper() : dataMember() {}
AggregatePODStruct dataMember;
};
bool operator == ( AggregatePODStructWrapper const& lhs, AggregatePODStructWrapper const& rhs )
{ return lhs.dataMember == rhs.dataMember ; }
typedef unsigned char ArrayOfBytes[256];
//
// A struct that allows testing whether the appropriate copy functions are called.
//
struct CopyFunctionCallTester
{
bool is_copy_constructed;
bool is_assignment_called;
CopyFunctionCallTester()
: is_copy_constructed(false), is_assignment_called(false) {}
CopyFunctionCallTester(const CopyFunctionCallTester & )
: is_copy_constructed(true), is_assignment_called(false) {}
CopyFunctionCallTester & operator=(const CopyFunctionCallTester & )
{
is_assignment_called = true ;
return *this ;
}
};
//
// A struct that allows testing whether its customized swap function is called.
//
struct SwapFunctionCallTester
{
bool is_custom_swap_called;
int data;
SwapFunctionCallTester()
: is_custom_swap_called(false), data(0) {}
SwapFunctionCallTester(const SwapFunctionCallTester & arg)
: is_custom_swap_called(false), data(arg.data) {}
void swap(SwapFunctionCallTester & arg)
{
std::swap(data, arg.data);
is_custom_swap_called = true;
arg.is_custom_swap_called = true;
}
};
void swap(SwapFunctionCallTester & lhs, SwapFunctionCallTester & rhs)
{
lhs.swap(rhs);
}
template<class T>
void check_initialized_value ( T const& y )
{
T initializedValue = boost::initialized_value ;
BOOST_TEST ( y == initializedValue ) ;
}
#ifdef __BORLANDC__
#if __BORLANDC__ == 0x582
void check_initialized_value( NonPOD const& )
{
// The initialized_value check is skipped for Borland 5.82
// and this type (NonPOD), because the following statement
// won't compile on this particular compiler version:
// NonPOD initializedValue = boost::initialized_value() ;
//
// This is caused by a compiler bug, that is fixed with a newer version
// of the Borland compiler. The Release Notes for Delphi(R) 2007 for
// Win32(R) and C++Builder(R) 2007 (http://dn.codegear.com/article/36575)
// say about similar statements:
// both of these statements now compile but under 5.82 got the error:
// Error E2015: Ambiguity between 'V::V(const A &)' and 'V::V(const V &)'
}
#endif
#endif
//
// This test function tests boost::value_initialized<T> for a specific type T.
// The first argument (y) is assumed have the value of a value-initialized object.
// Returns true on success.
//
template<class T>
bool test ( T const& y, T const& z )
{
const int errors_before_test = boost::detail::test_errors();
check_initialized_value(y);
boost::value_initialized<T> x ;
BOOST_TEST ( y == x ) ;
BOOST_TEST ( y == boost::get(x) ) ;
static_cast<T&>(x) = z ;
boost::get(x) = z ;
BOOST_TEST ( x == z ) ;
boost::value_initialized<T> const x_c ;
BOOST_TEST ( y == x_c ) ;
BOOST_TEST ( y == boost::get(x_c) ) ;
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
x_c_ref = z ;
BOOST_TEST ( x_c == z ) ;
boost::value_initialized<T> const copy1 = x;
BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ;
boost::value_initialized<T> copy2;
copy2 = x;
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
BOOST_TEST ( y == *ptr ) ;
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
boost::value_initialized<T const> cx ;
BOOST_TEST ( y == cx ) ;
BOOST_TEST ( y == boost::get(cx) ) ;
boost::value_initialized<T const> const cx_c ;
BOOST_TEST ( y == cx_c ) ;
BOOST_TEST ( y == boost::get(cx_c) ) ;
#endif
return boost::detail::test_errors() == errors_before_test ;
}
int main(int, char **)
{
BOOST_TEST ( test( 0,1234 ) ) ;
BOOST_TEST ( test( 0.0,12.34 ) ) ;
BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
NonPOD NonPOD_object( std::string("NonPOD_object") );
BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
StringAndInt stringAndInt0;
StringAndInt stringAndInt1;
stringAndInt0.i = 0;
stringAndInt1.i = 1;
stringAndInt1.s = std::string("1");
BOOST_TEST ( test(stringAndInt0, stringAndInt1) );
StructWithDestructor structWithDestructor0;
StructWithDestructor structWithDestructor1;
structWithDestructor0.i = 0;
structWithDestructor1.i = 1;
BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) );
StructWithVirtualFunction structWithVirtualFunction0;
StructWithVirtualFunction structWithVirtualFunction1;
structWithVirtualFunction0.i = 0;
structWithVirtualFunction1.i = 1;
BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
AggregatePODStructWrapper aggregatePODStructWrapper0;
AggregatePODStructWrapper aggregatePODStructWrapper1;
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed);
BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called);
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed);
BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called);
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed);
BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called);
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
get(swapFunctionCallTester1).data = 1;
get(swapFunctionCallTester2).data = 2;
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
BOOST_TEST( get(swapFunctionCallTester1).data == 2 );
BOOST_TEST( get(swapFunctionCallTester2).data == 1 );
BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called );
BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called );
return boost::report_errors();
}

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