Compare commits

...

193 Commits

Author SHA1 Message Date
9ae6492af9 Merge pull request #25 from zerotypos-found/inspection_report
Remove tabs and Non-ASCII characters.  Thanks!
2016-11-21 18:25:08 -08:00
816607e212 Remove tabs and Non-ASCII characters. 2016-11-15 11:59:51 +09:00
a3ab942bc2 Merge branch 'develop' 2016-11-08 16:56:27 +03:00
0f1f793caf Removed std::binary_function from a comment. 2016-11-06 21:18:27 +03:00
ff445c0ece Remove std::binary_function use, it has been removed in C++17 2016-11-06 14:38:13 +02:00
9fae8be166 Add, and update, documentation build targets. 2016-10-10 11:39:54 -05:00
b90a28f0e1 Add, and update, documentation build targets. 2016-10-07 23:07:37 -05:00
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
1057ff4d9e Utility/noncopyable: Make use of =delete #6578.
[SVN r83833]
2013-04-10 17:16:02 +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
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
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
71205b6e84 Updated the string_ref docs with a reference section; committed the generated HTML
[SVN r82489]
2013-01-14 16:25:56 +00:00
98d793152c Move string_ref to Boost.Utility; first crack at docs
[SVN r81972]
2012-12-15 16:38:07 +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
3cca2755cf add missing close tag
[SVN r80834]
2012-10-03 23:08:44 +00:00
93f6e3473b friendlier wrt overloaded comma
[SVN r80732]
2012-09-28 08:47:35 +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
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
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
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
3558d61c51 Make the new pdf install rules explicit, and fix intrusive's.
[SVN r78877]
2012-06-11 01:33:10 +00:00
a201cbe646 Changes required to build PDF versions of docs.
[SVN r78845]
2012-06-07 12:32:56 +00:00
8036d4370f Utility/declval: update history.
[SVN r78729]
2012-05-28 18:44:24 +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
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
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
111 changed files with 4158 additions and 6256 deletions

View File

@ -57,10 +57,7 @@ aliasing.
</TR>
<TR>
<TD VAlign=top>Validity Test</TD>
<TD VAlign=top>&nbsp;<tt>t</tt><br>
&nbsp;<tt>t != 0</tt><br>
&nbsp;<tt>!!t</tt>
</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>
@ -68,9 +65,7 @@ aliasing.
</TR>
<TR>
<TD VAlign=top>Invalidity Test</TD>
<TD VAlign=top>&nbsp;<tt>t == 0</tt><br>
&nbsp;<tt>!t</tt>
</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>
@ -161,4 +156,4 @@ so direct usage of relational operators with the implied aliasing of shallow sem
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
</BODY>
</HTML>
</HTML>

View File

@ -1,76 +0,0 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
// addressof_fn_test.cpp: addressof( f )
//
// Copyright (c) 2008, 2009 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/utility/addressof.hpp>
#include <boost/detail/lightweight_test.hpp>
void f0()
{
}
void f1(int)
{
}
void f2(int, int)
{
}
void f3(int, int, int)
{
}
void f4(int, int, int, int)
{
}
void f5(int, int, int, int, int)
{
}
void f6(int, int, int, int, int, int)
{
}
void f7(int, int, int, int, int, int, int)
{
}
void f8(int, int, int, int, int, int, int, int)
{
}
void f9(int, int, int, int, int, int, int, int, int)
{
}
int main()
{
BOOST_TEST( boost::addressof( f0 ) == &f0 );
BOOST_TEST( boost::addressof( f1 ) == &f1 );
BOOST_TEST( boost::addressof( f2 ) == &f2 );
BOOST_TEST( boost::addressof( f3 ) == &f3 );
BOOST_TEST( boost::addressof( f4 ) == &f4 );
BOOST_TEST( boost::addressof( f5 ) == &f5 );
BOOST_TEST( boost::addressof( f6 ) == &f6 );
BOOST_TEST( boost::addressof( f7 ) == &f7 );
BOOST_TEST( boost::addressof( f8 ) == &f8 );
BOOST_TEST( boost::addressof( f9 ) == &f9 );
return boost::report_errors();
}

View File

@ -1,94 +0,0 @@
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
// Douglas Gregor (gregod@cs.rpi.edu)
//
// 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 <boost/utility/addressof.hpp>
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
#pragma warning(push, 3)
#endif
#include <iostream>
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
#pragma warning(pop)
#endif
#include <boost/detail/lightweight_test.hpp>
template<class T> void scalar_test( T * = 0 )
{
T* px = new T();
T& x = *px;
BOOST_TEST( boost::addressof(x) == px );
const T& cx = *px;
const T* pcx = boost::addressof(cx);
BOOST_TEST( pcx == px );
volatile T& vx = *px;
volatile T* pvx = boost::addressof(vx);
BOOST_TEST( pvx == px );
const volatile T& cvx = *px;
const volatile T* pcvx = boost::addressof(cvx);
BOOST_TEST( pcvx == px );
delete px;
}
template<class T> void array_test( T * = 0 )
{
T nrg[3] = {1,2,3};
T (*pnrg)[3] = &nrg;
BOOST_TEST( boost::addressof(nrg) == pnrg );
T const cnrg[3] = {1,2,3};
T const (*pcnrg)[3] = &cnrg;
BOOST_TEST( boost::addressof(cnrg) == pcnrg );
}
struct addressable
{
addressable( int = 0 )
{
}
};
struct useless_type {};
class nonaddressable {
public:
nonaddressable( int = 0 )
{
}
void dummy(); // Silence GCC warning: all member of class are private
private:
useless_type operator&() const;
};
int main()
{
scalar_test<char>();
scalar_test<int>();
scalar_test<addressable>();
scalar_test<nonaddressable>();
array_test<char>();
array_test<int>();
array_test<addressable>();
array_test<nonaddressable>();
return boost::report_errors();
}

View File

@ -1,95 +0,0 @@
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
// Douglas Gregor (gregod@cs.rpi.edu)
//
// Copyright 2009 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)
// For more information, see http://www.boost.org
#include <boost/utility/addressof.hpp>
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
#pragma warning(push, 3)
#endif
#include <iostream>
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
#pragma warning(pop)
#endif
#include <boost/detail/lightweight_test.hpp>
template<class T> void scalar_test( T * = 0 )
{
T* px = new T();
T& x = *px;
BOOST_TEST( boost::addressof(x) == px );
const T& cx = *px;
const T* pcx = boost::addressof(cx);
BOOST_TEST( pcx == px );
volatile T& vx = *px;
volatile T* pvx = boost::addressof(vx);
BOOST_TEST( pvx == px );
const volatile T& cvx = *px;
const volatile T* pcvx = boost::addressof(cvx);
BOOST_TEST( pcvx == px );
delete px;
}
template<class T> void array_test( T * = 0 )
{
T nrg[3] = {1,2,3};
T (*pnrg)[3] = &nrg;
BOOST_TEST( boost::addressof(nrg) == pnrg );
T const cnrg[3] = {1,2,3};
T const (*pcnrg)[3] = &cnrg;
BOOST_TEST( boost::addressof(cnrg) == pcnrg );
}
class convertible {
public:
convertible( int = 0 )
{
}
template<class U> operator U () const
{
return U();
}
};
class convertible2 {
public:
convertible2( int = 0 )
{
}
operator convertible2* () const
{
return 0;
}
};
int main()
{
scalar_test<convertible>();
scalar_test<convertible2>();
array_test<convertible>();
array_test<convertible2>();
return boost::report_errors();
}

View File

@ -1,115 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Boost: assert.hpp documentation</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
<table border="0" width="100%">
<tr>
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
</td>
<td align="center">
<h1>assert.hpp</h1>
</td>
</tr>
<tr>
<td colspan="2" height="64">&nbsp;</td>
</tr>
</table>
<p>
<a href="#BOOST_ASSERT">BOOST_ASSERT</a><br>
<a href="#BOOST_ASSERT_MSG">BOOST_ASSERT_MSG</a><br>
<a href="#BOOST_VERIFY">BOOST_VERIFY</a></p>
<h2><a name="BOOST_ASSERT">BOOST_ASSERT</a></h2>
<p>
The header <STRONG>&lt;boost/assert.hpp&gt;</STRONG> defines the macro <b>BOOST_ASSERT</b>,
which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG>&lt;cassert&gt;</STRONG>.
The macro is intended to be used in both Boost libraries and user
code.
</p>
<P>By default, <tt>BOOST_ASSERT(expr)</tt> is equivalent to <tt>assert(expr)</tt>.</P>
<P>If the macro <STRONG>BOOST_DISABLE_ASSERTS</STRONG> is defined when <STRONG>&lt;boost/assert.hpp&gt;</STRONG>
is included, <tt>BOOST_ASSERT(expr)</tt> is defined as <tt>((void)0)</tt>. This
allows users to selectively disable <STRONG>BOOST_ASSERT</STRONG> without
affecting the definition of the standard <STRONG>assert</STRONG>.</P>
<P>If the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG>&lt;boost/assert.hpp&gt;</STRONG>
is included, <tt>BOOST_ASSERT(expr)</tt> evaluates <b>expr</b> and, if the
result is false, evaluates the expression</P>
<blockquote>
<P><tt>::boost::assertion_failed(#expr, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,
__FILE__, __LINE__)</tt></P>
</blockquote>
<P><STRONG>assertion_failed</STRONG> is declared in <STRONG>&lt;boost/assert.hpp&gt;</STRONG>
as</P>
<blockquote>
<pre>namespace boost
{
void assertion_failed(char const * expr, char const * function, char const * file, long line);
}
</pre>
</blockquote>
<p>but it is never defined. The user is expected to supply an appropriate
definition.</p>
<P>As is the case with <STRONG>&lt;cassert&gt;</STRONG>, <STRONG>&lt;boost/assert.hpp&gt;</STRONG>
can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT</STRONG>
will be redefined each time as specified above.</P>
<h2><a name="BOOST_ASSERT_MSG">BOOST_ASSERT_MSG</a></h2>
<p>
The header <STRONG>&lt;boost/assert.hpp&gt;</STRONG> defines the macro <b>BOOST_ASSERT_MSG</b>,
which is similar to the standard <STRONG>assert</STRONG> macro defined in <STRONG>&lt;cassert&gt;</STRONG>,
but with an additional macro parameter supplying an error message. The macro is intended to be used in both Boost libraries
and user code.
</p>
<P> <tt>BOOST_ASSERT_MSG(expr, msg)</tt> is equivalent to <code>
((void)0)</code> if <b>BOOST_DISABLE_ASSERTS</b> or <b>NDEBUG</b> are
defined or <code>expr</code> evaluates to <code>true</code>. If those
macros and <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> are not
defined, and <code>expr</code> evaluates to <code>false</code>, an error
message that includes <tt>#expr</tt>, <tt>msg</tt>, <tt> <a href="current_function.html">BOOST_CURRENT_FUNCTION</a></tt>, <tt>
__FILE__</tt>, and <tt>__LINE__</tt> is sent to output stream <b>
BOOST_ASSERT_MSG_OSTREAM</b>
and <code>std::abort()</code> is called.</P>
<P> <b>BOOST_ASSERT_MSG_OSTREAM</b> defines the output stream. It defaults to <code>std::cerr</code>.
Integrated development environments (IDE's) like Microsoft Visual Studio
may produce easier to understand output if messages go to a different
stream, such as <code>std::cout</code>. Users may define <b>BOOST_ASSERT_MSG_OSTREAM</b> before including <STRONG>&lt;boost/assert.hpp&gt;</STRONG>
to specify a different output stream.&nbsp; </P>
<P>If the macro <STRONG>BOOST_ENABLE_ASSERT_HANDLER</STRONG> is defined when <STRONG>&lt;boost/assert.hpp&gt;</STRONG>
is included, instead of sending a error message to an output
stream, this expression is evaluated</P>
<blockquote>
<P><tt>::boost::assertion_failed_msg(#expr, msg, <a href="current_function.html">BOOST_CURRENT_FUNCTION</a>,
__FILE__, __LINE__)</tt></P>
</blockquote>
<P><STRONG>assertion_failed_msg</STRONG> is declared in <STRONG>&lt;boost/assert.hpp&gt;</STRONG>
as</P>
<blockquote>
<pre>namespace boost
{
void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line);
}
</pre>
</blockquote>
<p>but it is never defined. The user is expected to supply an appropriate
definition.</p>
<P>As is the case with <STRONG>&lt;cassert&gt;</STRONG>, <STRONG>&lt;boost/assert.hpp&gt;</STRONG>
can be included multiple times in a single translation unit. <STRONG>BOOST_ASSERT_MSG</STRONG>
will be redefined each time as specified above.</P>
<h2><a name="BOOST_VERIFY">BOOST_VERIFY</a></h2>
<p><STRONG>&lt;boost/assert.hpp&gt;</STRONG> also defines the macro <STRONG>BOOST_VERIFY</STRONG>.
It has exactly the same behavior as <STRONG>BOOST_ASSERT</STRONG>, except that
the expression that is passed to <STRONG>BOOST_VERIFY</STRONG> is always
evaluated. This is useful when the asserted expression has desirable side
effects; it can also help suppress warnings about unused variables when the
only use of the variable is inside an assertion.</p>
<p><br>
<small>Copyright <20> 2002, 2007 by Peter Dimov.&nbsp; Copyright <20> 2011
by Beman Dawes. 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>.</small></p>
</body>
</html>

View File

@ -1,153 +0,0 @@
//
// assert_test.cpp - a test for boost/assert.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright (2) Beman Dawes 2011
//
// 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/detail/lightweight_test.hpp>
#include <boost/assert.hpp>
void test_default()
{
int x = 1;
BOOST_ASSERT(1);
BOOST_ASSERT(x);
BOOST_ASSERT(x == 1);
BOOST_ASSERT(&x);
BOOST_ASSERT_MSG(1, "msg");
BOOST_ASSERT_MSG(x, "msg");
BOOST_ASSERT_MSG(x == 1, "msg");
BOOST_ASSERT_MSG(&x, "msg");
}
#define BOOST_DISABLE_ASSERTS
#include <boost/assert.hpp>
void test_disabled()
{
int x = 1;
BOOST_ASSERT(1);
BOOST_ASSERT(x);
BOOST_ASSERT(x == 1);
BOOST_ASSERT(&x);
BOOST_ASSERT_MSG(1, "msg");
BOOST_ASSERT_MSG(x, "msg");
BOOST_ASSERT_MSG(x == 1, "msg");
BOOST_ASSERT_MSG(&x, "msg");
BOOST_ASSERT(0);
BOOST_ASSERT(!x);
BOOST_ASSERT(x == 0);
BOOST_ASSERT_MSG(0, "msg");
BOOST_ASSERT_MSG(!x, "msg");
BOOST_ASSERT_MSG(x == 0, "msg");
void * p = 0;
BOOST_ASSERT(p);
BOOST_ASSERT_MSG(p, "msg");
// supress warnings
p = &x;
p = &p;
}
#undef BOOST_DISABLE_ASSERTS
#define BOOST_ENABLE_ASSERT_HANDLER
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <cstdio>
int handler_invoked = 0;
int msg_handler_invoked = 0;
void boost::assertion_failed(char const * expr, char const * function, char const * file, long line)
{
#if !defined(BOOST_NO_STDC_NAMESPACE)
using std::printf;
#endif
printf("Expression: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n", expr, function, file, line);
++handler_invoked;
}
void boost::assertion_failed_msg(char const * expr, char const * msg, char const * function,
char const * file, long line)
{
#if !defined(BOOST_NO_STDC_NAMESPACE)
using std::printf;
#endif
printf("Expression: %s Message: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n",
expr, msg, function, file, line);
++msg_handler_invoked;
}
struct X
{
static void f()
{
BOOST_ASSERT(0);
BOOST_ASSERT_MSG(0, "msg f()");
}
};
void test_handler()
{
int x = 1;
BOOST_ASSERT(1);
BOOST_ASSERT(x);
BOOST_ASSERT(x == 1);
BOOST_ASSERT(&x);
BOOST_ASSERT_MSG(1, "msg2");
BOOST_ASSERT_MSG(x, "msg3");
BOOST_ASSERT_MSG(x == 1, "msg4");
BOOST_ASSERT_MSG(&x, "msg5");
BOOST_ASSERT(0);
BOOST_ASSERT(!x);
BOOST_ASSERT(x == 0);
BOOST_ASSERT_MSG(0,"msg 0");
BOOST_ASSERT_MSG(!x, "msg !x");
BOOST_ASSERT_MSG(x == 0, "msg x == 0");
void * p = 0;
BOOST_ASSERT(p);
BOOST_ASSERT_MSG(p, "msg p");
X::f();
BOOST_ASSERT(handler_invoked == 5);
BOOST_TEST(handler_invoked == 5);
BOOST_ASSERT_MSG(msg_handler_invoked == 5, "msg_handler_invoked count is wrong");
BOOST_TEST(msg_handler_invoked == 5);
}
#undef BOOST_ENABLE_ASSERT_HANDLER
#undef BOOST_ENABLE_ASSERT_MSG_HANDLER
int main()
{
test_default();
test_disabled();
test_handler();
return boost::report_errors();
}

View File

@ -1,371 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>Boost: Base-from-Member Idiom Documentation</title>
</head>
<body bgcolor="white" link="blue" text="black" vlink="purple" alink="red">
<h1><img src="../../boost.png" alt="C++ Boost" align="middle"
width="277" height="86">Base-from-Member Idiom</h1>
<p>The class template <code>boost::base_from_member</code> provides
a workaround for a class that needs to initialize a base class with a
member. The class template is in <cite><a
href="../../boost/utility/base_from_member.hpp">boost/utility/base_from_member.hpp</a></cite>
which is included in <i><a href="../../boost/utility.hpp">boost/utility.hpp</a></i>.</p>
<p>There is test/example code in <cite><a
href="base_from_member_test.cpp">base_from_member_test.cpp</a></cite>.</p>
<h2><a name="contents">Contents</a></h2>
<ul>
<li><a href="#contents">Contents</a></li>
<li><a href="#rationale">Rationale</a></li>
<li><a href="#synopsis">Synopsis</a></li>
<li><a href="#usage">Usage</a></li>
<li><a href="#example">Example</a></li>
<li><a href="#credits">Credits</a>
<ul>
<li><a href="#contributors">Contributors</a></li>
</ul></li>
</ul>
<h2><a name="rationale">Rationale</a></h2>
<p>When developing a class, sometimes a base class needs to be
initialized with a member of the current class. As a na&iuml;ve
example:</p>
<blockquote><pre>
#include &lt;streambuf&gt; <i>// for std::streambuf</i>
#include &lt;ostream&gt; <i>// for std::ostream</i>
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( &amp;buf )
{}
//...
};
</pre></blockquote>
<p>This is undefined because C++'s initialization order mandates that
the base class is initialized before the member it uses. <a
href="http://www.moocat.org">R. Samuel Klatchko</a> 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.</p>
<p>A custom base class can be made for this idiom:</p>
<blockquote><pre>
#include &lt;streambuf&gt; <i>// for std::streambuf</i>
#include &lt;ostream&gt; <i>// for std::ostream</i>
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( &amp;sbuffer )
{}
//...
};
</pre></blockquote>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<h2><a name="synopsis">Synopsis</a></h2>
<blockquote><pre>
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
#endif
template &lt; typename MemberType, int UniqueID = 0 &gt;
class boost::base_from_member
{
protected:
MemberType member;
base_from_member();
template&lt; typename T1 &gt;
explicit base_from_member( T1 x1 );
template&lt; typename T1, typename T2 &gt;
base_from_member( T1 x1, T2 x2 );
//...
template&lt; typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10 &gt;
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
T8 x8, T9 x9, T10 x10 );
};
</pre></blockquote>
<p>The class template has a first template parameter
<var>MemberType</var> representing the type of the based-member.
It has a last template parameter <var>UniqueID</var>, that is an
<code>int</code>, 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 <var>member</var> that the derived class can use
for later base classes (or itself).</p>
<p>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. 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.</p>
<p>The <var>BOOST_BASE_FROM_MEMBER_MAX_ARITY</var> 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.)</p>
<h2><a name="usage">Usage</a></h2>
<p>With the starting example, the <code>fdoutbuf</code> sub-object needs
to be encapsulated in a base class that is inheirited before
<code>std::ostream</code>.</p>
<blockquote><pre>
#include &lt;boost/utility/base_from_member.hpp&gt;
#include &lt;streambuf&gt; <i>// for std::streambuf</i>
#include &lt;ostream&gt; <i>// for std::ostream</i>
class fdoutbuf
: public std::streambuf
{
public:
explicit fdoutbuf( int fd );
//...
};
class fdostream
: private boost::base_from_member&lt;fdoutbuf&gt;
, public std::ostream
{
// Helper typedef's
typedef boost::base_from_member&lt;fdoutbuf&gt; pbase_type;
typedef std::ostream base_type;
public:
explicit fdostream( int fd )
: pbase_type( fd ), base_type( &amp;member )
{}
//...
};
</pre></blockquote>
<p>The base-from-member idiom is an implementation detail, so it
should not be visible to the clients (or any derived classes) of
<code>fdostream</code>. Due to the initialization order, the
<code>fdoutbuf</code> sub-object will get initialized before the
<code>std::ostream</code> sub-object does, making the former
sub-object safe to use in the latter sub-object's construction. Since the
<code>fdoutbuf</code> sub-object of the final type is the only sub-object
with the name &quot;member,&quot; that name can be used
unqualified within the final class.</p>
<h2><a name="example">Example</a></h2>
<p>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.</p>
<blockquote><pre>
#include &lt;boost/utility/base_from_member.hpp&gt;
#include &lt;cstddef&gt; <i>// for NULL</i>
struct an_int
{
int y;
an_int( float yf );
};
class switcher
{
public:
switcher();
switcher( double, int * );
//...
};
class flow_regulator
{
public:
flow_regulator( switcher &amp;, switcher &amp; );
//...
};
template &lt; unsigned Size &gt;
class fan
{
public:
explicit fan( switcher );
//...
};
class system
: private boost::base_from_member&lt;an_int&gt;
, private boost::base_from_member&lt;switcher&gt;
, private boost::base_from_member&lt;switcher, 1&gt;
, private boost::base_from_member&lt;switcher, 2&gt;
, protected flow_regulator
, public fan&lt;6&gt;
{
// Helper typedef's
typedef boost::base_from_member&lt;an_int&gt; pbase0_type;
typedef boost::base_from_member&lt;switcher&gt; pbase1_type;
typedef boost::base_from_member&lt;switcher, 1&gt; pbase2_type;
typedef boost::base_from_member&lt;switcher, 2&gt; pbase3_type;
typedef flow_regulator base1_type;
typedef fan&lt;6&gt; base2_type;
public:
system( double x );
//...
};
system::system( double x )
: pbase0_type( 0.2 )
, pbase1_type()
, pbase2_type( -16, &amp;this-&gt;pbase0_type::member )
, pbase3_type( x, static_cast&lt;int *&gt;(NULL) )
, base1_type( pbase3_type::member, pbase1_type::member )
, base2_type( pbase2_type::member )
{
//...
}
</pre></blockquote>
<p>The final class has multiple sub-objects with the name
&quot;member,&quot; so any use of that name needs qualification by
a name of the appropriate base type. (Using <code>typedef</code>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 <code>an_int boost::base_from_member&lt;an_int,
0&gt; :: *</code>) instead of a pointer to the member (having a type of
<code>an_int *</code>). The new problem is fixed by qualifying the
sub-object with &quot;<code>this-&gt;</code>,&quot; and is needed just
for pointers, and not for references or values.</p>
<p>There are some argument conversions in the initialization. The
constructor argument for <code>pbase0_type</code> is converted from
<code>double</code> to <code>float</code>. The first constructor
argument for <code>pbase2_type</code> is converted from <code>int</code>
to <code>double</code>. The second constructor argument for
<code>pbase3_type</code> is a special case of necessary conversion; all
forms of the null-pointer literal in C++ 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 <code>switcher</code>'s constructor.</p>
<h2><a name="credits">Credits</a></h2>
<h3><a name="contributors">Contributors</a></h3>
<dl>
<dt><a href="http://www.boost.org/people/ed_brey.htm">Ed Brey</a>
<dd>Suggested some interface changes.
<dt><a href="http://www.moocat.org">R. Samuel Klatchko</a> (<a
href="mailto:rsk@moocat.org">rsk@moocat.org</a>, <a
href="mailto:rsk@brightmail.com">rsk@brightmail.com</a>)
<dd>Invented the idiom of how to use a class member for initializing
a base class.
<dt><a href="http://www.boost.org/people/dietmar_kuehl.htm">Dietmar Kuehl</a>
<dd>Popularized the base-from-member idiom in his
<a href="http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/">IOStream
example classes</a>.
<dt>Jonathan Turkanis
<dd>Supplied an implementation of generating the constructor templates that
can be controlled and automated with macros. The implementation uses
the <a href="../preprocessor/index.html">Preprocessor library</a>.
<dt><a href="http://www.boost.org/people/daryle_walker.html">Daryle Walker</a>
<dd>Started the library. Contributed the test file <cite><a
href="base_from_member_test.cpp">base_from_member_test.cpp</a></cite>.
</dl>
<hr>
<p>Revised: 28 August 2004</p>
<p>Copyright 2001, 2003, 2004 Daryle Walker. 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 a copy at &lt;<a
href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</p>
</body>
</html>

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();
}

View File

@ -18,7 +18,7 @@
#include <boost/utility/base_from_member.hpp> // for boost::base_from_member
#include <functional> // for std::binary_function, std::less
#include <functional> // for std::less
#include <iostream> // for std::cout (std::ostream, std::endl indirectly)
#include <set> // for std::set
#include <typeinfo> // for std::type_info
@ -46,7 +46,6 @@ template < typename T >
// 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;

View File

@ -1,258 +0,0 @@
// (C) Copyright David Abrahams 2000.
// 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 <vector>
#include <string>
#include <memory>
#include <climits>
#include <iostream>
#include <cassert>
#include <stdlib.h> // for rand(). Would use cstdlib but VC6.4 doesn't put it in std::
#include <list>
#include <algorithm>
#include <boost/detail/binary_search.hpp>
#include <boost/detail/workaround.hpp>
#include <cstddef>
#if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
# define USE_SSTREAM
#endif
#ifdef USE_SSTREAM
# include <sstream>
#else
# include <strstream>
#endif
namespace {
// In order to get ADL to find the comparison operators defined below, they have
struct mystring : std::string
{
typedef std::string base;
mystring(std::string const& x)
: base(x) {}
};
typedef std::vector<mystring> string_vector;
const std::size_t sequence_length = 1000;
unsigned random_number()
{
return static_cast<unsigned>(::rand()) % sequence_length;
}
# ifndef USE_SSTREAM
class unfreezer {
public:
unfreezer(std::ostrstream& s) : m_stream(s) {}
~unfreezer() { m_stream.freeze(false); }
private:
std::ostrstream& m_stream;
};
# endif
template <class T>
void push_back_random_number_string(T& seq)
{
unsigned value = random_number();
# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
std::ostringstream s;
s << value;
seq.push_back(s.str());
# else
std::ostrstream s;
auto unfreezer unfreeze(s);
s << value << char(0);
seq.push_back(std::string(s.str()));
# endif
}
inline unsigned to_int(unsigned x) { return x; }
inline unsigned to_int(const std::string& x) { return atoi(x.c_str()); }
struct cmp
{
template <class A1, class A2>
inline bool operator()(const A1& a1, const A2& a2) const
{
return to_int(a1) < to_int(a2);
}
};
inline bool operator<(const mystring& x, const unsigned y)
{
return to_int(x) < y;
}
inline bool operator<(const unsigned y, const mystring& x)
{
return y < to_int(x);
}
template <class T>
void sort_by_value(T& x);
template <class T>
void sort_by_value_(T& v, long)
{
std::sort(v.begin(), v.end(), cmp());
}
template <class T>
void random_sorted_sequence(T& seq)
{
seq.clear();
for (std::size_t i = 0; i < sequence_length; ++i)
{
push_back_random_number_string(seq);
}
sort_by_value(seq);
}
template <class T, class A>
void sort_by_value_(std::list<T,A>& l, int)
{
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) && !defined(__SGI_STL_PORT)
// VC6's standard lib doesn't have a template member function for list::sort()
std::vector<T> seq;
seq.reserve(sequence_length);
std::copy(l.begin(), l.end(), std::back_inserter(seq));
sort_by_value(seq);
std::copy(seq.begin(), seq.end(), l.begin());
# else
l.sort(cmp());
# endif
}
template <class T>
void sort_by_value(T& x)
{
(sort_by_value_)(x, 1);
}
// A way to select the comparisons with/without a Compare parameter for testing.
template <class Compare> struct searches
{
template <class Iterator, class Key>
static Iterator lower_bound(Iterator start, Iterator finish, Key key, Compare cmp)
{ return boost::detail::lower_bound(start, finish, key, cmp); }
template <class Iterator, class Key>
static Iterator upper_bound(Iterator start, Iterator finish, Key key, Compare cmp)
{ return boost::detail::upper_bound(start, finish, key, cmp); }
template <class Iterator, class Key>
static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, Compare cmp)
{ return boost::detail::equal_range(start, finish, key, cmp); }
template <class Iterator, class Key>
static bool binary_search(Iterator start, Iterator finish, Key key, Compare cmp)
{ return boost::detail::binary_search(start, finish, key, cmp); }
};
struct no_compare {};
template <> struct searches<no_compare>
{
template <class Iterator, class Key>
static Iterator lower_bound(Iterator start, Iterator finish, Key key, no_compare)
{ return boost::detail::lower_bound(start, finish, key); }
template <class Iterator, class Key>
static Iterator upper_bound(Iterator start, Iterator finish, Key key, no_compare)
{ return boost::detail::upper_bound(start, finish, key); }
template <class Iterator, class Key>
static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, no_compare)
{ return boost::detail::equal_range(start, finish, key); }
template <class Iterator, class Key>
static bool binary_search(Iterator start, Iterator finish, Key key, no_compare)
{ return boost::detail::binary_search(start, finish, key); }
};
template <class Sequence, class Compare>
void test_loop(Sequence& x, Compare cmp, unsigned long test_count)
{
typedef typename Sequence::const_iterator const_iterator;
for (unsigned long i = 0; i < test_count; ++i)
{
random_sorted_sequence(x);
const const_iterator start = x.begin();
const const_iterator finish = x.end();
unsigned key = random_number();
const const_iterator l = searches<Compare>::lower_bound(start, finish, key, cmp);
const const_iterator u = searches<Compare>::upper_bound(start, finish, key, cmp);
bool found_l = false;
bool found_u = false;
std::size_t index = 0;
std::size_t count = 0;
unsigned last_value = 0;
for (const_iterator p = start; p != finish; ++p)
{
if (p == l)
found_l = true;
if (p == u)
{
assert(found_l);
found_u = true;
}
unsigned value = to_int(*p);
assert(value >= last_value);
last_value = value;
if (!found_l)
{
++index;
assert(to_int(*p) < key);
}
else if (!found_u)
{
++count;
assert(to_int(*p) == key);
}
else
assert(to_int(*p) > key);
}
assert(found_l || l == finish);
assert(found_u || u == finish);
std::pair<const_iterator, const_iterator>
range = searches<Compare>::equal_range(start, finish, key, cmp);
assert(range.first == l);
assert(range.second == u);
bool found = searches<Compare>::binary_search(start, finish, key, cmp);
assert(found == (u != l));
std::cout << "found " << count << " copies of " << key << " at index " << index << "\n";
}
}
}
int main()
{
string_vector x;
std::cout << "=== testing random-access iterators with <: ===\n";
test_loop(x, no_compare(), 25);
std::cout << "=== testing random-access iterators with compare: ===\n";
test_loop(x, cmp(), 25);
std::list<mystring> y;
std::cout << "=== testing bidirectional iterators with <: ===\n";
test_loop(y, no_compare(), 25);
std::cout << "=== testing bidirectional iterators with compare: ===\n";
test_loop(y, cmp(), 25);
std::cerr << "******TEST PASSED******\n";
return 0;
}

View File

@ -210,8 +210,10 @@ int main()
comparible_UDT u;
c1(u);
call_traits_checker<int> c2;
call_traits_checker<enum_UDT> c2b;
int i = 2;
c2(i);
c2b(one);
int* pi = &i;
int a[2] = {1,2};
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
@ -292,7 +294,11 @@ int main()
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;
}

View File

@ -1,122 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Boost: checked_delete.hpp documentation</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
<table border="0" width="100%">
<tr>
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
</td>
<td align="center">
<h1>checked_delete.hpp</h1>
</td>
</tr>
<tr>
<td colspan="2" height="64">&nbsp;</td>
</tr>
</table>
<p>
The header <STRONG>&lt;boost/checked_delete.hpp&gt;</STRONG> defines two
function templates, <STRONG>checked_delete</STRONG> and <STRONG>checked_array_delete</STRONG>,
and two class templates, <STRONG>checked_deleter</STRONG> and <STRONG>checked_array_deleter</STRONG>.
</p>
<P>The C++ Standard allows, in 5.3.5/5, pointers to incomplete class types to be
deleted with a <EM>delete-expression</EM>. When the class has a non-trivial
destructor, or a class-specific operator delete, the behavior is undefined.
Some compilers issue a warning when an incomplete type is deleted, but
unfortunately, not all do, and programmers sometimes ignore or disable
warnings.</P>
<P>A particularly troublesome case is when a smart pointer's destructor, such as <STRONG>
boost::scoped_ptr&lt;T&gt;::~scoped_ptr</STRONG>, is instantiated with an
incomplete type. This can often lead to silent, hard to track failures.</P>
<P>The supplied function and class templates can be used to prevent these problems,
as they require a complete type, and cause a compilation error otherwise.</P>
<h3><a name="Synopsis">Synopsis</a></h3>
<pre>
namespace boost
{
template&lt;class T&gt; void checked_delete(T * p);
template&lt;class T&gt; void checked_array_delete(T * p);
template&lt;class T&gt; struct checked_deleter;
template&lt;class T&gt; struct checked_array_deleter;
}
</pre>
<h3>checked_delete</h3>
<h4><a name="checked_delete">template&lt;class T&gt; void checked_delete(T * p);</a></h4>
<blockquote>
<p>
<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete p</tt>
must be well-formed.
</p>
<p>
<b>Effects:</b> <tt>delete p;</tt>
</p>
</blockquote>
<h3>checked_array_delete</h3>
<h4><a name="checked_array_delete">template&lt;class T&gt; void checked_array_delete(T
* p);</a></h4>
<blockquote>
<p>
<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete [] p</tt>
must be well-formed.
</p>
<p>
<b>Effects:</b> <tt>delete [] p;</tt>
</p>
</blockquote>
<h3>checked_deleter</h3>
<pre>
template&lt;class T&gt; struct checked_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * p) const;
};
</pre>
<h4>void checked_deleter&lt;T&gt;::operator()(T * p) const;</h4>
<blockquote>
<p>
<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete p</tt>
must be well-formed.
</p>
<p>
<b>Effects:</b> <tt>delete p;</tt>
</p>
</blockquote>
<h3>checked_array_deleter</h3>
<pre>
template&lt;class T&gt; struct checked_array_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * p) const;
};
</pre>
<h4>void checked_array_deleter&lt;T&gt;::operator()(T * p) const;</h4>
<blockquote>
<p>
<b>Requires:</b> <b>T</b> must be a complete type. The expression <tt>delete [] p</tt>
must be well-formed.
</p>
<p>
<b>Effects:</b> <tt>delete [] p;</tt>
</p>
</blockquote>
<h3><a name="Acknowledgements">Acknowledgements</a></h3>
<p>
The function templates <STRONG>checked_delete</STRONG> and <STRONG>checked_array_delete</STRONG>
were originally part of <STRONG>&lt;boost/utility.hpp&gt;</STRONG>, and the
documentation acknowledged Beman Dawes, Dave Abrahams, Vladimir Prus, Rainer
Deyke, John Maddock, and others as contributors.
</p>
<p>
<br>
<small>Copyright <20> 2002 by Peter Dimov. 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>.</small></p>
</body>
<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,28 +0,0 @@
// Boost checked_delete test program ---------------------------------------//
// Copyright Beman Dawes 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 for documentation.
// Revision History
// 21 May 01 Initial version (Beman Dawes)
#include <boost/checked_delete.hpp> // for checked_delete
// This program demonstrates compiler errors when trying to delete an
// incomplete type.
namespace
{
class Incomplete;
}
int main()
{
Incomplete * p = 0;
boost::checked_delete(p); // should cause compile time error
boost::checked_array_delete(p); // should cause compile time error
return 0;
} // main

View File

@ -1,76 +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>
<title>Header </title>
<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 5.0">
<boostcompressed_pair.hpp>
</head>
<body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#800080">
<h2><img src="../../boost.png" width="276" height="86">Header &lt;<a href="../../boost/detail/compressed_pair.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 "empty base-class optimisation"
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);
compressed_pair&amp; operator=(const compressed_pair&amp;);
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 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.</P>
<p>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.</p>
<p>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.</p>
<h3>Acknowledgements</h3>
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and John
Maddock.</p>
<p>Maintained by <a href="mailto:john@johnmaddock.co.uk">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.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->07 November 2007<!--webbot bot="Timestamp" endspan i-checksum="40338" --></p>
<p><EFBFBD> Copyright Beman Dawes, 2000.</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>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/compressed_pair.html">
</head>
<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,36 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Boost: current_function.hpp documentation</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
<table border="0" width="100%">
<tr>
<td width="277"><A href="../../index.htm"> <img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86" border="0"></A>
</td>
<td align="center">
<h1>current_function.hpp</h1>
</td>
</tr>
<tr>
<td colspan="2" height="64">&nbsp;</td>
</tr>
</table>
<p>
The header <STRONG>&lt;boost/current_function.hpp&gt;</STRONG> defines a single
macro, <STRONG>BOOST_CURRENT_FUNCTION</STRONG>,<STRONG> </STRONG>similar to the
C99 predefined identifier <STRONG>__func__</STRONG>.
</p>
<P><STRONG>BOOST_CURRENT_FUNCTION</STRONG> expands to a string literal containing
the (fully qualified, if possible) name of the enclosing function. If there is
no enclosing function, the behavior is undefined.</P>
<p>Some compilers do not provide a way to obtain the name of the current enclosing
function. On such compilers, the string literal has an unspecified value.</p>
<p>
<br>
<small>Copyright <20> 2002 by Peter Dimov. 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>.</small></p>
</body>
</html>

View File

@ -1,40 +0,0 @@
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
//
// current_function_test.cpp - a test for boost/current_function.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// 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/current_function.hpp>
#include <boost/config.hpp>
#include <cstdio>
void message(char const * file, long line, char const * func, char const * msg)
{
#if !defined(BOOST_NO_STDC_NAMESPACE)
using std::printf;
#endif
printf("%s(%ld): %s in function '%s'\n", file, line, msg, func);
}
#define MESSAGE(msg) message(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, msg)
int main()
{
MESSAGE("assertion failed");
return 0;
}

View File

@ -6,7 +6,7 @@
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
@ -42,6 +42,44 @@ 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
:
@ -59,7 +97,6 @@ boostbook standalone_declval
<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 ;
@ -79,5 +116,12 @@ boostbook standalone_string_ref
<xsl:param>toc.max.depth=1
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=1
;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease :
standalone_base_from_member standalone_compressed_pair
standalone_declval standalone_string_ref ;
explicit boostrelease ;

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]

View File

@ -106,7 +106,6 @@ Declares a function template convert which only participates in overloading if t
Fixes:
* [@http://svn.boost.org/trac/boost/ticket/6570 #6570] Adding noexcept to boost::declval.
[endsect]

View File

@ -1,176 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Declval</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.0">
<link rel="home" href="declval.html" title="Declval">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav"></div>
<div class="article">
<div class="titlepage">
<div>
<div><h2 class="title">
<a name="declval"></a>Declval</h2></div>
<div><div class="authorgroup">
<div class="author"><h3 class="author">
<span class="firstname">Howard</span> <span class="surname">Hinnant</span>
</h3></div>
<div class="author"><h3 class="author">
<span class="firstname">Vicente J.</span> <span class="surname">Botet Escriba</span>
</h3></div>
</div></div>
<div><p class="copyright">Copyright &#169; 2008 Howard Hinnant</p></div>
<div><p class="copyright">Copyright &#169; 2009 -2012 Vicente J. Botet Escriba</p></div>
<div><div class="legalnotice">
<a name="idp13449552"></a><p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></div>
</div>
<hr>
</div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="section"><a href="declval.html#declval.overview">Overview</a></span></dt>
<dt><span class="section"><a href="declval.html#declval.reference">Reference </a></span></dt>
<dt><span class="section"><a href="declval.html#declval.history">History</a></span></dt>
</dl>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="declval.overview"></a><a class="link" href="declval.html#declval.overview" title="Overview">Overview</a>
</h2></div></div></div>
<p>
The motivation for <code class="computeroutput"><span class="identifier">declval</span></code>
was introduced in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value" target="_top">N2958:
Moving Swap Forward</a>. Here follows a rewording of this chapter.
</p>
<p>
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
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">// not used
</span></pre>
<p>
as part of the function template declaration
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">To</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">From</span><span class="special">&gt;</span>
<span class="identifier">decltype</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">To</span><span class="special">&gt;(</span><span class="identifier">declval</span><span class="special">&lt;</span><span class="identifier">From</span><span class="special">&gt;()))</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">From</span><span class="special">&amp;&amp;);</span>
</pre>
<p>
or as part of a class template definition
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span><span class="special">&gt;</span> <span class="keyword">class</span> <span class="identifier">result_of</span><span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">ArgTypes</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">result_of</span><span class="special">&lt;</span><span class="identifier">Fn</span><span class="special">(</span><span class="identifier">ArgTypes</span><span class="special">...)&gt;</span>
<span class="special">{</span>
<span class="keyword">typedef</span> <span class="identifier">decltype</span><span class="special">(</span><span class="identifier">declval</span><span class="special">&lt;</span><span class="identifier">Fn</span><span class="special">&gt;()(</span><span class="identifier">declval</span><span class="special">&lt;</span><span class="identifier">ArgTypes</span><span class="special">&gt;()...))</span> <span class="identifier">type</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
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 <code class="computeroutput"><span class="identifier">declval</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;()</span></code> 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
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">add_rvalue_reference</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">// not used
</span></pre>
<p>
which ensures that we can also use cv void as template parameter. The careful
reader might have noticed that <code class="computeroutput"><span class="identifier">declval</span><span class="special">()</span></code> 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.
</p>
<p>
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.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="declval.reference"></a><a class="link" href="declval.html#declval.reference" title="Reference">Reference </a>
</h2></div></div></div>
<p>
<code class="computeroutput"><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">declval</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">typename</span> <span class="identifier">add_rvalue_reference</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">()</span> <span class="identifier">noexcept</span><span class="special">;</span> <span class="comment">// as unevaluated operand
</span>
<span class="special">}</span> <span class="comment">// namespace boost
</span></pre>
<p>
The library provides the function template declval to simplify the definition
of expressions which occur as unevaluated operands.
</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">typename</span> <span class="identifier">add_rvalue_reference</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">();</span>
</pre>
<p>
<span class="bold"><strong>Remarks:</strong></span> If this function is used, the program
is ill-formed.
</p>
<p>
<span class="bold"><strong>Remarks:</strong></span> The template parameter T of declval
may be an incomplete type.
</p>
<p>
<span class="bold"><strong>Example:</strong></span>
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">To</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">From</span><span class="special">&gt;</span>
<span class="identifier">decltype</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">To</span><span class="special">&gt;(</span><span class="identifier">declval</span><span class="special">&lt;</span><span class="identifier">From</span><span class="special">&gt;()))</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">From</span><span class="special">&amp;&amp;);</span>
</pre>
<p>
Declares a function template convert which only participates in overloading
if the type From can be explicitly converted to type To.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="declval.history"></a><a class="link" href="declval.html#declval.history" title="History">History</a>
</h2></div></div></div>
<a name="declval.history.boost_1_50"></a><h4>
<a name="idp13553216"></a>
<a class="link" href="declval.html#declval.history.boost_1_50">boost 1.50</a>
</h4>
<p>
Fixes:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<a href="http://svn.boost.org/trac/boost/ticket/6570" target="_top">#6570</a>
Adding noexcept to boost::declval.
</li></ul></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: May 28, 2012 at 18:59:06 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
<div class="spirit-nav"></div>
</body>
</html>

View File

@ -1,280 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>String_Ref</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="string_ref.html" title="String_Ref">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav"></div>
<div class="article">
<div class="titlepage">
<div>
<div><h2 class="title">
<a name="string_ref"></a>String_Ref</h2></div>
<div><div class="authorgroup"><div class="author"><h3 class="author">
<span class="firstname">Marshall</span> <span class="surname">Clow</span>
</h3></div></div></div>
<div><p class="copyright">Copyright &#169; 2012 Marshall Clow</p></div>
<div><div class="legalnotice">
<a name="string_ref.legal"></a><p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></div>
</div>
<hr>
</div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="section"><a href="string_ref.html#string_ref.overview">Overview</a></span></dt>
<dt><span class="section"><a href="string_ref.html#string_ref.examples">Examples</a></span></dt>
<dt><span class="section"><a href="string_ref.html#string_ref.reference">Reference </a></span></dt>
<dt><span class="section"><a href="string_ref.html#string_ref.history">History</a></span></dt>
</dl>
</div>
<div class="section string_ref_overview">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="string_ref.overview"></a><a class="link" href="string_ref.html#string_ref.overview" title="Overview">Overview</a>
</h2></div></div></div>
<p>
Boost.StringRef is an implementation of Jeffrey Yaskin's <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html" target="_top">N3442:
string_ref: a non-owning reference to a string</a>.
</p>
<p>
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 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
but that has certain drawbacks:
</p>
<p>
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.
</p>
<p>
2) if a routine receives a constant <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
and wants to pass a portion of that string to another routine, then it must
create a new string of that substring.
</p>
<p>
3) A routine receives a constant <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
and wants to return a portion of the string, then it must create a new string
to return.
</p>
<p>
<code class="computeroutput"><span class="identifier">string_ref</span></code> is designed to solve
these efficiency problems. A <code class="computeroutput"><span class="identifier">string_ref</span></code>
is a read-only reference to a contiguous sequence of characters, and provides
much of the functionality of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
A <code class="computeroutput"><span class="identifier">string_ref</span></code> is cheap to create,
copy and pass by value, because it does not actually own the storage that it
points to.
</p>
<p>
A <code class="computeroutput"><span class="identifier">string_ref</span></code> is implemented
as a small struct that contains a pointer to the start of the character data
and a count. A <code class="computeroutput"><span class="identifier">string_ref</span></code> is
cheap to create and cheap to copy.
</p>
<p>
<code class="computeroutput"><span class="identifier">string_ref</span></code> acts as a container;
it includes all the methods that you would expect in a container, including
iteration support, <code class="computeroutput"><span class="keyword">operator</span> <span class="special">[]</span></code>,
<code class="computeroutput"><span class="identifier">at</span></code> and <code class="computeroutput"><span class="identifier">size</span></code>.
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 (<code class="computeroutput"><span class="identifier">sort</span></code>
and <code class="computeroutput"><span class="identifier">remove</span></code>, for example, will
not work)
</p>
<p>
Besides generic container functionality, <code class="computeroutput"><span class="identifier">string_ref</span></code>
provides a subset of the interface of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
This makes it easy to replace parameters of type <code class="computeroutput"><span class="keyword">const</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span></code>
with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span></code>. Like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
<code class="computeroutput"><span class="identifier">string_ref</span></code> has a static member
variable named <code class="computeroutput"><span class="identifier">npos</span></code> to denote
the result of failed searches, and to mean "the end".
</p>
<p>
Because a <code class="computeroutput"><span class="identifier">string_ref</span></code> 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 <code class="computeroutput"><span class="identifier">string_ref</span></code> refers to exists as long as the
<code class="computeroutput"><span class="identifier">string_ref</span></code> does.
</p>
</div>
<div class="section string_ref_examples">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="string_ref.examples"></a><a class="link" href="string_ref.html#string_ref.examples" title="Examples">Examples</a>
</h2></div></div></div>
<p>
Integrating <code class="computeroutput"><span class="identifier">string_ref</span></code> into
your code is fairly simple. Wherever you pass a <code class="computeroutput"><span class="keyword">const</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span></code>
or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> as a parameter, that's a candidate
for passing a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span></code>.
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span><span class="identifier">bar</span> <span class="special">)</span> <span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">bar</span><span class="special">.</span><span class="identifier">substr</span> <span class="special">(</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span> <span class="special">);</span>
<span class="special">}</span>
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="string">"ABCDEFG"</span> <span class="special">).</span><span class="identifier">front</span><span class="special">()</span> <span class="special">==</span> <span class="string">"C"</span> <span class="special">)</span> <span class="special">{</span> <span class="comment">/* do something */</span> <span class="special">}</span>
</pre>
<p>
Let's figure out what happens in this (contrived) example.
</p>
<p>
First, a temporary string is created from the string literal <code class="computeroutput"><span class="string">"ABCDEFG"</span></code>, and it is passed (by reference)
to the routine <code class="computeroutput"><span class="identifier">extract_part</span></code>.
Then a second string is created in the call <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">substr</span></code>
and returned to <code class="computeroutput"><span class="identifier">extract_part</span></code>
(this copy may be elided by RVO). Then <code class="computeroutput"><span class="identifier">extract_part</span></code>
returns that string back to the caller (again this copy may be elided). The
first temporary string is deallocated, and <code class="computeroutput"><span class="identifier">front</span></code>
is called on the second string, and then it is deallocated as well.
</p>
<p>
Two <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>s are created, and two copy operations.
That's (potentially) four memory allocations and deallocations, and the associated
copying of data.
</p>
<p>
Now let's look at the same code with <code class="computeroutput"><span class="identifier">string_ref</span></code>:
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span> <span class="identifier">bar</span> <span class="special">)</span> <span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">bar</span><span class="special">.</span><span class="identifier">substr</span> <span class="special">(</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span> <span class="special">);</span>
<span class="special">}</span>
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="string">"ABCDEFG"</span> <span class="special">).</span><span class="identifier">front</span><span class="special">()</span> <span class="special">==</span> <span class="string">"C"</span> <span class="special">)</span> <span class="special">{</span> <span class="comment">/* do something */</span> <span class="special">}</span>
</pre>
<p>
No memory allocations. No copying of character data. No changes to the code
other than the types. There are two <code class="computeroutput"><span class="identifier">string_ref</span></code>s
created, and two <code class="computeroutput"><span class="identifier">string_ref</span></code>s
copied, but those are cheap operations.
</p>
</div>
<div class="section string_ref_reference">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="string_ref.reference"></a><a class="link" href="string_ref.html#string_ref.reference" title="Reference">Reference </a>
</h2></div></div></div>
<p>
The header file "string_ref.hpp" defines a template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">basic_string_ref</span></code>,
and four specializations - for <code class="computeroutput"><span class="keyword">char</span></code>
/ <code class="computeroutput"><span class="keyword">wchar_t</span></code> / <code class="computeroutput"><span class="identifier">char16_t</span></code>
/ <code class="computeroutput"><span class="identifier">char32_t</span></code> .
</p>
<p>
<code class="computeroutput"><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">string_ref</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
</p>
<p>
Construction and copying:
</p>
<pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span> <span class="special">();</span> <span class="comment">// Constructs an empty string_ref</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// Constructs from a NULL-terminated string</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">str</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">len</span><span class="special">);</span> <span class="comment">// Constructs from a pointer, length pair</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
<span class="identifier">basic_string_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special">&lt;</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;&amp;</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// Constructs from a std::string</span>
<span class="identifier">basic_string_ref</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">basic_string_ref</span> <span class="special">&amp;</span><span class="identifier">rhs</span><span class="special">);</span>
<span class="identifier">basic_string_ref</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">basic_string_ref</span> <span class="special">&amp;</span><span class="identifier">rhs</span><span class="special">);</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">string_ref</span></code> does not define
a move constructor nor a move-assignment operator because copying a <code class="computeroutput"><span class="identifier">string_ref</span></code> is just a cheap as moving one.
</p>
<p>
Basic container-like functions:
</p>
<pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">length</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">max_size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">bool</span> <span class="identifier">empty</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="comment">// All iterators are const_iterators</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span> <span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span> <span class="identifier">cbegin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span> <span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span> <span class="identifier">cend</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">const_reverse_iterator</span> <span class="identifier">rbegin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">const_reverse_iterator</span> <span class="identifier">crbegin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">const_reverse_iterator</span> <span class="identifier">rend</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">const_reverse_iterator</span> <span class="identifier">crend</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
</pre>
<p>
Access to the individual elements (all of which are const):
</p>
<pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">size_type</span> <span class="identifier">pos</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&amp;</span> <span class="identifier">at</span><span class="special">(</span><span class="identifier">size_t</span> <span class="identifier">pos</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&amp;</span> <span class="identifier">front</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&amp;</span> <span class="identifier">back</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">data</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
</pre>
<p>
Modifying the <code class="computeroutput"><span class="identifier">string_ref</span></code> (but
not the underlying data):
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">clear</span><span class="special">();</span>
<span class="keyword">void</span> <span class="identifier">remove_prefix</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">);</span>
<span class="keyword">void</span> <span class="identifier">remove_suffix</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">);</span>
</pre>
<p>
Searching:
</p>
<pre class="programlisting"><span class="identifier">size_type</span> <span class="identifier">find</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">find</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">rfind</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">rfind</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">find_first_of</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">find_last_of</span> <span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">find_first_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">find_last_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">find_first_not_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">find_first_not_of</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">find_last_not_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="identifier">size_type</span> <span class="identifier">find_last_not_of</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
</pre>
<p>
String-like operations:
</p>
<pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span> <span class="identifier">substr</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">pos</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">=</span><span class="identifier">npos</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> <span class="comment">// Creates a new string_ref</span>
<span class="keyword">bool</span> <span class="identifier">starts_with</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">starts_with</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">ends_with</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
<span class="keyword">bool</span> <span class="identifier">ends_with</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
</pre>
</div>
<div class="section string_ref_history">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="string_ref.history"></a><a class="link" href="string_ref.html#string_ref.history" title="History">History</a>
</h2></div></div></div>
<h4>
<a name="string_ref.history.h0"></a>
<span><a name="string_ref.history.boost_1_53"></a></span><a class="link" href="string_ref.html#string_ref.history.boost_1_53">boost
1.53</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Introduced
</li></ul></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: January 14, 2013 at 16:24:14 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>
<div class="spirit-nav"></div>
</body>
</html>

View File

@ -1,464 +1,15 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD><TITLE>enable_if</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="Microsoft FrontPage 5.0">
</HEAD>
<BODY >
<!--HEVEA command line is: hevea -nosymb -noiso -pedantic -v enable_if_docs_for_boost.tex -->
<!--HTMLHEAD-->
<!--ENDHTML-->
<!--PREFIX <ARG ></ARG>-->
<!--CUT DEF section 1 -->
<BR>
<BR>
<h1>
<img border="0" src="../../boost.png" align="center" width="277" height="86">enable_if</h1>
<BR>
<BR>
Copyright 2003 Jaakko J&auml;rvi, Jeremiah Willcock, Andrew Lumsdaine.<BR>
Copyright 2011 Matt Calabrese.<BR>
<BR>
<!--TOC section Introduction-->
<H2><A NAME="htoc1">1</A>&nbsp;&nbsp;Introduction</H2><!--SEC END -->
<A NAME="introduction"></A>
The <TT>enable_if</TT> family of templates is a set of tools to allow a function template or a class template specialization
to include or exclude itself from a set of matching functions or specializations
based on properties of its template arguments.
For example, one can define function templates that
are only enabled for, and thus only match, an arbitrary set of types
defined by a traits class. The <TT>enable_if</TT> templates can also be
applied to enable class template specializations. Applications of
<TT>enable_if</TT> are discussed in length
in&nbsp;[<A HREF="#jarvi:03:cuj_arbitrary_overloading"><CITE>1</CITE></A>] and&nbsp;[<A HREF="#jarvi:03:c++typeclasses"><CITE>2</CITE></A>].<BR>
<BR>
<!--TOC subsection Synopsis-->
<H3><A NAME="htoc2">1.1</A>&nbsp;&nbsp;Synopsis</H3><!--SEC END -->
<A NAME="sec:synopsis"></A>
<PRE>namespace boost {
template &lt;class Cond, class T = void&gt; struct enable_if;
template &lt;class Cond, class T = void&gt; struct disable_if;
template &lt;class Cond, class T&gt; struct lazy_enable_if;
template &lt;class Cond, class T&gt; struct lazy_disable_if;
template &lt;bool B, class T = void&gt; struct enable_if_c;
template &lt;bool B, class T = void&gt; struct disable_if_c;
template &lt;bool B, class T&gt; struct lazy_enable_if_c;
template &lt;bool B, class T&gt; struct lazy_disable_if_c;
}
</PRE>
<!--TOC subsection Background-->
<H3><A NAME="htoc3">1.2</A>&nbsp;&nbsp;Background</H3><!--SEC END -->
<A NAME="sec:background"></A>
Sensible operation of template function overloading in C++ relies
on the <EM>SFINAE</EM> (substitution-failure-is-not-an-error)
principle&nbsp;[<A HREF="#vandevoorde2002:templates"><CITE>3</CITE></A>]: if an invalid argument
or return type is formed during the instantiation of a function
template, the instantiation is removed from the overload resolution
set instead of causing a compilation error. The following example,
taken from&nbsp;[<A HREF="#jarvi:03:cuj_arbitrary_overloading"><CITE>1</CITE></A>],
demonstrates why this is important:
<PRE>int negate(int i) { return -i; }
template &lt;class F&gt;
typename F::result_type negate(const F&amp; f) { return -f(); }
</PRE>
Suppose the compiler encounters the call <TT>negate(1)</TT>. The first
definition is obviously a better match, but the compiler must
nevertheless consider (and instantiate the prototypes) of both
definitions to find this out. Instantiating the latter definition with
<TT>F</TT> as <TT>int</TT> would result in:
<PRE>int::result_type negate(const int&amp;);
</PRE>
where the return type is invalid. If this were an error, adding an unrelated function template
(that was never called) could break otherwise valid code.
Due to the SFINAE principle the above example is not, however, erroneous.
The latter definition of <TT>negate</TT> is simply removed from the overload resolution set.<BR>
<BR>
The <TT>enable_if</TT> templates are tools for controlled creation of the SFINAE
conditions.<BR>
<BR>
<!--TOC section The <TT>enable_if</TT> templates-->
<H2><A NAME="htoc4">2</A>&nbsp;&nbsp;The <TT>enable_if</TT> templates</H2><!--SEC END -->
<A NAME="enable_if"></A>
The names of the <TT>enable_if</TT> templates have three parts: an optional <TT>lazy_</TT> tag,
either <TT>enable_if</TT> or <TT>disable_if</TT>, and an optional <TT>_c</TT> tag.
All eight combinations of these parts are supported.
The meaning of the <TT>lazy_</TT> tag is described in Section&nbsp;<A HREF="#sec:enable_if_lazy">3.3</A>.
The second part of the name indicates whether a true condition argument should
enable or disable the current overload.
The third part of the name indicates whether the condition argument is a <TT>bool</TT> value
(<TT>_c</TT> suffix), or a type containing a static <TT>bool</TT> constant named <TT>value</TT> (no suffix).
The latter version interoperates with Boost.MPL. <BR>
<BR>
The definitions of <TT>enable_if_c</TT> and <TT>enable_if</TT> are as follows (we use <TT>enable_if</TT> templates
unqualified but they are in the <TT>boost</TT> namespace).
<PRE>template &lt;bool B, class T = void&gt;
struct enable_if_c {
typedef T type;
};
template &lt;class T&gt;
struct enable_if_c&lt;false, T&gt; {};
template &lt;class Cond, class T = void&gt;
struct enable_if : public enable_if_c&lt;Cond::value, T&gt; {};
</PRE>
An instantiation of the <TT>enable_if_c</TT> template with the parameter
<TT>B</TT> as <TT>true</TT> contains a member type <TT>type</TT>, defined
to be <TT>T</TT>. If <TT>B</TT> is
<TT>false</TT>, no such member is defined. Thus
<TT>enable_if_c&lt;B, T&gt;::type</TT> is either a valid or an invalid type
expression, depending on the value of <TT>B</TT>.
When valid, <TT>enable_if_c&lt;B, T&gt;::type</TT> equals <TT>T</TT>.
The <TT>enable_if_c</TT> template can thus be used for controlling when functions are considered for
overload resolution and when they are not.
For example, the following function is defined for all arithmetic types (according to the
classification of the <A HREF="../type_traits/index.html">Boost type_traits library</A>):
<PRE>template &lt;class T&gt;
typename enable_if_c&lt;boost::is_arithmetic&lt;T&gt;::value, T&gt;::type
foo(T t) { return t; }
</PRE>
The <TT>disable_if_c</TT> template is provided as well, and has the
same functionality as <TT>enable_if_c</TT> except for the negated condition. The following
function is enabled for all non-arithmetic types.
<PRE>template &lt;class T&gt;
typename disable_if_c&lt;boost::is_arithmetic&lt;T&gt;::value, T&gt;::type
bar(T t) { return t; }
</PRE>
For easier syntax in some cases and interoperation with Boost.MPL we provide versions of
the <TT>enable_if</TT> templates taking any type with a <TT>bool</TT> member constant named
<TT>value</TT> as the condition argument.
The MPL <TT>bool_</TT>, <TT>and_</TT>, <TT>or_</TT>, and <TT>not_</TT> templates are likely to be
useful for creating such types. Also, the traits classes in the Boost.Type_traits library
follow this convention.
For example, the above example function <TT>foo</TT> can be alternatively written as:
<PRE>template &lt;class T&gt;
typename enable_if&lt;boost::is_arithmetic&lt;T&gt;, T&gt;::type
foo(T t) { return t; }
</PRE>
<!--TOC section Using <TT>enable_if</TT>-->
<H2><A NAME="htoc5">3</A>&nbsp;&nbsp;Using <TT>enable_if</TT></H2><!--SEC END -->
<A NAME="sec:using_enable_if"></A>
The <TT>enable_if</TT> templates are defined in
<TT>boost/utility/enable_if.hpp</TT>, which is included by <TT>boost/utility.hpp</TT>.<BR>
<BR>
With respect to function templates, <TT>enable_if</TT> can be used in multiple different ways:
<UL>
<LI>As the return type of an instantiatied function
<LI>As an extra parameter of an instantiated function
<LI>As an extra template parameter (useful only in a compiler that supports C++0x default
arguments for function template parameters, see <A href="#sec:enable_if_0x">Enabling function
templates in C++0x</a> for details)
</UL>
In the previous section, the return type form of <TT>enable_if</TT> was shown. As an example
of using the form of <TT>enable_if</TT> that works via an extra function parameter, the
<TT>foo</TT> function in the previous section could also be written
as:
<PRE>template &lt;class T&gt;
T foo(T t, typename enable_if&lt;boost::is_arithmetic&lt;T&gt; &gt;::type* dummy = 0);
</PRE>Hence, an extra parameter of type <TT>void*</TT> is added, but it is given
a default value to keep the parameter hidden from client code.
Note that the second template argument was not given to <TT>enable_if</TT>, as the default
<TT>void</TT> gives the desired behavior.<BR>
<BR>
Which way to write the enabler is largely a matter of taste, but for certain functions, only a
subset of the options is possible:
<UL><LI>
Many operators have a fixed number of arguments, thus <TT>enable_if</TT> must be used either in the
return type or in an extra template parameter.
<LI>Functions that have a variadic parameter list must use either the return type form or an extra
template parameter.
<LI>Constructors do not have a return type so you must use either an extra function parameter or an
extra template parameter.
<LI>Constructors that have a variadic parameter list must an extra template parameter.
<LI>Conversion operators can only be written with an extra template parameter.
</UL>
<!--TOC subsection Enabling function templates in C++0x-->
<A NAME="sec:enable_if_0x"></A>
<H3><A NAME="htoc7">3.1</A>&nbsp;&nbsp;Enabling function templates in C++0x</H3><!--SEC END -->
In a compiler which supports C++0x default arguments for function template parameters, you can
enable and disable function templates by adding an additional template parameter. This approach
works in all situations where you would use either the return type form of <TT>enable_if</TT> or
the function parameter form, including operators, constructors, variadic function templates, and
even overloaded conversion operations.
As an example:
<PRE>#include &lt;boost/type_traits/is_arithmetic.hpp&gt;
#include &lt;boost/type_traits/is_pointer.hpp&gt;
#include &lt;boost/utility/enable_if.hpp&gt;
class test
{
public:
// A constructor that works for any argument list of size 10
template&lt; class... T
, typename boost::enable_if_c&lt; sizeof...( T ) == 10, int &gt;::type = 0
&gt;
test( T&amp;&amp;... );
// A conversion operation that can convert to any arithmetic type
template&lt; class T
, typename boost::enable_if&lt; boost::is_arithmetic&lt; T &gt;, int &gt;::type = 0
&gt;
operator T() const;
// A conversion operation that can convert to any pointer type
template&lt; class T
, typename boost::enable_if&lt; boost::is_pointer&lt; T &gt;, int &gt;::type = 0
&gt;
operator T() const;
};
int main()
{
// Works
test test_( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 );
// Fails as expected
test fail_construction( 1, 2, 3, 4, 5 );
// Works by calling the conversion operator enabled for arithmetic types
int arithmetic_object = test_;
// Works by calling the conversion operator enabled for pointer types
int* pointer_object = test_;
// Fails as expected
struct {} fail_conversion = test_;
}
</PRE>
<!--TOC subsection Enabling template class specializations-->
<H3><A NAME="htoc7">3.2</A>&nbsp;&nbsp;Enabling template class specializations</H3><!--SEC END -->
<A NAME="sec:enable_if_classes"></A>
Class template specializations can be enabled or disabled with <TT>enable_if</TT>.
One extra template parameter needs to be added for the enabler expressions.
This parameter has the default value <TT>void</TT>.
For example:
<PRE>template &lt;class T, class Enable = void&gt;
class A { ... };
template &lt;class T&gt;
class A&lt;T, typename enable_if&lt;is_integral&lt;T&gt; &gt;::type&gt; { ... };
template &lt;class T&gt;
class A&lt;T, typename enable_if&lt;is_float&lt;T&gt; &gt;::type&gt; { ... };
</PRE>Instantiating <TT>A</TT> with any integral type matches the first specialization,
whereas any floating point type matches the second one. All other types
match the primary template.
The condition can be any compile-time boolean expression that depends on the
template arguments of the class.
Note that again, the second argument to <TT>enable_if</TT> is not needed; the default (<TT>void</TT>)
is the correct value.<BR>
<BR>
<!--TOC subsection Overlapping enabler conditions-->
<H3><A NAME="htoc8">3.3</A>&nbsp;&nbsp;Overlapping enabler conditions</H3><!--SEC END -->
<A NAME="sec:overlapping_conditions"></A>
Once the compiler has examined the enabling conditions and included the
function into the overload resolution set, normal C++ overload resolution
rules are used to select the best matching function.
In particular, there is no ordering between enabling conditions.
Function templates with enabling conditions that are not mutually exclusive can
lead to ambiguities. For example:
<PRE>template &lt;class T&gt;
typename enable_if&lt;boost::is_integral&lt;T&gt;, void&gt;::type
foo(T t) {}
template &lt;class T&gt;
typename enable_if&lt;boost::is_arithmetic&lt;T&gt;, void&gt;::type
foo(T t) {}
</PRE>
All integral types are also arithmetic. Therefore, say, for the call <TT>foo(1)</TT>,
both conditions are true and both functions are thus in the overload resolution set.
They are both equally good matches and thus ambiguous.
Of course, more than one enabling condition can be simultaneously true as long as
other arguments disambiguate the functions.<BR>
<BR>
The above discussion applies to using <TT>enable_if</TT> in class template
partial specializations as well.<BR>
<BR>
<!--TOC subsection Lazy <TT>enable_if</TT>-->
<H3><A NAME="htoc9">3.4</A>&nbsp;&nbsp;Lazy <TT>enable_if</TT></H3><!--SEC END -->
<A NAME="sec:enable_if_lazy"></A>
In some cases it is necessary to avoid instantiating part of a
function signature unless an enabling condition is true. For example:
<PRE>template &lt;class T, class U&gt; class mult_traits;
template &lt;class T, class U&gt;
typename enable_if&lt;is_multipliable&lt;T, U&gt;, typename mult_traits&lt;T, U&gt;::type&gt;::type
operator*(const T&amp; t, const U&amp; u) { ... }
</PRE>Assume the class template <TT>mult_traits</TT> is a traits class defining
the resulting type of a multiplication operator. The <TT>is_multipliable</TT> traits
class specifies for which types to enable the operator. Whenever
<TT>is_multipliable&lt;A, B&gt;::value</TT> is <TT>true</TT> for some types <TT>A</TT> and <TT>B</TT>,
then <TT>mult_traits&lt;A, B&gt;::type</TT> is defined.<BR>
<BR>
Now, trying to invoke (some other overload) of <TT>operator*</TT> with, say, operand types <TT>C</TT> and <TT>D</TT>
for which <TT>is_multipliable&lt;C, D&gt;::value</TT> is <TT>false</TT>
and <TT>mult_traits&lt;C, D&gt;::type</TT> is not defined is an error on some compilers.
The SFINAE principle is not applied because
the invalid type occurs as an argument to another template. The <TT>lazy_enable_if</TT>
and <TT>lazy_disable_if</TT> templates (and their <TT>_c</TT> versions) can be used in such
situations:
<PRE>template&lt;class T, class U&gt;
typename lazy_enable_if&lt;is_multipliable&lt;T, U&gt;, mult_traits&lt;T, U&gt; &gt;::type
operator*(const T&amp; t, const U&amp; u) { ... }
</PRE>The second argument of <TT>lazy_enable_if</TT> must be a class type
that defines a nested type named <TT>type</TT> whenever the first
parameter (the condition) is true.<BR>
<BR>
<!--TOC paragraph Note-->
<H5>Note</H5><!--SEC END -->
Referring to one member type or static constant in a traits class
causes all of the members (type and static constant) of that
specialization to be instantiated. Therefore, if your traits classes
can sometimes contain invalid types, you should use two distinct
templates for describing the conditions and the type mappings. In the
above example, <TT>is_multipliable&lt;T, U&gt;::value</TT> defines when
<TT>mult_traits&lt;T, U&gt;::type</TT> is valid.<BR>
<BR>
<!--TOC subsection Compiler workarounds-->
<H3><A NAME="htoc10">3.5</A>&nbsp;&nbsp;Compiler workarounds</H3><!--SEC END -->
<A NAME="sec:workarounds"></A>
Some compilers flag functions as ambiguous if the only distinguishing factor is a different
condition in an enabler (even though the functions could never be ambiguous). For example,
some compilers (e.g. GCC 3.2) diagnose the following two functions as ambiguous:
<PRE>template &lt;class T&gt;
typename enable_if&lt;boost::is_arithmetic&lt;T&gt;, T&gt;::type
foo(T t);
template &lt;class T&gt;
typename disable_if&lt;boost::is_arithmetic&lt;T&gt;, T&gt;::type
foo(T t);
</PRE>Two workarounds can be applied:
<UL><LI>
Use an extra dummy parameter which disambiguates the functions. Use a default value for
it to hide the parameter from the caller. For example:
<PRE>template &lt;int&gt; struct dummy { dummy(int) {} };
template &lt;class T&gt;
typename enable_if&lt;boost::is_arithmetic&lt;T&gt;, T&gt;::type
foo(T t, dummy&lt;0&gt; = 0);
template &lt;class T&gt;
typename disable_if&lt;boost::is_arithmetic&lt;T&gt;, T&gt;::type
foo(T t, dummy&lt;1&gt; = 0);
</PRE><BR>
<BR>
<LI>Define the functions in different namespaces and bring them into a common
namespace with <TT>using</TT> declarations:
<PRE>namespace A {
template &lt;class T&gt;
typename enable_if&lt;boost::is_arithmetic&lt;T&gt;, T&gt;::type
foo(T t);
}
namespace B {
template &lt;class T&gt;
typename disable_if&lt;boost::is_arithmetic&lt;T&gt;, T&gt;::type
foo(T t);
}
using A::foo;
using B::foo;
</PRE>
Note that the second workaround above cannot be used for member
templates. On the other hand, operators do not accept extra arguments,
which makes the first workaround unusable. As the net effect,
neither of the workarounds are of assistance for templated operators that
need to be defined as member functions (assignment and
subscript operators).
</UL>
<!--TOC section Acknowledgements-->
<H2><A NAME="htoc10">4</A>&nbsp;&nbsp;Acknowledgements</H2><!--SEC END -->
We are grateful to Howard Hinnant, Jason Shirk, Paul Mensonides, and Richard
Smith whose findings have influenced the library.<BR>
<BR>
<!--TOC section References-->
<H2>References</H2><!--SEC END -->
<DL COMPACT=compact><DT><A NAME="jarvi:03:cuj_arbitrary_overloading"><FONT COLOR=purple>[1]</FONT></A><DD>
Jaakko J&auml;rvi, Jeremiah Willcock, Howard Hinnant, and Andrew Lumsdaine.
Function overloading based on arbitrary properties of types.
<EM>C/C++ Users Journal</EM>, 21(6):25--32, June 2003.<BR>
<BR>
<DT><A NAME="jarvi:03:c++typeclasses"><FONT COLOR=purple>[2]</FONT></A><DD>
Jaakko J&auml;rvi, Jeremiah Willcock, and Andrew Lumsdaine.
Concept-controlled polymorphism.
In Frank Pfennig and Yannis Smaragdakis, editors, <EM>Generative
Programming and Component Engineering</EM>, volume 2830 of <EM>LNCS</EM>, pages
228--244. Springer Verlag, September 2003.<BR>
<BR>
<DT><A NAME="vandevoorde2002:templates"><FONT COLOR=purple>[3]</FONT></A><DD>
David Vandevoorde and Nicolai&nbsp;M. Josuttis.
<EM>C++ Templates: The Complete Guide</EM>.
Addison-Wesley, 2002.</DL>
<hr/>
<p>Copyright Jaakko J&auml;rvi<sup>*</sup>, Jeremiah Willcock<sup>*</sup>, Andrew Lumsdaine<sup>*</sup>, Matt Calabrese<BR>
<EM>{jajarvi|jewillco|lums}@osl.iu.edu, rivorus@gmail.com</EM><BR>
<sup>*</sup>Indiana University<BR>
Open Systems Lab<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>
<!--HTMLFOOT-->
<!--ENDHTML-->
<!--FOOTER-->
<HR SIZE=2>
<BLOCKQUOTE><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
</EM><A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html"><EM>H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A</EM></A><EM>.
</EM></BLOCKQUOTE>
</BODY>
</HTML>
<!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>

View File

@ -1,23 +0,0 @@
# Copyright David Abrahams 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)
# For more information, see http://www.boost.org/
project
: requirements <library>/boost/test//boost_test_exec_monitor
;
test-suite utility/enable_if
:
[ run constructors.cpp ]
[ run dummy_arg_disambiguation.cpp ]
[ run lazy.cpp ]
[ run lazy_test.cpp ]
[ run member_templates.cpp ]
[ run namespace_disambiguation.cpp ]
[ run no_disambiguation.cpp ]
[ run partial_specializations.cpp ]
;

View File

@ -1,62 +0,0 @@
// Boost enable_if library
// Copyright 2003 (c) 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)
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
// Jeremiah Willcock (jewillco at osl.iu.edu)
// Andrew Lumsdaine (lums at osl.iu.edu)
#include <boost/test/minimal.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
using boost::enable_if;
using boost::disable_if;
using boost::is_arithmetic;
struct container {
bool my_value;
template <class T>
container(const T&, const typename enable_if<is_arithmetic<T>, T>::type * = 0):
my_value(true) {}
template <class T>
container(const T&, const typename disable_if<is_arithmetic<T>, T>::type * = 0):
my_value(false) {}
};
// example from Howard Hinnant (tests enable_if template members of a templated class)
template <class charT>
struct xstring
{
template <class It>
xstring(It begin, It end, typename
disable_if<is_arithmetic<It> >::type* = 0)
: data(end-begin) {}
int data;
};
int test_main(int, char*[])
{
BOOST_CHECK(container(1).my_value);
BOOST_CHECK(container(1.0).my_value);
BOOST_CHECK(!container("1").my_value);
BOOST_CHECK(!container(static_cast<void*>(0)).my_value);
char sa[] = "123456";
BOOST_CHECK(xstring<char>(sa, sa+6).data == 6);
return 0;
}

View File

@ -1,46 +0,0 @@
// Boost enable_if library
// Copyright 2003 (c) 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)
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
// Jeremiah Willcock (jewillco at osl.iu.edu)
// Andrew Lumsdaine (lums at osl.iu.edu)
#include <boost/test/minimal.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
using boost::enable_if;
using boost::disable_if;
using boost::is_arithmetic;
template <int N> struct dummy {
dummy(int) {};
};
template<class T>
typename enable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t, dummy<0> = 0) { return true; }
template<class T>
typename disable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t, dummy<1> = 0) { return false; }
int test_main(int, char*[])
{
BOOST_CHECK(arithmetic_object(1));
BOOST_CHECK(arithmetic_object(1.0));
BOOST_CHECK(!arithmetic_object("1"));
BOOST_CHECK(!arithmetic_object(static_cast<void*>(0)));
return 0;
}

View File

@ -1,82 +0,0 @@
// Boost enable_if library
// Copyright 2003 (c) 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)
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
// Jeremiah Willcock (jewillco at osl.iu.edu)
// Andrew Lumsdaine (lums at osl.iu.edu)
#include <boost/test/minimal.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
using boost::enable_if_c;
using boost::lazy_enable_if_c;
// This class provides a reduced example of a traits class for
// computing the result of multiplying two types. The member typedef
// 'type' in this traits class defines the return type of this
// operator. The return type member is invalid unless both arguments
// for mult_traits are values that mult_traits expects (ints in this
// case). This kind of situation may arise if a traits class only
// makes sense for some set of types, not all C++ types.
template <class T> struct is_int {
BOOST_STATIC_CONSTANT(bool, value = (boost::is_same<T, int>::value));
};
template <class T, class U>
struct mult_traits {
typedef typename T::does_not_exist type;
};
template <>
struct mult_traits<int, int> {
typedef int type;
};
// Next, a forwarding function mult() is defined. It is enabled only
// when both arguments are of type int. The first version, using
// non-lazy enable_if_c does not work.
#if 0
template <class T, class U>
typename enable_if_c<
is_int<T>::value && is_int<U>::value,
typename mult_traits<T, U>::type
>::type
mult(const T& x, const U& y) {return x * y;}
#endif
// A correct version uses lazy_enable_if_c.
// This template removes compiler errors from invalid code used as an
// argument to enable_if_c.
#if 1
template <class T, class U>
typename lazy_enable_if_c<
is_int<T>::value & is_int<U>::value,
mult_traits<T, U>
>::type
mult(const T& x, const U& y) {return x * y;}
#endif
double mult(int i, double d) { return (double)i * d; }
int test_main(int, char*[])
{
BOOST_CHECK(mult(1, 2) == 2);
BOOST_CHECK(mult(1, 3.0) == 3.0);
return 0;
}

View File

@ -1,100 +0,0 @@
// Boost enable_if library
// Copyright 2003 (c) 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)
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
// Jeremiah Willcock (jewillco at osl.iu.edu)
// Andrew Lumsdaine (lums at osl.iu.edu)
// Testing all variations of lazy_enable_if.
#include <boost/test/minimal.hpp>
#include <boost/mpl/not.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
using boost::lazy_enable_if;
using boost::lazy_disable_if;
using boost::lazy_enable_if_c;
using boost::lazy_disable_if_c;
template <class T>
struct is_int_or_double {
BOOST_STATIC_CONSTANT(bool,
value = (boost::is_same<T, int>::value ||
boost::is_same<T, double>::value));
};
template <class T>
struct some_traits {
typedef typename T::does_not_exist type;
};
template <>
struct some_traits<int> {
typedef bool type;
};
template <>
struct some_traits<double> {
typedef bool type;
};
template <class T>
struct make_bool {
typedef bool type;
};
template <>
struct make_bool<int> {};
template <>
struct make_bool<double> {};
namespace A {
template<class T>
typename lazy_enable_if<is_int_or_double<T>, some_traits<T> >::type
foo(T t) { return true; }
template<class T>
typename lazy_enable_if_c<is_int_or_double<T>::value, some_traits<T> >::type
foo2(T t) { return true; }
}
namespace B {
template<class T>
typename lazy_disable_if<is_int_or_double<T>, make_bool<T> >::type
foo(T t) { return false; }
template<class T>
typename lazy_disable_if_c<is_int_or_double<T>::value, make_bool<T> >::type
foo2(T t) { return false; }
}
int test_main(int, char*[])
{
using namespace A;
using namespace B;
BOOST_CHECK(foo(1));
BOOST_CHECK(foo(1.0));
BOOST_CHECK(!foo("1"));
BOOST_CHECK(!foo(static_cast<void*>(0)));
BOOST_CHECK(foo2(1));
BOOST_CHECK(foo2(1.0));
BOOST_CHECK(!foo2("1"));
BOOST_CHECK(!foo2(static_cast<void*>(0)));
return 0;
}

View File

@ -1,43 +0,0 @@
// Boost enable_if library
// Copyright 2003 (c) 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)
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
// Jeremiah Willcock (jewillco at osl.iu.edu)
// Andrew Lumsdaine (lums at osl.iu.edu)
#include <boost/test/minimal.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
using boost::enable_if;
using boost::disable_if;
using boost::is_arithmetic;
struct container {
template <class T>
typename enable_if<is_arithmetic<T>, bool>::type
arithmetic_object(const T&, const int* /* disambiguate */ = 0) {return true;}
template <class T>
typename disable_if<is_arithmetic<T>, bool>::type
arithmetic_object(const T&) {return false;}
};
int test_main(int, char*[])
{
BOOST_CHECK(container().arithmetic_object(1));
BOOST_CHECK(container().arithmetic_object(1.0));
BOOST_CHECK(!container().arithmetic_object("1"));
BOOST_CHECK(!container().arithmetic_object(static_cast<void*>(0)));
return 0;
}

View File

@ -1,47 +0,0 @@
// Boost enable_if library
// Copyright 2003 (c) 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)
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
// Jeremiah Willcock (jewillco at osl.iu.edu)
// Andrew Lumsdaine (lums at osl.iu.edu)
#include <boost/test/minimal.hpp>
#include <boost/mpl/not.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
using boost::enable_if;
using boost::mpl::not_;
using boost::is_arithmetic;
namespace A {
template<class T>
typename enable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t) { return true; }
}
namespace B {
template<class T>
typename enable_if<not_<is_arithmetic<T> >, bool>::type
arithmetic_object(T t) { return false; }
}
int test_main(int, char*[])
{
using namespace A;
using namespace B;
BOOST_CHECK(arithmetic_object(1));
BOOST_CHECK(arithmetic_object(1.0));
BOOST_CHECK(!arithmetic_object("1"));
BOOST_CHECK(!arithmetic_object(static_cast<void*>(0)));
return 0;
}

View File

@ -1,43 +0,0 @@
// Boost enable_if library
// Copyright 2003 (c) 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)
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
// Jeremiah Willcock (jewillco at osl.iu.edu)
// Andrew Lumsdaine (lums at osl.iu.edu)
#include <boost/test/minimal.hpp>
#include <boost/mpl/not.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
using boost::mpl::not_;
using boost::enable_if;
using boost::is_arithmetic;
template<class T>
typename enable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t) { return true; }
template<class T>
typename enable_if<not_<is_arithmetic<T> >, bool>::type
arithmetic_object(T t) { return false; }
int test_main(int, char*[])
{
BOOST_CHECK(arithmetic_object(1));
BOOST_CHECK(arithmetic_object(1.0));
BOOST_CHECK(!arithmetic_object("1"));
BOOST_CHECK(!arithmetic_object(static_cast<void*>(0)));
return 0;
}

View File

@ -1,67 +0,0 @@
// Boost enable_if library
// Copyright 2003 (c) 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)
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
// Jeremiah Willcock (jewillco at osl.iu.edu)
// Andrew Lumsdaine (lums at osl.iu.edu)
#include <boost/test/minimal.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
using boost::enable_if_c;
using boost::disable_if_c;
using boost::enable_if;
using boost::disable_if;
using boost::is_arithmetic;
template <class T, class Enable = void>
struct tester;
template <class T>
struct tester<T, typename enable_if_c<is_arithmetic<T>::value>::type> {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct tester<T, typename disable_if_c<is_arithmetic<T>::value>::type> {
BOOST_STATIC_CONSTANT(bool, value = false);
};
template <class T, class Enable = void>
struct tester2;
template <class T>
struct tester2<T, typename enable_if<is_arithmetic<T> >::type> {
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class T>
struct tester2<T, typename disable_if<is_arithmetic<T> >::type> {
BOOST_STATIC_CONSTANT(bool, value = false);
};
int test_main(int, char*[])
{
BOOST_CHECK(tester<int>::value);
BOOST_CHECK(tester<double>::value);
BOOST_CHECK(!tester<char*>::value);
BOOST_CHECK(!tester<void*>::value);
BOOST_CHECK(tester2<int>::value);
BOOST_CHECK(tester2<double>::value);
BOOST_CHECK(!tester2<char*>::value);
BOOST_CHECK(!tester2<void*>::value);
return 0;
}

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

@ -1,136 +0,0 @@
//
// boost/assert.hpp - BOOST_ASSERT(expr)
// BOOST_ASSERT_MSG(expr, msg)
// BOOST_VERIFY(expr)
//
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2007 Peter Dimov
// Copyright (c) Beman Dawes 2011
//
// 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)
//
// Note: There are no include guards. This is intentional.
//
// See http://www.boost.org/libs/utility/assert.html for documentation.
//
//
// Stop inspect complaining about use of 'assert':
//
// boostinspect:naassert_macro
//
//--------------------------------------------------------------------------------------//
// BOOST_ASSERT //
//--------------------------------------------------------------------------------------//
#undef BOOST_ASSERT
#if defined(BOOST_DISABLE_ASSERTS)
# define BOOST_ASSERT(expr) ((void)0)
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
#include <boost/current_function.hpp>
namespace boost
{
void assertion_failed(char const * expr,
char const * function, char const * file, long line); // user defined
} // namespace boost
#define BOOST_ASSERT(expr) ((expr) \
? ((void)0) \
: ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
#else
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
# define BOOST_ASSERT(expr) assert(expr)
#endif
//--------------------------------------------------------------------------------------//
// BOOST_ASSERT_MSG //
//--------------------------------------------------------------------------------------//
# undef BOOST_ASSERT_MSG
#if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG)
#define BOOST_ASSERT_MSG(expr, msg) ((void)0)
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
#include <boost/current_function.hpp>
namespace boost
{
void assertion_failed_msg(char const * expr, char const * msg,
char const * function, char const * file, long line); // user defined
} // namespace boost
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
? ((void)0) \
: ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
#else
#ifndef BOOST_ASSERT_HPP
#define BOOST_ASSERT_HPP
#include <cstdlib>
#include <iostream>
#include <boost/current_function.hpp>
// IDE's like Visual Studio perform better if output goes to std::cout or
// some other stream, so allow user to configure output stream:
#ifndef BOOST_ASSERT_MSG_OSTREAM
# define BOOST_ASSERT_MSG_OSTREAM std::cerr
#endif
namespace boost
{
namespace assertion
{
namespace detail
{
inline void assertion_failed_msg(char const * expr, char const * msg, char const * function,
char const * file, long line)
{
BOOST_ASSERT_MSG_OSTREAM
<< "***** Internal Program Error - assertion (" << expr << ") failed in "
<< function << ":\n"
<< file << '(' << line << "): " << msg << std::endl;
#ifdef UNDER_CE
// The Windows CE CRT library does not have abort() so use exit(-1) instead.
std::exit(-1);
#else
std::abort();
#endif
}
} // detail
} // assertion
} // detail
#endif
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
? ((void)0) \
: ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \
BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
#endif
//--------------------------------------------------------------------------------------//
// BOOST_VERIFY //
//--------------------------------------------------------------------------------------//
#undef BOOST_VERIFY
#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) )
# define BOOST_VERIFY(expr) ((void)(expr))
#else
# define BOOST_VERIFY(expr) BOOST_ASSERT(expr)
#endif

View File

@ -5,7 +5,7 @@
//
// See http://www.boost.org/libs/utility 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
@ -15,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,69 +0,0 @@
#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
#define BOOST_CHECKED_DELETE_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/checked_delete.hpp
//
// Copyright (c) 2002, 2003 Peter Dimov
// Copyright (c) 2003 Daniel Frey
// Copyright (c) 2003 Howard Hinnant
//
// 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/checked_delete.html for documentation.
//
namespace boost
{
// verify that types are complete for increased safety
template<class T> inline void checked_delete(T * x)
{
// intentionally complex - simplification causes regressions
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete x;
}
template<class T> inline void checked_array_delete(T * x)
{
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete [] x;
}
template<class T> struct checked_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * x) const
{
// boost:: disables ADL
boost::checked_delete(x);
}
};
template<class T> struct checked_array_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * x) const
{
boost::checked_array_delete(x);
}
};
} // namespace boost
#endif // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED

View File

@ -5,7 +5,7 @@
//
// See http://www.boost.org/libs/utility 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
@ -15,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,68 +0,0 @@
#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/current_function.hpp - BOOST_CURRENT_FUNCTION
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
//
// 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)
//
// http://www.boost.org/libs/utility/current_function.html
//
namespace boost
{
namespace detail
{
inline void current_function_helper()
{
#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__DMC__) && (__DMC__ >= 0x810)
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__FUNCSIG__)
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
# define BOOST_CURRENT_FUNCTION __FUNCTION__
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
# define BOOST_CURRENT_FUNCTION __FUNC__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
# define BOOST_CURRENT_FUNCTION __func__
#else
# define BOOST_CURRENT_FUNCTION "(unknown)"
#endif
}
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED

View File

@ -6,7 +6,7 @@
// 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()

View File

@ -1,168 +0,0 @@
// (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.
//
// Crippled version for crippled compilers:
// see libs/utility/call_traits.htm
//
/* Release notes:
01st October 2000:
Fixed call_traits on VC6, using "poor man's partial specialisation",
using ideas taken from "Generative programming" by Krzysztof Czarnecki
& Ulrich Eisenecker.
*/
#ifndef BOOST_OB_CALL_TRAITS_HPP
#define BOOST_OB_CALL_TRAITS_HPP
#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
#include <boost/type_traits/arithmetic_traits.hpp>
#endif
#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
#include <boost/type_traits/composite_traits.hpp>
#endif
namespace boost{
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
//
// use member templates to emulate
// partial specialisation:
//
namespace detail{
template <class T>
struct standard_call_traits
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T& param_type;
};
template <class T>
struct simple_call_traits
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T param_type;
};
template <class T>
struct reference_call_traits
{
typedef T value_type;
typedef T reference;
typedef T const_reference;
typedef T param_type;
};
template <bool pointer, bool arithmetic, bool reference>
struct call_traits_chooser
{
template <class T>
struct rebind
{
typedef standard_call_traits<T> type;
};
};
template <>
struct call_traits_chooser<true, false, false>
{
template <class T>
struct rebind
{
typedef simple_call_traits<T> type;
};
};
template <>
struct call_traits_chooser<false, false, true>
{
template <class T>
struct rebind
{
typedef reference_call_traits<T> type;
};
};
template <bool size_is_small>
struct call_traits_sizeof_chooser2
{
template <class T>
struct small_rebind
{
typedef simple_call_traits<T> small_type;
};
};
template<>
struct call_traits_sizeof_chooser2<false>
{
template <class T>
struct small_rebind
{
typedef standard_call_traits<T> small_type;
};
};
template <>
struct call_traits_chooser<false, true, false>
{
template <class T>
struct rebind
{
enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) };
typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser;
typedef typename chooser::template small_rebind<T> bound_type;
typedef typename bound_type::small_type type;
};
};
} // namespace detail
template <typename T>
struct call_traits
{
private:
typedef detail::call_traits_chooser<
::boost::is_pointer<T>::value,
::boost::is_arithmetic<T>::value,
::boost::is_reference<T>::value
> chooser;
typedef typename chooser::template rebind<T> bound_type;
typedef typename bound_type::type call_traits_type;
public:
typedef typename call_traits_type::value_type value_type;
typedef typename call_traits_type::reference reference;
typedef typename call_traits_type::const_reference const_reference;
typedef typename call_traits_type::param_type param_type;
};
#else
//
// sorry call_traits is completely non-functional
// blame your broken compiler:
//
template <typename T>
struct call_traits
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T& param_type;
};
#endif // member templates
}
#endif // BOOST_OB_CALL_TRAITS_HPP

View File

@ -167,17 +167,6 @@ public:
compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
: T2(x.second()), _first(x.first()) {}
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// Total weirdness. If the assignment to _first is moved after
// the call to the inherited operator=, then this breaks graph/test/graph.cpp
// by way of iterator_adaptor.
compressed_pair_1& operator=(const compressed_pair_1& x) {
_first = x._first;
T2::operator=(x);
return *this;
}
#endif
first_reference first() { return _first; }
first_const_reference first() const { return _first; }

View File

@ -1,11 +0,0 @@
//Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc.
//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)
#ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492
#define UUID_1D94A7C6054E11DB9804B622A1EF5492
#error The header <boost/exception.hpp> has been deprecated. Please #include <boost/exception/all.hpp> instead.
#endif

View File

@ -1,80 +0,0 @@
// (C) Copyright Jens Maurer 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)
//
// Revision History:
// 15 Nov 2001 Jens Maurer
// created.
// See http://www.boost.org/libs/utility/iterator_adaptors.htm for documentation.
#ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
#define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
#include <boost/iterator/iterator_facade.hpp>
#include <boost/ref.hpp>
namespace boost {
template<class Generator>
class generator_iterator
: public iterator_facade<
generator_iterator<Generator>
, typename Generator::result_type
, single_pass_traversal_tag
, typename Generator::result_type const&
>
{
typedef iterator_facade<
generator_iterator<Generator>
, typename Generator::result_type
, single_pass_traversal_tag
, typename Generator::result_type const&
> super_t;
public:
generator_iterator() {}
generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {}
void increment()
{
m_value = (*m_g)();
}
const typename Generator::result_type&
dereference() const
{
return m_value;
}
bool equal(generator_iterator const& y) const
{
return this->m_g == y.m_g && this->m_value == y.m_value;
}
private:
Generator* m_g;
typename Generator::result_type m_value;
};
template<class Generator>
struct generator_iterator_generator
{
typedef generator_iterator<Generator> type;
};
template <class Generator>
inline generator_iterator<Generator>
make_generator_iterator(Generator & gen)
{
typedef generator_iterator<Generator> result_t;
return result_t(&gen);
}
} // namespace boost
#endif // BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP

View File

@ -13,6 +13,17 @@
#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 {
@ -26,14 +37,118 @@ namespace boost {
// 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)
{
std::advance(x, n);
return x;
return next_prior_detail::next_impl1< T, Distance >::call(x, n);
}
template <class T>
@ -42,8 +157,7 @@ inline T prior(T x) { return --x; }
template <class T, class Distance>
inline T prior(T x, Distance n)
{
std::advance(x, -n);
return x;
return next_prior_detail::prior_impl1< T, Distance >::call(x, n);
}
} // namespace boost

View File

@ -1,48 +0,0 @@
// Boost noncopyable.hpp header file --------------------------------------//
// (C) Copyright Beman Dawes 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.
#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED
#define BOOST_NONCOPYABLE_HPP_INCLUDED
#include <boost/config.hpp>
namespace boost {
// Private copy constructor and copy assignment ensure classes derived from
// class noncopyable cannot be copied.
// Contributed by Dave Abrahams
namespace noncopyable_ // protection from unintended ADL
{
class noncopyable
{
protected:
#ifndef BOOST_NO_DEFAULTED_FUNCTIONS
BOOST_CONSTEXPR noncopyable() = default;
~noncopyable() = default;
#else
noncopyable() {}
~noncopyable() {}
#endif
#ifndef BOOST_NO_DELETED_FUNCTIONS
noncopyable( const noncopyable& ) = delete;
noncopyable& operator=( const noncopyable& ) = delete;
#else
private: // emphasize the following members are private
noncopyable( const noncopyable& );
noncopyable& operator=( const noncopyable& );
#endif
};
}
typedef noncopyable_::noncopyable noncopyable;
} // namespace boost
#endif // BOOST_NONCOPYABLE_HPP_INCLUDED

View File

@ -1,6 +1,7 @@
// Boost operators.hpp header file ----------------------------------------//
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
// (C) Copyright Daniel Frey 2002-2016.
// 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)
@ -8,6 +9,8 @@
// See http://www.boost.org/libs/utility/operators.htm for documentation.
// Revision History
// 22 Feb 16 Added ADL protection, preserve old work-arounds in
// operators_v1.hpp and clean up this file. (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)
@ -24,8 +27,8 @@
// 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
// 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
@ -38,18 +41,18 @@
// 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)
// 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.
// (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)
// 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
@ -60,8 +63,8 @@
// 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
// 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
@ -70,20 +73,28 @@
// 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
// 'is_chained_base<>' (see 'operators_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
// 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
// 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.
// you understand the whole library implementation.
#ifndef BOOST_OPERATORS_HPP
#define BOOST_OPERATORS_HPP
// If old work-arounds are needed, refer to the preserved version without
// ADL protection.
#if defined(BOOST_NO_OPERATORS_IN_NAMESPACE) || defined(BOOST_USE_OPERATORS_V1)
#include "operators_v1.hpp"
#else
#include <cstddef>
#include <iterator>
#include <boost/config.hpp>
#include <boost/iterator.hpp>
#include <boost/detail/workaround.hpp>
#if defined(__sgi) && !defined(__GNUC__)
@ -91,42 +102,30 @@
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
# pragma warning( disable : 4284 ) // complaint about return type of
# 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 {
// Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
bool dummy;
#endif
};
} // 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.
// 2-type-argument operator forms, respectively.
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
namespace boost
{
#endif
namespace operators_impl
{
namespace operators_detail
{
template <typename T> class empty_base {};
} // namespace operators_detail
// 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> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct less_than_comparable2 : B
{
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
@ -137,7 +136,7 @@ struct less_than_comparable2 : B
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> >
template <class T, class B = operators_detail::empty_base<T> >
struct less_than_comparable1 : B
{
friend bool operator>(const T& x, const T& y) { return y < x; }
@ -145,7 +144,7 @@ struct less_than_comparable1 : B
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> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct equality_comparable2 : B
{
friend bool operator==(const U& y, const T& x) { return x == y; }
@ -153,7 +152,7 @@ struct equality_comparable2 : B
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> >
template <class T, class B = operators_detail::empty_base<T> >
struct equality_comparable1 : B
{
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
@ -171,39 +170,39 @@ struct equality_comparable1 : B
// 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_COMMUTATIVE( NAME, OP ) \
template <class T, class U, class B = operators_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 = operators_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> > \
template <class T, class U, class B = operators_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> > \
template <class T, class U, class B = operators_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> > \
template <class T, class B = operators_detail::empty_base<T> > \
struct NAME##1 : B \
{ \
friend T operator OP( const T& lhs, const T& rhs ) \
@ -218,34 +217,34 @@ struct NAME##1 : B \
// optimization opportunities to the compiler :)
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
template <class T, class U, class B = operators_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> > \
template <class T, class B = operators_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> > \
template <class T, class U, class B = operators_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> > \
template <class T, class U, class B = operators_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> > \
template <class T, class B = operators_detail::empty_base<T> > \
struct NAME##1 : B \
{ \
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
@ -268,7 +267,7 @@ BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
// incrementable and decrementable contributed by Jeremy Siek
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_detail::empty_base<T> >
struct incrementable : B
{
friend T operator++(T& x, int)
@ -281,7 +280,7 @@ 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> >
template <class T, class B = operators_detail::empty_base<T> >
struct decrementable : B
{
friend T operator--(T& x, int)
@ -296,16 +295,16 @@ private: // The use of this typedef works around a Borland bug
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
template <class T, class P, class B = ::boost::detail::empty_base<T> >
template <class T, class P, class B = operators_detail::empty_base<T> >
struct dereferenceable : B
{
P operator->() const
{
return &*static_cast<const T&>(*this);
{
return &*static_cast<const T&>(*this);
}
};
template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
template <class T, class I, class R, class B = operators_detail::empty_base<T> >
struct indexable : B
{
R operator[](I n) const
@ -319,34 +318,34 @@ struct indexable : B
#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; } \
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
template <class T, class U, class B = operators_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 = operators_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; } \
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
template <class T, class U, class B = operators_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 = operators_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)
@ -356,7 +355,7 @@ BOOST_BINARY_OPERATOR( right_shiftable, >> )
#undef BOOST_BINARY_OPERATOR
template <class T, class U, class B = ::boost::detail::empty_base<T> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct equivalent2 : B
{
friend bool operator==(const T& x, const U& y)
@ -365,7 +364,7 @@ struct equivalent2 : B
}
};
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_detail::empty_base<T> >
struct equivalent1 : B
{
friend bool operator==(const T&x, const T&y)
@ -374,7 +373,7 @@ struct equivalent1 : B
}
};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct partially_ordered2 : B
{
friend bool operator<=(const T& x, const U& y)
@ -391,7 +390,7 @@ struct partially_ordered2 : B
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
};
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_detail::empty_base<T> >
struct partially_ordered1 : B
{
friend bool operator>(const T& x, const T& y)
@ -404,161 +403,161 @@ struct partially_ordered1 : B
// Combined operator classes (contributed by Daryle Walker) ----------------//
template <class T, class U, class B = ::boost::detail::empty_base<T> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_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> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct additive2
: addable2<T, U
, subtractable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_detail::empty_base<T> >
struct additive1
: addable1<T
, subtractable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct multiplicative2
: multipliable2<T, U
, dividable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_detail::empty_base<T> >
struct multiplicative1
: multipliable1<T
, dividable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct integer_multiplicative2
: multiplicative2<T, U
, modable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_detail::empty_base<T> >
struct integer_multiplicative1
: multiplicative1<T
, modable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct arithmetic2
: additive2<T, U
, multiplicative2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_detail::empty_base<T> >
struct arithmetic1
: additive1<T
, multiplicative1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_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> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_detail::empty_base<T> >
struct bitwise1
: xorable1<T
, andable1<T
, orable1<T, B
> > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_detail::empty_base<T> >
struct unit_steppable
: incrementable<T
, decrementable<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_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> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_detail::empty_base<T> >
struct ring_operators1
: additive1<T
, multipliable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base<T> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_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> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_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> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_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> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct euclidian_ring_operators2
: ring_operators2<T, U
, dividable2<T, U
@ -567,26 +566,26 @@ struct euclidian_ring_operators2
, modable2_left<T, U, B
> > > > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_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> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_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> >
template <class T, class U, class B = operators_detail::empty_base<T> >
struct euclidean_ring_operators2
: ring_operators2<T, U
, dividable2<T, U
@ -595,43 +594,43 @@ struct euclidean_ring_operators2
, modable2_left<T, U, B
> > > > > {};
template <class T, class B = ::boost::detail::empty_base<T> >
template <class T, class B = operators_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> >
template <class T, class U, class B = operators_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> >
template <class T, class B = operators_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> >
template <class T, class P, class B = operators_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> >
template <class T, class B = operators_detail::empty_base<T> >
struct output_iteratable
: incrementable<T, B
> {};
template <class T, class P, class B = ::boost::detail::empty_base<T> >
template <class T, class P, class B = operators_detail::empty_base<T> >
struct forward_iteratable
: input_iteratable<T, P, B
> {};
template <class T, class P, class B = ::boost::detail::empty_base<T> >
template <class T, class P, class B = operators_detail::empty_base<T> >
struct bidirectional_iteratable
: forward_iteratable<T, P
, decrementable<T, B
@ -641,7 +640,7 @@ struct bidirectional_iteratable
// 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> >
template <class T, class P, class D, class R, class B = operators_detail::empty_base<T> >
struct random_access_iteratable
: bidirectional_iteratable<T, P
, less_than_comparable1<T
@ -649,125 +648,64 @@ struct random_access_iteratable
, 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.
// Here's where we put it all together, defining the xxxx forms of the templates.
// We also define specializations of is_chained_base<> for
// the xxxx, xxxx1, and xxxx2 templates.
//
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace operators_detail
{
// 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.
struct true_t {};
struct false_t {};
} // namespace operators_detail
// 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;
typedef operators_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; \
// Provide a specialization of 'is_chained_base<>'
// for a 4-type-argument operator template.
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
template<class T, class U, class V, class W, class B> \
struct is_chained_base< template_name4<T, U, V, W, B> > { \
typedef operators_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; \
// Provide a specialization of 'is_chained_base<>'
// for a 3-type-argument operator template.
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
template<class T, class U, class V, class B> \
struct is_chained_base< template_name3<T, U, V, B> > { \
typedef operators_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; \
// Provide a specialization of 'is_chained_base<>'
// for a 2-type-argument operator template.
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
template<class T, class U, class B> \
struct is_chained_base< template_name2<T, U, B> > { \
typedef operators_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; \
// Provide a specialization of 'is_chained_base<>'
// for a 1-type-argument operator template.
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
template<class T, class B> \
struct is_chained_base< template_name1<T, B> > { \
typedef operators_detail::true_t value; \
};
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
@ -784,52 +722,34 @@ template<class T> struct is_chained_base {
// 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) \
# define BOOST_OPERATOR_TEMPLATE(template_name) \
template <class T \
,class U = T \
,class B = operators_detail::empty_base<T> \
,class O = typename is_chained_base<U>::value \
> \
struct template_name; \
\
template<class T, class U, class B> \
struct template_name<T, U, B, operators_detail::false_t> \
: template_name##2<T, U, B> {}; \
\
template<class T, class U> \
struct template_name<T, U, operators_detail::empty_base<T>, operators_detail::true_t> \
: template_name##1<T, U> {}; \
\
template <class T, class B> \
struct template_name<T, T, B, operators_detail::false_t> \
: template_name##1<T, B> {}; \
\
template<class T, class U, class B, class O> \
struct is_chained_base< template_name<T, U, B, O> > { \
typedef operators_detail::true_t value; \
}; \
\
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
BOOST_OPERATOR_TEMPLATE1(template_name##1)
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
BOOST_IMPORT_TEMPLATE4(template_name4)
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
BOOST_IMPORT_TEMPLATE3(template_name3)
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
BOOST_IMPORT_TEMPLATE2(template_name2)
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
BOOST_IMPORT_TEMPLATE1(template_name1)
// In this case we can only assume that template_name<> is equivalent to the
// more commonly needed template_name1<> form.
# define BOOST_OPERATOR_TEMPLATE(template_name) \
template <class T, class B = ::boost::detail::empty_base<T> > \
struct template_name : template_name##1<T, B> {};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
BOOST_OPERATOR_TEMPLATE(equality_comparable)
BOOST_OPERATOR_TEMPLATE(multipliable)
@ -883,13 +803,7 @@ BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
#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
@ -897,14 +811,10 @@ struct operators2
, bitwise2<T,U
> > > {};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
struct operators : operators2<T, U> {};
template <class T> struct operators<T, T>
#else
template <class T> struct operators
#endif
: totally_ordered<T
, integer_arithmetic<T
, bitwise<T
@ -921,13 +831,13 @@ template <class T,
class R = V const &>
struct input_iterator_helper
: input_iteratable<T, P
, boost::iterator<std::input_iterator_tag, V, D, P, R
, std::iterator<std::input_iterator_tag, V, D, P, R
> > {};
template<class T>
struct output_iterator_helper
: output_iteratable<T
, boost::iterator<std::output_iterator_tag, void, void, void, void
, std::iterator<std::output_iterator_tag, void, void, void, void
> >
{
T& operator*() { return static_cast<T&>(*this); }
@ -941,7 +851,7 @@ template <class T,
class R = V&>
struct forward_iterator_helper
: forward_iteratable<T, P
, boost::iterator<std::forward_iterator_tag, V, D, P, R
, std::iterator<std::forward_iterator_tag, V, D, P, R
> > {};
template <class T,
@ -951,17 +861,17 @@ template <class T,
class R = V&>
struct bidirectional_iterator_helper
: bidirectional_iteratable<T, P
, boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
, std::iterator<std::bidirectional_iterator_tag, V, D, P, R
> > {};
template <class T,
class V,
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
, boost::iterator<std::random_access_iterator_tag, V, D, P, R
, std::iterator<std::random_access_iterator_tag, V, D, P, R
> >
{
friend D requires_difference_operator(const T& x, const T& y) {
@ -969,10 +879,14 @@ struct random_access_iterator_helper
}
}; // random_access_iterator_helper
} // namespace operators_impl
using namespace operators_impl;
} // namespace boost
#if defined(__sgi) && !defined(__GNUC__)
#pragma reset woff 1234
#endif
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
#endif // BOOST_OPERATORS_HPP

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,189 +0,0 @@
#ifndef BOOST_REF_HPP_INCLUDED
#define BOOST_REF_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/detail/workaround.hpp>
//
// ref.hpp - ref/cref, useful helper functions
//
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2001, 2002 Peter Dimov
// Copyright (C) 2002 David Abrahams
//
// 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/bind/ref.html for documentation.
//
namespace boost
{
template<class T> class reference_wrapper
{
public:
typedef T type;
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 )
explicit reference_wrapper(T& t): t_(&t) {}
#else
explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
#endif
operator T& () const { return *t_; }
T& get() const { return *t_; }
T* get_pointer() const { return t_; }
private:
T* t_;
};
# if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
# define BOOST_REF_CONST
# else
# define BOOST_REF_CONST const
# endif
template<class T> inline reference_wrapper<T> BOOST_REF_CONST ref(T & t)
{
return reference_wrapper<T>(t);
}
template<class T> inline reference_wrapper<T const> BOOST_REF_CONST cref(T const & t)
{
return reference_wrapper<T const>(t);
}
# undef BOOST_REF_CONST
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
class is_reference_wrapper
: public mpl::false_
{
};
template<typename T>
class unwrap_reference
{
public:
typedef T type;
};
# define AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(X) \
template<typename T> \
class is_reference_wrapper< X > \
: public mpl::true_ \
{ \
}; \
\
template<typename T> \
class unwrap_reference< X > \
{ \
public: \
typedef T type; \
}; \
/**/
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T>)
#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const)
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> volatile)
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const volatile)
#endif
# undef AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF
# else // no partial specialization
} // namespace boost
#include <boost/type.hpp>
namespace boost
{
namespace detail
{
typedef char (&yes_reference_wrapper_t)[1];
typedef char (&no_reference_wrapper_t)[2];
no_reference_wrapper_t is_reference_wrapper_test(...);
template<typename T>
yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper<T> >);
template<bool wrapped>
struct reference_unwrapper
{
template <class T>
struct apply
{
typedef T type;
};
};
template<>
struct reference_unwrapper<true>
{
template <class T>
struct apply
{
typedef typename T::type type;
};
};
}
template<typename T>
class is_reference_wrapper
{
public:
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(detail::is_reference_wrapper_test(type<T>()))
== sizeof(detail::yes_reference_wrapper_t)));
typedef ::boost::mpl::bool_<value> type;
};
template <typename T>
class unwrap_reference
: public detail::reference_unwrapper<
is_reference_wrapper<T>::value
>::template apply<T>
{};
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T> inline typename unwrap_reference<T>::type&
unwrap_ref(T& t)
{
return t;
}
template<class T> inline T* get_pointer( reference_wrapper<T> const & r )
{
return r.get_pointer();
}
} // namespace boost
#endif // #ifndef BOOST_REF_HPP_INCLUDED

View File

@ -1,12 +0,0 @@
// Copyright (C) 2007 Joseph Gauterin
//
// 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)
#ifndef BOOST_SWAP_HPP
#define BOOST_SWAP_HPP
#include "boost/utility/swap.hpp"
#endif

View File

@ -1,102 +0,0 @@
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
// Douglas Gregor (gregod@cs.rpi.edu)
//
// Copyright (C) 2002, 2008 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)
// For more information, see http://www.boost.org
#ifndef BOOST_UTILITY_ADDRESSOF_HPP
# define BOOST_UTILITY_ADDRESSOF_HPP
# include <boost/config.hpp>
# include <boost/detail/workaround.hpp>
namespace boost
{
namespace detail
{
template<class T> struct addr_impl_ref
{
T & v_;
inline addr_impl_ref( T & v ): v_( v ) {}
inline operator T& () const { return v_; }
private:
addr_impl_ref & operator=(const addr_impl_ref &);
};
template<class T> struct addressof_impl
{
static inline T * f( T & v, long )
{
return reinterpret_cast<T*>(
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
}
static inline T * f( T * v, int )
{
return v;
}
};
} // namespace detail
template<class T> T * addressof( T & v )
{
#if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || defined( __SUNPRO_CC )
return boost::detail::addressof_impl<T>::f( v, 0 );
#else
return boost::detail::addressof_impl<T>::f( boost::detail::addr_impl_ref<T>( v ), 0 );
#endif
}
#if defined( __SUNPRO_CC ) && BOOST_WORKAROUND( __SUNPRO_CC, BOOST_TESTED_AT( 0x590 ) )
namespace detail
{
template<class T> struct addressof_addp
{
typedef T * type;
};
} // namespace detail
template< class T, std::size_t N >
typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] )
{
return &t;
}
#endif
// Borland doesn't like casting an array reference to a char reference
// but these overloads work around the problem.
#if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template<typename T,std::size_t N>
T (*addressof(T (&t)[N]))[N]
{
return reinterpret_cast<T(*)[N]>(&t);
}
template<typename T,std::size_t N>
const T (*addressof(const T (&t)[N]))[N]
{
return reinterpret_cast<const T(*)[N]>(&t);
}
#endif
} // namespace boost
#endif // BOOST_UTILITY_ADDRESSOF_HPP

View File

@ -1,6 +1,6 @@
// boost utility/base_from_member.hpp header file --------------------------//
// Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and
// 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>.)
@ -10,10 +10,15 @@
#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 ------------------------------//
@ -42,17 +47,70 @@
// {}
// This macro should only persist within this file.
#define BOOST_PRIVATE_CTR_DEF( z, n, data ) \
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
explicit base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
: member( BOOST_PP_ENUM_PARAMS(n, x) ) \
{} \
#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
@ -68,12 +126,39 @@ 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()
{}
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
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

View File

@ -33,8 +33,12 @@ bool equal_pointees ( OptionalPointee const& x, OptionalPointee const& y )
}
template<class OptionalPointee>
struct equal_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
struct equal_pointees_t
{
typedef bool result_type;
typedef OptionalPointee first_argument_type;
typedef OptionalPointee second_argument_type;
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
{ return equal_pointees(x,y) ; }
} ;
@ -56,8 +60,12 @@ bool less_pointees ( OptionalPointee const& x, OptionalPointee const& y )
}
template<class OptionalPointee>
struct less_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
struct less_pointees_t
{
typedef bool result_type;
typedef OptionalPointee first_argument_type;
typedef OptionalPointee second_argument_type;
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
{ return less_pointees(x,y) ; }
} ;

View File

@ -1,49 +0,0 @@
// common_type.hpp ---------------------------------------------------------//
// Copyright 2010 Vicente J. Botet Escriba
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
#define BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
#include <boost/config.hpp>
//----------------------------------------------------------------------------//
#include <boost/type_traits/add_rvalue_reference.hpp>
//#include <boost/type_traits/add_lvalue_reference.hpp>
//----------------------------------------------------------------------------//
// //
// C++03 implementation of //
// Written by Vicente J. Botet Escriba //
//~ 20.3.4 Function template declval [declval]
//~ 1 The library provides the function template declval to simplify the definition of expressions which occur as
//~ unevaluated operands.
//~ 2 Remarks: If this function is used, the program is ill-formed.
//~ 3 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 participats in overloading if the type From can be
//~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). <20>end
//~ example ]
// //
//----------------------------------------------------------------------------//
namespace boost {
//#if !defined(BOOST_NO_RVALUE_REFERENCES)
template <typename T>
typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
//#else
// template <typename T>
// typename add_lvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
//#endif
} // namespace boost
#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP

View File

@ -38,10 +38,25 @@ struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
#endif
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
// Uses declval following N3225 20.7.7.6 when F is not a pointer.
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),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<
@ -54,8 +69,6 @@ struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
>::type
{};
namespace detail {
#ifdef BOOST_NO_SFINAE_EXPR
template<typename F>
@ -139,7 +152,7 @@ struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)),
} // namespace detail
#else // defined(BOOST_RESULT_OF_USE_DECLTYPE)
#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)>

View File

@ -1,119 +0,0 @@
// Boost enable_if library
// Copyright 2003 (c) 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)
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
// Jeremiah Willcock (jewillco at osl.iu.edu)
// Andrew Lumsdaine (lums at osl.iu.edu)
#ifndef BOOST_UTILITY_ENABLE_IF_HPP
#define BOOST_UTILITY_ENABLE_IF_HPP
#include "boost/config.hpp"
// Even the definition of enable_if causes problems on some compilers,
// so it's macroed out for all compilers that do not support SFINAE
#ifndef BOOST_NO_SFINAE
namespace boost
{
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool B, class T>
struct lazy_enable_if_c {
typedef typename T::type type;
};
template <class T>
struct lazy_enable_if_c<false, T> {};
template <class Cond, class T>
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
template <bool B, class T = void>
struct disable_if_c {
typedef T type;
};
template <class T>
struct disable_if_c<true, T> {};
template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {};
template <bool B, class T>
struct lazy_disable_if_c {
typedef typename T::type type;
};
template <class T>
struct lazy_disable_if_c<true, T> {};
template <class Cond, class T>
struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
} // namespace boost
#else
namespace boost {
namespace detail { typedef void enable_if_default_T; }
template <typename T>
struct enable_if_does_not_work_on_this_compiler;
template <bool B, class T = detail::enable_if_default_T>
struct enable_if_c : enable_if_does_not_work_on_this_compiler<T>
{ };
template <bool B, class T = detail::enable_if_default_T>
struct disable_if_c : enable_if_does_not_work_on_this_compiler<T>
{ };
template <bool B, class T = detail::enable_if_default_T>
struct lazy_enable_if_c : enable_if_does_not_work_on_this_compiler<T>
{ };
template <bool B, class T = detail::enable_if_default_T>
struct lazy_disable_if_c : enable_if_does_not_work_on_this_compiler<T>
{ };
template <class Cond, class T = detail::enable_if_default_T>
struct enable_if : enable_if_does_not_work_on_this_compiler<T>
{ };
template <class Cond, class T = detail::enable_if_default_T>
struct disable_if : enable_if_does_not_work_on_this_compiler<T>
{ };
template <class Cond, class T = detail::enable_if_default_T>
struct lazy_enable_if : enable_if_does_not_work_on_this_compiler<T>
{ };
template <class Cond, class T = detail::enable_if_default_T>
struct lazy_disable_if : enable_if_does_not_work_on_this_compiler<T>
{ };
} // namespace boost
#endif // BOOST_NO_SFINAE
#endif

View File

@ -48,15 +48,13 @@ public:
{}
template<class T>
void* apply(void* address
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const
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
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) const
void* apply(void* address, std::size_t n) const
{
for(char* next = address = this->BOOST_NESTED_TEMPLATE apply<T>(address);
!! --n;)

View File

@ -38,18 +38,27 @@
// 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 either BOOST_RESULT_OF_USE_DECLTYPE or
// BOOST_RESULT_OF_USE_TR1, but not both!
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)
# error Both BOOST_RESULT_OF_USE_DECLTYPE and BOOST_RESULT_OF_USE_TR1 cannot be defined at the same time.
// 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_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
# define BOOST_RESULT_OF_USE_DECLTYPE
# else
# define BOOST_RESULT_OF_USE_TR1
# 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
@ -59,13 +68,20 @@ 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) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#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

View File

@ -1,5 +1,5 @@
/*
Copyright (c) Marshall Clow 2012-2012.
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)
@ -17,11 +17,20 @@
#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 <functional>
#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 {
@ -36,18 +45,6 @@ namespace boost {
};
}
template<typename charT, typename traits> 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
template<typename charT, typename traits>
class basic_string_ref {
public:
@ -61,41 +58,52 @@ namespace boost {
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef const_reverse_iterator reverse_iterator;
typedef std::size_t size_type;
typedef ptrdiff_t difference_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_CONSTEXPR basic_string_ref () BOOST_NOEXCEPT
: ptr_(NULL), len_(0) {}
BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs)
// 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) {
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)
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_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> ( ptr_, len_ );
return std::basic_string<charT, traits, Allocator> ( begin(), end());
}
#endif
std::basic_string<charT, traits> to_string () const {
return std::basic_string<charT, traits> ( ptr_, len_ );
return std::basic_string<charT, traits> ( begin(), end());
}
// iterators
@ -119,7 +127,7 @@ namespace boost {
const charT& at(size_t pos) const {
if ( pos >= len_ )
throw std::out_of_range ( "boost::string_ref::at" );
BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_ref::at" ) );
return ptr_[pos];
}
@ -144,18 +152,12 @@ namespace boost {
// basic_string_ref string operations
BOOST_CONSTEXPR
basic_string_ref substr(size_type pos, size_type n=npos) const {
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1600)
// Looks like msvc 8 and 9 have a codegen bug when one branch of
// a conditional operator is a throw expression. -EAN 2012/12/04
if ( pos > size()) throw std::out_of_range ( "string_ref::substr" );
if ( n == npos || pos + n > size()) n = size () - pos;
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 );
#else
return pos > size() ? throw std::out_of_range ( "string_ref::substr" ) :
basic_string_ref ( data() + pos, n == npos || pos + n > size() ? size() - pos : n );
#endif
}
int compare(basic_string_ref x) const {
@ -188,13 +190,13 @@ namespace boost {
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 : reverse_distance ( this->crbegin (), iter );
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 : reverse_distance ( this->crbegin (), iter );
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
}
size_type find_first_of(charT c) const { return find (c); }
@ -209,7 +211,7 @@ namespace boost {
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 : reverse_distance ( this->crbegin (), iter);
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
}
size_type find_first_not_of(basic_string_ref s) const {
@ -226,21 +228,17 @@ namespace boost {
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 : reverse_distance ( this->crbegin (), iter );
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 reverse_distance ( this->crbegin (), iter );
return this->size() - 1 - std::distance(this->crbegin(), iter);
return npos;
}
private:
template <typename r_iter>
size_type reverse_distance ( r_iter first, r_iter last ) const {
return len_ - 1 - std::distance ( first, last );
}
template <typename Iterator>
Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
@ -260,173 +258,207 @@ namespace boost {
// Comparison operators
// Equality
template<typename charT, typename traits>
bool operator==(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
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>
bool operator==(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
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>
bool operator==(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
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>
bool operator==(basic_string_ref<charT, traits> x, const charT * y) {
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>
bool operator==(const charT * x, basic_string_ref<charT, traits> y) {
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>
bool operator!=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
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>
bool operator!=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
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>
bool operator!=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
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>
bool operator!=(basic_string_ref<charT, traits> x, const charT * y) {
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>
bool operator!=(const charT * x, basic_string_ref<charT, traits> y) {
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>
bool operator<(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
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>
bool operator<(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
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>
bool operator<(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
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>
bool operator<(basic_string_ref<charT, traits> x, const charT * y) {
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>
bool operator<(const charT * x, basic_string_ref<charT, traits> y) {
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>
bool operator>(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
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>
bool operator>(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
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>
bool operator>(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
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>
bool operator>(basic_string_ref<charT, traits> x, const charT * y) {
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>
bool operator>(const charT * x, basic_string_ref<charT, traits> y) {
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>
bool operator<=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
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>
bool operator<=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
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>
bool operator<=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
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>
bool operator<=(basic_string_ref<charT, traits> x, const charT * y) {
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>
bool operator<=(const charT * x, basic_string_ref<charT, traits> y) {
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>
bool operator>=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
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>
bool operator>=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
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>
bool operator>=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
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>
bool operator>=(basic_string_ref<charT, traits> x, const charT * y) {
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>
bool operator>=(const charT * x, basic_string_ref<charT, traits> y) {
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>
std::basic_ostream<charT, traits>&
inline std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
#ifdef BOOST_NO_CXX11_RANGE_BASED_FOR
for ( typename basic_string_ref<charT, traits>::const_iterator iter = str.begin (); iter != str.end (); ++iter )
os << *iter;
#else
for ( charT x : str )
os << x;
#endif
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;
}
@ -436,67 +468,67 @@ namespace boost {
// These are short-term implementations.
// In a production environment, I would rather avoid the copying.
//
int stoi (string_ref str, size_t* idx=0, int base=10) {
inline int stoi (string_ref str, size_t* idx=0, int base=10) {
return std::stoi ( std::string(str), idx, base );
}
long stol (string_ref str, size_t* idx=0, int base=10) {
inline long stol (string_ref str, size_t* idx=0, int base=10) {
return std::stol ( std::string(str), idx, base );
}
unsigned long stoul (string_ref str, size_t* idx=0, int base=10) {
inline unsigned long stoul (string_ref str, size_t* idx=0, int base=10) {
return std::stoul ( std::string(str), idx, base );
}
long long stoll (string_ref str, size_t* idx=0, int base=10) {
inline long long stoll (string_ref str, size_t* idx=0, int base=10) {
return std::stoll ( std::string(str), idx, base );
}
unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) {
inline unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) {
return std::stoull ( std::string(str), idx, base );
}
float stof (string_ref str, size_t* idx=0) {
inline float stof (string_ref str, size_t* idx=0) {
return std::stof ( std::string(str), idx );
}
double stod (string_ref str, size_t* idx=0) {
inline double stod (string_ref str, size_t* idx=0) {
return std::stod ( std::string(str), idx );
}
long double stold (string_ref str, size_t* idx=0) {
inline long double stold (string_ref str, size_t* idx=0) {
return std::stold ( std::string(str), idx );
}
int stoi (wstring_ref str, size_t* idx=0, int base=10) {
inline int stoi (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoi ( std::wstring(str), idx, base );
}
long stol (wstring_ref str, size_t* idx=0, int base=10) {
inline long stol (wstring_ref str, size_t* idx=0, int base=10) {
return std::stol ( std::wstring(str), idx, base );
}
unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) {
inline unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoul ( std::wstring(str), idx, base );
}
long long stoll (wstring_ref str, size_t* idx=0, int base=10) {
inline long long stoll (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoll ( std::wstring(str), idx, base );
}
unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) {
inline unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoull ( std::wstring(str), idx, base );
}
float stof (wstring_ref str, size_t* idx=0) {
inline float stof (wstring_ref str, size_t* idx=0) {
return std::stof ( std::wstring(str), idx );
}
double stod (wstring_ref str, size_t* idx=0) {
inline double stod (wstring_ref str, size_t* idx=0) {
return std::stod ( std::wstring(str), idx );
}
long double stold (wstring_ref str, size_t* idx=0) {
inline long double stold (wstring_ref str, size_t* idx=0) {
return std::stold ( std::wstring(str), idx );
}
#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 @@
/*
Copyright (c) Marshall Clow 2012-2015.
Copyright (c) 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

@ -1,55 +0,0 @@
// Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, 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)
// For more information, see http://www.boost.org
#ifndef BOOST_UTILITY_SWAP_HPP
#define BOOST_UTILITY_SWAP_HPP
// Note: the implementation of this utility contains various workarounds:
// - swap_impl is put outside the boost namespace, to avoid infinite
// recursion (causing stack overflow) when swapping objects of a primitive
// type.
// - swap_impl has a using-directive, rather than a using-declaration,
// because some compilers (including MSVC 7.1, Borland 5.9.3, and
// Intel 8.1) don't do argument-dependent lookup when it has a
// using-declaration instead.
// - boost::swap has two template arguments, instead of one, to
// avoid ambiguity when swapping objects of a Boost type that does
// not have its own boost::swap overload.
#include <algorithm> //for std::swap
#include <cstddef> //for std::size_t
namespace boost_swap_impl
{
template<class T>
void swap_impl(T& left, T& right)
{
using namespace std;//use std::swap if argument dependent lookup fails
swap(left,right);
}
template<class T, std::size_t N>
void swap_impl(T (& left)[N], T (& right)[N])
{
for (std::size_t i = 0; i < N; ++i)
{
::boost_swap_impl::swap_impl(left[i], right[i]);
}
}
}
namespace boost
{
template<class T1, class T2>
void swap(T1& left, T2& right)
{
::boost_swap_impl::swap_impl(left, right);
}
}
#endif

View File

@ -33,7 +33,6 @@
#ifdef BOOST_MSVC
#pragma warning(push)
#if _MSC_VER >= 1310
// 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)
@ -41,7 +40,6 @@
// a const type: "warning C4512: assignment operator could not be generated".
#pragma warning(disable: 4512)
#endif
#endif
#ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION
// Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
@ -73,12 +71,14 @@ class initialized
#endif
remove_const<T>::type data;
BOOST_GPU_ENABLED
wrapper()
:
data()
{
}
BOOST_GPU_ENABLED
wrapper(T const & arg)
:
data(arg)
@ -92,6 +92,7 @@ class initialized
#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));
@ -99,6 +100,7 @@ class initialized
public :
BOOST_GPU_ENABLED
initialized()
{
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
@ -107,16 +109,19 @@ class initialized
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.
@ -125,31 +130,37 @@ class initialized
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;
@ -158,18 +169,21 @@ class initialized
} ;
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) ;
@ -185,31 +199,37 @@ class value_initialized
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;
@ -218,18 +238,21 @@ class value_initialized
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) ;
@ -240,7 +263,7 @@ class initialized_value_t
{
public :
template <class T> operator T() const
template <class T> BOOST_GPU_ENABLED operator T() const
{
return initialized<T>().data();
}

View File

@ -14,22 +14,25 @@
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
<blockquote>
<p>
<a href="assert.html">assert</a><br>
<a href="base_from_member.html">base_from_member</a><br>
<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="checked_delete.html">checked_delete</a><br>
<a href="compressed_pair.htm">compressed_pair</a><br>
<a href="current_function.html">current_function</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="enable_if.html">enable_if</a><br>
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
<a href="generator_iterator.htm">generator iterator adaptors</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="swap.html">swap</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>
<a href="value_init.htm">value_init</a><br>
</p>
</blockquote>
<hr>
@ -43,4 +46,3 @@
<!--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>

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,36 +0,0 @@
// boost class noncopyable test program ------------------------------------//
// (C) Copyright Beman Dawes 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
// 9 Jun 99 Add unnamed namespace
// 2 Jun 99 Initial Version
#include <boost/noncopyable.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 : private boost::noncopyable
{
public:
DontTreadOnMe() { std::cout << "defanged!" << std::endl; }
}; // DontTreadOnMe
} // unnamed namespace
int main()
{
DontTreadOnMe object1;
DontTreadOnMe object2(object1);
object1 = object2;
return 0;
} // main

View File

@ -61,18 +61,19 @@ struct complement
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
// 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) << CHAR_BIT)
Number(Number(prev::max) * shift)
+ Number(UCHAR_MAX));
BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) << CHAR_BIT));
BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) * shift));
#endif
};
};

View File

@ -38,11 +38,9 @@ namespace
int true_value(int x) { return x; }
long true_value(long x) { return x; }
signed char true_value(signed char x) { return x; }
short true_value(short x) { return x; }
unsigned int true_value(unsigned int x) { return x; }
unsigned long true_value(unsigned long x) { return x; }
unsigned char true_value(unsigned char x) { return x; }
unsigned short true_value(unsigned short x) { return x; }
// verify the minimum requirements for some operators
class convertible_to_bool

View File

@ -1,134 +0,0 @@
// Copyright David Abrahams and Aleksey Gurtovoy
// 2002-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)
// compile-time test for "boost/ref.hpp" header content
// see 'ref_test.cpp' for run-time part
#include <boost/ref.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/assert.hpp>
namespace {
template< typename T, typename U >
void ref_test(boost::reference_wrapper<U>)
{
typedef typename boost::reference_wrapper<U>::type type;
BOOST_STATIC_ASSERT((boost::is_same<U,type>::value));
BOOST_STATIC_ASSERT((boost::is_same<T,type>::value));
}
template< typename T >
void assignable_test(T x)
{
x = x;
}
template< bool R, typename T >
void is_reference_wrapper_test(T)
{
BOOST_STATIC_ASSERT(boost::is_reference_wrapper<T>::value == R);
}
template< typename R, typename Ref >
void cxx_reference_test(Ref)
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
typedef typename boost::remove_const<Ref>::type ref;
BOOST_STATIC_ASSERT((boost::is_same<R,ref>::value));
#else
BOOST_STATIC_ASSERT((boost::is_same<R,Ref>::value));
#endif
}
template< typename R, typename Ref >
void unwrap_reference_test(Ref)
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
typedef typename boost::remove_const<Ref>::type ref;
typedef typename boost::unwrap_reference<ref>::type type;
#else
typedef typename boost::unwrap_reference<Ref>::type type;
#endif
BOOST_STATIC_ASSERT((boost::is_same<R,type>::value));
}
} // namespace
int main()
{
int i = 0;
int& ri = i;
int const ci = 0;
int const& rci = ci;
// 'ref/cref' functions test
ref_test<int>(boost::ref(i));
ref_test<int>(boost::ref(ri));
ref_test<int const>(boost::ref(ci));
ref_test<int const>(boost::ref(rci));
ref_test<int const>(boost::cref(i));
ref_test<int const>(boost::cref(ri));
ref_test<int const>(boost::cref(ci));
ref_test<int const>(boost::cref(rci));
// test 'assignable' requirement
assignable_test(boost::ref(i));
assignable_test(boost::ref(ri));
assignable_test(boost::cref(i));
assignable_test(boost::cref(ci));
assignable_test(boost::cref(rci));
// 'is_reference_wrapper' test
is_reference_wrapper_test<true>(boost::ref(i));
is_reference_wrapper_test<true>(boost::ref(ri));
is_reference_wrapper_test<true>(boost::cref(i));
is_reference_wrapper_test<true>(boost::cref(ci));
is_reference_wrapper_test<true>(boost::cref(rci));
is_reference_wrapper_test<false>(i);
is_reference_wrapper_test<false, int&>(ri);
is_reference_wrapper_test<false>(ci);
is_reference_wrapper_test<false, int const&>(rci);
// ordinary references/function template arguments deduction test
cxx_reference_test<int>(i);
cxx_reference_test<int>(ri);
cxx_reference_test<int>(ci);
cxx_reference_test<int>(rci);
cxx_reference_test<int&, int&>(i);
cxx_reference_test<int&, int&>(ri);
cxx_reference_test<int const&, int const&>(i);
cxx_reference_test<int const&, int const&>(ri);
cxx_reference_test<int const&, int const&>(ci);
cxx_reference_test<int const&, int const&>(rci);
// 'unwrap_reference' test
unwrap_reference_test<int>(boost::ref(i));
unwrap_reference_test<int>(boost::ref(ri));
unwrap_reference_test<int const>(boost::cref(i));
unwrap_reference_test<int const>(boost::cref(ci));
unwrap_reference_test<int const>(boost::cref(rci));
unwrap_reference_test<int>(i);
unwrap_reference_test<int>(ri);
unwrap_reference_test<int>(ci);
unwrap_reference_test<int>(rci);
unwrap_reference_test<int&, int&>(i);
unwrap_reference_test<int&, int&>(ri);
unwrap_reference_test<int const&, int const&>(i);
unwrap_reference_test<int const&, int const&>(ri);
unwrap_reference_test<int const&, int const&>(ci);
unwrap_reference_test<int const&, int const&>(rci);
return 0;
}

View File

@ -1,121 +0,0 @@
// Copyright David Abrahams and Aleksey Gurtovoy
// 2002-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)
// run-time test for "boost/ref.hpp" header content
// see 'ref_ct_test.cpp' for compile-time part
#if defined(_MSC_VER) && !defined(__ICL)
# pragma warning(disable: 4786) // identifier truncated in debug info
# pragma warning(disable: 4710) // function not inlined
# pragma warning(disable: 4711) // function selected for automatic inline expansion
# pragma warning(disable: 4514) // unreferenced inline removed
#endif
#include <boost/ref.hpp>
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
# pragma warning(push, 3)
#endif
#include <iostream>
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
# pragma warning(pop)
#endif
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
namespace {
using namespace boost;
template <class T>
struct ref_wrapper
{
// Used to verify implicit conversion
static T* get_pointer(T& x)
{
return &x;
}
static T const* get_const_pointer(T const& x)
{
return &x;
}
template <class Arg>
static T* passthru(Arg x)
{
return get_pointer(x);
}
template <class Arg>
static T const* cref_passthru(Arg x)
{
return get_const_pointer(x);
}
static void test(T x)
{
BOOST_CHECK(passthru(ref(x)) == &x);
BOOST_CHECK(&ref(x).get() == &x);
BOOST_CHECK(cref_passthru(cref(x)) == &x);
BOOST_CHECK(&cref(x).get() == &x);
}
};
struct copy_counter {
static int count_;
copy_counter(copy_counter const& /*other*/) {
++count_;
}
copy_counter() {}
static void reset() { count_ = 0; }
static int count() { return copy_counter::count_; }
};
int copy_counter::count_ = 0;
} // namespace unnamed
template <class T>
void do_unwrap(T t) {
/* typename unwrap_reference<T>::type& lt = */
unwrap_ref(t);
}
void unwrap_test() {
int i = 3;
const int ci = 2;
do_unwrap(i);
do_unwrap(ci);
do_unwrap(ref(i));
do_unwrap(cref(ci));
do_unwrap(ref(ci));
copy_counter cc;
BOOST_CHECK(cc.count() == 0);
do_unwrap(cc);
do_unwrap(ref(cc));
do_unwrap(cref(cc));
BOOST_CHECK(cc.count() == 1);
BOOST_CHECK(unwrap_ref(ref(cc)).count() == 1);
}
int test_main(int, char * [])
{
ref_wrapper<int>::test(1);
ref_wrapper<int const>::test(1);
unwrap_test();
return 0;
}

View File

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Boost: Swap Documentation</title>
</head>
<body>
<!-- Page header -->
<h2>
<img src="../../boost.png" alt="C++ Boost" align="middle" width="277" height="86"/>
Header &lt;<a href="../../boost/swap.hpp">boost/swap.hpp</a>&gt;
</h2>
<h1>Swap</h1>
<p>
<tt>template&lt;class T&gt; void swap(T&amp; <em>left</em>, T&amp; <em>right</em>);</tt>
</p>
<!-- Introduction -->
<p>
The template function <tt>boost::swap</tt> allows the values of two variables to be swapped, using argument dependent lookup to select a specialized swap function if available. If no specialized swap function is available, <tt>std::swap</tt> is used.
</p>
<!-- Rationale -->
<h2>Rationale</h2>
<p>
The generic <tt>std::swap</tt> function requires that the elements to be swapped are assignable and copy constructible. It is usually implemented using one copy construction and two assignments - this is often both unnecessarily restrictive and unnecessarily slow. In addition, where the generic swap implementation provides only the basic guarantee, specialized swap functions are often able to provide the no-throw exception guarantee (and it is considered best practice to do so where possible<sup><a href="#ref1">1</a></sup>).</p>
<p>
The alternative to using argument dependent lookup in this situation is to provide a template specialization of <tt>std::swap</tt> for every type that requires a specialized swap. Although this is legal C++, no Boost libraries use this method, whereas many Boost libraries provide specialized swap functions in their own namespaces.
</p>
<p>
<tt>boost::swap</tt> also supports swapping built-in arrays. Note that <tt>std::swap</tt> originally did not do so, but a request to add an overload of <tt>std::swap</tt> for built-in arrays has been accepted by the C++ Standards Committee<sup><a href="#ref2">2</a></sup>.
</p>
<!-- Exception Safety -->
<h2>Exception Safety</h2>
<p>
<tt>boost::swap</tt> provides the same exception guarantee as the underlying swap function used, with one exception; for an array of type <tt>T[n]</tt>, where <tt>n > 1</tt> and the underlying swap function for <tt>T</tt> provides the strong exception guarantee, <tt>boost::swap</tt> provides only the basic exception guarantee.
</p>
<!-- Requirements -->
<h2>Requirements</h2>
<p>Either:</p>
<ul>
<li>T must be assignable</li>
<li>T must be copy constructible</li>
</ul>
<p>Or:</p>
<ul>
<li>A function with the signature <tt>swap(T&amp;,T&amp;)</tt> is available via argument dependent lookup</li>
</ul>
<p>Or:</p>
<ul>
<li>A template specialization of <tt>std::swap</tt> exists for T</li>
</ul>
<p>Or:</p>
<ul>
<li>T is a built-in array of swappable elements</li>
</ul>
<!-- Portability -->
<h2>Portability</h2>
<p>
Several older compilers do not support argument dependent lookup &#x2012; on these compilers <tt>boost::swap</tt> will call <tt>std::swap</tt>, ignoring any specialized swap functions that could be found as a result of argument dependent lookup.
</p>
<!-- Credits -->
<h2>Credits</h2>
<ul>
<li>
<em>Niels Dekker</em> - for implementing and documenting support for built-in arrays
</li>
<li>
<em><a href="mailto:Joseph.Gauterin@googlemail.com">Joseph Gauterin</a></em> - for the initial idea, implementation, tests, and documentation
</li>
<li>
<em>Steven Watanabe</em> - for the idea to make <tt>boost::swap</tt> less specialized than <tt>std::swap</tt>, thereby allowing the function to have the name 'swap' without introducing ambiguity
</li>
</ul>
<!-- References -->
<hr/>
<p><sup><a id="ref1"/>[1]</sup>Scott Meyers, Effective C++ Third Edition, Item 25: "Consider support for a non-throwing swap"</p>
<p><sup><a id="ref2"/>[2]</sup><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#809">LWG Defect Report 809 (std::swap should be overloaded for array types)</a></p>
<!-- Copyright info -->
<hr/>
<p>Revised: 08 September 2009</p>
<p>
Copyright 2007 - 2009 Joseph Gauterin. 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 a copy at &lt;<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)
</p>
</body>
</html>

View File

@ -1,37 +0,0 @@
# Copyright (c) 2007, 2008 Joseph Gauterin
#
# 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)
# bring in rules for testing
import testing ;
test-suite utility/swap
:
[ compile root_header_1.cpp ]
[ compile root_header_2.cpp ]
[ compile lib_header_1.cpp ]
[ compile lib_header_2.cpp ]
[ compile mixed_headers_1.cpp ]
[ compile mixed_headers_2.cpp ]
[ run primitive.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_global.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_other.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_std.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run specialized_in_boost_and_other.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_bitset.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_dateorder.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_string.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_typeinfo_ptr.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_vector_of_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_vector_of_global.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run std_vector_of_other.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run no_ambiguity_in_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run array_of_array_of_class.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run array_of_array_of_int.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run array_of_class.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run array_of_int.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
[ run array_of_template.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
;

View File

@ -1,69 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in the global namespace
#include "./swap_test_class.hpp"
#include <algorithm> //for std::copy and std::equal
#include <cstddef> //for std::size_t
//Provide swap function in both the namespace of swap_test_class
//(which is the global namespace), and the std namespace.
//It's common to provide a swap function for a class in both
//namespaces. Scott Meyers recommends doing so: Effective C++,
//Third Edition, item 25, "Consider support for a non-throwing swap".
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
namespace std
{
template <>
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const std::size_t first_dimension = 3;
const std::size_t second_dimension = 4;
const std::size_t number_of_elements = first_dimension * second_dimension;
swap_test_class array1[first_dimension][second_dimension];
swap_test_class array2[first_dimension][second_dimension];
swap_test_class* const ptr1 = array1[0];
swap_test_class* const ptr2 = array2[0];
for (std::size_t i = 0; i < number_of_elements; ++i)
{
ptr1[i].set_data( static_cast<int>(i) );
ptr2[i].set_data( static_cast<int>(i + number_of_elements) );
}
boost::swap(array1, array2);
for (std::size_t i = 0; i < number_of_elements; ++i)
{
BOOST_CHECK_EQUAL(ptr1[i].get_data(), static_cast<int>(i + number_of_elements) );
BOOST_CHECK_EQUAL(ptr2[i].get_data(), static_cast<int>(i) );
}
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), number_of_elements);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
return 0;
}

View File

@ -1,42 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping an array of arrays of integers by means of boost::swap.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <algorithm> //for std::copy and std::equal
#include <cstddef> //for std::size_t
int test_main(int, char*[])
{
const std::size_t first_dimension = 3;
const std::size_t second_dimension = 4;
const std::size_t number_of_elements = first_dimension * second_dimension;
int array1[first_dimension][second_dimension];
int array2[first_dimension][second_dimension];
int* const ptr1 = array1[0];
int* const ptr2 = array2[0];
for (std::size_t i = 0; i < number_of_elements; ++i)
{
ptr1[i] = static_cast<int>(i);
ptr2[i] = static_cast<int>(i + number_of_elements);
}
boost::swap(array1, array2);
for (std::size_t i = 0; i < number_of_elements; ++i)
{
BOOST_CHECK_EQUAL(ptr1[i], static_cast<int>(i + number_of_elements) );
BOOST_CHECK_EQUAL(ptr2[i], static_cast<int>(i) );
}
return 0;
}

View File

@ -1,61 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in the global namespace
#include "./swap_test_class.hpp"
#include <algorithm> //for std::copy and std::equal
#include <cstddef> //for std::size_t
//Provide swap function in both the namespace of swap_test_class
//(which is the global namespace), and the std namespace.
//It's common to provide a swap function for a class in both
//namespaces. Scott Meyers recommends doing so: Effective C++,
//Third Edition, item 25, "Consider support for a non-throwing swap".
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
namespace std
{
template <>
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const std::size_t array_size = 2;
const swap_test_class initial_array1[array_size] = { swap_test_class(1), swap_test_class(2) };
const swap_test_class initial_array2[array_size] = { swap_test_class(3), swap_test_class(4) };
swap_test_class array1[array_size];
swap_test_class array2[array_size];
std::copy(initial_array1, initial_array1 + array_size, array1);
std::copy(initial_array2, initial_array2 + array_size, array2);
swap_test_class::reset();
boost::swap(array1, array2);
BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), array_size);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
return 0;
}

View File

@ -1,35 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping an array of integers by means of boost::swap.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <algorithm> //for std::copy and std::equal
#include <cstddef> //for std::size_t
int test_main(int, char*[])
{
const std::size_t array_size = 3;
const int initial_array1[array_size] = { 1, 2, 3 };
const int initial_array2[array_size] = { 4, 5, 6 };
int array1[array_size];
int array2[array_size];
std::copy(initial_array1, initial_array1 + array_size, array1);
std::copy(initial_array2, initial_array2 + array_size, array2);
boost::swap(array1, array2);
BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));
return 0;
}

View File

@ -1,71 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping an array of swap_test_template<int> objects by means of boost::swap.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in the global namespace
#include "./swap_test_class.hpp"
#include <algorithm> //for std::copy and std::equal
#include <cstddef> //for std::size_t
template <class T>
class swap_test_template
{
public:
typedef T template_argument;
swap_test_class swap_test_object;
};
template <class T>
inline bool operator==(const swap_test_template<T> & lhs, const swap_test_template<T> & rhs)
{
return lhs.swap_test_object == rhs.swap_test_object;
}
template <class T>
inline bool operator!=(const swap_test_template<T> & lhs, const swap_test_template<T> & rhs)
{
return !(lhs == rhs);
}
//Provide swap function in the namespace of swap_test_template
//(which is the global namespace). Note that it isn't allowed to put
//an overload of this function within the std namespace.
template <class T>
void swap(swap_test_template<T>& left, swap_test_template<T>& right)
{
left.swap_test_object.swap(right.swap_test_object);
}
int test_main(int, char*[])
{
const std::size_t array_size = 2;
const swap_test_template<int> initial_array1[array_size] = { swap_test_class(1), swap_test_class(2) };
const swap_test_template<int> initial_array2[array_size] = { swap_test_class(3), swap_test_class(4) };
swap_test_template<int> array1[array_size];
swap_test_template<int> array2[array_size];
std::copy(initial_array1, initial_array1 + array_size, array1);
std::copy(initial_array2, initial_array2 + array_size, array2);
swap_test_class::reset();
boost::swap(array1, array2);
BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2));
BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1));
BOOST_CHECK_EQUAL(swap_test_class::swap_count(), array_size);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0);
return 0;
}

View File

@ -1,10 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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)
// Tests that the swap header compiles as a standalone translation unit
#include <boost/utility/swap.hpp>

View File

@ -1,11 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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)
// Tests that the swap header include guards work correctly
#include <boost/utility/swap.hpp>
#include <boost/utility/swap.hpp>

View File

@ -1,11 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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)
// Tests that the swap headers work when both are included
#include <boost/swap.hpp>
#include <boost/utility/swap.hpp>

View File

@ -1,12 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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)
// Tests that the swap headers work when both are included
#include <boost/utility/swap.hpp>
#include <boost/swap.hpp>

View File

@ -1,44 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// boost::swap internally does an unqualified function call to swap.
// This could have led to ambiguity or infinite recursion, when the
// objects to be swapped would themselves be from the boost namespace.
// If so, boost::swap itself might be found by argument dependent lookup.
// The implementation of boost::swap resolves this issue by giving
// boost::swap two template argumetns, thereby making it less specialized
// than std::swap.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in namespace boost
namespace boost
{
#include "./swap_test_class.hpp"
}
int test_main(int, char*[])
{
const boost::swap_test_class initial_value1(1);
const boost::swap_test_class initial_value2(2);
boost::swap_test_class object1 = initial_value1;
boost::swap_test_class object2 = initial_value2;
boost::swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(boost::swap_test_class::swap_count(),0);
BOOST_CHECK_EQUAL(boost::swap_test_class::copy_count(),3);
return 0;
}

View File

@ -1,23 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
int test_main(int, char*[])
{
int object1 = 1;
int object2 = 2;
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1,2);
BOOST_CHECK_EQUAL(object2,1);
return 0;
}

View File

@ -1,10 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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)
// Tests that the swap header compiles as a standalone translation unit
#include <boost/swap.hpp>

View File

@ -1,11 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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)
// Tests that the swap header include guards work correctly
#include <boost/swap.hpp>
#include <boost/swap.hpp>

View File

@ -1,45 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in namespace boost
namespace boost
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace boost
namespace boost
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const boost::swap_test_class initial_value1(1);
const boost::swap_test_class initial_value2(2);
boost::swap_test_class object1 = initial_value1;
boost::swap_test_class object2 = initial_value2;
boost::swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(boost::swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(boost::swap_test_class::copy_count(),0);
return 0;
}

View File

@ -1,64 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests whether instances of a class from a namespace other than boost are
// properly swapped, when both boost and the other namespace have a custom
// swap function for that class. Note that it shouldn't be necessary for a class
// in an other namespace to have a custom swap function in boost, because the
// boost::swap utility should find the swap function in the other namespace, by
// argument dependent lookup (ADL). Unfortunately ADL isn't fully implemented
// by some specific compiler versions, including Intel C++ 8.1, MSVC 7.1, and
// Borland 5.9.3. Users of those compilers might consider adding a swap overload
// to the boost namespace.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in namespace other
namespace other
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace boost
namespace boost
{
void swap(::other::swap_test_class& left, ::other::swap_test_class& right)
{
left.swap(right);
}
}
//Provide swap function in namespace other
namespace other
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const other::swap_test_class initial_value1(1);
const other::swap_test_class initial_value2(2);
other::swap_test_class object1 = initial_value1;
other::swap_test_class object2 = initial_value2;
other::swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(other::swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(other::swap_test_class::copy_count(),0);
return 0;
}

View File

@ -1,39 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in the global namespace
#include "./swap_test_class.hpp"
//Provide swap function in gloabl namespace
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
int test_main(int, char*[])
{
const swap_test_class initial_value1(1);
const swap_test_class initial_value2(2);
swap_test_class object1 = initial_value1;
swap_test_class object2 = initial_value2;
swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(),0);
return 0;
}

View File

@ -1,45 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in namespace other
namespace other
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace other
namespace other
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const other::swap_test_class initial_value1(1);
const other::swap_test_class initial_value2(2);
other::swap_test_class object1 = initial_value1;
other::swap_test_class object2 = initial_value2;
other::swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(other::swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(other::swap_test_class::copy_count(),0);
return 0;
}

View File

@ -1,44 +0,0 @@
// Copyright (c) 2007 Joseph Gauterin
//
// 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/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
//Put test class in the global namespace
#include "./swap_test_class.hpp"
//Provide swap function in namespace std
namespace std
{
template <>
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
const swap_test_class initial_value1(1);
const swap_test_class initial_value2(2);
swap_test_class object1 = initial_value1;
swap_test_class object2 = initial_value2;
swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class::swap_count(),1);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(),0);
return 0;
}

View File

@ -1,33 +0,0 @@
// Copyright (c) 2008 - 2010 Joseph Gauterin, 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)
// Tests swapping std::bitset<T> objects by means of boost::swap.
// Unlike most other Standard C++ Library template classes,
// std::bitset<T> does not have its own std::swap overload.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <bitset>
int test_main(int, char*[])
{
typedef std::bitset<8> bitset_type;
const bitset_type initial_value1 = 1;
const bitset_type initial_value2 = 2;
bitset_type object1 = initial_value1;
bitset_type object2 = initial_value2;
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1);
return 0;
}

View File

@ -1,32 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping std::time_base::dateorder objects by means of boost::swap.
// std::time_base::dateorder is an enumerated type. It does not have an
// std::swap overload or template specialization.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <locale>
int test_main(int, char*[])
{
const std::time_base::dateorder initial_value1 = std::time_base::dmy;
const std::time_base::dateorder initial_value2 = std::time_base::mdy;
std::time_base::dateorder object1 = initial_value1;
std::time_base::dateorder object2 = initial_value2;
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1);
return 0;
}

View File

@ -1,31 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping std::string objects by means of boost::swap.
// std::string has its own std::swap overload.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <string>
int test_main(int, char*[])
{
const std::string initial_value1 = "one";
const std::string initial_value2 = "two";
std::string object1 = initial_value1;
std::string object2 = initial_value2;
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1,initial_value2);
BOOST_CHECK_EQUAL(object2,initial_value1);
return 0;
}

View File

@ -1,32 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping std::type_info pointers by means of boost::swap.
// There is no std::swap overload or template specialization
// for std::type_info pointers.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <typeinfo>
int test_main(int, char*[])
{
const std::type_info * const initial_value1 = 0;
const std::type_info * const initial_value2 = &typeid(double);
const std::type_info * ptr1 = initial_value1;
const std::type_info * ptr2 = initial_value2;
boost::swap(ptr1,ptr2);
BOOST_CHECK_EQUAL(ptr1,initial_value2);
BOOST_CHECK_EQUAL(ptr2,initial_value1);
return 0;
}

View File

@ -1,60 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping std::vector objects by means of boost::swap,
// having boost::swap_test_class as vector element type.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <vector>
//Put test class in namespace boost
namespace boost
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace boost
namespace boost
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
typedef boost::swap_test_class swap_test_class_type;
typedef std::vector<swap_test_class_type> vector_type;
const vector_type::size_type initial_size1 = 1;
const vector_type::size_type initial_size2 = 2;
const vector_type initial_value1(initial_size1, swap_test_class_type(1));
const vector_type initial_value2(initial_size2, swap_test_class_type(2));
vector_type object1 = initial_value1;
vector_type object2 = initial_value2;
swap_test_class_type::reset();
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class_type::swap_count(),0);
BOOST_CHECK_EQUAL(swap_test_class_type::copy_count(),0);
return 0;
}

View File

@ -1,53 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping std::vector objects by means of boost::swap,
// having ::swap_test_class as vector element type.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <vector>
//Put test class in the global namespace
#include "./swap_test_class.hpp"
//Provide swap function in the global namespace
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
int test_main(int, char*[])
{
typedef std::vector<swap_test_class> vector_type;
const vector_type::size_type initial_size1 = 1;
const vector_type::size_type initial_size2 = 2;
const vector_type initial_value1(initial_size1, swap_test_class(1));
const vector_type initial_value2(initial_size2, swap_test_class(2));
vector_type object1 = initial_value1;
vector_type object2 = initial_value2;
swap_test_class::reset();
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class::swap_count(),0);
BOOST_CHECK_EQUAL(swap_test_class::copy_count(),0);
return 0;
}

View File

@ -1,60 +0,0 @@
// Copyright (c) 2008 Joseph Gauterin, 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)
// Tests swapping std::vector objects by means of boost::swap,
// having other::swap_test_class as vector element type.
#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <vector>
//Put test class in namespace other
namespace other
{
#include "./swap_test_class.hpp"
}
//Provide swap function in namespace other
namespace other
{
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
}
}
int test_main(int, char*[])
{
typedef other::swap_test_class swap_test_class_type;
typedef std::vector<swap_test_class_type> vector_type;
const vector_type::size_type initial_size1 = 1;
const vector_type::size_type initial_size2 = 2;
const vector_type initial_value1(initial_size1, swap_test_class_type(1));
const vector_type initial_value2(initial_size2, swap_test_class_type(2));
vector_type object1 = initial_value1;
vector_type object2 = initial_value2;
swap_test_class_type::reset();
boost::swap(object1,object2);
BOOST_CHECK_EQUAL(object1.size(),initial_size2);
BOOST_CHECK_EQUAL(object2.size(),initial_size1);
BOOST_CHECK(object1 == initial_value2);
BOOST_CHECK(object2 == initial_value1);
BOOST_CHECK_EQUAL(swap_test_class_type::swap_count(),0);
BOOST_CHECK_EQUAL(swap_test_class_type::copy_count(),0);
return 0;
}

View File

@ -1,114 +0,0 @@
// Copyright (c) 2007-2008 Joseph Gauterin
//
// 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)
// Tests class used by the Boost.Swap tests
#ifndef BOOST_UTILITY_SWAP_TEST_CLASS_HPP
#define BOOST_UTILITY_SWAP_TEST_CLASS_HPP
class swap_test_class
{
int m_data;
public:
explicit swap_test_class(int arg = 0)
:
m_data(arg)
{
++constructCount();
}
~swap_test_class()
{
++destructCount();
}
swap_test_class(const swap_test_class& arg)
:
m_data(arg.m_data)
{
++copyCount();
++destructCount();
}
swap_test_class& operator=(const swap_test_class& arg)
{
m_data = arg.m_data;
++copyCount();
return *this;
}
void swap(swap_test_class& other)
{
const int temp = m_data;
m_data = other.m_data;
other.m_data = temp;
++swapCount();
}
int get_data() const
{
return m_data;
}
void set_data(int arg)
{
m_data = arg;
}
static unsigned int swap_count(){ return swapCount(); }
static unsigned int copy_count(){ return copyCount(); }
static unsigned int construct_count(){ return constructCount(); }
static unsigned int destruct_count(){ return destructCount(); }
static void reset()
{
swapCount() = 0;
copyCount() = 0;
constructCount() = 0;
destructCount() = 0;
}
private:
static unsigned int& swapCount()
{
static unsigned int value = 0;
return value;
}
static unsigned int& copyCount()
{
static unsigned int value = 0;
return value;
}
static unsigned int& constructCount()
{
static unsigned int value = 0;
return value;
}
static unsigned int& destructCount()
{
static unsigned int value = 0;
return value;
}
};
inline bool operator==(const swap_test_class & lhs, const swap_test_class & rhs)
{
return lhs.get_data() == rhs.get_data();
}
inline bool operator!=(const swap_test_class & lhs, const swap_test_class & rhs)
{
return !(lhs == rhs);
}
#endif

View File

@ -11,33 +11,28 @@ import testing ;
alias unit_test_framework
: # sources
/boost//unit_test_framework
;
;
# Please keep the tests ordered by filename
test-suite utility
:
[ run ../addressof_fn_test.cpp ]
[ run ../addressof_test.cpp ]
[ run ../addressof_test2.cpp ]
[ run ../assert_test.cpp ]
[ run ../base_from_member_test.cpp ]
[ run ../binary_search_test.cpp ]
[ run ../base_from_member_ref_test.cpp ]
[ run ../binary_test.cpp ]
[ run ../call_traits_test.cpp : -u ]
[ compile-fail ../checked_delete_test.cpp ]
[ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>static : -u ]
[ run ../current_function_test.cpp : : : <test-info>always_show_run_output ]
[ 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 ]
[ compile-fail ../noncopyable_test.cpp ]
[ run ../numeric_traits_test.cpp ]
[ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
[ compile ../ref_ct_test.cpp ]
[ run ../ref_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 ]
@ -46,6 +41,7 @@ test-suite utility
[ compile-fail ../value_init_test_fail3.cpp ]
[ compile-fail ../initialized_test_fail1.cpp ]
[ compile-fail ../initialized_test_fail2.cpp ]
[ run ../verify_test.cpp ]
[ run ../generator_iterator_test.cpp ]
;

18
test/next_prior_test.cpp Executable file → Normal file
View File

@ -66,14 +66,32 @@ bool minus_n_test(RandomAccessIterator first, RandomAccessIterator last, Bidirec
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;
}

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