Compare commits

...

171 Commits

Author SHA1 Message Date
7aafdf92a0 [skip ci] Merge pull request #71 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-01-20 11:18:10 +03:00
a7570d7608 [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-19 22:19:49 -05:00
37168a3f4b Use address-model=32 for msvc-9.0, 10.0, 11.0 2020-10-12 00:01:10 +03:00
e56171989a Merge pull request #69 from giomasce-throwaway/develop
Fix copyright headers.
2020-10-11 11:48:14 -04:00
f00a5bf0d3 Fix copyright headers. 2020-10-11 17:35:14 +02:00
a4feaf4f24 Merge pull request #66 from boostorg/feature/value-init
Add a new value_init test, change implementation to not depend on TypeTraits
2020-05-27 12:51:45 +03:00
688628f764 Add test/value_init_test3 2020-05-26 00:39:51 +03:00
8faf831bd1 memset data_ instead of *this 2020-05-25 23:50:35 +03:00
25cb7aa122 Use a base class to apply the memset workaround to avoid dependency on TypeTraits 2020-05-25 05:09:36 +03:00
0ae5cebc7f Add value_init_test2.cpp, which tests the cases from value_init_workaround_test 2020-05-25 04:44:29 +03:00
1caa002121 Added gcc 10 build jobs to Travis CI. 2020-05-22 18:46:41 +03:00
691f3238d7 Use 20 instead of 2a to refer to C++20 in Travis CI. 2020-05-05 23:12:01 +03:00
8b6da499a3 Added clang-10 jobs to Travis CI. 2020-05-05 23:02:58 +03:00
6e6d0777e8 Merge pull request #64 from glenfe/develop
Update to Operators constexpr support
2020-04-12 13:33:17 -04:00
64fffa0f97 Simplify BOOST_OPERATORS_CONSTEXPR definition 2020-04-12 13:03:30 -04:00
5da340a2a4 Rename BOOST_OPS_CONSTEXPR to BOOST_OPERATORS_CONSTEXPR 2020-04-12 13:03:22 -04:00
9a4cff038b Move constexpr operators test to separate test 2020-04-12 13:03:18 -04:00
0c059a50ad Merge pull request #63 from eldiener/develop
Changes for Embarcadero C++ clang-based compilers, targeting Boost 1.74. Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost conf…
2020-04-12 09:49:06 -07:00
bdc5b5cf3a Merge pull request #55 from tonyelewis/add-constexpr-support
Add constexpr to operators (w/ basic docs, tests)
2020-04-12 13:07:24 +02:00
86e7caefea Update CMakeLists.txt 2020-04-11 14:14:33 -04:00
7953ba56ba Update tests to run constexpr on newer MSVCs 2020-04-11 18:39:15 +01:00
46f72656b3 Remove constexpr from all but the comparison ops 2020-04-11 18:31:15 +01:00
e3a2a06011 Re-add constexpr support for newer MSVC versions 2020-04-11 18:30:24 +01:00
a4752e066d Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers. 2020-03-24 01:39:51 -04:00
957aeba2e9 Update Travis and Appveyor configurations 2019-12-15 10:39:10 -05:00
2b436d7d50 Use ostream_put from Boost.IO 2019-12-15 09:46:38 -05:00
882c9c86c4 More detabification 2019-12-12 06:00:51 +02:00
c81d8e3990 Add <cstdio> for EOF; detabify, remove trailing whitespace 2019-12-12 05:57:51 +02:00
75276a055d Disabled all but one OS X jobs because they are slow on Travis CI. 2019-10-22 15:11:41 +03:00
309e6a1b31 Updated CI configs, added compilers. 2019-10-22 00:52:54 +03:00
9eeb7f85c5 Replaced tabs with spaces. 2019-06-25 15:46:36 +03:00
62c34f51f6 Avoid confusion with the spaceship operator, fixes #59 2019-04-30 18:29:28 +02:00
6a1917ceec Add Free Functions section heading 2019-04-29 20:12:30 -04:00
47c9f69ffe Correct documentation URLs and update documentation 2019-04-29 18:48:51 -04:00
7b74d2d494 Update libraries.json and documentation 2019-04-23 15:37:57 -04:00
57da5f0c18 Merge pull request #58 from boostorg/ostream_write
Refactor stream write functionality into a standalone utility
2019-04-23 03:56:04 -07:00
dabf53a703 Refactor stream write functionality into a standalone utility 2019-04-19 09:53:29 -04:00
ff56b3649e Merge pull request #57 from glenfe/develop
Make string_view operator<< use rdbuf directly
2019-04-18 09:00:53 -07:00
31e0ae4c37 Switch Appveyor to 2015 image 2019-04-14 18:13:56 +03:00
5fe9df91c0 Make string_view operator<< use rdbuf directly 2019-04-12 18:06:35 -04:00
f03b681d01 Increased the number of git fetch jobs to 8 in CI. 2019-01-15 18:34:38 +03:00
e120a83d1e Revert "Use depinst to install dependencies in CI. Increase the number of git fetch jobs to 8."
This reverts commit 424fea5881.

By request from Peter Dimov in 424fea5881 (commitcomment-31945411).

The manual enumeration of Boost.Utility dependencies server as a detection
mechanism for unwanted dependencies creep in.
2019-01-15 18:28:28 +03:00
424fea5881 Use depinst to install dependencies in CI. Increase the number of git fetch jobs to 8. 2019-01-15 14:06:11 +03:00
53d9aa9d2f Use the actual number of logical CPUs for the number of CI build/test jobs. 2019-01-03 23:23:55 +03:00
6b62dcc504 Completely remove constexpr for MSVC 2018-12-24 07:02:31 +00:00
91ebdcd1dd Remove C++14 constexpr due to MSVC/GCC problems 2018-12-22 15:52:13 +00:00
e8d2b2ba76 Add constexpr to operators (w/ basic docs, tests) 2018-12-21 10:28:22 +00:00
ce64b13846 Added tools/boost_install and libs/headers manual checkout to CI jobs. 2018-12-18 22:14:06 +03:00
32c50e0814 Added an experimental partial CMakeLists.txt for dependency tracking in CMake projects. 2018-12-18 19:51:11 +03:00
05dda09fd3 Added libstdc++5 installation in the clang 7 job.
Apparently, a more recent libstdc++ is needed by Boost.StringView in C++14
and later mode.
2018-11-02 12:12:15 +03:00
a4cafcc75d Added gcc 8 and clang 7 CI jobs. 2018-11-01 20:36:52 +03:00
796fb965be Merge branch 'develop' 2018-11-01 17:17:11 +03:00
08da98a551 Added a readme file.
For Boost.Utility logo thanks to Adam Wulkiewicz. The logo was taken from:

https://github.com/awulkiew/boost-logos
2018-11-01 17:09:34 +03:00
57b027f1cd Merge branch 'develop' 2018-09-23 08:47:11 -04:00
db05c11f50 Fix string_ref::find/rfind's handling of empty strings. Thanks to 'reluctantbugreporter' for the bug report 2018-09-14 09:48:13 -07:00
3d2a7f0c17 Merge pull request #49 from boostorg/final
Avoid inheritance for final types in compressed_pair
2018-09-12 22:29:26 -04:00
8858bad352 Merge pull request #38 from danieljames/feature/fix-links
Fix some links
2018-09-11 08:35:08 -04:00
fc135e0d72 Avoid inheritance for final types in compressed_pair 2018-09-09 17:34:22 -04:00
ebe44296ca Add boilerplate reference to LICENSE_1_0.txt 2018-07-31 01:46:53 +03:00
bdf55e0b6f Add boilerplate reference to LICENSE_1_0.txt 2018-07-31 00:22:42 +03:00
d4170ccdb5 Merge pull request #45 from dimztimz/develop
Implement boost hash for string_view
2018-05-01 07:51:36 -07:00
e2d115db97 Use hash_fwd.hpp in string_view for more lightweight dependencies. 2018-04-20 23:18:31 +02:00
15cfa44937 Boost detail is dependency of boost hash. 2018-04-20 14:07:33 +02:00
473be2e4c1 Boost integer is dependency of boost hash. 2018-04-20 13:58:12 +02:00
6ad6bc005c Implement boost hash for string_view 2018-04-20 13:42:07 +02:00
7709f0e430 Merge pull request #42 from dimztimz/develop
Faster find functions in string_view by using traits::find()
2018-04-09 16:34:23 -07:00
eacea4664d implement string_view.find(string) in terms of traits.compare and find.
This should be faster that it's previous implementations
in terms of std::search()
2018-04-02 00:52:57 +02:00
1fe5af5264 Faster find functions in string_view by using traits::find() 2018-04-01 20:00:03 +02:00
d2fb06e6a0 Fix another link 2018-01-12 10:48:52 +00:00
73baeb7a63 Fix some links 2018-01-11 18:01:50 +00:00
56f13625b1 Fix link to declval 2017-12-24 00:33:12 +02:00
ac4e8da91d Only install the necessary submodules in Travis and Appveyor 2017-12-24 00:28:06 +02:00
426836d860 Remove shared_iterator files (they're in Iterator now) 2017-12-24 00:05:50 +02:00
82df2b82fc Merge pull request #37 from glenfe/develop
Utility tests should use lightweight_test instead of test
2017-12-23 21:52:07 +02:00
f8a243bcff Utility tests should use lightweight_test instead of test 2017-12-23 13:00:33 -05:00
51f7f7f53e Add -d0 to b2 headers on Appveyor 2017-12-23 12:01:03 +02:00
5f535a151c Add -j3 to Travis 2017-12-23 11:56:09 +02:00
c88936800d Remove dependency on Random in operators_test.cpp 2017-12-23 06:19:43 +02:00
96fbce5759 Remove use of shared_ptr in test/value_init_test.cpp 2017-12-23 04:44:29 +02:00
9d46de1578 Replace use of mpl/has_xxx.hpp with handwritten traits 2017-12-21 06:30:03 +02:00
976a4d2fc1 Merge branch 'develop' into feature/result_of-no-mpl 2017-12-20 23:16:08 +02:00
ea81279b35 Add appveyor.yml 2017-12-20 23:14:36 +02:00
7d101d420c Replace mpl primitives with type_traits 2017-12-20 21:55:07 +02:00
d8acfef27b Update includes in utility.hpp; add deprecation comment 2017-12-02 04:35:22 +02:00
d7ae336915 Merge branch 'master' into develop 2017-12-02 03:47:03 +02:00
b74f49f1e5 Remove dependency on iterator in <boost/utility.hpp> 2017-12-02 03:38:29 +02:00
5977f11be8 Merge pull request #36 from boostorg/develop
Protect dereferenceable<> against overloaded operator&, fixes #35
2017-12-01 20:59:24 +01:00
ad0fc7c9d3 Protect dereferenceable<> against overloaded operator&, fixes #35 2017-11-23 21:14:07 +01:00
a6c175e2c3 clang 3.5 can't handle libstdc++-5 2017-10-28 14:11:41 +03:00
874ca2307b Update clangs to libstdc++-5-dev for constexpr std::min 2017-10-28 04:49:50 +03:00
5220260145 Update .travis.yml 2017-10-27 15:31:19 +03:00
2f5a6fbcf1 Adapt to C++17, fixes #34 2017-10-15 10:34:04 +02:00
51ba9f1b45 Add one more case to value_init_workaround_test 2017-09-24 12:47:05 +03:00
5cef1403b0 Merge pull request #33 from morinmorin/fix_no_expr_sfinae
result_of<F&(…)> fails on MSVC-12 if F is a function pointer
2017-09-23 21:59:06 +03:00
81ce4693f6 Add tests for result_of<F&(...)> in C++11. 2017-09-20 23:44:35 +09:00
fb2f110eb4 Fix result_of_is_callable to support references to function pointers.
On compilers without the support of expression SFINAE, decltype-based
result_of<FP&(...)> failed to compile (FP is a function pointer type).
2017-09-20 23:40:56 +09:00
2ed5ee9588 Moved numeric_traits_test.cpp to Boost.Detail. 2017-09-20 01:42:15 +03:00
88c36c1941 Remove generator iterator test and docs as these were moved to Boost.Iterator. 2017-08-28 20:41:11 +03:00
0b2409a942 Updated links to next/prior docs. 2017-08-26 20:07:12 +03:00
62b39548be Moved next/prior to Boost.Iterator. 2017-08-26 17:25:14 +03:00
2722fdcda3 Use std::iterator_traits to detect iterators, when possible.
This allows next/prior to detect user's iterators that do not
define iterator_category nested type but specialize
std::iterator_traits instead.
2017-07-23 20:29:25 +03:00
792d0538d2 Merge branch 'develop' 2017-07-17 20:47:57 +03:00
06ae661775 Merge pull request #31 from Lastique/next_prior_use_traversal
Use Boost.Iterator to advance iterators.
2017-07-13 21:04:18 +03:00
d9d076874e Merge branch 'develop' 2017-07-13 20:59:28 +03:00
e25d85446e Use Boost.Iterator to advance iterators.
By using Boost.Iterator we rely on the separate traversal category instead of
the standard iterator category to advance iterators efficiently. For instance,
this allows to advance transform iterators over a random access sequence
in constant time, despite that they are formally input iterators.

Also, std::reverse_iterator formally requires at least bidirectional iterator
as the underlying iterator type. Transform iterators from the example above
don't qualify, so potentially std::reverse_iterator could fail to compile.
2017-07-12 21:15:20 +03:00
5bc9e47688 Changed iterator_category nested type detection to work with MSVC and different versions of gcc. 2017-07-12 20:14:48 +03:00
ec50f22b8b Merge pull request #30 from Lastique/fix_next_prior_for_iterators
Fix next/prior for iterators
2017-07-09 13:41:03 +03:00
592382dc61 Add test cases for std::reverse_iterator 2017-07-09 03:10:10 +03:00
6cf9c22cf1 Reworked iterator handling in next/prior helpers.
The new implementation tries to detect if the incremented/decremented type
is an iterator first and if not falls back to operator probing. This way
iterators that are not SFINAE-friendly (i.e. unconditionally define
arithmetic operators regardless of the iterator category) are still treated
as iterators through std::advance and do not fail the compilation.

The iterator detection is based on probing for the nested iterator_category
type that is expected to be present in class-type iterators. This heuristic
is not flawless since iterators are not required to defined this type.
User-defined iterators may not have it and instead specialize
std::iterator_traits. This use case is not covered by the current implementation
and will likely fail to compile. With C++17 SFINAE-friendly std::iterator_traits
this can be fixed, but currently Boost.Config lacks the macro to detect
availability of this feature. Support for it can be added by a later commit.

Also simplified boost::prior for iterators, removing the possibility of
integer overflow caused by negation of the distance value.
2017-07-09 03:10:01 +03:00
33475f87e4 Merge branch 'develop' 2017-05-30 15:08:09 +03:00
21261a8630 Add visible dependency to result_of_iterate.hpp 2017-05-30 01:20:02 +03:00
7d60e8e378 Merge branch 'develop' 2017-05-30 00:56:41 +03:00
10ff4d4fcd Try to upgrade libstdc++ for clang in 14/1z mode 2017-05-29 21:27:57 +03:00
89bf74beee Add .travis.yml 2017-05-29 19:16:28 +03:00
bfdcce0f97 Move test files to test/ 2017-05-29 19:10:46 +03:00
330b49d602 Mark comparison operators for string_view as constexpr; add tests. Reference: https://svn.boost.org/trac/boost/ticket/12896 2017-05-03 19:58:02 -07:00
68b26cddbe Merge branch 'develop' of github.com:boostorg/utility into develop 2017-04-06 07:59:12 -07:00
6c4ab93573 Revert change disallowing construction of string_view/string_ref from rvalue string 2017-03-28 15:17:09 +02:00
0876da45db Fix potential overflow in substr; Trac #11536. Also change string_view::copy to use the traits::copy 2017-02-13 10:49:17 -08:00
00f02167e3 Add tests to ensure that string_view|ref from rvalue fails (whenever it can) 2017-02-13 10:25:04 -08:00
9960d9f395 Don't construct string_view|string_ref from rvalue string. That way lies pain 2017-02-13 08:15:44 -08:00
ccfd741c0a Merge pull request #27 from MarcelRaad/patch-1
Use non-deprecated include paths
2016-12-21 12:20:20 +04:00
c5c479d49c Use non-deprecated include paths
According to the comments in these two headers, the files in the core directory should be used instead.
2016-12-21 08:22:35 +01:00
3e8f73c6ac Merge pull request #26 from Surrog/develop
Fixing visual studio compilation of string_view::at(); preserving C++11 constexpr-ness.
2016-12-12 17:22:29 -08:00
38121f2af3 Allow string_view::at() to be constexpr again on VS2015
VS2015 doesn't support extended constexpr. Thanks to Lastique for the
ternary trick
2016-12-12 23:45:34 +01:00
38b536ff05 Fixing visual studio compilation of string_view::at()
VS2013, VS2015 & VS2017RC don't like the ternary throwing an exception :
'return': cannot convert from 'void' to 'const char &'
Now using classic if when compiling on a windows platform.
2016-12-12 22:57:56 +01:00
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
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
69 changed files with 5173 additions and 2329 deletions

382
.travis.yml Normal file
View File

@ -0,0 +1,382 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright 2019 Andrey Semashev
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
sudo: false
python: "2.7"
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
# gcc, Linux
- os: linux
dist: trusty
compiler: gcc-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: gcc-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: gcc-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: xenial
compiler: gcc-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: gcc-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-9
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
dist: bionic
compiler: gcc-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,20
addons:
apt:
packages:
- g++-10
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
# clang, Linux
- os: linux
dist: trusty
compiler: clang-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.5
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.5 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: trusty
compiler: clang-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.6
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.6 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: trusty
compiler: clang-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.7
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.7 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.8 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-4
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-5
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
- libstdc++-7-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-5.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-6
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-6.0
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-7
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-7 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-8
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-9
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-9
- libstdc++-9-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-10
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20
addons:
apt:
packages:
- clang-10
- libstdc++-9-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-libc++
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,20 CXXFLAGS="-stdlib=libc++" LINKFLAGS="-stdlib=libc++"
addons:
apt:
packages:
- clang-10
- libc++-10-dev
- libc++abi-10-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
# clang, OS X
# OS X builds are slow on Travis CI
# - os: osx
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
# osx_image: xcode9.4
#
# - os: osx
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
# osx_image: xcode10.3
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17
osx_image: xcode11.2
install:
- GIT_FETCH_JOBS=8
- BOOST_BRANCH=develop
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
- cd ..
- git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init tools/build
- git submodule init tools/boost_install
- git submodule init libs/headers
- git submodule init libs/assert
- git submodule init libs/config
- git submodule init libs/core
- git submodule init libs/io
- git submodule init libs/preprocessor
- git submodule init libs/static_assert
- git submodule init libs/throw_exception
- git submodule init libs/type_traits
- git submodule init libs/container_hash
- git submodule init libs/integer
- git submodule init libs/detail
- git submodule update --jobs $GIT_FETCH_JOBS
- cp -r $TRAVIS_BUILD_DIR/* libs/utility
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- BUILD_JOBS=`(nproc || sysctl -n hw.ncpu) 2> /dev/null`
- ./b2 -j $BUILD_JOBS libs/utility/test toolset=$TOOLSET cxxstd=$CXXSTD ${CXXFLAGS:+cxxflags="$CXXFLAGS"} ${LINKFLAGS:+linkflags="$LINKFLAGS"}
notifications:
email:
on_success: always

28
CMakeLists.txt Normal file
View File

@ -0,0 +1,28 @@
# Copyright 2018 Peter Dimov
# Copyright 2018 Andrey Semashev
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
# Partial (add_subdirectory only) and experimental CMake support
# Subject to change; please do not rely on the contents of this file yet.
cmake_minimum_required(VERSION 3.5)
project(BoostUtility LANGUAGES CXX)
add_library(boost_utility INTERFACE)
add_library(Boost::utility ALIAS boost_utility)
target_include_directories(boost_utility INTERFACE include)
target_link_libraries(boost_utility
INTERFACE
Boost::config
Boost::container_hash
Boost::core
Boost::io
Boost::preprocessor
Boost::static_assert
Boost::throw_exception
Boost::type_traits
)

24
README.md Normal file
View File

@ -0,0 +1,24 @@
# ![Boost.Utility](doc/logo.png)
Boost.Utility, part of collection of the [Boost C++ Libraries](https://github.com/boostorg), provides a number of smaller components, too small to be called libraries in their own right. See the documentation for the list of components.
### Directories
* **doc** - Documentation sources
* **include** - Interface headers of Boost.Utility
* **test** - Boost.Utility unit tests
### More information
* [Documentation](https://boost.org/libs/utility)
* [Report bugs](https://github.com/boostorg/utility/issues/new). Be sure to mention Boost version, Boost.Utility component, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
### Build status
Master: [![Travis CI](https://travis-ci.org/boostorg/utility.svg?branch=master)](https://travis-ci.org/boostorg/utility)
Develop: [![Travis CI](https://travis-ci.org/boostorg/utility.svg?branch=develop)](https://travis-ci.org/boostorg/utility)
### License
Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).

89
appveyor.yml Normal file
View File

@ -0,0 +1,89 @@
# Copyright 2016-2019 Peter Dimov
# Copyright 2019 Andrey Semashev
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
- /feature\/.*/
environment:
matrix:
- TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
ADDRMD: 32
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-12.0,msvc-14.0
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-14.1
CXXSTD: 14,17
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: msvc-14.2
ADDRMD: 32,64
CXXSTD: 14,17
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- TOOLSET: clang-win
ADDRMD: 32,64
CXXSTD: 14,17
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\cygwin\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\cygwin64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\mingw\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
install:
- set GIT_FETCH_JOBS=8
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init tools/build
- git submodule init tools/boost_install
- git submodule init libs/headers
- git submodule init libs/assert
- git submodule init libs/config
- git submodule init libs/core
- git submodule init libs/io
- git submodule init libs/preprocessor
- git submodule init libs/static_assert
- git submodule init libs/throw_exception
- git submodule init libs/type_traits
- git submodule init libs/container_hash
- git submodule init libs/integer
- git submodule init libs/detail
- git submodule update --jobs %GIT_FETCH_JOBS%
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\utility\
- cmd /c bootstrap
- b2 -d0 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j %NUMBER_OF_PROCESSORS% libs/utility/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release

View File

@ -493,7 +493,7 @@ call_traits can not be used with reference or array types.</p>
<h4>Example 1:</h4>
<p>The following class is a trivial class that stores some type T
by value (see the <a href="call_traits_test.cpp">call_traits_test.cpp</a>
by value (see the <a href="test/call_traits_test.cpp">call_traits_test.cpp</a>
file), the aim is to illustrate how each of the available
call_traits typedefs may be used:</p>

View File

@ -117,3 +117,11 @@ boostbook standalone_string_ref
# 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 ;

View File

@ -356,7 +356,7 @@ 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
library. Contributed the test file [@../../test/base_from_member_test.cpp
base_from_member_test.cpp].
[endsect]

View File

@ -1,6 +1,6 @@
[/
/ Copyright (c) 2008 Howard Hinnant
/ Copyright (c) 2009-20012 Vicente J. Botet Escriba
/ Copyright (c) 2009-2012 Vicente J. Botet Escriba
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

BIN
doc/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

539
doc/logo.svg Normal file
View File

@ -0,0 +1,539 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg6858"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="utility.svg">
<defs
id="defs6860">
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
id="linearGradient10687-2-5"
gradientUnits="userSpaceOnUse"
x1="753.02301"
y1="3132.0801"
x2="1146.25"
y2="3132.0801" />
<linearGradient
id="linearGradient4453-7-8-6-7-3-5">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop4455-61-8-7-1-2-8" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop4457-4-1-9-1-12-1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
id="linearGradient10685-2-2"
gradientUnits="userSpaceOnUse"
x1="753.02301"
y1="3132.0801"
x2="1146.25"
y2="3132.0801" />
<linearGradient
id="linearGradient6749">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6751" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6753" />
</linearGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3387-3-6-4-2-8-4">
<path
inkscape:connector-curvature="0"
d="m 862.109,3289.75 -109.086,-190.45 69.122,-124.42 164.511,-0.47 c 0,0 111.044,188.28 116.564,197.63 7.66,0 43.03,0 43.03,0 l -67.03,117.71 -217.111,0 z"
id="path3389-2-0-7-7-8-9" />
</clipPath>
<linearGradient
y2="3132.0801"
x2="1146.25"
y1="3132.0801"
x1="753.02301"
gradientUnits="userSpaceOnUse"
id="linearGradient4492-8-8"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
inkscape:collect="always" />
<linearGradient
id="linearGradient6758">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6760" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6762" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
id="linearGradient10691-7-8"
gradientUnits="userSpaceOnUse"
x1="1026.6899"
y1="2937.73"
x2="1463.14"
y2="2937.73" />
<linearGradient
id="linearGradient6765">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6767" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6769" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
id="linearGradient10689-4-2"
gradientUnits="userSpaceOnUse"
x1="1026.6899"
y1="2937.73"
x2="1463.14"
y2="2937.73" />
<linearGradient
id="linearGradient6772">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6774" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6776" />
</linearGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3369-1-5-6-1-0-7">
<path
inkscape:connector-curvature="0"
d="m 1131.64,3128.5 -104.95,-181.12 116.38,-200.42 208.05,0.94 112.02,191.63 -112.08,188.97 -219.42,0 z"
id="path3371-89-4-1-6-0-1" />
</clipPath>
<linearGradient
y2="2937.73"
x2="1463.14"
y1="2937.73"
x1="1026.6899"
gradientUnits="userSpaceOnUse"
id="linearGradient4498-5-7"
xlink:href="#linearGradient4453-7-8-6-7-3-5"
inkscape:collect="always" />
<linearGradient
id="linearGradient6781">
<stop
style="stop-color:#aac4dd;stop-opacity:1;"
offset="0"
id="stop6783" />
<stop
style="stop-color:#c2dbe9;stop-opacity:1;"
offset="1"
id="stop6785" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4459-1-2-8-9-9-5"
id="linearGradient10695-9-9"
gradientUnits="userSpaceOnUse"
x1="646.55499"
y1="2736.25"
x2="1088.27"
y2="2736.25" />
<linearGradient
id="linearGradient4459-1-2-8-9-9-5">
<stop
id="stop4461-2-1-5-2-5-0"
offset="0"
style="stop-color:#839bc2;stop-opacity:1;" />
<stop
id="stop4463-3-2-8-7-30-3"
offset="1"
style="stop-color:#9fb6d4;stop-opacity:1;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4459-1-2-8-9-9-5"
id="linearGradient10693-9-4"
gradientUnits="userSpaceOnUse"
x1="646.55499"
y1="2736.25"
x2="1088.27"
y2="2736.25" />
<linearGradient
id="linearGradient6792">
<stop
id="stop6794"
offset="0"
style="stop-color:#839bc2;stop-opacity:1;" />
<stop
id="stop6796"
offset="1"
style="stop-color:#9fb6d4;stop-opacity:1;" />
</linearGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3351-4-7-3-5-95-0">
<path
inkscape:connector-curvature="0"
d="m 757.242,2926.25 -110.687,-189.11 110.656,-190.89 219.437,0 111.622,189.1 -111.59,190.9 -219.438,0 z"
id="path3353-1-9-3-4-1-1" />
</clipPath>
<linearGradient
y2="2736.25"
x2="1088.27"
y1="2736.25"
x1="646.55499"
gradientUnits="userSpaceOnUse"
id="linearGradient4510-1-5"
xlink:href="#linearGradient4459-1-2-8-9-9-5"
inkscape:collect="always" />
<linearGradient
id="linearGradient6801">
<stop
id="stop6803"
offset="0"
style="stop-color:#839bc2;stop-opacity:1;" />
<stop
id="stop6805"
offset="1"
style="stop-color:#9fb6d4;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#radialGradient3327-8-4-8-0-2-4"
id="radialGradient10699-1-3"
gradientUnits="userSpaceOnUse"
cx="997.46997"
cy="2896.25"
fx="997.46997"
fy="2896.25"
r="583.73999" />
<radialGradient
fx="0"
fy="0"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(58.375,0,0,-58.375,99.75,289.625)"
spreadMethod="pad"
id="radialGradient3327-8-4-8-0-2-4">
<stop
style="stop-opacity:1;stop-color:#aeaeb3"
offset="0"
id="stop3329-7-0-1-0-33-2" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="0.949438"
id="stop3331-4-3-0-0-97-3" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="1"
id="stop3333-2-4-9-7-2-2" />
</radialGradient>
<radialGradient
r="583.73999"
fy="2896.25"
fx="997.46997"
cy="2896.25"
cx="997.46997"
gradientUnits="userSpaceOnUse"
id="radialGradient13050"
xlink:href="#radialGradient3327-8-4-8-0-2-4"
inkscape:collect="always" />
<radialGradient
fx="0"
fy="0"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(58.375,0,0,-58.375,99.75,289.625)"
spreadMethod="pad"
id="radialGradient6813">
<stop
style="stop-opacity:1;stop-color:#aeaeb3"
offset="0"
id="stop6815" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="0.949438"
id="stop6817" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="1"
id="stop6819" />
</radialGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath3323-7-2-4-5-3-4">
<path
inkscape:connector-curvature="0"
d="m 997.469,2312.51 c -322.379,0 -583.739,261.36 -583.739,583.74 0,322.38 261.36,583.74 583.739,583.74 322.381,0 583.741,-261.36 583.741,-583.74 0,-322.38 -261.36,-583.74 -583.741,-583.74"
id="path3325-9-2-9-5-04-9" />
</clipPath>
<radialGradient
r="583.73999"
fy="2896.25"
fx="997.46997"
cy="2896.25"
cx="997.46997"
gradientUnits="userSpaceOnUse"
id="radialGradient4516-8-2"
xlink:href="#radialGradient3327-8-4-8-0-2-4"
inkscape:collect="always" />
<radialGradient
fx="0"
fy="0"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(58.375,0,0,-58.375,99.75,289.625)"
spreadMethod="pad"
id="radialGradient6824">
<stop
style="stop-opacity:1;stop-color:#aeaeb3"
offset="0"
id="stop6826" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="0.949438"
id="stop6828" />
<stop
style="stop-opacity:1;stop-color:#ffffff"
offset="1"
id="stop6830" />
</radialGradient>
<radialGradient
r="583.73999"
fy="2896.25"
fx="997.46997"
cy="2896.25"
cx="997.46997"
gradientUnits="userSpaceOnUse"
id="radialGradient6856"
xlink:href="#radialGradient3327-8-4-8-0-2-4"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="234.05635"
inkscape:cy="581.46313"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1680"
inkscape:window-height="982"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid3066" />
</sodipodi:namedview>
<metadata
id="metadata6863">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g3319-1-2-5-1-4-4"
transform="matrix(0.10419818,0,0,-0.10419818,137.10955,897.00327)"
style="fill:url(#radialGradient10699-1-3);fill-opacity:1"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<g
clip-path="url(#clipPath3323-7-2-4-5-3-4)"
id="g3321-9-2-7-4-3-9"
style="fill:url(#radialGradient6856);fill-opacity:1">
<path
id="path3335-8-7-3-8-92-0"
style="fill:url(#radialGradient4516-8-2);fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 997.469,2312.51 c -322.379,0 -583.739,261.36 -583.739,583.74 0,322.38 261.36,583.74 583.739,583.74 322.381,0 583.741,-261.36 583.741,-583.74 0,-322.38 -261.36,-583.74 -583.741,-583.74"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g3347-6-8-3-7-4-4"
transform="matrix(0.125,0,0,-0.125,112.08304,959.82207)"
style="fill:url(#linearGradient10695-9-9);fill-opacity:1"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<g
clip-path="url(#clipPath3351-4-7-3-5-95-0)"
id="g3349-5-5-4-7-9-4"
style="fill:url(#linearGradient10693-9-4);fill-opacity:1">
<path
id="path3361-0-8-2-9-0-9"
style="fill:url(#linearGradient4510-1-5);fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 757.242,2926.25 -110.687,-189.11 110.656,-190.89 219.437,0 111.622,189.1 -111.59,190.9 -219.438,0"
inkscape:connector-curvature="0" />
</g>
</g>
<path
id="path3363-6-9-0-1-5-8"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 194.34816,617.68335 13.106,-22.3925 25.99649,0 13.21487,22.60874 -13.21487,22.39125 -25.99649,0 -13.106,-22.60749 z m 40.53761,-24.8925 -28.86524,0 -0.72412,1.23749 -13.106,22.39251 -0.73575,1.25625 0.73087,1.26 13.106,22.60744 0.72263,1.24634 28.86374,0 0.72512,-1.22884 13.215,-22.39119 0.74625,-1.265 -0.74,-1.26751 -13.21537,-22.60875 -0.72313,-1.23874"
inkscape:connector-curvature="0"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523" />
<g
id="g3365-0-4-1-9-7-5"
transform="matrix(0.125,0,0,-0.125,112.08304,959.82207)"
style="fill:url(#linearGradient10691-7-8);fill-opacity:1"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<g
clip-path="url(#clipPath3369-1-5-6-1-0-7)"
id="g3367-2-4-2-8-4-3"
style="fill:url(#linearGradient10689-4-2);fill-opacity:1">
<path
id="path3379-4-6-7-6-7-2"
style="fill:url(#linearGradient4498-5-7);fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 1131.64,3128.5 -104.95,-181.12 116.38,-200.42 208.05,0.94 112.02,191.63 -112.08,188.97 -219.42,0"
inkscape:connector-curvature="0" />
</g>
</g>
<path
id="path3381-6-8-0-0-66-3"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 241.86427,591.39959 12.3925,-21.38999 25.99625,0 13.27125,22.37625 -13.27125,22.7025 -24.56875,0.11 -13.82,-23.79876 z m 39.8125,-23.88999 -28.86125,0 -0.7225,1.24625 -12.3925,21.39 -0.72625,1.255 0.7275,1.25374 13.82,23.79876 0.7275,1.25125 1.44625,-0.006 24.56875,-0.11 1.4275,-0.006 0.72,-1.2325 13.27125,-22.7025 0.7425,-1.27 -0.75125,-1.26625 -13.27125,-22.37625 -0.72625,-1.225"
inkscape:connector-curvature="0"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523" />
<g
id="g3383-5-5-2-2-3-0"
transform="matrix(0.125,0,0,-0.125,112.08304,959.82207)"
style="fill:url(#linearGradient10687-2-5);fill-opacity:1"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<g
clip-path="url(#clipPath3387-3-6-4-2-8-4)"
id="g3385-0-6-4-8-0-1"
style="fill:url(#linearGradient10685-2-2);fill-opacity:1">
<path
id="path3397-9-6-1-6-9-7"
style="fill:url(#linearGradient4492-8-8);fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 862.109,3289.75 -109.086,-190.45 69.122,-124.42 164.511,-0.47 c 0,0 111.044,188.28 116.564,197.63 7.66,0 43.03,0 43.03,0 l -67.03,117.71 -217.111,0"
inkscape:connector-curvature="0" />
</g>
</g>
<path
id="path3399-6-7-3-2-0-1"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 207.64603,572.41959 12.92424,-22.56624 25.68775,0 6.95625,12.21375 -3.94375,0 -14.56837,24.7025 -19.11525,-0.055 -7.94087,-14.295 z m 40.06574,-25.06624 -28.59012,0 -0.71975,1.2575 -12.92537,22.56625 -0.70112,1.22375 0.68512,1.23249 7.94137,14.295 0.71087,1.2825 1.46638,0.004 19.11525,0.055 1.43212,0.004 0.729,-1.23375 13.84375,-23.47249 6.81625,0 -2.12875,-3.7375 -6.95625,-12.21375 -0.71875,-1.2625"
inkscape:connector-curvature="0"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523" />
<g
transform="matrix(1.25,0,0,-1.25,105.02062,972.84257)"
id="g3465-0-8-9"
inkscape:export-filename="C:\Users\Adam\Desktop\bg_logo1.png"
inkscape:export-xdpi="63.625523"
inkscape:export-ydpi="63.625523">
<text
id="text3467-9-0-8"
transform="matrix(1,0,-0.17627963,-1,0,0)"
x="116.98372"
y="-267.77499"
style="font-size:11.81779194px">
<tspan
sodipodi:role="line"
style="font-size:46.39999771px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#49608a;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Denmark;-inkscape-font-specification:Denmark"
x="116.98372"
y="-267.77499"
id="tspan13239">UTILITY</tspan>
<tspan
sodipodi:role="line"
style="font-size:46.39999771px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#49608a;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Denmark;-inkscape-font-specification:Denmark"
x="116.98372"
y="-209.77499"
id="tspan11278-3" />
</text>
<text
id="text3471-0-51-2"
transform="matrix(0.99235617,0,-0.17763746,-1.0077027,0,0)"
style="font-size:38.40000153px"
x="112.74373"
y="-306.75479">
<tspan
id="tspan3473-6-0-9"
sodipodi:role="line"
style="font-size:38.40000153px;font-variant:normal;font-weight:normal;writing-mode:lr-tb;fill:#49608a;fill-opacity:1;fill-rule:nonzero;stroke:none;font-family:Denmark;-inkscape-font-specification:Denmark"
x="112.74373"
y="-306.75479">boost</tspan>
</text>
</g>
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 201.43967,613.81579 4.64114,4.2175 3.3738,-3.71306 -0.92817,-0.84354 1.68708,-1.85636 20.53445,20.81026 4.2175,-4.64111 -22.22144,-18.95384 c 0,0 1.69594,-1.83698 2.53062,-2.78454 2.53905,-2.76559 5.98925,-4.72587 5.98925,-4.72587 0,0 -6.03647,0.58224 -8.76507,2.21476 -0.84428,0.92751 -6.75676,7.40649 -6.75676,7.40649 l -0.92819,-0.84355 -3.37382,3.71308"
id="path13283"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccc" />
<g
id="g3086"
transform="matrix(0.99872217,-0.05053738,0.05053738,0.99872217,-31.539183,11.181538)">
<path
sodipodi:nodetypes="ccccccccc"
inkscape:connector-curvature="0"
id="path13243"
d="m 227.74101,611.16418 -15.09943,12.783 2.55659,3.01989 15.09944,-12.78302 c 3.56324,2.16769 7.58975,-1.2411 7.0464,-5.96538 l -4.02652,3.40879 -2.55659,-3.01989 4.02652,-3.40879 c -3.56324,-2.16769 -8.59639,2.0933 -7.04641,5.9654 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="ccccccccc"
inkscape:connector-curvature="0"
id="path13243-1"
d="m 215.25729,626.9851 15.08951,-12.7947 -2.55893,-3.01791 -15.08952,12.79471 c -3.56492,-2.16491 -7.58878,1.24699 -7.04177,5.97085 l 4.02388,-3.41192 2.55892,3.01791 -4.02387,3.41192 c 3.56491,2.16492 8.59476,-2.09997 7.04178,-5.97086 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -156,6 +156,11 @@ String-like operations:
[section History]
[/===============]
[heading boost 1.71]
* Glen Fernandes updated the implementation of the stream insertion operator to
write directly to the `basic_streambuf` and refactored that functionality into
a common utility.
[heading boost 1.53]
* Introduced

View File

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

View File

@ -1,63 +0,0 @@
//
// 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

@ -100,7 +100,7 @@ struct call_traits<T&>
typedef T& param_type; // hh removed const
};
#if BOOST_WORKAROUND( __BORLANDC__, < 0x5A0 )
#if BOOST_WORKAROUND( BOOST_BORLANDC, < 0x5A0 )
// these are illegal specialisations; cv-qualifies applied to
// references have no effect according to [8.3.2p1],
// C++ Builder requires them though as it treats cv-qualified

View File

@ -24,6 +24,7 @@
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/is_empty.hpp>
#include <boost/type_traits/is_final.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/call_traits.hpp>
@ -42,6 +43,14 @@ class compressed_pair;
namespace details
{
template<class T, bool E = boost::is_final<T>::value>
struct compressed_pair_empty
: ::boost::false_type { };
template<class T>
struct compressed_pair_empty<T, false>
: ::boost::is_empty<T> { };
// JM altered 26 Jan 2000:
template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
struct compressed_pair_switch;
@ -343,8 +352,8 @@ class compressed_pair
T1,
T2,
::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
::boost::is_empty<T1>::value,
::boost::is_empty<T2>::value>::value>
::boost::details::compressed_pair_empty<T1>::value,
::boost::details::compressed_pair_empty<T2>::value>::value>
{
private:
typedef details::compressed_pair_imp<T1, T2,
@ -352,8 +361,8 @@ private:
T1,
T2,
::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
::boost::is_empty<T1>::value,
::boost::is_empty<T2>::value>::value> base;
::boost::details::compressed_pair_empty<T1>::value,
::boost::details::compressed_pair_empty<T2>::value>::value> base;
public:
typedef T1 first_type;
typedef T2 second_type;
@ -388,8 +397,8 @@ class compressed_pair<T, T>
T,
T,
::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
::boost::is_empty<T>::value,
::boost::is_empty<T>::value>::value>
::boost::details::compressed_pair_empty<T>::value,
::boost::details::compressed_pair_empty<T>::value>::value>
{
private:
typedef details::compressed_pair_imp<T, T,
@ -397,8 +406,8 @@ private:
T,
T,
::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
::boost::is_empty<T>::value,
::boost::is_empty<T>::value>::value> base;
::boost::details::compressed_pair_empty<T>::value,
::boost::details::compressed_pair_empty<T>::value>::value> base;
public:
typedef T first_type;
typedef T second_type;

View File

@ -1,51 +0,0 @@
// Boost next_prior.hpp header file ---------------------------------------//
// (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/utility for documentation.
// Revision History
// 13 Dec 2003 Added next(x, n) and prior(x, n) (Daniel Walker)
#ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED
#define BOOST_NEXT_PRIOR_HPP_INCLUDED
#include <iterator>
namespace boost {
// Helper functions for classes like bidirectional iterators not supporting
// operator+ and operator-
//
// Usage:
// const std::list<T>::iterator p = get_some_iterator();
// const std::list<T>::iterator prev = boost::prior(p);
// const std::list<T>::iterator next = boost::next(prev, 2);
// Contributed by Dave Abrahams
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;
}
template <class T>
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;
}
} // namespace boost
#endif // BOOST_NEXT_PRIOR_HPP_INCLUDED

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -9,13 +9,16 @@
#ifndef BOOST_UTILITY_HPP
#define BOOST_UTILITY_HPP
#include <boost/utility/addressof.hpp>
// Use of this header is discouraged and it will be deprecated.
// Please include one or more of the headers below instead.
#include <boost/utility/base_from_member.hpp>
#include <boost/utility/binary.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/identity_type.hpp>
#include <boost/checked_delete.hpp>
#include <boost/next_prior.hpp>
#include <boost/noncopyable.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/core/checked_delete.hpp>
#include <boost/core/noncopyable.hpp>
#endif // BOOST_UTILITY_HPP

View File

@ -47,11 +47,11 @@
// {}
// 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) ) \
{} \
/**/
@ -142,7 +142,8 @@ protected:
: 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

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

@ -0,0 +1,58 @@
#ifndef BOOST_UTILITY_DETAIL_MINSTD_RAND_HPP_INCLUDED
#define BOOST_UTILITY_DETAIL_MINSTD_RAND_HPP_INCLUDED
// Copyright 2017 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
//
// An implementation of minstd_rand that does not require
// the Random library
#include <boost/cstdint.hpp>
namespace boost
{
namespace detail
{
class minstd_rand
{
private:
boost::uint_least32_t x_;
enum { a = 48271, m = 2147483647 };
public:
minstd_rand(): x_( 1 )
{
}
explicit minstd_rand( boost::uint_least32_t x ): x_( x % m )
{
if( x_ == 0 )
{
x_ = 1;
}
}
boost::uint_least32_t operator()()
{
boost::uint_least64_t y = x_;
y = ( a * y ) % m;
x_ = static_cast<boost::uint_least32_t>( y );
return x_;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_UTILITY_DETAIL_MINSTD_RAND_HPP_INCLUDED

View File

@ -22,19 +22,19 @@
# define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)
#endif
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
: mpl::if_<
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
: conditional<
is_pointer<F>::value || is_member_function_pointer<F>::value
, boost::detail::tr1_result_of_impl<
typename remove_cv<F>::type,
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
(boost::detail::has_result_type<F>::value)>
(boost::detail::result_of_has_result_type<F>::value)>
, boost::detail::tr1_result_of_impl<
F,
F(BOOST_RESULT_OF_ARGS),
(boost::detail::has_result_type<F>::value)> >::type { };
(boost::detail::result_of_has_result_type<F>::value)> >::type { };
#endif
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
@ -46,7 +46,7 @@ struct result_of<F(BOOST_RESULT_OF_ARGS)>
#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> >,
: conditional<detail::result_of_has_result_type<F>::value || detail::result_of_has_result<F>::value,
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
@ -57,8 +57,8 @@ 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>
: conditional<
is_member_function_pointer<F>::value
, detail::tr1_result_of_impl<
typename remove_cv<F>::type,
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
@ -82,25 +82,22 @@ struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<R(BOOST_PP_
};
template<typename F>
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION());
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())
: BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
{};
template<typename F>
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F *>
: BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
{};
template<typename F>
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F &>
: BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
{};
template<typename F>
struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())
: mpl::eval_if<
is_class<typename remove_reference<F>::type>,
: conditional<
is_class<typename remove_reference<F>::type>::value,
result_of_wrap_callable_class<F>,
mpl::identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<F>::type> >
>
type_identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<typename remove_reference<F>::type>::type> >
>::type
{};
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)>
@ -111,7 +108,7 @@ struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) {
(boost::declval<wrapper_t>()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)), result_of_weird_type())
))
);
typedef mpl::bool_<value> type;
typedef integral_constant<bool, value> type;
};
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
@ -154,7 +151,7 @@ struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)),
#else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct result_of<F(BOOST_RESULT_OF_ARGS)>
: tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { };
@ -180,7 +177,7 @@ struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), F
typedef R type;
};
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of_impl<R (T0::*)
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),

View File

@ -18,19 +18,16 @@
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/declval.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/type_identity.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/core/enable_if.hpp>
#ifndef BOOST_RESULT_OF_NUM_ARGS
# define BOOST_RESULT_OF_NUM_ARGS 16
@ -47,10 +44,6 @@
BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time.
#endif
#if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
# error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined.
#endif
#ifndef BOOST_RESULT_OF_USE_TR1
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
@ -71,11 +64,40 @@ template<typename F> struct tr1_result_of; // a TR1-style implementation of resu
#if !defined(BOOST_NO_SFINAE)
namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1
typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2
template<class T> struct result_of_has_type {};
template<class T> struct result_of_has_result_type_impl
{
template<class U> static result_of_yes_type f( result_of_has_type<typename U::result_type>* );
template<class U> static result_of_no_type f( ... );
typedef boost::integral_constant<bool, sizeof(f<T>(0)) == sizeof(result_of_yes_type)> type;
};
template<class T> struct result_of_has_result_type: result_of_has_result_type_impl<T>::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)
template<template<class> class C> struct result_of_has_template {};
template<class T> struct result_of_has_result_impl
{
template<class U> static result_of_yes_type f( result_of_has_template<U::template result>* );
template<class U> static result_of_no_type f( ... );
typedef boost::integral_constant<bool, sizeof(f<T>(0)) == sizeof(result_of_yes_type)> type;
};
template<class T> struct result_of_has_result: result_of_has_result_impl<T>::type
{
};
#endif
template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
@ -97,9 +119,6 @@ struct result_of_weird_type {
friend result_of_private_type operator,(result_of_private_type, result_of_weird_type);
};
typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1
typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2
template<typename T>
result_of_no_type result_of_is_private_type(T const &);
result_of_yes_type result_of_is_private_type(result_of_private_type);
@ -180,10 +199,10 @@ struct tr1_result_of_impl<F, FArgs, true>
};
template<typename FArgs>
struct is_function_with_no_args : mpl::false_ {};
struct is_function_with_no_args : false_type {};
template<typename F>
struct is_function_with_no_args<F(void)> : mpl::true_ {};
struct is_function_with_no_args<F(void)> : true_type {};
template<typename F, typename FArgs>
struct result_of_nested_result : F::template result<FArgs>
@ -191,7 +210,7 @@ struct result_of_nested_result : F::template result<FArgs>
template<typename F, typename FArgs>
struct tr1_result_of_impl<F, FArgs, false>
: mpl::if_<is_function_with_no_args<FArgs>,
: conditional<is_function_with_no_args<FArgs>::value,
result_of_void_impl<F>,
result_of_nested_result<F, FArgs> >::type
{};
@ -201,6 +220,11 @@ struct tr1_result_of_impl<F, FArgs, false>
#define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))
#include BOOST_PP_ITERATE()
#if 0
// inform dependency trackers, as they can't see through macro includes
#include <boost/utility/detail/result_of_iterate.hpp>
#endif
#else
# define BOOST_NO_RESULT_OF 1
#endif

View File

@ -1,5 +1,6 @@
/*
Copyright (c) Marshall Clow 2012-2012.
Copyright (c) Marshall Clow 2012-2015.
Copyright (c) Glen Joseph Fernandes 2019 (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -17,6 +18,7 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/io/ostream_put.hpp>
#include <boost/utility/string_ref_fwd.hpp>
#include <boost/throw_exception.hpp>
@ -27,6 +29,11 @@
#include <string>
#include <iosfwd>
#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
// GCC 4.6 cannot handle a defaulted function with noexcept specifier
#define BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
#endif
namespace boost {
namespace detail {
@ -57,37 +64,55 @@ namespace boost {
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)
// #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
// // Constructing a string_ref from a temporary string is a bad idea
// template<typename Allocator>
// basic_string_ref( std::basic_string<charT, traits, Allocator>&&)
// = delete;
// #endif
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
@ -139,9 +164,7 @@ namespace boost {
basic_string_ref substr(size_type pos, size_type n=npos) const {
if ( pos > size())
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) );
if ( n == npos || pos + n > size())
n = size () - pos;
return basic_string_ref ( data() + pos, n );
return basic_string_ref(data() + pos, (std::min)(size() - pos, n));
}
int compare(basic_string_ref x) const {
@ -160,6 +183,7 @@ namespace boost {
}
size_type find(basic_string_ref s) const {
if (s.empty()) return 0;
const_iterator iter = std::search ( this->cbegin (), this->cend (),
s.cbegin (), s.cend (), traits::eq );
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
@ -172,15 +196,16 @@ namespace boost {
}
size_type rfind(basic_string_ref s) const {
if (s.empty()) return 0;
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); }
@ -195,7 +220,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 {
@ -212,21 +237,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 {
@ -402,52 +423,11 @@ namespace boost {
return basic_string_ref<charT, traits>(x) >= y;
}
namespace detail {
template<class charT, class traits>
inline void 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 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::insert_fill_chars(os, alignment_size);
if (os.good())
os.write(str.data(), size);
}
else {
os.write(str.data(), size);
if (os.good())
detail::insert_fill_chars(os, alignment_size);
}
}
} // namespace detail
// Inserter
template<class charT, class traits>
inline std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
if (os.good()) {
const std::size_t size = str.size();
const std::size_t w = static_cast< std::size_t >(os.width());
if (w <= size)
os.write(str.data(), size);
else
detail::insert_aligned(os, str);
os.width(0);
}
return os;
return boost::io::ostream_put(os, str.data(), str.size());
}
#if 0

View File

@ -0,0 +1,671 @@
/*
Copyright (c) Marshall Clow 2012-2015.
Copyright (c) Beman Dawes 2015
Copyright (c) Glen Joseph Fernandes 2019 (glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
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/io/ostream_put.hpp>
#include <boost/utility/string_view_fwd.hpp>
#include <boost/throw_exception.hpp>
#include <boost/container_hash/hash_fwd.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()) {}
// #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
// // Constructing a string_view from a temporary string is a bad idea
// template<typename Allocator>
// basic_string_view( std::basic_string<charT, traits, Allocator>&&)
// = delete;
// #endif
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_[0] : 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);
traits_type::copy(s, data() + pos, rlen);
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" ) );
return basic_string_view(data() + pos, (std::min)(size() - 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;
if (s.size() > size() - pos)
return npos;
const charT* cur = ptr_ + pos;
const charT* last = cend() - s.size() + 1;
for (; cur != last ; ++cur) {
cur = traits::find(cur, last - cur, s[0]);
if (!cur)
return npos;
if (traits::compare(cur, s.cbegin(), s.size()) == 0)
return cur - ptr_;
}
return npos;
}
BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT {
if (pos > size())
return npos;
const charT* ret_ptr = traits::find(ptr_ + pos, len_ - pos, c);
if (ret_ptr)
return ret_ptr - ptr_;
return npos;
}
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(c, 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR 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 BOOST_CXX14_CONSTEXPR bool operator>=(const charT * x,
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
return basic_string_view<charT, traits>(x) >= y;
}
// 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) {
return boost::io::ostream_put(os, str.data(), str.size());
}
#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
template <class charT, class traits>
std::size_t hash_value(basic_string_view<charT, traits> s) {
return boost::hash_range(s.begin(), s.end());
}
}
#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,4 +1,5 @@
// (C) Copyright 2002-2008, Fernando Luis Cacciola Carballal.
// Copyright 2020 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@ -21,15 +22,10 @@
// issues, by clearing the bytes of T, before constructing the T object it
// contains. More details on these issues are at libs/utility/value_init.htm
#include <boost/aligned_storage.hpp>
#include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
#include <boost/detail/workaround.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/cv_traits.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/swap.hpp>
#include <cstring>
#include <new>
#include <cstddef>
#ifdef BOOST_MSVC
#pragma warning(push)
@ -60,92 +56,58 @@
namespace boost {
namespace detail {
struct zero_init
{
zero_init()
{
}
zero_init( void * p, std::size_t n )
{
std::memset( p, 0, n );
}
};
} // namespace detail
template<class T>
class initialized
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
: detail::zero_init
#endif
{
private :
struct wrapper
{
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
typename
#endif
remove_const<T>::type data;
private:
BOOST_GPU_ENABLED
wrapper()
:
data()
{
}
BOOST_GPU_ENABLED
wrapper(T const & arg)
:
data(arg)
{
}
};
mutable
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
typename
#endif
aligned_storage<sizeof(wrapper), alignment_of<wrapper>::value>::type x;
BOOST_GPU_ENABLED
wrapper * wrapper_address() const
{
return static_cast<wrapper *>( static_cast<void*>(&x));
}
T data_;
public :
BOOST_GPU_ENABLED
initialized()
{
initialized():
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
std::memset(&x, 0, sizeof(x));
zero_init( &const_cast< char& >( reinterpret_cast<char const volatile&>( data_ ) ), sizeof( data_ ) ),
#endif
new (wrapper_address()) wrapper();
data_()
{
}
BOOST_GPU_ENABLED
initialized(initialized const & arg)
explicit initialized(T const & arg): data_( arg )
{
new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address())));
}
BOOST_GPU_ENABLED
explicit initialized(T const & arg)
{
new (wrapper_address()) wrapper(arg);
}
BOOST_GPU_ENABLED
initialized & operator=(initialized const & arg)
{
// Assignment is only allowed when T is non-const.
BOOST_STATIC_ASSERT( ! is_const<T>::value );
*wrapper_address() = static_cast<wrapper const &>(*(arg.wrapper_address()));
return *this;
}
BOOST_GPU_ENABLED
~initialized()
{
wrapper_address()->wrapper::~wrapper();
}
BOOST_GPU_ENABLED
T const & data() const
{
return wrapper_address()->data;
return data_;
}
BOOST_GPU_ENABLED
T& data()
{
return wrapper_address()->data;
return data_;
}
BOOST_GPU_ENABLED
@ -157,13 +119,13 @@ class initialized
BOOST_GPU_ENABLED
operator T const &() const
{
return wrapper_address()->data;
return data_;
}
BOOST_GPU_ENABLED
operator T&()
{
return wrapper_address()->data;
return data_;
}
} ;

View File

@ -12,29 +12,31 @@
<p>The Boost Utility Library isn't really a single library at all. It is just a
collection for components too small to be called libraries in their own right.</p>
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
<blockquote>
<p>
<a href="../core/doc/html/core/addressof.html">addressof</a> (moved to the Boost.Core library)<br>
<a href="doc/html/base_from_member.html">base_from_member</a><br>
<a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a><br>
<a href="call_traits.htm">call_traits</a><br>
<a href="../core/doc/html/core/checked_delete.html">checked_delete</a> (moved to the Boost.Core library)<br>
<a href="doc/html/compressed_pair.html">compressed_pair</a><br>
<a href="doc/html/declval.html">declval</a><br>
<a href="../core/doc/html/core/enable_if.html">enable_if</a> (moved to the Boost.Core library)<br>
<a href="in_place_factories.html">in_place_factory</a><br>
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
<a href="utility.htm#functions_next_prior">next/prior</a><br>
<a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)<br>
<a href="operators.htm">operators</a><br>
<a href="utility.htm#result_of">result_of</a><br>
<a href="throw_exception.html">throw_exception</a><br>
<a href="utility.htm">utility</a><br>
<a href="doc/html/string_ref.html">string_ref</a><br>
<a href="value_init.htm">value_init</a><br>
</p>
</blockquote>
<ul>
<li><a href="doc/html/base_from_member.html">base_from_member</a></li>
<li><a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a></li>
<li><a href="call_traits.htm">call_traits</a></li>
<li><a href="doc/html/compressed_pair.html">compressed_pair</a></li>
<li><a href="in_place_factories.html">in_place_factory</a></li>
<li><a href="iterator_adaptors.htm">iterator_adaptors</a></li>
<li><a href="operators.htm">operators</a></li>
<li><a href="utility.htm#result_of">result_of</a></li>
<li><a href="throw_exception.html">throw_exception</a></li>
<li><a href="utility.htm">utility</a></li>
<li><a href="doc/html/string_ref.html">string_ref</a></li>
<li><a href="value_init.htm">value_init</a></li>
</ul>
<p>Over time useful stuff here has moved to more appropriate Boost libraries:</p>
<ul>
<li><a href="../core/doc/html/core/addressof.html">addressof</a> (moved to Boost.Core)</li>
<li><a href="../core/doc/html/core/checked_delete.html">checked_delete</a> (moved to Boost.Core)</li>
<li><a href="../type_traits/doc/html/boost_typetraits/reference/declval.html">declval</a> (moved to Boost.TypeTraits)</li>
<li><a href="../core/doc/html/core/enable_if.html">enable_if</a> (moved to Boost.Core)</li>
<li><a href="../iterator/doc/generator_iterator.htm">generator iterator adaptors</a> (moved to Boost.Iterator)</li>
<li><a href="../iterator/doc/html/iterator/algorithms/next_prior.html">next/prior</a> (moved to Boost.Iterator)</li>
<li><a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to Boost.Core)</li>
<li><a href="../io/doc/html/io.html">ostream_string</a> (moved to Boost.IO)</li>
</ul>
<hr>
<p>&copy; Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See

135
meta/libraries.json Normal file
View File

@ -0,0 +1,135 @@
[
{
"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"
],
"cxxstd": "03"
},
{
"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"
],
"cxxstd": "03"
},
{
"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"
],
"cxxstd": "03"
},
{
"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>"
],
"cxxstd": "03"
},
{
"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"
],
"cxxstd": "03"
},
{
"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>"
],
"cxxstd": "03"
},
{
"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>"
],
"cxxstd": "03"
},
{
"key": "utility/string_ref",
"name": "string_ref",
"description": "String view templates.",
"documentation": "doc/html/string_ref.html",
"category": [
"Containers"
],
"authors": "Marshall Clow",
"maintainers": [
"Marshall Clow <marshall -at- idio.com>"
],
"cxxstd": "03"
},
{
"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"
],
"cxxstd": "03"
}
]

View File

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

View File

@ -119,8 +119,8 @@
also want <code>x &gt; y, x &gt;= y,</code> and <code>x &lt;= y</code>.
Moreover, unless your class has really surprising behavior, some of these
related operators can be defined in terms of others (e.g. <code>x &gt;= y
&lt;=&gt; !(x &lt; y)</code>). Replicating this boilerplate for multiple
classes is both tedious and error-prone. The <cite><a href=
is equivalent to !(x &lt; y)</code>). Replicating this boilerplate for
multiple classes is both tedious and error-prone. The <cite><a href=
"../../boost/operators.hpp">boost/operators.hpp</a></cite> templates help
by generating operators for you at namespace scope based on other
operators you've defined in your class.</p>
@ -454,7 +454,7 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
</caption>
<tr>
<td colspan="3">
<td colspan="4">
<table align="center" border="1">
<caption>
<em>Key</em>
@ -482,6 +482,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<th>Supplied Operations</th>
<th>Requirements</th>
<th>Propagates <code>constexpr</code>?</th>
</tr>
<tr>
@ -496,6 +498,9 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>t &lt; t1</code>.<br>
Return convertible to <code>bool</code>. See the <a href=
"#ordering">Ordering Note</a>.</td>
<td>Since <code>C++11</code><br>
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC &lt; v19.22</a>)</span></td>
</tr>
<tr>
@ -513,6 +518,9 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>t &lt; u</code>. <code>t &gt; u</code>.<br>
Returns convertible to <code>bool</code>. See the <a href=
"#ordering">Ordering Note</a>.</td>
<td>Since <code>C++11</code><br>
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC &lt; v19.22</a>)</span></td>
</tr>
<tr>
@ -524,6 +532,9 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>t == t1</code>.<br>
Return convertible to <code>bool</code>.</td>
<td>Since <code>C++11</code><br>
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC &lt; v19.22</a>)</span></td>
</tr>
<tr>
@ -537,6 +548,9 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>t == u</code>.<br>
Return convertible to <code>bool</code>.</td>
<td>Since <code>C++11</code><br>
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC &lt; v19.22</a>)</span></td>
</tr>
<tr>
@ -548,6 +562,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp += t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -560,6 +576,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp += u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -572,6 +590,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp -= t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -584,6 +604,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp -= u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -594,6 +616,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(u); temp -= t</code>.<br>
Return convertible to <code>T</code>.</td>
<td>No</td>
</tr>
<tr>
@ -606,6 +630,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp *= t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -619,6 +645,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp *= u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -630,6 +658,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp /= t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -641,6 +671,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp /= u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -651,6 +683,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(u); temp /= t</code>.<br>
Return convertible to <code>T</code>.</td>
<td>No</td>
</tr>
<tr>
@ -662,6 +696,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp %= t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -673,6 +709,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp %= u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -683,6 +721,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(u); temp %= t</code>.<br>
Return convertible to <code>T</code>.</td>
<td>No</td>
</tr>
<tr>
@ -694,6 +734,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp |= t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -706,6 +748,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp |= u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -717,6 +761,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp &amp;= t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -729,6 +775,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp &amp;= u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -740,6 +788,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp ^= t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -752,6 +802,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp ^= u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -762,6 +814,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); ++t</code><br>
Return convertible to <code>T</code>.</td>
<td>No</td>
</tr>
<tr>
@ -772,6 +826,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); --t;</code><br>
Return convertible to <code>T</code>.</td>
<td>No</td>
</tr>
<tr>
@ -784,6 +840,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp &lt;&lt;= t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -796,6 +854,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp &lt;&lt;= u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -808,6 +868,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp &gt;&gt;= t1</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -820,6 +882,8 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>T temp(t); temp &gt;&gt;= u</code>.<br>
Return convertible to <code>T</code>. See the <a href=
"#symmetry">Symmetry Note</a>.</td>
<td>No</td>
</tr>
<tr>
@ -831,6 +895,9 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>t &lt; t1</code>.<br>
Return convertible to <code>bool</code>. See the <a href=
"#ordering">Ordering Note</a>.</td>
<td>Since <code>C++11</code><br>
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC &lt; v19.22</a>)</span></td>
</tr>
<tr>
@ -842,6 +909,9 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>t &lt; u</code>. <code>t &gt; u</code>.<br>
Returns convertible to <code>bool</code>. See the <a href=
"#ordering">Ordering Note</a>.</td>
<td>Since <code>C++11</code><br>
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC &lt; v19.22</a>)</span></td>
</tr>
<tr>
@ -856,6 +926,9 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
<td><code>t &lt; t1</code>. <code>t == t1</code>.<br>
Returns convertible to <code>bool</code>. See the <a href=
"#ordering">Ordering Note</a>.</td>
<td>Since <code>C++11</code><br>
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC &lt; v19.22</a>)</span></td>
</tr>
<tr>
@ -874,6 +947,9 @@ const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
u</code>.<br>
Returns convertible to <code>bool</code>. See the <a href=
"#ordering">Ordering Note</a>.</td>
<td>Since <code>C++11</code><br>
<span style="font-size:small;">(except <a href="https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html">MSVC &lt; v19.22</a>)</span></td>
</tr>
</table>
@ -1586,7 +1662,7 @@ T operator+( T lhs, const T&amp; rhs )
<h3><a name="a_demo">Arithmetic Operators Demonstration</a> and Test
Program</h3>
<p>The <cite><a href="operators_test.cpp">operators_test.cpp</a></cite>
<p>The <cite><a href="test/operators_test.cpp">operators_test.cpp</a></cite>
program demonstrates the use of the arithmetic operator templates, and
can also be used to verify correct operation. Check the compiler status
report for the test results with selected platforms.</p>
@ -1667,8 +1743,8 @@ T operator+( T lhs, const T&amp; rhs )
<td><code>P operator-&gt;() const</code></td>
<td><code>(&amp;*i)</code>. Return convertible to
<code>P</code>.</td>
<td><code>*i</code>. Address of the returned value convertible
to <code>P</code>.</td>
</tr>
<tr>
@ -1998,7 +2074,7 @@ struct function_output_iterator
<h3><a name="i_demo">Iterator Demonstration</a> and Test Program</h3>
<p>The <cite><a href="iterators_test.cpp">iterators_test.cpp</a></cite>
<p>The <cite><a href="test/iterators_test.cpp">iterators_test.cpp</a></cite>
program demonstrates the use of the iterator templates, and can also be
used to verify correct operation. The following is the custom iterator
defined in the test program. It demonstrates a correct (though trivial)
@ -2064,7 +2140,7 @@ public:
<dt><a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a></dt>
<dd>Contributed <cite><a href=
"operators_test.cpp">operators_test.cpp</a></cite>.</dd>
"test/operators_test.cpp">operators_test.cpp</a></cite>.</dd>
<dt><a href="http://www.boost.org/people/daryle_walker.html">Daryle Walker</a></dt>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,37 +8,40 @@
# bring in rules for testing
import testing ;
alias unit_test_framework
: # sources
/boost//unit_test_framework
;
run base_from_member_test.cpp ;
run base_from_member_ref_test.cpp ;
# Please keep the tests ordered by filename
test-suite utility
:
[ run ../base_from_member_test.cpp ]
[ run ../base_from_member_ref_test.cpp ]
[ run ../binary_test.cpp ]
[ run ../call_traits_test.cpp : -u ]
[ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>static : -u ]
[ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
[ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
[ run ../numeric_traits_test.cpp ]
[ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
[ compile result_of_test.cpp ]
[ run ../shared_iterator_test.cpp ]
[ run string_ref_test1.cpp unit_test_framework ]
[ run string_ref_test2.cpp unit_test_framework ]
[ run string_ref_test_io.cpp unit_test_framework ]
[ run ../value_init_test.cpp ]
[ run ../value_init_workaround_test.cpp ]
[ run ../initialized_test.cpp ]
[ compile-fail ../value_init_test_fail1.cpp ]
[ compile-fail ../value_init_test_fail2.cpp ]
[ compile-fail ../value_init_test_fail3.cpp ]
[ compile-fail ../initialized_test_fail1.cpp ]
[ compile-fail ../initialized_test_fail2.cpp ]
run binary_test.cpp ;
[ run ../generator_iterator_test.cpp ]
;
run call_traits_test.cpp : -u ;
run compressed_pair_test.cpp ;
run compressed_pair_final_test.cpp ;
run iterators_test.cpp ;
run operators_test.cpp ;
compile operators_constexpr_test.cpp ;
compile result_of_test.cpp ;
# compile-fail string_ref_from_rvalue.cpp ;
run string_ref_test1.cpp ;
run string_ref_test2.cpp ;
run string_ref_test_io.cpp ;
# compile-fail string_view_from_rvalue.cpp ;
compile string_view_constexpr_test1.cpp ;
run string_view_test1.cpp ;
run string_view_test2.cpp ;
run string_view_test_io.cpp ;
run value_init_test.cpp ;
run value_init_test2.cpp ;
run value_init_test3.cpp ;
run value_init_workaround_test.cpp ;
run initialized_test.cpp ;
compile-fail value_init_test_fail1.cpp ;
compile-fail value_init_test_fail2.cpp ;
compile-fail value_init_test_fail3.cpp ;
compile-fail initialized_test_fail1.cpp ;
compile-fail initialized_test_fail2.cpp ;

View File

@ -10,7 +10,7 @@
#include <boost/utility/base_from_member.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
struct foo : boost::base_from_member<int&>
{

View File

@ -10,15 +10,14 @@
// 14 Jun 2003 Adjusted code for Boost.Test changes (Daryle Walker)
// 29 Aug 2001 Initial Version (Daryle Walker)
#include <boost/test/minimal.hpp> // for BOOST_CHECK, main
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp> // for BOOST_NO_MEMBER_TEMPLATES
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/noncopyable.hpp> // for boost::noncopyable
#include <boost/utility/base_from_member.hpp> // for boost::base_from_member
#include <functional> // for std::binary_function, std::less
#include <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 +45,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;
@ -173,13 +171,13 @@ object_registrar obj_reg;
// Main functionality
int
test_main( int , char * [] )
main()
{
BOOST_CHECK( obj_reg.db_.empty() );
BOOST_CHECK( obj_reg.defrauders_in_.empty() );
BOOST_CHECK( obj_reg.defrauders_out_.empty() );
BOOST_CHECK( obj_reg.overeager_.empty() );
BOOST_CHECK( obj_reg.overkilled_.empty() );
BOOST_TEST( obj_reg.db_.empty() );
BOOST_TEST( obj_reg.defrauders_in_.empty() );
BOOST_TEST( obj_reg.defrauders_out_.empty() );
BOOST_TEST( obj_reg.overeager_.empty() );
BOOST_TEST( obj_reg.overkilled_.empty() );
// Make a separate block to examine pre- and post-effects
{
@ -187,20 +185,20 @@ test_main( int , char * [] )
using std::endl;
bad_class bc;
BOOST_CHECK( obj_reg.db_.size() == 3 );
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
BOOST_TEST( obj_reg.db_.size() == 3 );
BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
good_class_1 gc1;
BOOST_CHECK( obj_reg.db_.size() == 6 );
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
BOOST_TEST( obj_reg.db_.size() == 6 );
BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
good_class_2 gc2;
BOOST_CHECK( obj_reg.db_.size() == 11 );
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
BOOST_TEST( obj_reg.db_.size() == 11 );
BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
BOOST_CHECK( obj_reg.defrauders_out_.empty() );
BOOST_CHECK( obj_reg.overeager_.empty() );
BOOST_CHECK( obj_reg.overkilled_.empty() );
BOOST_TEST( obj_reg.defrauders_out_.empty() );
BOOST_TEST( obj_reg.overeager_.empty() );
BOOST_TEST( obj_reg.overkilled_.empty() );
// Getting the addresses of the objects ensure
// that they're used, and not optimized away.
@ -209,13 +207,13 @@ test_main( int , char * [] )
cout << "Object 'gc2' is at " << &gc2 << '.' << endl;
}
BOOST_CHECK( obj_reg.db_.empty() );
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
BOOST_CHECK( obj_reg.defrauders_out_.size() == 1 );
BOOST_CHECK( obj_reg.overeager_.empty() );
BOOST_CHECK( obj_reg.overkilled_.empty() );
BOOST_TEST( obj_reg.db_.empty() );
BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
BOOST_TEST( obj_reg.defrauders_out_.size() == 1 );
BOOST_TEST( obj_reg.overeager_.empty() );
BOOST_TEST( obj_reg.overkilled_.empty() );
return boost::exit_success;
return boost::report_errors();
}

View File

@ -6,7 +6,7 @@
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#include <boost/test/minimal.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/utility/binary.hpp>
#include <algorithm>
#include <cstddef>
@ -614,34 +614,34 @@ typedef char (&unsigned_long_int_id_type)[unsigned_long_int_id];
unsigned_int_id_type binary_type_checker( unsigned int );
unsigned_long_int_id_type binary_type_checker( unsigned long int );
int test_main( int, char *[] )
int main()
{
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_1_bit ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_2_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_3_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_4_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_5_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_6_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_7_bits ) );
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_8_bits ) );
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_1_bit ) );
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_2_bits ) );
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_3_bits ) );
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_4_bits ) );
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_5_bits ) );
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_6_bits ) );
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_7_bits ) );
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_8_bits ) );
BOOST_CHECK( std::equal( &random_unsigned_ints_hex[0]
BOOST_TEST( std::equal( &random_unsigned_ints_hex[0]
, random_unsigned_ints_hex + num_random_test_values
, &random_unsigned_ints_binary[0]
)
);
BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) )
BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) )
== unsigned_int_id
);
BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) )
BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) )
== unsigned_long_int_id
);
BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) )
BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) )
== unsigned_long_int_id
);
return 0;
return boost::report_errors();
}

View File

@ -376,7 +376,7 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>:
reference r = t;
const_reference cr = t;
reference r2 = r;
#ifndef __BORLANDC__
#ifndef BOOST_BORLANDC
// C++ Builder buglet:
const_reference cr2 = r;
#endif
@ -393,7 +393,7 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>:
unused_variable(v3);
unused_variable(v4);
unused_variable(v5);
#ifndef __BORLANDC__
#ifndef BOOST_BORLANDC
unused_variable(r2);
unused_variable(cr2);
#endif

View File

@ -0,0 +1,55 @@
/*
Copyright 2018 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_FINAL)
#include <boost/compressed_pair.hpp>
#include <boost/core/lightweight_test.hpp>
struct type1 {
operator bool() const {
return false;
}
};
struct type2 final {
operator bool() const {
return false;
}
};
#if !defined(BOOST_IS_FINAL)
namespace boost {
template<>
struct is_final<type2>
: true_type { };
} /* boost*/
#endif
template<class T1, class T2>
void test()
{
boost::compressed_pair<T1, T2> p;
BOOST_TEST(!p.first());
BOOST_TEST(!p.second());
}
int main()
{
test<type1, type2>();
test<type2, type1>();
test<type2, type2>();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@ -14,7 +14,7 @@
#include <cassert>
#include <boost/compressed_pair.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost;
@ -79,47 +79,47 @@ void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type
// first param construct:
boost::compressed_pair<T1,T2> cp2(p1);
cp2.second() = p2;
BOOST_CHECK(cp2.first() == p1);
BOOST_CHECK(cp2.second() == p2);
BOOST_TEST(cp2.first() == p1);
BOOST_TEST(cp2.second() == p2);
// second param construct:
boost::compressed_pair<T1,T2> cp3(p2);
cp3.first() = p1;
BOOST_CHECK(cp3.second() == p2);
BOOST_CHECK(cp3.first() == p1);
BOOST_TEST(cp3.second() == p2);
BOOST_TEST(cp3.first() == p1);
// both param construct:
boost::compressed_pair<T1,T2> cp4(p1, p2);
BOOST_CHECK(cp4.first() == p1);
BOOST_CHECK(cp4.second() == p2);
BOOST_TEST(cp4.first() == p1);
BOOST_TEST(cp4.second() == p2);
boost::compressed_pair<T1,T2> cp5(p3, p4);
BOOST_CHECK(cp5.first() == p3);
BOOST_CHECK(cp5.second() == p4);
BOOST_TEST(cp5.first() == p3);
BOOST_TEST(cp5.second() == p4);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
BOOST_CHECK(cpr1.first() == p1);
BOOST_CHECK(cpr1.second() == p2);
BOOST_TEST(cpr1.first() == p1);
BOOST_TEST(cpr1.second() == p2);
// copy construct:
boost::compressed_pair<T1,T2> cp6(cp4);
BOOST_CHECK(cp6.first() == p1);
BOOST_CHECK(cp6.second() == p2);
BOOST_TEST(cp6.first() == p1);
BOOST_TEST(cp6.second() == p2);
// assignment:
cp1 = cp4;
BOOST_CHECK(cp1.first() == p1);
BOOST_CHECK(cp1.second() == p2);
BOOST_TEST(cp1.first() == p1);
BOOST_TEST(cp1.second() == p2);
cp1 = cp5;
BOOST_CHECK(cp1.first() == p3);
BOOST_CHECK(cp1.second() == p4);
BOOST_TEST(cp1.first() == p3);
BOOST_TEST(cp1.second() == p4);
// swap:
cp4.swap(cp5);
BOOST_CHECK(cp4.first() == p3);
BOOST_CHECK(cp4.second() == p4);
BOOST_CHECK(cp5.first() == p1);
BOOST_CHECK(cp5.second() == p2);
BOOST_TEST(cp4.first() == p3);
BOOST_TEST(cp4.second() == p4);
BOOST_TEST(cp5.first() == p1);
BOOST_TEST(cp5.second() == p2);
swap(cp4,cp5);
BOOST_CHECK(cp4.first() == p1);
BOOST_CHECK(cp4.second() == p2);
BOOST_CHECK(cp5.first() == p3);
BOOST_CHECK(cp5.second() == p4);
BOOST_TEST(cp4.first() == p1);
BOOST_TEST(cp4.second() == p2);
BOOST_TEST(cp5.first() == p3);
BOOST_TEST(cp5.second() == p4);
}
//
@ -148,20 +148,20 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_
#endif
// both param construct:
boost::compressed_pair<T1,T2> cp4(p1, p2);
BOOST_CHECK(cp4.first() == p1);
BOOST_CHECK(cp4.second() == p2);
BOOST_TEST(cp4.first() == p1);
BOOST_TEST(cp4.second() == p2);
boost::compressed_pair<T1,T2> cp5(p3, p4);
BOOST_CHECK(cp5.first() == p3);
BOOST_CHECK(cp5.second() == p4);
BOOST_TEST(cp5.first() == p3);
BOOST_TEST(cp5.second() == p4);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
BOOST_CHECK(cpr1.first() == p1);
BOOST_CHECK(cpr1.second() == p2);
BOOST_TEST(cpr1.first() == p1);
BOOST_TEST(cpr1.second() == p2);
// copy construct:
boost::compressed_pair<T1,T2> cp6(cp4);
BOOST_CHECK(cp6.first() == p1);
BOOST_CHECK(cp6.second() == p2);
BOOST_TEST(cp6.first() == p1);
BOOST_TEST(cp6.second() == p2);
// assignment:
// VC6 bug:
// When second() is an empty class, VC6 performs the
@ -174,8 +174,8 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_
// settings - some generate the problem others do not.
cp4.first() = p3;
cp4.second() = p4;
BOOST_CHECK(cp4.first() == p3);
BOOST_CHECK(cp4.second() == p4);
BOOST_TEST(cp4.first() == p3);
BOOST_TEST(cp4.second() == p4);
}
//
// supplimentary tests for case where first arg only is a reference type:
@ -199,8 +199,8 @@ void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second
// first param construct:
boost::compressed_pair<T1,T2> cp2(p1);
cp2.second() = p2;
BOOST_CHECK(cp2.first() == p1);
BOOST_CHECK(cp2.second() == p2);
BOOST_TEST(cp2.first() == p1);
BOOST_TEST(cp2.second() == p2);
#endif
}
//
@ -225,8 +225,8 @@ void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second
// second param construct:
boost::compressed_pair<T1,T2> cp3(p2);
cp3.first() = p1;
BOOST_CHECK(cp3.second() == p2);
BOOST_CHECK(cp3.first() == p1);
BOOST_TEST(cp3.second() == p2);
BOOST_TEST(cp3.first() == p1);
#endif
}
@ -253,14 +253,14 @@ void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_par
// second param construct:
boost::compressed_pair<T1,T2> cp3(p2);
cp3.first()[0] = p1[0];
BOOST_CHECK(cp3.second() == p2);
BOOST_CHECK(cp3.first()[0] == p1[0]);
BOOST_TEST(cp3.second() == p2);
BOOST_TEST(cp3.first()[0] == p1[0]);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp3;
BOOST_CHECK(cpr1.first()[0] == p1[0]);
BOOST_CHECK(cpr1.second() == p2);
BOOST_TEST(cpr1.first()[0] == p1[0]);
BOOST_TEST(cpr1.second() == p2);
BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
}
template <class T1, class T2>
@ -283,14 +283,14 @@ void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_par
// first param construct:
boost::compressed_pair<T1,T2> cp2(p1);
cp2.second()[0] = p2[0];
BOOST_CHECK(cp2.first() == p1);
BOOST_CHECK(cp2.second()[0] == p2[0]);
BOOST_TEST(cp2.first() == p1);
BOOST_TEST(cp2.second()[0] == p2[0]);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp2;
BOOST_CHECK(cpr1.first() == p1);
BOOST_CHECK(cpr1.second()[0] == p2[0]);
BOOST_TEST(cpr1.first() == p1);
BOOST_TEST(cpr1.second()[0] == p2[0]);
BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
}
template <class T1, class T2>
@ -312,18 +312,18 @@ void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_para
boost::compressed_pair<T1,T2> cp1;
cp1.first()[0] = p1[0];
cp1.second()[0] = p2[0];
BOOST_CHECK(cp1.first()[0] == p1[0]);
BOOST_CHECK(cp1.second()[0] == p2[0]);
BOOST_TEST(cp1.first()[0] == p1[0]);
BOOST_TEST(cp1.second()[0] == p2[0]);
// check const members:
const boost::compressed_pair<T1,T2>& cpr1 = cp1;
BOOST_CHECK(cpr1.first()[0] == p1[0]);
BOOST_CHECK(cpr1.second()[0] == p2[0]);
BOOST_TEST(cpr1.first()[0] == p1[0]);
BOOST_TEST(cpr1.second()[0] == p2[0]);
BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
}
int test_main(int, char *[])
int main()
{
// declare some variables to pass to the tester:
non_empty1 ne1(2);
@ -383,13 +383,5 @@ int test_main(int, char *[])
compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4);
// T1 == T2, both non-empty
compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2);
return 0;
return boost::report_errors();
}
unsigned int expected_failures = 0;

View File

@ -9,7 +9,7 @@
// 2 May 2010 (Created) Niels Dekker
#include <boost/utility/value_init.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <string>

View File

@ -12,11 +12,9 @@
// library (Daryle Walker)
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp> // for main
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/operators.hpp> // for boost::random_access_iterator_helper
#include <cstddef> // for std::ptrdiff_t, std::size_t
@ -126,7 +124,7 @@ typename test_opr<T, R, P>::iter_type const
// Main testing function
int
test_main( int , char * [] )
main()
{
using std::string;
@ -136,7 +134,7 @@ test_main( int , char * [] )
test1_type::master_test( "non-const string" );
test2_type::master_test( "const string" );
return boost::exit_success;
return boost::report_errors();
}
// Tests for all of the operators added by random_access_iterator_helper
@ -174,7 +172,7 @@ test_opr<T, R, P>::post_increment_test
oss << *i++ << ' ';
}
BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
BOOST_TEST( oss.str() == "apple orange pear peach grape plum ");
}
// Test post-decrement
@ -193,7 +191,7 @@ test_opr<T, R, P>::post_decrement_test
oss << *i << ' ';
}
BOOST_CHECK( oss.str() == "plum grape peach pear orange apple ");
BOOST_TEST( oss.str() == "plum grape peach pear orange apple ");
}
// Test indirect structure referral
@ -211,7 +209,7 @@ test_opr<T, R, P>::indirect_referral_test
oss << i->size() << ' ';
}
BOOST_CHECK( oss.str() == "5 6 4 5 5 4 ");
BOOST_TEST( oss.str() == "5 6 4 5 5 4 ");
}
// Test offset addition
@ -230,7 +228,7 @@ test_opr<T, R, P>::offset_addition_test
oss << *i << ' ';
}
BOOST_CHECK( oss.str() == "apple pear grape ");
BOOST_TEST( oss.str() == "apple pear grape ");
}
// Test offset addition, in reverse order
@ -249,7 +247,7 @@ test_opr<T, R, P>::reverse_offset_addition_test
oss << *i << ' ';
}
BOOST_CHECK( oss.str() == "apple pear grape ");
BOOST_TEST( oss.str() == "apple pear grape ");
}
// Test offset subtraction
@ -272,7 +270,7 @@ test_opr<T, R, P>::offset_subtraction_test
}
}
BOOST_CHECK( oss.str() == "grape pear apple ");
BOOST_TEST( oss.str() == "grape pear apple ");
}
// Test comparisons
@ -296,10 +294,10 @@ test_opr<T, R, P>::comparison_test
{
ptrdiff_t const j_offset = j - fruit_begin;
BOOST_CHECK( (i != j) == (i_offset != j_offset) );
BOOST_CHECK( (i > j) == (i_offset > j_offset) );
BOOST_CHECK( (i <= j) == (i_offset <= j_offset) );
BOOST_CHECK( (i >= j) == (i_offset >= j_offset) );
BOOST_TEST( (i != j) == (i_offset != j_offset) );
BOOST_TEST( (i > j) == (i_offset > j_offset) );
BOOST_TEST( (i <= j) == (i_offset <= j_offset) );
BOOST_TEST( (i >= j) == (i_offset >= j_offset) );
}
}
cout << std::endl;
@ -320,5 +318,5 @@ test_opr<T, R, P>::indexing_test
oss << fruit_begin[ k ] << ' ';
}
BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
BOOST_TEST( oss.str() == "apple orange pear peach grape plum ");
}

View File

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

View File

@ -0,0 +1,59 @@
/*
Copyright 2020 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && \
(!defined(BOOST_MSVC) || (BOOST_MSVC >= 1922))
#include <boost/operators.hpp>
#include <boost/static_assert.hpp>
namespace {
class Value
: boost::operators<Value> {
public:
BOOST_OPERATORS_CONSTEXPR explicit Value(int v)
: v_(v) { }
BOOST_OPERATORS_CONSTEXPR bool
operator<(const Value& x) const {
return v_ < x.v_;
}
BOOST_OPERATORS_CONSTEXPR bool
operator==(const Value& x) const {
return v_ == x.v_;
}
private:
int v_;
};
} // namespace
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) == Value(2)));
BOOST_STATIC_ASSERT(Value(1) != Value(2));
BOOST_STATIC_ASSERT(Value(1) < Value(2));
BOOST_STATIC_ASSERT(Value(1) <= Value(2));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) > Value(2)));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) >= Value(2)));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(2) == Value(1)));
BOOST_STATIC_ASSERT(Value(2) != Value(1));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(2) < Value(1)));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(2) <= Value(1)));
BOOST_STATIC_ASSERT(Value(2) > Value(1));
BOOST_STATIC_ASSERT(Value(2) >= Value(1));
BOOST_STATIC_ASSERT(Value(1) == Value(1));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) != Value(1)));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) < Value(1)));
BOOST_STATIC_ASSERT(Value(1) <= Value(1));
BOOST_STATIC_ASSERT(!static_cast<bool>(Value(1) > Value(1)));
BOOST_STATIC_ASSERT(Value(1) >= Value(1));
#endif

View File

@ -21,13 +21,10 @@
// 12 Dec 99 Minor update, output confirmation message.
// 15 Nov 99 Initial version
#define BOOST_INCLUDE_MAIN
#include <boost/config.hpp> // for BOOST_MSVC
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/operators.hpp> // for the tested items
#include <boost/random/linear_congruential.hpp> // for boost::minstd_rand
#include <boost/test/test_tools.hpp> // for main
#include <boost/utility/detail/minstd_rand.hpp> // for boost::detail::minstd_rand
#include <boost/core/lightweight_test.hpp>
#include <iostream> // for std::cout (std::endl indirectly)
@ -38,11 +35,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
@ -55,9 +50,9 @@ namespace
void operator!() const;
public:
convertible_to_bool( const bool value ) : _value( value ) {}
convertible_to_bool( const bool value ) : _value( value ) {}
operator unspecified_bool_type() const
operator unspecified_bool_type() const
{ return _value ? &convertible_to_bool::_value : 0; }
};
@ -69,12 +64,12 @@ namespace
, boost::shiftable<Wrapped1<T> >
{
public:
explicit Wrapped1( T v = T() ) : _value(v) {}
T value() const { return _value; }
explicit Wrapped1( T v = T() ) : _value(v) {}
T value() const { return _value; }
convertible_to_bool operator<(const Wrapped1& x) const
convertible_to_bool operator<(const Wrapped1& x) const
{ return _value < x._value; }
convertible_to_bool operator==(const Wrapped1& x) const
convertible_to_bool operator==(const Wrapped1& x) const
{ return _value == x._value; }
Wrapped1& operator+=(const Wrapped1& x)
@ -97,8 +92,8 @@ namespace
{ _value <<= x._value; return *this; }
Wrapped1& operator>>=(const Wrapped1& x)
{ _value >>= x._value; return *this; }
Wrapped1& operator++() { ++_value; return *this; }
Wrapped1& operator--() { --_value; return *this; }
Wrapped1& operator++() { ++_value; return *this; }
Wrapped1& operator--() { --_value; return *this; }
private:
T _value;
@ -313,17 +308,17 @@ namespace
template <class X1, class Y1, class X2, class Y2>
void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
BOOST_CHECK( true_value(y1) == true_value(y2) );
BOOST_CHECK( true_value(x1) == true_value(x2) );
BOOST_TEST( true_value(y1) == true_value(y2) );
BOOST_TEST( true_value(x1) == true_value(x2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
BOOST_CHECK( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) );
BOOST_CHECK( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) );
BOOST_CHECK( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) );
BOOST_CHECK( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) );
BOOST_TEST( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) );
BOOST_TEST( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) );
BOOST_TEST( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) );
BOOST_TEST( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) );
}
template <class X1, class Y1, class X2, class Y2>
@ -337,8 +332,8 @@ namespace
template <class X1, class Y1, class X2, class Y2>
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
BOOST_CHECK( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) );
BOOST_CHECK( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) );
BOOST_TEST( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) );
BOOST_TEST( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) );
}
template <class X1, class Y1, class X2, class Y2>
@ -352,7 +347,7 @@ namespace
template <class X1, class Y1, class X2, class Y2>
void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
BOOST_CHECK( (x1 * y1).value() == (x2 * y2) );
BOOST_TEST( (x1 * y1).value() == (x2 * y2) );
}
template <class X1, class Y1, class X2, class Y2>
@ -366,7 +361,7 @@ namespace
template <class A, class B>
void test_value_equality(A a, B b)
{
BOOST_CHECK(a.value() == b);
BOOST_TEST(a.value() == b);
}
#define TEST_OP_R(op) test_value_equality(x1 op y1, x2 op y2)
@ -492,16 +487,16 @@ namespace
void test_incrementable(X1 x1, X2 x2)
{
sanity_check( x1, x1, x2, x2 );
BOOST_CHECK( (x1++).value() == x2++ );
BOOST_CHECK( x1.value() == x2 );
BOOST_TEST( (x1++).value() == x2++ );
BOOST_TEST( x1.value() == x2 );
}
template <class X1, class X2>
void test_decrementable(X1 x1, X2 x2)
{
sanity_check( x1, x1, x2, x2 );
BOOST_CHECK( (x1--).value() == x2-- );
BOOST_CHECK( x1.value() == x2 );
BOOST_TEST( (x1--).value() == x2-- );
BOOST_TEST( x1.value() == x2 );
}
template <class X1, class Y1, class X2, class Y2>
@ -534,7 +529,7 @@ namespace
template <class Big, class Small>
struct tester
{
void operator()(boost::minstd_rand& randomizer) const
void operator()(boost::detail::minstd_rand& randomizer) const
{
Big b1 = Big( randomizer() );
Big b2 = Big( randomizer() );
@ -548,7 +543,7 @@ namespace
template <class Big, class Small>
struct tester_left
{
void operator()(boost::minstd_rand& randomizer) const
void operator()(boost::detail::minstd_rand& randomizer) const
{
Big b1 = Big( randomizer() );
Small s = Small( randomizer() );
@ -605,10 +600,10 @@ template Wrapped6<unsigned long, unsigned char>;
template Wrapped6<unsigned int, unsigned char>;
#endif
#define PRIVATE_EXPR_TEST(e, t) BOOST_CHECK( ((e), (t)) )
#define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) )
int
test_main( int , char * [] )
main()
{
using std::cout;
using std::endl;
@ -622,7 +617,7 @@ test_main( int , char * [] )
for (int n = 0; n < 1000; ++n) // was 10,000 but took too long (Beman)
{
boost::minstd_rand r;
boost::detail::minstd_rand r;
tester<long, int>()(r);
tester<long, signed char>()(r);
tester<long, long>()(r);
@ -650,22 +645,22 @@ test_main( int , char * [] )
MyInt i2(2);
MyInt i;
BOOST_CHECK( i1.value() == 1 );
BOOST_CHECK( i2.value() == 2 );
BOOST_CHECK( i.value() == 0 );
BOOST_TEST( i1.value() == 1 );
BOOST_TEST( i2.value() == 2 );
BOOST_TEST( i.value() == 0 );
cout << "Created MyInt objects.\n";
PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
BOOST_CHECK( static_cast<bool>(i2 == i) );
BOOST_CHECK( static_cast<bool>(i1 != i2) );
BOOST_CHECK( static_cast<bool>(i1 < i2) );
BOOST_CHECK( static_cast<bool>(i1 <= i2) );
BOOST_CHECK( static_cast<bool>(i <= i2) );
BOOST_CHECK( static_cast<bool>(i2 > i1) );
BOOST_CHECK( static_cast<bool>(i2 >= i1) );
BOOST_CHECK( static_cast<bool>(i2 >= i) );
BOOST_TEST( static_cast<bool>(i2 == i) );
BOOST_TEST( static_cast<bool>(i1 != i2) );
BOOST_TEST( static_cast<bool>(i1 < i2) );
BOOST_TEST( static_cast<bool>(i1 <= i2) );
BOOST_TEST( static_cast<bool>(i <= i2) );
BOOST_TEST( static_cast<bool>(i2 > i1) );
BOOST_TEST( static_cast<bool>(i2 >= i1) );
BOOST_TEST( static_cast<bool>(i2 >= i) );
PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
@ -689,86 +684,86 @@ test_main( int , char * [] )
MyLong j2(2);
MyLong j;
BOOST_CHECK( j1.value() == 1 );
BOOST_CHECK( j2.value() == 2 );
BOOST_CHECK( j.value() == 0 );
BOOST_TEST( j1.value() == 1 );
BOOST_TEST( j2.value() == 2 );
BOOST_TEST( j.value() == 0 );
cout << "Created MyLong objects.\n";
PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
BOOST_CHECK( static_cast<bool>(j2 == j) );
BOOST_CHECK( static_cast<bool>(2 == j) );
BOOST_CHECK( static_cast<bool>(j2 == 2) );
BOOST_CHECK( static_cast<bool>(j == j2) );
BOOST_CHECK( static_cast<bool>(j1 != j2) );
BOOST_CHECK( static_cast<bool>(j1 != 2) );
BOOST_CHECK( static_cast<bool>(1 != j2) );
BOOST_CHECK( static_cast<bool>(j1 < j2) );
BOOST_CHECK( static_cast<bool>(1 < j2) );
BOOST_CHECK( static_cast<bool>(j1 < 2) );
BOOST_CHECK( static_cast<bool>(j1 <= j2) );
BOOST_CHECK( static_cast<bool>(1 <= j2) );
BOOST_CHECK( static_cast<bool>(j1 <= j) );
BOOST_CHECK( static_cast<bool>(j <= j2) );
BOOST_CHECK( static_cast<bool>(2 <= j2) );
BOOST_CHECK( static_cast<bool>(j <= 2) );
BOOST_CHECK( static_cast<bool>(j2 > j1) );
BOOST_CHECK( static_cast<bool>(2 > j1) );
BOOST_CHECK( static_cast<bool>(j2 > 1) );
BOOST_CHECK( static_cast<bool>(j2 >= j1) );
BOOST_CHECK( static_cast<bool>(2 >= j1) );
BOOST_CHECK( static_cast<bool>(j2 >= 1) );
BOOST_CHECK( static_cast<bool>(j2 >= j) );
BOOST_CHECK( static_cast<bool>(2 >= j) );
BOOST_CHECK( static_cast<bool>(j2 >= 2) );
BOOST_TEST( static_cast<bool>(j2 == j) );
BOOST_TEST( static_cast<bool>(2 == j) );
BOOST_TEST( static_cast<bool>(j2 == 2) );
BOOST_TEST( static_cast<bool>(j == j2) );
BOOST_TEST( static_cast<bool>(j1 != j2) );
BOOST_TEST( static_cast<bool>(j1 != 2) );
BOOST_TEST( static_cast<bool>(1 != j2) );
BOOST_TEST( static_cast<bool>(j1 < j2) );
BOOST_TEST( static_cast<bool>(1 < j2) );
BOOST_TEST( static_cast<bool>(j1 < 2) );
BOOST_TEST( static_cast<bool>(j1 <= j2) );
BOOST_TEST( static_cast<bool>(1 <= j2) );
BOOST_TEST( static_cast<bool>(j1 <= j) );
BOOST_TEST( static_cast<bool>(j <= j2) );
BOOST_TEST( static_cast<bool>(2 <= j2) );
BOOST_TEST( static_cast<bool>(j <= 2) );
BOOST_TEST( static_cast<bool>(j2 > j1) );
BOOST_TEST( static_cast<bool>(2 > j1) );
BOOST_TEST( static_cast<bool>(j2 > 1) );
BOOST_TEST( static_cast<bool>(j2 >= j1) );
BOOST_TEST( static_cast<bool>(2 >= j1) );
BOOST_TEST( static_cast<bool>(j2 >= 1) );
BOOST_TEST( static_cast<bool>(j2 >= j) );
BOOST_TEST( static_cast<bool>(2 >= j) );
BOOST_TEST( static_cast<bool>(j2 >= 2) );
BOOST_CHECK( static_cast<bool>((j1 + 2) == 3) );
BOOST_CHECK( static_cast<bool>((1 + j2) == 3) );
BOOST_TEST( static_cast<bool>((j1 + 2) == 3) );
BOOST_TEST( static_cast<bool>((1 + j2) == 3) );
PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
BOOST_CHECK( static_cast<bool>((j + 2) == 5) );
BOOST_CHECK( static_cast<bool>((3 + j2) == 5) );
BOOST_TEST( static_cast<bool>((j + 2) == 5) );
BOOST_TEST( static_cast<bool>((3 + j2) == 5) );
PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
BOOST_CHECK( static_cast<bool>((j - 1) == 4) );
BOOST_TEST( static_cast<bool>((j - 1) == 4) );
PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
BOOST_CHECK( static_cast<bool>((j * 2) == 8) );
BOOST_CHECK( static_cast<bool>((4 * j2) == 8) );
BOOST_TEST( static_cast<bool>((j * 2) == 8) );
BOOST_TEST( static_cast<bool>((4 * j2) == 8) );
PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
BOOST_CHECK( static_cast<bool>((j / 2) == 4) );
BOOST_TEST( static_cast<bool>((j / 2) == 4) );
PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
BOOST_CHECK( static_cast<bool>((j % 3) == 1) );
BOOST_TEST( static_cast<bool>((j % 3) == 1) );
PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
BOOST_CHECK( static_cast<bool>((1 | j2 | j) == 7) );
BOOST_CHECK( static_cast<bool>((j1 | 2 | j) == 7) );
BOOST_CHECK( static_cast<bool>((j1 | j2 | 4) == 7) );
BOOST_TEST( static_cast<bool>((1 | j2 | j) == 7) );
BOOST_TEST( static_cast<bool>((j1 | 2 | j) == 7) );
BOOST_TEST( static_cast<bool>((j1 | j2 | 4) == 7) );
PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
BOOST_CHECK( static_cast<bool>((7 & j2) == 2) );
BOOST_CHECK( static_cast<bool>((j & 2) == 2) );
BOOST_TEST( static_cast<bool>((7 & j2) == 2) );
BOOST_TEST( static_cast<bool>((j & 2) == 2) );
PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
BOOST_CHECK( static_cast<bool>((3 ^ j1) == 2) );
BOOST_CHECK( static_cast<bool>((j ^ 1) == 2) );
BOOST_TEST( static_cast<bool>((3 ^ j1) == 2) );
BOOST_TEST( static_cast<bool>((j ^ 1) == 2) );
PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
BOOST_CHECK( static_cast<bool>((j1 << 2) == 4) );
BOOST_CHECK( static_cast<bool>((j2 << 1) == 4) );
BOOST_TEST( static_cast<bool>((j1 << 2) == 4) );
BOOST_TEST( static_cast<bool>((j2 << 1) == 4) );
PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
BOOST_CHECK( static_cast<bool>((j >> 2) == 1) );
BOOST_CHECK( static_cast<bool>((j2 >> 1) == 1) );
BOOST_TEST( static_cast<bool>((j >> 2) == 1) );
BOOST_TEST( static_cast<bool>((j2 >> 1) == 1) );
PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
cout << "Performed tests on MyLong objects.\n";
@ -777,22 +772,22 @@ test_main( int , char * [] )
MyChar k2(2);
MyChar k;
BOOST_CHECK( k1.value() == 1 );
BOOST_CHECK( k2.value() == 2 );
BOOST_CHECK( k.value() == 0 );
BOOST_TEST( k1.value() == 1 );
BOOST_TEST( k2.value() == 2 );
BOOST_TEST( k.value() == 0 );
cout << "Created MyChar objects.\n";
PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
BOOST_CHECK( static_cast<bool>(k2 == k) );
BOOST_CHECK( static_cast<bool>(k1 != k2) );
BOOST_CHECK( static_cast<bool>(k1 < k2) );
BOOST_CHECK( static_cast<bool>(k1 <= k2) );
BOOST_CHECK( static_cast<bool>(k <= k2) );
BOOST_CHECK( static_cast<bool>(k2 > k1) );
BOOST_CHECK( static_cast<bool>(k2 >= k1) );
BOOST_CHECK( static_cast<bool>(k2 >= k) );
BOOST_TEST( static_cast<bool>(k2 == k) );
BOOST_TEST( static_cast<bool>(k1 != k2) );
BOOST_TEST( static_cast<bool>(k1 < k2) );
BOOST_TEST( static_cast<bool>(k1 <= k2) );
BOOST_TEST( static_cast<bool>(k <= k2) );
BOOST_TEST( static_cast<bool>(k2 > k1) );
BOOST_TEST( static_cast<bool>(k2 >= k1) );
BOOST_TEST( static_cast<bool>(k2 >= k) );
cout << "Performed tests on MyChar objects.\n";
@ -800,39 +795,39 @@ test_main( int , char * [] )
MyShort l2(2);
MyShort l;
BOOST_CHECK( l1.value() == 1 );
BOOST_CHECK( l2.value() == 2 );
BOOST_CHECK( l.value() == 0 );
BOOST_TEST( l1.value() == 1 );
BOOST_TEST( l2.value() == 2 );
BOOST_TEST( l.value() == 0 );
cout << "Created MyShort objects.\n";
PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
BOOST_CHECK( static_cast<bool>(l2 == l) );
BOOST_CHECK( static_cast<bool>(2 == l) );
BOOST_CHECK( static_cast<bool>(l2 == 2) );
BOOST_CHECK( static_cast<bool>(l == l2) );
BOOST_CHECK( static_cast<bool>(l1 != l2) );
BOOST_CHECK( static_cast<bool>(l1 != 2) );
BOOST_CHECK( static_cast<bool>(1 != l2) );
BOOST_CHECK( static_cast<bool>(l1 < l2) );
BOOST_CHECK( static_cast<bool>(1 < l2) );
BOOST_CHECK( static_cast<bool>(l1 < 2) );
BOOST_CHECK( static_cast<bool>(l1 <= l2) );
BOOST_CHECK( static_cast<bool>(1 <= l2) );
BOOST_CHECK( static_cast<bool>(l1 <= l) );
BOOST_CHECK( static_cast<bool>(l <= l2) );
BOOST_CHECK( static_cast<bool>(2 <= l2) );
BOOST_CHECK( static_cast<bool>(l <= 2) );
BOOST_CHECK( static_cast<bool>(l2 > l1) );
BOOST_CHECK( static_cast<bool>(2 > l1) );
BOOST_CHECK( static_cast<bool>(l2 > 1) );
BOOST_CHECK( static_cast<bool>(l2 >= l1) );
BOOST_CHECK( static_cast<bool>(2 >= l1) );
BOOST_CHECK( static_cast<bool>(l2 >= 1) );
BOOST_CHECK( static_cast<bool>(l2 >= l) );
BOOST_CHECK( static_cast<bool>(2 >= l) );
BOOST_CHECK( static_cast<bool>(l2 >= 2) );
BOOST_TEST( static_cast<bool>(l2 == l) );
BOOST_TEST( static_cast<bool>(2 == l) );
BOOST_TEST( static_cast<bool>(l2 == 2) );
BOOST_TEST( static_cast<bool>(l == l2) );
BOOST_TEST( static_cast<bool>(l1 != l2) );
BOOST_TEST( static_cast<bool>(l1 != 2) );
BOOST_TEST( static_cast<bool>(1 != l2) );
BOOST_TEST( static_cast<bool>(l1 < l2) );
BOOST_TEST( static_cast<bool>(1 < l2) );
BOOST_TEST( static_cast<bool>(l1 < 2) );
BOOST_TEST( static_cast<bool>(l1 <= l2) );
BOOST_TEST( static_cast<bool>(1 <= l2) );
BOOST_TEST( static_cast<bool>(l1 <= l) );
BOOST_TEST( static_cast<bool>(l <= l2) );
BOOST_TEST( static_cast<bool>(2 <= l2) );
BOOST_TEST( static_cast<bool>(l <= 2) );
BOOST_TEST( static_cast<bool>(l2 > l1) );
BOOST_TEST( static_cast<bool>(2 > l1) );
BOOST_TEST( static_cast<bool>(l2 > 1) );
BOOST_TEST( static_cast<bool>(l2 >= l1) );
BOOST_TEST( static_cast<bool>(2 >= l1) );
BOOST_TEST( static_cast<bool>(l2 >= 1) );
BOOST_TEST( static_cast<bool>(l2 >= l) );
BOOST_TEST( static_cast<bool>(2 >= l) );
BOOST_TEST( static_cast<bool>(l2 >= 2) );
cout << "Performed tests on MyShort objects.\n";
@ -842,44 +837,44 @@ test_main( int , char * [] )
MyDoubleInt di;
MyDoubleInt tmp;
BOOST_CHECK( di1.value() == 1 );
BOOST_CHECK( di2.value() == 2 );
BOOST_CHECK( di2.value() == 2 );
BOOST_CHECK( di.value() == 0 );
BOOST_TEST( di1.value() == 1 );
BOOST_TEST( di2.value() == 2 );
BOOST_TEST( di2.value() == 2 );
BOOST_TEST( di.value() == 0 );
cout << "Created MyDoubleInt objects.\n";
PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
BOOST_CHECK( static_cast<bool>(di2 == di) );
BOOST_CHECK( static_cast<bool>(2 == di) );
BOOST_CHECK( static_cast<bool>(di == 2) );
BOOST_CHECK( static_cast<bool>(di1 < di2) );
BOOST_CHECK( static_cast<bool>(1 < di2) );
BOOST_CHECK( static_cast<bool>(di1 <= di2) );
BOOST_CHECK( static_cast<bool>(1 <= di2) );
BOOST_CHECK( static_cast<bool>(di2 > di1) );
BOOST_CHECK( static_cast<bool>(di2 > 1) );
BOOST_CHECK( static_cast<bool>(di2 >= di1) );
BOOST_CHECK( static_cast<bool>(di2 >= 1) );
BOOST_CHECK( static_cast<bool>(di1 / di2 == half) );
BOOST_CHECK( static_cast<bool>(di1 / 2 == half) );
BOOST_CHECK( static_cast<bool>(1 / di2 == half) );
BOOST_TEST( static_cast<bool>(di2 == di) );
BOOST_TEST( static_cast<bool>(2 == di) );
BOOST_TEST( static_cast<bool>(di == 2) );
BOOST_TEST( static_cast<bool>(di1 < di2) );
BOOST_TEST( static_cast<bool>(1 < di2) );
BOOST_TEST( static_cast<bool>(di1 <= di2) );
BOOST_TEST( static_cast<bool>(1 <= di2) );
BOOST_TEST( static_cast<bool>(di2 > di1) );
BOOST_TEST( static_cast<bool>(di2 > 1) );
BOOST_TEST( static_cast<bool>(di2 >= di1) );
BOOST_TEST( static_cast<bool>(di2 >= 1) );
BOOST_TEST( static_cast<bool>(di1 / di2 == half) );
BOOST_TEST( static_cast<bool>(di1 / 2 == half) );
BOOST_TEST( static_cast<bool>(1 / di2 == half) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=2) == half) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=di2) == half) );
BOOST_CHECK( static_cast<bool>(di1 * di2 == di2) );
BOOST_CHECK( static_cast<bool>(di1 * 2 == di2) );
BOOST_CHECK( static_cast<bool>(1 * di2 == di2) );
BOOST_TEST( static_cast<bool>(di1 * di2 == di2) );
BOOST_TEST( static_cast<bool>(di1 * 2 == di2) );
BOOST_TEST( static_cast<bool>(1 * di2 == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=2) == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=di2) == di2) );
BOOST_CHECK( static_cast<bool>(di2 - di1 == di1) );
BOOST_CHECK( static_cast<bool>(di2 - 1 == di1) );
BOOST_CHECK( static_cast<bool>(2 - di1 == di1) );
BOOST_TEST( static_cast<bool>(di2 - di1 == di1) );
BOOST_TEST( static_cast<bool>(di2 - 1 == di1) );
BOOST_TEST( static_cast<bool>(2 - di1 == di1) );
PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=1) == di1) );
PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=di1) == di1) );
BOOST_CHECK( static_cast<bool>(di1 + di1 == di2) );
BOOST_CHECK( static_cast<bool>(di1 + 1 == di2) );
BOOST_CHECK( static_cast<bool>(1 + di1 == di2) );
BOOST_TEST( static_cast<bool>(di1 + di1 == di2) );
BOOST_TEST( static_cast<bool>(di1 + 1 == di2) );
BOOST_TEST( static_cast<bool>(1 + di1 == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=1) == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=di1) == di2) );
@ -890,52 +885,52 @@ test_main( int , char * [] )
MyLongInt li;
MyLongInt tmp2;
BOOST_CHECK( li1.value() == 1 );
BOOST_CHECK( li2.value() == 2 );
BOOST_CHECK( li.value() == 0 );
BOOST_TEST( li1.value() == 1 );
BOOST_TEST( li2.value() == 2 );
BOOST_TEST( li.value() == 0 );
cout << "Created MyLongInt objects.\n";
PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
BOOST_CHECK( static_cast<bool>(li2 == li) );
BOOST_CHECK( static_cast<bool>(2 == li) );
BOOST_CHECK( static_cast<bool>(li == 2) );
BOOST_CHECK( static_cast<bool>(li1 < li2) );
BOOST_CHECK( static_cast<bool>(1 < li2) );
BOOST_CHECK( static_cast<bool>(li1 <= li2) );
BOOST_CHECK( static_cast<bool>(1 <= li2) );
BOOST_CHECK( static_cast<bool>(li2 > li1) );
BOOST_CHECK( static_cast<bool>(li2 > 1) );
BOOST_CHECK( static_cast<bool>(li2 >= li1) );
BOOST_CHECK( static_cast<bool>(li2 >= 1) );
BOOST_CHECK( static_cast<bool>(li1 % li2 == li1) );
BOOST_CHECK( static_cast<bool>(li1 % 2 == li1) );
BOOST_CHECK( static_cast<bool>(1 % li2 == li1) );
BOOST_TEST( static_cast<bool>(li2 == li) );
BOOST_TEST( static_cast<bool>(2 == li) );
BOOST_TEST( static_cast<bool>(li == 2) );
BOOST_TEST( static_cast<bool>(li1 < li2) );
BOOST_TEST( static_cast<bool>(1 < li2) );
BOOST_TEST( static_cast<bool>(li1 <= li2) );
BOOST_TEST( static_cast<bool>(1 <= li2) );
BOOST_TEST( static_cast<bool>(li2 > li1) );
BOOST_TEST( static_cast<bool>(li2 > 1) );
BOOST_TEST( static_cast<bool>(li2 >= li1) );
BOOST_TEST( static_cast<bool>(li2 >= 1) );
BOOST_TEST( static_cast<bool>(li1 % li2 == li1) );
BOOST_TEST( static_cast<bool>(li1 % 2 == li1) );
BOOST_TEST( static_cast<bool>(1 % li2 == li1) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=2) == li1) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=li2) == li1) );
BOOST_CHECK( static_cast<bool>(li1 / li2 == 0) );
BOOST_CHECK( static_cast<bool>(li1 / 2 == 0) );
BOOST_CHECK( static_cast<bool>(1 / li2 == 0) );
BOOST_TEST( static_cast<bool>(li1 / li2 == 0) );
BOOST_TEST( static_cast<bool>(li1 / 2 == 0) );
BOOST_TEST( static_cast<bool>(1 / li2 == 0) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=2) == 0) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=li2) == 0) );
BOOST_CHECK( static_cast<bool>(li1 * li2 == li2) );
BOOST_CHECK( static_cast<bool>(li1 * 2 == li2) );
BOOST_CHECK( static_cast<bool>(1 * li2 == li2) );
BOOST_TEST( static_cast<bool>(li1 * li2 == li2) );
BOOST_TEST( static_cast<bool>(li1 * 2 == li2) );
BOOST_TEST( static_cast<bool>(1 * li2 == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=2) == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=li2) == li2) );
BOOST_CHECK( static_cast<bool>(li2 - li1 == li1) );
BOOST_CHECK( static_cast<bool>(li2 - 1 == li1) );
BOOST_CHECK( static_cast<bool>(2 - li1 == li1) );
BOOST_TEST( static_cast<bool>(li2 - li1 == li1) );
BOOST_TEST( static_cast<bool>(li2 - 1 == li1) );
BOOST_TEST( static_cast<bool>(2 - li1 == li1) );
PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=1) == li1) );
PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=li1) == li1) );
BOOST_CHECK( static_cast<bool>(li1 + li1 == li2) );
BOOST_CHECK( static_cast<bool>(li1 + 1 == li2) );
BOOST_CHECK( static_cast<bool>(1 + li1 == li2) );
BOOST_TEST( static_cast<bool>(li1 + li1 == li2) );
BOOST_TEST( static_cast<bool>(li1 + 1 == li2) );
BOOST_TEST( static_cast<bool>(1 + li1 == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=1) == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=li1) == li2) );
cout << "Performed tests on MyLongInt objects.\n";
return boost::exit_success;
return boost::report_errors();
}

View File

@ -297,6 +297,12 @@ int main()
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<volatile int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const volatile int> >::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr&(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr const&(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of&(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of const&(double)>::type, int>::value));
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&&)>::type, short>::value));
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&)>::type, int>::value));

View File

@ -0,0 +1,26 @@
/*
Copyright (c) Marshall Clow 2017.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <algorithm>
#include <string>
#include <boost/utility/string_ref.hpp>
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
#error "Unsupported test"
#endif
std::string makeatemp() { return "abc"; }
int main()
{
boost::basic_string_ref<char> sv(makeatemp());
return 0;
}

View File

@ -13,17 +13,16 @@
#include <boost/utility/string_ref.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include <boost/core/lightweight_test.hpp>
typedef boost::string_ref string_ref;
// Should be equal
void interop ( const std::string &str, string_ref ref ) {
// BOOST_CHECK ( str == ref );
BOOST_CHECK ( str.size () == ref.size ());
BOOST_CHECK ( std::equal ( str.begin (), str.end (), ref.begin ()));
BOOST_CHECK ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
// BOOST_TEST ( str == ref );
BOOST_TEST ( str.size () == ref.size ());
BOOST_TEST ( std::equal ( str.begin (), str.end (), ref.begin ()));
BOOST_TEST ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
}
void null_tests ( const char *p ) {
@ -34,10 +33,10 @@ void null_tests ( const char *p ) {
string_ref sr4 ( p );
sr4.clear ();
BOOST_CHECK ( sr1 == sr2 );
BOOST_CHECK ( sr1 == sr3 );
BOOST_CHECK ( sr2 == sr3 );
BOOST_CHECK ( sr1 == sr4 );
BOOST_TEST ( sr1 == sr2 );
BOOST_TEST ( sr1 == sr3 );
BOOST_TEST ( sr2 == sr3 );
BOOST_TEST ( sr1 == sr4 );
}
// make sure that substrings work just like strings
@ -94,7 +93,7 @@ const char *test_strings [] = {
NULL
};
BOOST_AUTO_TEST_CASE( test_main )
int main()
{
const char **p = &test_strings[0];
@ -106,4 +105,6 @@ BOOST_AUTO_TEST_CASE( test_main )
p++;
}
return boost::report_errors();
}

View File

@ -12,63 +12,62 @@
#include <boost/utility/string_ref.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include <boost/core/lightweight_test.hpp>
typedef boost::string_ref string_ref;
void ends_with ( const char *arg ) {
const size_t sz = strlen ( arg );
const size_t sz = std::strlen ( arg );
string_ref sr ( arg );
string_ref sr2 ( arg );
const char *p = arg;
while ( *p ) {
BOOST_CHECK ( sr.ends_with ( p ));
BOOST_TEST ( sr.ends_with ( p ));
++p;
}
while ( !sr2.empty ()) {
BOOST_CHECK ( sr.ends_with ( sr2 ));
BOOST_TEST ( sr.ends_with ( sr2 ));
sr2.remove_prefix (1);
}
sr2 = arg;
while ( !sr2.empty ()) {
BOOST_CHECK ( sr.ends_with ( sr2 ));
BOOST_TEST ( sr.ends_with ( sr2 ));
sr2.remove_prefix (1);
}
char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
sr2 = arg;
if ( sz > 0 )
BOOST_CHECK ( sr2.ends_with ( ch ));
BOOST_CHECK ( !sr2.ends_with ( ++ch ));
BOOST_CHECK ( sr2.ends_with ( string_ref ()));
BOOST_TEST ( sr2.ends_with ( ch ));
BOOST_TEST ( !sr2.ends_with ( ++ch ));
BOOST_TEST ( sr2.ends_with ( string_ref ()));
}
void starts_with ( const char *arg ) {
const size_t sz = strlen ( arg );
const size_t sz = std::strlen ( arg );
string_ref sr ( arg );
string_ref sr2 ( arg );
const char *p = arg + std::strlen ( arg ) - 1;
while ( p >= arg ) {
std::string foo ( arg, p + 1 );
BOOST_CHECK ( sr.starts_with ( foo ));
BOOST_TEST ( sr.starts_with ( foo ));
--p;
}
while ( !sr2.empty ()) {
BOOST_CHECK ( sr.starts_with ( sr2 ));
BOOST_TEST ( sr.starts_with ( sr2 ));
sr2.remove_suffix (1);
}
char ch = *arg;
sr2 = arg;
if ( sz > 0 )
BOOST_CHECK ( sr2.starts_with ( ch ));
BOOST_CHECK ( !sr2.starts_with ( ++ch ));
BOOST_CHECK ( sr2.starts_with ( string_ref ()));
BOOST_TEST ( sr2.starts_with ( ch ));
BOOST_TEST ( !sr2.starts_with ( ++ch ));
BOOST_TEST ( sr2.starts_with ( string_ref ()));
}
void reverse ( const char *arg ) {
@ -78,14 +77,14 @@ void reverse ( const char *arg ) {
string_ref sr2 ( string1 );
std::string string2 ( sr2.rbegin (), sr2.rend ());
BOOST_CHECK ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
BOOST_CHECK ( string2 == arg );
BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
BOOST_TEST ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
BOOST_TEST ( string2 == arg );
BOOST_TEST ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
}
// This helper function eliminates signed vs. unsigned warnings
// This helper function eliminates signed vs. unsigned warnings
string_ref::size_type ptr_diff ( const char *res, const char *base ) {
BOOST_CHECK ( res >= base );
BOOST_TEST ( res >= base );
return static_cast<string_ref::size_type> ( res - base );
}
@ -94,12 +93,16 @@ void find ( const char *arg ) {
string_ref sr2;
const char *p;
// When we search for the empty string, we find it at position 0
BOOST_TEST ( sr1.find (sr2) == 0 );
BOOST_TEST ( sr1.rfind(sr2) == 0 );
// Look for each character in the string(searching from the start)
p = arg;
sr1 = arg;
while ( *p ) {
string_ref::size_type pos = sr1.find(*p);
BOOST_CHECK ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg )));
BOOST_TEST ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg )));
++p;
}
@ -108,17 +111,17 @@ void find ( const char *arg ) {
sr1 = arg;
while ( *p ) {
string_ref::size_type pos = sr1.rfind(*p);
BOOST_CHECK ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
BOOST_TEST ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
++p;
}
// Look for pairs on characters (searching from the start)
// Look for pairs on characters (searching from the start)
sr1 = arg;
p = arg;
while ( *p && *(p+1)) {
string_ref sr3 ( p, 2 );
string_ref::size_type pos = sr1.find ( sr3 );
BOOST_CHECK ( pos != string_ref::npos && pos <= static_cast<string_ref::size_type>( p - arg ));
BOOST_TEST ( pos != string_ref::npos && pos <= static_cast<string_ref::size_type>( p - arg ));
p++;
}
@ -129,9 +132,9 @@ void find ( const char *arg ) {
for ( int ch = 1; ch < 256; ++ch ) {
string_ref::size_type pos = sr1.find(ch);
const char *strp = std::strchr ( arg, ch );
BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
BOOST_TEST (( strp == NULL ) == ( pos == string_ref::npos ));
if ( strp != NULL )
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
}
sr1 = arg;
@ -141,9 +144,9 @@ void find ( const char *arg ) {
for ( int ch = 1; ch < 256; ++ch ) {
string_ref::size_type pos = sr1.rfind(ch);
const char *strp = std::strrchr ( arg, ch );
BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
BOOST_TEST (( strp == NULL ) == ( pos == string_ref::npos ));
if ( strp != NULL )
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
}
@ -152,17 +155,17 @@ void find ( const char *arg ) {
sr1 = arg;
while ( !sr1.empty ()) {
string_ref::size_type pos = sr1.find(*p);
BOOST_CHECK ( pos == 0 );
BOOST_TEST ( pos == 0 );
sr1.remove_prefix (1);
++p;
}
// Find everything at the end
sr1 = arg;
p = arg + strlen ( arg ) - 1;
p = arg + std::strlen ( arg ) - 1;
while ( !sr1.empty ()) {
string_ref::size_type pos = sr1.rfind(*p);
BOOST_CHECK ( pos == sr1.size () - 1 );
BOOST_TEST ( pos == sr1.size () - 1 );
sr1.remove_suffix (1);
--p;
}
@ -172,7 +175,7 @@ void find ( const char *arg ) {
p = arg;
while ( !sr1.empty ()) {
string_ref::size_type pos = sr1.find_first_of(*p);
BOOST_CHECK ( pos == 0 );
BOOST_TEST ( pos == 0 );
sr1.remove_prefix (1);
++p;
}
@ -180,10 +183,10 @@ void find ( const char *arg ) {
// Find everything at the end
sr1 = arg;
p = arg + strlen ( arg ) - 1;
p = arg + std::strlen ( arg ) - 1;
while ( !sr1.empty ()) {
string_ref::size_type pos = sr1.find_last_of(*p);
BOOST_CHECK ( pos == sr1.size () - 1 );
BOOST_TEST ( pos == sr1.size () - 1 );
sr1.remove_suffix (1);
--p;
}
@ -192,8 +195,8 @@ void find ( const char *arg ) {
sr1 = arg;
sr2 = arg;
while ( !sr1.empty() ) {
BOOST_CHECK ( sr1.find_first_of ( sr2 ) == 0 );
BOOST_CHECK ( sr1.find_first_not_of ( sr2 ) == string_ref::npos );
BOOST_TEST ( sr1.find_first_of ( sr2 ) == 0 );
BOOST_TEST ( sr1.find_first_not_of ( sr2 ) == string_ref::npos );
sr1.remove_prefix ( 1 );
}
@ -202,14 +205,14 @@ void find ( const char *arg ) {
while ( *p ) {
string_ref::size_type pos1 = sr1.find_first_of(*p);
string_ref::size_type pos2 = sr1.find_first_not_of(*p);
BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
BOOST_TEST ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
if ( pos2 != string_ref::npos ) {
for ( size_t i = 0 ; i < pos2; ++i )
BOOST_CHECK ( sr1[i] == *p );
BOOST_CHECK ( sr1 [ pos2 ] != *p );
BOOST_TEST ( sr1[i] == *p );
BOOST_TEST ( sr1 [ pos2 ] != *p );
}
BOOST_CHECK ( pos2 != pos1 );
BOOST_TEST ( pos2 != pos1 );
++p;
}
@ -217,8 +220,8 @@ void find ( const char *arg ) {
sr1 = arg;
sr2 = arg;
while ( !sr1.empty() ) {
BOOST_CHECK ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
BOOST_CHECK ( sr1.find_last_not_of ( sr2 ) == string_ref::npos );
BOOST_TEST ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
BOOST_TEST ( sr1.find_last_not_of ( sr2 ) == string_ref::npos );
sr1.remove_suffix ( 1 );
}
@ -227,15 +230,15 @@ void find ( const char *arg ) {
while ( *p ) {
string_ref::size_type pos1 = sr1.find_last_of(*p);
string_ref::size_type pos2 = sr1.find_last_not_of(*p);
BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
BOOST_CHECK ( pos2 == string_ref::npos || pos1 < sr1.size ());
BOOST_TEST ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
BOOST_TEST ( pos2 == string_ref::npos || pos1 < sr1.size ());
if ( pos2 != string_ref::npos ) {
for ( size_t i = sr1.size () -1 ; i > pos2; --i )
BOOST_CHECK ( sr1[i] == *p );
BOOST_CHECK ( sr1 [ pos2 ] != *p );
BOOST_TEST ( sr1[i] == *p );
BOOST_TEST ( sr1 [ pos2 ] != *p );
}
BOOST_CHECK ( pos2 != pos1 );
BOOST_TEST ( pos2 != pos1 );
++p;
}
@ -249,13 +252,13 @@ void to_string ( const char *arg ) {
str1.assign ( arg );
sr1 = arg;
// str2 = sr1.to_string<std::allocator<char> > ();
// str2 = sr1.to_string<std::allocator<char> > ();
str2 = sr1.to_string ();
BOOST_CHECK ( str1 == str2 );
BOOST_TEST ( str1 == str2 );
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
std::string str3 = static_cast<std::string> ( sr1 );
BOOST_CHECK ( str1 == str3 );
BOOST_TEST ( str1 == str3 );
#endif
}
@ -266,28 +269,28 @@ void compare ( const char *arg ) {
str1.assign ( arg );
sr1 = arg;
BOOST_CHECK ( sr1 == sr1); // compare string_ref and string_ref
BOOST_CHECK ( sr1 == str1); // compare string and string_ref
BOOST_CHECK ( str1 == sr1 ); // compare string_ref and string
BOOST_CHECK ( sr1 == arg ); // compare string_ref and pointer
BOOST_CHECK ( arg == sr1 ); // compare pointer and string_ref
BOOST_TEST ( sr1 == sr1); // compare string_ref and string_ref
BOOST_TEST ( sr1 == str1); // compare string and string_ref
BOOST_TEST ( str1 == sr1 ); // compare string_ref and string
BOOST_TEST ( sr1 == arg ); // compare string_ref and pointer
BOOST_TEST ( arg == sr1 ); // compare pointer and string_ref
if ( sr1.size () > 0 ) {
(*str1.rbegin())++;
BOOST_CHECK ( sr1 != str1 );
BOOST_CHECK ( str1 != sr1 );
BOOST_CHECK ( sr1 < str1 );
BOOST_CHECK ( sr1 <= str1 );
BOOST_CHECK ( str1 > sr1 );
BOOST_CHECK ( str1 >= sr1 );
BOOST_TEST ( sr1 != str1 );
BOOST_TEST ( str1 != sr1 );
BOOST_TEST ( sr1 < str1 );
BOOST_TEST ( sr1 <= str1 );
BOOST_TEST ( str1 > sr1 );
BOOST_TEST ( str1 >= sr1 );
(*str1.rbegin()) -= 2;
BOOST_CHECK ( sr1 != str1 );
BOOST_CHECK ( str1 != sr1 );
BOOST_CHECK ( sr1 > str1 );
BOOST_CHECK ( sr1 >= str1 );
BOOST_CHECK ( str1 < sr1 );
BOOST_CHECK ( str1 <= sr1 );
BOOST_TEST ( sr1 != str1 );
BOOST_TEST ( str1 != sr1 );
BOOST_TEST ( sr1 > str1 );
BOOST_TEST ( sr1 >= str1 );
BOOST_TEST ( str1 < sr1 );
BOOST_TEST ( str1 <= sr1 );
}
}
@ -301,7 +304,7 @@ const char *test_strings [] = {
NULL
};
BOOST_AUTO_TEST_CASE( test_main )
int main()
{
const char **p = &test_strings[0];
@ -315,4 +318,6 @@ BOOST_AUTO_TEST_CASE( test_main )
p++;
}
return boost::report_errors();
}

View File

@ -12,8 +12,6 @@
* \brief This header contains tests for stream operations of \c basic_string_ref.
*/
#define BOOST_TEST_MODULE string_ref_test_io
#include <boost/utility/string_ref.hpp>
#include <iomanip>
@ -23,23 +21,10 @@
#include <string>
#include <boost/config.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/core/lightweight_test.hpp>
typedef boost::mpl::vector<
char
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
, wchar_t
#endif
/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available.
#if !defined(BOOST_NO_CXX11_CHAR16_T)
, char16_t
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
, char32_t
#endif
*/
>::type char_types;
static const char* test_strings[] =
{
@ -72,10 +57,10 @@ struct context
};
// Test regular output
BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types)
template<class CharT>
void test_string_ref_output()
{
typedef CharT char_type;
typedef std::basic_string< char_type > string_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_ref< char_type > string_ref_type;
@ -83,14 +68,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types)
ostream_type strm;
strm << string_ref_type(ctx.abcd);
BOOST_CHECK(strm.str() == ctx.abcd);
BOOST_TEST(strm.str() == ctx.abcd);
}
// Test support for padding
BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
template<class CharT>
void test_padding()
{
typedef CharT char_type;
typedef std::basic_string< char_type > string_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_ref< char_type > string_ref_type;
@ -104,7 +89,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
ostream_type strm_correct;
strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
BOOST_TEST(strm_ref.str() == strm_correct.str());
}
// Test for long padding
@ -115,7 +100,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
ostream_type strm_correct;
strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
BOOST_TEST(strm_ref.str() == strm_correct.str());
}
// Test that short width does not truncate the string
@ -126,15 +111,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
ostream_type strm_correct;
strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
BOOST_TEST(strm_ref.str() == strm_correct.str());
}
}
// Test support for padding fill
BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
template<class CharT>
void test_padding_fill()
{
typedef CharT char_type;
typedef std::basic_string< char_type > string_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_ref< char_type > string_ref_type;
@ -146,14 +131,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
ostream_type strm_correct;
strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
BOOST_TEST(strm_ref.str() == strm_correct.str());
}
// Test support for alignment
BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
template<class CharT>
void test_alignment()
{
typedef CharT char_type;
typedef std::basic_string< char_type > string_type;
typedef std::basic_ostringstream< char_type > ostream_type;
typedef boost::basic_string_ref< char_type > string_ref_type;
@ -167,7 +152,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
ostream_type strm_correct;
strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
BOOST_TEST(strm_ref.str() == strm_correct.str());
}
// Right alignment
@ -178,6 +163,22 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
ostream_type strm_correct;
strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
BOOST_CHECK(strm_ref.str() == strm_correct.str());
BOOST_TEST(strm_ref.str() == strm_correct.str());
}
}
template<class CharT>
void test()
{
test_string_ref_output<CharT>();
test_padding<CharT>();
test_padding_fill<CharT>();
test_alignment<CharT>();
}
int main()
{
test<char>();
test<wchar_t>();
return boost::report_errors();
}

View File

@ -0,0 +1,115 @@
/*
Copyright (c) Marshall Clow 2017-2017.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#include <new> // for placement new
#include <iostream>
#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
#include <cstring> // for std::strchr and std::strcmp
#include <cstdlib> // for std::malloc and std::free
#include <cstdio> // for EOF
#include <boost/config.hpp>
#include <boost/utility/string_view.hpp>
#if __cplusplus >= 201402L
struct constexpr_char_traits
{
typedef char char_type;
typedef int int_type;
typedef std::streamoff off_type;
typedef std::streampos pos_type;
typedef std::mbstate_t state_type;
static void assign(char_type& c1, const char_type& c2) noexcept { c1 = c2; }
static constexpr bool eq(char_type c1, char_type c2) noexcept { return c1 == c2; }
static constexpr bool lt(char_type c1, char_type c2) noexcept { return c1 < c2; }
static constexpr int compare(const char_type* s1, const char_type* s2, size_t n) noexcept;
static constexpr size_t length(const char_type* s) noexcept;
static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a) noexcept;
static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n) noexcept;
static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n) noexcept;
static constexpr char_type* assign(char_type* s, size_t n, char_type a) noexcept;
static constexpr int_type not_eof(int_type c) noexcept { return eq_int_type(c, eof()) ? ~eof() : c; }
static constexpr char_type to_char_type(int_type c) noexcept { return char_type(c); }
static constexpr int_type to_int_type(char_type c) noexcept { return int_type(c); }
static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept { return c1 == c2; }
static constexpr int_type eof() noexcept { return EOF; }
};
// yields:
// 0 if for each i in [0,n), X::eq(s1[i],s2[i]) is true;
// else, a negative value if, for some j in [0,n), X::lt(s1[j],s2[j]) is true and
// for each i in [0,j) X::eq(s2[i],s2[i]) is true;
// else a positive value.
constexpr int constexpr_char_traits::compare(const char_type* s1, const char_type* s2, size_t n) noexcept
{
for (; n != 0; --n, ++s1, ++s2)
{
if (lt(*s1, *s2))
return -1;
if (lt(*s2, *s1))
return 1;
}
return 0;
}
// yields: the smallest i such that X::eq(s[i],charT()) is true.
constexpr size_t constexpr_char_traits::length(const char_type* s) noexcept
{
size_t len = 0;
for (; !eq(*s, char_type(0)); ++s)
++len;
return len;
}
typedef boost::basic_string_view<char, constexpr_char_traits> string_view;
int main()
{
constexpr string_view sv1;
constexpr string_view sv2{"abc", 3}; // ptr, len
constexpr string_view sv3{"def"}; // ptr
constexpr const char *s1 = "";
constexpr const char *s2 = "abc";
static_assert( (sv1 == sv1), "" );
static_assert(!(sv1 == sv2), "" );
static_assert( (sv1 != sv2), "" );
static_assert( (sv1 < sv2), "" );
static_assert( (sv1 <= sv2), "" );
static_assert(!(sv1 > sv2), "" );
static_assert(!(sv1 >= sv2), "" );
static_assert(!(s1 == sv2), "" );
static_assert( (s1 != sv2), "" );
static_assert( (s1 < sv2), "" );
static_assert( (s1 <= sv2), "" );
static_assert(!(s1 > sv2), "" );
static_assert(!(s1 >= sv2), "" );
static_assert(!(sv1 == s2), "" );
static_assert( (sv1 != s2), "" );
static_assert( (sv1 < s2), "" );
static_assert( (sv1 <= s2), "" );
static_assert(!(sv1 > s2), "" );
static_assert(!(sv1 >= s2), "" );
static_assert( sv1.compare(sv2) < 0, "" );
static_assert( sv1.compare(sv1) == 0, "" );
static_assert( sv3.compare(sv1) > 0, "" );
static_assert( sv1.compare(s2) < 0, "" );
static_assert( sv1.compare(s1) == 0, "" );
static_assert( sv3.compare(s1) > 0, "" );
}
#endif

View File

@ -0,0 +1,26 @@
/*
Copyright (c) Marshall Clow 2017.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
For more information, see http://www.boost.org
*/
#include <iostream>
#include <algorithm>
#include <string>
#include <boost/utility/string_view.hpp>
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
#error "Unsupported test"
#endif
std::string makeatemp() { return "abc"; }
int main()
{
boost::basic_string_view<char> sv(makeatemp());
return 0;
}

120
test/string_view_test1.cpp Normal file
View File

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

410
test/string_view_test2.cpp Normal file
View File

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

View File

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

View File

@ -16,13 +16,13 @@
#include <string>
#include "boost/utility/value_init.hpp"
#include <boost/shared_ptr.hpp>
#ifdef __BORLANDC__
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/workaround.hpp>
//
// Sample POD type
@ -218,8 +218,8 @@ void check_initialized_value ( T const& y )
BOOST_TEST ( y == initializedValue ) ;
}
#ifdef __BORLANDC__
#if __BORLANDC__ == 0x582
#ifdef BOOST_BORLANDC
#if BOOST_BORLANDC == 0x582
void check_initialized_value( NonPOD const& )
{
// The initialized_value check is skipped for Borland 5.82
@ -270,9 +270,12 @@ bool test ( T const& y, T const& z )
boost::value_initialized<T> copy2;
copy2 = x;
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
BOOST_TEST ( y == *ptr ) ;
{
boost::value_initialized<T> * ptr = new boost::value_initialized<T>;
BOOST_TEST ( y == *ptr ) ;
delete ptr;
}
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
boost::value_initialized<T const> cx ;
@ -287,7 +290,7 @@ bool test ( T const& y, T const& z )
return boost::detail::test_errors() == errors_before_test ;
}
int main(int, char **)
int main()
{
BOOST_TEST ( test( 0,1234 ) ) ;
BOOST_TEST ( test( 0.0,12.34 ) ) ;

169
test/value_init_test2.cpp Normal file
View File

@ -0,0 +1,169 @@
// Copyright 2010, Niels Dekker.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Test program for the boost::value_initialized<T> workaround.
//
// 17 June 2010 (Created) Niels Dekker
#include <boost/utility/value_init.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config/workaround.hpp>
#include <iostream>
namespace
{
struct empty_struct
{
};
// A POD aggregate struct derived from an empty struct.
// Similar to struct Foo1 from Microsoft Visual C++ bug report 484295,
// "VC++ does not value-initialize members of derived classes without
// user-declared constructor", reported in 2009 by Sylvester Hesp:
// https://connect.microsoft.com/VisualStudio/feedback/details/484295
struct derived_struct: empty_struct
{
int data;
};
bool is_value_initialized(const derived_struct& arg)
{
return arg.data == 0;
}
class virtual_destructor_holder
{
public:
int i;
virtual ~virtual_destructor_holder()
{
}
};
bool is_value_initialized(const virtual_destructor_holder& arg)
{
return arg.i == 0;
}
// Equivalent to the Stats class from GCC Bug 33916,
// "Default constructor fails to initialize array members", reported in 2007 by
// Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
// and fixed for GCC 4.2.4.
class private_int_array_pair
{
friend bool is_value_initialized(const private_int_array_pair& arg);
private:
int first[12];
int second[12];
};
bool is_value_initialized(const private_int_array_pair& arg)
{
for ( unsigned i = 0; i < 12; ++i)
{
if ( (arg.first[i] != 0) || (arg.second[i] != 0) )
{
return false;
}
}
return true;
}
struct int_pair_struct
{
int first;
int second;
};
typedef int int_pair_struct::*ptr_to_member_type;
struct ptr_to_member_struct
{
ptr_to_member_type data;
};
bool is_value_initialized(const ptr_to_member_struct& arg)
{
return arg.data == 0;
}
template <typename T>
bool is_value_initialized(const T(& arg)[2])
{
return
is_value_initialized(arg[0]) &&
is_value_initialized(arg[1]);
}
template <typename T>
bool is_value_initialized(const boost::value_initialized<T>& arg)
{
return is_value_initialized(arg.data());
}
// Returns zero when the specified object is value-initializated, and one otherwise.
// Prints a message to standard output if the value-initialization has failed.
template <class T>
unsigned failed_to_value_initialized(const T& object, const char *const object_name)
{
if ( is_value_initialized(object) )
{
return 0u;
}
else
{
std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl;
return 1u;
}
}
// A macro that passed both the name and the value of the specified object to
// the function above here.
#define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value)
// Equivalent to the dirty_stack() function from GCC Bug 33916,
// "Default constructor fails to initialize array members", reported in 2007 by
// Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
void dirty_stack()
{
unsigned char array_on_stack[4096];
for (unsigned i = 0; i < sizeof(array_on_stack); ++i)
{
array_on_stack[i] = 0x11;
}
}
}
int main()
{
#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
std::cout << "BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED is defined.\n\n";
#endif
dirty_stack();
BOOST_TEST( is_value_initialized( boost::value_initialized<derived_struct>() ) );
BOOST_TEST( is_value_initialized( boost::value_initialized<virtual_destructor_holder[2]>() ) );
BOOST_TEST( is_value_initialized( boost::value_initialized<private_int_array_pair>() ) );
#if !BOOST_WORKAROUND( BOOST_MSVC, BOOST_TESTED_AT(1925) )
// Null pointers to data members are represented as -1 in MSVC, but
// value initialization sets them to all zero. The workaround employed
// by value_initialized<> is to memset the storage to all zero, which
// doesn't help.
BOOST_TEST( is_value_initialized( boost::value_initialized<ptr_to_member_struct>() ) );
#endif
return boost::report_errors();
}

40
test/value_init_test3.cpp Normal file
View File

@ -0,0 +1,40 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/utility/value_init.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if __cplusplus >= 201103L || ( defined(BOOST_MSVC) && BOOST_MSVC >= 1900 )
struct X
{
int a;
char b;
};
struct Y: boost::value_initialized<X>
{
char c = 42;
};
int main()
{
Y y;
BOOST_TEST_EQ( y.data().a, 0 );
BOOST_TEST_EQ( y.data().b, 0 );
BOOST_TEST_EQ( y.c, 42 );
return boost::report_errors();
}
#else
BOOST_PRAGMA_MESSAGE( "Skipping test because compiler doesn't support in-class member initializers" )
int main() {}
#endif

View File

@ -13,13 +13,11 @@
#include "boost/utility/value_init.hpp"
#ifdef __BORLANDC__
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/test/minimal.hpp"
int test_main(int, char **)
int main()
{
boost::value_initialized<int> const x_c ;
@ -27,11 +25,3 @@ int test_main(int, char **)
return 0;
}
unsigned int expected_failures = 0;

View File

@ -13,13 +13,11 @@
#include "boost/utility/value_init.hpp"
#ifdef __BORLANDC__
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/test/minimal.hpp"
int test_main(int, char **)
int main()
{
boost::value_initialized<int const> cx ;
@ -27,10 +25,3 @@ int test_main(int, char **)
return 0;
}
unsigned int expected_failures = 0;

View File

@ -13,13 +13,11 @@
#include "boost/utility/value_init.hpp"
#ifdef __BORLANDC__
#ifdef BOOST_BORLANDC
#pragma hdrstop
#endif
#include "boost/test/minimal.hpp"
int test_main(int, char **)
int main()
{
boost::value_initialized<int const> const cx_c ;
@ -27,11 +25,3 @@ int test_main(int, char **)
return 0;
}
unsigned int expected_failures = 0;

View File

@ -75,6 +75,24 @@ namespace
return true;
}
struct int_pair_struct
{
int first;
int second;
};
typedef int int_pair_struct::*ptr_to_member_type;
struct ptr_to_member_struct
{
ptr_to_member_type data;
};
bool is_value_initialized(const ptr_to_member_struct& arg)
{
return arg.data == 0;
}
template <typename T>
bool is_value_initialized(const T(& arg)[2])
{
@ -132,7 +150,8 @@ int main()
const unsigned num_failures =
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<derived_struct>()) +
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>()) +
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>());
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>()) +
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<ptr_to_member_struct>());
#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
// One or more failures are expected.

View File

@ -17,7 +17,7 @@
Function templates <a href="../core/doc/html/core/checked_delete.html">checked_delete() and
checked_array_delete()</a> (moved to the Boost.Core library)</li>
<li>
Function templates <a href="#functions_next_prior">next() and prior()</a></li>
Function templates <a href="../iterator/doc/html/iterator/algorithms/next_prior.html">next() and prior()</a> (moved to the Boost.Iterator library)</li>
<li>
Class <a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)</li>
<li>
@ -28,45 +28,6 @@
<li><a href="index.html">Other utilities not part of <code>utility.hpp</code></a></li>
</ul>
<h2>
<a name="functions_next_prior">Function</a> templates next() and prior()</h2>
<p>Certain data types, such as the C++ Standard Library's forward and bidirectional
iterators, do not provide addition and subtraction via operator+() or
operator-().&nbsp; This means that non-modifying computation of the next or
prior value requires a temporary, even though operator++() or operator--() is
provided.&nbsp; It also means that writing code like <code>itr+1</code> inside
a template restricts the iterator category to random access iterators.</p>
<p>The next() and prior() functions provide a simple way around these problems:</p>
<blockquote>
<pre>template &lt;class T&gt;
T next(T x) { return ++x; }
template &lt;class T, class Distance&gt;
T next(T x, Distance n)
{
std::advance(x, n);
return x;
}
template &lt;class T&gt;
T prior(T x) { return --x; }
template &lt;class T, class Distance&gt;
T prior(T x, Distance n)
{
std::advance(x, -n);
return x;
}</pre>
</blockquote>
<p>Usage is simple:</p>
<blockquote>
<pre>const std::list&lt;T&gt;::iterator p = get_some_iterator();
const std::list&lt;T&gt;::iterator prev = boost::prior(p);
const std::list&lt;T&gt;::iterator next = boost::next(prev, 2);</pre>
</blockquote>
<p>The distance from the given iterator should be supplied as an absolute value. For
example, the iterator four iterators prior to the given iterator <code>p</code>
may be obtained by <code>prior(p, 4)</code>.</p>
<p>Contributed by <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>. Two-argument versions by Daniel Walker.</p>
<h2><a name="result_of">Class template
result_of</a></h2> <p>The class template