1
0
forked from boostorg/core

Compare commits

...

278 Commits

Author SHA1 Message Date
Peter Dimov
ac9d79992e Update ci.yml 2022-06-24 14:09:47 +03:00
Peter Dimov
b6c3190468 Add tn_holder specializations for __int128 (avoids macOS link errors for missing typeinfo for same) 2022-05-30 04:03:18 +03:00
Peter Dimov
f941d2e1f7 Add tests for __int128 to type_name_test.cpp 2022-05-30 03:00:37 +03:00
Glen Fernandes
c0e2211c2b Simplify test 2022-05-14 13:05:56 -04:00
Glen Fernandes
eec8689d58 Merge pull request #116 from boostorg/feature/span_boost_begin_test
Add test around the MSVC defect
2022-05-14 01:59:39 -04:00
Glen Fernandes
45e5b1ebcf Add test around the MSVC defect 2022-05-14 00:51:05 -04:00
Peter Dimov
8645bcb06e Merge pull request #101 from boostorg/feature/bit_use_if_constexpr
bit.hpp: Use C++17 if constexpr where possible
2022-05-14 04:35:13 +03:00
Glen Fernandes
ebff02a932 Merge pull request #115 from glenfe/develop
Remove inline friend begin and end functions
2022-05-13 20:45:27 -04:00
Glen Fernandes
42ed795866 Remove inline friend begin and end functions 2022-05-13 18:26:08 -04:00
Peter Dimov
0212774324 Avoid -Wshadow warning under g++ 4.8 2022-04-29 02:43:37 +03:00
Peter Dimov
43d0da03f3 Remove msvc-14.1 from ci.yml 2022-04-28 21:28:11 +03:00
Peter Dimov
0011697492 Add hash_value (refs #110) 2022-04-28 20:42:48 +03:00
Glen Fernandes
d74140983d Correct definition of C++11 alias rebind 2022-04-26 14:11:31 -04:00
Glen Fernandes
1e5c86eb9d Add tests for the C++11 alias rebind 2022-04-26 14:10:21 -04:00
Andrey Semashev
00cc660f28 Merge pull request #108 from Aiee/fix-typo
[Minor] Fix typo
2022-04-19 11:17:52 +03:00
Yichen Wang
44610b65ba Fix typo 2022-04-19 15:26:36 +08:00
Glen Fernandes
5e0ff1680f Use a different workaround for supporting noinit_adaptor in C++03 2022-03-15 14:47:39 -04:00
Glen Fernandes
4defdfd233 Add allocator_construct_n to allocator_access and deprecate alloc_construct 2022-03-12 10:45:05 -05:00
Glen Fernandes
c4deb479fd Add detection support for single argument construct and destroy 2022-03-12 01:31:31 -05:00
Glen Fernandes
f326683d42 Add allocator_construct and allocator_destroy tests to Jamfile 2022-03-12 00:51:52 -05:00
Peter Dimov
dbefea9631 Update revision history 2022-02-15 20:54:37 +02:00
Peter Dimov
a32c1ee7ac Disable test under CMake, CTest doesn't like crashing tests 2022-02-15 06:49:46 +02:00
Peter Dimov
230dd83002 Add newlines, fflush 2022-02-15 06:49:46 +02:00
Peter Dimov
ec91f29d56 Disable msvc warnings 2022-02-15 06:49:46 +02:00
Peter Dimov
188ca25bf3 Mark verbose_terminate_handler as inline 2022-02-15 06:49:46 +02:00
Peter Dimov
ed84fc4e23 Document verbose_terminate_handler 2022-02-15 06:49:46 +02:00
Peter Dimov
622b7a398a Add core/verbose_terminate_handler.hpp 2022-02-15 06:49:46 +02:00
Peter Dimov
35a4e09854 Add clang-win to GHA 2022-02-15 05:46:09 +02:00
Peter Dimov
b7c987f83c Mark quick_exit as inline 2022-02-15 02:08:30 +02:00
Peter Dimov
89d8efb7ff Avoid -Wlong-long in bit_ceil_test.cpp 2022-02-08 22:58:45 +02:00
Peter Dimov
f12eeb6b9f Avoid -Wlong-long in bit_rotate_test.cpp 2022-02-08 22:55:08 +02:00
Peter Dimov
ad63dcda9f Fix -Wlong-long warnings in splitmix64.hpp 2022-02-08 22:49:44 +02:00
Peter Dimov
6a5f726602 Add splitmix64_test.cpp 2022-02-08 22:48:01 +02:00
Peter Dimov
cf619432a7 Fix GCC -Wlong-long warnings 2022-02-08 22:00:42 +02:00
Peter Dimov
b38c148969 Enable -pedantic for the cmath.hpp and bit.hpp tests 2022-02-08 21:37:34 +02:00
Peter Dimov
bae7c049b0 Avoid conversion warning in bit_width 2022-01-19 17:20:39 +02:00
Glen Fernandes
ea7b623b7d Use consistent section titles in documentation 2022-01-07 11:16:44 -05:00
Andrey Semashev
6ae6ff79f1 Deprecated boost/iterator.hpp, emit warnings on inclusion.
The header defines boost::iterator template, which is an alias for
std::iterator, which is itself deprecated since C++17.

Updated test to avoid testing the definition in C++17 onwards
to avoid failures due to deprecation warnings from libc++-13.
2021-12-23 16:46:29 +03:00
Andrey Semashev
06976ccad7 Use path-constant to specify path to headers in docs Jamfile. 2021-12-23 15:10:58 +03:00
Andrey Semashev
65723e0e1f Added clang-13 CI jobs. 2021-12-23 14:50:35 +03:00
Peter Dimov
df3b9827cf Enclose std::min in parentheses to guard against <windows.h> 2021-12-20 01:35:55 +02:00
Peter Dimov
392cc988dd Add sv_windows_h_test 2021-12-20 01:30:32 +02:00
Peter Dimov
0ef1c06fd8 Add cxxstd=20 to msvc-14.2, msvc-14.3 2021-12-18 21:59:21 +02:00
Peter Dimov
0b9624d047 Add sv_common_reference_test2 2021-12-18 18:53:42 +02:00
Peter Dimov
574c7cf86e Update string_view.hpp to use BOOST_NO_CXX20_HDR_CONCEPTS 2021-12-18 18:39:03 +02:00
Peter Dimov
6e6af5fc90 Update sv_common_reference_test to check BOOST_NO_CXX20_HDR_CONCEPTS 2021-12-18 18:18:19 +02:00
Peter Dimov
95f2a76c90 Specialize std::basic_common_reference to enable std::common_reference and std::common_reference_with 2021-12-18 07:43:33 +02:00
Peter Dimov
28d26d13f1 Add sv_common_reference_test 2021-12-18 07:34:16 +02:00
Peter Dimov
ac71c55b4e Remove msvc-14.2 from appveyor.yml (in GHA); use clang-win from VS2019 2021-12-18 05:07:12 +02:00
Peter Dimov
c83e682b7e Update ci.yml 2021-12-18 05:05:36 +02:00
Peter Dimov
7a79d17da2 Add conversions from and to boost::string_view 2021-12-18 04:15:06 +02:00
Glen Fernandes
02b3f91fc3 Use same style of detection in pointer_traits and allocator_traits 2021-12-15 15:30:57 -05:00
Glen Fernandes
a2b37091eb Update documentation 2021-12-15 11:36:02 -05:00
Glen Fernandes
78dd0cce2f Make pointer_to SFINAE friendlier 2021-12-15 09:31:34 -05:00
Glen Fernandes
a121ab0278 Update release notes for 1.79 2021-12-14 07:52:42 -05:00
Glen Fernandes
0e62373aa2 Make pointer_traits SFINAE friendly 2021-12-13 13:13:12 -05:00
Glen Fernandes
6da7958281 Update unit tests 2021-12-08 10:26:49 -05:00
Glen Fernandes
c8479b4eca Simplify C++03 detection traits slightly 2021-12-07 21:17:28 -05:00
Glen Fernandes
f5ab83efe8 Merge pull request #104 from boostorg/feature/allocator_access
Support additional is_empty intrinsics
2021-12-07 11:02:04 -05:00
Glen Fernandes
eb7bc1ff53 Support additional is_empty intrinsics 2021-12-07 10:10:07 -05:00
Glen Fernandes
d038633f98 Correct spelling of detail macro 2021-12-07 02:57:14 -05:00
Glen Fernandes
ac4bdcc4c5 Update documentation 2021-12-06 23:43:03 -05:00
Glen Fernandes
85a3183c01 Update bool constant 2021-12-06 23:36:48 -05:00
Glen Fernandes
0c9675cf56 Add partial C++03 support for C++11 allocator model 2021-12-06 19:56:57 -05:00
Glen Fernandes
5abadf4472 Change A::value_type to allocator_value_type 2021-12-06 16:41:16 -05:00
Glen Fernandes
6b3fb219cc Minor refactoring in allocator access 2021-12-06 15:58:48 -05:00
Glen Fernandes
febc195093 Add default_allocator allocate hint overload in C++03 mode 2021-12-04 14:41:23 -05:00
Glen Fernandes
8985ce604e Simplify test 2021-12-04 14:39:36 -05:00
Glen Fernandes
15c884438c Correct note in documentation 2021-12-04 14:38:18 -05:00
Glen Fernandes
15f7fb7eaa Move Notes to a top level section 2021-12-04 00:32:27 -05:00
Glen Fernandes
46f37b2f16 Make max_size noexcept 2021-12-04 00:24:45 -05:00
Glen Fernandes
c1be2097d7 Minor documentation changes 2021-12-04 00:22:51 -05:00
Glen Fernandes
c8b989d80b Add allocator_traits that uses allocator_access 2021-12-03 23:55:40 -05:00
Glen Fernandes
74c770206a Allow all individual traits to be specialized 2021-12-02 23:09:09 -05:00
Andrey Semashev
a1ad1784bf Updated check for apt-add-repository capabilities.
In Ubuntu 20.04 there appeared an updated version of the
software-properties-common package in focal-updates, which ships a newer
apt-add-repository version that doesn't support -P/-S/-U command line arguments.

Since we cannot rely on package version checks to determine apt-add-repository
capabilities, we have to parse its --help output instead.

Also, made source list processing more protected against spaces.
2021-11-16 00:36:15 +03:00
Andrey Semashev
213e4695bf Use C++17 if constexpr where possible. 2021-11-01 22:35:28 +03:00
Glen Fernandes
a4172b4319 MSVC warning workaround for empty_value 2021-11-01 06:33:44 -04:00
Peter Dimov
e4fb94b73c Merge branch 'develop' into feature/warnings-as-errors 2021-11-01 05:12:33 +02:00
Peter Dimov
ef3505db59 Disable -Wtype-limits for g++ 4.4 in Jamfile 2021-11-01 04:44:07 +02:00
Peter Dimov
f94db671f6 Disable C4702 in lightweight_test_fail6, no_exceptions_support_test 2021-11-01 04:17:51 +02:00
Peter Dimov
7b45315af1 Avoid C4996 in sv_copy_test.cpp 2021-11-01 04:15:33 +02:00
Peter Dimov
bdd4bf7d9a #pragma GCC diagnostic push requires g++ 4.6 2021-11-01 04:04:52 +02:00
Peter Dimov
9f2cdfa7d2 Disable C4244 in scoped_enum.cpp, underlying_type.cpp 2021-11-01 03:58:37 +02:00
Peter Dimov
964ef98eee Avoid streamsize -> size_t warning in string_view.hpp 2021-11-01 03:52:09 +02:00
Peter Dimov
f09ab90243 Disable -Wsign-compare for g++ 4.4 2021-11-01 03:14:53 +02:00
Glen Fernandes
d2e897fd60 MSVC warning workaround for dynamic_extent 2021-10-31 21:14:40 -04:00
Peter Dimov
66f6ea594a Disable -Wtype-limits in string_view.hpp 2021-11-01 03:10:42 +02:00
Peter Dimov
6a91536da6 Disable -Wunused-function in swap_array(_of_array)_of_class.cpp 2021-11-01 03:05:47 +02:00
Peter Dimov
c3a398b9a0 Merge branch 'develop' into feature/warnings-as-errors 2021-11-01 02:56:47 +02:00
Peter Dimov
e73e8bfc83 Disable C4512 in uncaught_exceptions(_np).cpp 2021-11-01 02:55:52 +02:00
Glen Fernandes
633a47f85b MSVC warning workaround for destroy 2021-10-31 20:52:44 -04:00
Glen Fernandes
eae98e909e MSVC warning workaround for as_bytes 2021-10-31 20:52:23 -04:00
Peter Dimov
a581a42c4f Disable C4577 in no_exceptions_support_test.cpp 2021-11-01 02:50:16 +02:00
Peter Dimov
e44781e290 Avoid C4101 in explicit_operator_bool_noexcept.cpp 2021-11-01 02:44:24 +02:00
Peter Dimov
11958e9568 Avoid C4101 in scoped_enum.cpp 2021-11-01 02:42:03 +02:00
Peter Dimov
56566d9abc Disable C4100 in alloc_construct_cxx11_test.cpp 2021-11-01 02:38:19 +02:00
Peter Dimov
9efeed68cb Disable C4530 in no_exceptions_support_test.cpp 2021-11-01 02:32:49 +02:00
Peter Dimov
da3c89dc5b Apply a better fix to iterator_test.cpp 2021-11-01 02:26:06 +02:00
Peter Dimov
ba208ad7fc Avoid signed/unsigned mismatch warning in span.hpp 2021-11-01 02:20:26 +02:00
Peter Dimov
bbfa6344fa Avoid ptrdiff_t -> int warning in eif_constructors.cpp 2021-11-01 02:18:51 +02:00
Peter Dimov
bf4354a3a4 Disable C4127 in bit_endian_test.cpp 2021-11-01 02:16:31 +02:00
Peter Dimov
a4b661068d Disable C4127, C4244 in bit.hpp 2021-11-01 02:14:43 +02:00
Peter Dimov
8299d25eb2 Avoid size_t to int conversion warning in visit_each_test.cpp 2021-11-01 02:06:42 +02:00
Peter Dimov
847f9d43fe Disable C4702 in quick_exit_test.cpp, quick_exit_fail.cpp 2021-11-01 02:04:45 +02:00
Peter Dimov
44e294fff1 Avoid unused parameter warning in to_address_test.cpp 2021-11-01 01:58:05 +02:00
Peter Dimov
b5f59858b9 Avoid unused parameter warning in visit_each_test.cpp 2021-11-01 01:56:27 +02:00
Peter Dimov
bed07e7d5b Disable -Wdeprecated-declarations in iterator_test.cpp 2021-11-01 01:47:28 +02:00
Peter Dimov
971cda2e4c Avoid -Wmissing-braces in swap_array_of_template.cpp 2021-11-01 01:45:15 +02:00
Peter Dimov
d81c61abb4 Disable -Wstring-plus-int in lightweight_test_fail10.cpp 2021-11-01 01:43:50 +02:00
Peter Dimov
370a74c249 Avoid self-assignment warning in ref_ct_test.cpp 2021-11-01 01:41:54 +02:00
Peter Dimov
62d1b1bb59 Avoid sturct/class mismatch warning in use_default_test.cpp 2021-11-01 01:39:13 +02:00
Peter Dimov
bb99544852 Use warnings-as-errors=off for compile-fail tests 2021-11-01 01:35:57 +02:00
Peter Dimov
9b5bf05fae Disable -Wdeprecated-declarations in get_pointer_test.cpp 2021-11-01 01:29:15 +02:00
Peter Dimov
309a6bb797 Fix unused parameter 't' warnings in eif_*.cpp 2021-11-01 01:27:01 +02:00
Peter Dimov
9d1b59ec6c Enable warnings=extra, warnings-as-errors=on 2021-11-01 01:24:02 +02:00
Glen Fernandes
12f5f51427 Switch tests to not rely on requires checks 2021-10-27 01:41:40 -04:00
Peter Dimov
0565456622 Use boost::(u)long_long_type to avoid g++ warning 2021-10-27 04:45:40 +03:00
Peter Dimov
fda0f87576 Add void, move nullptr_t to fundamental type section 2021-10-27 03:46:06 +03:00
Peter Dimov
e9718374ac Hardcode all integral and floating point types 2021-10-27 03:41:40 +03:00
Peter Dimov
79b7c49fb3 Refactor typeid_name<T> slighlty 2021-10-27 03:20:22 +03:00
Peter Dimov
585ac9ace1 Move string_view.hpp to boost/core/detail 2021-10-27 03:08:10 +03:00
Peter Dimov
493832a570 Remove string_view from documentation 2021-10-27 02:57:55 +03:00
Peter Dimov
8942e8ecc9 Update cmake_subdir_test/CMakeLists.txt 2021-10-26 01:00:15 +03:00
Peter Dimov
cbf03c4b9c Add msvc-14.3 to GHA 2021-10-26 00:54:37 +03:00
Glen Fernandes
5cf3569218 Correct documentation 2021-10-20 22:26:25 -04:00
Peter Dimov
d5bd40e528 Update test/Jamfile and test/CMakeLists.txt so that missing dependencies are caught 2021-10-16 18:10:13 +03:00
Peter Dimov
0e57df5aab Regenerate CMakeLists.txt 2021-10-16 17:55:35 +03:00
Glen Fernandes
62b23df9ef Update revision history 2021-10-15 19:00:57 -04:00
Glen Fernandes
fdf1ed78a7 Contribute span implementation 2021-10-14 21:16:19 -04:00
Peter Dimov
e02c333706 Update string_view.qbk 2021-10-11 02:09:45 +03:00
Peter Dimov
b677d1eeae Only update the necessary submodules in ci.yml 2021-10-10 19:35:26 +03:00
Peter Dimov
0f7d02de01 Update revision history 2021-10-10 19:29:46 +03:00
Peter Dimov
773499db5e Remove concurrency section from ci.yml 2021-10-10 18:23:21 +03:00
Peter Dimov
ce912859aa Change cancel-in-progress to false in ci.yml 2021-10-10 18:22:08 +03:00
Peter Dimov
bfeee019dd Update revision history 2021-10-10 18:20:46 +03:00
Peter Dimov
220d4ae0a9 Improve starts_with/ends_with 2021-10-10 17:47:57 +03:00
Peter Dimov
5d7b469e29 Improve .find 2021-10-10 03:09:53 +03:00
Peter Dimov
3cec508460 Update string_view.qbk 2021-10-10 02:25:50 +03:00
Peter Dimov
a47fac1449 Update string_view.qbk 2021-10-10 02:04:43 +03:00
Peter Dimov
7340f123fe Update string_view.qbk 2021-10-10 01:46:32 +03:00
Peter Dimov
038064e824 Update string_view.qbk 2021-10-10 00:44:00 +03:00
Peter Dimov
52c58efc36 Improve operator== 2021-10-09 21:04:38 +03:00
Peter Dimov
15fdc0ab39 Test std::pmr::string in sv_lt_test 2021-10-09 20:14:06 +03:00
Peter Dimov
b520289660 Test std::pmr::string in sv_eq_test 2021-10-09 20:12:32 +03:00
Peter Dimov
9b22937647 g++ 11 has <memory_resource> but not std::pmr::string 2021-10-09 20:06:20 +03:00
Peter Dimov
903d44c0c5 Test std::pmr::string in sv_conversion_test 2021-10-09 19:52:10 +03:00
Peter Dimov
88eee0c628 Test std::pmr::string in sv_construct_test 2021-10-09 19:50:34 +03:00
Peter Dimov
54965f567d Add an allocator argument to operator string() 2021-10-09 19:50:15 +03:00
Peter Dimov
c43a172ded Use os << "" for the padding instead of os << p[0] 2021-10-09 19:31:41 +03:00
Peter Dimov
ddf9b5087b Add sv_conversion_test 2021-10-09 18:36:05 +03:00
Peter Dimov
d17313d407 Add missing #include <ios> 2021-10-09 18:00:58 +03:00
Peter Dimov
c8b860704e Add sv_stream_insert_test 2021-10-09 17:36:06 +03:00
Peter Dimov
e9ffc4336c Remove unused npos variables 2021-10-09 17:10:52 +03:00
Peter Dimov
a121d5a000 Add sv_lt_test 2021-10-09 17:09:23 +03:00
Peter Dimov
5c82e38c93 Add other relational operators; update sv_eq_test 2021-10-09 16:55:33 +03:00
Peter Dimov
db15c7419d Add sv_eq_test 2021-10-09 16:50:14 +03:00
Peter Dimov
62e9d9b868 Update tests 2021-10-09 07:13:56 +03:00
Peter Dimov
b01f2fe4d2 Add optimized implementation of find_last_not_of 2021-10-09 07:08:48 +03:00
Peter Dimov
408cd96595 Update sv_find_last_not_of_test 2021-10-09 07:00:32 +03:00
Peter Dimov
9f2ec3bfca Update find_first_not_of_test 2021-10-09 06:58:11 +03:00
Peter Dimov
63f3a97a15 Update find_last_of_test 2021-10-09 06:54:23 +03:00
Peter Dimov
b70bbf14db Update sv_find_first_of_test 2021-10-09 06:52:08 +03:00
Peter Dimov
b251310a8f Update implementation of find_last_of 2021-10-09 06:47:39 +03:00
Peter Dimov
969a201c75 Update implementation of find_first_of 2021-10-09 06:43:48 +03:00
Peter Dimov
b9f1b9f39a Add optimized implementation of find_first_not_of 2021-10-09 06:40:59 +03:00
Peter Dimov
3d4eb536cd Add optimized implementation of find_last_of 2021-10-09 05:13:23 +03:00
Peter Dimov
a51364c5d3 sv_find_last_not_of_test 2021-10-09 03:33:10 +03:00
Peter Dimov
ab3950fdfb Add sv_find_first_not_of_test 2021-10-09 03:09:32 +03:00
Peter Dimov
fe9c0164c0 Add sv_find_last_of_test 2021-10-09 02:32:00 +03:00
Peter Dimov
8ec0e7f68a Merge branch 'develop' into feature/string-view 2021-10-09 01:50:17 +03:00
Peter Dimov
85e24f0483 Disable std::tuple tests on msvc-10.0 2021-10-08 18:21:04 +03:00
Peter Dimov
be820fea2e Remove uint64_t mask path from find_first_of; no longer a win after fix 2021-10-08 10:28:06 +03:00
Peter Dimov
af3e6a667b Update sv_find_first_of_test 2021-10-08 10:21:07 +03:00
Peter Dimov
c3cfe7a861 Merge branch 'develop' into feature/string-view 2021-10-08 10:15:05 +03:00
Peter Dimov
d87766a768 Remove no longer necessary workarounds 2021-10-08 10:14:21 +03:00
Peter Dimov
706747ab08 Work around g++'s instantiating X on typeid(X*) 2021-10-08 09:44:23 +03:00
Peter Dimov
41c3b6a7dd Reimplement type_name with class templates to avoid instantiating types such as pair<void, void> and tuple<void> 2021-10-08 09:23:26 +03:00
Peter Dimov
8223ff03e4 Add char8_t tests to sv_find_first_of_test 2021-10-08 07:14:54 +03:00
Peter Dimov
18334b1614 Add optimized implementation of find_first_of 2021-10-08 07:03:39 +03:00
Peter Dimov
df65ea6600 Update sv_find_first_of_test 2021-10-08 06:21:52 +03:00
Peter Dimov
d1ad50cefb Add sv_contains_test 2021-10-08 05:50:00 +03:00
Peter Dimov
09870f0739 Add sv_find_first_of_test 2021-10-08 05:39:24 +03:00
Peter Dimov
95e64ef71f Fix msvc-14.0 failure 2021-10-06 17:45:10 +03:00
Peter Dimov
673e3c302c Add sv_rfind_test 2021-10-06 05:49:09 +03:00
Peter Dimov
a8e7a3395e Add sv_iteration_test 2021-10-06 05:36:12 +03:00
Peter Dimov
09044f58d6 Add sv_find_test 2021-10-06 05:04:32 +03:00
Peter Dimov
f9fa1772f2 Add sv_ends_with_test 2021-10-06 04:39:16 +03:00
Peter Dimov
c7dfa29f29 Add sv_starts_with_test 2021-10-06 04:38:27 +03:00
Peter Dimov
93c18fb937 Use BOOST_TEST_TRAIT_SAME in sv_types_test 2021-10-06 03:36:40 +03:00
Peter Dimov
c005ad5e55 Merge branch 'develop' into feature/string-view 2021-10-06 03:32:05 +03:00
Peter Dimov
8cf4d16297 Merge branch 'feature/type-name' into feature/lwt-type-name 2021-10-05 19:47:11 +03:00
Peter Dimov
0deaa2d502 Update msvc-12.0 workaround 2021-10-05 19:22:20 +03:00
Peter Dimov
22de922125 Merge branch 'develop' into feature/type-name 2021-10-05 19:17:39 +03:00
Peter Dimov
3ec157eb6f Disable cmath_test_generic on msvc-8.0 2021-10-05 19:16:24 +03:00
Peter Dimov
531726eb09 Update msvc workarounds in type_name_test 2021-10-05 19:05:40 +03:00
Peter Dimov
31a9336778 Merge branch 'develop' into feature/lwt-type-name 2021-10-05 18:47:25 +03:00
Peter Dimov
75fc48ad32 Add a revision history section to documentation 2021-10-05 18:46:47 +03:00
Peter Dimov
87c21a23bb Update copyright 2021-10-05 17:32:50 +03:00
Peter Dimov
3e9cc2153b Disable no-rtti tests for g++ 4.4 because <memory> breaks 2021-10-05 17:11:31 +03:00
Peter Dimov
98630095f3 Merge branch 'develop' into feature/lwt-type-name 2021-10-05 16:24:49 +03:00
Peter Dimov
6985b1ae25 Remove extra semicolons 2021-10-05 15:53:16 +03:00
Peter Dimov
8ab119135c Add overload for char8_t because Mac has no typeinfo for char8_t 2021-10-05 15:46:22 +03:00
Peter Dimov
1fd2cadddd g++ 4.4 has no string::front 2021-10-05 15:38:33 +03:00
Peter Dimov
bb0c6381f6 Add msvc workarounds 2021-10-05 08:04:01 +03:00
Peter Dimov
4f6f7c3799 Add tests for all fundamental types 2021-10-05 07:50:52 +03:00
Peter Dimov
cd1a8fd238 Support pointers to members 2021-10-05 07:25:35 +03:00
Peter Dimov
b0b48c5783 Support qualified function types 2021-10-05 07:05:34 +03:00
Peter Dimov
ccdf5ce031 Track the type suffix independently for better decomposition of functions and arrays 2021-10-05 06:45:41 +03:00
Peter Dimov
b3906601f7 Merge branch 'feature/type-name' into feature/lwt-type-name 2021-10-05 05:43:01 +03:00
Peter Dimov
f833040d48 Disable msvc warnings around tn_is_function 2021-10-05 05:42:41 +03:00
Peter Dimov
3b5595e940 Merge branch 'feature/type-name' into feature/lwt-type-name 2021-10-05 05:31:09 +03:00
Peter Dimov
b93317815c Apply msvc-12.0 (and below) workarounds 2021-10-05 05:30:37 +03:00
Peter Dimov
01bd23df5d Add tests for function types 2021-10-05 05:04:56 +03:00
Peter Dimov
36cec9a5cc Handle references to functions 2021-10-05 05:01:05 +03:00
Peter Dimov
290340fd27 Use core::type_name in lightweight_test_trait 2021-10-05 04:58:52 +03:00
Peter Dimov
31e2caef12 Add sv_compare_test 2021-10-04 22:11:14 +03:00
Peter Dimov
042bb98142 Add sv_substr_test 2021-10-04 20:57:10 +03:00
Peter Dimov
c65c05c006 Add sv_copy_test 2021-10-04 20:45:10 +03:00
Peter Dimov
1aa8341bd7 Add sv_modifiers_test 2021-10-04 20:36:40 +03:00
Peter Dimov
e206cddc6f Fix line endings 2021-10-04 20:27:14 +03:00
Peter Dimov
c8b55f1bde Change BOOST_CONSTEXPR to BOOST_CXX14_CONSTEXPR appropriately 2021-10-04 19:12:05 +03:00
Peter Dimov
62ba7ca18b Define npos as BOOST_CONSTEXPR_OR_CONST 2021-10-04 19:08:12 +03:00
Peter Dimov
964dfe2b74 Fix line endings 2021-10-04 17:45:24 +03:00
Peter Dimov
016ae92ecf Add sv_element_access_test 2021-10-04 17:33:04 +03:00
Peter Dimov
7d05dfa87d Add sv_construct_test 2021-10-04 17:25:34 +03:00
Peter Dimov
95924b1329 Add boost/core/string_view.hpp 2021-10-04 16:49:46 +03:00
Peter Dimov
5e382efa84 Fix std::ostream failure on libstdc++ 2021-10-01 15:51:13 +03:00
Peter Dimov
e260bb865d Add support for string_view 2021-10-01 15:07:19 +03:00
Peter Dimov
f884833b42 Add workaround for msvc-10.0 2021-09-30 03:21:31 +03:00
Peter Dimov
8265fe6405 Minor documentation fix 2021-09-29 21:55:40 +03:00
Peter Dimov
f7b04afe4d Add documentation for type_name 2021-09-29 21:34:23 +03:00
Peter Dimov
2c1eb07a68 Add test for scoped enums 2021-09-29 21:12:54 +03:00
Peter Dimov
a5cbddc466 Add test for enums 2021-09-29 21:09:19 +03:00
Peter Dimov
91a64b3bcf Add support for std::array 2021-09-29 21:02:39 +03:00
Peter Dimov
a039f8c318 Support -fno-rtti 2021-09-29 20:53:38 +03:00
Peter Dimov
bebb7349ba Add workarounds for msvc-12.0 and earlier 2021-09-29 20:05:23 +03:00
Peter Dimov
dc6e3261ec Use typedef instead of using 2021-09-29 19:51:16 +03:00
Peter Dimov
15a7d84858 Use basic_string<char8_t> instead of u8string 2021-09-29 19:50:14 +03:00
Peter Dimov
06023d4ffe Strip libstdc++ and libc++ inline namespaces 2021-09-29 19:34:37 +03:00
Peter Dimov
3e0bc52c32 Add <boost/core/type_name.hpp> 2021-09-29 19:13:12 +03:00
Andrey Semashev
b83f27a9e0 Another fix in git version check. 2021-09-26 20:35:37 +03:00
Andrey Semashev
578e3105b8 Fixed git version check on Mac OS. 2021-09-26 20:31:43 +03:00
Andrey Semashev
f34c4986c1 Added a timeout for GHA CI. 2021-09-15 20:45:23 +03:00
Andrey Semashev
cfd469d858 Removed unused reference to extra_tests variable in GHA config. 2021-09-15 18:27:17 +03:00
Peter Dimov
b1e01b53f3 Merge branch 'develop' into feature/cmath 2021-09-14 19:15:41 +03:00
Peter Dimov
177c093151 Automatically use generic cmath if FP_SUBNORMAL isn't defined 2021-09-14 18:57:33 +03:00
Peter Dimov
cffaabead8 Update and fix CMake test jobs 2021-09-14 18:49:03 +03:00
Peter Dimov
2715f9b5d8 Add a workaround for g++ 4.4, 4.6 2021-09-14 18:35:31 +03:00
Peter Dimov
8043bafb6b Add a generic cmath.hpp implementation, enabled when BOOST_CORE_USE_GENERIC_CMATH is defined 2021-09-14 16:50:34 +03:00
Andrey Semashev
f6bdb17fd9 Updated GitHub Actions config for better configurability.
Reworked extra package installation and added explicit specification
of external package sources. Moved some common constants to environment
variables. Removed installation of unneeded packages in the containers.
2021-09-12 18:28:02 +03:00
Andrey Semashev
cd6847aee8 Update GitHub Actions config to switch Ubuntu 16.04 jobs to Docker containers.
The Ubuntu 16.04 environment is scheduled to be removed from GitHub Actions
in September 2021. Migrate those jobs to Docker containers or Ubuntu 18.04.

Also, added some older compilers. Ported CMake tests from Travis CI.

Based on https://github.com/boostorg/core/pull/95.
Closes https://github.com/boostorg/core/pull/95.
2021-09-06 02:00:12 +03:00
Andrey Semashev
9ff312e2fb Updated README.md to refer to GitHub Actions instead of Travis. 2021-09-06 01:24:19 +03:00
Andrey Semashev
494927312d Removed Travis CI config file.
Travis CI no longer provides (adequate) service to open source projects,
so we have switched to GitHub Actions as a replacement.
2021-09-06 01:24:19 +03:00
Peter Dimov
df91243a1d Whether wchar_t is signed is implementation-defined 2021-08-21 20:28:47 +03:00
Andrey Semashev
f4b3d5dba6 Merge pull request #93 from sdarwin/feature/gha_fix
Small GHA fix, create destination dir
2021-07-27 23:53:44 +03:00
sdarwin
9f0b97c80b Small GHA fix, create destination dir 2021-07-27 13:35:51 -05:00
Andrey Semashev
ce53cc1f8f Changed quotes in format() expression. 2021-07-02 20:38:22 +03:00
Andrey Semashev
8fad14b804 Use gcc-7 toolchain for clang-8 CI job. 2021-07-02 20:35:45 +03:00
Andrey Semashev
24b6d89e7f Changed CI concurrency group format.
This should fix CI and also make concurrncy work for PRs.
2021-07-02 20:34:19 +03:00
Andrey Semashev
ffd79a28e1 Added concurrency settings to auto-cancel redundant CI jobs. 2021-07-02 20:03:50 +03:00
Andrey Semashev
aa97e418f2 Increased git fetch jobs on Windows and use CPU count for build jobs. 2021-07-02 19:33:06 +03:00
Andrey Semashev
f563d50d42 Use more git fetch jobs to speed up clones. 2021-07-02 19:19:48 +03:00
Andrey Semashev
c55a20dff2 Reverted gcc package removal and instead setup a dummy gcc toolset tree.
Removing gcc and libstdc++ packages did not fix the clang-8 test failures.

Instead, setup a dummy gcc toolset tree and point clang to it to force
the compiler detect and use an older libstdc++.
2021-07-02 19:14:04 +03:00
Andrey Semashev
bc508f8b4c Remove gcc-10 for clang-8 testing.
This is another attempt to make clang-8 tests not fail in C++20 mode. Remove
gcc-10 and libstdc++-10 to prevent clang using it.

Also, use apt-get instead of apt since the former is recommended to use in
scripts. This should silence apt warnings.
2021-07-02 16:15:59 +03:00
Andrey Semashev
03c5481dd4 Moved clang-8 to Bionic and gcc-10,11 to Focal.
clang-8 jobs fail in C++20 mode since it doesn't support
std::is_constant_evaluated, which is called from libstdc++-10 that is installed
in Focal image. Moving it back to Bionic should work around the issue
as it should use an older libstdc++ version.

gcc-10 and 11 were moved to Focal just to make this configuration tested.

Also, changed 2a to 20 for compilers that support this.
2021-07-02 11:52:44 +03:00
Andrey Semashev
8e7ee90080 Merge pull request #92 from evanmiller/develop
Restore support for ancient Mac OS
2021-07-02 01:59:50 +03:00
Evan Miller
128d9314d6 Restore support for ancient Mac OS
Mac OS 10.4 and earlier lack Availability.h, causing compilation to
fail. Rearrange the macro logic to include Availability.h only if we
already think there may be support for uncaught exceptions.
2021-07-01 16:32:40 -04:00
Peter Dimov
012d96a72b Use non-const references in non-variadic branch as well 2021-06-10 10:09:46 +03:00
Peter Dimov
27d700ec01 Use non-const references in ignore_unused to avoid g++-11 warning 2021-06-10 09:54:51 +03:00
Peter Dimov
507c182f4c Revert "Initialize variables in ignore_unused_test to avoid a g++-11 warning"
This reverts commit 1a011cde56.
2021-06-10 09:40:08 +03:00
Peter Dimov
1a011cde56 Initialize variables in ignore_unused_test to avoid a g++-11 warning 2021-06-10 08:25:28 +03:00
Peter Dimov
71c3d320d5 Update ci.yml 2021-06-10 07:20:24 +03:00
Peter Dimov
b3fa7ca565 Take care of gcc-4.4 in addition to gcc-4.4.7 2021-06-10 04:58:17 +03:00
Peter Dimov
d3aa4a2f12 Update .travis.yml 2021-06-10 04:56:26 +03:00
Peter Dimov
67107dbaf9 Update ci.yml 2021-06-10 04:22:36 +03:00
Peter Dimov
0b74f0d394 Update CMakeLists.txt 2021-06-10 02:03:10 +03:00
Peter Dimov
e53393357f Update .github/workflows 2021-04-19 18:11:37 +03:00
Peter Dimov
7daee1d41b Add -DBUILD_TESTING=ON to .yml files; it's not default anymore 2021-03-19 03:53:31 +02:00
132 changed files with 12824 additions and 1221 deletions

View File

@@ -1,3 +1,9 @@
# Copyright 2020-2021 Peter Dimov
# Copyright 2021 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)
name: CI
on:
@@ -9,105 +15,525 @@ on:
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
GIT_FETCH_JOBS: 8
NET_RETRY_COUNT: 5
DEFAULT_BUILD_VARIANT: debug,release
jobs:
posix:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
# Linux, gcc
- toolset: gcc-4.4
cxxstd: "98,0x"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.4
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.6
cxxstd: "03,0x"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.6
sources:
- "ppa:ubuntu-toolchain-r/test"
- toolset: gcc-4.7
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.7
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.7
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.8
os: ubuntu-18.04
install:
- g++-4.8
- toolset: gcc-4.9
cxxstd: "03,11"
os: ubuntu-16.04
install: g++-4.9
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-4.9
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
os: ubuntu-20.04
container: ubuntu:16.04
install:
- g++-5
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
install: g++-6
os: ubuntu-18.04
install:
- g++-6
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install:
- g++-7
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install:
- g++-8
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install:
- g++-9
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- g++-10
- toolset: gcc-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- g++-11
- toolset: gcc-12
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install:
- g++-12
- name: UBSAN
toolset: gcc-12
cxxstd: "03,11,14,17,20"
ubsan: 1
os: ubuntu-22.04
install:
- g++-12
# Linux, clang
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.5
cxxstd: "03,11"
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.6
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.7
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.7
- toolset: clang
compiler: clang++-3.8
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.8
os: ubuntu-20.04
container: ubuntu:16.04
install:
- clang-3.8
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-3.9
os: ubuntu-18.04
install:
- clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-16.04
install: clang-4.0
os: ubuntu-18.04
install:
- clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-16.04
install: clang-5.0
os: ubuntu-18.04
install:
- clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install:
- clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: clang-7
install:
- clang-7
# Note: clang-8 does not fully support C++20, so it is not compatible with libstdc++-8 in this mode
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
os: ubuntu-18.04
install:
- clang-8
- g++-7
gcc_toolchain: 7
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-12
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
os: ubuntu-20.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
- toolset: clang
compiler: clang++-13
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install:
- clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install:
- clang-14
- toolset: clang
compiler: clang++-13
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install:
- clang-13
- libc++-13-dev
- libc++abi-13-dev
sources:
- "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- name: UBSAN
toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
ubsan: 1
os: ubuntu-20.04
install:
- clang-12
- libc++-12-dev
- libc++abi-12-dev
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
timeout-minutes: 120
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
steps:
- name: Setup environment
run: |
if [ -f "/etc/debian_version" ]
then
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
export DEBIAN_FRONTEND=noninteractive
fi
if [ -n "${{matrix.container}}" ]
then
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
if [ -f "/etc/debian_version" ]
then
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common tzdata wget curl apt-transport-https ca-certificates make build-essential g++ python python3 perl git cmake
fi
fi
git config --global pack.threads 0
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: |
declare -a SOURCE_KEYS SOURCES
if [ -n "${{join(matrix.source_keys, ' ')}}" ]
then
SOURCE_KEYS=("${{join(matrix.source_keys, '" "')}}")
fi
if [ -n "${{join(matrix.sources, ' ')}}" ]
then
SOURCES=("${{join(matrix.sources, '" "')}}")
fi
for key in "${SOURCE_KEYS[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
echo "Adding key: $key"
wget -O - "$key" | sudo apt-key add - && break || sleep 2
done
done
if [ ${#SOURCES[@]} -gt 0 ]
then
APT_ADD_REPO_COMMON_ARGS=("-y")
APT_ADD_REPO_SUPPORTED_ARGS="$(apt-add-repository --help | perl -ne 'if (/^\s*-n/) { print "n"; } elsif (/^\s*-P/) { print "P"; } elsif (/^\s*-S/) { print "S"; } elsif (/^\s*-U/) { print "U"; }')"
if [ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*n*}" ]
then
APT_ADD_REPO_COMMON_ARGS+=("-n")
fi
APT_ADD_REPO_HAS_SOURCE_ARGS="$([ -n "$APT_ADD_REPO_SUPPORTED_ARGS" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*P*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*S*}" -a -z "${APT_ADD_REPO_SUPPORTED_ARGS##*U*}" ] && echo 1 || echo 0)"
for source in "${SOURCES[@]}"
do
for i in {1..$NET_RETRY_COUNT}
do
APT_ADD_REPO_ARGS=("${APT_ADD_REPO_COMMON_ARGS[@]}")
if [ $APT_ADD_REPO_HAS_SOURCE_ARGS -ne 0 ]
then
case "$source" in
"ppa:"*)
APT_ADD_REPO_ARGS+=("-P")
;;
"deb "*)
APT_ADD_REPO_ARGS+=("-S")
;;
*)
APT_ADD_REPO_ARGS+=("-U")
;;
esac
fi
APT_ADD_REPO_ARGS+=("$source")
echo "apt-add-repository ${APT_ADD_REPO_ARGS[@]}"
sudo -E apt-add-repository "${APT_ADD_REPO_ARGS[@]}" && break || sleep 2
done
done
fi
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y ${{join(matrix.install, ' ')}}
- name: Setup GCC Toolchain
if: matrix.gcc_toolchain
run: |
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
echo "GCC_TOOLCHAIN_ROOT=\"$GCC_TOOLCHAIN_ROOT\"" >> $GITHUB_ENV
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
mkdir -p "$GCC_TOOLCHAIN_ROOT"
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" = "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
BUILD_JOBS=$((nproc || sysctl -n hw.ncpu) 2> /dev/null)
echo "BUILD_JOBS=$BUILD_JOBS" >> $GITHUB_ENV
echo "CMAKE_BUILD_PARALLEL_LEVEL=$BUILD_JOBS" >> $GITHUB_ENV
GIT_VERSION="$(git --version | sed -e 's/git version //')"
GIT_HAS_JOBS=1
if [ -f "/etc/debian_version" ]
then
if $(dpkg --compare-versions "$GIT_VERSION" lt 2.8.0)
then
GIT_HAS_JOBS=0
fi
else
declare -a GIT_VER=(${GIT_VERSION//./ })
declare -a GIT_MIN_VER=(2 8 0)
for ((i=0; i<${#GIT_VER[@]}; i++))
do
if [ -z "${GIT_MIN_VER[i]}" ]
then
GIT_MIN_VER[i]=0
fi
if [ "${GIT_VER[i]}" -lt "${GIT_MIN_VER[i]}" ]
then
GIT_HAS_JOBS=0
break
fi
done
fi
if [ "$GIT_HAS_JOBS" -ne 0 ]
then
GIT_ARGS="--jobs $GIT_FETCH_JOBS"
fi
cd ..
git clone -b "$BOOST_BRANCH" --depth 1 "https://github.com/boostorg/boost.git" "boost-root"
cd boost-root
mkdir -p libs/$LIBRARY
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule init tools/boost_install
git submodule init libs/headers
git submodule init tools/build
git submodule init tools/cmake
git submodule init libs/assert
git submodule init libs/config
git submodule init libs/static_assert
git submodule init libs/throw_exception
git submodule init libs/type_traits
git submodule init libs/utility
git submodule init libs/io
git submodule update $GIT_ARGS
./bootstrap.sh
./b2 headers
if [ -n "${{matrix.compiler}}" -o -n "$GCC_TOOLCHAIN_ROOT" ]
then
echo -n "using ${{matrix.toolset}} : : ${{matrix.compiler}}" > ~/user-config.jam
if [ -n "$GCC_TOOLCHAIN_ROOT" ]
then
echo -n " : <compileflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\" <linkflags>\"--gcc-toolchain=$GCC_TOOLCHAIN_ROOT\"" >> ~/user-config.jam
fi
echo " ;" >> ~/user-config.jam
fi
- name: Run tests
if: matrix.cmake_tests == ''
run: |
cd ../boost-root
B2_ARGS=("-j" "$BUILD_JOBS" "toolset=${{matrix.toolset}}" "cxxstd=${{matrix.cxxstd}}")
if [ -n "${{matrix.build_variant}}" ]
then
B2_ARGS+=("variant=${{matrix.build_variant}}")
else
B2_ARGS+=("variant=$DEFAULT_BUILD_VARIANT")
fi
if [ -n "${{matrix.threading}}" ]
then
B2_ARGS+=("threading=${{matrix.threading}}")
fi
if [ -n "${{matrix.ubsan}}" ]
then
export UBSAN_OPTIONS="print_stacktrace=1"
B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global")
fi
if [ -n "${{matrix.cxxflags}}" ]
then
B2_ARGS+=("cxxflags=${{matrix.cxxflags}}")
fi
if [ -n "${{matrix.linkflags}}" ]
then
B2_ARGS+=("linkflags=${{matrix.linkflags}}")
fi
B2_ARGS+=("libs/$LIBRARY/test")
./b2 "${B2_ARGS[@]}"
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: "14"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule init tools/boost_install
git submodule init libs/headers
git submodule init tools/build
git submodule init tools/cmake
git submodule init libs/assert
git submodule init libs/config
git submodule init libs/static_assert
git submodule init libs/throw_exception
git submodule init libs/type_traits
git submodule init libs/utility
git submodule init libs/io
git submodule update --jobs %GIT_FETCH_JOBS%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j %NUMBER_OF_PROCESSORS% libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
posix-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-10.15
runs-on: ${{matrix.os}}
steps:
@@ -136,66 +562,123 @@ jobs:
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
- name: Use library with add_subdirectory
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build .
ctest --output-on-failure --no-tests=error
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release
windows:
posix-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.1
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2016
- toolset: msvc-14.2
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2019
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Run tests
shell: cmd
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
- name: Install
run: |
cd ../boost-root/__build__
cmake --build . --target install
- name: Use the installed library
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd ../boost-root/__build__
cmake --build . --target tests
- name: Run tests
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error

View File

@@ -1,208 +0,0 @@
# Copyright 2016-2019 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
dist: xenial
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
addons:
apt:
packages:
- g++-multilib
- os: linux
arch: arm64
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
- os: linux
arch: ppc64le
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14
- os: linux
arch: s390x
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11,14 ADDRMD=32,64
- os: linux
compiler: g++-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
compiler: g++-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: bionic
compiler: g++-10
env: UBSAN=1 TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold
addons:
apt:
packages:
- g++-10
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.3
- os: linux
dist: trusty
compiler: /usr/bin/clang++
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
addons:
apt:
packages:
- clang-3.4
- os: linux
compiler: clang++-11
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-11 CXXSTD=03,11,14,17,20 UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- clang-11
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-11 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: bionic
compiler: clang++-libc++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,17,2a UBSAN_OPTIONS=print_stacktrace=1
addons:
apt:
packages:
- libc++-dev
- libc++abi-dev
- os: freebsd
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17,2a
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
osx_image: xcode7.3
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
osx_image: xcode8.3
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z ADDRMD=32,64
osx_image: xcode9.4
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode10.1
- os: osx
osx_image: xcode11.3
compiler: clang++
env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z UBSAN_OPTIONS=print_stacktrace=1
- os: linux
env: CMAKE_TEST=1
script:
- mkdir __build__ && cd __build__
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=core ..
- ctest --output-on-failure -R boost_core
- os: linux
env: CMAKE_SUBDIR_TEST=1
install:
- BOOST_BRANCH=develop
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
- git clone -b $BOOST_BRANCH https://github.com/boostorg/config.git ../config
- git clone -b $BOOST_BRANCH https://github.com/boostorg/assert.git ../assert
script:
- cd test/cmake_subdir_test && mkdir __build__ && cd __build__
- cmake ..
- cmake --build .
- cmake --build . --target check
- os: linux
env: CMAKE_INSTALL_TEST=1
script:
- mkdir __build__ && cd __build__
- cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES="assert;config;core" -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake --build . --target install
- cd ../libs/core/test/cmake_install_test && mkdir __build__ && cd __build__
- cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
- cmake --build .
- cmake --build . --target check
install:
- BOOST_BRANCH=develop
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
- cd ..
- git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init libs/headers
- git submodule init libs/assert
- git submodule init libs/config
- git submodule init libs/predef
- git submodule init libs/static_assert
- git submodule init libs/throw_exception
- git submodule init libs/type_traits
- git submodule init tools/build
- git submodule init tools/boost_install
- git submodule init tools/cmake
- git submodule update
- cp -r $TRAVIS_BUILD_DIR/* libs/core
- ./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/core/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}
notifications:
email:
on_success: always

View File

@@ -1,8 +1,9 @@
# Copyright 2018, 2019 Peter Dimov
# Generated by `boostdep --cmake core`
# Copyright 2020, 2021 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
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.16)
cmake_minimum_required(VERSION 3.5...3.20)
project(boost_core VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
@@ -15,16 +16,11 @@ target_link_libraries(boost_core
INTERFACE
Boost::assert
Boost::config
Boost::static_assert
Boost::throw_exception
)
if(BOOST_SUPERPROJECT_VERSION)
include(BoostInstall)
boost_install(TARGETS boost_core HEADER_DIRECTORY include/)
endif()
if(BUILD_TESTING)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)

View File

@@ -8,12 +8,12 @@ The criteria for inclusion is that the utility component be:
* used by other Boost libraries, and
* not dependent on any other Boost modules except Core itself, Config, Assert, Static Assert, or Predef.
### CI Status
### Build Status
Branch | Travis | Appveyor
---------|--------|---------
Develop | [![Build Status](https://travis-ci.org/boostorg/core.svg?branch=develop)](https://travis-ci.org/boostorg/core) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/core?branch=develop&svg=true)](https://ci.appveyor.com/project/pdimov/core)
Master | [![Build Status](https://travis-ci.org/boostorg/core.svg?branch=master)](https://travis-ci.org/boostorg/core) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/core?branch=master&svg=true)](https://ci.appveyor.com/project/pdimov/core)
Branch | GitHub Actions | AppVeyor | Test Matrix | Dependencies |
---------|----------------|--------- | ----------- | ------------ |
Develop | [![GitHub Actions](https://github.com/boostorg/core/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/filesystem/actions?query=branch%3Adevelop) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/boostorg/core?branch=develop&svg=true)](https://ci.appveyor.com/project/pdimov/core) | [![Tests](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/core.html) | [![Dependencies](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/core.html)
Master | [![GitHub Actions](https://github.com/boostorg/core/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/filesystem/actions?query=branch%3Amaster) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/boostorg/core?branch=master&svg=true)](https://ci.appveyor.com/project/pdimov/core) | [![Tests](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/core.html) | [![Dependencies](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/core.html)
### Directories

View File

@@ -1,4 +1,4 @@
# Copyright 2016-2019 Peter Dimov
# Copyright 2016-2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
@@ -29,14 +29,9 @@ environment:
# clang-win 32 bit fails to link with "unable to load mspdbcore.dll (error code: 126)"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
ADDRMD: 32,64
CXXSTD: 14,17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
@@ -77,6 +72,8 @@ install:
- git submodule init libs/static_assert
- git submodule init libs/throw_exception
- git submodule init libs/type_traits
- git submodule init libs/utility
- git submodule init libs/io
- git submodule init tools/build
- git submodule init tools/boost_install
- git submodule update --jobs 4
@@ -90,4 +87,4 @@ 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/core/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release
- b2 -j %NUMBER_OF_PROCESSORS% libs/core/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker

View File

@@ -5,12 +5,15 @@
# Version 1.0. (See accompanying file LICENSE_1_0.txt
# or copy at http://boost.org/LICENSE_1_0.txt)
import project ;
import doxygen ;
import quickbook ;
path-constant INCLUDES : ../../.. ;
doxygen ref_reference
:
[ glob ../../../boost/core/ref.hpp ]
$(INCLUDES)/boost/core/ref.hpp
:
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES

View File

@@ -1,149 +0,0 @@
[/
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:alloc_construct alloc_construct, alloc_destroy]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
The header <boost/core/alloc_construct.hpp> provides function templates
`alloc_construct`, `alloc_construct_n`, `alloc_destroy`, and `alloc_destroy_n`
for allocator aware and exception safe construction and destruction of objects
and arrays.
[endsect]
[section Example]
The following example allocates storage for an array of `n` elements of `T`
using an allocator `a` and constructs `T` elements in that storage. If any
exception was thrown during construction of an element, the constructed
elements are destroyed in reverse order.
```
template<class A>
auto create(A& a, std::size_t n)
{
auto p = a.allocate(n);
try {
boost::alloc_construct_n(a, boost::to_address(p), n);
} catch (...) {
a.deallocate(p, n);
throw;
}
return p;
}
```
[endsect]
[section Reference]
```
namespace boost {
template<class A, class T>
void alloc_destroy(A& a, T* p);
template<class A, class T>
void alloc_destroy_n(A& a, T* p, std::size_t n);
template<class A, class T, class Args>
void alloc_construct(A& a, T* p, Args&&... args);
template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n);
template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m);
template<class A, class T, class I>
void alloc_construct_n(A& a, T* p, std::size_t n, I begin);
} /* boost */
```
[section Functions]
[variablelist
[[`template<class A, class T> void alloc_destroy(A& a, T* p);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects][`std::allocator_traits<A>::destroy(a, p)`.]]]]]
[[`template<class A, class T> void alloc_destroy_n(A& a, T* p,
std::size_t n);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects]
[Destroys each `i`-th element in reverse order by calling
`std::allocator_traits<A>::destroy(a, &p[i])`.]]]]]
[[`template<class A, class T, class Args> void alloc_construct(A& a, T* p,
Args&&... args);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects]
[`std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...)`.]]]]]
[[`template<class A, class T> void alloc_construct_n(A& a, T* p,
std::size_t n);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects]
[Constructs each `i`-th element in order by calling
`std::allocator_traits<A>::construct(a, &p[i])`.]]
[[Remarks]
[If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `std::allocator_traits<A>::destroy(a, &p[j])`.]]]]]
[[`template<class A, class T> void alloc_construct_n(A& a, T* p, std::size_t n,
const T* l, std::size_t m);`]
[[variablelist
[[Requires][`A` is an /Allocator/]]
[[Effects]
[Constructs each `i`-th element in order by calling
`std::allocator_traits<A>::construct(a, &p[i], l[i % m])`.]]
[[Remarks]
[If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `std::allocator_traits<A>::destroy(a, &p[j])`.]]]]]
[[`template<class A, class T, class I> void alloc_construct_n(A& a, T* p,
std::size_t n, I begin);`]
[[variablelist
[[Requires]
[[itemized_list
[`A` is an /Allocator/][`I` is an /InputIterator/]]]]
[[Effects]
[Constructs each `i`-th element in order by calling
`std::allocator_traits<A>::construct(a, &p[i], *begin++])`.]]
[[Remarks]
[If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `std::allocator_traits<A>::destroy(a, &p[j])`.]]]]]]
[endsect]
[endsect]
[section Compatibility]
When `BOOST_NO_CXX11_ALLOCATOR` is defined, and the C++11 allocator model is
not supported, these functions invoke constructors and destructors directly
without going through the supplied allocator.
[endsect]
[section Acknowledgments]
Glen Fernandes originally implemented this functionality in Boost.Smart_Ptr and
later moved these functions to Boost.Core for use in other Boost libraries,
such as Boost.Multi_Array and Boost.Histogram.
[endsect]
[endsect]

View File

@@ -1,12 +1,12 @@
[/
Copyright 2020 Glen Joseph Fernandes
Copyright 2020-2022 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section Allocator Access]
[section allocator_access]
[simplesect Authors]
@@ -21,6 +21,9 @@ templates to simplify allocator use. It provides the same functionality as the
C++ standard library `std::allocator_traits` but with individual templates for
each allocator feature.
It also adds additional functionality for allocator aware exception safe
construction and destruction of arrays.
These facilities also simplify existing libraries by avoiding having to check
for `BOOST_NO_CXX11_ALLOCATOR` and conditionally use `std::allocator_traits`.
@@ -51,6 +54,26 @@ public:
In C++11 or above, aliases such as `boost::allocator_pointer_t<A>` can be used
instead of `typename boost::allocator_pointer<A>::type`.
The following example allocates storage for an array of `n` elements of `T`
using an allocator `a` and constructs `T` elements in that storage. If any
exception was thrown during construction of an element, the constructed
elements are destroyed in reverse order.
```
template<class A>
auto create(A& a, std::size_t n)
{
auto p = a.allocate(n);
try {
boost::allocator_construct_n(a, boost::to_address(p), n);
} catch (...) {
a.deallocate(p, n);
throw;
}
return p;
}
```
[endsect]
[section Reference]
@@ -150,9 +173,22 @@ void allocator_deallocate(A& a, allocator_pointer_t<A> p,
template<class A, class T, class... Args>
void allocator_construct(A& a, T* p, Args&&... args);
template<class A, class T>
void allocator_construct_n(A& a, T* p, std::size_t n);
template<class A, class T>
void allocator_construct_n(A& a, T* p, std::size_t n, const T* l,
std::size_t m);
template<class A, class T, class I>
void allocator_construct_n(A& a, T* p, std::size_t n, I begin);
template<class A, class T>
void allocator_destroy(A& a, T* p);
template<class A, class T>
void allocator_destroy_n(A& a, T* p, std::size_t n);
template<class A>
allocator_size_type_t<A> allocator_max_size(const A& a);
@@ -168,7 +204,8 @@ A allocator_select_on_container_copy_construction(const A& a);
[[`template<class A> struct allocator_value_type;`]
[The member `type` is `A::value_type`.]]
[[`template<class A> struct allocator_pointer;`]
[The member `type` is `A::pointer` if valid, otherwise `A::value_type*`.]]
[The member `type` is `A::pointer` if valid, otherwise
`allocator_value_type_t<A>*`.]]
[[`template<class A> struct allocator_const_pointer;`]
[The member `type` is `A::const_pointer` if valid, otherwise
`pointer_traits<allocator_pointer_t<A> >::rebind<const
@@ -219,12 +256,34 @@ allocator_size_type_t<A> n);`]
void allocator_construct(A& a, T*p, Args&&... args);`]
[Calls `a.construct(p, std::forward<Args>(args)...)` if valid, otherwise calls
`::new(static_cast<void*>(p)) T(std::forward<Args>(args)...)`.]]
[[`template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n);`]
[Constructs each `i`-th element in order by calling
`boost::allocator_construct(a, &p[i])`.
If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
[[`template<class A, class T>
void alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m);`]
[Constructs each `i`-th element in order by calling
`boost::allocator_construct(a, &p[i], l[i % m])`.
If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
[[`template<class A, class T, class I>
void alloc_construct_n(A& a, T* p, std::size_t n, I begin);`]
[Constructs each `i`-th element in order by calling
`boost::allocator_construct(a, &p[i], *begin++)`.
If an exception is thrown destroys each already constructed `j`-th element in
reverse order by calling `boost::allocator_destroy(a, &p[j])`.]]
[[`template<class A, class T> void allocator_destroy(A& a, T* p);`]
[Calls `a.destroy(p)` if valid, otherwise calls `p->~T()`.]]
[[`template<class A, class T>
void allocator_destroy_n(A& a, T* p, std::size_t n);`]
[Destroys each `i`-th element in reverse order by calling
`boost::allocator_destroy(a, &p[i])`.]]
[[`template<class A> allocator_size_type_t<A> allocator_max_size(const A& a);`]
[Returns `a.max_size()` if valid, otherwise returns
`std::numeric_limits<allocator_size_type_t<A> >::max() /
sizeof(A::value_type)`.]]
sizeof(allocator_value_type_t<A>)`.]]
[[`template<class A> A allocator_select_on_container_copy_construction(const
A& a);`]
[Returns `a.select_on_container_copy_construction()` if valid, otherwise

116
doc/allocator_traits.qbk Normal file
View File

@@ -0,0 +1,116 @@
[/
Copyright 2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:allocator_traits allocator_traits]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
This header <boost/core/allocator_traits.hpp> provides an implementation of the
C++ standard library class template `allocator_traits` based on the facilities
in [link core.allocator_access Allocator Access]. Users should still prefer the
individual traits, but this utility exists to simplify migration.
[endsect]
[section Reference]
```
namespace boost {
template<class A>
struct allocator_traits {
using allocator_type = A;
using value_type = allocator_value_type_t<A>;
using pointer = allocator_pointer_t<A>;
using const_pointer = allocator_const_pointer_t<A>;
using void_pointer = allocator_void_pointer_t<A>;
using const_pointer = allocator_const_void_pointer_t<A>;
using difference_type = allocator_difference_type_t<A>;
using size_type = allocator_size_type_t<A>;
using propagate_on_container_copy_assignment =
allocator_propagate_on_container_copy_assignment_t<A>;
using propagate_on_container_move_assignment =
allocator_propagate_on_container_move_assignment_t<A>;
using propagate_on_container_swap =
allocator_propagate_on_container_swap_t<A>;
using is_always_equal = allocator_is_always_equal_t<A>;
template<class T>
using rebind_traits = allocator_traits<allocator_rebind_t<A, T> >;
static pointer allocate(A& a, size_type n);
static pointer allocate(A& a, size_type n, const_void_pointer h);
static void deallocate(A& a, pointer p, size_type n);
template<class T, class... Args>
static void construct(A& a, T* p, Args&&... args);
static void destroy(A& a, T* p);
static size_type max_size(const A& a) noexcept;
static A select_on_container_copy_construction(const A& a);
};
} /* boost */
```
[section Static member functions]
[variablelist
[[`static pointer allocate(A& a, size_type n);`]
[Equivalent to: `return boost::allocator_allocate(a, n);`]]
[[`static pointer allocate(A& a, size_type n, const_void_pointer h);`]
[Equivalent to: `return boost::allocator_allocate(a, n, h);`]]
[[`static void deallocate(A& a, pointer p, size_type n);`]
[Equivalent to: `boost::allocator_deallocate(a, n, h);`]]
[[`template<class T, class... Args>
static void construct(A& a, T* p, Args&&... args);`]
[Equivalent to:
`boost::allocator_construct(a, p, std::forward<Args>(args)...);`]]
[[`static void destroy(A& a, T* p);`]
[Equivalent to: `boost::allocator_destroy(a, p);`]]
[[`static size_type max_size(const A& a) noexcept;`]
[Equivalent to: `return boost::allocator_max_size(a);`]]
[[`static A select_on_container_copy_construction(const A& a);`]
[Equivalent to:
`return boost::allocator_select_on_container_copy_construction(a);`]]]
[endsect]
[endsect]
[section Notes]
# The member `rebind_alloc` is not provided for parity with C++03 where it is
unimplementable. Instead of `allocator_traits<A>::rebind_alloc<U>` you can
express the same with `allocator_traits<A>::rebind_traits<U>::allocator_type`
or more simply with `allocator_rebind_t<A, U>`.
[endsect]
[endsect]

101
doc/changes.qbk Normal file
View File

@@ -0,0 +1,101 @@
[/
Copyright 2021 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt)
]
[section Revision History]
[section Changes in 1.79.0]
* Added `boost::allocator_traits`, an implementation of `std::allocator_traits`.
* Made `boost::pointer_traits` SFINAE friendly.
* `boost/iterator.hpp` is deprecated and will be removed in a future release. The header defines `boost::iterator` template, which is equivalent to `std::iterator` in `<iterator>` header. However, since `std::iterator` is itself deprecated in C++17, users are advised to remove `boost::iterator` or `std::iterator` use from their code.
* Added `boost::core::verbose_terminate_handler`, a utility function intended
to be passed to `std::set_terminate` that prints information about the
uncaught exception to `stderr`.
[endsect]
[section Changes in 1.78.0]
* Added a generic implementation to `boost/core/cmath.hpp`, enabled when `BOOST_CORE_USE_GENERIC_CMATH`
is defined or when the platform does not provide the necessary facilities in `<cmath>`.
* Added `boost::core::type_name`, a utility function that returns the name of a type as a string.
* Added `boost::span`, a C++11 implementation of C++20's `std::span`.
[endsect]
[section Changes in 1.77.0]
* `boost/core/uncaught_exceptions.hpp` has been modified for compatibility with Mac OS 10.4 and older.
[endsect]
[section Changes in 1.76.0]
* Added implicit conversion between compatible reference wrappers.
* Added `boost/core/cmath.hpp`, a portable implementation of the floating point classification functions from `<cmath>`.
* Added `boost/core/bit.hpp`, a portable implementation of the C++20 standard header `<bit>`.
* Fixed `BOOST_TEST_EQ`, `BOOST_TEST_NE` for character types under C++20.
* Revised allocator access utilities (now support VS2013, and no workarounds use `allocator_traits`.)
[endsect]
[section Changes in 1.74.0]
* Implemented the allocator access utilities which provide a replacement for `allocator_traits`
with individual traits and functions for each facility. They support the C++11 allocator model
when possible and provide a fallback for C++98 compatibility.
* Added `BOOST_TEST_WITH` to Lightweight Test.
[endsect]
[section Changes in 1.71.0]
* Added functions `alloc_construct`, `alloc_construct_n`, `alloc_destroy`, and `alloc_destroy_n`
in `<boost/core/alloc_construct.hpp>` for allocator aware and exception safe construction and
destruction of objects and arrays.
* Added constexpr functions `first_scalar` in `<boost/core/first_scalar.hpp>` for obtaining a pointer
to the first scalar element of an array. Given a pointer of type `T*` they return a pointer of type
`remove_all_extents_t<T>*`.
* Added class template `noinit_adaptor` in `<boost/core/noinit_adaptor.hpp>` which is an allocator adaptor
that converts any allocator into one whose `construct(ptr)` performs default initialization via placement
`new`, and whose `destroy(ptr)` invokes the `value_type` destructor directly.
* Added class template `default_allocator` in `<boost/core/default_allocator.hpp>`, which can serve as a minimal
default allocator that has interface similar to C++20 `std::allocator`, supports configurations with disabled
exceptions and does not have `std` as an associated namespace. The allocator uses `operator new` and
`operator delete` for allocation.
* In `<boost/core/uncaught_exceptions.hpp>` header, added workarounds for better compatibility with QNX SDP 7.0
when libc++/libc++abi libraries are used.
* The `<boost/detail/sp_typeinfo.hpp>` header is now marked as deprecated and will be removed in a future release.
`<boost/core/typeinfo.hpp>` should be used instead.
[endsect]
[section Changes in 1.69.0]
* Implemented `boost::empty_value`, for library authors to conveniently leverage the Empty Base Optimization to
store objects of potentially empty types.
* Implemented `boost::quick_exit` to provide the C++11 standard library facility `std::quick_exit` functionality.
* Reduced the number of statics in Lightweight Test, and employ lighter abort behavior for MSVC compilers upon
failure to call `boost::report_errors`.
[endsect]
[section Changes in 1.67.0]
* Updated `to_address` and `pointer_traits` to reflect the design adopted for C++20 in
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0653r2.html P0653R2].
[endsect]
[section Changes in 1.65.0]
* Implemented `pointer_traits` for C++03 and higher, that implements
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0653r0.html P0653r0].
* Added `BOOST_TEST_GT` and `BOOST_TEST_GE` to Lightweight Test.
[endsect]
[endsect]

View File

@@ -34,13 +34,15 @@ criteria for inclusion is that the utility component be:
* simple,
* used by other Boost libraries, and
* not dependent on any other Boost modules except Core
itself, Config, Assert, Static Assert, or Predef.
itself, Config, Assert, StaticAssert, or ThrowException.
[endsect]
[include changes.qbk]
[include addressof.qbk]
[include allocator_access.qbk]
[include alloc_construct.qbk]
[include allocator_traits.qbk]
[include bit.qbk]
[include checked_delete.qbk]
[include cmath.qbk]
@@ -63,7 +65,10 @@ criteria for inclusion is that the utility component be:
[include quick_exit.qbk]
[include ref.qbk]
[include scoped_enum.qbk]
[include span.qbk]
[include swap.qbk]
[include typeinfo.qbk]
[include type_name.qbk]
[include uncaught_exceptions.qbk]
[include use_default.qbk]
[include verbose_terminate_handler.qbk]

View File

@@ -1,5 +1,5 @@
[/
Copyright 2017-2018 Glen Joseph Fernandes
Copyright 2017-2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -47,68 +47,88 @@ void function(Allocator& a)
```
namespace boost {
template<class T> struct pointer_traits {
template<class T>
struct pointer_traits {
typedef T pointer;
typedef ``['see below]`` element_type;
typedef ``['see below]`` difference_type;
template<class U> struct rebind_to { typedef ``['see below]`` type; };
template<class U> using rebind = typename rebind_to<U>::type;
template<class U>
struct rebind_to {
typedef ``['see below]`` type;
};
static pointer pointer_to(``['see below]`` v);
};
template<class U>
using rebind = typename rebind_to<U>::type;
template<class T> struct pointer_traits<T*> {
static pointer pointer_to(element_type& v);
};
template<class T>
struct pointer_traits<T*> {
typedef T* pointer;
typedef T element_type;
typedef std::ptrdiff_t difference_type;
template<class U> struct rebind_to { typedef U* type; };
template<class U> using rebind = typename rebind_to<U>::type;
template<class U>
struct rebind_to {
typedef U* type;
};
template<class U>
using rebind = typename rebind_to<U>::type;
static pointer pointer_to(``['see below]`` v) noexcept;
};
};
template<class T>
constexpr T* to_address(T* v) noexcept;
template<class T>
constexpr T* to_address(T* v) noexcept;
template<class T>
auto to_address(const T& v) noexcept;
}
template<class T>
auto to_address(const T& v) noexcept;
} // boost
```
[section Overview]
If the member type `element_type` is not defined, then all other members are
also not defined (`pointer_traits` is SFINAE-friendly).
[endsect]
[section Member types]
[variablelist
[[`typedef` ['see below] `element_type;`]
[`T::element_type` if such a type exists; otherwise `U` if `T` is a class
template instantiation of the form `Pointer<U, Args>`, where `Args` is zero
or more type arguments; otherwise the specialization is ill-formed.]]
or more type arguments; otherwise the member is not defined.]]
[[`typedef` ['see below] `difference_type;`]
[`T::difference_type` if such a type exists; otherwise `std::ptrdiff_t`.]]
[[`template<class U> struct rebind_to { typedef` ['see below] `type; };`]
[`type` is `T::rebind<U>` if such a type exists; otherwise, `Pointer<V, Args>`
if `T` is a class template instantiation of the form `Pointer<T, Args>`,
where `Args` is zero or more type arguments; otherwise, the instantiation of
`rebind_to` is ill-formed.]]]
where `Args` is zero or more type arguments; otherwise, the member is not
defined.]]]
[endsect]
[section Member functions]
[variablelist
[[`static pointer pointer_traits::pointer_to(`['see below] `v);`]
[[`static pointer pointer_traits::pointer_to(element_type& v);`]
[[variablelist
[[Remark]
[If `element_type` is a void type, the type of `v` is unspecified; otherwise,
it is `element_type&`.]]
[If `element_type` is a void type, or if `T::pointer_to(v)` is not well formed,
this member is not defined.]]
[[Returns]
[A pointer to `v` obtained by calling `T::pointer_to(v)`.]]]]]
[[`static pointer pointer_traits<T*>::pointer_to(`['see below] `v) noexcept;`]
[[`static pointer pointer_traits<T*>::pointer_to(element_type& v) noexcept;`]
[[variablelist
[[Remark]
[If `element_type` is a void type, the type of `v` is unspecified; otherwise,
it is `element_type&`.]]
[If `element_type` is a void type, this member is not defined.]]
[[Returns][`addressof(v)`.]]]]]]
[endsect]

396
doc/span.qbk Normal file
View File

@@ -0,0 +1,396 @@
[/
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:span span]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
This header <boost/core/span.hpp> provides class template `span`, which is a
view over a sequence of objects. It implements the C++20 standard library
`std::span` facility. This implementation supports C++11 and higher.
In addition to referencing the sequence of objects, the span knows the count of
objects. There are two kinds of spans:
* Dynamic size (`span<T>` or `span<T, dynamic_extent>`)
* Static size (`span<T, N>`)
Dynamic size spans have a count that can be a value known at run time. Static
size spans have a count that must be known at compile time.
[endsect]
[section Examples]
The following snippet shows a function to compute a SHA1 hash whose parameters
and return type use spans.
```
auto sha1(boost::span<const unsigned char> input,
boost::span<unsigned char, SHA_DIGEST_LENGTH> ouput)
{
SHA_CTX context;
SHA1_Init(&context);
SHA1_Update(&context, input.data(), input.size());
SHA1_Final(output.data(), &context);
return output;
}
```
[endsect]
[section Reference]
```
namespace boost {
constexpr std::size_t dynamic_extent = -1;
template<class T, std::size_t E = dynamic_extent>
class span {
public:
typedef T element_type;
typedef std::remove_cv_t<T> value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<T*> reverse_iterator;
typedef std::reverse_iterator<const T*> const_reverse_iterator;
static constexpr std::size_t extent = E;
constexpr span() noexcept;
explicit(E != dynamic_extent)
template<class I>
constexpr span(I* f, size_type c);
explicit(E != dynamic_extent)
template<class I, class L>
constexpr span(I* f, L* l);
template<std::size_t N>
constexpr span(type_identity_t<T> (&a)[N]);
template<class U, std::size_t N>
constexpr span(std::array<U, N>& a) noexcept;
template<class U, std::size_t N>
constexpr span(const std::array<U, N>& a) noexcept;
explicit(E != dynamic_extent)
template<class R>
constexpr span(R&& r);
explicit(E != dynamic_extent && N == dynamic_extent)
template<class U, std::size_t N>
constexpr span(const span<U, N>& s) noexcept;
template<std::size_t C>
constexpr span<T, C> first() const;
template<std::size_t C>
constexpr span<T, C> last() const;
template<std::size_t O, std::size_t C = dynamic_extent>
constexpr span<T, see below> subspan() const;
constexpr span<T, dynamic_extent> first(size_type c) const;
constexpr span<T, dynamic_extent> last(size_type c) const;
constexpr span<T, dynamic_extent> subspan(size_type o,
size_type c = dynamic_extent) const;
constexpr size_type size() const noexcept;
constexpr size_type size_bytes() const noexcept;
constexpr bool empty() const noexcept;
constexpr reference operator[](size_type i) const;
constexpr reference front() const;
constexpr reference back() const;
constexpr pointer data() const noexcept;
constexpr iterator begin() const noexcept;
constexpr iterator end() const noexcept;
constexpr reverse_iterator rbegin() const noexcept;
constexpr reverse_iterator rend() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
};
template<class I, class L>
span(I*, L) -> span<I>;
template<class T, std::size_t N>
span(T(&)[N]) -> span<T, N>;
template<class T, std::size_t N>
span(std::array<T, N>&) -> span<T, N>;
template<class T, std::size_t N>
span(const std::array<T, N>&) -> span<const T, N>;
template<class R>
span(R&&) -> span<std::remove_pointer_t<decltype(std::declval<R&>().data())> >;
template<class T, std::size_t E>
span<const std::byte, E == dynamic_extent ? dynamic_extent : sizeof(T) * E>
as_bytes(span<T, E> s) noexcept;
template<class T, std::size_t E>
span<std::byte, E == dynamic_extent ? dynamic_extent : sizeof(T) * E>
as_writable_bytes(span<T, E> s) noexcept;
} /* boost */
```
[section Constructors]
[variablelist
[[`constexpr span() noexcept;`]
[[variablelist
[[Constraints][`E == dynamic_extent || E == 0` is `true`.]]
[[Postconditions][`size() == 0 && data() == nullptr`.]]]]]
[[`explicit(E != dynamic_extent)
template<class I>
constexpr span(I* f, size_type c);`]
[[variablelist
[[Constraints]
[`is_convertible_v<I(*)[], T(*)[]>` is `true`.]]
[[Preconditions]
[[itemized_list
[`[f, f + c)` is a valid range.]
[If `E` is not equal to `dynamic_extent`, then `c` is equal to `E`.]]]]
[[Effects][Constructs a `span` with data `f` and size `c`.]]
[[Throws][Nothing.]]]]]
[[`explicit(E != dynamic_extent)
template<class I, class L>
constexpr span(I* f, L* l);`]
[[variablelist
[[Constraints]
[`is_convertible_v<I(*)[], T(*)[]>` is `true`.]]
[[Preconditions]
[[itemized_list
[If `E` is not equal to `dynamic_extent`, then `l - f` is equal to `E`.]
[`[f, l)` is a valid range.]]]]
[[Effects][Constructs a `span` with data `f` and size `l - f`.]]
[[Throws][Nothing.]]]]]
[[`template<std::size_t N>
constexpr span(type_identity_t<T> (&a)[N]);`]
[[variablelist
[[Constraints][`E == dynamic_extent || E == N` is `true`.]]
[[Effects][Constructs a `span` that is a view over the supplied array.]]
[[Postconditions][`size() == N && data() == &a[0]` is `true`.]]]]]
[[`template<class U, std::size_t N>
constexpr span(std::array<U, N>& a) noexcept;`]
[[variablelist
[[Constraints]
[[itemized_list
[`E == dynamic_extent || E == N` is `true`, and]
[`U(*)[]` is convertible to `T(*)[]`.]]]]
[[Effects][Constructs a `span` that is a view over the supplied array.]]
[[Postconditions][`size() == N && data() == a.data()` is `true`.]]]]]
[[`template<class U, std::size_t N>
constexpr span(const std::array<U, N>& a) noexcept;`]
[[variablelist
[[Constraints]
[[itemized_list
[`E == dynamic_extent || E == N` is `true`, and]
[`U(*)[]` is convertible to `T(*)[]`.]]]]
[[Effects][Constructs a `span` that is a view over the supplied array.]]
[[Postconditions][`size() == N && data() == a.data()` is `true`.]]]]]
[[`explicit(E != dynamic_extent)
template<class R>
constexpr span(R&& r);`]
[[variablelist
[[Constraints]
[[itemized_list
[`is_lvalue_reference_v<R> || is_const_v<T>` is `true`]
[`remove_cvref_t<R>` is not a specialization of `span`,]
[`remove_cvref_t<R>` is not a specialization of `array`,]
[`is_array_v<remove_cvref_t<R>>` is `false`,]
[`r.data()` is well-formed and
`is_convertible_v<remove_pointer_t<decltype(declval<R&>().data())>(*)[],
T(*)[]>` is `true`, and]
[`r.size()` is well-formed and
`is_convertible_v<decltype(declval<R&>().size()), size_t>` is `true`.]]]]
[[Effects][Constructs a `span` with data `r.data()` and size `r.size()`.]]
[[Throws][What and when r.data() and r.size() throw.]]]]]
[[`explicit(E != dynamic_extent && N == dynamic_extent)
template<class U, std::size_t N>
constexpr span(const span<U, N>& s) noexcept;`]
[[variablelist
[[Constraints]
[[itemized_list
[`E == dynamic_extent || N == dynamic_extent || E == N` is `true`, and]
[`is_convertible_v<U(*)[], T(*)[]>` is `true`.]]]]
[[Preconditions]
[If `E` is not equal to `dynamic_extent`, then `s.size()` is equal to `E`.]]
[[Effects]
[Constructs a `span` that is a view over the range
`[s.data(), s.data() + s.size())`.]]
[[Postconditions][`size() == s.size() && data() == s.data()`.]]]]]]
[endsect]
[section Subviews]
[variablelist
[[`template<std::size_t C> constexpr span<T, C> first() const;`]
[[variablelist
[[Mandates][`C <= E` is `true`.]]
[[Preconditions][`C <= size()` is `true`.]]
[[Effects]
[Equivalent to `return R{data(), C};` where `R` is the return type.]]]]]
[[`template<std::size_t C> constexpr span<T, C> last() const;`]
[[variablelist
[[Mandates][`C <= E` is `true`.]]
[[Preconditions][`C <= size()` is `true`.]]
[[Effects]
[Equivalent to `return R{data() + (size() - C), C};` where `R` is the return
type.]]]]]
[[`template<std::size_t O, std::size_t C = dynamic_extent>
constexpr span<T, see below> subspan() const;`]
[[variablelist
[[Mandates][`O <= E && (C == dynamic_extent || C <= E - O)` is `true`.]]
[[Preconditions]
[`O <= size() && (C == dynamic_extent || C <= size() - O)` is `true`.]]
[[Effects]
[Equivalent to
`return span<T, see below>(data() + O,
C != dynamic_extent ? C : size() - O);`.]]
[[Remarks]
[The second template argument of the returned span type is:
`C != dynamic_extent ? C : (E != dynamic_extent ? E - O :
dynamic_extent)`]]]]]
[[`constexpr span<T, dynamic_extent> first(size_type c) const;`]
[[variablelist
[[Preconditions][`c <= size()` is `true`.]]
[[Effects][Equivalent to: `return {data(), c};`]]]]]
[[`constexpr span<T, dynamic_extent> last(size_type c) const;`]
[[variablelist
[[Preconditions][`c <= size()` is `true`.]]
[[Effects][Equivalent to: `return {data() + (size() - c), c};`]]]]]
[[`constexpr span<T, dynamic_extent> subspan(size_type o,
size_type c = dynamic_extent) const;`]
[[variablelist
[[Preconditions]
[`o <= size() && (c == dynamic_extent || o + c <= size())` is `true`.]]
[[Effects]
[Equivalent to:
`return {data() + o, c == dynamic_extent ? size() - o : c};`]]]]]]
[endsect]
[section Observers]
[variablelist
[[`constexpr size_type size() const noexcept;`]
[[variablelist
[[Returns][The number of elements in the span.]]]]]
[[`constexpr size_type size_bytes() const noexcept;`]
[[variablelist
[[Effects][Equivalent to: `return size() * sizeof(T);`]]]]]
[[`constexpr bool empty() const noexcept;`]
[[variablelist
[[Effects][Equivalent to: `return size() == 0;`]]]]]]
[endsect]
[section Element access]
[variablelist
[[`constexpr reference operator[](size_type i) const;`]
[[variablelist
[[Preconditions][`i < size()` is `true`.]]
[[Effects][Equivalent to: `return *(data() + i);`]]]]]
[[`constexpr reference front() const;`]
[[variablelist
[[Preconditions][`empty()` is `false`.]]
[[Effects][Equivalent to: `return *data();`]]]]]
[[`constexpr reference back() const;`]
[[variablelist
[[Preconditions][`empty()` is `false`.]]
[[Effects][Equivalent to: `return *(data() + (size() - 1);`]]]]]
[[`constexpr pointer data() const noexcept;`]
[[variablelist
[[Returns][A pointer to the first element in the span.]]]]]]
[endsect]
[section Iterator support]
[variablelist
[[`constexpr iterator begin() const noexcept;`]
[[variablelist
[[Returns][A constant iterator referring to the first element in the span. If `empty()`,
then it returns the same value as `cend()`.]]]]]
[[`constexpr iterator end() const noexcept;`]
[[variablelist
[[Returns][A constant iterator which is the past-the-end value.]]]]]
[[`constexpr reverse_iterator rbegin() const noexcept;`]
[[variablelist
[[Effects][Equivalent to: `return reverse_iterator(end());`]]]]]
[[`constexpr reverse_iterator rend() const noexcept;`]
[[variablelist
[[Effects][Equivalent to: `return reverse_iterator(begin());`]]]]]
[[`constexpr const_iterator cbegin() const noexcept;`]
[[variablelist
[[Returns]
[A constant iterator referring to the first element in the span. If `empty()`,
then it returns the same value as `cend()`.]]]]]
[[`constexpr const_iterator cend() const noexcept;`]
[[variablelist
[[Returns][A constant iterator which is the past-the-end value.]]]]]
[[`constexpr const_reverse_iterator crbegin() const noexcept;`]
[[variablelist
[[Effects][Equivalent to: `return const_reverse_iterator(cend());`]]]]]
[[`constexpr const_reverse_iterator crend() const noexcept;`]
[[variablelist
[[Effects]
[Equivalent to: `return const_reverse_iterator(cbegin());`]]]]]]
[endsect]
[section Views of object representation]
[variablelist
[[`template<class T, std::size_t E>
span<const std::byte, E == dynamic_extent ? dynamic_extent : sizeof(T) * E>
as_bytes(span<T, E> s) noexcept;`]
[[variablelist
[[Effects]
[Equivalent to:
`return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};`.]]]]]
[[`template<class T, std::size_t E>
span<std::byte, E == dynamic_extent ? dynamic_extent : sizeof(T) * E>
as_writable_bytes(span<T, E> s) noexcept;`]
[[variablelist
[[Constraints][`is_const_v<T>` is `false`.]]
[[Effects]
[Equivalent to: `return R{reinterpret_cast<byte*>(s.data()), s.size_bytes()};`
where `R` is the return type.]]]]]]
[endsect]
[endsect]
[endsect]

768
doc/string_view.qbk Normal file
View File

@@ -0,0 +1,768 @@
[/
Copyright 2021 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt
]
[section:string_view string_view]
[simplesect Authors]
* Peter Dimov
[endsimplesect]
[section Header <boost/core/string_view.hpp>]
The header `<boost/core/string_view.hpp>` defines `boost::core::string_view`,
a portable and interoperable implementation of `std::string_view`.
Unlike `boost::string_view`, `boost::core::string_view` has implicit
conversions from and to `std::string_view`, which allows Boost libraries that
support C++11/C++14 to use it in interfaces without forcing users to forgo the
use of `std::string_view` in their code.
[section Synopsis]
``
namespace boost
{
namespace core
{
template<class Ch> class basic_string_view
{
public:
// types
typedef std::char_traits<Ch> traits_type;
typedef Ch value_type;
typedef Ch* pointer;
typedef Ch const* const_pointer;
typedef Ch& reference;
typedef Ch const& const_reference;
typedef Ch const* const_iterator;
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;
// npos
static constexpr size_type npos = static_cast<size_type>( -1 );
public:
// construction and assignment
constexpr basic_string_view() noexcept;
constexpr basic_string_view( basic_string_view const& ) noexcept = default;
constexpr basic_string_view& operator=( basic_string_view const& ) noexcept & = default;
constexpr basic_string_view( Ch const* str ) noexcept;
constexpr basic_string_view( Ch const* str, size_type len ) noexcept;
constexpr basic_string_view( Ch const* begin, Ch const* end ) noexcept;
template<class A> basic_string_view( std::basic_string<Ch, std::char_traits<Ch>, A> const& str ) noexcept;
basic_string_view( std::basic_string_view<Ch, std::char_traits<Ch>> const& str ) noexcept;
// conversions
template<class A> operator std::basic_string<Ch, std::char_traits<Ch>, A>() const;
template<class Ch2> operator std::basic_string_view<Ch2>() const noexcept;
// iterator support
constexpr const_iterator begin() const noexcept;
constexpr const_iterator end() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
constexpr const_reverse_iterator rbegin() const noexcept;
constexpr const_reverse_iterator rend() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
// capacity
constexpr size_type size() const noexcept;
constexpr size_type length() const noexcept;
constexpr size_type max_size() const noexcept;
constexpr bool empty() const noexcept;
// element access
constexpr const_reference operator[]( size_type pos ) const noexcept;
constexpr const_reference at( size_type pos ) const;
constexpr const_reference front() const noexcept;
constexpr const_reference back() const noexcept;
constexpr const_pointer data() const noexcept;
// modifiers
constexpr void remove_prefix( size_type n ) noexcept;
constexpr void remove_suffix( size_type n ) noexcept;
constexpr void swap( basic_string_view& s ) noexcept;
// string operations
constexpr size_type copy( Ch* s, size_type n, size_type pos = 0 ) const;
constexpr basic_string_view substr( size_type pos = 0, size_type n = npos ) const;
// compare
constexpr int compare( basic_string_view str ) const noexcept;
constexpr int compare( size_type pos1, size_type n1, basic_string_view str ) const;
constexpr int compare( size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2 ) const;
constexpr int compare( Ch const* s ) const;
constexpr int compare( size_type pos1, size_type n1, Ch const* s ) const;
constexpr int compare( size_type pos1, size_type n1, Ch const* s, size_type n2 ) const;
// starts_with
constexpr bool starts_with( basic_string_view x ) const noexcept;
constexpr bool starts_with( Ch x ) const noexcept;
constexpr bool starts_with( Ch const* x ) const noexcept;
// ends_with
constexpr bool ends_with( basic_string_view x ) const noexcept;
constexpr bool ends_with( Ch x ) const noexcept;
constexpr bool ends_with( Ch const* x ) const noexcept;
// find
constexpr size_type find( basic_string_view str, size_type pos = 0 ) const noexcept;
constexpr size_type find( Ch c, size_type pos = 0 ) const noexcept;
constexpr size_type find( Ch const* s, size_type pos, size_type n ) const noexcept;
constexpr size_type find( Ch const* s, size_type pos = 0 ) const noexcept;
// rfind
constexpr size_type rfind( basic_string_view str, size_type pos = npos ) const noexcept;
constexpr size_type rfind( Ch c, size_type pos = npos ) const noexcept;
constexpr size_type rfind( Ch const* s, size_type pos, size_type n ) const noexcept;
constexpr size_type rfind( Ch const* s, size_type pos = npos ) const noexcept;
// find_first_of
constexpr size_type find_first_of( basic_string_view str, size_type pos = 0 ) const noexcept;
constexpr size_type find_first_of( Ch c, size_type pos = 0 ) const noexcept;
constexpr size_type find_first_of( Ch const* s, size_type pos, size_type n ) const noexcept;
constexpr size_type find_first_of( Ch const* s, size_type pos = 0 ) const noexcept;
// find_last_of
constexpr size_type find_last_of( basic_string_view str, size_type pos = npos ) const noexcept;
constexpr size_type find_last_of( Ch c, size_type pos = npos ) const noexcept;
constexpr size_type find_last_of( Ch const* s, size_type pos, size_type n ) const noexcept;
constexpr size_type find_last_of( Ch const* s, size_type pos = npos ) const noexcept;
// find_first_not_of
constexpr size_type find_first_not_of( basic_string_view str, size_type pos = 0 ) const noexcept;
constexpr size_type find_first_not_of( Ch c, size_type pos = 0 ) const noexcept;
constexpr size_type find_first_not_of( Ch const* s, size_type pos, size_type n ) const noexcept;
constexpr size_type find_first_not_of( Ch const* s, size_type pos = 0 ) const noexcept;
// find_last_not_of
constexpr size_type find_last_not_of( basic_string_view str, size_type pos = npos ) const noexcept;
constexpr size_type find_last_not_of( Ch c, size_type pos = npos ) const noexcept;
constexpr size_type find_last_not_of( Ch const* s, size_type pos, size_type n ) const noexcept;
constexpr size_type find_last_not_of( Ch const* s, size_type pos = npos ) const noexcept;
// contains
constexpr bool contains( basic_string_view sv ) const noexcept;
constexpr bool contains( Ch c ) const noexcept;
constexpr bool contains( Ch const* s ) const noexcept;
// relational operators
constexpr friend bool operator==( basic_string_view sv1, basic_string_view sv2 ) noexcept;
constexpr friend bool operator!=( basic_string_view sv1, basic_string_view sv2 ) noexcept;
constexpr friend bool operator<( basic_string_view sv1, basic_string_view sv2 ) noexcept;
constexpr friend bool operator<=( basic_string_view sv1, basic_string_view sv2 ) noexcept;
constexpr friend bool operator>( basic_string_view sv1, basic_string_view sv2 ) noexcept;
constexpr friend bool operator>=( basic_string_view sv1, basic_string_view sv2 ) noexcept;
};
// stream inserter
template<class Ch> std::basic_ostream<Ch>& operator<<( std::basic_ostream<Ch>& os, basic_string_view<Ch> str );
// typedef names
typedef basic_string_view<char> string_view;
typedef basic_string_view<wchar_t> wstring_view;
typedef basic_string_view<char16_t> u16string_view;
typedef basic_string_view<char32_t> u32string_view;
typedef basic_string_view<char8_t> u8string_view;
} // namespace core
} // namespace boost
``
[endsect]
[section Construction]
[section `constexpr basic_string_view() noexcept;`]
* *Ensures:* `data() == 0`; `size() == 0`.
[endsect]
[section `constexpr basic_string_view( Ch const* str ) noexcept;`]
* *Ensures:* `data() == str`; `size() == traits_type::length( str )`.
[endsect]
[section `constexpr basic_string_view( Ch const* str, size_type len ) noexcept;`]
* *Ensures:* `data() == str`; `size() == len`.
[endsect]
[section `constexpr basic_string_view( Ch const* begin, Ch const* end ) noexcept;`]
* *Requires:* `end >= begin`.
* *Ensures:* `data() == begin`; `size() == end - begin`.
[endsect]
[section `template<class A> basic_string_view( std::basic_string<Ch, std::char_traits<Ch>, A> const& str ) noexcept;`]
* *Ensures:* `data() == str.data()`; `size() == str.size()`.
[endsect]
[section `basic_string_view( std::basic_string_view<Ch, std::char_traits<Ch>> const& str ) noexcept;`]
* *Ensures:* `data() == str.data()`; `size() == str.size()`.
[endsect]
[endsect]
[section Conversions]
[section `template<class A> operator std::basic_string<Ch, std::char_traits<Ch>, A>() const;`]
* *Returns:* `std::basic_string<Ch, std::char_traits<Ch>, A>( data(), size() )`.
[endsect]
[section `template<class Ch2> operator std::basic_string_view<Ch2>() const noexcept;`]
* *Constraints:* `Ch2` is the same type as `Ch`.
* *Returns:* `std::basic_string_view<Ch2>( data(), size() )`.
[endsect]
[endsect]
[section Iterator Support]
[section `constexpr const_iterator begin() const noexcept;`]
* *Returns:* `data()`.
[endsect]
[section `constexpr const_iterator end() const noexcept;`]
* *Returns:* `data() + size()`.
[endsect]
[section `constexpr const_iterator cbegin() const noexcept;`]
* *Returns:* `begin()`.
[endsect]
[section `constexpr const_iterator cend() const noexcept;`]
* *Returns:* `end()`.
[endsect]
[section `constexpr const_reverse_iterator rbegin() const noexcept;`]
* *Returns:* `const_reverse_iterator( end() )`.
[endsect]
[section `constexpr const_reverse_iterator rend() const noexcept;`]
* *Returns:* `const_reverse_iterator( begin() )`.
[endsect]
[section `constexpr const_reverse_iterator crbegin() const noexcept;`]
* *Returns:* `rbegin()`.
[endsect]
[section `constexpr const_reverse_iterator crend() const noexcept;`]
* *Returns:* `rend()`.
[endsect]
[endsect]
[section Capacity]
[section `constexpr size_type size() const noexcept;`]
* *Returns:* the length of the referenced character sequence.
[endsect]
[section `constexpr size_type length() const noexcept;`]
* *Returns:* `size()`.
[endsect]
[section `constexpr size_type max_size() const noexcept;`]
* *Returns:* `std::numeric_limits<size_type>::max() / sizeof(Ch)`.
[endsect]
[section `constexpr bool empty() const noexcept;`]
* *Returns:* `size() == 0`.
[endsect]
[endsect]
[section Element Access]
[section `constexpr const_reference operator[]( size_type pos ) const noexcept;`]
* *Requires:* `pos < size()`.
* *Returns:* `data()[ pos ]`.
[endsect]
[section `constexpr const_reference at( size_type pos ) const;`]
* *Returns:* `data()[ pos ]`.
* *Throws:* `std::out_of_range` when `pos >= size()`.
[endsect]
[section `constexpr const_reference front() const noexcept;`]
* *Requires:* `!empty()`.
* *Returns:* `data()[ 0 ]`.
[endsect]
[section `constexpr const_reference back() const noexcept;`]
* *Requires:* `!empty()`.
* *Returns:* `data()[ size() - 1 ]`.
[endsect]
[section `constexpr const_pointer data() const noexcept;`]
* *Returns:* a pointer to the beginning of the referenced character sequence.
[endsect]
[endsect]
[section Modifiers]
[section `constexpr void remove_prefix( size_type n ) noexcept;`]
* *Requires:* `n <= size()`.
* *Effects:* advances `data()` by `n` and decreases `size()` by `n`.
[endsect]
[section `constexpr void remove_suffix( size_type n ) noexcept;`]
* *Requires:* `n <= size()`.
* *Effects:* decreases `size()` by `n`.
[endsect]
[section `constexpr void swap( basic_string_view& s ) noexcept;`]
* *Effects:* exchanges the contents of `*this` and `s`.
[endsect]
[endsect]
[section String Operations]
[section copy]
[section `constexpr size_type copy( Ch* s, size_type n, size_type pos = 0 ) const;`]
* *Effects:* copies to `s` the contents of `substr( pos, n )`.
* *Throws:* `std::out_of_range` when `pos >= size()`.
[endsect]
[endsect]
[section substr]
[section `constexpr basic_string_view substr( size_type pos = 0, size_type n = npos ) const;`]
* *Returns:* `basic_string_view( data() + pos, std::min( size() - pos, n ) )`.
* *Throws:* `std::out_of_range` when `pos >= size()`.
[endsect]
[endsect]
[section compare]
[section `constexpr int compare( basic_string_view str ) const noexcept;`]
* *Returns:*
* if `traits_type::compare( data(), str.data(), std::min( size(), str.size() ) )` is not zero, returns it. Otherwise,
* if `size() < str.size()`, returns a negative number. Otherwise,
* if `size() > str.size()`, returns a positive number. Otherwise,
* returns 0.
[endsect]
[section `constexpr int compare( size_type pos1, size_type n1, basic_string_view str ) const;`]
* *Returns:* `substr( pos1, n1 ).compare( str )`.
[endsect]
[section `constexpr int compare( size_type pos1, size_type n1, basic_string_view str, size_type pos2, size_type n2 ) const;`]
* *Returns:* `substr( pos1, n1 ).compare( str.substr( pos2, n2 ) )`.
[endsect]
[section `constexpr int compare( Ch const* s ) const noexcept;`]
* *Returns:* `compare( basic_string_view( s ) )`.
[endsect]
[section `constexpr int compare( size_type pos1, size_type n1, Ch const* s ) const;`]
* *Returns:* `substr( pos1, n1 ).compare( basic_string_view( s ) )`.
[endsect]
[section `constexpr int compare( size_type pos1, size_type n1, Ch const* s, size_type n2 ) const;`]
* *Returns:* `substr( pos1, n1 ).compare( basic_string_view( s, n2 ) )`.
[endsect]
[endsect]
[section starts_with]
[section `constexpr bool starts_with( basic_string_view x ) const noexcept;`]
* *Returns:* `substr( 0, x.size() ) == x`.
[endsect]
[section `constexpr bool starts_with( Ch x ) const noexcept;`]
* *Returns:* `starts_with( basic_string_view( &x, 1 ) )`.
[endsect]
[section `constexpr bool starts_with( Ch const* x ) const noexcept;`]
* *Returns:* `starts_with( basic_string_view( x ) )`.
[endsect]
[endsect]
[section ends_with]
[section `constexpr bool ends_with( basic_string_view x ) const noexcept;`]
* *Returns:* `size() >= x.size() && substr( size() - x.size(), x.size() ) == x`.
[endsect]
[section `constexpr bool ends_with( Ch x ) const noexcept;`]
* *Returns:* `ends_with( basic_string_view( &x, 1 ) )`.
[endsect]
[section `constexpr bool ends_with( Ch const* x ) const noexcept;`]
* *Returns:* `ends_with( basic_string_view( x ) )`.
[endsect]
[endsect]
[endsect]
[section Searching]
[section find]
[section `constexpr size_type find( basic_string_view str, size_type pos = 0 ) const noexcept;`]
* *Returns:* The lowest position `i` such that `i >= pos` and `substr( i, str.size() ) == str`, or `npos` if such a position doesn't exist.
[endsect]
[section `constexpr size_type find( Ch c, size_type pos = 0 ) const noexcept;`]
* *Returns:* `find( basic_string_view( &c, 1 ), pos )`.
[endsect]
[section `constexpr size_type find( Ch const* s, size_type pos, size_type n ) const noexcept;`]
* *Returns:* `find( basic_string_view( s, n ), pos )`.
[endsect]
[section `constexpr size_type find( Ch const* s, size_type pos = 0 ) const noexcept;`]
* *Returns:* `find( basic_string_view( s ), pos )`.
[endsect]
[endsect]
[section rfind]
[section `constexpr size_type rfind( basic_string_view str, size_type pos = npos ) const noexcept;`]
* *Returns:* The highest position `i` such that `i <= pos` and `substr( i, str.size() ) == str`, or `npos` if such a position doesn't exist.
[endsect]
[section `constexpr size_type rfind( Ch c, size_type pos = npos ) const noexcept;`]
* *Returns:* `rfind( basic_string_view( &c, 1 ), pos )`.
[endsect]
[section `constexpr size_type rfind( Ch const* s, size_type pos, size_type n ) const noexcept;`]
* *Returns:* `rfind( basic_string_view( s, n ), pos )`.
[endsect]
[section `constexpr size_type rfind( Ch const* s, size_type pos = npos ) const noexcept;`]
* *Returns:* `rfind( basic_string_view( s ), pos )`.
[endsect]
[endsect]
[section find_first_of]
[section `constexpr size_type find_first_of( basic_string_view str, size_type pos = 0 ) const noexcept;`]
* *Returns:* The lowest position `i` such that `i >= pos` and the character at position `i` is equal to one of the characters in `str`, or `npos` if such a position doesn't exist.
[endsect]
[section `constexpr size_type find_first_of( Ch c, size_type pos = 0 ) const noexcept;`]
* *Returns:* `find_first_of( basic_string_view( &c, 1 ), pos )`.
[endsect]
[section `constexpr size_type find_first_of( Ch const* s, size_type pos, size_type n ) const noexcept;`]
* *Returns:* `find_first_of( basic_string_view( s, n ), pos )`.
[endsect]
[section `constexpr size_type find_first_of( Ch const* s, size_type pos = 0 ) const noexcept;`]
* *Returns:* `find_first_of( basic_string_view( s ), pos )`.
[endsect]
[endsect]
[section find_last_of]
[section `constexpr size_type find_last_of( basic_string_view str, size_type pos = npos ) const noexcept;`]
* *Returns:* The highest position `i` such that `i <= pos` and the character at position `i` is equal to one of the characters in `str`, or `npos` if such a position doesn't exist.
[endsect]
[section `constexpr size_type find_last_of( Ch c, size_type pos = npos ) const noexcept;`]
* *Returns:* `find_last_of( basic_string_view( &c, 1 ), pos )`.
[endsect]
[section `constexpr size_type find_last_of( Ch const* s, size_type pos, size_type n ) const noexcept;`]
* *Returns:* `find_last_of( basic_string_view( s, n ), pos )`.
[endsect]
[section `constexpr size_type find_last_of( Ch const* s, size_type pos = npos ) const noexcept;`]
* *Returns:* `find_last_of( basic_string_view( s ), pos )`.
[endsect]
[endsect]
[section find_first_not_of]
[section `constexpr size_type find_first_not_of( basic_string_view str, size_type pos = 0 ) const noexcept;`]
* *Returns:* The lowest position `i` such that `i >= pos` and the character at position `i` is not equal to one of the characters in `str`, or `npos` if such a position doesn't exist.
[endsect]
[section `constexpr size_type find_first_not_of( Ch c, size_type pos = 0 ) const noexcept;`]
* *Returns:* `find_first_not_of( basic_string_view( &c, 1 ), pos )`.
[endsect]
[section `constexpr size_type find_first_not_of( Ch const* s, size_type pos, size_type n ) const noexcept;`]
* *Returns:* `find_first_not_of( basic_string_view( s, n ), pos )`.
[endsect]
[section `constexpr size_type find_first_not_of( Ch const* s, size_type pos = 0 ) const noexcept;`]
* *Returns:* `find_first_not_of( basic_string_view( s ), pos )`.
[endsect]
[endsect]
[section find_last_not_of]
[section `constexpr size_type find_last_not_of( basic_string_view str, size_type pos = npos ) const noexcept;`]
* *Returns:* The highest position `i` such that `i <= pos` and the character at position `i` is not equal to one of the characters in `str`, or `npos` if such a position doesn't exist.
[endsect]
[section `constexpr size_type find_last_not_of( Ch c, size_type pos = npos ) const noexcept;`]
* *Returns:* `find_last_not_of( basic_string_view( &c, 1 ), pos )`.
[endsect]
[section `constexpr size_type find_last_not_of( Ch const* s, size_type pos, size_type n ) const noexcept;`]
* *Returns:* `find_last_not_of( basic_string_view( s, n ), pos )`.
[endsect]
[section `constexpr size_type find_last_not_of( Ch const* s, size_type pos = npos ) const noexcept;`]
* *Returns:* `find_last_not_of( basic_string_view( s ), pos )`.
[endsect]
[endsect]
[section contains]
[section `constexpr bool contains( basic_string_view sv ) const noexcept;`]
* *Returns:* `find( sv ) != npos`.
[endsect]
[section `constexpr bool contains( Ch c ) const noexcept;`]
* *Returns:* `find( c ) != npos`.
[endsect]
[section `constexpr bool contains( Ch const* s ) const noexcept;`]
* *Returns:* `find( s ) != npos`.
[endsect]
[endsect]
[endsect]
[section Relational Operators]
[section `constexpr friend bool operator==( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
* *Returns:* `sv1.compare( sv2 ) == 0`.
[endsect]
[section `constexpr friend bool operator!=( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
* *Returns:* `sv1.compare( sv2 ) != 0`.
[endsect]
[section `constexpr friend bool operator<( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
* *Returns:* `sv1.compare( sv2 ) < 0`.
[endsect]
[section `constexpr friend bool operator<=( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
* *Returns:* `sv1.compare( sv2 ) <= 0`.
[endsect]
[section `constexpr friend bool operator>( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
* *Returns:* `sv1.compare( sv2 ) > 0`.
[endsect]
[section `constexpr friend bool operator>=( basic_string_view sv1, basic_string_view sv2 ) noexcept;`]
* *Returns:* `sv1.compare( sv2 ) >= 0`.
[endsect]
[endsect]
[section Stream Inserter]
[section `template<class Ch> std::basic_ostream<Ch>& operator<<( std::basic_ostream<Ch>& os, basic_string_view<Ch> str );`]
* *Effects:* equivalent to `os << x`, where `x` is a pointer to a null-terminated character sequence with the same contents as `str`.
[endsect]
[endsect]
[endsect]
[endsect]

77
doc/type_name.qbk Normal file
View File

@@ -0,0 +1,77 @@
[/
Copyright 2021 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt
]
[section:type_name type_name]
[simplesect Authors]
* Peter Dimov
[endsimplesect]
[section Header <boost/core/type_name.hpp>]
The header `<boost/core/type_name.hpp>` defines the function
template `boost::core::type_name<T>()` that returns a string
representation of the name of `T`, suitable for logging or
diagnostic display purposes.
The result is similar to `boost::core::demangle( typeid(T).name() )`,
but it's made more regular by eliminating some of the platform-specific
differences and extra template parameters of the standard library
container types.
For example, `type_name< std::map<std::string, int> >()` returns
`"std::map<std::string, int>"` and not
```
std::map<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > >, std::allocator<
std::pair<std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > const, int> > >
```
or
```
class std::map<class std::basic_string<char,struct std::char_traits<char>,
class std::allocator<char> >,int,struct std::less<class std::basic_string<
char,struct std::char_traits<char>,class std::allocator<char> > >,class
std::allocator<struct std::pair<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> > const ,int> > >
```
The return values aren't guaranteed to be stable across Boost releases.
Compilation with `-fno-rtti` is supported, but the returned type names aren't
guaranteed to be particularly useful or unique.
[section Synopsis]
``
namespace boost
{
namespace core
{
template<class T> std::string type_name();
} // namespace core
} // namespace boost
``
[endsect]
[section template<class T> std::string type_name();]
* *Returns:* A string representation of the name of `T`.
[endsect]
[endsect]
[endsect]

View File

@@ -0,0 +1,70 @@
[/
Copyright 2022 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt
]
[section:verbose_terminate_handler verbose_terminate_handler]
[simplesect Authors]
* Peter Dimov
[endsimplesect]
[section Header <boost/core/verbose_terminate_handler.hpp>]
The header `<boost/core/verbose_terminate_handler.hpp>` defines
the function `void boost::core::verbose_terminate_handler()`. Its
purpose is to be set as a terminate handler as in
```
std::set_terminate( boost::core::verbose_terminate_handler );
```
When invoked, the function prints information about the current
uncaught exception to `stderr` and then calls `std::abort`.
[section Synopsis]
``
namespace boost
{
namespace core
{
[[noreturn]] void verbose_terminate_handler();
} // namespace core
} // namespace boost
``
[endsect]
[section Example]
```
#include <boost/core/verbose_terminate_handler.hpp>
#include <boost/throw_exception.hpp>
#include <exception>
int main()
{
std::set_terminate( boost::core::verbose_terminate_handler );
boost::throw_with_location( std::exception() );
}
```
Sample output:
```
std::terminate called after throwing an exception:
type: class boost::detail::with_throw_location<class std::exception>
what(): Unknown exception
location: example.cpp:8:12 in function 'main'
```
[endsect]
[endsect]
[endsect]

View File

@@ -8,6 +8,9 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_CORE_ALLOC_CONSTRUCT_HPP
#define BOOST_CORE_ALLOC_CONSTRUCT_HPP
/*
This functionality is now in <boost/core/allocator_access.hpp>.
*/
#include <boost/core/noinit_adaptor.hpp>
namespace boost {
@@ -23,56 +26,9 @@ template<class A, class T>
inline void
alloc_destroy_n(A& a, T* p, std::size_t n)
{
while (n > 0) {
boost::allocator_destroy(a, p + --n);
}
boost::allocator_destroy_n(a, p, n);
}
template<class A, class T>
inline void
alloc_destroy(noinit_adaptor<A>&, T* p)
{
p->~T();
}
template<class A, class T>
inline void
alloc_destroy_n(noinit_adaptor<A>&, T* p, std::size_t n)
{
while (n > 0) {
p[--n].~T();
}
}
namespace detail {
template<class A, class T>
class alloc_destroyer {
public:
alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT
: a_(a),
p_(p),
n_(0) { }
~alloc_destroyer() {
boost::alloc_destroy_n(a_, p_, n_);
}
std::size_t& size() BOOST_NOEXCEPT {
return n_;
}
private:
alloc_destroyer(const alloc_destroyer&);
alloc_destroyer& operator=(const alloc_destroyer&);
A& a_;
T* p_;
std::size_t n_;
};
} /* detail */
template<class A, class T>
inline void
alloc_construct(A& a, T* p)
@@ -117,51 +73,21 @@ template<class A, class T>
inline void
alloc_construct_n(A& a, T* p, std::size_t n)
{
detail::alloc_destroyer<A, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; ++i) {
boost::allocator_construct(a, p + i);
}
hold.size() = 0;
boost::allocator_construct_n(a, p, n);
}
template<class A, class T>
inline void
alloc_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
{
detail::alloc_destroyer<A, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; ++i) {
boost::allocator_construct(a, p + i, l[i % m]);
}
hold.size() = 0;
boost::allocator_construct_n(a, p, n, l, m);
}
template<class A, class T, class I>
inline void
alloc_construct_n(A& a, T* p, std::size_t n, I b)
{
detail::alloc_destroyer<A, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; void(++i), void(++b)) {
boost::allocator_construct(a, p + i, *b);
}
hold.size() = 0;
}
template<class A, class T>
inline void
alloc_construct(noinit_adaptor<A>&, T* p)
{
::new(static_cast<void*>(p)) T;
}
template<class A, class T>
inline void
alloc_construct_n(noinit_adaptor<A>& a, T* p, std::size_t n)
{
detail::alloc_destroyer<noinit_adaptor<A>, T> hold(a, p);
for (std::size_t& i = hold.size(); i < n; ++i) {
::new(static_cast<void*>(p + i)) T;
}
hold.size() = 0;
boost::allocator_construct_n(a, p, n, b);
}
} /* boost */

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020-2021 Glen Joseph Fernandes
Copyright 2020-2022 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -9,16 +9,34 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_CORE_ALLOCATOR_ACCESS_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <boost/core/pointer_traits.hpp>
#include <limits>
#include <new>
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <type_traits>
#endif
#include <new>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <utility>
#endif
#if defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION >= 40300)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#elif defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#elif defined(BOOST_CLANG) && !defined(__CUDACC__)
#if __has_feature(is_empty)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#endif
#elif defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __oracle_is_empty(T)
#elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#elif defined(BOOST_CODEGEARC)
#define BOOST_DETAIL_ALLOC_EMPTY(T) __is_empty(T)
#endif
#if defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH)
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
#endif
@@ -37,244 +55,311 @@ struct allocator_value_type {
typedef typename A::value_type type;
};
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_pointer {
typedef typename A::pointer type;
};
#else
template<class A, class = void>
struct allocator_pointer {
typedef typename A::value_type* type;
};
namespace detail {
template<class A, class = void>
struct alloc_ptr {
typedef typename boost::allocator_value_type<A>::type* type;
};
template<class>
struct alloc_void {
typedef void type;
};
} /* detail */
template<class A>
struct allocator_pointer<A,
typename detail::alloc_void<typename A::pointer>::type> {
struct alloc_ptr<A,
typename alloc_void<typename A::pointer>::type> {
typedef typename A::pointer type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_const_pointer {
typedef typename A::const_pointer type;
};
#else
template<class A, class = void>
struct allocator_const_pointer {
typedef typename pointer_traits<typename
allocator_pointer<A>::type>::template
rebind_to<const typename A::value_type>::type type;
};
} /* detail */
template<class A>
struct allocator_const_pointer<A,
typename detail::alloc_void<typename A::const_pointer>::type> {
typedef typename A::const_pointer type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_void_pointer {
typedef typename A::template rebind<void>::other::pointer type;
};
#else
template<class A, class = void>
struct allocator_void_pointer {
typedef typename pointer_traits<typename
allocator_pointer<A>::type>::template
rebind_to<void>::type type;
struct allocator_pointer {
typedef typename detail::alloc_ptr<A>::type type;
};
template<class A>
struct allocator_void_pointer<A,
typename detail::alloc_void<typename A::void_pointer>::type> {
typedef typename A::void_pointer type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_const_void_pointer {
typedef typename A::template rebind<void>::other::const_pointer type;
};
#else
template<class A, class = void>
struct allocator_const_void_pointer {
typedef typename pointer_traits<typename
allocator_pointer<A>::type>::template
rebind_to<const void>::type type;
};
template<class A>
struct allocator_const_void_pointer<A,
typename detail::alloc_void<typename A::const_void_pointer>::type> {
typedef typename A::const_void_pointer type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_difference_type {
typedef typename A::difference_type type;
};
#else
template<class A, class = void>
struct allocator_difference_type {
typedef typename pointer_traits<typename
allocator_pointer<A>::type>::difference_type type;
};
template<class A>
struct allocator_difference_type<A,
typename detail::alloc_void<typename A::difference_type>::type> {
typedef typename A::difference_type type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_size_type {
typedef typename A::size_type type;
};
#else
template<class A, class = void>
struct allocator_size_type {
typedef typename std::make_unsigned<typename
allocator_difference_type<A>::type>::type type;
};
template<class A>
struct allocator_size_type<A,
typename detail::alloc_void<typename A::size_type>::type> {
typedef typename A::size_type type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
namespace detail {
struct alloc_false {
BOOST_STATIC_CONSTEXPR bool value = false;
template<class A, class = void>
struct alloc_const_ptr {
typedef typename boost::pointer_traits<typename
boost::allocator_pointer<A>::type>::template rebind_to<const typename
boost::allocator_value_type<A>::type>::type type;
};
template<class A>
struct alloc_const_ptr<A,
typename alloc_void<typename A::const_pointer>::type> {
typedef typename A::const_pointer type;
};
} /* detail */
template<class A>
struct allocator_propagate_on_container_copy_assignment {
typedef detail::alloc_false type;
};
#else
template<class A, class = void>
struct allocator_propagate_on_container_copy_assignment {
typedef std::false_type type;
struct allocator_const_pointer {
typedef typename detail::alloc_const_ptr<A>::type type;
};
template<class A>
struct allocator_propagate_on_container_copy_assignment<A,
typename detail::alloc_void<typename
A::propagate_on_container_copy_assignment>::type> {
typedef typename A::propagate_on_container_copy_assignment type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_propagate_on_container_move_assignment {
typedef detail::alloc_false type;
};
#else
template<class A, class = void>
struct allocator_propagate_on_container_move_assignment {
typedef std::false_type type;
};
template<class A>
struct allocator_propagate_on_container_move_assignment<A,
typename detail::alloc_void<typename
A::propagate_on_container_move_assignment>::type> {
typedef typename A::propagate_on_container_move_assignment type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_propagate_on_container_swap {
typedef detail::alloc_false type;
};
#else
template<class A, class = void>
struct allocator_propagate_on_container_swap {
typedef std::false_type type;
};
template<class A>
struct allocator_propagate_on_container_swap<A,
typename detail::alloc_void<typename
A::propagate_on_container_swap>::type> {
typedef typename A::propagate_on_container_swap type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
struct allocator_is_always_equal {
typedef detail::alloc_false type;
};
#else
template<class A, class = void>
struct allocator_is_always_equal {
typedef typename std::is_empty<A>::type type;
};
template<class A>
struct allocator_is_always_equal<A,
typename detail::alloc_void<typename A::is_always_equal>::type> {
typedef typename A::is_always_equal type;
};
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
struct allocator_rebind {
typedef typename A::template rebind<T>::other type;
};
#else
namespace detail {
template<class, class>
struct alloc_to { };
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class> class A, class T, class U>
struct alloc_to<A<U>, T> {
typedef A<T> type;
};
template<template<class, class> class A, class T, class U, class V>
struct alloc_to<A<U, V>, T> {
typedef A<T, V> type;
};
template<template<class, class, class> class A, class T, class U, class V1,
class V2>
struct alloc_to<A<U, V1, V2>, T> {
typedef A<T, V1, V2> type;
};
#else
template<template<class, class...> class A, class T, class U, class... V>
struct alloc_to<A<U, V...>, T> {
typedef A<T, V...> type;
};
} /* detail */
#endif
template<class A, class T, class = void>
struct allocator_rebind {
typedef typename detail::alloc_to<A, T>::type type;
struct alloc_rebind {
typedef typename alloc_to<A, T>::type type;
};
template<class A, class T>
struct allocator_rebind<A, T,
typename detail::alloc_void<typename A::template rebind<T>::other>::type> {
struct alloc_rebind<A, T,
typename alloc_void<typename A::template rebind<T>::other>::type> {
typedef typename A::template rebind<T>::other type;
};
} /* detail */
template<class A, class T>
struct allocator_rebind {
typedef typename detail::alloc_rebind<A, T>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_void_ptr {
typedef typename boost::pointer_traits<typename
boost::allocator_pointer<A>::type>::template
rebind_to<void>::type type;
};
template<class A>
struct alloc_void_ptr<A,
typename alloc_void<typename A::void_pointer>::type> {
typedef typename A::void_pointer type;
};
} /* detail */
template<class A>
struct allocator_void_pointer {
typedef typename detail::alloc_void_ptr<A>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_const_void_ptr {
typedef typename boost::pointer_traits<typename
boost::allocator_pointer<A>::type>::template
rebind_to<const void>::type type;
};
template<class A>
struct alloc_const_void_ptr<A,
typename alloc_void<typename A::const_void_pointer>::type> {
typedef typename A::const_void_pointer type;
};
} /* detail */
template<class A>
struct allocator_const_void_pointer {
typedef typename detail::alloc_const_void_ptr<A>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_diff_type {
typedef typename boost::pointer_traits<typename
boost::allocator_pointer<A>::type>::difference_type type;
};
template<class A>
struct alloc_diff_type<A,
typename alloc_void<typename A::difference_type>::type> {
typedef typename A::difference_type type;
};
} /* detail */
template<class A>
struct allocator_difference_type {
typedef typename detail::alloc_diff_type<A>::type type;
};
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class = void>
struct alloc_size_type {
typedef std::size_t type;
};
#else
template<class A, class = void>
struct alloc_size_type {
typedef typename std::make_unsigned<typename
boost::allocator_difference_type<A>::type>::type type;
};
#endif
template<class A>
struct alloc_size_type<A,
typename alloc_void<typename A::size_type>::type> {
typedef typename A::size_type type;
};
} /* detail */
template<class A>
struct allocator_size_type {
typedef typename detail::alloc_size_type<A>::type type;
};
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<bool V>
struct alloc_bool {
typedef bool value_type;
typedef alloc_bool type;
static const bool value = V;
operator bool() const BOOST_NOEXCEPT {
return V;
}
bool operator()() const BOOST_NOEXCEPT {
return V;
}
};
template<bool V>
const bool alloc_bool<V>::value;
typedef alloc_bool<false> alloc_false;
#else
typedef std::false_type alloc_false;
#endif
template<class A, class = void>
struct alloc_pocca {
typedef alloc_false type;
};
template<class A>
struct alloc_pocca<A,
typename alloc_void<typename
A::propagate_on_container_copy_assignment>::type> {
typedef typename A::propagate_on_container_copy_assignment type;
};
} /* detail */
template<class A, class = void>
struct allocator_propagate_on_container_copy_assignment {
typedef typename detail::alloc_pocca<A>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_pocma {
typedef alloc_false type;
};
template<class A>
struct alloc_pocma<A,
typename alloc_void<typename
A::propagate_on_container_move_assignment>::type> {
typedef typename A::propagate_on_container_move_assignment type;
};
} /* detail */
template<class A>
struct allocator_propagate_on_container_move_assignment {
typedef typename detail::alloc_pocma<A>::type type;
};
namespace detail {
template<class A, class = void>
struct alloc_pocs {
typedef alloc_false type;
};
template<class A>
struct alloc_pocs<A,
typename alloc_void<typename A::propagate_on_container_swap>::type> {
typedef typename A::propagate_on_container_swap type;
};
} /* detail */
template<class A>
struct allocator_propagate_on_container_swap {
typedef typename detail::alloc_pocs<A>::type type;
};
namespace detail {
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class = void>
struct alloc_equal {
typedef typename std::is_empty<A>::type type;
};
#elif defined(BOOST_DETAIL_ALLOC_EMPTY)
template<class A, class = void>
struct alloc_equal {
typedef alloc_bool<BOOST_DETAIL_ALLOC_EMPTY(A)> type;
};
#else
template<class A, class = void>
struct alloc_equal {
typedef alloc_false type;
};
#endif
template<class A>
struct alloc_equal<A,
typename alloc_void<typename A::is_always_equal>::type> {
typedef typename A::is_always_equal type;
};
} /* detail */
template<class A>
struct allocator_is_always_equal {
typedef typename detail::alloc_equal<A>::type type;
};
template<class A>
inline typename allocator_pointer<A>::type
allocator_allocate(A& a, typename allocator_size_type<A>::type n)
@@ -301,21 +386,24 @@ allocator_allocate(A& a, typename allocator_size_type<A>::type n,
#else
namespace detail {
struct alloc_none { };
template<class>
struct alloc_no {
char x, y;
};
template<class A>
class alloc_has_allocate {
template<class O>
static auto check(int) -> decltype(std::declval<O&>().allocate(
std::declval<typename allocator_size_type<A>::type>(),
std::declval<typename allocator_const_void_pointer<A>::type>()));
static auto check(int)
-> alloc_no<decltype(std::declval<O&>().allocate(std::declval<typename
boost::allocator_size_type<A>::type>(), std::declval<typename
boost::allocator_const_void_pointer<A>::type>()))>;
template<class>
static alloc_none check(long);
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
} /* detail */
@@ -339,9 +427,55 @@ allocator_allocate(A& a, typename allocator_size_type<A>::type n,
}
#endif
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class = void>
struct alloc_has_construct {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class A>
struct alloc_has_construct<A,
typename alloc_void<typename A::_default_construct_destroy>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
};
#else
template<class A, class T, class... Args>
class alloc_has_construct {
template<class O>
static auto check(int)
-> alloc_no<decltype(std::declval<O&>().construct(std::declval<T*>(),
std::declval<Args&&>()...))>;
template<class>
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#endif
template<bool, class = void>
struct alloc_if { };
template<class T>
struct alloc_if<true, T> {
typedef T type;
};
} /* detail */
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
inline void
inline typename detail::alloc_if<detail::alloc_has_construct<A>::value>::type
allocator_construct(A& a, T* p)
{
a.construct(p);
}
template<class A, class T>
inline typename detail::alloc_if<!detail::alloc_has_construct<A>::value>::type
allocator_construct(A&, T* p)
{
::new((void*)p) T();
@@ -379,25 +513,6 @@ allocator_construct(A&, T* p, V& v)
}
#endif
#else
namespace detail {
template<class A, class T, class... Args>
class alloc_has_construct {
template<class O>
static auto check(int)
-> decltype(std::declval<O&>().construct(std::declval<T*>(),
std::declval<Args&&>()...));
template<class>
static alloc_none check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
};
} /* detail */
template<class A, class T, class... Args>
inline typename std::enable_if<detail::alloc_has_construct<A, T,
Args...>::value>::type
@@ -415,132 +530,236 @@ allocator_construct(A&, T* p, Args&&... args)
}
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
inline void
allocator_destroy(A&, T* p)
{
p->~T();
(void)p;
}
#else
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class, class = void>
struct alloc_has_destroy {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class A, class T>
struct alloc_has_destroy<A, T,
typename alloc_void<typename A::_default_construct_destroy>::type> {
BOOST_STATIC_CONSTEXPR bool value = true;
};
#else
template<class A, class T>
class alloc_has_destroy {
template<class O>
static auto check(int)
-> decltype(std::declval<O&>().destroy(std::declval<T*>()));
-> alloc_no<decltype(std::declval<O&>().destroy(std::declval<T*>()))>;
template<class>
static alloc_none check(long);
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#endif
} /* detail */
template<class A, class T>
inline typename std::enable_if<detail::alloc_has_destroy<A, T>::value>::type
inline typename detail::alloc_if<detail::alloc_has_destroy<A, T>::value>::type
allocator_destroy(A& a, T* p)
{
a.destroy(p);
}
template<class A, class T>
inline typename std::enable_if<!detail::alloc_has_destroy<A, T>::value>::type
inline typename detail::alloc_if<!detail::alloc_has_destroy<A, T>::value>::type
allocator_destroy(A&, T* p)
{
p->~T();
(void)p;
}
#endif
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
inline typename allocator_size_type<A>::type
allocator_max_size(const A& a)
{
return a.max_size();
}
#else
namespace detail {
template<class T, T>
struct alloc_no {
char x, y;
};
template<class A>
class alloc_has_max_size {
template<class O>
static auto check(int) -> decltype(std::declval<O&>().max_size());
static alloc_no<typename boost::allocator_size_type<O>::type(O::*)(),
&O::max_size> check(int);
template<class O>
static alloc_no<typename boost::allocator_size_type<O>::type(O::*)() const,
&O::max_size> check(int);
template<class O>
static alloc_no<typename boost::allocator_size_type<O>::type(*)(),
&O::max_size> check(int);
template<class>
static alloc_none check(long);
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#else
template<class A>
class alloc_has_max_size {
template<class O>
static auto check(int)
-> alloc_no<decltype(std::declval<const O&>().max_size())>;
template<class>
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#endif
} /* detail */
template<class A>
inline typename std::enable_if<detail::alloc_has_max_size<A>::value,
inline typename detail::alloc_if<detail::alloc_has_max_size<A>::value,
typename allocator_size_type<A>::type>::type
allocator_max_size(const A& a)
allocator_max_size(const A& a) BOOST_NOEXCEPT
{
return a.max_size();
}
template<class A>
inline typename std::enable_if<!detail::alloc_has_max_size<A>::value,
inline typename detail::alloc_if<!detail::alloc_has_max_size<A>::value,
typename allocator_size_type<A>::type>::type
allocator_max_size(const A&)
allocator_max_size(const A&) BOOST_NOEXCEPT
{
return (std::numeric_limits<typename
allocator_size_type<A>::type>::max)() / sizeof(typename A::value_type);
allocator_size_type<A>::type>::max)() /
sizeof(typename allocator_value_type<A>::type);
}
#endif
namespace detail {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A>
inline A
allocator_select_on_container_copy_construction(const A& a)
{
return a;
}
#else
namespace detail {
class alloc_has_soccc {
template<class O>
static alloc_no<O(O::*)(), &O::select_on_container_copy_construction>
check(int);
template<class O>
static alloc_no<O(O::*)() const, &O::select_on_container_copy_construction>
check(int);
template<class O>
static alloc_no<O(*)(), &O::select_on_container_copy_construction>
check(int);
template<class>
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#else
template<class A>
class alloc_has_soccc {
template<class O>
static auto check(int)
-> decltype(std::declval<O&>().select_on_container_copy_construction());
static auto check(int) -> alloc_no<decltype(std::declval<const
O&>().select_on_container_copy_construction())>;
template<class>
static alloc_none check(long);
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value =
!std::is_same<decltype(check<A>(0)), alloc_none>::value;
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<A>(0)) > 1;
};
#endif
} /* detail */
template<class A>
inline typename std::enable_if<detail::alloc_has_soccc<A>::value, A>::type
inline typename detail::alloc_if<detail::alloc_has_soccc<A>::value, A>::type
allocator_select_on_container_copy_construction(const A& a)
{
return a.select_on_container_copy_construction();
}
template<class A>
inline typename std::enable_if<!detail::alloc_has_soccc<A>::value, A>::type
inline typename detail::alloc_if<!detail::alloc_has_soccc<A>::value, A>::type
allocator_select_on_container_copy_construction(const A& a)
{
return a;
}
#endif
template<class A, class T>
inline void
allocator_destroy_n(A& a, T* p, std::size_t n)
{
while (n > 0) {
boost::allocator_destroy(a, p + --n);
}
}
namespace detail {
template<class A, class T>
class alloc_destroyer {
public:
alloc_destroyer(A& a, T* p) BOOST_NOEXCEPT
: a_(a), p_(p), n_(0) { }
~alloc_destroyer() {
boost::allocator_destroy_n(a_, p_, n_);
}
std::size_t& size() BOOST_NOEXCEPT {
return n_;
}
private:
alloc_destroyer(const alloc_destroyer&);
alloc_destroyer& operator=(const alloc_destroyer&);
A& a_;
T* p_;
std::size_t n_;
};
} /* detail */
template<class A, class T>
inline void
allocator_construct_n(A& a, T* p, std::size_t n)
{
detail::alloc_destroyer<A, T> d(a, p);
for (std::size_t& i = d.size(); i < n; ++i) {
boost::allocator_construct(a, p + i);
}
d.size() = 0;
}
template<class A, class T>
inline void
allocator_construct_n(A& a, T* p, std::size_t n, const T* l, std::size_t m)
{
detail::alloc_destroyer<A, T> d(a, p);
for (std::size_t& i = d.size(); i < n; ++i) {
boost::allocator_construct(a, p + i, l[i % m]);
}
d.size() = 0;
}
template<class A, class T, class I>
inline void
allocator_construct_n(A& a, T* p, std::size_t n, I b)
{
detail::alloc_destroyer<A, T> d(a, p);
for (std::size_t& i = d.size(); i < n; void(++i), void(++b)) {
boost::allocator_construct(a, p + i, *b);
}
d.size() = 0;
}
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class A>

View File

@@ -0,0 +1,112 @@
/*
Copyright 2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_ALLOCATOR_TRAITS_HPP
#define BOOST_CORE_ALLOCATOR_TRAITS_HPP
#include <boost/core/allocator_access.hpp>
namespace boost {
template<class A>
struct allocator_traits {
typedef A allocator_type;
typedef typename allocator_value_type<A>::type value_type;
typedef typename allocator_pointer<A>::type pointer;
typedef typename allocator_const_pointer<A>::type const_pointer;
typedef typename allocator_void_pointer<A>::type void_pointer;
typedef typename allocator_const_void_pointer<A>::type const_void_pointer;
typedef typename allocator_difference_type<A>::type difference_type;
typedef typename allocator_size_type<A>::type size_type;
typedef typename allocator_propagate_on_container_copy_assignment<A>::type
propagate_on_container_copy_assignment;
typedef typename allocator_propagate_on_container_move_assignment<A>::type
propagate_on_container_move_assignment;
typedef typename allocator_propagate_on_container_swap<A>::type
propagate_on_container_swap;
typedef typename allocator_is_always_equal<A>::type is_always_equal;
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class T>
using rebind_traits = allocator_traits<typename
allocator_rebind<A, T>::type>;
#else
template<class T>
struct rebind_traits
: allocator_traits<typename allocator_rebind<A, T>::type> { };
#endif
static pointer allocate(A& a, size_type n) {
return boost::allocator_allocate(a, n);
}
static pointer allocate(A& a, size_type n, const_void_pointer h) {
return boost::allocator_allocate(a, n, h);
}
static void deallocate(A& a, pointer p, size_type n) {
return boost::allocator_deallocate(a, p, n);
}
template<class T>
static void construct(A& a, T* p) {
boost::allocator_construct(a, p);
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class V, class... Args>
static void construct(A& a, T* p, V&& v, Args&&... args) {
boost::allocator_construct(a, p, std::forward<V>(v),
std::forward<Args>(args)...);
}
#else
template<class T, class V>
static void construct(A& a, T* p, V&& v) {
boost::allocator_construct(a, p, std::forward<V>(v));
}
#endif
#else
template<class T, class V>
static void construct(A& a, T* p, const V& v) {
boost::allocator_construct(a, p, v);
}
template<class T, class V>
static void construct(A& a, T* p, V& v) {
boost::allocator_construct(a, p, v);
}
#endif
template<class T>
static void destroy(A& a, T* p) {
boost::allocator_destroy(a, p);
}
static size_type max_size(const A& a) BOOST_NOEXCEPT {
return boost::allocator_max_size(a);
}
static A select_on_container_copy_construction(const A& a) {
return boost::allocator_select_on_container_copy_construction(a);
}
};
} /* boost */
#endif

View File

@@ -22,13 +22,20 @@
#include <cstring>
#if defined(_MSC_VER)
# include <intrin.h>
# pragma intrinsic(_BitScanForward)
# pragma intrinsic(_BitScanReverse)
# if defined(_M_X64)
# pragma intrinsic(_BitScanForward64)
# pragma intrinsic(_BitScanReverse64)
# endif
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4244) // conversion from int to T
#endif // defined(_MSC_VER)
namespace boost
@@ -75,9 +82,9 @@ BOOST_CONSTEXPR inline int countl_impl( unsigned long x ) BOOST_NOEXCEPT
return x? __builtin_clzl( x ): std::numeric_limits<unsigned long>::digits;
}
BOOST_CONSTEXPR inline int countl_impl( unsigned long long x ) BOOST_NOEXCEPT
BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
{
return x? __builtin_clzll( x ): std::numeric_limits<unsigned long long>::digits;
return x? __builtin_clzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
}
} // namespace detail
@@ -164,15 +171,15 @@ int countl_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
if( sizeof(T) == sizeof(boost::uint8_t) )
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
{
return boost::core::detail::countl_impl( static_cast<boost::uint8_t>( x ) );
}
else if( sizeof(T) == sizeof(boost::uint16_t) )
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
{
return boost::core::detail::countl_impl( static_cast<boost::uint16_t>( x ) );
}
else if( sizeof(T) == sizeof(boost::uint32_t) )
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
{
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) );
}
@@ -217,9 +224,9 @@ BOOST_CONSTEXPR inline int countr_impl( unsigned long x ) BOOST_NOEXCEPT
return x? __builtin_ctzl( x ): std::numeric_limits<unsigned long>::digits;
}
BOOST_CONSTEXPR inline int countr_impl( unsigned long long x ) BOOST_NOEXCEPT
BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
{
return x? __builtin_ctzll( x ): std::numeric_limits<unsigned long long>::digits;
return x? __builtin_ctzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
}
} // namespace detail
@@ -299,15 +306,15 @@ int countr_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
if( sizeof(T) == sizeof(boost::uint8_t) )
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
{
return boost::core::detail::countr_impl( static_cast<boost::uint8_t>( x ) );
}
else if( sizeof(T) == sizeof(boost::uint16_t) )
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
{
return boost::core::detail::countr_impl( static_cast<boost::uint16_t>( x ) );
}
else if( sizeof(T) == sizeof(boost::uint32_t) )
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
{
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) );
}
@@ -358,7 +365,7 @@ BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long x ) BOOST_
return __builtin_popcountl( x );
}
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long long x ) BOOST_NOEXCEPT
BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
{
return __builtin_popcountll( x );
}
@@ -403,7 +410,7 @@ BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
if( sizeof(T) <= sizeof(boost::uint32_t) )
BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
{
return boost::core::detail::popcount_impl( static_cast<boost::uint32_t>( x ) );
}
@@ -439,10 +446,13 @@ BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT
return x != 0 && ( x & ( x - 1 ) ) == 0;
}
// bit_width should return int, https://cplusplus.github.io/LWG/issue3656
template<class T>
BOOST_CONSTEXPR T bit_width( T x ) BOOST_NOEXCEPT
{
return std::numeric_limits<T>::digits - boost::core::countl_zero( x );
return static_cast<T>(
std::numeric_limits<T>::digits - boost::core::countl_zero( x ) );
}
template<class T>
@@ -502,7 +512,7 @@ BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
if( sizeof(T) <= sizeof(boost::uint32_t) )
BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
{
return static_cast<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint32_t>( x ) ) );
}
@@ -578,4 +588,8 @@ typedef endian::type endian_type;
} // namespace core
} // namespace boost
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif // #ifndef BOOST_CORE_BIT_HPP_INCLUDED

View File

@@ -12,11 +12,108 @@
// Floating point classification and sign manipulation functions
// Extracted from https://github.com/boostorg/lexical_cast/pull/37
//
// Copyright 2020 Peter Dimov
// Copyright 2020, 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <cmath>
#if defined(BOOST_CORE_USE_GENERIC_CMATH) || (!defined(_MSC_VER) && !defined(FP_SUBNORMAL))
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <limits>
#include <cstring>
namespace boost
{
namespace core
{
// fpclassify return values
int const fp_zero = 0;
int const fp_subnormal = 1;
int const fp_normal = 2;
int const fp_infinite = 3;
int const fp_nan = 4;
// Classification functions
template<class T> bool isfinite( T x )
{
return x <= (std::numeric_limits<T>::max)() && x >= -(std::numeric_limits<T>::max)();
}
template<class T> bool isinf( T x )
{
return x > (std::numeric_limits<T>::max)() || x < -(std::numeric_limits<T>::max)();
}
template<class T> bool isnan( T x )
{
return !isfinite( x ) && !isinf( x );
}
template<class T> bool isnormal( T x )
{
return isfinite( x ) && ( x >= (std::numeric_limits<T>::min)() || x <= -(std::numeric_limits<T>::min)() );
}
template<class T> int fpclassify( T x )
{
if( x == 0 ) return fp_zero;
if( x < 0 ) x = -x;
if( x > (std::numeric_limits<T>::max)() ) return fp_infinite;
if( x >= (std::numeric_limits<T>::min)() ) return fp_normal;
if( x < (std::numeric_limits<T>::min)() ) return fp_subnormal;
return fp_nan;
}
// Sign manipulation functions
inline bool signbit( float x )
{
boost::int32_t y;
BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
std::memcpy( &y, &x, sizeof( y ) );
return y < 0;
}
inline bool signbit( double x )
{
boost::int64_t y;
BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
std::memcpy( &y, &x, sizeof( y ) );
return y < 0;
}
inline bool signbit( long double x )
{
return signbit( static_cast<double>( x ) );
}
template<class T> T copysign( T x, T y )
{
return signbit( x ) == signbit( y )? x: -x;
}
} // namespace core
} // namespace boost
#else // defined(BOOST_CORE_USE_GENERIC_CMATH)
#if defined(_MSC_VER) && _MSC_VER < 1800
# include <float.h>
#endif
@@ -196,4 +293,6 @@ template<class T> T copysign( T x, T y )
} // namespace core
} // namespace boost
#endif // defined(BOOST_CORE_USE_GENERIC_CMATH)
#endif // #ifndef BOOST_CORE_CMATH_HPP_INCLUDED

View File

@@ -19,21 +19,25 @@ BOOST_NORETURN void throw_exception(const std::exception&);
namespace default_ {
struct true_type {
template<bool V>
struct bool_constant {
typedef bool value_type;
typedef true_type type;
typedef bool_constant type;
BOOST_STATIC_CONSTANT(bool, value = true);
static const bool value = V;
BOOST_CONSTEXPR operator bool() const BOOST_NOEXCEPT {
return true;
operator bool() const BOOST_NOEXCEPT {
return V;
}
BOOST_CONSTEXPR bool operator()() const BOOST_NOEXCEPT {
return true;
bool operator()() const BOOST_NOEXCEPT {
return V;
}
};
template<bool V>
const bool bool_constant<V>::value;
template<class T>
struct add_reference {
typedef T& type;
@@ -58,8 +62,8 @@ struct default_allocator {
typedef typename add_reference<const T>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
typedef bool_constant<true> propagate_on_container_move_assignment;
typedef bool_constant<true> is_always_equal;
template<class U>
struct rebind {
@@ -108,6 +112,12 @@ struct default_allocator {
}
#endif
#if defined(BOOST_NO_CXX11_ALLOCATOR)
T* allocate(std::size_t n, const void*) {
return allocate(n);
}
#endif
#if (defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000) || \
defined(BOOST_NO_CXX11_ALLOCATOR)
template<class U, class V>

View File

@@ -34,14 +34,14 @@ public:
boost::uint64_t operator()()
{
x_ += 0x9e3779b97f4a7c15;
x_ += ( boost::uint64_t(0x9e3779b9u) << 32 ) + 0x7f4a7c15u;
boost::uint64_t z = x_;
z ^= z >> 30;
z *= 0xbf58476d1ce4e5b9;
z *= ( boost::uint64_t(0xbf58476du) << 32 ) + 0x1ce4e5b9u;
z ^= z >> 27;
z *= 0x94d049bb133111eb;
z *= ( boost::uint64_t(0x94d049bbu) << 32 ) + 0x133111ebu;
z ^= z >> 31;
return z;

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,11 @@ Distributed under the Boost Software License, Version 1.0.
#endif
#endif
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4510)
#endif
namespace boost {
template<class T>
@@ -143,4 +148,8 @@ BOOST_INLINE_CONSTEXPR empty_init_t empty_init = empty_init_t();
} /* boost */
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif

View File

@@ -11,34 +11,64 @@
namespace boost {
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename... Ts>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts&& ...)
{}
#else
template <typename... Ts>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts const& ...)
{}
#endif
template <typename... Ts>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused()
{}
#else
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename T1>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&)
{}
template <typename T1>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&)
{}
template <typename T1, typename T2>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&)
{}
template <typename T1, typename T2>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&)
{}
template <typename T1, typename T2, typename T3>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&)
{}
template <typename T1, typename T2, typename T3>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&)
{}
template <typename T1, typename T2, typename T3, typename T4>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&, T4&)
{}
template <typename T1, typename T2, typename T3, typename T4>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&)
{}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1&, T2&, T3&, T4&, T5&)
{}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&, T5 const&)
{}

View File

@@ -181,7 +181,13 @@ inline const void* test_output_impl(std::nullptr_t) { return nullptr; }
inline int test_output_impl( signed char const& v ) { return v; }
inline unsigned test_output_impl( unsigned char const& v ) { return v; }
inline unsigned long test_output_impl( wchar_t const& v ) { return v; }
// Whether wchar_t is signed is implementation-defined
template<bool Signed> struct lwt_long_type {};
template<> struct lwt_long_type<true> { typedef long type; };
template<> struct lwt_long_type<false> { typedef unsigned long type; };
inline lwt_long_type<(static_cast<wchar_t>(-1) < static_cast<wchar_t>(0))>::type test_output_impl( wchar_t const& v ) { return v; }
#if !defined( BOOST_NO_CXX11_CHAR16_T )
inline unsigned long test_output_impl( char16_t const& v ) { return v; }

View File

@@ -11,7 +11,7 @@
//
// BOOST_TEST_TRAIT_TRUE, BOOST_TEST_TRAIT_FALSE, BOOST_TEST_TRAIT_SAME
//
// Copyright 2014 Peter Dimov
// Copyright 2014, 2021 Peter Dimov
//
// Copyright 2019 Glen Joseph Fernandes
// (glenjofe@gmail.com)
@@ -21,60 +21,15 @@
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/core/lightweight_test.hpp>
#include <boost/core/typeinfo.hpp>
#include <boost/core/type_name.hpp>
#include <boost/core/is_same.hpp>
#include <boost/config.hpp>
namespace boost
{
namespace detail
{
template<class, int = 0> struct test_print { };
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T, 2>)
{
return o << boost::core::demangled_name(BOOST_CORE_TYPEID(T));
}
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T, 1>)
{
return o << test_print<T, 2>();
}
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<const T, 1>)
{
return o << test_print<T, 2>() << " const";
}
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<volatile T, 1>)
{
return o << test_print<T, 2>() << " volatile";
}
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<const volatile T, 1>)
{
return o << test_print<T, 2>() << " const volatile";
}
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T>)
{
return o << test_print<T, 1>();
}
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T&>)
{
return o << test_print<T, 1>() << " &";
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T&&>)
{
return o << test_print<T, 1>() << " &&";
}
#endif
template< class T > inline void test_trait_impl( char const * trait, void (*)( T ),
bool expected, char const * file, int line, char const * function )
{
@@ -86,7 +41,7 @@ template< class T > inline void test_trait_impl( char const * trait, void (*)( T
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): predicate '" << trait << "' ["
<< boost::core::demangled_name( BOOST_CORE_TYPEID(T) ) << "]"
<< boost::core::type_name<T>() << "]"
<< " test failed in function '" << function
<< "' (should have been " << ( expected? "true": "false" ) << ")"
<< std::endl;
@@ -112,8 +67,8 @@ template<class T1, class T2> inline void test_trait_same_impl( char const * type
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test 'is_same<" << types << ">'"
<< " failed in function '" << function
<< "' ('" << test_print<T1>()
<< "' != '" << test_print<T2>() << "')"
<< "' ('" << boost::core::type_name<T1>()
<< "' != '" << boost::core::type_name<T2>() << "')"
<< std::endl;
++test_results().errors();
@@ -121,7 +76,6 @@ template<class T1, class T2> inline void test_trait_same_impl( char const * type
}
} // namespace detail
} // namespace boost
#define BOOST_TEST_TRAIT_TRUE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, true, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )

View File

@@ -15,6 +15,8 @@ namespace boost {
template<class A>
struct noinit_adaptor
: A {
typedef void _default_construct_destroy;
template<class U>
struct rebind {
typedef noinit_adaptor<typename allocator_rebind<A, U>::type> other;
@@ -56,6 +58,7 @@ struct noinit_adaptor
template<class U>
void destroy(U* p) {
p->~U();
(void)p;
}
};

View File

@@ -27,7 +27,7 @@ namespace noncopyable_ // protection from unintended ADL
// whether a type derives from noncopyable without needing the definition
// of noncopyable itself.
//
// The definition of base_token is macro-guarded so that Type Trais can
// The definition of base_token is macro-guarded so that Type Traits can
// define it locally without including this header, to avoid a dependency
// on Core.

View File

@@ -1,5 +1,5 @@
/*
Copyright 2017-2018 Glen Joseph Fernandes
Copyright 2017-2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -9,43 +9,23 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_CORE_POINTER_TRAITS_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
#include <memory>
#else
#include <boost/core/addressof.hpp>
#include <cstddef>
#endif
namespace boost {
#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
template<class T>
struct pointer_traits
: std::pointer_traits<T> {
template<class U>
struct rebind_to {
typedef typename std::pointer_traits<T>::template rebind<U> type;
};
};
template<class T>
struct pointer_traits<T*>
: std::pointer_traits<T*> {
template<class U>
struct rebind_to {
typedef U* type;
};
};
#else
namespace detail {
struct ptr_none { };
template<class>
struct ptr_void {
struct ptr_valid {
typedef void type;
};
template<class T>
struct ptr_first;
template<class>
struct ptr_first {
typedef ptr_none type;
};
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class, class...> class T, class U, class... Args>
@@ -75,7 +55,7 @@ struct ptr_element {
};
template<class T>
struct ptr_element<T, typename ptr_void<typename T::element_type>::type> {
struct ptr_element<T, typename ptr_valid<typename T::element_type>::type> {
typedef typename T::element_type type;
};
@@ -86,12 +66,12 @@ struct ptr_difference {
template<class T>
struct ptr_difference<T,
typename ptr_void<typename T::difference_type>::type> {
typename ptr_valid<typename T::difference_type>::type> {
typedef typename T::difference_type type;
};
template<class T, class V>
struct ptr_transform;
template<class, class>
struct ptr_transform { };
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class, class...> class T, class U, class... Args, class V>
@@ -117,68 +97,131 @@ struct ptr_transform<T<U1, U2, U3>, V> {
#endif
template<class T, class U, class = void>
struct ptr_rebind {
typedef typename ptr_transform<T, U>::type type;
};
struct ptr_rebind
: ptr_transform<T, U> { };
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class T, class U>
struct ptr_rebind<T, U,
typename ptr_void<typename T::template rebind<U> >::type> {
typename ptr_valid<typename T::template rebind<U> >::type> {
typedef typename T::template rebind<U> type;
};
#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
template<class T, class E>
class ptr_to_expr {
template<class>
struct result {
char x, y;
};
static E& source();
template<class O>
static auto check(int) -> result<decltype(O::pointer_to(source()))>;
template<class>
static char check(long);
public:
BOOST_STATIC_CONSTEXPR bool value = sizeof(check<T>(0)) > 1;
};
template<class T, class E>
struct ptr_to_expr<T*, E> {
BOOST_STATIC_CONSTEXPR bool value = true;
};
template<class T, class E>
struct ptr_has_to {
BOOST_STATIC_CONSTEXPR bool value = ptr_to_expr<T, E>::value;
};
#else
template<class, class>
struct ptr_has_to {
BOOST_STATIC_CONSTEXPR bool value = true;
};
#endif
template<class T>
struct ptr_value {
typedef T type;
struct ptr_has_to<T, void> {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<>
struct ptr_value<void> {
typedef struct { } type;
template<class T>
struct ptr_has_to<T, const void> {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class T>
struct ptr_has_to<T, volatile void> {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class T>
struct ptr_has_to<T, const volatile void> {
BOOST_STATIC_CONSTEXPR bool value = false;
};
template<class T, class E, bool = ptr_has_to<T, E>::value>
struct ptr_to { };
template<class T, class E>
struct ptr_to<T, E, true> {
static T pointer_to(E& v) {
return T::pointer_to(v);
}
};
template<class T>
struct ptr_to<T*, T, true> {
static T* pointer_to(T& v) BOOST_NOEXCEPT {
return boost::addressof(v);
}
};
template<class T, class E>
struct ptr_traits
: ptr_to<T, E> {
typedef T pointer;
typedef E element_type;
typedef typename ptr_difference<T>::type difference_type;
template<class U>
struct rebind_to
: ptr_rebind<T, U> { };
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class U>
using rebind = typename rebind_to<U>::type;
#endif
};
template<class T>
struct ptr_traits<T, ptr_none> { };
} /* detail */
template<class T>
struct pointer_traits {
typedef T pointer;
typedef typename detail::ptr_element<T>::type element_type;
typedef typename detail::ptr_difference<T>::type difference_type;
template<class U>
struct rebind_to {
typedef typename detail::ptr_rebind<T, U>::type type;
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class U>
using rebind = typename detail::ptr_rebind<T, U>::type;
#endif
static pointer
pointer_to(typename detail::ptr_value<element_type>::type& v) {
return pointer::pointer_to(v);
}
};
struct pointer_traits
: detail::ptr_traits<T, typename detail::ptr_element<T>::type> { };
template<class T>
struct pointer_traits<T*> {
struct pointer_traits<T*>
: detail::ptr_to<T*, T> {
typedef T* pointer;
typedef T element_type;
typedef std::ptrdiff_t difference_type;
template<class U>
struct rebind_to {
typedef U* type;
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class U>
using rebind = U*;
using rebind = typename rebind_to<U>::type;
#endif
static T*
pointer_to(typename detail::ptr_value<T>::type& v) BOOST_NOEXCEPT {
return boost::addressof(v);
}
};
#endif
template<class T>
BOOST_CONSTEXPR inline T*

View File

@@ -33,7 +33,7 @@ extern "C" _Noreturn void quick_exit(int);
namespace boost
{
BOOST_NORETURN void quick_exit( int code ) BOOST_NOEXCEPT
BOOST_NORETURN inline void quick_exit( int code ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER) && _MSC_VER < 1900

399
include/boost/core/span.hpp Normal file
View File

@@ -0,0 +1,399 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_SPAN_HPP
#define BOOST_CORE_SPAN_HPP
#include <array>
#include <iterator>
#include <type_traits>
#include <cstddef>
namespace boost {
constexpr std::size_t dynamic_extent = static_cast<std::size_t>(-1);
template<class T, std::size_t E = dynamic_extent>
class span;
namespace detail {
template<class U, class T>
struct span_convertible {
static constexpr bool value = std::is_convertible<U(*)[], T(*)[]>::value;
};
template<std::size_t E, std::size_t N>
struct span_capacity {
static constexpr bool value = E == boost::dynamic_extent || E == N;
};
template<class T, std::size_t E, class U, std::size_t N>
struct span_compatible {
static constexpr bool value = span_capacity<E, N>::value &&
span_convertible<U, T>::value;
};
template<class T>
struct span_uncvref {
typedef typename std::remove_cv<typename
std::remove_reference<T>::type>::type type;
};
template<class>
struct span_is_span {
static constexpr bool value = false;
};
template<class T, std::size_t E>
struct span_is_span<boost::span<T, E> > {
static constexpr bool value = true;
};
template<class T>
struct span_is_array {
static constexpr bool value = false;
};
template<class T, std::size_t N>
struct span_is_array<std::array<T, N> > {
static constexpr bool value = true;
};
template<class, class = void>
struct span_data { };
template<class T>
struct span_data<T,
typename std::enable_if<std::is_pointer<decltype(std::declval<T
&>().data())>::value>::type> {
typedef typename std::remove_pointer<decltype(std::declval<T
&>().data())>::type type;
};
template<class, class, class = void>
struct span_has_data {
static constexpr bool value = false;
};
template<class R, class T>
struct span_has_data<R, T, typename std::enable_if<span_convertible<typename
span_data<R>::type, T>::value>::type> {
static constexpr bool value = true;
};
template<class, class = void>
struct span_has_size {
static constexpr bool value = false;
};
template<class R>
struct span_has_size<R, typename
std::enable_if<std::is_convertible<decltype(std::declval<R&>().size()),
std::size_t>::value>::type> {
static constexpr bool value = true;
};
template<class R, class T>
struct span_is_range {
static constexpr bool value = (std::is_const<T>::value ||
std::is_lvalue_reference<R>::value) &&
!span_is_span<typename span_uncvref<R>::type>::value &&
!span_is_array<typename span_uncvref<R>::type>::value &&
!std::is_array<typename span_uncvref<R>::type>::value &&
span_has_data<R, T>::value &&
span_has_size<R>::value;
};
template<std::size_t E, std::size_t N>
struct span_implicit {
static constexpr bool value = E == boost::dynamic_extent ||
N != boost::dynamic_extent;
};
template<class T, std::size_t E, class U, std::size_t N>
struct span_copyable {
static constexpr bool value = (N == boost::dynamic_extent ||
span_capacity<E, N>::value) && span_convertible<U, T>::value;
};
template<std::size_t E, std::size_t O>
struct span_sub {
static constexpr std::size_t value = E == boost::dynamic_extent ?
boost::dynamic_extent : E - O;
};
template<class T, std::size_t E>
struct span_store {
constexpr span_store(T* p_, std::size_t) noexcept
: p(p_) { }
static constexpr std::size_t n = E;
T* p;
};
template<class T>
struct span_store<T, boost::dynamic_extent> {
constexpr span_store(T* p_, std::size_t n_) noexcept
: p(p_)
, n(n_) { }
T* p;
std::size_t n;
};
template<class T, std::size_t E>
struct span_bytes {
static constexpr std::size_t value = sizeof(T) * E;
};
template<class T>
struct span_bytes<T, boost::dynamic_extent> {
static constexpr std::size_t value = boost::dynamic_extent;
};
} /* detail */
template<class T, std::size_t E>
class span {
public:
typedef T element_type;
typedef typename std::remove_cv<T>::type value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<T*> reverse_iterator;
typedef std::reverse_iterator<const T*> const_reverse_iterator;
static constexpr std::size_t extent = E;
template<std::size_t N = E,
typename std::enable_if<N == dynamic_extent || N == 0, int>::type = 0>
constexpr span() noexcept
: s_(0, 0) { }
template<class I,
typename std::enable_if<E == dynamic_extent &&
detail::span_convertible<I, T>::value, int>::type = 0>
constexpr span(I* f, size_type c)
: s_(f, c) { }
template<class I,
typename std::enable_if<E != dynamic_extent &&
detail::span_convertible<I, T>::value, int>::type = 0>
explicit constexpr span(I* f, size_type c)
: s_(f, c) { }
template<class I, class L,
typename std::enable_if<E == dynamic_extent &&
detail::span_convertible<I, T>::value, int>::type = 0>
constexpr span(I* f, L* l)
: s_(f, l - f) { }
template<class I, class L,
typename std::enable_if<E != dynamic_extent &&
detail::span_convertible<I, T>::value, int>::type = 0>
explicit constexpr span(I* f, L* l)
: s_(f, l - f) { }
template<std::size_t N,
typename std::enable_if<detail::span_capacity<E, N>::value,
int>::type = 0>
constexpr span(typename std::enable_if<true, T>::type (&a)[N]) noexcept
: s_(a, N) { }
template<class U, std::size_t N,
typename std::enable_if<detail::span_compatible<T, E, U, N>::value,
int>::type = 0>
constexpr span(std::array<U, N>& a) noexcept
: s_(a.data(), N) { }
template<class U, std::size_t N,
typename std::enable_if<detail::span_compatible<T, E, const U,
N>::value, int>::type = 0>
constexpr span(const std::array<U, N>& a) noexcept
: s_(a.data(), N) { }
template<class R,
typename std::enable_if<E == dynamic_extent &&
detail::span_is_range<R, T>::value, int>::type = 0>
constexpr span(R&& r) noexcept(noexcept(r.data()) && noexcept(r.size()))
: s_(r.data(), r.size()) { }
template<class R,
typename std::enable_if<E != dynamic_extent &&
detail::span_is_range<R, T>::value, int>::type = 0>
explicit constexpr span(R&& r) noexcept(noexcept(r.data()) &&
noexcept(r.size()))
: s_(r.data(), r.size()) { }
template<class U, std::size_t N,
typename std::enable_if<detail::span_implicit<E, N>::value &&
detail::span_copyable<T, E, U, N>::value, int>::type = 0>
constexpr span(const span<U, N>& s) noexcept
: s_(s.data(), s.size()) { }
template<class U, std::size_t N,
typename std::enable_if<!detail::span_implicit<E, N>::value &&
detail::span_copyable<T, E, U, N>::value, int>::type = 0>
explicit constexpr span(const span<U, N>& s) noexcept
: s_(s.data(), s.size()) { }
template<std::size_t C>
constexpr span<T, C> first() const {
static_assert(C <= E, "Count <= Extent");
return span<T, C>(s_.p, C);
}
template<std::size_t C>
constexpr span<T, C> last() const {
static_assert(C <= E, "Count <= Extent");
return span<T, C>(s_.p + (s_.n - C), C);
}
template<std::size_t O, std::size_t C = dynamic_extent>
constexpr typename std::enable_if<C == dynamic_extent,
span<T, detail::span_sub<E, O>::value> >::type subspan() const {
static_assert(O <= E, "Offset <= Extent");
return span<T, detail::span_sub<E, O>::value>(s_.p + O, s_.n - O);
}
template<std::size_t O, std::size_t C = dynamic_extent>
constexpr typename std::enable_if<C != dynamic_extent,
span<T, C> >::type subspan() const {
static_assert(O <= E && C <= E - O,
"Offset <= Extent && Count <= Extent - Offset");
return span<T, C>(s_.p + O, C);
}
constexpr span<T, dynamic_extent> first(size_type c) const {
return span<T, dynamic_extent>(s_.p, c);
}
constexpr span<T, dynamic_extent> last(size_type c) const {
return span<T, dynamic_extent>(s_.p + (s_.n - c), c);
}
constexpr span<T, dynamic_extent> subspan(size_type o,
size_type c = dynamic_extent) const {
return span<T, dynamic_extent>(s_.p + o,
c == dynamic_extent ? s_.n - o : c);
}
constexpr size_type size() const noexcept {
return s_.n;
}
constexpr size_type size_bytes() const noexcept {
return s_.n * sizeof(T);
}
constexpr bool empty() const noexcept {
return s_.n == 0;
}
constexpr reference operator[](size_type i) const {
return s_.p[i];
}
constexpr reference front() const {
return *s_.p;
}
constexpr reference back() const {
return s_.p[s_.n - 1];
}
constexpr pointer data() const noexcept {
return s_.p;
}
constexpr iterator begin() const noexcept {
return s_.p;
}
constexpr iterator end() const noexcept {
return s_.p + s_.n;
}
constexpr reverse_iterator rbegin() const noexcept {
return reverse_iterator(s_.p + s_.n);
}
constexpr reverse_iterator rend() const noexcept {
return reverse_iterator(s_.p);
}
constexpr const_iterator cbegin() const noexcept {
return s_.p;
}
constexpr const_iterator cend() const noexcept {
return s_.p + s_.n;
}
constexpr const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator(s_.p + s_.n);
}
constexpr const_reverse_iterator crend() const noexcept {
return const_reverse_iterator(s_.p);
}
private:
detail::span_store<T, E> s_;
};
template<class T, std::size_t E>
constexpr std::size_t span<T, E>::extent;
#ifdef __cpp_deduction_guides
template<class I, class L>
span(I*, L) -> span<I>;
template<class T, std::size_t N>
span(T(&)[N]) -> span<T, N>;
template<class T, std::size_t N>
span(std::array<T, N>&) -> span<T, N>;
template<class T, std::size_t N>
span(const std::array<T, N>&) -> span<const T, N>;
template<class R>
span(R&&) -> span<typename detail::span_data<R>::type>;
template<class T, std::size_t E>
span(span<T, E>) -> span<T, E>;
#endif
#ifdef __cpp_lib_byte
template<class T, std::size_t E>
inline span<const std::byte, detail::span_bytes<T, E>::value>
as_bytes(span<T, E> s) noexcept
{
return span<const std::byte, detail::span_bytes<T,
E>::value>(reinterpret_cast<const std::byte*>(s.data()),
s.size_bytes());
}
template<class T, std::size_t E>
inline typename std::enable_if<!std::is_const<T>::value,
span<std::byte, detail::span_bytes<T, E>::value> >::type
as_writable_bytes(span<T, E> s) noexcept
{
return span<std::byte, detail::span_bytes<T,
E>::value>(reinterpret_cast<std::byte*>(s.data()), s.size_bytes());
}
#endif
} /* boost */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,7 @@
#pragma once
#endif
#if (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411)
#if defined(__APPLE__)
#include <Availability.h>
// Apple systems only support std::uncaught_exceptions starting with specific versions:
@@ -34,16 +35,15 @@
// - tvOS >= 10.0
// - watchOS >= 3.0
// https://github.com/boostorg/core/issues/80
#if (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411) && \
( \
(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || \
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) \
)
#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || \
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000)
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
#endif
#else
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
#endif // defined(__APPLE__)
// Visual Studio 14.0 supports N4152 std::uncaught_exceptions() but doesn't define __cpp_lib_uncaught_exceptions
#elif (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411) || \
(defined(_MSC_VER) && _MSC_VER >= 1900)
#elif (defined(_MSC_VER) && _MSC_VER >= 1900)
#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS
#endif

View File

@@ -0,0 +1,88 @@
#ifndef BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
#define BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/demangle.hpp>
#include <boost/throw_exception.hpp>
#include <boost/config.hpp>
#include <exception>
#include <typeinfo>
#include <cstdlib>
#include <cstdio>
namespace boost
{
namespace core
{
BOOST_NORETURN inline void verbose_terminate_handler()
{
std::set_terminate( 0 );
#if defined(BOOST_NO_EXCEPTIONS)
std::fputs( "std::terminate called with exceptions disabled\n", stderr );
#else
try
{
throw;
}
catch( std::exception const& x )
{
#if defined(BOOST_NO_RTTI)
char const * typeid_name = "unknown (RTTI is disabled)";
#else
char const * typeid_name = typeid( x ).name();
boost::core::scoped_demangled_name typeid_demangled_name( typeid_name );
if( typeid_demangled_name.get() != 0 )
{
typeid_name = typeid_demangled_name.get();
}
#endif
boost::source_location loc = boost::get_throw_location( x );
std::fprintf( stderr,
"std::terminate called after throwing an exception:\n\n"
" type: %s\n"
" what(): %s\n"
" location: %s:%lu:%lu in function '%s'\n",
typeid_name,
x.what(),
loc.file_name(), static_cast<unsigned long>( loc.line() ),
static_cast<unsigned long>( loc.column() ), loc.function_name()
);
}
catch( ... )
{
std::fputs( "std::terminate called after throwing an unknown exception\n", stderr );
}
#endif
std::fflush( stdout );
std::abort();
}
} // namespace core
} // namespace boost
#endif // #ifndef BOOST_CORE_VERBOSE_TERMINATE_HANDLER_HPP_INCLUDED

View File

@@ -5,7 +5,9 @@
#ifndef BOOST_ITERATOR_HPP
#define BOOST_ITERATOR_HPP
// This header is obsolete and will be deprecated.
#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED("<iterator>")
#include <iterator>
#include <cstddef> // std::ptrdiff_t

View File

@@ -1,4 +1,4 @@
# Copyright 2018, 2019 Peter Dimov
# Copyright 2018-2021 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
@@ -6,7 +6,26 @@ include(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
if(HAVE_BOOST_TEST)
boost_test_jamfile(FILE Jamfile.v2 LINK_LIBRARIES Boost::core Boost::static_assert Boost::type_traits Boost::throw_exception)
boost_test_jamfile(FILE Jamfile.v2 LINK_LIBRARIES Boost::core Boost::static_assert)
set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::type_traits)
boost_test(TYPE run SOURCES eif_constructors.cpp)
boost_test(TYPE run SOURCES eif_dummy_arg_disambiguation.cpp)
boost_test(TYPE run SOURCES eif_lazy.cpp)
boost_test(TYPE run SOURCES eif_lazy_test.cpp)
boost_test(TYPE run SOURCES eif_member_templates.cpp)
boost_test(TYPE run SOURCES eif_namespace_disambiguation.cpp)
boost_test(TYPE run SOURCES eif_no_disambiguation.cpp)
boost_test(TYPE run SOURCES eif_partial_specializations.cpp)
set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::throw_exception)
boost_test(TYPE run SOURCES no_exceptions_support_test.cpp)
set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::utility)
boost_test(TYPE run SOURCES sv_conversion_test2.cpp)
endif()

View File

@@ -1,6 +1,6 @@
# Boost.Core Library test Jamfile
#
# Copyright (c) 2014, 2017 Peter Dimov
# Copyright (c) 2014-2021 Peter Dimov
#
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at
@@ -9,6 +9,19 @@
import modules ;
import testing ;
project : requirements
<warnings>extra
<toolset>msvc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>gcc-4.4:<cxxflags>-Wno-sign-compare ;
local warning-as-errors-off =
"-<toolset>msvc:<warnings-as-errors>on"
"-<toolset>gcc:<warnings-as-errors>on"
"-<toolset>clang:<warnings-as-errors>on" ;
# quick test (for CI)
run quick.cpp ;
@@ -18,51 +31,64 @@ run addressof_test2.cpp ;
run addressof_np_test.cpp ;
run addressof_fn_test.cpp ;
compile addressof_constexpr_test.cpp ;
compile-fail addressof_fail_rvalue.cpp ;
compile-fail addressof_fail_rvalue.cpp
: $(warning-as-errors-off) ;
run checked_delete_test.cpp ;
compile-fail checked_delete_fail.cpp ;
compile-fail checked_delete_fail2.cpp ;
compile-fail checked_delete_fail.cpp
: $(warning-as-errors-off) ;
compile-fail checked_delete_fail2.cpp
: $(warning-as-errors-off) ;
compile ref_ct_test.cpp ;
run ref_test.cpp ;
run ref_ref_test.cpp ;
run ref_fn_test.cpp ;
compile-fail ref_rv_fail1.cpp ;
compile-fail ref_rv_fail2.cpp ;
compile-fail ref_rv_fail3.cpp ;
compile-fail ref_rv_fail4.cpp ;
compile-fail ref_rv_fail5.cpp ;
compile-fail ref_implicit_fail.cpp ;
compile-fail ref_implicit_fail2.cpp ;
compile-fail ref_implicit_fail3.cpp ;
compile-fail ref_implicit_fail4.cpp ;
compile-fail ref_rv_fail1.cpp
: $(warning-as-errors-off) ;
compile-fail ref_rv_fail2.cpp
: $(warning-as-errors-off) ;
compile-fail ref_rv_fail3.cpp
: $(warning-as-errors-off) ;
compile-fail ref_rv_fail4.cpp
: $(warning-as-errors-off) ;
compile-fail ref_rv_fail5.cpp
: $(warning-as-errors-off) ;
compile-fail ref_implicit_fail.cpp
: $(warning-as-errors-off) ;
compile-fail ref_implicit_fail2.cpp
: $(warning-as-errors-off) ;
compile-fail ref_implicit_fail3.cpp
: $(warning-as-errors-off) ;
compile-fail ref_implicit_fail4.cpp
: $(warning-as-errors-off) ;
run ref_cv_test.cpp ;
run ref_conversion_test.cpp ;
run eif_constructors.cpp ;
run eif_dummy_arg_disambiguation.cpp ;
run eif_lazy.cpp ;
run eif_lazy_test.cpp ;
run eif_member_templates.cpp ;
run eif_namespace_disambiguation.cpp ;
run eif_no_disambiguation.cpp ;
run eif_partial_specializations.cpp ;
run eif_constructors.cpp : ;
run eif_dummy_arg_disambiguation.cpp : ;
run eif_lazy.cpp : ;
run eif_lazy_test.cpp : ;
run eif_member_templates.cpp : ;
run eif_namespace_disambiguation.cpp : ;
run eif_no_disambiguation.cpp : ;
run eif_partial_specializations.cpp : ;
compile-fail noncopyable_compile_fail.cpp ;
compile-fail noncopyable_compile_fail.cpp
: $(warning-as-errors-off) ;
run explicit_operator_bool.cpp ;
run explicit_operator_bool_noexcept.cpp ;
compile-fail explicit_operator_bool_compile_fail_conv_int.cpp ;
compile-fail explicit_operator_bool_compile_fail_conv_pvoid.cpp ;
compile-fail explicit_operator_bool_compile_fail_delete.cpp ;
compile-fail explicit_operator_bool_compile_fail_shift.cpp ;
compile-fail explicit_operator_bool_compile_fail_conv_int.cpp
: $(warning-as-errors-off) ;
compile-fail explicit_operator_bool_compile_fail_conv_pvoid.cpp
: $(warning-as-errors-off) ;
compile-fail explicit_operator_bool_compile_fail_delete.cpp
: $(warning-as-errors-off) ;
compile-fail explicit_operator_bool_compile_fail_shift.cpp
: $(warning-as-errors-off) ;
compile ignore_unused_test.cpp
: <warnings>extra
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on
<toolset>msvc:<warnings-as-errors>on ;
compile ignore_unused_test.cpp ;
run sp_typeinfo_test.cpp ;
run sp_typeinfo_test.cpp : : : <rtti>off : sp_typeinfo_test_no_rtti ;
@@ -96,7 +122,9 @@ run lightweight_test_test4.cpp
: : : $(pedantic-errors) ;
run lightweight_test_test5.cpp
: : : $(pedantic-errors)
<toolset>gcc-4.4.7:<cxxflags>-Wno-sign-compare ;
<toolset>gcc-4.4.7:<cxxflags>-Wno-sign-compare
<toolset>gcc-4.4:<cxxflags>-Wno-sign-compare
;
run lightweight_test_test6.cpp
: : : $(pedantic-errors) ;
@@ -110,9 +138,9 @@ run-fail lightweight_test_fail4.cpp ;
run-fail lightweight_test_fail5.cpp ;
run-fail lightweight_test_fail6.cpp ;
run-fail lightweight_test_fail7.cpp ;
run-fail lightweight_test_fail7.cpp : : : <rtti>off : lightweight_test_fail7_no_rtti ;
run-fail lightweight_test_fail7.cpp : : : <rtti>off <toolset>gcc-4.4:<build>no : lightweight_test_fail7_no_rtti ;
run-fail lightweight_test_fail8.cpp ;
run-fail lightweight_test_fail8.cpp : : : <rtti>off : lightweight_test_fail8_no_rtti ;
run-fail lightweight_test_fail8.cpp : : : <rtti>off <toolset>gcc-4.4:<build>no : lightweight_test_fail8_no_rtti ;
run-fail lightweight_test_fail9.cpp ;
run-fail lightweight_test_fail10.cpp ;
run-fail lightweight_test_fail11.cpp : ;
@@ -149,8 +177,10 @@ run demangled_name_test.cpp
run demangled_name_test.cpp : : : <rtti>off <test-info>always_show_run_output : demangled_name_test_no_rtti ;
run scoped_enum.cpp ;
compile-fail scoped_enum_compile_fail_conv_from_int.cpp ;
compile-fail scoped_enum_compile_fail_conv_to_int.cpp ;
compile-fail scoped_enum_compile_fail_conv_from_int.cpp
: $(warning-as-errors-off) ;
compile-fail scoped_enum_compile_fail_conv_to_int.cpp
: $(warning-as-errors-off) ;
run underlying_type.cpp ;
@@ -159,6 +189,9 @@ run pointer_traits_element_type_test.cpp ;
run pointer_traits_difference_type_test.cpp ;
run pointer_traits_rebind_test.cpp ;
run pointer_traits_pointer_to_test.cpp ;
run pointer_traits_sfinae_test.cpp ;
run pointer_traits_rebind_sfinae_test.cpp ;
run pointer_traits_pointer_to_sfinae_test.cpp ;
run to_address_test.cpp ;
run exchange_test.cpp ;
@@ -181,6 +214,7 @@ run default_allocator_test.cpp
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on ;
run default_allocator_allocate_hint_test.cpp ;
run noinit_adaptor_test.cpp ;
run alloc_construct_test.cpp ;
@@ -206,6 +240,11 @@ run allocator_allocate_hint_test.cpp ;
run allocator_deallocate_test.cpp ;
run allocator_max_size_test.cpp ;
run allocator_soccc_test.cpp ;
run allocator_construct_test.cpp ;
run allocator_destroy_test.cpp ;
run allocator_construct_n_test.cpp ;
run allocator_destroy_n_test.cpp ;
run allocator_traits_test.cpp ;
lib lib_typeid : lib_typeid.cpp : <link>shared:<define>LIB_TYPEID_DYN_LINK=1 ;
@@ -226,21 +265,81 @@ run uncaught_exceptions.cpp
run uncaught_exceptions_np.cpp
: : : <exception-handling>on ;
run no_exceptions_support_test.cpp ;
run no_exceptions_support_test.cpp : ;
run no_exceptions_support_test.cpp : : : <exception-handling>off : no_exceptions_support_test_nx ;
run cmath_test.cpp ;
run cmath_test.cpp
: : : $(pedantic-errors) ;
run cmath_test.cpp : : : <define>BOOST_CORE_USE_GENERIC_CMATH <toolset>msvc-8.0:<build>no : cmath_test_generic ;
run bit_cast_test.cpp ;
run bit_rotate_test.cpp ;
run bit_countr_test.cpp ;
run bit_countl_test.cpp ;
run bit_width_test.cpp ;
run has_single_bit_test.cpp ;
run bit_floor_test.cpp ;
run bit_ceil_test.cpp ;
run bit_popcount_test.cpp ;
run bit_endian_test.cpp ;
run bit_cast_test.cpp
: : : $(pedantic-errors) ;
run bit_rotate_test.cpp
: : : $(pedantic-errors) ;
run bit_countr_test.cpp
: : : $(pedantic-errors) ;
run bit_countl_test.cpp
: : : $(pedantic-errors) ;
run bit_width_test.cpp
: : : $(pedantic-errors) ;
run has_single_bit_test.cpp
: : : $(pedantic-errors) ;
run bit_floor_test.cpp
: : : $(pedantic-errors) ;
run bit_ceil_test.cpp
: : : $(pedantic-errors) ;
run bit_popcount_test.cpp
: : : $(pedantic-errors) ;
run bit_endian_test.cpp
: : : $(pedantic-errors) ;
run type_name_test.cpp ;
run sv_types_test.cpp ;
run sv_construct_test.cpp ;
run sv_iteration_test.cpp ;
run sv_element_access_test.cpp ;
run sv_modifiers_test.cpp ;
run sv_copy_test.cpp ;
run sv_substr_test.cpp ;
run sv_compare_test.cpp ;
run sv_starts_with_test.cpp ;
run sv_ends_with_test.cpp ;
run sv_find_test.cpp ;
run sv_rfind_test.cpp ;
run sv_find_first_of_test.cpp
: : : <toolset>gcc-4.4:<cxxflags>-Wno-type-limits ;
run sv_find_last_of_test.cpp
: : : <toolset>gcc-4.4:<cxxflags>-Wno-type-limits ;
run sv_find_first_not_of_test.cpp
: : : <toolset>gcc-4.4:<cxxflags>-Wno-type-limits ;
run sv_find_last_not_of_test.cpp
: : : <toolset>gcc-4.4:<cxxflags>-Wno-type-limits ;
run sv_contains_test.cpp ;
run sv_eq_test.cpp ;
run sv_lt_test.cpp ;
run sv_stream_insert_test.cpp ;
run sv_conversion_test.cpp ;
run sv_conversion_test2.cpp : ;
run sv_common_reference_test.cpp ;
compile sv_common_reference_test2.cpp ;
compile sv_windows_h_test.cpp ;
run span_test.cpp ;
run span_types_test.cpp ;
run span_constructible_test.cpp ;
run span_deduction_guide_test.cpp ;
run as_bytes_test.cpp ;
run as_writable_bytes_test.cpp ;
compile span_boost_begin_test.cpp ;
run splitmix64_test.cpp
: : : $(pedantic-errors) ;
run-fail verbose_terminate_handler_fail.cpp : ;
run-fail verbose_terminate_handler_fail.cpp : : : <exception-handling>off : verbose_terminate_handler_fail_nx ;
run-fail verbose_terminate_handler_fail.cpp : : : <rtti>off : verbose_terminate_handler_fail_nr ;
run-fail verbose_terminate_handler_fail.cpp : : : <exception-handling>off <rtti>off : verbose_terminate_handler_fail_nxr ;
use-project /boost/core/swap : ./swap ;
build-project ./swap ;

View File

@@ -10,6 +10,10 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/core/alloc_construct.hpp>
#include <boost/core/lightweight_test.hpp>
#if defined(_MSC_VER)
# pragma warning(disable: 4100) // unreferenced parameter 'ptr'
#endif
class type {
public:
explicit type(int x)

View File

@@ -15,20 +15,16 @@ struct A1 {
typedef int* const_pointer;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_const_pointer<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<const int*,
boost::allocator_const_pointer<A2<int> >::type>));
#endif
return boost::report_errors();
}

View File

@@ -20,20 +20,16 @@ struct A1 {
};
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_const_void_pointer<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<const void*,
boost::allocator_const_void_pointer<A2<int> >::type>));
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,47 @@
/*
Copyright 2022 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/core/allocator_access.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T>
struct A {
typedef T value_type;
A() { }
};
int main()
{
{
A<int> a;
int i[3] = { 5, 5, 5 };
boost::allocator_construct_n(a, &i[0], 3);
BOOST_TEST_EQ(i[0], 0);
BOOST_TEST_EQ(i[1], 0);
BOOST_TEST_EQ(i[2], 0);
}
{
A<int> a;
int i[4] = { 5, 5, 5, 5 };
int j[2] = { 1, 2 };
boost::allocator_construct_n(a, &i[0], 4, &j[0], 2);
BOOST_TEST_EQ(i[0], 1);
BOOST_TEST_EQ(i[1], 2);
BOOST_TEST_EQ(i[2], 1);
BOOST_TEST_EQ(i[3], 2);
}
{
A<int> a;
int i[3] = { 5, 5, 5 };
int j[3] = { 1, 2, 3 };
boost::allocator_construct_n(a, &i[0], 3, &j[0]);
BOOST_TEST_EQ(i[0], 1);
BOOST_TEST_EQ(i[1], 2);
BOOST_TEST_EQ(i[2], 3);
}
return boost::report_errors();
}

View File

@@ -36,7 +36,7 @@ int main()
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
{
A1<int> a;
A2<int> a;
int i = 0;
boost::allocator_construct(a, &i, 5);
BOOST_TEST_EQ(i, 6);

View File

@@ -0,0 +1,66 @@
/*
Copyright 2022 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/core/allocator_access.hpp>
#include <boost/core/lightweight_test.hpp>
struct S {
static int count;
S() {
++count;
}
S(const S&) {
++count;
}
~S() {
--count;
}
};
int S::count = 0;
template<class T>
struct A1 {
typedef T value_type;
A1() { }
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
A2() { }
template<class U>
void destroy(U* p) {
*p = U();
}
};
#endif
int main()
{
{
A1<int> a;
S s[3];
boost::allocator_destroy_n(a, &s[0], 3);
BOOST_TEST_EQ(S::count, 0);
::new((void*)&s[0]) S();
::new((void*)&s[1]) S();
::new((void*)&s[2]) S();
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
{
A2<int> a;
int i[3] = { 5, 5, 5 };
boost::allocator_destroy_n(a, &i[0], 3);
BOOST_TEST_EQ(i[0], 0);
BOOST_TEST_EQ(i[1], 0);
BOOST_TEST_EQ(i[2], 0);
}
#endif
return boost::report_errors();
}

View File

@@ -52,7 +52,7 @@ int main()
}
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
{
A1<int> a;
A2<int> a;
int i = 5;
boost::allocator_destroy(a, &i);
BOOST_TEST_EQ(i, 0);

View File

@@ -15,20 +15,16 @@ struct A1 {
typedef short difference_type;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<short,
boost::allocator_difference_type<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<std::ptrdiff_t,
boost::allocator_difference_type<A2<int> >::type>));
#endif
return boost::report_errors();
}

View File

@@ -15,7 +15,6 @@ struct A1 {
int value;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
@@ -24,24 +23,25 @@ struct A2 {
template<class T>
struct A3 {
typedef T value_type;
typedef std::false_type is_always_equal;
struct is_always_equal {
static const bool value = false;
};
};
template<class T>
struct A4 {
typedef T value_type;
typedef std::true_type is_always_equal;
struct is_always_equal {
static const bool value = true;
};
int value;
};
#endif
int main()
{
BOOST_TEST_TRAIT_FALSE((boost::allocator_is_always_equal<A1<int> >::type));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::allocator_is_always_equal<A2<int> >::type));
BOOST_TEST_TRAIT_FALSE((boost::allocator_is_always_equal<A3<int> >::type));
BOOST_TEST_TRAIT_TRUE((boost::allocator_is_always_equal<A4<int> >::type));
#endif
return boost::report_errors();
}

View File

@@ -19,21 +19,17 @@ struct A1 {
}
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
typedef short size_type;
A2() { }
};
#endif
int main()
{
BOOST_TEST_EQ(boost::allocator_max_size(A1<int>()), 1);
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_LE(boost::allocator_max_size(A2<int>()),
(std::numeric_limits<short>::max)());
#endif
return boost::report_errors();
}

View File

@@ -14,21 +14,19 @@ struct A1 {
typedef T value_type;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
typedef std::true_type propagate_on_container_copy_assignment;
struct propagate_on_container_copy_assignment {
static const bool value = true;
};
};
#endif
int main()
{
BOOST_TEST_TRAIT_FALSE((boost::
allocator_propagate_on_container_copy_assignment<A1<int> >::type));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::
allocator_propagate_on_container_copy_assignment<A2<int> >::type));
#endif
return boost::report_errors();
}

View File

@@ -14,21 +14,19 @@ struct A1 {
typedef T value_type;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
typedef std::true_type propagate_on_container_move_assignment;
struct propagate_on_container_move_assignment {
static const bool value = true;
};
};
#endif
int main()
{
BOOST_TEST_TRAIT_FALSE((boost::
allocator_propagate_on_container_move_assignment<A1<int> >::type));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::
allocator_propagate_on_container_move_assignment<A2<int> >::type));
#endif
return boost::report_errors();
}

View File

@@ -14,21 +14,19 @@ struct A1 {
typedef T value_type;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
typedef std::true_type propagate_on_container_swap;
struct propagate_on_container_swap {
static const bool value = true;
};
};
#endif
int main()
{
BOOST_TEST_TRAIT_FALSE((boost::
allocator_propagate_on_container_swap<A1<int> >::type));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::
allocator_propagate_on_container_swap<A2<int> >::type));
#endif
return boost::report_errors();
}

View File

@@ -15,20 +15,16 @@ struct A1 {
typedef int* pointer;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_pointer<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_pointer<A2<int> >::type>));
#endif
return boost::report_errors();
}

View File

@@ -18,20 +18,16 @@ struct A1 {
};
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<A1<int>,
boost::allocator_rebind<A1<char>, bool>::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<A2<int>,
boost::allocator_rebind<A2<char>, int>::type>));
#endif
return boost::report_errors();
}

View File

@@ -16,7 +16,6 @@ struct A1 {
int value;
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
@@ -27,15 +26,12 @@ struct A2 {
}
int value;
};
#endif
int main()
{
BOOST_TEST_EQ(1, boost::
allocator_select_on_container_copy_construction(A1<int>(1)).value);
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_EQ(2, boost::
allocator_select_on_container_copy_construction(A2<int>(1)).value);
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,114 @@
/*
Copyright 2021 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/core/allocator_traits.hpp>
#include <boost/core/lightweight_test_trait.hpp>
template<class T>
class creator {
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;
template<class U>
struct rebind {
typedef creator<U> other;
};
explicit creator(int value) BOOST_NOEXCEPT
: state_(value) { }
template<class U>
creator(const creator<U>& other) BOOST_NOEXCEPT
: state_(other.state) { }
std::size_t max_size() const BOOST_NOEXCEPT {
return static_cast<std::size_t>(-1) / sizeof(T);
}
T* allocate(std::size_t n, const void* = 0) {
return static_cast<T*>(::operator new(sizeof(T) * n));
}
void deallocate(T* p, std::size_t) {
::operator delete(p);
}
int state() const {
return state_;
}
private:
int state_;
};
template<class T, class U>
inline bool operator==(const creator<T>& lhs,
const creator<U>& rhs) BOOST_NOEXCEPT
{
return lhs.state() == rhs.state();
}
template<class T, class U>
inline bool operator!=(const creator<T>& lhs,
const creator<U>& rhs) BOOST_NOEXCEPT
{
return !(lhs == rhs);
}
int main()
{
BOOST_TEST_TRAIT_SAME(creator<int>,
boost::allocator_traits<creator<int> >::allocator_type);
BOOST_TEST_TRAIT_SAME(int,
boost::allocator_traits<creator<int> >::value_type);
BOOST_TEST_TRAIT_SAME(int*,
boost::allocator_traits<creator<int> >::pointer);
BOOST_TEST_TRAIT_SAME(const int*,
boost::allocator_traits<creator<int> >::const_pointer);
BOOST_TEST_TRAIT_SAME(void*,
boost::allocator_traits<creator<int> >::void_pointer);
BOOST_TEST_TRAIT_SAME(const void*,
boost::allocator_traits<creator<int> >::const_void_pointer);
BOOST_TEST_TRAIT_SAME(std::ptrdiff_t,
boost::allocator_traits<creator<int> >::difference_type);
BOOST_TEST_TRAIT_SAME(std::size_t,
boost::allocator_traits<creator<int> >::size_type);
BOOST_TEST_TRAIT_FALSE((boost::allocator_traits<creator<int> >::
propagate_on_container_copy_assignment));
BOOST_TEST_TRAIT_FALSE((boost::allocator_traits<creator<int> >::
propagate_on_container_move_assignment));
BOOST_TEST_TRAIT_FALSE((boost::allocator_traits<creator<int> >::
propagate_on_container_swap));
BOOST_TEST_TRAIT_FALSE((boost::allocator_traits<creator<int> >::
is_always_equal));
BOOST_TEST_TRAIT_SAME(creator<char>,
boost::allocator_traits<creator<int> >::
rebind_traits<char>::allocator_type);
creator<int> a(1);
int* p1 = boost::allocator_traits<creator<int> >::allocate(a, 1);
if (BOOST_TEST(p1)) {
boost::allocator_traits<creator<int> >::construct(a, p1, 5);
BOOST_TEST_EQ(*p1, 5);
boost::allocator_traits<creator<int> >::destroy(a, p1);
boost::allocator_traits<creator<int> >::deallocate(a, p1, 1);
}
int* p2 = boost::allocator_traits<creator<int> >::allocate(a, 1, 0);
if (BOOST_TEST(p2)) {
boost::allocator_traits<creator<int> >::deallocate(a, p2, 1);
}
BOOST_TEST_EQ(boost::allocator_traits<creator<int> >::max_size(a),
static_cast<std::size_t>(-1) / sizeof(int));
BOOST_TEST(boost::allocator_traits<creator<int> >::
select_on_container_copy_construction(a) == a);
return boost::report_errors();
}

View File

@@ -20,20 +20,16 @@ struct A1 {
};
};
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class T>
struct A2 {
typedef T value_type;
};
#endif
int main()
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::allocator_void_pointer<A1<char> >::type>));
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<void*,
boost::allocator_void_pointer<A2<int> >::type>));
#endif
return boost::report_errors();
}

42
test/as_bytes_test.cpp Normal file
View File

@@ -0,0 +1,42 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <cstddef>
#ifdef __cpp_lib_byte
#include <boost/core/span.hpp>
#include <boost/core/lightweight_test.hpp>
void test_dynamic()
{
int a[4];
boost::span<const std::byte> s =
boost::as_bytes(boost::span<int>(&a[0], 4));
BOOST_TEST_EQ(s.data(), reinterpret_cast<const std::byte*>(&a[0]));
BOOST_TEST_EQ(s.size(), sizeof(int) * 4);
}
void test_static()
{
int a[4];
boost::span<const std::byte, sizeof(int) * 4> s =
boost::as_bytes(boost::span<int, 4>(&a[0], 4));
BOOST_TEST_EQ(s.data(), reinterpret_cast<const std::byte*>(&a[0]));
BOOST_TEST_EQ(s.size(), sizeof(int) * 4);
}
int main()
{
test_dynamic();
test_static();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,42 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <cstddef>
#ifdef __cpp_lib_byte
#include <boost/core/span.hpp>
#include <boost/core/lightweight_test.hpp>
void test_dynamic()
{
int a[4];
boost::span<std::byte> s =
boost::as_writable_bytes(boost::span<int>(&a[0], 4));
BOOST_TEST_EQ(s.data(), reinterpret_cast<std::byte*>(&a[0]));
BOOST_TEST_EQ(s.size(), sizeof(int) * 4);
}
void test_static()
{
int a[4];
boost::span<std::byte, sizeof(int) * 4> s =
boost::as_writable_bytes(boost::span<int, 4>(&a[0], 4));
BOOST_TEST_EQ(s.data(), reinterpret_cast<std::byte*>(&a[0]));
BOOST_TEST_EQ(s.size(), sizeof(int) * 4);
}
int main()
{
test_dynamic();
test_static();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -38,14 +38,14 @@ int main()
test_bit_ceil( static_cast<unsigned short>( 0 ) );
test_bit_ceil( static_cast<unsigned int>( 0 ) );
test_bit_ceil( static_cast<unsigned long>( 0 ) );
test_bit_ceil( static_cast<unsigned long long>( 0 ) );
test_bit_ceil( static_cast<boost::ulong_long_type>( 0 ) );
}
{
test_bit_ceil( static_cast<boost::uint8_t>( 0x80 ) );
test_bit_ceil( static_cast<boost::uint16_t>( 0x8000 ) );
test_bit_ceil( static_cast<boost::uint32_t>( 0x80000000 ) );
test_bit_ceil( static_cast<boost::uint64_t>( 0x8000000000000000 ) );
test_bit_ceil( boost::uint64_t( 1 ) << 63 );
}
boost::detail::splitmix64 rng;
@@ -58,7 +58,7 @@ int main()
test_bit_ceil( static_cast<unsigned short>( x ) );
test_bit_ceil( static_cast<unsigned int>( x ) );
test_bit_ceil( static_cast<unsigned long>( x ) );
test_bit_ceil( static_cast<unsigned long long>( x ) );
test_bit_ceil( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -27,7 +27,7 @@ int main()
test_countl( static_cast<unsigned short>( 0 ) );
test_countl( static_cast<unsigned int>( 0 ) );
test_countl( static_cast<unsigned long>( 0 ) );
test_countl( static_cast<unsigned long long>( 0 ) );
test_countl( static_cast<boost::ulong_long_type>( 0 ) );
boost::detail::splitmix64 rng;
@@ -39,7 +39,7 @@ int main()
test_countl( static_cast<unsigned short>( x ) );
test_countl( static_cast<unsigned int>( x ) );
test_countl( static_cast<unsigned long>( x ) );
test_countl( static_cast<unsigned long long>( x ) );
test_countl( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -27,7 +27,7 @@ int main()
test_countr( static_cast<unsigned short>( 0 ) );
test_countr( static_cast<unsigned int>( 0 ) );
test_countr( static_cast<unsigned long>( 0 ) );
test_countr( static_cast<unsigned long long>( 0 ) );
test_countr( static_cast<boost::ulong_long_type>( 0 ) );
boost::detail::splitmix64 rng;
@@ -39,7 +39,7 @@ int main()
test_countr( static_cast<unsigned short>( x ) );
test_countr( static_cast<unsigned int>( x ) );
test_countr( static_cast<unsigned long>( x ) );
test_countr( static_cast<unsigned long long>( x ) );
test_countr( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -9,9 +9,13 @@
#include <boost/cstdint.hpp>
#include <cstring>
#if defined(_MSC_VER)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
int main()
{
boost::uint64_t v = static_cast<boost::uint64_t>( 0x0102030405060708ull );
boost::uint64_t v = ( static_cast<boost::uint64_t>( 0x01020304u ) << 32 ) + 0x05060708u;
if( boost::core::endian::native == boost::core::endian::little )
{

View File

@@ -33,7 +33,7 @@ int main()
test_bit_floor( static_cast<unsigned short>( 0 ) );
test_bit_floor( static_cast<unsigned int>( 0 ) );
test_bit_floor( static_cast<unsigned long>( 0 ) );
test_bit_floor( static_cast<unsigned long long>( 0 ) );
test_bit_floor( static_cast<boost::ulong_long_type>( 0 ) );
}
boost::detail::splitmix64 rng;
@@ -46,7 +46,7 @@ int main()
test_bit_floor( static_cast<unsigned short>( x ) );
test_bit_floor( static_cast<unsigned int>( x ) );
test_bit_floor( static_cast<unsigned long>( x ) );
test_bit_floor( static_cast<unsigned long long>( x ) );
test_bit_floor( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -26,7 +26,7 @@ int main()
test_popcount( static_cast<unsigned short>( 0 ) );
test_popcount( static_cast<unsigned int>( 0 ) );
test_popcount( static_cast<unsigned long>( 0 ) );
test_popcount( static_cast<unsigned long long>( 0 ) );
test_popcount( static_cast<boost::ulong_long_type>( 0 ) );
}
boost::detail::splitmix64 rng;
@@ -39,7 +39,7 @@ int main()
test_popcount( static_cast<unsigned short>( x ) );
test_popcount( static_cast<unsigned int>( x ) );
test_popcount( static_cast<unsigned long>( x ) );
test_popcount( static_cast<unsigned long long>( x ) );
test_popcount( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -103,26 +103,28 @@ int main()
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x44444444 );
}
#define CONST64(x) ((boost::uint64_t(x) << 32) + (x))
{
boost::uint64_t x = 0x1111111111111111;
boost::uint64_t x = CONST64(0x11111111);
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x2222222222222222 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x8888888888888888 );
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), CONST64(0x22222222) );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), CONST64(0x88888888) );
x = 0x2222222222222222;
x = CONST64(0x22222222);
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x4444444444444444 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x1111111111111111 );
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), CONST64(0x44444444) );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), CONST64(0x11111111) );
x = 0x4444444444444444;
x = CONST64(0x44444444);
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x8888888888888888 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x2222222222222222 );
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), CONST64(0x88888888) );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), CONST64(0x22222222) );
x = 0x8888888888888888;
x = CONST64(0x88888888);
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), 0x1111111111111111 );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), 0x4444444444444444 );
BOOST_TEST_EQ( +boost::core::rotl( x, 1 ), CONST64(0x11111111) );
BOOST_TEST_EQ( +boost::core::rotr( x, 1 ), CONST64(0x44444444) );
}
for( int i = -M; i <= M; ++i )
@@ -152,7 +154,7 @@ int main()
}
{
unsigned long long x = 0;
boost::ulong_long_type x = 0;
BOOST_TEST_EQ( boost::core::rotl( x, i ), x );
BOOST_TEST_EQ( boost::core::rotr( x, i ), x );
}
@@ -168,7 +170,7 @@ int main()
test_rotate( static_cast<unsigned short>( x ) );
test_rotate( static_cast<unsigned int>( x ) );
test_rotate( static_cast<unsigned long>( x ) );
test_rotate( static_cast<unsigned long long>( x ) );
test_rotate( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -87,7 +87,7 @@ int main()
test_width( static_cast<unsigned short>( x ) );
test_width( static_cast<unsigned int>( x ) );
test_width( static_cast<unsigned long>( x ) );
test_width( static_cast<unsigned long long>( x ) );
test_width( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -1,4 +1,4 @@
# Copyright 2018, 2019 Peter Dimov
# Copyright 2018, 2019, 2021 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
@@ -9,6 +9,8 @@ project(cmake_subdir_test LANGUAGES CXX)
add_subdirectory(../.. boostorg/core)
add_subdirectory(../../../assert boostorg/assert)
add_subdirectory(../../../config boostorg/config)
add_subdirectory(../../../static_assert boostorg/static_assert)
add_subdirectory(../../../throw_exception boostorg/throw_exception)
add_executable(quick ../quick.cpp)
target_link_libraries(quick Boost::core)

View File

@@ -6,6 +6,8 @@
#include <boost/core/cmath.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <limits>
#include <cfloat>
@@ -63,10 +65,18 @@ template<class T> void test_negative_zero( T x )
BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_zero );
#if defined(BOOST_CORE_USE_GENERIC_CMATH) && BOOST_WORKAROUND(BOOST_GCC, < 40700)
// g++ 4.4, 4.6 fail these tests with optimizations on
#else
BOOST_TEST( boost::core::signbit( x ) );
BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
#endif
}
template<class T> void test_positive_infinity( T x )

View File

@@ -0,0 +1,19 @@
/*
Copyright 2021 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/core/default_allocator.hpp>
#include <boost/core/allocator_access.hpp>
#include <boost/core/lightweight_test.hpp>
int main()
{
boost::default_allocator<int> a;
int* p = boost::allocator_allocate(a, 1, 0);
BOOST_TEST(p != 0);
a.deallocate(p, 1);
return boost::report_errors();
}

View File

@@ -13,6 +13,7 @@
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cstddef>
using boost::enable_if;
using boost::disable_if;
@@ -39,7 +40,7 @@ struct xstring
disable_if<is_arithmetic<It> >::type* = 0)
: data(end-begin) {}
int data;
std::ptrdiff_t data;
};
@@ -58,4 +59,3 @@ int main()
return boost::report_errors();
}

View File

@@ -24,11 +24,11 @@ template <int N> struct dummy {
template<class T>
typename enable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t, dummy<0> = 0) { return true; }
arithmetic_object(T /*t*/, dummy<0> = 0) { return true; }
template<class T>
typename disable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t, dummy<1> = 0) { return false; }
arithmetic_object(T /*t*/, dummy<1> = 0) { return false; }
int main()
@@ -42,4 +42,3 @@ int main()
return boost::report_errors();
}

View File

@@ -60,21 +60,21 @@ namespace A {
template<class T>
typename lazy_enable_if<is_int_or_double<T>, some_traits<T> >::type
foo(T t) { return true; }
foo(T /*t*/) { return true; }
template<class T>
typename lazy_enable_if_c<is_int_or_double<T>::value, some_traits<T> >::type
foo2(T t) { return true; }
foo2(T /*t*/) { return true; }
}
namespace B {
template<class T>
typename lazy_disable_if<is_int_or_double<T>, make_bool<T> >::type
foo(T t) { return false; }
foo(T /*t*/) { return false; }
template<class T>
typename lazy_disable_if_c<is_int_or_double<T>::value, make_bool<T> >::type
foo2(T t) { return false; }
foo2(T /*t*/) { return false; }
}
int main()
@@ -95,4 +95,3 @@ int main()
return boost::report_errors();
}

View File

@@ -26,13 +26,13 @@ template<class T> struct not_
namespace A {
template<class T>
typename enable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t) { return true; }
arithmetic_object(T /*t*/) { return true; }
}
namespace B {
template<class T>
typename enable_if<not_<is_arithmetic<T> >, bool>::type
arithmetic_object(T t) { return false; }
arithmetic_object(T /*t*/) { return false; }
}
int main()
@@ -47,4 +47,3 @@ int main()
return boost::report_errors();
}

View File

@@ -25,11 +25,11 @@ template<class T> struct not_
template<class T>
typename enable_if<is_arithmetic<T>, bool>::type
arithmetic_object(T t) { return true; }
arithmetic_object(T /*t*/) { return true; }
template<class T>
typename enable_if<not_<is_arithmetic<T> >, bool>::type
arithmetic_object(T t) { return false; }
arithmetic_object(T /*t*/) { return false; }
int main()
@@ -43,4 +43,3 @@ int main()
return boost::report_errors();
}

View File

@@ -76,6 +76,11 @@ int main(int, char*[])
BOOST_TEST(noexcept(static_cast< bool >(noexcept_val1)));
BOOST_TEST(noexcept(static_cast< bool >(noexcept_val2)));
(void)val1;
(void)val2;
(void)noexcept_val1;
(void)noexcept_val2;
return boost::report_errors();
}

View File

@@ -8,6 +8,10 @@
// http://www.boost.org/LICENSE_1_0.txt
//
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // std::auto_ptr
#endif
#include <boost/get_pointer.hpp>
#include <boost/core/lightweight_test.hpp>
#include <memory>

View File

@@ -103,7 +103,7 @@ int main()
test_single_bit( static_cast<unsigned short>( x ) );
test_single_bit( static_cast<unsigned int>( x ) );
test_single_bit( static_cast<unsigned long>( x ) );
test_single_bit( static_cast<unsigned long long>( x ) );
test_single_bit( static_cast<boost::ulong_long_type>( x ) );
}
return boost::report_errors();

View File

@@ -8,6 +8,15 @@
// http://www.boost.org/LICENSE_1_0.txt
//
#define BOOST_ALLOW_DEPRECATED_HEADERS
#define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING
#include <boost/config.hpp>
// std::iterator template is deprecated in C++17. Some standard libraries emit warnings
// that cannot be easily suppressed, so disable the tests in C++17 onwards.
#if BOOST_CXX_VERSION < 201703
#include <boost/iterator.hpp>
#include <boost/core/is_same.hpp>
#include <boost/core/lightweight_test_trait.hpp>
@@ -67,3 +76,11 @@ int main()
return boost::report_errors();
}
#else // BOOST_CXX_VERSION < 201703
int main()
{
}
#endif // BOOST_CXX_VERSION < 201703

View File

@@ -8,6 +8,10 @@
// http://www.boost.org/LICENSE_1_0.txt
//
#if defined(__clang__)
# pragma clang diagnostic ignored "-Wstring-plus-int"
#endif
#include <boost/core/lightweight_test.hpp>
int main()

View File

@@ -8,6 +8,10 @@
// http://www.boost.org/LICENSE_1_0.txt
//
#if defined(_MSC_VER)
# pragma warning(disable: 4702) // unreachable code
#endif
#include <boost/core/lightweight_test.hpp>
struct X

View File

@@ -8,6 +8,12 @@
// http://www.boost.org/LICENSE_1_0.txt
//
#if defined(_MSC_VER)
# pragma warning(disable: 4530) // C++ exception handler used
# pragma warning(disable: 4577) // noexcept used without /EHsc
# pragma warning(disable: 4702) // unreachable code
#endif
#include <boost/core/no_exceptions_support.hpp>
#include <boost/core/quick_exit.hpp>
#include <boost/throw_exception.hpp>

View File

@@ -0,0 +1,72 @@
/*
Copyright 2021 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_DECLTYPE_N3276)
#include <boost/core/pointer_traits.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T>
class has_pointer_to {
template<class>
struct result {
char x, y;
};
template<class O>
static auto check(int) -> result<decltype(O::pointer_to)>;
template<class O>
static char check(long);
public:
static const bool value = sizeof(check<T>(0)) > 1;
};
struct P1 { };
struct P2 {
typedef int element_type;
static int* pointer_to(int& value) {
return &value;
}
};
struct P3 {
typedef void element_type;
};
struct P4 {
typedef int element_type;
};
struct P5 {
typedef int element_type;
static int* pointer_to() {
return 0;
}
};
int main()
{
BOOST_TEST((!has_pointer_to<boost::pointer_traits<P1> >::value));
BOOST_TEST(has_pointer_to<boost::pointer_traits<P2> >::value);
BOOST_TEST(!has_pointer_to<boost::pointer_traits<P3> >::value);
BOOST_TEST(!has_pointer_to<boost::pointer_traits<P4> >::value);
BOOST_TEST(!has_pointer_to<boost::pointer_traits<P5> >::value);
BOOST_TEST(has_pointer_to<boost::pointer_traits<int*> >::value);
BOOST_TEST(!has_pointer_to<boost::pointer_traits<void*> >::value);
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,83 @@
/*
Copyright 2021 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_TEMPLATE_ALIASES) && \
(!defined(BOOST_GCC) || (BOOST_GCC >= 40800)) && \
(!defined(BOOST_MSVC) || (BOOST_MSVC >= 1900))
#include <boost/core/pointer_traits.hpp>
#include <boost/core/lightweight_test.hpp>
template<class>
struct valid {
typedef void type;
};
#if !defined(BOOST_GCC) || (BOOST_GCC >= 50000)
template<class, class, class = void>
struct has_rebind {
static const bool value = false;
};
template<class T, class U>
struct has_rebind<T, U,
typename valid<typename T::template rebind<U> >::type> {
static const bool value = true;
};
#else
template<template<class> class T, class U>
using defer = T<U>;
template<class T, class U>
using rebind = defer<T::template rebind, U>;
template<class, class, template<class, class> class = rebind, class = void>
struct has_rebind {
static const bool value = false;
};
template<class T, class U, template<class, class> class R>
struct has_rebind<T, U, R, typename valid<R<T, U> >::type> {
static const bool value = true;
};
#endif
struct P1 { };
struct P2 {
typedef int element_type;
};
struct P3 {
typedef int element_type;
template<class>
struct rebind { };
};
template<class T>
struct S {
typedef T element_type;
};
typedef S<int> P4;
int main()
{
BOOST_TEST((!has_rebind<boost::pointer_traits<P1>, char>::value));
BOOST_TEST((!has_rebind<boost::pointer_traits<P2>, char>::value));
BOOST_TEST((has_rebind<boost::pointer_traits<P3>, char>::value));
BOOST_TEST((has_rebind<boost::pointer_traits<P4>, char>::value));
BOOST_TEST((has_rebind<boost::pointer_traits<int*>, char>::value));
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2017 Glen Joseph Fernandes
Copyright 2017-2022 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -84,15 +84,49 @@ int main()
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<int>,
boost::pointer_traits<P1<const R> >::rebind_to<int>::type>));
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<char*,
boost::pointer_traits<R*>::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<char>,
boost::pointer_traits<P1<R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P2<char, R>,
boost::pointer_traits<P2<R, R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P3<char, R, R>,
boost::pointer_traits<P3<R, R, R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<void*,
boost::pointer_traits<R*>::rebind<void> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<void>,
boost::pointer_traits<P1<R> >::rebind<void> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<R*,
boost::pointer_traits<void*>::rebind<R> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<R>,
boost::pointer_traits<P1<void> >::rebind<R> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<const int*,
boost::pointer_traits<R*>::rebind<const int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<const int>,
boost::pointer_traits<P1<R> >::rebind<const int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<int*,
boost::pointer_traits<const R*>::rebind<int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P1<int>,
boost::pointer_traits<P1<const R> >::rebind<int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind_to<char>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E2<bool, R>,
boost::pointer_traits<E2<R, R> >::rebind_to<char>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E3<bool, R, R>,
boost::pointer_traits<E3<R, R, R> >::rebind_to<char>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E2<bool, R>,
boost::pointer_traits<E2<R, R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E3<bool, R, R>,
boost::pointer_traits<E3<R, R, R> >::rebind<char> >));
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<P<char, R, R, R>,
boost::pointer_traits<P<R, R, R, R> >::rebind<char> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E<bool, R, R, R>,
boost::pointer_traits<E<R, R, R, R> >::rebind_to<char>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E<bool, R, R, R>,
boost::pointer_traits<E<R, R, R, R> >::rebind<char> >));
#endif
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind_to<void>::type>));
@@ -102,6 +136,14 @@ int main()
boost::pointer_traits<E1<R> >::rebind_to<const int>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<const R> >::rebind_to<int>::type>));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind<void> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<void> >::rebind<R> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<R> >::rebind<const int> >));
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<E1<bool>,
boost::pointer_traits<E1<const R> >::rebind<int> >));
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,101 @@
/*
Copyright 2021 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/core/pointer_traits.hpp>
#include <boost/core/lightweight_test.hpp>
template<class>
struct valid {
typedef void type;
};
template<class, class = void>
struct has_pointer {
static const bool value = false;
};
template<class T>
struct has_pointer<T, typename valid<typename T::pointer>::type> {
static const bool value = true;
};
template<class, class = void>
struct has_element_type {
static const bool value = false;
};
template<class T>
struct has_element_type<T, typename valid<typename T::element_type>::type> {
static const bool value = true;
};
template<class, class = void>
struct has_difference_type {
static const bool value = false;
};
template<class T>
struct has_difference_type<T,
typename valid<typename T::difference_type>::type> {
static const bool value = true;
};
template<class, class, class = void>
struct has_rebind_to_type {
static const bool value = false;
};
template<class T, class U>
struct has_rebind_to_type<T, U,
typename valid<typename T::template rebind_to<U>::type>::type> {
static const bool value = true;
};
struct P1 { };
struct P2 {
typedef int element_type;
};
struct P3 {
typedef int element_type;
template<class>
struct rebind { };
};
template<class T>
struct S {
typedef T element_type;
};
typedef S<int> P4;
int main()
{
BOOST_TEST(!has_pointer<boost::pointer_traits<P1> >::value);
BOOST_TEST(!has_element_type<boost::pointer_traits<P1> >::value);
BOOST_TEST(!has_difference_type<boost::pointer_traits<P1> >::value);
BOOST_TEST((!has_rebind_to_type<boost::pointer_traits<P1>, char>::value));
BOOST_TEST(has_pointer<boost::pointer_traits<P2> >::value);
BOOST_TEST(has_element_type<boost::pointer_traits<P2> >::value);
BOOST_TEST(has_difference_type<boost::pointer_traits<P2> >::value);
BOOST_TEST((!has_rebind_to_type<boost::pointer_traits<P2>, char>::value));
BOOST_TEST(has_pointer<boost::pointer_traits<P3> >::value);
BOOST_TEST(has_element_type<boost::pointer_traits<P3> >::value);
BOOST_TEST(has_difference_type<boost::pointer_traits<P3> >::value);
BOOST_TEST((has_rebind_to_type<boost::pointer_traits<P3>, char>::value));
BOOST_TEST(has_pointer<boost::pointer_traits<P4> >::value);
BOOST_TEST(has_element_type<boost::pointer_traits<P4> >::value);
BOOST_TEST(has_difference_type<boost::pointer_traits<P4> >::value);
BOOST_TEST((has_rebind_to_type<boost::pointer_traits<P4>, char>::value));
BOOST_TEST(has_pointer<boost::pointer_traits<int*> >::value);
BOOST_TEST(has_element_type<boost::pointer_traits<int*> >::value);
BOOST_TEST(has_difference_type<boost::pointer_traits<int*> >::value);
BOOST_TEST((has_rebind_to_type<boost::pointer_traits<int*>, char>::value));
return boost::report_errors();
}

View File

@@ -1,4 +1,3 @@
// Test for quick_exit.hpp
//
// Copyright 2018 Peter Dimov
@@ -7,6 +6,9 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER)
# pragma warning(disable: 4702) // unreachable code
#endif
#include <boost/core/quick_exit.hpp>

View File

@@ -1,4 +1,3 @@
// Test for quick_exit.hpp
//
// Copyright 2018 Peter Dimov
@@ -7,6 +6,9 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER)
# pragma warning(disable: 4702) // unreachable code
#endif
#include <boost/core/quick_exit.hpp>

View File

@@ -21,10 +21,16 @@ void ref_test(boost::reference_wrapper<U>)
BOOST_STATIC_ASSERT((boost::core::is_same<T,type>::value));
}
template< typename T >
void assignable_test_(T x1, T x2)
{
x1 = x2;
}
template< typename T >
void assignable_test(T x)
{
x = x;
assignable_test_( x, x );
}
template< bool R, typename T >

View File

@@ -15,6 +15,10 @@
#include <boost/core/scoped_enum.hpp>
#include <boost/core/lightweight_test.hpp>
#if defined(_MSC_VER)
# pragma warning(disable: 4244) // conversion from enum_type to underlying_type
#endif
BOOST_SCOPED_ENUM_DECLARE_BEGIN(namespace_enum1)
{
value0,
@@ -142,6 +146,7 @@ void check_underlying_type()
// The real check for the type is in the underlying_type trait test.
namespace_enum2 enum1 = namespace_enum2::value1;
BOOST_TEST(sizeof(enum1) == sizeof(unsigned char));
(void)enum1;
}
int main(int, char*[])

View File

@@ -0,0 +1,32 @@
/*
Copyright 2022 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_NO_CXX11_DECLTYPE)
#include <boost/core/span.hpp>
#include <vector>
namespace boost {
namespace begin_ {
template<class T>
void begin(T&) { }
} // begin_
using namespace begin_;
} // boost
template class boost::span<float>;
void function()
{
std::vector<int> y;
boost::begin(y);
}
#endif

View File

@@ -0,0 +1,200 @@
/*
Copyright 2019 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_NO_CXX11_DECLTYPE)
#include <boost/core/span.hpp>
#include <boost/core/lightweight_test_trait.hpp>
template<class T>
struct range {
T* data() {
return 0;
}
const T* data() const {
return 0;
}
std::size_t size() const {
return 0;
}
};
struct base { };
struct derived
: base { };
void test_default()
{
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<
boost::span<int> >));
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<
boost::span<int, 0> >));
BOOST_TEST_TRAIT_FALSE((std::is_default_constructible<
boost::span<int, 2> >));
}
void test_data_size()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int>,
int*, std::size_t>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
int*, std::size_t>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
int, std::size_t>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
const int*, std::size_t>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<base>,
derived*, std::size_t>));
}
void test_first_last()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int>,
int*, int*>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int>,
int*, const int*>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
int*, int*>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
int, int*>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
const int*, int*>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<base>,
derived*, derived*>));
}
void test_array()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int>,
int(&)[4]>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int, 4>,
int(&)[4]>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int, 2>,
int(&)[4]>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int, 4>,
int(&)[2]>));
}
void test_std_array()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int>,
std::array<int, 4>&>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
std::array<int, 4>&>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int, 4>,
std::array<int, 4>&>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int,
4>, std::array<int, 4>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
std::array<const int, 4>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<base>,
std::array<derived, 4>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int, 2>,
std::array<int, 4>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int, 4>,
std::array<const int, 4>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<base, 4>,
std::array<derived, 4>&>));
}
void test_const_std_array()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
const std::array<int, 4> >));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int,
4>, const std::array<int, 4> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
const std::array<int, 4> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<const
base>, const std::array<derived, 4> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<const int,
2>, const std::array<int, 4> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int, 4>,
const std::array<int, 4> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<const
base, 4>, const std::array<derived, 4> >));
}
void test_range()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int>,
range<int>&>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
range<int>&>));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
range<int> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
int*>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
range<int> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
const range<int>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<base>,
range<derived>&>));
}
void test_span()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
boost::span<int> >));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int>,
boost::span<int, 4> >));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<int, 4>,
boost::span<int> >));
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int,
4>, boost::span<int, 4> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
boost::span<const int> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<base>,
boost::span<derived> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int, 2>,
boost::span<int, 4> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int, 4>,
boost::span<const int, 4> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<base, 4>,
boost::span<derived, 4> >));
}
void test_copy()
{
BOOST_TEST_TRAIT_TRUE((std::is_copy_constructible<
boost::span<int> >));
BOOST_TEST_TRAIT_TRUE((std::is_copy_constructible<
boost::span<int, 4> >));
}
void test_assign()
{
BOOST_TEST_TRAIT_TRUE((std::is_copy_assignable<
boost::span<int> >));
BOOST_TEST_TRAIT_TRUE((std::is_copy_assignable<
boost::span<int, 4> >));
}
int main()
{
test_default();
test_data_size();
test_first_last();
test_array();
test_std_array();
test_const_std_array();
test_range();
test_span();
test_copy();
test_assign();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,116 @@
/*
Copyright 2019 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifdef __cpp_deduction_guides
#include <boost/core/span.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T>
class range {
public:
T* data() {
return &v_[0];
}
std::size_t size() const {
return 4;
}
private:
T v_[4];
};
void test_data_size()
{
int a[4];
boost::span s(&a[0], 4);
BOOST_TEST_EQ(s.extent, boost::dynamic_extent);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_first_last()
{
int a[4];
boost::span s(&a[0], &a[4]);
BOOST_TEST_EQ(s.extent, boost::dynamic_extent);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_array()
{
int a[4];
boost::span s(a);
BOOST_TEST_EQ(s.extent, 4);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_std_array()
{
std::array<int, 4> a;
boost::span s(a);
BOOST_TEST_EQ(s.extent, 4);
BOOST_TEST_EQ(s.data(), a.data());
BOOST_TEST_EQ(s.size(), a.size());
}
void test_const_std_array()
{
const std::array<int, 4> a = std::array<int, 4>();
boost::span s(a);
BOOST_TEST_EQ(s.extent, 4);
BOOST_TEST_EQ(s.data(), a.data());
BOOST_TEST_EQ(s.size(), a.size());
}
void test_range()
{
range<int> c;
boost::span s(c);
BOOST_TEST_EQ(s.extent, boost::dynamic_extent);
BOOST_TEST_EQ(s.data(), c.data());
BOOST_TEST_EQ(s.size(), c.size());
}
void test_span_dynamic()
{
int a[4];
boost::span s(boost::span<int>(&a[0], 4));
BOOST_TEST_EQ(s.extent, boost::dynamic_extent);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_span_static()
{
int a[4];
boost::span s(boost::span<int, 4>(&a[0], 4));
BOOST_TEST_EQ(s.extent, 4);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
int main()
{
test_data_size();
test_first_last();
test_array();
test_std_array();
test_const_std_array();
test_range();
test_span_dynamic();
test_span_static();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

419
test/span_test.cpp Normal file
View File

@@ -0,0 +1,419 @@
/*
Copyright 2019 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_NO_CXX11_DECLTYPE)
#include <boost/core/span.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T>
class range {
public:
T* data() {
return &v_[0];
}
std::size_t size() const {
return 4;
}
private:
T v_[4];
};
void test_extent()
{
BOOST_TEST_EQ(boost::span<int>::extent,
boost::dynamic_extent);
BOOST_TEST_EQ((boost::span<int, 2>::extent), 2);
}
void test_default_construct_dynamic()
{
boost::span<int> s;
BOOST_TEST_EQ(s.data(), static_cast<int*>(0));
BOOST_TEST_EQ(s.size(), 0);
}
void test_default_construct_static()
{
boost::span<int, 0> s;
BOOST_TEST_EQ(s.data(), static_cast<int*>(0));
BOOST_TEST_EQ(s.size(), 0);
}
void test_construct_data_size()
{
int a[4];
boost::span<int> s(&a[0], 4);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_construct_first_last()
{
int a[4];
boost::span<int> s(&a[0], &a[4]);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_construct_array_dynamic()
{
int a[4];
boost::span<int> s(a);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_construct_array_static()
{
int a[4];
boost::span<int, 4> s(a);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_construct_std_array_dynamic()
{
std::array<int, 4> a;
boost::span<int> s(a);
BOOST_TEST_EQ(s.data(), a.data());
BOOST_TEST_EQ(s.size(), a.size());
}
void test_construct_std_array_static()
{
std::array<int, 4> a;
boost::span<int, 4> s(a);
BOOST_TEST_EQ(s.data(), a.data());
BOOST_TEST_EQ(s.size(), a.size());
}
void test_construct_const_std_array_dynamic()
{
const std::array<int, 4> a = std::array<int, 4>();
boost::span<const int> s(a);
BOOST_TEST_EQ(s.data(), a.data());
BOOST_TEST_EQ(s.size(), a.size());
}
void test_construct_const_std_array_static()
{
const std::array<int, 4> a = std::array<int, 4>();
boost::span<const int, 4> s(a);
BOOST_TEST_EQ(s.data(), a.data());
BOOST_TEST_EQ(s.size(), a.size());
}
void test_construct_range()
{
range<int> c;
boost::span<int> s(c);
BOOST_TEST_EQ(s.data(), c.data());
BOOST_TEST_EQ(s.size(), c.size());
}
void test_construct_span_dynamic()
{
int a[4];
boost::span<const int> s(boost::span<int>(&a[0], 4));
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_construct_span_dynamic_static()
{
int a[4];
boost::span<int> s(boost::span<int, 4>(&a[0], 4));
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_construct_span_static()
{
int a[4];
boost::span<const int, 4> s(boost::span<int, 4>(&a[0], 4));
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_construct_span_static_dynamic()
{
int a[4];
boost::span<int, 4> s(boost::span<int>(&a[0], 4));
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_copy_dynamic()
{
int a[4];
boost::span<int> s1(&a[0], 4);
boost::span<int> s2(s1);
BOOST_TEST_EQ(s2.data(), &a[0]);
BOOST_TEST_EQ(s2.size(), 4);
}
void test_copy_static()
{
int a[4];
boost::span<int, 4> s1(&a[0], 4);
boost::span<int, 4> s2(s1);
BOOST_TEST_EQ(s2.data(), &a[0]);
BOOST_TEST_EQ(s2.size(), 4);
}
void test_assign_dynamic()
{
boost::span<int> s;
int a[4];
s = boost::span<int>(&a[0], 4);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_assign_static()
{
int a1[4];
boost::span<int, 4> s(&a1[0], 4);
int a2[4];
s = boost::span<int, 4>(&a2[0], 4);
BOOST_TEST_EQ(s.data(), &a2[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_first()
{
int a[4];
boost::span<int, 2> s = boost::span<int>(&a[0],
4).first<2>();
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_last()
{
int a[4];
boost::span<int, 2> s = boost::span<int>(&a[0], 4).last<2>();
BOOST_TEST_EQ(s.data(), &a[2]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_subspan_dynamic()
{
int a[4];
boost::span<int> s = boost::span<int>(&a[0], 4).subspan<2>();
BOOST_TEST_EQ(s.data(), &a[2]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_subspan_static()
{
int a[4];
boost::span<int, 2> s = boost::span<int, 4>(&a[0],
4).subspan<2>();
BOOST_TEST_EQ(s.data(), &a[2]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_subspan()
{
int a[4];
boost::span<int, 1> s = boost::span<int>(&a[0],
4).subspan<2, 1>();
BOOST_TEST_EQ(s.data(), &a[2]);
BOOST_TEST_EQ(s.size(), 1);
}
void test_first_size()
{
int a[4];
boost::span<int> s = boost::span<int>(&a[0], 4).first(2);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_last_size()
{
int a[4];
boost::span<int> s = boost::span<int>(&a[0], 4).last(2);
BOOST_TEST_EQ(s.data(), &a[2]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_subspan_range()
{
int a[4];
boost::span<int> s = boost::span<int>(&a[0], 4).subspan(2);
BOOST_TEST_EQ(s.data(), &a[2]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_subspan_range_count()
{
int a[4];
boost::span<int> s = boost::span<int>(&a[0],
4).subspan(2, 1);
BOOST_TEST_EQ(s.data(), &a[2]);
BOOST_TEST_EQ(s.size(), 1);
}
void test_size()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).size()), 4);
}
void test_size_bytes()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).size_bytes()),
4 * sizeof(int));
}
void test_empty_dynamic()
{
int a[4];
BOOST_TEST(boost::span<int>().empty());
BOOST_TEST_NOT((boost::span<int>(&a[0], 4).empty()));
}
void test_empty_static()
{
int a[4];
BOOST_TEST((boost::span<int, 0>().empty()));
BOOST_TEST_NOT((boost::span<int, 4>(&a[0], 4).empty()));
}
void test_index()
{
int a[4] = { 1, 2, 3, 4 };
BOOST_TEST_EQ((boost::span<int>(&a[0], 4)[2]), 3);
}
void test_front()
{
int a[4] = { 1, 2, 3, 4 };
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).front()), 1);
}
void test_back()
{
int a[4] = { 1, 2, 3, 4 };
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).back()), 4);
}
void test_data()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).data()), &a[0]);
}
void test_begin()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).begin()), &a[0]);
}
void test_end()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).end()), &a[4]);
}
void test_rbegin()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).rbegin().base()), &a[4]);
}
void test_rend()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).rend().base()), &a[0]);
}
void test_cbegin()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).cbegin()), &a[0]);
}
void test_cend()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).cend()), &a[4]);
}
void test_crbegin()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).crbegin().base()), &a[4]);
}
void test_crend()
{
int a[4];
BOOST_TEST_EQ((boost::span<int>(&a[0], 4).crend().base()), &a[0]);
}
int main()
{
test_extent();
test_default_construct_dynamic();
test_default_construct_static();
test_construct_data_size();
test_construct_first_last();
test_construct_array_dynamic();
test_construct_array_static();
test_construct_std_array_dynamic();
test_construct_std_array_static();
test_construct_const_std_array_dynamic();
test_construct_const_std_array_static();
test_construct_range();
test_construct_span_dynamic();
test_construct_span_dynamic_static();
test_construct_span_static();
test_construct_span_static_dynamic();
test_copy_dynamic();
test_copy_static();
test_assign_dynamic();
test_assign_static();
test_first();
test_last();
test_subspan_dynamic();
test_subspan_static();
test_subspan();
test_first_size();
test_last_size();
test_subspan_range();
test_subspan_range_count();
test_size();
test_size_bytes();
test_empty_dynamic();
test_empty_static();
test_index();
test_front();
test_back();
test_data();
test_begin();
test_end();
test_rbegin();
test_rend();
test_cbegin();
test_cend();
test_crbegin();
test_crend();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

136
test/span_types_test.cpp Normal file
View File

@@ -0,0 +1,136 @@
/*
Copyright 2019 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_NO_CXX11_DECLTYPE)
#include <boost/core/span.hpp>
#include <boost/core/lightweight_test_trait.hpp>
void test_element_type()
{
BOOST_TEST_TRAIT_SAME(int,
boost::span<int>::element_type);
BOOST_TEST_TRAIT_SAME(char,
boost::span<char>::element_type);
}
void test_value_type()
{
BOOST_TEST_TRAIT_SAME(char,
boost::span<char>::value_type);
BOOST_TEST_TRAIT_SAME(int,
boost::span<int>::value_type);
BOOST_TEST_TRAIT_SAME(int,
boost::span<const int>::value_type);
BOOST_TEST_TRAIT_SAME(int,
boost::span<volatile int>::value_type);
BOOST_TEST_TRAIT_SAME(int,
boost::span<const volatile int>::value_type);
}
void test_size_type()
{
BOOST_TEST_TRAIT_SAME(std::size_t,
boost::span<char>::size_type);
BOOST_TEST_TRAIT_SAME(std::size_t,
boost::span<int>::size_type);
}
void test_difference_type()
{
BOOST_TEST_TRAIT_SAME(std::ptrdiff_t,
boost::span<char>::difference_type);
BOOST_TEST_TRAIT_SAME(std::ptrdiff_t,
boost::span<int>::difference_type);
}
void test_pointer()
{
BOOST_TEST_TRAIT_SAME(char*,
boost::span<char>::pointer);
BOOST_TEST_TRAIT_SAME(int*,
boost::span<int>::pointer);
}
void test_const_pointer()
{
BOOST_TEST_TRAIT_SAME(const char*,
boost::span<char>::const_pointer);
BOOST_TEST_TRAIT_SAME(const int*,
boost::span<int>::const_pointer);
}
void test_reference()
{
BOOST_TEST_TRAIT_SAME(char&,
boost::span<char>::reference);
BOOST_TEST_TRAIT_SAME(int&,
boost::span<int>::reference);
}
void test_const_reference()
{
BOOST_TEST_TRAIT_SAME(const char&,
boost::span<char>::const_reference);
BOOST_TEST_TRAIT_SAME(const int&,
boost::span<int>::const_reference);
}
void test_iterator()
{
BOOST_TEST_TRAIT_SAME(char*,
boost::span<char>::iterator);
BOOST_TEST_TRAIT_SAME(int*,
boost::span<int>::iterator);
}
void test_const_iterator()
{
BOOST_TEST_TRAIT_SAME(const char*,
boost::span<char>::const_iterator);
BOOST_TEST_TRAIT_SAME(const int*,
boost::span<int>::const_iterator);
}
void test_reverse_iterator()
{
BOOST_TEST_TRAIT_SAME(std::reverse_iterator<char*>,
boost::span<char>::reverse_iterator);
BOOST_TEST_TRAIT_SAME(std::reverse_iterator<int*>,
boost::span<int>::reverse_iterator);
}
void test_const_reverse_iterator()
{
BOOST_TEST_TRAIT_SAME(std::reverse_iterator<const char*>,
boost::span<char>::const_reverse_iterator);
BOOST_TEST_TRAIT_SAME(std::reverse_iterator<const int*>,
boost::span<int>::const_reverse_iterator);
}
int main()
{
test_element_type();
test_value_type();
test_size_type();
test_difference_type();
test_pointer();
test_const_pointer();
test_reference();
test_const_reference();
test_iterator();
test_const_iterator();
test_reverse_iterator();
test_const_reverse_iterator();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

38
test/splitmix64_test.cpp Normal file
View File

@@ -0,0 +1,38 @@
// Test for boost/core/detail/splitmix64.hpp
//
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/splitmix64.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/cstdint.hpp>
int main()
{
{
boost::detail::splitmix64 rng;
boost::uint64_t r1 = rng(), x1 = ( boost::uint64_t(0xe220a839u) << 32 ) + 0x7b1dcdafu;
BOOST_TEST_EQ( r1, x1 );
for( int i = 0; i < 1000; ++i ) rng();
boost::uint64_t r2 = rng(), x2 = ( boost::uint64_t(0xdcad513cu) << 32 ) + 0x211f942du;
BOOST_TEST_EQ( r2, x2 );
}
{
boost::detail::splitmix64 rng( 12345 );
boost::uint64_t r1 = rng(), x1 = ( boost::uint64_t(0x22118258u) << 32 ) + 0xa9d111a0u;
BOOST_TEST_EQ( r1, x1 );
for( int i = 0; i < 1000; ++i ) rng();
boost::uint64_t r2 = rng(), x2 = ( boost::uint64_t(0xaaefb4b6u) << 32 ) + 0x5c15e958u;
BOOST_TEST_EQ( r2, x2 );
}
return boost::report_errors();
}

View File

@@ -0,0 +1,34 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/string_view.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/config/pragma_message.hpp>
#include <boost/config.hpp>
#include <string>
#if defined(BOOST_NO_CXX20_HDR_CONCEPTS)
BOOST_PRAGMA_MESSAGE( "Skipping test because BOOST_NO_CXX20_HDR_CONCEPTS is defined" )
int main() {}
#else
#include <concepts>
#include <type_traits>
using T = std::common_reference_t< boost::core::string_view&&, std::string& >;
static_assert( std::common_reference_with< boost::core::string_view&&, std::string& > );
static_assert( std::common_reference_with< boost::core::wstring_view&&, std::wstring const& > );
int main()
{
BOOST_TEST_TRAIT_SAME( std::common_reference_t< boost::core::string_view&&, std::string& >, boost::core::string_view );
BOOST_TEST_TRAIT_SAME( std::common_reference_t< boost::core::wstring_view&&, std::wstring const& >, boost::core::wstring_view );
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,24 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/string_view.hpp>
#include <boost/config/pragma_message.hpp>
#include <string>
#include <iterator>
#if !defined(__cpp_lib_ranges)
BOOST_PRAGMA_MESSAGE( "Skipping test because __cpp_lib_ranges is not defined" )
#else
struct Iterator
{
using value_type = std::string;
boost::core::string_view operator*() const noexcept;
};
static_assert( std::indirectly_readable<Iterator> );
#endif

145
test/sv_compare_test.cpp Normal file
View File

@@ -0,0 +1,145 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/string_view.hpp>
#include <boost/core/lightweight_test.hpp>
#include <stdexcept>
#include <cstddef>
int main()
{
std::size_t const npos = boost::core::string_view::npos;
{
boost::core::string_view sv1( "" );
boost::core::string_view sv2( "" );
BOOST_TEST_EQ( sv1.compare( sv2 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 0, sv2 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 1, sv2 ), 0 );
BOOST_TEST_THROWS( sv1.compare( 1, 0, sv2 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 1, 1, sv2 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 1, npos, sv2 ), std::out_of_range );
BOOST_TEST_EQ( sv1.compare( 0, 0, sv2, 0, 0 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 1, sv2, 0, 1 ), 0 );
BOOST_TEST_THROWS( sv1.compare( 1, 0, sv2, 0, 0 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 1, 1, sv2, 0, 1 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 0, 0, sv2, 1, 0 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 0, 1, sv2, 1, 1 ), std::out_of_range );
BOOST_TEST_EQ( sv1.compare( "" ), 0 );
BOOST_TEST_LT( sv1.compare( "1" ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 0, "" ), 0 );
BOOST_TEST_LT( sv1.compare( 0, 0, "1" ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 1, "" ), 0 );
BOOST_TEST_LT( sv1.compare( 0, 1, "1" ), 0 );
BOOST_TEST_THROWS( sv1.compare( 1, 0, "" ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 1, 1, "1" ), std::out_of_range );
BOOST_TEST_EQ( sv1.compare( 0, 0, "", 0 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 0, "1", 0 ), 0 );
BOOST_TEST_LT( sv1.compare( 0, 0, "1", 1 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 1, "", 0 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 1, "1", 0 ), 0 );
BOOST_TEST_LT( sv1.compare( 0, 1, "1", 1 ), 0 );
BOOST_TEST_THROWS( sv1.compare( 1, 0, "", 0 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 1, 1, "1", 0 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 1, 1, "1", 1 ), std::out_of_range );
}
{
boost::core::string_view sv1( "123412345" );
boost::core::string_view sv2( "1234" );
BOOST_TEST_GT( sv1.compare( sv2 ), 0 );
BOOST_TEST_LT( sv1.compare( 0, 3, sv2 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 4, sv2 ), 0 );
BOOST_TEST_GT( sv1.compare( 0, 5, sv2 ), 0 );
BOOST_TEST_GT( sv1.compare( 0, npos, sv2 ), 0 );
BOOST_TEST_LT( sv1.compare( 1, 0, sv2 ), 0 );
BOOST_TEST_GT( sv1.compare( 1, 1, sv2 ), 0 );
BOOST_TEST_LT( sv1.compare( 4, 3, sv2 ), 0 );
BOOST_TEST_EQ( sv1.compare( 4, 4, sv2 ), 0 );
BOOST_TEST_GT( sv1.compare( 4, 5, sv2 ), 0 );
BOOST_TEST_LT( sv1.compare( 9, 0, sv2 ), 0 );
BOOST_TEST_LT( sv1.compare( 9, 1, sv2 ), 0 );
BOOST_TEST_THROWS( sv1.compare( 10, 0, sv2 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 10, 1, sv2 ), std::out_of_range );
BOOST_TEST_GT( sv1.compare( 0, 3, sv2, 0, 2 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 3, sv2, 0, 3 ), 0 );
BOOST_TEST_LT( sv1.compare( 0, 3, sv2, 0, 4 ), 0 );
BOOST_TEST_LT( sv1.compare( 0, 3, sv2, 0, 5 ), 0 );
BOOST_TEST_GT( sv1.compare( 0, 4, sv2, 0, 3 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 4, sv2, 0, 4 ), 0 );
BOOST_TEST_EQ( sv1.compare( 0, 4, sv2, 0, 5 ), 0 );
BOOST_TEST_LT( sv1.compare( 5, 2, sv2, 1, npos ), 0 );
BOOST_TEST_EQ( sv1.compare( 5, 3, sv2, 1, npos ), 0 );
BOOST_TEST_GT( sv1.compare( 5, 4, sv2, 1, npos ), 0 );
BOOST_TEST_EQ( sv1.compare( 9, 0, sv2, 0, 0 ), 0 );
BOOST_TEST_LT( sv1.compare( 9, 1, sv2, 0, 1 ), 0 );
BOOST_TEST_THROWS( sv1.compare( 10, 0, sv2, 0, 0 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 10, 1, sv2, 0, 1 ), std::out_of_range );
BOOST_TEST_EQ( sv1.compare( 0, 0, sv2, 4, 0 ), 0 );
BOOST_TEST_GT( sv1.compare( 0, 1, sv2, 4, 1 ), 0 );
BOOST_TEST_THROWS( sv1.compare( 0, 0, sv2, 5, 0 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 0, 1, sv2, 5, 1 ), std::out_of_range );
BOOST_TEST_GT( sv1.compare( "" ), 0 );
BOOST_TEST_GT( sv1.compare( "12341234" ), 0 );
BOOST_TEST_GT( sv1.compare( "123412344" ), 0 );
BOOST_TEST_EQ( sv1.compare( "123412345" ), 0 );
BOOST_TEST_LT( sv1.compare( "123412346" ), 0 );
BOOST_TEST_LT( sv1.compare( "1234123456" ), 0 );
BOOST_TEST_GT( sv1.compare( 4, 3, "" ), 0 );
BOOST_TEST_GT( sv1.compare( 4, 3, "1" ), 0 );
BOOST_TEST_GT( sv1.compare( 4, 3, "12" ), 0 );
BOOST_TEST_GT( sv1.compare( 4, 3, "122" ), 0 );
BOOST_TEST_EQ( sv1.compare( 4, 3, "123" ), 0 );
BOOST_TEST_LT( sv1.compare( 4, 3, "124" ), 0 );
BOOST_TEST_LT( sv1.compare( 4, 3, "1234" ), 0 );
BOOST_TEST_EQ( sv1.compare( 9, 0, "" ), 0 );
BOOST_TEST_LT( sv1.compare( 9, 1, "1" ), 0 );
BOOST_TEST_THROWS( sv1.compare( 10, 0, "" ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 10, 1, "1" ), std::out_of_range );
BOOST_TEST_GT( sv1.compare( 4, npos, "123456", 4 ), 0 );
BOOST_TEST_EQ( sv1.compare( 4, npos, "123456", 5 ), 0 );
BOOST_TEST_LT( sv1.compare( 4, npos, "123456", 6 ), 0 );
BOOST_TEST_EQ( sv1.compare( 9, npos, "", 0 ), 0 );
BOOST_TEST_EQ( sv1.compare( 9, npos, "1", 0 ), 0 );
BOOST_TEST_LT( sv1.compare( 9, npos, "1", 1 ), 0 );
BOOST_TEST_THROWS( sv1.compare( 10, npos, "", 0 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 10, npos, "1", 0 ), std::out_of_range );
BOOST_TEST_THROWS( sv1.compare( 10, npos, "1", 1 ), std::out_of_range );
}
return boost::report_errors();
}

346
test/sv_construct_test.cpp Normal file
View File

@@ -0,0 +1,346 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/string_view.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iterator>
#include <string>
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
# include <string_view>
#endif
#if !defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
# include <memory_resource>
#endif
template<class It> std::reverse_iterator<It> make_reverse_iterator( It it )
{
return std::reverse_iterator<It>( it );
}
int main()
{
{
boost::core::string_view sv;
BOOST_TEST_EQ( sv.data(), static_cast<char const*>(0) );
BOOST_TEST_EQ( sv.size(), 0 );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
}
{
char const* s = "";
boost::core::string_view sv( s );
BOOST_TEST_EQ( sv.data(), s );
BOOST_TEST_EQ( sv.size(), 0 );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
if( !sv.empty() )
{
BOOST_TEST_EQ( &sv.front(), sv.data() );
BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 );
}
}
{
char const* s = "123";
boost::core::string_view sv( s );
BOOST_TEST_EQ( sv.data(), s );
BOOST_TEST_EQ( sv.size(), 3 );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
if( !sv.empty() )
{
BOOST_TEST_EQ( &sv.front(), sv.data() );
BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 );
}
}
{
char const* s = "123";
boost::core::string_view sv( s, 0 );
BOOST_TEST_EQ( sv.data(), s );
BOOST_TEST_EQ( sv.size(), 0 );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
if( !sv.empty() )
{
BOOST_TEST_EQ( &sv.front(), sv.data() );
BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 );
}
}
{
char const* s = "123";
boost::core::string_view sv( s, 2 );
BOOST_TEST_EQ( sv.data(), s );
BOOST_TEST_EQ( sv.size(), 2 );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
if( !sv.empty() )
{
BOOST_TEST_EQ( &sv.front(), sv.data() );
BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 );
}
}
{
char const* s = "123";
boost::core::string_view sv( s, s );
BOOST_TEST_EQ( sv.data(), s );
BOOST_TEST_EQ( sv.size(), 0 );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
if( !sv.empty() )
{
BOOST_TEST_EQ( &sv.front(), sv.data() );
BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 );
}
}
{
char const* s = "123";
boost::core::string_view sv( s, s + 2 );
BOOST_TEST_EQ( sv.data(), s );
BOOST_TEST_EQ( sv.size(), 2 );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
if( !sv.empty() )
{
BOOST_TEST_EQ( &sv.front(), sv.data() );
BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 );
}
}
{
std::string str = "123";
boost::core::string_view sv( str );
BOOST_TEST_EQ( sv.data(), str.data() );
BOOST_TEST_EQ( sv.size(), str.size() );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
if( !sv.empty() )
{
BOOST_TEST_EQ( &sv.front(), sv.data() );
BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 );
}
}
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
{
std::string_view str = "123";
boost::core::string_view sv( str );
BOOST_TEST_EQ( sv.data(), str.data() );
BOOST_TEST_EQ( sv.size(), str.size() );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
if( !sv.empty() )
{
BOOST_TEST_EQ( &sv.front(), sv.data() );
BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 );
}
}
#endif
#if !defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
{
using pmr_string = std::basic_string<char, std::char_traits<char>, std::pmr::polymorphic_allocator<char>>;
pmr_string str = "123";
boost::core::string_view sv( str );
BOOST_TEST_EQ( sv.data(), str.data() );
BOOST_TEST_EQ( sv.size(), str.size() );
BOOST_TEST_EQ( sv.begin(), sv.data() );
BOOST_TEST_EQ( sv.end(), sv.data() + sv.size() );
BOOST_TEST_EQ( sv.cbegin(), sv.data() );
BOOST_TEST_EQ( sv.cend(), sv.data() + sv.size() );
BOOST_TEST( sv.rbegin() == ::make_reverse_iterator( sv.end() ) );
BOOST_TEST( sv.rend() == ::make_reverse_iterator( sv.begin() ) );
BOOST_TEST( sv.crbegin() == ::make_reverse_iterator( sv.cend() ) );
BOOST_TEST( sv.crend() == ::make_reverse_iterator( sv.cbegin() ) );
BOOST_TEST_EQ( sv.length(), sv.size() );
BOOST_TEST_EQ( sv.empty(), sv.size() == 0 );
BOOST_TEST_EQ( sv.max_size(), boost::core::string_view::npos );
if( !sv.empty() )
{
BOOST_TEST_EQ( &sv.front(), sv.data() );
BOOST_TEST_EQ( &sv.back(), sv.data() + sv.size() - 1 );
}
}
#endif
return boost::report_errors();
}

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