Compare commits

...

19 Commits

Author SHA1 Message Date
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
Mohammad Nejati 6afe70e09d detail::span_convertible handles void types
fixes #202
2025-09-08 17:02:46 +00:00
24 changed files with 785 additions and 69 deletions
+21 -24
View File
@@ -151,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"
@@ -334,15 +320,26 @@ jobs:
linkflags: -stdlib=libc++
- toolset: clang
compiler: clang++-20
cxxstd: "03,11,14,17,20,2b,2c"
cxxstd: "03,11,14,17,20,23,2c"
os: ubuntu-latest
container: ubuntu:25.04
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
toolset: clang
compiler: clang++-15
@@ -365,14 +362,14 @@ jobs:
- g++-13
- toolset: clang
cxxstd: "03,11,14,17,20,2b"
os: macos-13
- toolset: clang
cxxstd: "03,11,14,17,20,2b"
os: macos-14
- toolset: clang
cxxstd: "03,11,14,17,20,2b"
- toolset: clang
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}}
@@ -680,9 +677,9 @@ jobs:
include:
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-13
- os: macos-14
- os: macos-15
- os: macos-26
runs-on: ${{matrix.os}}
timeout-minutes: 10
@@ -747,9 +744,9 @@ jobs:
include:
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-13
- os: macos-14
- os: macos-15
- os: macos-26
runs-on: ${{matrix.os}}
timeout-minutes: 10
@@ -824,9 +821,9 @@ jobs:
include:
- os: ubuntu-22.04
- os: ubuntu-24.04
- os: macos-13
- os: macos-14
- os: macos-15
- os: macos-26
runs-on: ${{matrix.os}}
timeout-minutes: 20
-1
View File
@@ -16,7 +16,6 @@ target_link_libraries(boost_core
INTERFACE
Boost::assert
Boost::config
Boost::static_assert
Boost::throw_exception
)
+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)](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/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)](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)
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
+1 -8
View File
@@ -27,17 +27,10 @@ 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
TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17,latest
CXXSTD: 14,17,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();
}
-1
View File
@@ -8,7 +8,6 @@ require-b2 5.2 ;
constant boost_dependencies :
/boost/assert//boost_assert
/boost/config//boost_config
/boost/static_assert//boost_static_assert
/boost/throw_exception//boost_throw_exception
;
+1 -1
View File
@@ -37,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]
+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]
``
+22 -22
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>
@@ -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 );
}
@@ -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 );
}
@@ -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 ) );
}
@@ -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 ) );
@@ -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
+8 -2
View File
@@ -23,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>
+10
View File
@@ -14,6 +14,7 @@ import testing ;
project : requirements
<library>/boost/core//boost_core
<library>/boost/static_assert//boost_static_assert
<library>/boost/type_traits//boost_type_traits
<warnings>extra
<toolset>msvc:<warnings-as-errors>on
@@ -469,3 +470,12 @@ run minstd_rand_test.cpp
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 ;
-1
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
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()
+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;
}