Compare commits

...

125 Commits

Author SHA1 Message Date
Andrey Semashev a90a31934f Remove dependencies on Boost.StaticAssert.
Boost.StaticAssert has been merged into Boost.Config, so replace
the dependency accordingly.
2026-01-22 15:21:40 +03:00
Peter Dimov f3cae495d3 Document is_placeholder 2026-01-02 13:40:47 +02:00
Peter Dimov 8c338d5a65 Add boost/is_placeholder.hpp (moved from Bind) 2026-01-02 13:22:31 +02:00
Peter Dimov 89b242e540 Add VS2026 to Drone 2025-12-25 16:31:01 +02:00
Peter Dimov c4e5a6541f Add a test_output_impl overload for char8_t 2025-12-25 15:05:02 +02:00
Peter Dimov abb1b9ce5b Add char8_t tests to lightweight_test_test6 2025-12-25 14:57:51 +02:00
Peter Dimov a35b0620a9 Update .drone.jsonnet 2025-12-21 20:13:06 +02:00
Peter Dimov f3cd3afb69 Specialize output for all pointer types; fixes EQ w/ wchar_t* et al 2025-12-21 19:02:50 +02:00
Peter Dimov 378dc90a73 Add lightweight_test_eq_ptr; tests EQ and NE with various pointer types. 2025-12-21 18:46:12 +02:00
Peter Dimov cc765abfc6 Split clang-win job in appveyor.yml to avoid timeout 2025-12-14 22:45:57 +02:00
Peter Dimov b7fdbf41a7 Add benchmark/sv_find_first_of.cpp, sv_find_first_not_of.cpp 2025-12-14 21:41:12 +02:00
Peter Dimov 5bea3b85e6 Add macos-26, clang-21 to ci.yml 2025-12-14 20:56:55 +02:00
Andrey Semashev b0bae8a8ae Removed macos-13 from GitHub Actions.
The macos-13 image is retierd.

Also, clang on macos-15 supports C++23.
2025-12-13 20:35:43 +03:00
Andrey Semashev 99d550a5e4 Mention that null_deleter can be useful when the object doesn't need to be deallocated. 2025-12-08 14:18:15 +03:00
Peter Dimov 239953da9f Remove Clang 3.5, 3.6 from GHA 2025-10-27 02:24:45 +02:00
Peter Dimov 52831a4fd9 Remove VS2017 Clang from Appveyor 2025-10-26 20:51:36 +02:00
Glen Fernandes b852430614 Update formatting to be consistent with rest of span 2025-10-25 14:55:53 -04:00
Peter Dimov ed46bfacff Merge pull request #203 from ashtum/develop
detail::span_convertible handles void types
2025-10-24 11:36:04 +03:00
Peter Dimov 174013e3a7 Delete documentation of static_assert.hpp 2025-10-24 02:59:05 +03:00
Peter Dimov 67aaac82d8 Move boost/core/static_assert.hpp to boost/core/detail 2025-10-24 02:57:49 +03:00
Peter Dimov b700f98b4e Cosmetic grammar change in README 2025-10-22 10:34:22 +03:00
Peter Dimov db8b59139b Fix links in README 2025-10-22 10:29:46 +03:00
Peter Dimov 46c5576508 Update documentation and README to reflect removal of StaticAssert dependency 2025-10-22 10:21:18 +03:00
Peter Dimov 4fadb5319a Document BOOST_CORE_STATIC_ASSERT 2025-10-21 18:32:48 +03:00
Peter Dimov 87b410ddfa Remove static_assert from dependencies 2025-10-21 15:45:50 +03:00
Peter Dimov a330736438 Use a local C++03 implementation of BOOST_CORE_STATIC_ASSERT 2025-10-21 02:32:00 +03:00
Peter Dimov aaff2c0d54 Add tests for BOOST_CORE_STATIC_ASSERT 2025-10-21 02:32:00 +03:00
Peter Dimov 82a16ccc95 Add boost/core/static_assert.hpp; change bit.hpp and cmath.hpp to use it 2025-10-21 02:32:00 +03:00
Peter Dimov 7b2c714b55 Disable warning 4127 under msvc-12.0 and earlier 2025-10-20 20:58:49 +03:00
Peter Dimov 4777321ff2 Revert "Omit do {} while (false) for MSVC versions prior to 2015"
This reverts commit 40fda50ae1.
2025-10-20 20:27:17 +03:00
Peter Dimov d5a57eb725 Increase timeout in ci.yml for macos-13 2025-10-20 06:11:34 +03:00
Peter Dimov fb34afaabd Correct CMake version check; VERSION_GREATER 3.18 is true for 3.18.1 2025-10-20 02:10:33 +03:00
Andrey Semashev e8fdc407bd Added a changelog entry for the lightweight_test.hpp change.
Refs https://github.com/boostorg/core/pull/205.
2025-10-19 22:14:36 +03:00
Andrey Semashev 64093058de Added a changelog entry for the boost::data/size change. 2025-10-19 22:08:39 +03:00
Andrey Semashev 3cd29323be Add a test for boost::span verifying unqualified calls to data()/size().
The test checks that unqualified calls to data()/size() with boost::span
as argument don't cause ambiguity between std:: and boost:: implementations.

Fixes https://github.com/boostorg/core/issues/206.
2025-10-19 21:56:04 +03:00
Andrey Semashev 45bd9bf69b Use std::data and std::size for boost equivalents, when possible.
This avoids the potential ambiguity between boost:: and std:: functions
when the user calls data() or size() unqualified and both alternatives
are found via ADL.

Refs https://github.com/boostorg/core/issues/206.
2025-10-19 21:56:04 +03:00
Peter Dimov 6814bc508c Merge pull request #205 from gennaroprota/fix/use_do_while_false_for_boost_test_throws_and_boost_test_no_throw
Use the do {} while (false) idiom for BOOST_TEST_THROWS() and BOOST_TEST_NO_THROW()
2025-10-18 16:06:01 +03:00
Gennaro Prota 40fda50ae1 Omit do {} while (false) for MSVC versions prior to 2015
Reason: See the new code comment.
2025-10-15 12:30:48 +02:00
Gennaro Prota 8a352e253a Use the do {} while (false) idiom for BOOST_TEST_THROWS() and BOOST_TEST_NO_THROW()
Reason: Common hygiene for multi-line macros. Makes things like

if (condition)
    BOOST_TEST_THROWS(...);
else
    ...

work correctly. Also, it doesn't generate an empty statement (which
compilers may warn about) when the user adds a semicolon (which they
usually do).
2025-10-09 19:00:47 +02:00
Mohammad Nejati 6afe70e09d detail::span_convertible handles void types
fixes #202
2025-09-08 17:02:46 +00:00
Andrey Semashev c6b098d25d Merge pull request #201 from Flamefire/test-link-update
Update Link to regression test matrix in README
2025-08-25 19:05:15 +03:00
Alexander Grund c4bfbf9ec5 Update Link to regression test matrix in README 2025-08-25 17:26:11 +02:00
Peter Dimov a128501403 Update revision history 2025-06-30 13:06:07 +03:00
Peter Dimov 24b5bb625e Update .drone.jsonnet 2025-06-25 20:26:52 +03:00
Peter Dimov d513ed162a Update .drone.jsonnet 2025-06-25 19:28:05 +03:00
Peter Dimov 65337d1af8 Add a std::formatter specialization for core::string_view. Fixes #190. 2025-06-25 17:11:26 +03:00
Peter Dimov 16d8f5f8ff Add sv_format_test.cpp. Refs #190. 2025-06-25 16:51:59 +03:00
Andrey Semashev 58f469cd80 Added ARM jobs in GitHub Actions. 2025-06-13 02:30:14 +03:00
Andrey Semashev 457d6a8ad0 Use Azure mirrors of Ubuntu .deb repositories in containers.
This reduces the likelihood of spurious CI failures caused by DDoS filters
being triggered by massive numbers of concurrent CI jobs.
2025-06-13 02:23:02 +03:00
Andrey Semashev e3d8de377b Removed windows-2019 jobs from GitHub Actions.
The windows-2019 image is deprecated and is about to be removed.

https://github.com/actions/runner-images/issues/12045
2025-06-13 02:21:12 +03:00
Peter Dimov 8d25b9ce54 Add missing include 2025-06-06 21:47:38 +03:00
Peter Dimov 6e05e5e764 Update ci.yml 2025-06-06 21:00:18 +03:00
Peter Dimov 7cb3e689e0 Update bit_ceil_test.cpp 2025-06-06 19:03:11 +03:00
Peter Dimov 11d367377f Merge pull request #199 from Pega5us/fix-issue#197-bitceil
🐛 Fix bit_ceil() to return 1 for input 0 as per specification
2025-06-06 18:17:15 +03:00
Abhay Kumar f32cb2f696 🐛 Fix bit_ceil() to return 1 for input 0 as per specification 2025-06-06 14:23:26 +05:30
Peter Dimov 21761b3f62 Merge pull request #192 from mborland/msvc_clz
Use bit scan intrinsic on Windows ARM64 platform
2025-04-16 15:13:43 +03:00
Peter Dimov 2e87ab53f7 Merge pull request #193 from striezel-stash/ci-ubuntu-20.04-deprecation
Move Ubuntu 20.04 builds to container or newer Ubuntu version
2025-04-16 15:12:26 +03:00
Andrey Semashev 8d5ee24c97 Merge pull request #194 from striezel-stash/fix-typos
Fix a few typos
2025-04-16 04:19:08 +03:00
Dirk Stolle db59ef2a81 Fix a few typos 2025-04-16 02:16:49 +02:00
Dirk Stolle c48b7f269f Move Ubuntu 20.04 builds to container or newer Ubuntu version
The Ubuntu 20.04 image on GitHub Actions will be unavailable by
2025-04-15. See <https://github.com/actions/runner-images/issues/11101>
for more information on the deprecation and removal.

Therefore all build jobs that use the Ubuntu 20.04 runner image
of GHA have to be either migrated to a newer runner image (if
the compiler version is available on a newer image) or have to be
moved to Docker containers using Ubuntu 20.04 (if the compiler
version is not available on the newer runner images).
2025-04-16 02:07:28 +02:00
Matt Borland 4c74671f73 Use bit scan intrinsic on ARM64 platform 2025-04-10 08:35:11 -04:00
Peter Dimov 1e1ccb491e Fix GCC 4.8 Drone job to actually use 4.8 2025-02-23 18:37:43 +02:00
Glen Fernandes 787b03ea9c Use BOOST_ASSERT but disable assertions on older GCC 2025-01-18 17:14:03 -05:00
Glen Fernandes b9a2221b3b Rename detail assert macro since it isn't a public facility 2025-01-18 14:14:24 -05:00
Glen Fernandes cb603c9c6b Undef assert macro and remove guards 2025-01-18 00:53:35 -05:00
Glen Fernandes 24a8174ef1 Add asserts to span 2025-01-18 00:52:31 -05:00
Peter Dimov 7178a52909 Merge pull request #187 from eagleoflqj/ohos
OpenHarmony doesn't support pthread_setcancelstate.
2025-01-08 16:45:11 +02:00
Qijia Liu 9a3febf848 OpenHarmony doesn't support pthread_setcancelstate. 2025-01-07 21:13:58 -05:00
Peter Dimov 3e147e4ced Merge pull request #183 from Flamefire/warning
Avoid `-Wzero-as-null-pointer-constant` warning in string_view ctor
2025-01-05 17:25:14 +02:00
Alexander Grund 1222948a8e Avoid -Wzero-as-null-pointer-constant warning in string_view ctor 2025-01-05 11:57:02 +01:00
Peter Dimov 749b6340b5 Update ci.yml 2024-11-27 20:58:46 +02:00
Peter Dimov 92f6cfb3cc Remove hash_value overload for basic_string_view; it's no longer needed 2024-11-11 03:18:02 +02:00
Peter Dimov ed452c57a3 Add sv_hash_test to test/CMakeLists.txt 2024-11-11 02:31:11 +02:00
Peter Dimov 78885aab8e Disable serialization tests under MinGW 32 bit 2024-11-10 22:35:54 +02:00
Peter Dimov 8ebe2e7f57 Update ci.yml 2024-11-10 19:57:55 +02:00
Peter Dimov 32e6c30f4b Add test/sv_hash_test.cpp 2024-11-10 19:32:31 +02:00
Peter Dimov cebfe007e8 Update test/Jamfile 2024-11-10 16:21:59 +02:00
Peter Dimov 3e16f3df14 Update .drone.jsonnet 2024-11-10 15:43:57 +02:00
Peter Dimov e3a2e88e4c Update .drone.jsonnet 2024-08-21 10:50:28 +03:00
Peter Dimov 5e451b6c84 Add VERBATIM to add_custom_target 2024-08-21 04:14:05 +03:00
Peter Dimov 88a957b21c test/Jamfile: add cxx11_ref_qualifiers (GCC 4.8+) to Serialization tests because of Optional 2024-08-21 03:02:31 +03:00
Peter Dimov 1bac0ccfd1 Update build.jam 2024-08-21 02:32:32 +03:00
Rene Rivera 602961e526 Update build deps. 2024-08-01 21:30:37 -05:00
Rene Rivera 366802b43c Adjust doc build to avoid boost-root references. 2024-07-28 10:42:22 -05:00
Rene Rivera 9dd0a8e1e4 Sync from upstream. 2024-07-27 11:09:51 -05:00
Andrey Semashev 622476533c Added a release notes entry for the empty_value fix. 2024-07-27 10:35:28 +03:00
Rene Rivera a09ee19e3e Sync from upstream. 2024-07-25 17:19:14 -05:00
Rene Rivera 040b018ce0 Restore warnings-as-errors-off that got accidentally removed in a merge. 2024-07-24 23:55:54 -05:00
Rene Rivera 42d0c5954a Move inter-lib dependencies to a project variable and into the build targets. 2024-07-23 22:34:24 -05:00
Andrey Semashev 76d0f22d3b Added 1.86.0 release notes. 2024-07-24 03:02:00 +03:00
Rene Rivera 243eec26fe Update copyright dates. 2024-07-20 22:52:05 -05:00
Rene Rivera 44c32d7691 Change all <source> references to <library>. 2024-07-20 19:37:53 -05:00
Rene Rivera 0ee7dc5910 Sync from upstream. 2024-07-18 09:29:32 -05:00
Glen Fernandes 9e9e6e3898 Rename base type again 2024-07-16 23:53:47 -04:00
Glen Fernandes 242b14bb69 Rename base typedef 2024-07-14 07:14:38 -04:00
Glen Fernandes 76061d91d4 Move compile test to separate source file 2024-07-14 07:04:23 -04:00
Peter Dimov bda05a7812 Update .drone.jsonnet 2024-07-13 15:41:26 +03:00
Peter Dimov d66b8c1c13 Update ci.yml 2024-07-13 13:32:29 +03:00
Andrey Semashev bd29e0dd15 Merge pull request #177 from ashtum/rename-base-typedef
Rename typedef `base` to `core_ev_base`
2024-07-13 13:21:00 +03:00
Mohammad Nejati 72761e34e0 Rename typedef base to core_ev_base
Using typedef `base` poses a high risk of name conflict, given that
`empty_value` is inherited in user types.
2024-07-13 09:14:58 +00:00
Rene Rivera 983234baee Sync from upstream. 2024-07-12 08:54:55 -05:00
Glen Fernandes 83a3a51bee Merge pull request #175 from k3DW/feature/empty-value-inherit-public
Fix `empty_value` MSVC bug
2024-07-12 08:53:53 -04:00
Braden Ganetsky acbeaae181 Add link to Visual Studio bug report 2024-07-11 17:02:24 -05:00
Braden Ganetsky d01b4e94cc Write test for empty_value private inheritance 2024-07-11 17:02:23 -05:00
Braden Ganetsky e22bd49fa7 Fix MSVC issue with deriving from empty_value 2024-07-11 17:02:21 -05:00
Braden Ganetsky c056f3dfc9 Write failing test in MSVC for deriving from empty_value 2024-06-23 22:50:52 -05:00
Rene Rivera 8b8944dd6e Bump B2 require to 5.2 2024-06-14 11:33:55 -05:00
Rene Rivera 278d3f0060 Sync from upstream. 2024-05-30 11:21:22 -05:00
Peter Dimov 3f36d507f2 Disable the tn_holder<wchar_t> specialization when BOOST_NO_INTRINSIC_WCHAR_T. Refs #173. 2024-05-28 19:32:36 +03:00
Andrey Semashev a77338b1cd Use macos-14 image instead of macos-11 as the latter is being removed. 2024-05-21 01:06:02 +03:00
Rene Rivera a8c757ddf2 Add requires-b2 check to top-level build file. 2024-05-05 09:00:01 -05:00
Rene Rivera 98a055cf34 Add missing lib reference. 2024-04-25 22:20:12 -05:00
Rene Rivera 074a467d9d Sync from upstream. 2024-04-24 20:30:49 -05:00
Peter Dimov 965508d9e1 Fix type_name for abstract classes. Fixes #172. 2024-04-24 21:46:32 +03:00
Rene Rivera 0a238bb30d Sync from upstream. 2024-04-20 15:33:40 -05:00
Glen Fernandes d03e58b77e Correct parameter type in documentation 2024-04-18 13:16:12 -04:00
Peter Dimov f774295cdb Add boost/core/detail/minstd_rand.hpp 2024-04-14 04:40:44 +03:00
Rene Rivera b18495fe35 Sync from upstream. 2024-04-12 22:40:43 -05:00
Peter Dimov c928c844da Merge branch 'feature/sign-conversion' into develop 2024-04-11 13:43:49 +03:00
Glen Fernandes 0a42ddabef Update pointer_in_range documentation 2024-04-11 02:25:05 -04:00
Glen Fernandes 04cc766db3 Address C++17 redeclaration of constexpr static 2024-04-11 00:52:26 -04:00
Rene Rivera 151d0c4143 Sync from upstream. 2024-04-10 07:57:45 -05:00
Rene Rivera 25b0defdeb Switch to library requirements instead of source. As source puts extra source in install targets. 2024-03-29 21:15:58 -05:00
Rene Rivera 541745ea24 Sync from upstream. 2024-03-23 07:57:20 -05:00
Rene Rivera 5f825106c7 Make the library modular usable. 2024-03-11 08:32:21 -05:00
61 changed files with 1921 additions and 244 deletions
+75 -27
View File
@@ -32,7 +32,8 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch
commands:
[
'set -e',
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
'uname -a',
'echo $DRONE_STAGE_MACHINE',
] +
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
@@ -122,7 +123,7 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
linux_pipeline(
"Linux 16.04 GCC 4.8 32/64",
"cppalliance/droneubuntu1604:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11', ADDRMD: '32,64' },
{ TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '03,11', ADDRMD: '32,64' },
"g++-4.8-multilib",
),
@@ -200,31 +201,44 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
),
linux_pipeline(
"Linux 23.04 GCC 13 32 ASAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + asan,
"g++-13-multilib",
"Linux 24.04 GCC 13* 32/64",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 23.04 GCC 13 64 ASAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + asan,
"g++-13-multilib",
"Linux 24.04 GCC 14 32 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 32 UBSAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + ubsan,
"g++-13-multilib",
"Linux 24.04 GCC 14 64 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + asan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 23.04 GCC 13 64 UBSAN",
"cppalliance/droneubuntu2304:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + ubsan,
"g++-13-multilib",
"Linux 24.04 GCC 14 32 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 24.04 GCC 14 64 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-14', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' } + ubsan,
"g++-14-multilib",
),
linux_pipeline(
"Linux 25.04 GCC 15 32/64",
"cppalliance/droneubuntu2504:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-15', CXXSTD: '03,11,14,17,20,23,2c', ADDRMD: '32,64' },
"g++-15-multilib",
),
linux_pipeline(
@@ -347,24 +361,52 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
),
linux_pipeline(
"Linux 23.04 Clang 16",
"cppalliance/droneubuntu2304:1",
"Linux 24.04 Clang 16",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '03,11,14,17,20,2b' },
"clang-16",
),
linux_pipeline(
"Linux 23.10 Clang 17 UBSAN",
"cppalliance/droneubuntu2310:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '03,11,14,17,20,2b' } + ubsan,
"Linux 24.04 Clang 17",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '03,11,14,17,20,2b' },
"clang-17",
),
linux_pipeline(
"Linux 23.10 Clang 17 ASAN",
"cppalliance/droneubuntu2310:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-17', CXXSTD: '03,11,14,17,20,2b' } + asan,
"clang-17",
"Linux 24.04 Clang 18",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-18', CXXSTD: '03,11,14,17,20,2b' },
"clang-18",
),
linux_pipeline(
"Linux 24.04 Clang 19",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-19', CXXSTD: '03,11,14,17,20,2b' },
"clang-19",
),
linux_pipeline(
"Linux 24.04 Clang 20 UBSAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '03,11,14,17,20,23,2c' } + ubsan,
"clang-20",
),
linux_pipeline(
"Linux 24.04 Clang 20 ASAN",
"cppalliance/droneubuntu2404:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-20', CXXSTD: '03,11,14,17,20,23,2c' } + asan,
"clang-20",
),
linux_pipeline(
"Linux 25.10 Clang 21",
"cppalliance/droneubuntu2510:1",
{ TOOLSET: 'clang', COMPILER: 'clang++-21', CXXSTD: '03,11,14,17,20,23,2c' },
"clang-21",
),
macos_pipeline(
@@ -412,4 +454,10 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
"cppalliance/dronevs2022:1",
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest', ADDRMD: '32,64' },
),
windows_pipeline(
"Windows VS2026 msvc-14.5",
"cppalliance/dronevs2026:1",
{ TOOLSET: 'msvc-14.5', CXXSTD: '14,17,20,latest', ADDRMD: '32,64' },
),
]
+123 -57
View File
@@ -1,5 +1,5 @@
# Copyright 2020-2021 Peter Dimov
# Copyright 2021-2024 Andrey Semashev
# Copyright 2021-2025 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)
@@ -100,13 +100,13 @@ jobs:
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
address-model: 32,64
os: ubuntu-20.04
os: ubuntu-24.04
install:
- g++-9-multilib
- toolset: gcc-10
cxxstd: "03,11,14,17,20"
address-model: 32,64
os: ubuntu-20.04
os: ubuntu-24.04
install:
- g++-10-multilib
- toolset: gcc-11
@@ -125,9 +125,23 @@ jobs:
cxxstd: "03,11,14,17,20,23"
address-model: 32,64
os: ubuntu-latest
container: ubuntu:23.04
container: ubuntu:24.04
install:
- g++-13-multilib
- toolset: gcc-14
cxxstd: "03,11,14,17,20,23"
address-model: 32,64
os: ubuntu-latest
container: ubuntu:24.04
install:
- g++-14-multilib
- toolset: gcc-15
cxxstd: "03,11,14,17,20,23,2c"
address-model: 32,64
os: ubuntu-latest
container: ubuntu:25.04
install:
- g++-15-multilib
- name: UBSAN
toolset: gcc-12
cxxstd: "03,11,14,17,20,23"
@@ -137,20 +151,6 @@ jobs:
- g++-12
# Linux, clang
- toolset: clang
compiler: clang++-3.5
cxxstd: "03,11"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.5
- toolset: clang
compiler: clang++-3.6
cxxstd: "03,11,14"
os: ubuntu-latest
container: ubuntu:16.04
install:
- clang-3.6
- toolset: clang
compiler: clang++-3.7
cxxstd: "03,11,14"
@@ -213,13 +213,15 @@ jobs:
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:20.04
install:
- clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
os: ubuntu-latest
container: ubuntu:20.04
install:
- clang-10
- toolset: clang
@@ -276,7 +278,7 @@ jobs:
compiler: clang++-16
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:23.04
container: ubuntu:24.04
install:
- clang-16
- libc++-16-dev
@@ -286,15 +288,56 @@ jobs:
- toolset: clang
compiler: clang++-17
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-22.04
os: ubuntu-latest
container: ubuntu:24.04
install:
- clang-17
- libc++-17-dev
- libc++abi-17-dev
sources:
- "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main"
source_keys:
- "https://apt.llvm.org/llvm-snapshot.gpg.key"
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- toolset: clang
compiler: clang++-18
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:24.04
install:
- clang-18
- libc++-18-dev
- libc++abi-18-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- toolset: clang
compiler: clang++-19
cxxstd: "03,11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:24.04
install:
- clang-19
- libc++-19-dev
- libc++abi-19-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- toolset: clang
compiler: clang++-20
cxxstd: "03,11,14,17,20,23,2c"
os: ubuntu-latest
container: ubuntu:24.04
install:
- clang-20
- libc++-20-dev
- libc++abi-20-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- toolset: clang
compiler: clang++-21
cxxstd: "03,11,14,17,20,23,2c"
os: ubuntu-latest
container: ubuntu:25.10
install:
- clang-21
- libc++-21-dev
- libc++abi-21-dev
cxxflags: -stdlib=libc++
linkflags: -stdlib=libc++
- name: UBSAN
@@ -310,15 +353,23 @@ jobs:
- libc++-15-dev
- libc++abi-15-dev
- name: ARM
toolset: gcc-13
cxxstd: "03-gnu,11-gnu,14-gnu,17-gnu,20-gnu,23-gnu"
os: ubuntu-24.04-arm
container: ubuntu:24.04
install:
- g++-13
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-11
- toolset: clang
os: macos-14
cxxstd: "03,11,14,17,20,2b"
os: macos-12
- toolset: clang
cxxstd: "03,11,14,17,20,2b"
os: macos-13
os: macos-15
cxxstd: "03,11,14,17,20,23,2c"
- toolset: clang
os: macos-26
cxxstd: "03,11,14,17,20,23,2c"
timeout-minutes: 45
runs-on: ${{matrix.os}}
@@ -337,6 +388,22 @@ jobs:
echo "GHA_CONTAINER=${{matrix.container}}" >> $GITHUB_ENV
if [ -f "/etc/debian_version" ]
then
# Use Azure APT mirrors in containers to avoid HTTP errors due to DDoS filters triggered by lots of CI jobs launching concurrently.
# Note that not all Ubuntu versions support "mirror+file:..." URIs in APT sources, so just use Azure mirrors exclusively.
# Note also that on recent Ubuntu versions DEB822 format is used for source files.
APT_SOURCES=()
if [ -d "/etc/apt/sources.list.d" ]
then
readarray -t APT_SOURCES < <(find "/etc/apt/sources.list.d" -type f -name '*.sources' -print)
fi
if [ -f "/etc/apt/sources.list" ]
then
APT_SOURCES+=("/etc/apt/sources.list")
fi
if [ "${#APT_SOURCES[@]}" -gt 0 ]
then
sed -i -E -e 's!([^ ]+) (http|https)://(archive|security)\.ubuntu\.com/ubuntu[^ ]*(.*)!\1 http://azure.archive.ubuntu.com/ubuntu/\4!' "${APT_SOURCES[@]}"
fi
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
if [ "$(apt-cache search "^python-is-python3$" | wc -l)" -ne 0 ]
then
@@ -537,14 +604,6 @@ jobs:
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
@@ -556,10 +615,17 @@ jobs:
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
os: windows-2022
# Windows SDK 32-bit ARM libs not installed in this image
- name: ARM
toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 64
os: windows-11-arm
runs-on: ${{matrix.os}}
timeout-minutes: 45
timeout-minutes: 60
steps:
- name: Setup Boost
@@ -609,11 +675,11 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: macos-13
- os: ubuntu-24.04
- os: macos-14
- os: macos-15
- os: macos-26
runs-on: ${{matrix.os}}
timeout-minutes: 10
@@ -676,11 +742,11 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: macos-13
- os: ubuntu-24.04
- os: macos-14
- os: macos-15
- os: macos-26
runs-on: ${{matrix.os}}
timeout-minutes: 10
@@ -753,11 +819,11 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
- os: macos-13
- os: ubuntu-24.04
- os: macos-14
- os: macos-15
- os: macos-26
runs-on: ${{matrix.os}}
timeout-minutes: 20
@@ -834,8 +900,8 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
- os: windows-2025
runs-on: ${{matrix.os}}
timeout-minutes: 10
@@ -896,8 +962,8 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
- os: windows-2025
runs-on: ${{matrix.os}}
timeout-minutes: 10
@@ -976,8 +1042,8 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
- os: windows-2025
runs-on: ${{matrix.os}}
timeout-minutes: 20
+1 -2
View File
@@ -16,11 +16,10 @@ target_link_libraries(boost_core
INTERFACE
Boost::assert
Boost::config
Boost::static_assert
Boost::throw_exception
)
if(CMAKE_VERSION VERSION_GREATER 3.18 AND CMAKE_GENERATOR MATCHES "Visual Studio")
if(NOT CMAKE_VERSION VERSION_LESS 3.19 AND CMAKE_GENERATOR MATCHES "Visual Studio")
file(GLOB_RECURSE boost_core_IDEFILES CONFIGURE_DEPENDS include/*.hpp)
source_group(TREE ${PROJECT_SOURCE_DIR}/include FILES ${boost_core_IDEFILES} PREFIX "Header Files")
+5 -5
View File
@@ -6,14 +6,14 @@ The 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.
* not dependent on any other Boost modules except Core itself, Config, Assert, or ThrowException.
### Build Status
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)
Develop | [![GitHub Actions](https://github.com/boostorg/core/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/core/actions?query=branch%3Adevelop) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/75arrvfh5ibryd0p/branch/develop?svg=true)](https://ci.appveyor.com/project/cppalliance/core) | [![Tests](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](https://regression.boost.io/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/core/actions?query=branch%3Amaster) | [![AppVeyor](https://ci.appveyor.com/api/projects/status/75arrvfh5ibryd0p/branch/master?svg=true)](https://ci.appveyor.com/project/cppalliance/core) | [![Tests](https://img.shields.io/badge/matrix-master-brightgreen.svg)](https://regression.boost.io/master/developer/core.html) | [![Dependencies](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/core.html)
### Directories
@@ -24,8 +24,8 @@ Master | [![GitHub Actions](https://github.com/boostorg/core/actions/workflows
### More information
* [Documentation](https://boost.org/libs/core)
* [Report bugs](https://svn.boost.org/trac/boost/newticket?component=core;version=Boost%20Release%20Branch). Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
* Report bugs by opening issues in this repository. Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
* Submit your patches as pull requests against the **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
### License
+3 -5
View File
@@ -27,17 +27,15 @@ environment:
ADDRMD: 32,64
CXXSTD: 14,17
# 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,latest
CXXSTD: 14,17
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17,latest
CXXSTD: 20,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
+8
View File
@@ -0,0 +1,8 @@
# Copyright 2020, 2025 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
project : default-build release <link>static <cxxstd>17
: requirements <library>/boost/core//boost_core ;
exe sv_find_first_of : sv_find_first_of.cpp ;
exe sv_find_first_not_of : sv_find_first_not_of.cpp ;
+277
View File
@@ -0,0 +1,277 @@
// Copyright 2021, 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/utility/string_view.hpp>
#include <boost/core/detail/string_view.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/type_name.hpp>
#include <boost/cstdint.hpp>
#include <string_view>
#include <chrono>
#include <iostream>
using namespace std::chrono_literals;
template<class Sv> void test()
{
constexpr char const* q1 = "{";
constexpr char const* q2 = "<(";
constexpr char const* q3 = " :=";
constexpr char const* q4 = " \t\r\n";
constexpr char const* q6 = " \t\r\n\f\v";
constexpr char const* q10 = "0123456789";
constexpr char const* q52 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
constexpr std::size_t npos = static_cast<std::size_t>( -1 );
constexpr std::size_t N = 1'000'000'000;
std::cout << boost::core::type_name<Sv>() << ":\n\n";
auto t0 = std::chrono::steady_clock::now();
{
constexpr char const* q = q1;
std::string s1( 1'000'000, q[ std::strlen( q ) - 1 ] );
std::string s2( 100, q[ std::strlen( q ) - 1 ] );
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q2;
std::string s1( 1'000'000, q[ std::strlen( q ) - 1 ] );
std::string s2( 100, q[ std::strlen( q ) - 1 ] );
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q3;
std::string s1( 1'000'000, q[ std::strlen( q ) - 1 ] );
std::string s2( 100, q[ std::strlen( q ) - 1 ] );
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q4;
std::string s1( 1'000'000, q[ std::strlen( q ) - 1 ] );
std::string s2( 100, q[ std::strlen( q ) - 1 ] );
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q6;
std::string s1( 1'000'000, q[ std::strlen( q ) - 1 ] );
std::string s2( 100, q[ std::strlen( q ) - 1 ] );
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q10;
std::string s1( 1'000'000, q[ std::strlen( q ) - 1 ] );
std::string s2( 100, q[ std::strlen( q ) - 1 ] );
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q52;
std::string s1( 1'000'000, q[ std::strlen( q ) - 1 ] );
std::string s2( 100, q[ std::strlen( q ) - 1 ] );
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_not_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_not_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
auto tn = std::chrono::steady_clock::now();
std::cout << "\nTotal for " << boost::core::type_name<Sv>() << ": " << ( tn - t0 ) / 1ms << " ms\n\n";
}
int main()
{
test<std::string_view>();
test<boost::string_view>();
test<boost::core::string_view>();
return boost::report_errors();
}
+259
View File
@@ -0,0 +1,259 @@
// Copyright 2021, 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/utility/string_view.hpp>
#include <boost/core/detail/string_view.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/type_name.hpp>
#include <boost/cstdint.hpp>
#include <string_view>
#include <chrono>
#include <iostream>
using namespace std::chrono_literals;
template<class Sv> void test()
{
std::string s1( 1'000'000, '\x00' );
std::string s2( 100, '\x00' );
constexpr char const* q1 = "{";
constexpr char const* q2 = "<(";
constexpr char const* q3 = " :=";
constexpr char const* q4 = " \t\r\n";
constexpr char const* q6 = " \t\r\n\f\v";
constexpr char const* q10 = "0123456789";
constexpr char const* q52 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
constexpr std::size_t npos = static_cast<std::size_t>( -1 );
constexpr std::size_t N = 1'000'000'000;
std::cout << boost::core::type_name<Sv>() << ":\n\n";
auto t0 = std::chrono::steady_clock::now();
{
constexpr char const* q = q1;
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q2;
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q3;
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q4;
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q6;
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q10;
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
{
constexpr char const* q = q52;
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s1.size(); ++i )
{
BOOST_TEST_EQ( Sv( s1 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s1.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
{
auto t1 = std::chrono::steady_clock::now();
for( std::size_t i = 0; i < N / s2.size(); ++i )
{
BOOST_TEST_EQ( Sv( s2 ).find_first_of( q ), npos );
}
auto t2 = std::chrono::steady_clock::now();
std::cout << "find_first_of( sv, \"" << q << "\" ) in " << s2.size() << " bytes: " << ( t2 - t1 ) / 1ms << " ms\n";
}
}
auto tn = std::chrono::steady_clock::now();
std::cout << "\nTotal for " << boost::core::type_name<Sv>() << ": " << ( tn - t0 ) / 1ms << " ms\n\n";
}
int main()
{
test<std::string_view>();
test<boost::string_view>();
test<boost::core::string_view>();
return boost::report_errors();
}
+22
View File
@@ -0,0 +1,22 @@
# Copyright 2023-2024 René Ferdinand Rivera Morell
# Copyright 2024 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
require-b2 5.2 ;
constant boost_dependencies :
/boost/assert//boost_assert
/boost/config//boost_config
/boost/throw_exception//boost_throw_exception
;
project /boost/core ;
explicit
[ alias boost_core : : : : <include>include <library>$(boost_dependencies) ]
[ alias all : boost_core test ]
;
call-if : boost-library core
;
+1 -1
View File
@@ -9,7 +9,7 @@ import project ;
import doxygen ;
import quickbook ;
path-constant INCLUDES : ../../.. ;
path-constant INCLUDES : ../include ;
doxygen ref_reference
:
+40 -2
View File
@@ -1,18 +1,56 @@
[/
Copyright 2021 Peter Dimov
Copyright 2022-2024 Andrey Semashev
Copyright 2022-2025 Andrey Semashev
Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt)
]
[section Revision History]
[section Changes in 1.91.0]
* The header [link core.is_placeholder `boost/is_placeholder.hpp`] has been moved from Bind to Core. ([github_issue 90])
[endsect]
[section Changes in 1.90.0]
* The implementation of `BOOST_TEST_THROWS` and `BOOST_TEST_NO_THROW` macros defined in
[link core.lightweight_test `boost/core/lightweight_test.hpp`] has been changed to avoid
compiler warnings on some compilers, when the macros are used in `if`/`else` blocks. As
a side effect of this change, the semicolon after the macro is now necessary. ([github_pr 205])
* [link core.data `boost::data`] and [link core.size `boost::size`] are now aliases for `std::data`
and `std::size`, respectively, when the latter are provided by compiler. This resolves potential
ambiguities when both `boost::` and `std::` alternatives are found by the compiler, e.g. as a result
of ADL. ([github_issue 206])
[endsect]
[section Changes in 1.89.0]
* Fixed `bit_ceil` to return 1 for input 0 as per specification. ([github_pr 199])
* Added support for `std::format` to `boost::core::string_view`. ([github_issue 190])
[endsect]
[section Changes in 1.86.0]
* Added a [link core.pointer_in_range `boost/core/pointer_in_range.hpp`] header with a `pointer_in_range`
function template to check if a pointer is within a given range.
* Fixed `type_name` for abstract classes. ([github_issue 172])
* Fixed `boost/core/type_name.hpp` compilation error with MSVC with disabled native `wchar_t` type.
([github_issue 173])
* Added a workaround for an MSVC [@https://developercommunity.visualstudio.com/t/Compiler-bug:-Incorrect-C2247-and-C2248/10690025 bug]
causing `empty_value` compilation errors when it is used with a nested class. ([github_pr 175])
[endsect]
[section Changes in 1.85.0]
* Added a new [link core.functor `boost/core/functor.hpp`] header with a `functor` class template
for wrapping a raw function into a function object class.
* Changed [link core.null_deleter `null_deleter`], [link core.fclose_deleter `fclose_deleter`]
and [link.checked_delete checked deleter] definitions so that they don't bring namespace `boost`
and [link core.checked_delete checked deleter] definitions so that they don't bring namespace `boost`
into argument-dependent lookup in cases like this:
```
std::unique_ptr< std::FILE, boost::fclose_deleter > p1, p2;
+5 -1
View File
@@ -20,6 +20,9 @@ or copy at http://boost.org/LICENSE_1_0.txt)
]
]
[template github_issue[key]'''<ulink url="https://github.com/boostorg/core/issues/'''[key]'''">#'''[key]'''</ulink>''']
[template github_pr[key]'''<ulink url="https://github.com/boostorg/core/pull/'''[key]'''">PR#'''[key]'''</ulink>''']
[template simplesect[title]
[block '''<simplesect><title>'''[title]'''</title>''']]
@@ -34,7 +37,7 @@ 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, StaticAssert, or ThrowException.
itself, Config, Assert, or ThrowException.
[endsect]
@@ -58,6 +61,7 @@ criteria for inclusion is that the utility component be:
[include functor.qbk]
[include identity.qbk]
[include ignore_unused.qbk]
[include is_placeholder.qbk]
[include is_same.qbk]
[include launder.qbk]
[include lightweight_test.qbk]
+69
View File
@@ -0,0 +1,69 @@
[/
Copyright 2014, 2025 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
]
[section:is_placeholder is_placeholder]
[simplesect Authors]
* Peter Dimov
[endsimplesect]
[section Header <boost/is_placeholder.hpp>]
The header `<boost/is_placeholder.hpp>` defines the class template
`boost::is_placeholder<T>`. It defines a nested integral constant
`value` which is `0` when `T` is not a `boost::bind` placeholder
type, and a positive value corresponding to the placeholder index
otherwise.
That is, `is_placeholder<_1>::value` is `1`,
`is_placeholder<_2>::value` is `2`, and so on.
`is_placeholder` can be specialized for user types. If it is,
`boost::bind` will recognize these types as placeholders.
[section Synopsis]
``
namespace boost
{
template<class T> struct is_placeholder;
}
``
[endsect]
[section Example]
``
#include <boost/is_placeholder.hpp>
#include <boost/bind.hpp>
struct arg1_type {};
constexpr arg1_type arg1{};
template<> struct boost::is_placeholder<arg1_type>
{
static constexpr int value = 1;
};
int f( int x ) { return x + 1; }
int main()
{
return boost::bind( f, arg1 )( -1 );
}
``
[endsect]
[endsect]
[endsect]
+1 -1
View File
@@ -18,7 +18,7 @@
The header `<boost/core/null_deleter.hpp>` defines the `boost::null_deleter` function object,
which can be used as a deleter with smart pointers such as `unique_ptr` or `shared_ptr`. The
deleter doesn't do anything with the pointer provided upon deallocation, which makes it useful
when the pointed object is deallocated elsewhere.
when the pointed object doesn't need to be deallocated or is deallocated elsewhere.
[section Example]
``
+3 -2
View File
@@ -33,7 +33,7 @@ template<class T, class N>
void
Allocator<T, N>::deallocate(pointer ptr, size_type)
{
if (!boost::pointer_in_range(ptr, &buffer_[0], &buffer_[N])) {
if (!boost::pointer_in_range(ptr, buffer_, buffer_ + N)) {
::operator delete(ptr);
}
}
@@ -56,8 +56,9 @@ constexpr bool pointer_in_range(const T* ptr, const T* begin, const T* end);
[variablelist
[[`template<class T> constexpr bool pointer_in_range(const T* ptr,
const T* begin, T* end);`]
const T* begin, const T* end);`]
[[variablelist
[[Requires][`[begin,end)` is a valid range.]]
[[Returns][`true` if `ptr` is in range `[begin,end)`, otherwise `false`.]]]]]]
[endsect]
+1 -1
View File
@@ -38,7 +38,7 @@ and return type use spans.
```
auto sha1(boost::span<const unsigned char> input,
boost::span<unsigned char, SHA_DIGEST_LENGTH> ouput)
boost::span<unsigned char, SHA_DIGEST_LENGTH> output)
{
SHA_CTX context;
SHA1_Init(&context);
+29 -29
View File
@@ -15,8 +15,8 @@
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/static_assert.hpp>
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp>
#include <limits>
#include <cstring>
@@ -28,7 +28,7 @@
# pragma intrinsic(_BitScanForward)
# pragma intrinsic(_BitScanReverse)
# if defined(_M_X64)
# if defined(_M_X64) || defined(_M_ARM64)
# pragma intrinsic(_BitScanForward64)
# pragma intrinsic(_BitScanReverse64)
# endif
@@ -80,7 +80,7 @@ BOOST_CONSTEXPR To bit_cast( From const & from ) BOOST_NOEXCEPT
template<class To, class From>
To bit_cast( From const & from ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( sizeof(To) == sizeof(From) );
BOOST_CORE_STATIC_ASSERT( sizeof(To) == sizeof(From) );
To to;
std::memcpy( &to, &from, sizeof(To) );
@@ -126,7 +126,7 @@ BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEP
template<class T>
BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::detail::countl_impl( x );
}
@@ -230,7 +230,7 @@ inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
#endif
#if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
@@ -255,7 +255,7 @@ BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
}
}
#elif defined(_MSC_VER) && defined(_M_X64)
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
@@ -296,9 +296,9 @@ inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
template<class T>
BOOST_CXX14_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
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) );
BOOST_CORE_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) );
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
{
@@ -323,7 +323,7 @@ BOOST_CXX14_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::countl_zero( static_cast<T>( ~x ) );
}
@@ -365,7 +365,7 @@ BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEP
template<class T>
BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::detail::countr_impl( x );
}
@@ -455,7 +455,7 @@ inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
#endif
#if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64)) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
@@ -480,7 +480,7 @@ BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
}
}
#elif defined(_MSC_VER) && defined(_M_X64)
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
@@ -521,9 +521,9 @@ inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
template<class T>
BOOST_CXX14_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
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) );
BOOST_CORE_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) );
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
{
@@ -548,7 +548,7 @@ BOOST_CXX14_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::countr_zero( static_cast<T>( ~x ) );
}
@@ -598,7 +598,7 @@ BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x
template<class T>
BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return boost::core::detail::popcount_impl( x );
}
@@ -631,9 +631,9 @@ BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCE
template<class T>
BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
BOOST_CORE_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
{
@@ -652,7 +652,7 @@ BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
unsigned const mask = std::numeric_limits<T>::digits - 1;
return static_cast<T>( x << (static_cast<unsigned>( s ) & mask) | x >> (static_cast<unsigned>( -s ) & mask) );
@@ -661,7 +661,7 @@ BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT
template<class T>
BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
unsigned const mask = std::numeric_limits<T>::digits - 1;
return static_cast<T>( x >> (static_cast<unsigned>( s ) & mask) | x << (static_cast<unsigned>( -s ) & mask) );
@@ -672,7 +672,7 @@ BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return x != 0 && ( x & ( x - 1 ) ) == 0;
}
@@ -683,7 +683,7 @@ BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR int bit_width( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return std::numeric_limits<T>::digits - boost::core::countl_zero( x );
}
@@ -691,7 +691,7 @@ BOOST_CONSTEXPR int bit_width( T x ) BOOST_NOEXCEPT
template<class T>
BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return x == 0? T(0): static_cast<T>( T(1) << ( boost::core::bit_width( x ) - 1 ) );
}
@@ -703,7 +703,7 @@ BOOST_CXX14_CONSTEXPR inline boost::uint32_t bit_ceil_impl( boost::uint32_t x )
{
if( x == 0 )
{
return 0;
return 1;
}
--x;
@@ -723,7 +723,7 @@ BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x )
{
if( x == 0 )
{
return 0;
return 1;
}
--x;
@@ -745,9 +745,9 @@ BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x )
template<class T>
BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
BOOST_CORE_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
{
@@ -922,9 +922,9 @@ BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x )
template<class T> BOOST_CXX14_CONSTEXPR T byteswap( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer );
BOOST_CORE_STATIC_ASSERT( std::numeric_limits<T>::is_integer );
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) );
BOOST_CORE_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) );
BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
{
+3 -3
View File
@@ -20,8 +20,8 @@
#if defined(BOOST_CORE_USE_GENERIC_CMATH) || (!defined(_MSC_VER) && !defined(FP_SUBNORMAL))
#include <boost/core/detail/static_assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <limits>
#include <cstring>
@@ -81,7 +81,7 @@ inline bool signbit( float x )
{
boost::int32_t y;
BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
BOOST_CORE_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
std::memcpy( &y, &x, sizeof( y ) );
@@ -92,7 +92,7 @@ inline bool signbit( double x )
{
boost::int64_t y;
BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
BOOST_CORE_STATIC_ASSERT( sizeof( x ) == sizeof( y ) );
std::memcpy( &y, &x, sizeof( y ) );
+15 -1
View File
@@ -8,8 +8,20 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_CORE_DATA_HPP
#define BOOST_CORE_DATA_HPP
#include <initializer_list>
#include <iterator>
// Note: MSVC doesn't define __cpp_lib_nonmember_container_access but supports the feature even in C++14 mode
#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \
(defined(_MSC_VER) && (_MSC_VER >= 1900))
namespace boost {
using std::data;
} /* boost */
#else // (defined(__cpp_lib_nonmember_container_access) ...
#include <cstddef>
#include <initializer_list>
namespace boost {
@@ -43,4 +55,6 @@ data(std::initializer_list<T> l) noexcept
} /* boost */
#endif // (defined(__cpp_lib_nonmember_container_access) ...
#endif
+1
View File
@@ -10,6 +10,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/config.hpp>
#include <new>
#include <cstddef>
namespace boost {
+1 -1
View File
@@ -30,7 +30,7 @@
#if defined( BOOST_CORE_HAS_CXXABI_H )
# include <cxxabi.h>
// For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library
// For some architectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library
// (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement
// abi::__cxa_demangle(). We detect this implementation by checking the include guard here.
# if defined( __GABIXX_CXXABI_H__ )
+18
View File
@@ -0,0 +1,18 @@
/*
Copyright 2025 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#undef BOOST_CORE_DETAIL_ASSERT
#if !defined(__clang__) && \
!defined(__INTEL_COMPILER) && \
defined(__GNUC__) && \
(__GNUC__ < 5)
#define BOOST_CORE_DETAIL_ASSERT(expr) void(0)
#else
#include <boost/assert.hpp>
#define BOOST_CORE_DETAIL_ASSERT(expr) BOOST_ASSERT(expr)
#endif
+58
View File
@@ -0,0 +1,58 @@
#ifndef BOOST_CORE_DETAIL_MINSTD_RAND_HPP_INCLUDED
#define BOOST_CORE_DETAIL_MINSTD_RAND_HPP_INCLUDED
// Copyright 2017 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
//
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// An implementation of minstd_rand that does not require
// the Random library
#include <boost/cstdint.hpp>
namespace boost
{
namespace detail
{
class minstd_rand
{
private:
boost::uint_least32_t x_;
enum { a = 48271, m = 2147483647 };
public:
minstd_rand(): x_( 1 )
{
}
explicit minstd_rand( boost::uint_least32_t x ): x_( x % m )
{
if( x_ == 0 )
{
x_ = 1;
}
}
boost::uint_least32_t operator()()
{
boost::uint_least64_t y = x_;
y = ( a * y ) % m;
x_ = static_cast<boost::uint_least32_t>( y );
return x_;
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_CORE_DETAIL_MINSTD_RAND_HPP_INCLUDED
@@ -67,7 +67,7 @@ namespace core
inline void sp_thread_sleep() BOOST_NOEXCEPT
{
#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__)
#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) && !defined(__OHOS__)
int oldst;
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldst );
@@ -85,7 +85,7 @@ inline void sp_thread_sleep() BOOST_NOEXCEPT
nanosleep( &rqtp, 0 );
#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__)
#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) && !defined(__OHOS__)
pthread_setcancelstate( oldst, &oldst );
@@ -0,0 +1,42 @@
#ifndef BOOST_CORE_DETAIL_STATIC_ASSERT_HPP_INCLUDED
#define BOOST_CORE_DETAIL_STATIC_ASSERT_HPP_INCLUDED
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410L
#define BOOST_CORE_STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
#else
#include <boost/config.hpp>
#include <cstddef>
namespace boost
{
namespace core
{
template<bool> struct STATIC_ASSERTION_FAILURE;
template<> struct STATIC_ASSERTION_FAILURE<true>
{
};
template<std::size_t> struct static_assert_test
{
};
} // namespace core
} // namespace boost
#define BOOST_CORE_STATIC_ASSERT(expr) \
typedef ::boost::core::static_assert_test< \
sizeof( ::boost::core::STATIC_ASSERTION_FAILURE<(expr)? true: false> ) \
> BOOST_JOIN(boost_static_assert_typedef_,__LINE__) BOOST_ATTRIBUTE_UNUSED
#endif
#endif // #ifndef BOOST_CORE_DETAIL_STATIC_ASSERT_HPP_INCLUDED
+16 -10
View File
@@ -34,6 +34,9 @@
#if !defined(BOOST_NO_CXX20_HDR_CONCEPTS) // std::common_reference_with
# include <type_traits>
#endif
#if !defined(BOOST_NO_CXX20_HDR_FORMAT)
# include <format> // std::formatter
#endif
namespace boost
{
@@ -41,9 +44,6 @@ namespace boost
// forward declaration of boost::basic_string_view from Utility
template<class Ch, class Tr> class basic_string_view;
// forward declaration of boost::hash_range from ContainerHash
template<class It> std::size_t hash_range( It, It );
namespace core
{
namespace detail
@@ -381,7 +381,7 @@ public:
}
template<class End> BOOST_CXX14_CONSTEXPR basic_string_view( Ch const* first, End last,
typename boost::enable_if<boost::core::detail::is_same<End, Ch const*> >::type* = 0 ) BOOST_NOEXCEPT: p_( first ), n_( static_cast<size_type>( last - first ) )
typename boost::enable_if<boost::core::detail::is_same<End, Ch const*>, int >::type = 0 ) BOOST_NOEXCEPT: p_( first ), n_( static_cast<size_type>( last - first ) )
{
BOOST_ASSERT( last - first >= 0 );
}
@@ -399,7 +399,7 @@ public:
#endif
template<class Ch2> basic_string_view( boost::basic_string_view<Ch2, std::char_traits<Ch2> > const& str,
typename boost::enable_if<boost::core::detail::is_same<Ch, Ch2> >::type* = 0 ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() )
typename boost::enable_if<boost::core::detail::is_same<Ch, Ch2>, int >::type = 0 ) BOOST_NOEXCEPT: p_( str.data() ), n_( str.size() )
{
}
@@ -1181,11 +1181,6 @@ public:
}
#endif
inline friend std::size_t hash_value( basic_string_view const& sv )
{
return boost::hash_range( sv.begin(), sv.end() );
}
};
// stream inserter
@@ -1269,4 +1264,15 @@ struct std::basic_common_reference<
#endif
// std::format support
#if !defined(BOOST_NO_CXX20_HDR_FORMAT)
template<class Ch, class Ch2>
struct std::formatter<boost::core::basic_string_view<Ch>, Ch2>: std::formatter<std::basic_string_view<Ch>, Ch2>
{
};
#endif
#endif // #ifndef BOOST_CORE_STRING_VIEW_HPP_INCLUDED
+53 -5
View File
@@ -95,9 +95,57 @@ private:
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#if defined(BOOST_MSVC)
/*
This is a workaround to an MSVC bug when T is a nested class:
https://developercommunity.visualstudio.com/t/Compiler-bug:-Incorrect-C2247-and-C2248/10690025
*/
namespace detail {
template<class T>
class empty_value_base
: public T {
public:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
empty_value_base() = default;
#else
BOOST_CONSTEXPR empty_value_base() { }
#endif
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class U, class... Args>
BOOST_CONSTEXPR empty_value_base(U&& value, Args&&... args)
: T(std::forward<U>(value), std::forward<Args>(args)...) { }
#else
template<class U>
BOOST_CONSTEXPR empty_value_base(U&& value)
: T(std::forward<U>(value)) { }
#endif
#else
template<class U>
BOOST_CONSTEXPR empty_value_base(const U& value)
: T(value) { }
template<class U>
BOOST_CONSTEXPR empty_value_base(U& value)
: T(value) { }
#endif
};
} /* detail */
#endif
template<class T, unsigned N>
class empty_value<T, N, true>
#if defined(BOOST_MSVC)
: detail::empty_value_base<T> {
typedef detail::empty_value_base<T> empty_base_;
#else
: T {
typedef T empty_base_;
#endif
public:
typedef T type;
@@ -108,26 +156,26 @@ public:
#endif
BOOST_CONSTEXPR empty_value(boost::empty_init_t)
: T() { }
: empty_base_() { }
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class U, class... Args>
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value, Args&&... args)
: T(std::forward<U>(value), std::forward<Args>(args)...) { }
: empty_base_(std::forward<U>(value), std::forward<Args>(args)...) { }
#else
template<class U>
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U&& value)
: T(std::forward<U>(value)) { }
: empty_base_(std::forward<U>(value)) { }
#endif
#else
template<class U>
BOOST_CONSTEXPR empty_value(boost::empty_init_t, const U& value)
: T(value) { }
: empty_base_(value) { }
template<class U>
BOOST_CONSTEXPR empty_value(boost::empty_init_t, U& value)
: T(value) { }
: empty_base_(value) { }
#endif
BOOST_CONSTEXPR const T& get() const BOOST_NOEXCEPT {
+53 -38
View File
@@ -156,18 +156,15 @@ inline void no_throw_failed_impl(const char* expr, const char* what, const char*
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
// specialize test output for char pointers to avoid printing as cstring
template <class T> inline const T& test_output_impl(const T& v) { return v; }
inline const void* test_output_impl(const char* v) { return v; }
inline const void* test_output_impl(const unsigned char* v) { return v; }
inline const void* test_output_impl(const signed char* v) { return v; }
inline const void* test_output_impl(char* v) { return v; }
inline const void* test_output_impl(unsigned char* v) { return v; }
inline const void* test_output_impl(signed char* v) { return v; }
template<class T> inline const void* test_output_impl(T volatile* v) { return const_cast<T*>(v); }
// specialize test output for pointers to avoid printing as cstring
template<class T> inline T const& test_output_impl( T const& v ) { return v; }
template<class T> inline void const* test_output_impl( T* const& v ) { return v; }
template<class T> inline void const* test_output_impl( T volatile* const& v ) { return const_cast<T*>(v); }
#if !defined( BOOST_NO_CXX11_NULLPTR )
inline const void* test_output_impl(std::nullptr_t) { return nullptr; }
inline const void* test_output_impl( std::nullptr_t ) { return nullptr; }
#endif
// print chars as numeric
@@ -210,6 +207,16 @@ inline std::string test_output_impl( char const& v )
}
}
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
inline std::string test_output_impl( char8_t const& v )
{
// assume that char is ASCII, compatible with char8_t
return test_output_impl( static_cast<char>( v ) );
}
#endif
// predicates
struct lw_test_eq
@@ -551,39 +558,47 @@ inline void lwt_init()
#define BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2) ( ::boost::detail::test_all_eq_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2) )
#define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) ( ::boost::detail::test_all_with_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2, predicate) )
#ifndef BOOST_NO_EXCEPTIONS
#define BOOST_TEST_THROWS( EXPR, EXCEP ) \
try { \
EXPR; \
::boost::detail::throw_failed_impl \
(#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
} \
catch(EXCEP const&) { \
::boost::detail::test_results(); \
} \
catch(...) { \
::boost::detail::throw_failed_impl \
(#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
} \
//
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900
# define BOOST_LWT_DETAIL_WHILE_FALSE __pragma(warning(push)) __pragma(warning(disable:4127)) while(false) __pragma(warning(pop))
#else
#define BOOST_TEST_THROWS( EXPR, EXCEP )
# define BOOST_LWT_DETAIL_WHILE_FALSE while(false)
#endif
#ifndef BOOST_NO_EXCEPTIONS
# define BOOST_TEST_NO_THROW(EXPR) \
try { \
EXPR; \
} catch (const std::exception& e) { \
::boost::detail::no_throw_failed_impl \
(#EXPR, e.what(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
} catch (...) { \
::boost::detail::no_throw_failed_impl \
(#EXPR, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
}
//
#define BOOST_TEST_THROWS( EXPR, EXCEP ) \
do { \
try { \
EXPR; \
::boost::detail::throw_failed_impl \
(#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
} \
catch(EXCEP const&) { \
::boost::detail::test_results(); \
} \
catch(...) { \
::boost::detail::throw_failed_impl \
(#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
} \
} BOOST_LWT_DETAIL_WHILE_FALSE
#else
# define BOOST_TEST_NO_THROW(EXPR) { EXPR; }
#define BOOST_TEST_THROWS( EXPR, EXCEP ) do {} BOOST_LWT_DETAIL_WHILE_FALSE
#endif
#ifndef BOOST_NO_EXCEPTIONS
# define BOOST_TEST_NO_THROW(EXPR) \
do { \
try { \
EXPR; \
} catch (const std::exception& e) { \
::boost::detail::no_throw_failed_impl \
(#EXPR, e.what(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
} catch (...) { \
::boost::detail::no_throw_failed_impl \
(#EXPR, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \
} \
} BOOST_LWT_DETAIL_WHILE_FALSE
#else
# define BOOST_TEST_NO_THROW(EXPR) do { EXPR; } BOOST_LWT_DETAIL_WHILE_FALSE
#endif
#endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP
+1 -1
View File
@@ -37,7 +37,7 @@ namespace boost
/**
* Casts a scoped enum to its underlying type.
*
* This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type.
* This function is useful when working with scoped enum classes, which doesn't implicitly convert to the underlying type.
* @param v A scoped enum.
* @returns The underlying type.
* @throws No-throws.
+14
View File
@@ -8,6 +8,18 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_CORE_SIZE_HPP
#define BOOST_CORE_SIZE_HPP
#include <iterator>
// Note: MSVC doesn't define __cpp_lib_nonmember_container_access but supports the feature even in C++14 mode
#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \
(defined(_MSC_VER) && (_MSC_VER >= 1900))
namespace boost {
using std::size;
} /* boost */
#else // (defined(__cpp_lib_nonmember_container_access) ...
#include <cstddef>
namespace boost {
@@ -28,4 +40,6 @@ size(T(&)[N]) noexcept
} /* boost */
#endif // (defined(__cpp_lib_nonmember_container_access) ...
#endif
+22 -9
View File
@@ -8,6 +8,7 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_CORE_SPAN_HPP
#define BOOST_CORE_SPAN_HPP
#include <boost/core/detail/assert.hpp>
#include <boost/core/data.hpp>
#include <array>
#include <iterator>
@@ -22,9 +23,15 @@ class span;
namespace detail {
template<class U, class T>
template<class U, class T, class = void>
struct span_convertible {
static constexpr bool value = std::is_convertible<U(*)[], T(*)[]>::value;
static constexpr bool value = false;
};
template<class U, class T>
struct span_convertible<U, T, typename
std::enable_if<std::is_convertible<U(*)[], T(*)[]>::value>::type> {
static constexpr bool value = true;
};
template<std::size_t E, std::size_t N>
@@ -274,17 +281,21 @@ public:
}
constexpr span<T, dynamic_extent> first(size_type c) const {
return span<T, dynamic_extent>(s_.p, c);
return BOOST_CORE_DETAIL_ASSERT(c <= size()),
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);
return BOOST_CORE_DETAIL_ASSERT(c <= size()),
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);
return BOOST_CORE_DETAIL_ASSERT(o <= size() &&
(c == dynamic_extent || c + o <= size())),
span<T, dynamic_extent>(s_.p + o,
c == dynamic_extent ? s_.n - o : c);
}
constexpr size_type size() const noexcept {
@@ -300,15 +311,15 @@ public:
}
constexpr reference operator[](size_type i) const {
return s_.p[i];
return BOOST_CORE_DETAIL_ASSERT(i < size()), s_.p[i];
}
constexpr reference front() const {
return *s_.p;
return BOOST_CORE_DETAIL_ASSERT(!empty()), *s_.p;
}
constexpr reference back() const {
return s_.p[s_.n - 1];
return BOOST_CORE_DETAIL_ASSERT(!empty()), s_.p[s_.n - 1];
}
constexpr pointer data() const noexcept {
@@ -351,8 +362,10 @@ private:
detail::span_store<T, E> s_;
};
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
template<class T, std::size_t E>
constexpr std::size_t span<T, E>::extent;
#endif
#ifdef __cpp_deduction_guides
template<class I, class L>
+7 -2
View File
@@ -103,7 +103,8 @@ inline std::string fix_typeid_name( char const* n )
}
// class types can be incomplete
template<class T> std::string typeid_name_impl( int T::* )
// but also abstract (T[1] doesn't form)
template<class T> std::string typeid_name_impl( int T::*, T(*)[1] )
{
std::string r = fix_typeid_name( typeid(T[1]).name() );
return r.substr( 0, r.size() - 4 ); // remove ' [1]' suffix
@@ -116,7 +117,7 @@ template<class T> std::string typeid_name_impl( ... )
template<class T> std::string typeid_name()
{
return typeid_name_impl<T>( 0 );
return typeid_name_impl<T>( 0, 0 );
}
// template names
@@ -345,6 +346,8 @@ template<> struct tn_holder<boost::uint128_type>
#endif
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template<> struct tn_holder<wchar_t>
{
static std::string type_name( std::string const& suffix )
@@ -353,6 +356,8 @@ template<> struct tn_holder<wchar_t>
}
};
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
template<> struct tn_holder<char16_t>
+31
View File
@@ -0,0 +1,31 @@
#ifndef BOOST_IS_PLACEHOLDER_HPP_INCLUDED
#define BOOST_IS_PLACEHOLDER_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined( _MSC_VER ) && ( _MSC_VER >= 1020 )
# pragma once
#endif
// is_placeholder.hpp - TR1 is_placeholder metafunction
//
// Copyright (c) 2006 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
namespace boost
{
template< class T > struct is_placeholder
{
enum _vt { value = 0 };
};
} // namespace boost
#endif // #ifndef BOOST_IS_PLACEHOLDER_HPP_INCLUDED
+5 -12
View File
@@ -6,18 +6,7 @@ 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)
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)
boost_test_jamfile(FILE Jamfile.v2 LINK_LIBRARIES Boost::core Boost::config Boost::type_traits)
set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::throw_exception)
@@ -27,6 +16,10 @@ set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::utility)
boost_test(TYPE run SOURCES sv_conversion_test2.cpp)
set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::container_hash)
boost_test(TYPE run SOURCES sv_hash_test.cpp)
set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::config Boost::move Boost::smart_ptr)
boost_test(TYPE run SOURCES fclose_deleter_test.cpp)
+57 -17
View File
@@ -6,11 +6,16 @@
# See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt
require-b2 5.0.1 ;
import-search /boost/config/checks ;
import config : requires ;
import modules ;
import testing ;
project : requirements
<library>/boost/core//boost_core
<library>/boost/config//boost_config
<library>/boost/type_traits//boost_type_traits
<warnings>extra
<toolset>msvc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on
@@ -31,6 +36,8 @@ local pedantic-errors = <warnings>pedantic
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on ;
local CPP11 = [ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_constexpr cxx11_noexcept cxx11_ref_qualifiers ] ;
# quick test (for CI)
run quick.cpp ;
@@ -79,14 +86,14 @@ compile-fail ref_implicit_fail4.cpp
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
: $(warnings-as-errors-off) ;
@@ -170,6 +177,9 @@ run lightweight_test_with_test.cpp
: : : $(pedantic-errors) ;
run-fail lightweight_test_with_fail.cpp ;
run lightweight_test_eq_ptr.cpp
: : : $(pedantic-errors) ;
run is_same_test.cpp ;
run typeinfo_test.cpp ;
@@ -197,7 +207,13 @@ run underlying_type.cpp ;
compile-fail null_deleter_compile_fail_adl.cpp
: $(warnings-as-errors-off) ;
run fclose_deleter_test.cpp : : : <target-os>windows:<define>_CRT_SECURE_NO_WARNINGS <target-os>windows:<define>_CRT_SECURE_NO_DEPRECATE ;
run fclose_deleter_test.cpp : : :
$(CPP11)
<library>/boost/move//boost_move
<library>/boost/smart_ptr//boost_smart_ptr
<target-os>windows:<define>_CRT_SECURE_NO_WARNINGS
<target-os>windows:<define>_CRT_SECURE_NO_DEPRECATE ;
compile-fail fclose_deleter_compile_fail_adl.cpp
: <target-os>windows:<define>_CRT_SECURE_NO_WARNINGS <target-os>windows:<define>_CRT_SECURE_NO_DEPRECATE $(warnings-as-errors-off) ;
@@ -205,7 +221,6 @@ run functor_test.cpp ;
compile-fail functor_compile_fail_adl.cpp
: $(warnings-as-errors-off) ;
run pointer_traits_pointer_test.cpp ;
run pointer_traits_element_type_test.cpp ;
run pointer_traits_difference_type_test.cpp ;
@@ -226,6 +241,8 @@ run empty_value_test.cpp ;
run empty_value_size_test.cpp ;
run empty_value_final_test.cpp ;
run empty_value_constexpr_test.cpp ;
compile empty_value_nested_test.cpp ;
compile-fail empty_value_compile_fail_casting.cpp ;
run quick_exit_test.cpp ;
run-fail quick_exit_fail.cpp ;
@@ -379,7 +396,7 @@ run sv_stream_insert_test.cpp
: : : $(pedantic-errors) ;
run sv_conversion_test.cpp
: : : $(pedantic-errors) ;
run sv_conversion_test2.cpp : ;
run sv_conversion_test2.cpp : : : <library>/boost/utility//boost_utility ;
run sv_common_reference_test.cpp
: : : $(pedantic-errors) ;
compile sv_common_reference_test2.cpp ;
@@ -390,13 +407,20 @@ compile-fail sv_nullptr_fail.cpp
compile sv_construct_test_cx.cpp ;
compile sv_construct_test_cx2.cpp ;
run sv_hash_test.cpp : : : $(CPP11) <library>/boost/container_hash//boost_container_hash ;
run sv_format_test.cpp
: : : $(pedantic-errors) ;
run span_test.cpp ;
run span_types_test.cpp ;
run span_constructible_test.cpp ;
run span_deduction_guide_test.cpp ;
run span_constexpr_test.cpp ;
run as_bytes_test.cpp ;
run as_writable_bytes_test.cpp ;
compile span_boost_begin_test.cpp ;
compile span_nonmem_data_size_test.cpp ;
run make_span_test.cpp ;
run splitmix64_test.cpp
@@ -417,11 +441,15 @@ run memory_resource_test.cpp ;
run data_test.cpp ;
run size_test.cpp ;
import ../../config/checks/config : requires ;
local CPP11 = [ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_constexpr cxx11_noexcept ] ;
local with-serialization = <library>/boost//serialization/<warnings>off $(warnings-as-errors-off) <undefined-sanitizer>norecover:<link>static $(CPP11) ;
local with-serialization =
<library>/boost/serialization//boost_serialization/<warnings>off
$(warnings-as-errors-off)
<undefined-sanitizer>norecover:<link>static
$(CPP11)
# Serialization no longer builds under classic MinGW
# and <toolset>gcc,<target-os>windows,<address-model>32 fails for some reason
<toolset>gcc,<target-os>windows:<build>no
;
run serialization_nvp_test.cpp : : : $(with-serialization) <undefined-sanitizer>norecover:<build>no ;
run serialization_split_free_test.cpp : : : $(with-serialization) ;
@@ -440,5 +468,17 @@ run yield_prim_pthread_cancel_test.cpp : ;
run pointer_in_range_test.cpp ;
compile pointer_in_range_constexpr_test.cpp ;
run minstd_rand_test.cpp
: : : $(pedantic-errors) ;
use-project /boost/core/swap : ./swap ;
build-project ./swap ;
compile static_assert_test.cpp ;
compile static_assert_test2.cpp ;
compile static_assert_test3.cpp ;
compile-fail static_assert_fail.cpp ;
compile-fail static_assert_fail2.cpp ;
compile-fail static_assert_fail3.cpp ;
compile-fail static_assert_fail4.cpp ;
+4 -3
View File
@@ -19,14 +19,15 @@ template<class T> void test_bit_ceil( T x )
T y = boost::core::bit_ceil( x );
BOOST_TEST( boost::core::has_single_bit( y ) );
BOOST_TEST_GE( +y, +x );
if( x == 0 )
{
BOOST_TEST_EQ( y, 0 );
BOOST_TEST_EQ( y, 1 );
}
else
{
BOOST_TEST( boost::core::has_single_bit( y ) );
BOOST_TEST_GE( +y, +x );
BOOST_TEST_LT( y >> 1, +x );
}
}
+1 -1
View File
@@ -14,4 +14,4 @@ target_link_libraries(quick Boost::core)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
add_custom_target(check VERBATIM COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
+1 -2
View File
@@ -9,7 +9,6 @@ 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)
@@ -18,4 +17,4 @@ target_link_libraries(quick Boost::core)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
add_custom_target(check VERBATIM COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
+17
View File
@@ -9,6 +9,7 @@ Distributed under the Boost Software License, Version 1.0.
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/core/data.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iterator>
class range {
public:
@@ -52,12 +53,28 @@ void test_initializer_list()
BOOST_TEST_EQ(boost::data(l), l.begin());
}
void test_ambiguity_with_std_data()
{
// Note: This preprocessor check should be equivalent to that in boost/core/data.hpp
#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \
(defined(_MSC_VER) && (_MSC_VER >= 1900))
// https://github.com/boostorg/core/issues/206
range c;
using std::data;
using boost::data;
BOOST_TEST_EQ(data(c), c.data());
#endif
}
int main()
{
test_range();
test_const_range();
test_array();
test_initializer_list();
test_ambiguity_with_std_data();
return boost::report_errors();
}
#else
+1 -1
View File
@@ -31,7 +31,7 @@ using std::distance;
*/
// struct C {} doesn't wotk with libc++.
// struct C {} doesn't work with libc++.
typedef std::forward_iterator_tag C;
struct T
+20
View File
@@ -0,0 +1,20 @@
// Copyright 2024 Braden Ganetsky
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/empty_value.hpp>
struct empty {};
// This test ensures private inheritance of `boost::empty_value<T>` for empty `T`.
// With public inheritance, `boost::empty_value<empty>*` could cast to `empty*`.
void test_empty_not_convertible_to_base()
{
const boost::empty_value<empty> x(boost::empty_init);
const empty* x2 = static_cast<const empty*>(&x);
(void)x2;
}
int main()
{
}
+45
View File
@@ -0,0 +1,45 @@
/*
Copyright 2024 Braden Ganetsky
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/core/empty_value.hpp>
/*
Tests workaround for MSVC bug:
https://developercommunity.visualstudio.com/t/Compiler-bug:-Incorrect-C2247-and-C2248/10690025
*/
template<class T>
struct derived
: boost::empty_value<T> {
typedef typename boost::empty_value<T>::type type;
derived(boost::empty_init_t e)
: boost::empty_value<T>(e) { }
};
struct outer {
struct inner_empty { };
struct inner_non_empty {
inner_non_empty()
: value() { }
int value;
};
};
void test()
{
const boost::empty_value<outer> x1(boost::empty_init);
(void)x1;
const boost::empty_value<outer::inner_empty> x2(boost::empty_init);
(void)x2;
const boost::empty_value<outer::inner_non_empty> x3(boost::empty_init);
(void)x3;
const derived<outer> x4(boost::empty_init);
(void)x4;
const derived<outer::inner_empty> x5(boost::empty_init);
(void)x5;
const derived<outer::inner_non_empty> x6(boost::empty_init);
(void)x6;
}
+106
View File
@@ -0,0 +1,106 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
int main()
{
{
char const* p = "12";
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
{
wchar_t const* p = L"12";
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
#if !defined( BOOST_NO_CXX11_CHAR16_T )
{
char16_t const* p = u"12";
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
#endif
#if !defined( BOOST_NO_CXX11_CHAR32_T )
{
char32_t const* p = U"12";
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
{
char8_t const* p = u8"12";
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
#endif
{
int v;
int volatile* p = &v;
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
{
int v;
int const volatile* p = &v;
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
{
char v;
char volatile* p = &v;
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
{
char v;
char const volatile* p = &v;
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
{
wchar_t v;
wchar_t volatile* p = &v;
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
{
wchar_t v;
wchar_t const volatile* p = &v;
BOOST_TEST_EQ( p, p );
BOOST_TEST_NE( p, p + 1 );
}
return boost::report_errors();
}
+10 -1
View File
@@ -1,6 +1,6 @@
// Test BOOST_TEST_EQ with character types
//
// Copyright 2020 Peter Dimov
// Copyright 2020, 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
@@ -19,14 +19,23 @@ int main()
#if !defined(BOOST_NO_CXX11_CHAR16_T)
BOOST_TEST_EQ( u'A', u'A' );
BOOST_TEST_EQ( (char16_t)1, (char16_t)1 );
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
BOOST_TEST_EQ( U'A', U'A' );
BOOST_TEST_EQ( (char32_t)1, (char32_t)1 );
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
BOOST_TEST_EQ( u8'A', u8'A' );
BOOST_TEST_EQ( (char8_t)1, (char8_t)1 );
#endif
return boost::report_errors();
+38
View File
@@ -0,0 +1,38 @@
// Test for boost/core/detail/minstd_rand.hpp
//
// Copyright 2022, 2024 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/minstd_rand.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/cstdint.hpp>
int main()
{
{
boost::detail::minstd_rand rng;
boost::uint_least32_t r1 = rng(), x1 = 48271;
BOOST_TEST_EQ( r1, x1 );
for( int i = 0; i < 1000; ++i ) rng();
boost::uint_least32_t r2 = rng(), x2 = 2076422031;
BOOST_TEST_EQ( r2, x2 );
}
{
boost::detail::minstd_rand rng( 12345 );
boost::uint_least32_t r1 = rng(), x1 = 595905495;
BOOST_TEST_EQ( r1, x1 );
for( int i = 0; i < 1000; ++i ) rng();
boost::uint_least32_t r2 = rng(), x2 = 1065162103;
BOOST_TEST_EQ( r2, x2 );
}
return boost::report_errors();
}
+17
View File
@@ -9,6 +9,7 @@ Distributed under the Boost Software License, Version 1.0.
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/core/size.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iterator>
struct range {
std::size_t size() const {
@@ -28,10 +29,26 @@ void test_array()
BOOST_TEST_EQ(boost::size(a), 4);
}
void test_ambiguity_with_std_size()
{
// Note: This preprocessor check should be equivalent to that in boost/core/size.hpp
#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \
(defined(_MSC_VER) && (_MSC_VER >= 1900))
// https://github.com/boostorg/core/issues/206
range c;
using std::size;
using boost::size;
BOOST_TEST_EQ(size(c), c.size());
#endif
}
int main()
{
test_range();
test_array();
test_ambiguity_with_std_size();
return boost::report_errors();
}
#else
+72
View File
@@ -0,0 +1,72 @@
/*
Copyright 2025 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)
#include <boost/core/span.hpp>
#include <boost/core/lightweight_test.hpp>
constexpr const int array[4]{ 5, 10, 15, 20 };
void test_first()
{
constexpr boost::span<const int> s =
boost::span<const int>(array, 4).first(2);
BOOST_TEST_EQ(s.data(), &array[0]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_last()
{
constexpr boost::span<const int> s =
boost::span<const int>(array, 4).last(2);
BOOST_TEST_EQ(s.data(), &array[2]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_subspan()
{
constexpr boost::span<const int> s =
boost::span<const int>(array, 4).subspan(1, 2);
BOOST_TEST_EQ(s.data(), &array[1]);
BOOST_TEST_EQ(s.size(), 2);
}
void test_index()
{
constexpr const int i = boost::span<const int>(array, 4)[1];
BOOST_TEST_EQ(i, 10);
}
void test_front()
{
constexpr const int i = boost::span<const int>(array, 4).front();
BOOST_TEST_EQ(i, 5);
}
void test_back()
{
constexpr const int i = boost::span<const int>(array, 4).back();
BOOST_TEST_EQ(i, 20);
}
int main()
{
test_first();
test_last();
test_subspan();
test_index();
test_front();
test_back();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif
+18
View File
@@ -25,6 +25,20 @@ struct range {
}
};
struct buffer {
void* data() {
return 0;
}
const void* data() const {
return 0;
}
std::size_t size() const {
return 0;
}
};
struct base { };
struct derived
@@ -138,6 +152,10 @@ void test_range()
const range<int>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<base>,
range<derived>&>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
buffer>));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
const buffer&>));
}
void test_initializer_list()
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright Andrey Semashev 2025.
* 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)
*/
/*
* The test verifies that unqualified calls to data() and size()
* don't cause ambiguity between std:: and boost:: implementations.
* The ambiguity used to be caused by ADL bringing boost::data()/size()
* due to namespace of boost::span and a using-declaration of
* std::data()/size().
*
* https://github.com/boostorg/core/issues/206
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/core/span.hpp>
#include <iterator>
// Note: This preprocessor check should be equivalent to those in boost/core/data.hpp and boost/core/size.hpp
#if (defined(__cpp_lib_nonmember_container_access) && (__cpp_lib_nonmember_container_access >= 201411l)) || \
(defined(_MSC_VER) && (_MSC_VER >= 1900))
#include <boost/core/data.hpp>
#include <boost/core/size.hpp>
int* test_data_ambiguity(boost::span<int> sp)
{
using std::data;
return data(sp);
}
boost::span<int>::size_type test_size_ambiguity(boost::span<int> sp)
{
using std::size;
return size(sp);
}
#endif // (defined(__cpp_lib_nonmember_container_access) ...
#endif // !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)
+11
View File
@@ -0,0 +1,11 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/static_assert.hpp>
BOOST_CORE_STATIC_ASSERT( sizeof(char[1]) != 1 );
int main()
{
}
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/static_assert.hpp>
struct X
{
BOOST_CORE_STATIC_ASSERT( sizeof(char[2]) != 2 );
};
int main()
{
}
+10
View File
@@ -0,0 +1,10 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/static_assert.hpp>
int main()
{
BOOST_CORE_STATIC_ASSERT( sizeof(char[3]) != 3 );
}
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/static_assert.hpp>
template<int C> struct X
{
BOOST_CORE_STATIC_ASSERT( C >= 0 );
};
int main()
{
X< -4 > x;
(void)x;
}
+17
View File
@@ -0,0 +1,17 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/static_assert.hpp>
BOOST_CORE_STATIC_ASSERT( sizeof(char[1]) == 1 );
struct X
{
BOOST_CORE_STATIC_ASSERT( sizeof(char[2]) == 2 );
};
int main()
{
BOOST_CORE_STATIC_ASSERT( sizeof(char[3]) == 3 );
}
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/static_assert.hpp>
template<int A, int B> struct plus
{
static const int value = A + B;
};
BOOST_CORE_STATIC_ASSERT((plus<1, 2>::value == 3));
template<int C> struct X
{
BOOST_CORE_STATIC_ASSERT((plus<C, 1>::value == C + 1));
};
int main()
{
BOOST_CORE_STATIC_ASSERT((plus<3, 4>::value == 7));
X<4> x;
(void)x;
}
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2025 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/detail/static_assert.hpp>
template<int C> struct X
{
BOOST_CORE_STATIC_ASSERT( C >= 0 );
};
int main()
{
X<4> x;
(void)x;
}
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2025 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 <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if !( defined(__cpp_lib_format) && __cpp_lib_format >= 201907L )
BOOST_PRAGMA_MESSAGE( "Test skipped because __cpp_lib_format is not defined to at least 201907L" )
int main() {}
#else
#include <format>
#include <string_view>
int main()
{
BOOST_TEST_EQ( std::format( "{}", boost::core::string_view( "123" ) ), std::format( "{}", std::string_view( "123" ) ) );
BOOST_TEST_EQ( std::format( "{:s}", boost::core::string_view( "123" ) ), std::format( "{:s}", std::string_view( "123" ) ) );
BOOST_TEST_EQ( std::format( "{:^7}", boost::core::string_view( "123" ) ), std::format( "{:^7}", std::string_view( "123" ) ) );
BOOST_TEST_EQ( std::format( "{:-^7}", boost::core::string_view( "123" ) ), std::format( "{:-^7}", std::string_view( "123" ) ) );
return boost::report_errors();
}
#endif
+48
View File
@@ -0,0 +1,48 @@
// Copyright 2021-2024 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/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <string>
template<class T> std::size_t hv( T const& t )
{
return boost::hash<T>()( t );
}
template<class Ch> void test( Ch const* p )
{
std::basic_string<Ch> s( p );
boost::core::basic_string_view<Ch> sv( s );
BOOST_TEST_EQ( hv( s ), hv( sv ) );
}
int main()
{
test( "123" );
test( L"123" );
#if !defined(BOOST_NO_CXX11_CHAR16_T)
test( u"123" );
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
test( U"123" );
#endif
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
test( u8"123" );
#endif
return boost::report_errors();
}
+1 -1
View File
@@ -9,7 +9,7 @@
// objects to be swapped would themselves be from the boost namespace.
// If so, boost::core::invoke_swap itself might be found by argument dependent lookup.
// The implementation of boost::core::invoke_swap resolves this issue by giving
// boost::core::invoke_swap two template argumetns, thereby making it less specialized
// boost::core::invoke_swap two template arguments, thereby making it less specialized
// than std::swap.
#include <boost/core/invoke_swap.hpp>
+1 -1
View File
@@ -12,7 +12,7 @@
//Put test class in the global namespace
#include "./swap_test_class.hpp"
//Provide swap function in gloabl namespace
//Provide swap function in global namespace
void swap(swap_test_class& left, swap_test_class& right)
{
left.swap(right);
+17
View File
@@ -55,6 +55,13 @@ template<class T1, class T2> struct X
template<class T1, class T2> struct Y;
class W
{
public:
virtual void f() = 0;
};
enum E1
{
e1
@@ -122,6 +129,7 @@ int main()
TEST(A);
TEST(B);
TEST(C);
TEST(W);
TEST(E1);
@@ -143,6 +151,9 @@ int main()
TEST(C&);
TEST(C const&);
TEST(W const);
TEST(W&);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
TEST(B&&);
@@ -156,6 +167,8 @@ int main()
TEST(C*);
TEST(C const* volatile*);
TEST(W volatile*);
TEST(void*);
TEST(void const* volatile*);
@@ -307,6 +320,8 @@ int main()
TEST(std::pair<C, C>);
TEST(std::pair<W, W>);
TEST(std::pair<void, void>);
TEST(std::pair<std::pair<void, void>, void>);
@@ -336,9 +351,11 @@ int main()
TEST(X<A const&, B&> volatile&);
TEST(X<C, C>);
TEST(X<W, W>);
TEST(Y<A, B>);
TEST(Y<C, C>);
TEST(Y<W, W>);
TEST(X<std::pair<void, void>, void>);