1
0
forked from boostorg/core

Compare commits

..

47 Commits

Author SHA1 Message Date
Peter Dimov
85527c4045 More -Wconversion fixes 2023-05-31 20:22:15 +03:00
Peter Dimov
7ab05d5de0 More -Wconversion fixes for GCC 10 and below 2023-05-31 19:54:43 +03:00
Peter Dimov
266fbe6449 Fix -Wconversion warnings 2023-05-31 18:53:35 +03:00
Peter Dimov
fd0de5f538 Add -Wconversion to pedantic-errors 2023-05-31 18:28:33 +03:00
Peter Dimov
350526f7c7 Update documentation 2023-05-31 02:29:32 +03:00
Peter Dimov
06fef712c9 Use MS _byteswap intrinsics 2023-05-30 21:12:25 +03:00
Peter Dimov
b7f7eb4f90 Avoid -Wlong-long under C++03 2023-05-30 19:27:42 +03:00
Peter Dimov
f41b8f38c4 Use __builtin_bswap under GCC and Clang 2023-05-30 19:22:00 +03:00
Peter Dimov
b591214103 Add byteswap to bit.hpp 2023-05-30 19:09:09 +03:00
Peter Dimov
6b9f0cbf57 Update revision history 2023-05-30 06:24:43 +03:00
Peter Dimov
ecee9257d5 Update revision history 2023-05-30 06:20:44 +03:00
Peter Dimov
6c7edac9b1 Fix 32 bit constexpr failures 2023-05-30 04:32:23 +03:00
Peter Dimov
049d3447ca Test 32 bit Windows on Drone 2023-05-30 04:24:28 +03:00
Peter Dimov
b2fe98edf8 Make bit manipulation functions constexpr on MSVC 19.25+. Closes #109. 2023-05-30 02:56:37 +03:00
Peter Dimov
42c8898d24 Add constexpr tests for bit.hpp. Refs #109. 2023-05-29 21:59:37 +03:00
Peter Dimov
f2eab6d6ff Update ci.yml 2023-05-21 15:26:47 +03:00
Peter Dimov
36fa78f53c Add support for incomplete classes to type_name<>. Refs #145. 2023-05-21 05:52:33 +03:00
Peter Dimov
97606908b7 Add type_name<> tests for incomplete types. Refs #145. 2023-05-21 05:40:24 +03:00
Peter Dimov
5eb54d1d36 Fix type_name<> for cv-qualified member pointers without variadic templates. Refs #145. 2023-05-21 05:33:21 +03:00
Peter Dimov
c91f8fabff Test whether type_name<> compiles for member pointers even without variadic templates. Refs #145. 2023-05-21 05:16:30 +03:00
Peter Dimov
5904fb5636 Disable call to ::_seterrormode when WINAPI_FAMILY is defined to something other than WINAPI_FAMILY_DESKTOP_APP. Refs #143. 2023-04-15 19:36:12 +03:00
Glen Fernandes
39978bde2b Add note about identity being moved from functional 2023-02-24 00:19:13 -05:00
Glen Fernandes
d5fa9ae50f Fix and update documentation and release notes 2023-02-24 00:16:56 -05:00
Peter Dimov
2814b4ca1c Update documentation 2023-02-22 20:18:01 +02:00
Glen Fernandes
c4e420f69d Use boost::data in boost::span 2023-02-22 09:40:54 -05:00
Peter Dimov
94628cb2f9 Use undefined-sanitizer=norecover instead of cxxflags 2023-02-21 17:47:38 +02:00
Peter Dimov
19f9aa93e1 Merge branch 'feature/drone' into develop 2023-02-21 07:58:29 +02:00
Peter Dimov
2691efd1ca Re-disable serialization_nvp_test under UBSan; link=static doesn't help there 2023-02-21 06:29:10 +02:00
Peter Dimov
b6b1498275 Use link=static instead of visibility=global (which doesn't help) 2023-02-21 06:11:44 +02:00
Glen Fernandes
379899ef15 Move identity from functional to core 2023-02-20 23:02:30 -05:00
Peter Dimov
3ab949d321 Only use visibility=global in UBSan builds 2023-02-21 05:32:28 +02:00
Peter Dimov
dbf0ea98b9 Add visibility=global to serialization tests because of UBSan; disable serialization_nvp_test for GCC/UBSan as well 2023-02-21 05:25:20 +02:00
Peter Dimov
5afc91d52d Change _EQ(max_align, alignof(std::max_align_t)) to _GE unconditionally, because macOS 12.4/M1 also fails (16 > 8) 2023-02-21 05:23:43 +02:00
Peter Dimov
f2a1532105 Add macOS 12.4 (M1) to Drone 2023-02-21 04:55:39 +02:00
Peter Dimov
64e59db1f6 Update serialization_construct_data_test 2023-02-21 02:39:49 +02:00
Peter Dimov
ceb4fff8fc Avoid missing braces warning in serialization_construct_data_test 2023-02-21 02:23:52 +02:00
Peter Dimov
0be25e19cc Add load_construct_data_adl, save_construct_data_adl 2023-02-21 02:04:39 +02:00
Peter Dimov
6debbeb377 Disable serialization_nvp_test under Clang/UBSan 2023-02-21 01:34:35 +02:00
Peter Dimov
4b859e3d39 Use friend class, omission of class is C++11 2023-02-20 21:17:55 +02:00
Peter Dimov
38037b45f1 Add boost::core::split_member 2023-02-20 21:00:26 +02:00
Peter Dimov
7664d7ab7e Disable -Wdeprecated-copy in serialization_*_test 2023-02-20 20:39:03 +02:00
Peter Dimov
20d89b69db Add missing initializers to avoid warnings from GCC 4.x 2023-02-20 20:19:59 +02:00
Peter Dimov
89c5a78129 Add boost/core/serialization.hpp, serialization_nvp_test, serialization_split_free_test 2023-02-20 20:06:19 +02:00
Glen Fernandes
249c5bece2 Implement data and size functions 2023-02-17 15:27:36 -05:00
Glen Fernandes
8977da6f50 Update documentation 2023-01-30 16:19:31 -05:00
Glen Fernandes
edc0d935c0 Implement make_span 2023-01-28 13:07:33 -05:00
Glen Fernandes
7736b0b8ce span support for initializer_list 2023-01-28 12:20:59 -05:00
54 changed files with 2467 additions and 128 deletions

View File

@@ -344,27 +344,39 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,17,20,2b' } + ubsan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,17,20,2b' } + asan,
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
),
windows_pipeline(
"Windows VS2015 msvc-14.0",
"cppalliance/dronevs2015",
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest' },
{ TOOLSET: 'msvc-14.0', CXXSTD: '14,latest', ADDRMD: '32,64' },
),
windows_pipeline(
"Windows VS2017 msvc-14.1",
"cppalliance/dronevs2017",
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest', ADDRMD: '32,64' },
),
windows_pipeline(
"Windows VS2019 msvc-14.2",
"cppalliance/dronevs2019",
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' },
{ TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest', ADDRMD: '32,64' },
),
windows_pipeline(
"Windows VS2022 msvc-14.3",
"cppalliance/dronevs2022:1",
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' },
{ TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest', ADDRMD: '32,64' },
),
]

View File

@@ -5,6 +5,7 @@
# https://www.boost.org/LICENSE_1_0.txt
set -ex
export PATH=~/.local/bin:/usr/local/bin:$PATH
DRONE_BUILD_DIR=$(pwd)

View File

@@ -466,7 +466,7 @@ jobs:
if [ -n "${{matrix.ubsan}}" ]
then
export UBSAN_OPTIONS="print_stacktrace=1"
B2_ARGS+=("cxxflags=-fsanitize=undefined -fno-sanitize-recover=undefined" "linkflags=-fsanitize=undefined -fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global")
B2_ARGS+=("undefined-sanitizer=norecover" "linkflags=-fuse-ld=gold" "define=UBSAN=1" "debug-symbols=on" "visibility=global")
fi
if [ -n "${{matrix.cxxflags}}" ]
then
@@ -700,3 +700,183 @@ jobs:
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error
windows-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Use library with add_subdirectory (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use library with add_subdirectory (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_subdir_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
- name: Install (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Debug
- name: Install (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target install --config Release
- name: Use the installed library (Debug)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=C:/cmake-prefix ..
cmake --build . --config Debug
ctest --output-on-failure --no-tests=error -C Debug
- name: Use the installed library (Release)
shell: cmd
run: |
cd ../boost-root/libs/%LIBRARY%/test/cmake_install_test/__build__
cmake --build . --config Release
ctest --output-on-failure --no-tests=error -C Release
windows-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
- name: Configure
shell: cmd
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=%LIBRARY% -DBUILD_TESTING=ON ..
- name: Build tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Debug
- name: Run tests (Debug)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Debug
- name: Build tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
cmake --build . --target tests --config Release
- name: Run tests (Release)
shell: cmd
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error -C Release

View File

@@ -33,6 +33,11 @@ namespace core
template<class To, class From>
To bit_cast(From const& from) noexcept;
// byteswap
template<class T>
constexpr T byteswap(T x) noexcept;
// Integral powers of 2
template<class T>
@@ -102,6 +107,17 @@ constant expression context.
[endsect]
[section byteswap]
`template<class T> constexpr T byteswap(T x) noexcept;`
* *Requires:* `T` must be an integer type (i.e. one of `char`, `signed char`,
`unsigned char`, `short`, `unsigned short`, `int`, `unsigned int`, `long`,
`unsigned long`, `long long`, `unsigned long long`) without padding bits.
* *Returns:* `x` with the storage bytes reversed.
[endsect]
[section Integral powers of 2]
`template<class T> constexpr bool has_single_bit(T x) noexcept;`

View File

@@ -7,6 +7,16 @@
[section Revision History]
[section Changes in 1.83.0]
* Added support for incomplete types to [link core.type_name `boost::core::type_name`].
* Bit manipulation functions in [link core.bit `boost/core/bit.hpp`] are now
`constexpr` on recent MSVC versions (VS2019 update 5 and later.)
* Added `boost::core::byteswap` (an implementation of `std::byteswap` from
C++23) to [link core.bit `boost/core/bit.hpp`].
[endsect]
[section Changes in 1.82.0]
* Added [link core.snprintf `boost/core/snprintf.hpp`] header with portable definitions of `snprintf`, `vsnprintf` and
@@ -22,6 +32,15 @@
`boost::core::max_align`, the alignment of `max_align_t`.
* Added [link core.memory_resource `boost::core::memory_resource`], a portable equivalent of `std::pmr::memory_resource`
from C++17.
* Added [link core.serialization `boost/core/serialization.hpp`], a collection of primitives allowing libraries to
implement Boost.Serialization support for their types without including a Serialization header and thereby making
their libraries depend on Serialization.
* Added [link core.data `boost::data`], an implementation of `std::data`.
* Added [link core.size `boost::size`], an implementation of `std::size`.
* Updated `boost::span` to use `boost::data` which adds support for range
construction from an `std::initializer_list`.
* Added [link core.identity `boost::identity`], an implementation of
`std::identity`. This facility has been moved from Boost.Functional.
[endsect]

View File

@@ -47,6 +47,7 @@ criteria for inclusion is that the utility component be:
[include bit.qbk]
[include checked_delete.qbk]
[include cmath.qbk]
[include data.qbk]
[include default_allocator.qbk]
[include demangle.qbk]
[include empty_value.qbk]
@@ -54,10 +55,12 @@ criteria for inclusion is that the utility component be:
[include exchange.qbk]
[include explicit_operator_bool.qbk]
[include first_scalar.qbk]
[include identity.qbk]
[include ignore_unused.qbk]
[include is_same.qbk]
[include launder.qbk]
[include lightweight_test.qbk]
[include make_span.qbk]
[include max_align.qbk]
[include memory_resource.qbk]
[include no_exceptions_support.qbk]
@@ -70,6 +73,8 @@ criteria for inclusion is that the utility component be:
[include quick_exit.qbk]
[include ref.qbk]
[include scoped_enum.qbk]
[include serialization.qbk]
[include size.qbk]
[include span.qbk]
[include swap.qbk]
[include typeinfo.qbk]

67
doc/data.qbk Normal file
View File

@@ -0,0 +1,67 @@
[/
Copyright 2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:data data]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
The header <boost/core/data.hpp> provides function templates `data`
to obtain the pointer to the first element in a range.
[endsect]
[section Reference]
```
namespace boost {
template<class C>
constexpr auto
data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data());
template<class C>
constexpr auto
data(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data());
template<class T, std::size_t N>
constexpr T*
data(T(&a)[N]) noexcept;
template<class T>
constexpr const T*
data(std::initializer_list<T> l) noexcept;
} /* boost */
```
[section Functions]
[variablelist
[[`template<class C> constexpr auto data(C& c) noexcept(noexcept(c.data())) ->
decltype(c.data());`]
[Returns `c.data()`.]]
[[`template<class C> constexpr auto data(const C& c)
noexcept(noexcept(c.data())) -> decltype(c.data());`]
[Returns `c.data()`.]]
[[`template<class T, std::size_t N> constexpr T* data(T(&a)[N]) noexcept;`]
[Returns `a`.]]
[[`template<class T> constexpr const T* data(std::initializer_list<T> l)
noexcept;`]
[Returns `l.begin()`.]]]
[endsect]
[endsect]
[endsect]

61
doc/identity.qbk Normal file
View File

@@ -0,0 +1,61 @@
[/
Copyright 2021-2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:identity identity]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
The header <boost/functional/identity.hpp> provides the function object
`boost::identity` whose `operator()` returns its argument. It is an
implementation of C++20's `std::identity` that supports C++03 and above.
[endsect]
[section Example]
It is commonly used as the default projection in constrained algorithms.
```
template<class Range, class Projection = boost::identity>
void print(Range&& range, Projection projection = {});
```
[endsect]
[section Reference]
```
namespace boost {
struct identity {
using is_transparent = unspecified;
template<class T>
T&& operator()(T&& value) const noexcept;
};
} /* boost */
```
[section Operators]
[variablelist
[[`template<class T> T&& operator()(T&& value) const noexcept;`]
[Returns `std::forward<T>(value)`.]]]
[endsect]
[endsect]
[endsect]

81
doc/make_span.qbk Normal file
View File

@@ -0,0 +1,81 @@
[/
Copyright 2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:make_span make_span]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
The header <boost/core/make_span.hpp> provides function templates `make_span`
to conveniently create `span` objects. They are useful before C++17 where Class
Template Argument Deduction (CTAD) is not available.
[endsect]
[section Reference]
```
namespace boost {
template<class I>
constexpr span<I>
make_span(I* d, std::size_t n) noexcept;
template<class I>
constexpr span<I>
make_span(I* b, I* e) noexcept;
template<class T, std::size_t N>
constexpr span<T, N>
make_span(T(&a)[N]) noexcept;
template<class T, std::size_t N>
constexpr span<T, N>
make_span(std::array<T, N>& a) noexcept;
template<class T, std::size_t N>
constexpr span<const T, N>
make_span(const std::array<T, N>& a) noexcept;
template<class R>
span<remove_pointer_t<iterator_t<R> > >
make_span(R&& r);
} /* boost */
```
[section Functions]
[variablelist
[[`template<class I> span<I> make_span(I* f, std::size_t c);`]
[Returns `span<I>(f, c)`.]]
[[`template<class I> span<I> make_span(I* f, I* l);`]
[Returns `span<I>(f, l)`.]]
[[`template<class T, std::size_t N> span<T, N> make_span(T(&a)[N]);`]
[Returns `span<T, N>(a)`.]]
[[`template<class T, std::size_t N> span<T, N>
make_span(std::array<T, N>& a);`]
[Returns `span<T, N>(a)`.]]
[[`template<class T, std::size_t N> span<const T, N>
make_span(const std::array<T, N>& a);`]
[Returns `span<const T, N>(a)`.]]
[[`template<class R>
span<remove_pointer_t<iterator_t<R> > >
make_span(R&& r);`]
[Returns `span<remove_pointer_t<iterator_t<R> > >(std::forward<R>(r))`.]]]
[endsect]
[endsect]
[endsect]

145
doc/serialization.qbk Normal file
View File

@@ -0,0 +1,145 @@
[/
Copyright 2023 Peter Dimov
Distributed under the Boost Software License, Version 1.0.
https://boost.org/LICENSE_1_0.txt
]
[section:serialization serialization]
[simplesect Authors]
* Peter Dimov
[endsimplesect]
[section Header <boost/core/serialization.hpp>]
The header `<boost/core/serialization.hpp>` implements primitives
that are necessary to implement Boost.Serialization support without
including a Boost.Serialization header and thereby making a library
dependent on Boost.Serialization.
[section Synopsis]
``
#include <boost/core/nvp.hpp>
namespace boost
{
namespace serialization
{
// forward declarations
template<class T> struct version;
class access;
// core_version_type
struct core_version_type;
} // namespace serialization
namespace core
{
// nvp
using serialization::nvp;
using serialization::make_nvp;
// split_free
template<class Ar, class T> void split_free( Ar& ar, T& t, unsigned int v );
// split_member
template<class Ar, class T> void split_member( Ar& ar, T& t, unsigned int v );
// load_construct_data_adl
template<class Ar, class T> void load_construct_data_adl( Ar& ar, T* t, unsigned int v );
// save_construct_data_adl
template<class Ar, class T> void save_construct_data_adl( Ar& ar, T const* t, unsigned int v );
} // namespace core
} // namespace boost
``
[endsect]
[section `core_version_type`]
``
struct core_version_type
{
unsigned int version_;
core_version_type( unsigned int version ): version_( version ) {}
operator unsigned int () const { return version_; }
};
``
`core_version_type` is a Core reimplementation of
`boost::serialization::version_type`, needed to call ADL serialization
primitives such as, for example, `load_construct_data` below.
It's defined in the `serialization` namespace instead of the `core`
namespace because its only purpose is to add `boost::serialization` to
the list of the associated namespaces of the corresponding call.
[endsect]
[section `split_free`]
`template<class Ar, class T> inline void split_free( Ar& ar, T& t, unsigned int v );`
`boost::core::split_free` is a Core reimplementation of
`boost::serialization::split_free`.
* *Effects:*
* If `Ar::is_saving::value` is `true`, calls `save( ar, t, core_version_type( v ) )`;
* Otherwise, calls `load( ar, t, core_version_type( v ) )`.
[endsect]
[section `split_member`]
`template<class Ar, class T> void split_member( Ar& ar, T& t, unsigned int v );`
`boost::core::split_member` is a Core reimplementation of
`boost::serialization::split_member`.
* *Effects:*
* If `Ar::is_saving::value` is `true`, calls `t.save( ar, v )`;
* Otherwise, calls `t.load( ar, v )`.
[endsect]
[section `load_construct_data_adl`]
`template<class Ar, class T> void load_construct_data_adl( Ar& ar, T* t, unsigned int v );`
`boost::core::load_construct_data_adl` is a Core reimplementation of
`boost::serialization::load_construct_data_adl`.
* *Effects:* `load_construct_data( ar, t, serialization::core_version_type( v ) );`.
[endsect]
[section `save_construct_data_adl`]
`template<class Ar, class T> void save_construct_data_adl( Ar& ar, T const* t, unsigned int v );`
`boost::core::save_construct_data_adl` is a Core reimplementation of
`boost::serialization::save_construct_data_adl`.
* *Effects:* `save_construct_data( ar, t, serialization::core_version_type( v ) );`.
[endsect]
[endsect]
[endsect]

54
doc/size.qbk Normal file
View File

@@ -0,0 +1,54 @@
[/
Copyright 2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
]
[section:size size]
[simplesect Authors]
* Glen Fernandes
[endsimplesect]
[section Overview]
The header <boost/core/size.hpp> provides function templates `size` to obtain
the number of elements in a range.
[endsect]
[section Reference]
```
namespace boost {
template<class C>
constexpr auto
size(const C& c) noexcept(noexcept(c.size())) -> decltype(c.size());
template<class T, std::size_t N>
constexpr std::size_t
size(T(&)[N]) noexcept;
} /* boost */
```
[section Functions]
[variablelist
[[`template<class C> constexpr auto size(const C& c)
noexcept(noexcept(c.size())) -> decltype(c.size());`]
[Returns `c.size()`.]]
[[`template<class T, std::size_t N> constexpr std::size_t size(T(&)[N])
noexcept;`]
[Returns `N`.]]]
[endsect]
[endsect]
[endsect]

View File

@@ -149,7 +149,7 @@ template<class T, std::size_t N>
span(const std::array<T, N>&) -> span<const T, N>;
template<class R>
span(R&&) -> span<std::remove_pointer_t<decltype(std::declval<R&>().data())> >;
span(R&&) -> span<remove_pointer_t<iterator_t<R> > >;
template<class T, std::size_t E>
span<const std::byte, E == dynamic_extent ? dynamic_extent : sizeof(T) * E>
@@ -227,13 +227,13 @@ constexpr span(R&& r);`]
[`remove_cvref_t<R>` is not a specialization of `span`,]
[`remove_cvref_t<R>` is not a specialization of `array`,]
[`is_array_v<remove_cvref_t<R>>` is `false`,]
[`r.data()` is well-formed and
`is_convertible_v<remove_pointer_t<decltype(declval<R&>().data())>(*)[],
[`data(r)` is well-formed and
`is_convertible_v<remove_pointer_t<iterator_t<R> >(*)[],
T(*)[]>` is `true`, and]
[`r.size()` is well-formed and
`is_convertible_v<decltype(declval<R&>().size()), size_t>` is `true`.]]]]
[[Effects][Constructs a `span` with data `r.data()` and size `r.size()`.]]
[[Throws][What and when r.data() and r.size() throw.]]]]]
[[Effects][Constructs a `span` with data `data(r)` and size `r.size()`.]]
[[Throws][What and when data(r) and r.size() throw.]]]]]
[[`explicit(E != dynamic_extent && N == dynamic_extent)
template<class U, std::size_t N>
constexpr span(const span<U, N>& s) noexcept;`]

View File

@@ -20,6 +20,7 @@
#include <boost/cstdint.hpp>
#include <limits>
#include <cstring>
#include <cstdlib>
#if defined(_MSC_VER)
@@ -38,6 +39,10 @@
#endif // defined(_MSC_VER)
#if defined(BOOST_MSVC) && BOOST_MSVC >= 1925
# define BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL
#endif
namespace boost
{
namespace core
@@ -102,10 +107,51 @@ BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
namespace detail
{
#if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
if( __builtin_is_constant_evaluated() )
{
constexpr unsigned char mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 };
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return mod37[ x % 37 ];
}
else
{
unsigned long r;
if( _BitScanReverse( &r, x ) )
{
return 31 - static_cast<int>( r );
}
else
{
return 32;
}
}
}
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
}
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
}
#elif defined(_MSC_VER)
inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER)
unsigned long r;
if( _BitScanReverse( &r, x ) )
@@ -116,44 +162,6 @@ inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
return 32;
}
#else
static unsigned char const mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 };
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return mod37[ x % 37 ];
#endif
}
inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER) && defined(_M_X64)
unsigned long r;
if( _BitScanReverse64( &r, x ) )
{
return 63 - static_cast<int>( r );
}
else
{
return 64;
}
#else
return static_cast<boost::uint32_t>( x >> 32 ) != 0?
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
#endif
}
inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
@@ -166,10 +174,98 @@ inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
}
#else
inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
static unsigned char const mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 };
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return mod37[ x % 37 ];
}
inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
}
inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
}
#endif
#if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
if( __builtin_is_constant_evaluated() )
{
return static_cast<boost::uint32_t>( x >> 32 ) != 0?
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
}
else
{
unsigned long r;
if( _BitScanReverse64( &r, x ) )
{
return 63 - static_cast<int>( r );
}
else
{
return 64;
}
}
}
#elif defined(_MSC_VER) && defined(_M_X64)
inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
unsigned long r;
if( _BitScanReverse64( &r, x ) )
{
return 63 - static_cast<int>( r );
}
else
{
return 64;
}
}
#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
return static_cast<boost::uint32_t>( x >> 32 ) != 0?
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
}
#else
inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
return static_cast<boost::uint32_t>( x >> 32 ) != 0?
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
}
#endif
} // namespace detail
template<class T>
int countl_zero( T x ) BOOST_NOEXCEPT
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 );
@@ -250,10 +346,44 @@ BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
namespace detail
{
#if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
if( __builtin_is_constant_evaluated() )
{
constexpr unsigned char mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 };
return mod37[ ( -(boost::int32_t)x & x ) % 37 ];
}
else
{
unsigned long r;
if( _BitScanForward( &r, x ) )
{
return static_cast<int>( r );
}
else
{
return 32;
}
}
}
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
}
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
}
#elif defined(_MSC_VER)
inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER)
unsigned long r;
if( _BitScanForward( &r, x ) )
@@ -264,37 +394,6 @@ inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
return 32;
}
#else
static unsigned char const mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 };
return mod37[ ( -(boost::int32_t)x & x ) % 37 ];
#endif
}
inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
#if defined(_MSC_VER) && defined(_M_X64)
unsigned long r;
if( _BitScanForward64( &r, x ) )
{
return static_cast<int>( r );
}
else
{
return 64;
}
#else
return static_cast<boost::uint32_t>( x ) != 0?
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
#endif
}
inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
@@ -307,10 +406,91 @@ inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
}
#else
inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
static unsigned char const mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 };
return mod37[ ( -(boost::int32_t)x & x ) % 37 ];
}
inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
}
inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
{
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
}
#endif
#if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
if( __builtin_is_constant_evaluated() )
{
return static_cast<boost::uint32_t>( x ) != 0?
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
}
else
{
unsigned long r;
if( _BitScanForward64( &r, x ) )
{
return static_cast<int>( r );
}
else
{
return 64;
}
}
}
#elif defined(_MSC_VER) && defined(_M_X64)
inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
unsigned long r;
if( _BitScanForward64( &r, x ) )
{
return static_cast<int>( r );
}
else
{
return 64;
}
}
#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
return static_cast<boost::uint32_t>( x ) != 0?
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
}
#else
inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
return static_cast<boost::uint32_t>( x ) != 0?
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
}
#endif
} // namespace detail
template<class T>
int countr_zero( T x ) BOOST_NOEXCEPT
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 );
@@ -446,7 +626,7 @@ 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 );
unsigned const mask = std::numeric_limits<T>::digits - 1;
return x << (s & mask) | x >> ((-s) & mask);
return static_cast<T>( x << (static_cast<unsigned>( s ) & mask) | x >> (static_cast<unsigned>( -s ) & mask) );
}
template<class T>
@@ -455,7 +635,7 @@ 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 );
unsigned const mask = std::numeric_limits<T>::digits - 1;
return x >> (s & mask) | x << ((-s) & mask);
return static_cast<T>( x >> (static_cast<unsigned>( s ) & mask) | x << (static_cast<unsigned>( -s ) & mask) );
}
// integral powers of 2
@@ -484,7 +664,7 @@ BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
return x == 0? 0: T(1) << ( boost::core::bit_width( x ) - 1 );
return x == 0? T(0): static_cast<T>( T(1) << ( boost::core::bit_width( x ) - 1 ) );
}
namespace detail
@@ -613,6 +793,117 @@ typedef endian::type endian_type;
#undef BOOST_CORE_BIT_NATIVE_INITIALIZER
// byteswap
namespace detail
{
BOOST_CONSTEXPR inline boost::uint8_t byteswap_impl( boost::uint8_t x ) BOOST_NOEXCEPT
{
return x;
}
BOOST_CONSTEXPR inline boost::uint16_t byteswap_impl( boost::uint16_t x ) BOOST_NOEXCEPT
{
return static_cast<boost::uint16_t>( x << 8 | x >> 8 );
}
#if defined(__GNUC__) || defined(__clang__)
BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
return __builtin_bswap32( x );
}
BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
return __builtin_bswap64( x );
}
#elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
if( __builtin_is_constant_evaluated() )
{
boost::uint32_t step16 = x << 16 | x >> 16;
return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
}
else
{
return _byteswap_ulong( x );
}
}
BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
if( __builtin_is_constant_evaluated() )
{
boost::uint64_t step32 = x << 32 | x >> 32;
boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
}
else
{
return _byteswap_uint64( x );
}
}
#elif defined(_MSC_VER)
inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
return _byteswap_ulong( x );
}
inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
return _byteswap_uint64( x );
}
#else
BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
{
boost::uint32_t step16 = x << 16 | x >> 16;
return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
}
BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
{
boost::uint64_t step32 = x << 32 | x >> 32;
boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
}
#endif
} // namespace detail
template<class T> BOOST_CXX14_CONSTEXPR T byteswap( T x ) BOOST_NOEXCEPT
{
BOOST_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_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
{
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint8_t>( x ) ) );
}
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
{
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint16_t>( x ) ) );
}
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
{
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint32_t>( x ) ) );
}
else
{
return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint64_t>( x ) ) );
}
}
} // namespace core
} // namespace boost

View File

@@ -0,0 +1,46 @@
/*
Copyright 2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_DATA_HPP
#define BOOST_CORE_DATA_HPP
#include <initializer_list>
#include <cstddef>
namespace boost {
template<class C>
inline constexpr auto
data(C& c) noexcept(noexcept(c.data())) -> decltype(c.data())
{
return c.data();
}
template<class C>
inline constexpr auto
data(const C& c) noexcept(noexcept(c.data())) -> decltype(c.data())
{
return c.data();
}
template<class T, std::size_t N>
inline constexpr T*
data(T(&a)[N]) noexcept
{
return a;
}
template<class T>
inline constexpr const T*
data(std::initializer_list<T> l) noexcept
{
return l.begin();
}
} /* boost */
#endif

View File

@@ -35,9 +35,13 @@ inline void lwt_unattended()
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
# endif
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY == 100 /*WINAPI_FAMILY_DESKTOP_APP*/
// disable message box on crash
::_seterrormode( /*SEM_NOGPFAULTERRORBOX*/ 0x0002 );
#endif
# if defined(__clang__)
# pragma clang diagnostic pop
# endif

View File

@@ -0,0 +1,61 @@
/*
Copyright 2021-2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_IDENTITY_HPP
#define BOOST_CORE_IDENTITY_HPP
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#include <utility>
#endif
namespace boost {
struct identity {
typedef void is_transparent;
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class T>
BOOST_CONSTEXPR T&& operator()(T&& value) const BOOST_NOEXCEPT {
return std::forward<T>(value);
}
#else
template<class T>
BOOST_CONSTEXPR const T& operator()(const T& value) const BOOST_NOEXCEPT {
return value;
}
template<class T>
BOOST_CONSTEXPR T& operator()(T& value) const BOOST_NOEXCEPT {
return value;
}
#endif
template<class>
struct result { };
template<class T>
struct result<identity(T&)> {
typedef T& type;
};
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class T>
struct result<identity(T)> {
typedef T&& type;
};
template<class T>
struct result<identity(T&&)> {
typedef T&& type;
};
#endif
};
} /* boost */
#endif

View File

@@ -0,0 +1,59 @@
/*
Copyright 2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_MAKE_SPAN_HPP
#define BOOST_CORE_MAKE_SPAN_HPP
#include <boost/core/span.hpp>
namespace boost {
template<class I>
inline constexpr span<I>
make_span(I* f, std::size_t c) noexcept
{
return span<I>(f, c);
}
template<class I>
inline constexpr span<I>
make_span(I* f, I* l) noexcept
{
return span<I>(f, l);
}
template<class T, std::size_t N>
inline constexpr span<T, N>
make_span(T(&a)[N]) noexcept
{
return span<T, N>(a);
}
template<class T, std::size_t N>
inline constexpr span<T, N>
make_span(std::array<T, N>& a) noexcept
{
return span<T, N>(a);
}
template<class T, std::size_t N>
inline constexpr span<const T, N>
make_span(const std::array<T, N>& a) noexcept
{
return span<const T, N>(a);
}
template<class R>
inline span<typename detail::span_data<R>::type>
make_span(R&& r)
{
return span<typename detail::span_data<R>::type>(std::forward<R>(r));
}
} /* boost */
#endif

View File

@@ -0,0 +1,131 @@
#ifndef BOOST_CORE_SERIALIZATION_HPP_INCLUDED
#define BOOST_CORE_SERIALIZATION_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
//
// Utilities needed to implement serialization support
// without including a Boost.Serialization header
#include <boost/core/nvp.hpp>
#include <cstddef>
namespace boost
{
namespace serialization
{
// Forward declarations (needed for specializations)
template<class T> struct version;
class access;
// Our own version_type replacement. This has to be in
// the `serialization` namespace, because its only purpose
// is to add `serialization` as an associated namespace.
struct core_version_type
{
unsigned int version_;
core_version_type( unsigned int version ): version_( version ) {}
operator unsigned int () const { return version_; }
};
} // namespace serialization
namespace core
{
// nvp
using serialization::nvp;
using serialization::make_nvp;
// split_free
namespace detail
{
template<bool IsSaving> struct load_or_save_f;
template<> struct load_or_save_f<true>
{
template<class A, class T> void operator()( A& a, T& t, unsigned int v ) const
{
save( a, t, serialization::core_version_type( v ) );
}
};
template<> struct load_or_save_f<false>
{
template<class A, class T> void operator()( A& a, T& t, unsigned int v ) const
{
load( a, t, serialization::core_version_type( v ) );
}
};
} // namespace detail
template<class A, class T> inline void split_free( A& a, T& t, unsigned int v )
{
detail::load_or_save_f< A::is_saving::value >()( a, t, v );
}
// split_member
namespace detail
{
template<bool IsSaving, class Access = serialization::access> struct load_or_save_m;
template<class Access> struct load_or_save_m<true, Access>
{
template<class A, class T> void operator()( A& a, T const& t, unsigned int v ) const
{
Access::member_save( a, t, v );
}
};
template<class Access> struct load_or_save_m<false, Access>
{
template<class A, class T> void operator()( A& a, T& t, unsigned int v ) const
{
Access::member_load( a, t, v );
}
};
} // namespace detail
template<class A, class T> inline void split_member( A& a, T& t, unsigned int v )
{
detail::load_or_save_m< A::is_saving::value >()( a, t, v );
}
// load_construct_data_adl
template<class Ar, class T> void load_construct_data_adl( Ar& ar, T* t, unsigned int v )
{
load_construct_data( ar, t, serialization::core_version_type( v ) );
}
// save_construct_data_adl
template<class Ar, class T> void save_construct_data_adl( Ar& ar, T const* t, unsigned int v )
{
save_construct_data( ar, t, serialization::core_version_type( v ) );
}
} // namespace core
} // namespace boost
#endif // #ifndef BOOST_CORE_SERIALIZATION_HPP_INCLUDED

View File

@@ -0,0 +1,31 @@
/*
Copyright 2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_CORE_SIZE_HPP
#define BOOST_CORE_SIZE_HPP
#include <cstddef>
namespace boost {
template<class C>
inline constexpr auto
size(const C& c) noexcept(noexcept(c.size())) -> decltype(c.size())
{
return c.size();
}
template<class T, std::size_t N>
inline constexpr std::size_t
size(T(&)[N]) noexcept
{
return N;
}
} /* boost */
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2019 Glen Joseph Fernandes
Copyright 2019-2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -8,10 +8,10 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_CORE_SPAN_HPP
#define BOOST_CORE_SPAN_HPP
#include <boost/core/data.hpp>
#include <array>
#include <iterator>
#include <type_traits>
#include <cstddef>
namespace boost {
@@ -39,10 +39,8 @@ struct span_compatible {
};
template<class T>
struct span_uncvref {
typedef typename std::remove_cv<typename
std::remove_reference<T>::type>::type type;
};
using span_uncvref = typename std::remove_cv<typename
std::remove_reference<T>::type>::type;
template<class>
struct span_is_span {
@@ -64,15 +62,16 @@ struct span_is_array<std::array<T, N> > {
static constexpr bool value = true;
};
template<class T>
using span_ptr = decltype(boost::data(std::declval<T&>()));
template<class, class = void>
struct span_data { };
template<class T>
struct span_data<T,
typename std::enable_if<std::is_pointer<decltype(std::declval<T
&>().data())>::value>::type> {
typedef typename std::remove_pointer<decltype(std::declval<T
&>().data())>::type type;
typename std::enable_if<std::is_pointer<span_ptr<T> >::value>::type> {
typedef typename std::remove_pointer<span_ptr<T> >::type type;
};
template<class, class, class = void>
@@ -102,9 +101,9 @@ template<class R, class T>
struct span_is_range {
static constexpr bool value = (std::is_const<T>::value ||
std::is_lvalue_reference<R>::value) &&
!span_is_span<typename span_uncvref<R>::type>::value &&
!span_is_array<typename span_uncvref<R>::type>::value &&
!std::is_array<typename span_uncvref<R>::type>::value &&
!span_is_span<span_uncvref<R> >::value &&
!span_is_array<span_uncvref<R> >::value &&
!std::is_array<span_uncvref<R> >::value &&
span_has_data<R, T>::value &&
span_has_size<R>::value;
};
@@ -224,15 +223,16 @@ public:
template<class R,
typename std::enable_if<E == dynamic_extent &&
detail::span_is_range<R, T>::value, int>::type = 0>
constexpr span(R&& r) noexcept(noexcept(r.data()) && noexcept(r.size()))
: s_(r.data(), r.size()) { }
constexpr span(R&& r) noexcept(noexcept(boost::data(r)) &&
noexcept(r.size()))
: s_(boost::data(r), r.size()) { }
template<class R,
typename std::enable_if<E != dynamic_extent &&
detail::span_is_range<R, T>::value, int>::type = 0>
explicit constexpr span(R&& r) noexcept(noexcept(r.data()) &&
explicit constexpr span(R&& r) noexcept(noexcept(boost::data(r)) &&
noexcept(r.size()))
: s_(r.data(), r.size()) { }
: s_(boost::data(r), r.size()) { }
template<class U, std::size_t N,
typename std::enable_if<detail::span_implicit<E, N>::value &&

View File

@@ -102,11 +102,23 @@ inline std::string fix_typeid_name( char const* n )
return r;
}
template<class T> std::string typeid_name()
// class types can be incomplete
template<class T> std::string typeid_name_impl( int T::* )
{
std::string r = fix_typeid_name( typeid(T[1]).name() );
return r.substr( 0, r.size() - 4 ); // remove ' [1]' suffix
}
template<class T> std::string typeid_name_impl( ... )
{
return fix_typeid_name( typeid(T).name() );
}
template<class T> std::string typeid_name()
{
return typeid_name_impl<T>( 0 );
}
// template names
template<class T> std::string class_template_name()
@@ -862,6 +874,8 @@ template<class T, std::size_t N> struct tn_holder<T const volatile[N]>
// pointers to members
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class R, class T> struct tn_holder<R T::*>
{
static std::string type_name( std::string const& suffix )
@@ -870,7 +884,7 @@ template<class R, class T> struct tn_holder<R T::*>
}
};
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900 && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900
template<class R, class T, class... A> struct tn_holder<R(T::*)(A...)>
{
@@ -904,7 +918,9 @@ template<class R, class T, class... A> struct tn_holder<R(T::*)(A...) const vola
}
};
#endif
#endif // #if defined(BOOST_MSVC) && BOOST_MSVC < 1900
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
// strings

View File

@@ -31,6 +31,13 @@ set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::config Boost::move Boost::smart
boost_test(TYPE run SOURCES fclose_deleter_test.cpp)
set(BOOST_TEST_LINK_LIBRARIES Boost::core Boost::serialization)
boost_test(TYPE run SOURCES serialization_nvp_test.cpp)
boost_test(TYPE run SOURCES serialization_split_free_test.cpp)
boost_test(TYPE run SOURCES serialization_split_member_test.cpp)
boost_test(TYPE run SOURCES serialization_construct_data_test.cpp)
endif()
add_subdirectory(swap)

View File

@@ -98,6 +98,8 @@ run visit_each_test.cpp ;
run get_pointer_test.cpp ;
local pedantic-errors = <warnings>pedantic
<toolset>gcc:<cxxflags>"-Wconversion"
<toolset>clang:<cxxflags>"-Wconversion"
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on ;
@@ -296,10 +298,22 @@ run bit_popcount_test.cpp
: : : $(pedantic-errors) ;
run bit_endian_test.cpp
: : : $(pedantic-errors) ;
run bit_byteswap_test.cpp
: : : $(pedantic-errors) ;
compile-fail bit_width_fail.cpp
: <warnings>off ;
compile bit_rotate_test_cx.cpp ;
compile bit_countr_test_cx.cpp ;
compile bit_countl_test_cx.cpp ;
compile bit_width_test_cx.cpp ;
compile has_single_bit_test_cx.cpp ;
compile bit_floor_test_cx.cpp ;
compile bit_ceil_test_cx.cpp ;
compile bit_popcount_test_cx.cpp ;
compile bit_byteswap_test_cx.cpp ;
run type_name_test.cpp ;
run snprintf_test.cpp ;
@@ -343,6 +357,7 @@ run span_deduction_guide_test.cpp ;
run as_bytes_test.cpp ;
run as_writable_bytes_test.cpp ;
compile span_boost_begin_test.cpp ;
run make_span_test.cpp ;
run splitmix64_test.cpp
: : : $(pedantic-errors) ;
@@ -359,5 +374,16 @@ run max_align_test.cpp ;
run memory_resource_test.cpp ;
run data_test.cpp ;
run size_test.cpp ;
run serialization_nvp_test.cpp : : : <library>/boost//serialization/<warnings>off <undefined-sanitizer>norecover:<build>no ;
run serialization_split_free_test.cpp : : : <library>/boost//serialization/<warnings>off <undefined-sanitizer>norecover:<link>static ;
run serialization_split_member_test.cpp : : : <library>/boost//serialization/<warnings>off <undefined-sanitizer>norecover:<link>static ;
run serialization_construct_data_test.cpp : : : <library>/boost//serialization/<warnings>off <undefined-sanitizer>norecover:<link>static ;
run identity_test.cpp ;
run identity_rvalue_test.cpp ;
use-project /boost/core/swap : ./swap ;
build-project ./swap ;

View File

@@ -0,0 +1,26 @@
// Test for boost/core/bit.hpp (byteswap)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/core/bit.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/cstdint.hpp>
int main()
{
BOOST_TEST_EQ( boost::core::byteswap( (boost::int8_t)0x01 ), 0x01 );
BOOST_TEST_EQ( boost::core::byteswap( (boost::uint8_t)0xF1 ), 0xF1 );
BOOST_TEST_EQ( boost::core::byteswap( (boost::int16_t)0x0102 ), 0x0201 );
BOOST_TEST_EQ( boost::core::byteswap( (boost::uint16_t)0xF1E2 ), 0xE2F1 );
BOOST_TEST_EQ( boost::core::byteswap( (boost::int32_t)0x01020304 ), 0x04030201 );
BOOST_TEST_EQ( boost::core::byteswap( (boost::uint32_t)0xF1E2D3C4u ), 0xC4D3E2F1u );
BOOST_TEST_EQ( boost::core::byteswap( (boost::int64_t)0x01020304 << 32 | 0x05060708 ), (boost::int64_t)0x08070605 << 32 | 0x04030201 );
BOOST_TEST_EQ( boost::core::byteswap( (boost::uint64_t)0xF1E2D3C4u << 32 | 0xB5A69788u ), (boost::uint64_t)0x8897A6B5u << 32 | 0xC4D3E2F1u );
return boost::report_errors();
}

View File

@@ -0,0 +1,37 @@
// constexpr test for boost/core/bit.hpp (bit_width)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
#elif defined(BOOST_MSVC) && BOOST_MSVC / 10 == 191
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC is " BOOST_STRINGIZE(BOOST_MSVC) )
#else
#include <boost/core/bit.hpp>
#include <cstdint>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
STATIC_ASSERT( boost::core::byteswap( (std::int8_t)0x01 ) == 0x01 );
STATIC_ASSERT( boost::core::byteswap( (std::uint8_t)0xF1 ) == 0xF1 );
STATIC_ASSERT( boost::core::byteswap( (std::int16_t)0x0102 ) == 0x0201 );
STATIC_ASSERT( boost::core::byteswap( (std::uint16_t)0xF1E2 ) == 0xE2F1 );
STATIC_ASSERT( boost::core::byteswap( (std::int32_t)0x01020304 ) == 0x04030201 );
STATIC_ASSERT( boost::core::byteswap( (std::uint32_t)0xF1E2D3C4u ) == 0xC4D3E2F1u );
STATIC_ASSERT( boost::core::byteswap( (std::int64_t)0x0102030405060708ll ) == 0x0807060504030201ll );
STATIC_ASSERT( boost::core::byteswap( (std::uint64_t)0xF1E2D3C4B5A69788ull ) == 0x8897A6B5C4D3E2F1ull );
#endif

View File

@@ -14,7 +14,7 @@ template<class T> void test_bit_ceil( T x )
{
if( !boost::core::has_single_bit( x ) )
{
x >>= 1;
x = static_cast<T>( x >> 1 );
}
T y = boost::core::bit_ceil( x );

26
test/bit_ceil_test_cx.cpp Normal file
View File

@@ -0,0 +1,26 @@
// constexpr test for boost/core/bit.hpp (bit_ceil)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
#else
#include <boost/core/bit.hpp>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
STATIC_ASSERT( boost::core::bit_ceil( (unsigned char)0x74 ) == 0x80 );
STATIC_ASSERT( boost::core::bit_ceil( (unsigned short)0x7400 ) == 0x8000 );
STATIC_ASSERT( boost::core::bit_ceil( 0x740000u ) == 0x800000u );
STATIC_ASSERT( boost::core::bit_ceil( 0x74000000ul ) == 0x80000000ul );
STATIC_ASSERT( boost::core::bit_ceil( 0x7400000000ull ) == 0x8000000000ull );
#endif

View File

@@ -14,7 +14,7 @@ template<class T> void test_countl( T x )
{
x |= static_cast<T>( 1 ) << ( std::numeric_limits<T>::digits - 1 );
for( int i = 0; i <= std::numeric_limits<T>::digits; ++i, x >>= 1 )
for( int i = 0; i <= std::numeric_limits<T>::digits; ++i, x = static_cast<T>( x >> 1 ) )
{
BOOST_TEST_EQ( boost::core::countl_zero( x ), i );
BOOST_TEST_EQ( boost::core::countl_one( static_cast<T>( ~x ) ), i );

View File

@@ -0,0 +1,41 @@
// constexpr test for boost/core/bit.hpp (countl_zero, countl_one)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER)
# pragma warning(disable: 4310) // cast truncates constant value
#endif
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
#elif defined(BOOST_MSVC) && BOOST_MSVC / 10 == 191
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC is " BOOST_STRINGIZE(BOOST_MSVC) )
#else
#include <boost/core/bit.hpp>
#include <climits>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
STATIC_ASSERT( boost::core::countl_zero( (unsigned char)0x1F ) == CHAR_BIT - 5 );
STATIC_ASSERT( boost::core::countl_zero( (unsigned short)0x1F ) == sizeof(unsigned short) * CHAR_BIT - 5 );
STATIC_ASSERT( boost::core::countl_zero( 0x1Fu ) == sizeof(unsigned int) * CHAR_BIT - 5 );
STATIC_ASSERT( boost::core::countl_zero( 0x1Ful ) == sizeof(unsigned long) * CHAR_BIT - 5 );
STATIC_ASSERT( boost::core::countl_zero( 0x1Full ) == sizeof(unsigned long long) * CHAR_BIT - 5 );
STATIC_ASSERT( boost::core::countl_one( (unsigned char)~0x1Fu ) == CHAR_BIT - 5 );
STATIC_ASSERT( boost::core::countl_one( (unsigned short)~0x1Fu ) == sizeof(unsigned short) * CHAR_BIT - 5 );
STATIC_ASSERT( boost::core::countl_one( ~0x1Fu ) == sizeof(unsigned int) * CHAR_BIT - 5 );
STATIC_ASSERT( boost::core::countl_one( ~0x1Ful ) == sizeof(unsigned long) * CHAR_BIT - 5 );
STATIC_ASSERT( boost::core::countl_one( ~0x1Full ) == sizeof(unsigned long long) * CHAR_BIT - 5 );
#endif

View File

@@ -14,7 +14,7 @@ template<class T> void test_countr( T x )
{
x |= 1;
for( int i = 0; i <= std::numeric_limits<T>::digits; ++i, x <<= 1 )
for( int i = 0; i <= std::numeric_limits<T>::digits; ++i, x = static_cast<T>( x << 1 ) )
{
BOOST_TEST_EQ( boost::core::countr_zero( x ), i );
BOOST_TEST_EQ( boost::core::countr_one( static_cast<T>( ~x ) ), i );

View File

@@ -0,0 +1,41 @@
// constexpr test for boost/core/bit.hpp (countr_zero, countr_one)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER)
# pragma warning(disable: 4310) // cast truncates constant value
#endif
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
#elif defined(BOOST_MSVC) && BOOST_MSVC / 10 == 191
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC is " BOOST_STRINGIZE(BOOST_MSVC) )
#else
#include <boost/core/bit.hpp>
#include <climits>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
STATIC_ASSERT( boost::core::countr_zero( (unsigned char)0xF8 ) == 3 );
STATIC_ASSERT( boost::core::countr_zero( (unsigned short)0xF800 ) == 11 );
STATIC_ASSERT( boost::core::countr_zero( 0xF80000u ) == 19 );
STATIC_ASSERT( boost::core::countr_zero( 0xF8000000ul ) == 27 );
STATIC_ASSERT( boost::core::countr_zero( 0xF800000000ull ) == 35 );
STATIC_ASSERT( boost::core::countr_one( (unsigned char)~0xF8u ) == 3 );
STATIC_ASSERT( boost::core::countr_one( (unsigned short)~0xF800u ) == 11 );
STATIC_ASSERT( boost::core::countr_one( ~0xF80000u ) == 19 );
STATIC_ASSERT( boost::core::countr_one( ~0xF8000000ul ) == 27 );
STATIC_ASSERT( boost::core::countr_one( ~0xF800000000ull ) == 35 );
#endif

View File

@@ -0,0 +1,30 @@
// constexpr test for boost/core/bit.hpp (bit_floor)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
#elif defined(BOOST_MSVC) && BOOST_MSVC / 10 == 191
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC is " BOOST_STRINGIZE(BOOST_MSVC) )
#else
#include <boost/core/bit.hpp>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
STATIC_ASSERT( boost::core::bit_floor( (unsigned char)0x74 ) == 0x40 );
STATIC_ASSERT( boost::core::bit_floor( (unsigned short)0x7400 ) == 0x4000 );
STATIC_ASSERT( boost::core::bit_floor( 0x740000u ) == 0x400000u );
STATIC_ASSERT( boost::core::bit_floor( 0x74000000ul ) == 0x40000000ul );
STATIC_ASSERT( boost::core::bit_floor( 0x7400000000ull ) == 0x4000000000ull );
#endif

View File

@@ -1,4 +1,4 @@
// Test for boost/core/bit.hpp (bit_ceil)
// Test for boost/core/bit.hpp (popcount)
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
@@ -14,7 +14,7 @@
template<class T> void test_popcount( T x )
{
int k = 0;
for( T y = x; y; y &= y - 1, ++k );
for( T y = x; y; y = static_cast<T>( y & (y - 1) ), ++k );
BOOST_TEST_EQ( boost::core::popcount( x ), k ) || ( std::cerr << "x: " << +x << std::endl );
}

View File

@@ -0,0 +1,30 @@
// constexpr test for boost/core/bit.hpp (popcount)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER) && _MSC_VER / 10 == 191
# pragma warning(disable: 4307) // '*': integral constant overflow
#endif
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
#else
#include <boost/core/bit.hpp>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
STATIC_ASSERT( boost::core::popcount( (unsigned char)0x74 ) == 4 );
STATIC_ASSERT( boost::core::popcount( (unsigned short)0x7400 ) == 4 );
STATIC_ASSERT( boost::core::popcount( 0x740000u ) == 4 );
STATIC_ASSERT( boost::core::popcount( 0x74000000ul ) == 4 );
STATIC_ASSERT( boost::core::popcount( 0x7400000000ull ) == 4 );
#endif

View File

@@ -20,7 +20,7 @@ template<class T> void test_rotate( T x )
BOOST_TEST_EQ( +boost::core::rotl( x, -i ), +boost::core::rotr( x, i ) );
unsigned const width = std::numeric_limits<T>::digits;
unsigned r = i & ( width - 1 );
unsigned r = static_cast<unsigned>( i ) & ( width - 1 );
if( r == 0 )
{

View File

@@ -0,0 +1,33 @@
// constexpr test for boost/core/bit.hpp (rotl, rotr)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
#else
#include <boost/core/bit.hpp>
#include <cstdint>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
STATIC_ASSERT( boost::core::rotl( (std::uint8_t)0x11, 1 ) == 0x22 );
STATIC_ASSERT( boost::core::rotr( (std::uint8_t)0x11, 1 ) == 0x88 );
STATIC_ASSERT( boost::core::rotl( (std::uint16_t)0x1111, 1 ) == 0x2222 );
STATIC_ASSERT( boost::core::rotr( (std::uint16_t)0x1111, 1 ) == 0x8888 );
STATIC_ASSERT( boost::core::rotl( (std::uint32_t)0x11111111, 1 ) == 0x22222222 );
STATIC_ASSERT( boost::core::rotr( (std::uint32_t)0x11111111, 1 ) == 0x88888888 );
STATIC_ASSERT( boost::core::rotl( (std::uint64_t)0x1111111111111111, 1 ) == 0x2222222222222222 );
STATIC_ASSERT( boost::core::rotr( (std::uint64_t)0x1111111111111111, 1 ) == 0x8888888888888888 );
#endif

View File

@@ -24,7 +24,7 @@ int main()
x = 1;
for( int i = 0; i < 8; ++i, x <<= 1 )
for( int i = 0; i < 8; ++i, x = static_cast<boost::uint8_t>( x << 1 ) )
{
BOOST_TEST_EQ( boost::core::bit_width( x ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint8_t>( x | ( x >> 1 ) ) ), i+1 );
@@ -39,7 +39,7 @@ int main()
x = 1;
for( int i = 0; i < 16; ++i, x <<= 1 )
for( int i = 0; i < 16; ++i, x = static_cast<boost::uint16_t>( x << 1 ) )
{
BOOST_TEST_EQ( boost::core::bit_width( x ), i+1 );
BOOST_TEST_EQ( boost::core::bit_width( static_cast<boost::uint16_t>( x | ( x >> 1 ) ) ), i+1 );

View File

@@ -0,0 +1,30 @@
// constexpr test for boost/core/bit.hpp (bit_width)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
#elif defined(BOOST_MSVC) && BOOST_MSVC / 10 == 191
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_MSVC is " BOOST_STRINGIZE(BOOST_MSVC) )
#else
#include <boost/core/bit.hpp>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
STATIC_ASSERT( boost::core::bit_width( (unsigned char)0x74 ) == 7 );
STATIC_ASSERT( boost::core::bit_width( (unsigned short)0x7400 ) == 15 );
STATIC_ASSERT( boost::core::bit_width( 0x740000u ) == 23 );
STATIC_ASSERT( boost::core::bit_width( 0x74000000ul ) == 31 );
STATIC_ASSERT( boost::core::bit_width( 0x7400000000ull ) == 39 );
#endif

68
test/data_test.cpp Normal file
View File

@@ -0,0 +1,68 @@
/*
Copyright 2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/core/data.hpp>
#include <boost/core/lightweight_test.hpp>
class range {
public:
int* data() {
return &v_[0];
}
const int* data() const {
return &v_[0];
}
std::size_t size() const {
return 4;
}
private:
int v_[4];
};
void test_range()
{
range c;
BOOST_TEST_EQ(boost::data(c), c.data());
}
void test_const_range()
{
const range c = range();
BOOST_TEST_EQ(boost::data(c), c.data());
}
void test_array()
{
int a[4];
BOOST_TEST_EQ(boost::data(a), a);
}
void test_initializer_list()
{
std::initializer_list<int> l{1, 2, 3, 4};
BOOST_TEST_EQ(boost::data(l), l.begin());
}
int main()
{
test_range();
test_const_range();
test_array();
test_initializer_list();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -28,7 +28,7 @@ int main()
x = 2;
for( int i = 1; i < 8; ++i, x <<= 1 )
for( int i = 1; i < 8; ++i, x = static_cast<boost::uint8_t>( x << 1 ) )
{
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint8_t>( x | ( x >> 1 ) ) ), false );
@@ -47,7 +47,7 @@ int main()
x = 2;
for( int i = 1; i < 16; ++i, x <<= 1 )
for( int i = 1; i < 16; ++i, x = static_cast<boost::uint16_t>( x << 1 ) )
{
BOOST_TEST_EQ( boost::core::has_single_bit( x ), true );
BOOST_TEST_EQ( boost::core::has_single_bit( static_cast<boost::uint16_t>( x | ( x >> 1 ) ) ), false );

View File

@@ -0,0 +1,35 @@
// constexpr test for boost/core/bit.hpp (has_single_bit)
//
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX14_CONSTEXPR)
BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" )
#else
#include <boost/core/bit.hpp>
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
STATIC_ASSERT( boost::core::has_single_bit( (unsigned char)0x80 ) == true );
STATIC_ASSERT( boost::core::has_single_bit( (unsigned char)0x90 ) == false );
STATIC_ASSERT( boost::core::has_single_bit( (unsigned short)0x8000 ) == true );
STATIC_ASSERT( boost::core::has_single_bit( (unsigned short)0x9000 ) == false );
STATIC_ASSERT( boost::core::has_single_bit( 0x800000u ) == true );
STATIC_ASSERT( boost::core::has_single_bit( 0x900000u ) == false );
STATIC_ASSERT( boost::core::has_single_bit( 0x80000000ul ) == true );
STATIC_ASSERT( boost::core::has_single_bit( 0x90000000ul ) == false );
STATIC_ASSERT( boost::core::has_single_bit( 0x8000000000ull ) == true );
STATIC_ASSERT( boost::core::has_single_bit( 0x9000000000ull ) == false );
#endif

View File

@@ -0,0 +1,69 @@
/*
Copyright 2021-2023 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_RVALUE_REFERENCES)
#include <boost/core/identity.hpp>
#include <boost/core/lightweight_test.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
bool test(std::string&&)
{
return true;
}
bool test(const std::string&&)
{
return true;
}
template<class T>
bool test(T&&)
{
return false;
}
void simple_test()
{
typedef std::string string;
BOOST_TEST(boost::identity()(string("a")) == string("a"));
BOOST_TEST(test(boost::identity()(string("a"))));
typedef const std::string cstring;
BOOST_TEST(boost::identity()(cstring("a")) == cstring("a"));
BOOST_TEST(test(boost::identity()(cstring("a"))));
}
void algorithm_test()
{
std::vector<std::string> v1;
v1.push_back(std::string("a"));
v1.push_back(std::string("b"));
v1.push_back(std::string("c"));
std::vector<std::string> v2(v1);
std::vector<std::string> v3;
std::transform(std::make_move_iterator(v2.begin()),
std::make_move_iterator(v2.end()),
std::back_inserter(v3),
boost::identity());
BOOST_TEST(v3 == v1);
}
int main()
{
simple_test();
algorithm_test();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

66
test/identity_test.cpp Normal file
View File

@@ -0,0 +1,66 @@
/*
Copyright 2021-2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/core/identity.hpp>
#include <boost/core/lightweight_test.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
bool test(std::string&)
{
return true;
}
bool test(const std::string&)
{
return true;
}
template<class T>
bool test(T&)
{
return false;
}
template<class T>
bool test(const T&)
{
return false;
}
void simple_test()
{
std::string s1("a");
BOOST_TEST(boost::identity()(s1) == s1);
BOOST_TEST(&boost::identity()(s1) == &s1);
BOOST_TEST(test(boost::identity()(s1)));
const std::string s2("a");
BOOST_TEST(boost::identity()(s2) == s2);
BOOST_TEST(&boost::identity()(s2) == &s2);
BOOST_TEST(test(boost::identity()(s2)));
}
void algorithm_test()
{
std::vector<std::string> v1;
v1.push_back(std::string("a"));
v1.push_back(std::string("b"));
v1.push_back(std::string("c"));
std::vector<std::string> v2;
std::transform(v1.begin(), v1.end(), std::back_inserter(v2),
boost::identity());
BOOST_TEST(v2 == v1);
}
int main()
{
simple_test();
algorithm_test();
return boost::report_errors();
}

100
test/make_span_test.cpp Normal file
View File

@@ -0,0 +1,100 @@
/*
Copyright 2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/core/make_span.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T>
class range {
public:
T* data() {
return &v_[0];
}
std::size_t size() const {
return 4;
}
private:
T v_[4];
};
void test_data_size()
{
int a[4];
boost::span<int> s = boost::make_span(&a[0], 4);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_first_last()
{
int a[4];
boost::span<int> s = boost::make_span(&a[0], &a[4]);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_array()
{
int a[4];
boost::span<int, 4> s = boost::make_span(a);
BOOST_TEST_EQ(s.data(), &a[0]);
BOOST_TEST_EQ(s.size(), 4);
}
void test_std_array()
{
std::array<int, 4> a;
boost::span<int, 4> s = boost::make_span(a);
BOOST_TEST_EQ(s.data(), a.data());
BOOST_TEST_EQ(s.size(), a.size());
}
void test_const_std_array()
{
const std::array<int, 4> a = std::array<int, 4>();
boost::span<const int> s = boost::make_span(a);
BOOST_TEST_EQ(s.data(), a.data());
BOOST_TEST_EQ(s.size(), a.size());
}
void test_range()
{
range<int> c;
boost::span<int> s = boost::make_span(c);
BOOST_TEST_EQ(s.data(), c.data());
BOOST_TEST_EQ(s.size(), c.size());
}
void test_initializer_list()
{
std::initializer_list<int> l{1, 2};
boost::span<const int> s = boost::make_span(l);
BOOST_TEST_EQ(s.data(), l.begin());
BOOST_TEST_EQ(s.size(), l.size());
}
int main()
{
test_data_size();
test_first_last();
test_array();
test_std_array();
test_const_std_array();
test_range();
test_initializer_list();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -54,16 +54,9 @@ int main()
BOOST_TEST_GE( boost::core::max_align, boost::alignment_of<void (X::*)()>::value );
#if !defined(BOOST_NO_CXX11_ALIGNOF) && !defined(BOOST_NO_STD_MAX_ALIGN_T)
# if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 70000
// libstdc++ 7 adds __float128 to std::max_align_t, but we always have it
BOOST_TEST_GE( boost::core::max_align, alignof( std::max_align_t ) );
# else
BOOST_TEST_EQ( boost::core::max_align, alignof( std::max_align_t ) );
# endif
#endif
return boost::report_errors();

View File

@@ -0,0 +1,102 @@
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(__clang__) && defined(__has_warning)
# if __has_warning( "-Wdeprecated-copy" )
# pragma clang diagnostic ignored "-Wdeprecated-copy"
# endif
#endif
#include <boost/core/serialization.hpp>
#include <new>
struct X
{
int v_;
explicit X( int v ): v_( v ) {}
template<class Ar> void serialize( Ar& /*ar*/, unsigned /*v*/ )
{
}
};
template<class Ar> void save_construct_data( Ar& ar, X const* t, unsigned /*v*/ )
{
ar << t->v_;
}
template<class Ar> void load_construct_data( Ar& ar, X* t, unsigned /*v*/ )
{
int v;
ar >> v;
::new( t ) X( v );
}
struct Y
{
X x1, x2;
explicit Y( int v1, int v2 ): x1( v1 ), x2( v2 ) {}
private:
friend class boost::serialization::access;
template<class Ar> void load( Ar& ar, unsigned v )
{
boost::core::load_construct_data_adl( ar, &x1, v );
ar >> x1;
boost::core::load_construct_data_adl( ar, &x2, v );
ar >> x2;
}
template<class Ar> void save( Ar& ar, unsigned v ) const
{
boost::core::save_construct_data_adl( ar, &x1, v );
ar << x1;
boost::core::save_construct_data_adl( ar, &x2, v );
ar << x2;
}
template<class Ar> void serialize( Ar& ar, unsigned v )
{
boost::core::split_member( ar, *this, v );
}
};
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/core/lightweight_test.hpp>
#include <sstream>
#include <string>
int main()
{
std::ostringstream os;
Y y1( 7, 11 );
{
boost::archive::text_oarchive ar( os );
ar << y1;
}
std::string s = os.str();
Y y2( 0, 0 );
{
std::istringstream is( s );
boost::archive::text_iarchive ar( is );
ar >> y2;
}
BOOST_TEST_EQ( y1.x1.v_, y2.x1.v_ );
BOOST_TEST_EQ( y1.x2.v_, y2.x2.v_ );
return boost::report_errors();
}

View File

@@ -0,0 +1,55 @@
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(__clang__) && defined(__has_warning)
# if __has_warning( "-Wdeprecated-copy" )
# pragma clang diagnostic ignored "-Wdeprecated-copy"
# endif
#endif
#include <boost/core/serialization.hpp>
struct X
{
int a, b;
template<class Ar> void serialize( Ar& ar, unsigned /*v*/ )
{
ar & boost::core::make_nvp( "a", a );
ar & boost::core::make_nvp( "b", b );
}
};
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/core/lightweight_test.hpp>
#include <sstream>
#include <string>
int main()
{
std::ostringstream os;
X x1 = { 7, 11 };
{
boost::archive::xml_oarchive ar( os );
ar << boost::core::make_nvp( "x1", x1 );
}
std::string s = os.str();
X x2 = { 0, 0 };
{
std::istringstream is( s );
boost::archive::xml_iarchive ar( is );
ar >> boost::make_nvp( "x2", x2 );
}
BOOST_TEST_EQ( x1.a, x2.a );
BOOST_TEST_EQ( x1.b, x2.b );
return boost::report_errors();
}

View File

@@ -0,0 +1,66 @@
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(__clang__) && defined(__has_warning)
# if __has_warning( "-Wdeprecated-copy" )
# pragma clang diagnostic ignored "-Wdeprecated-copy"
# endif
#endif
#include <boost/core/serialization.hpp>
struct X
{
int a, b;
};
template<class Ar> void load( Ar& ar, X& x, unsigned /*v*/ )
{
ar >> x.a;
ar >> x.b;
}
template<class Ar> void save( Ar& ar, X const& x, unsigned /*v*/ )
{
ar << x.a;
ar << x.b;
}
template<class Ar> void serialize( Ar& ar, X& x, unsigned v )
{
boost::core::split_free( ar, x, v );
}
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/core/lightweight_test.hpp>
#include <sstream>
#include <string>
int main()
{
std::ostringstream os;
X x1 = { 7, 11 };
{
boost::archive::text_oarchive ar( os );
ar << x1;
}
std::string s = os.str();
X x2 = { 0, 0 };
{
std::istringstream is( s );
boost::archive::text_iarchive ar( is );
ar >> x2;
}
BOOST_TEST_EQ( x1.a, x2.a );
BOOST_TEST_EQ( x1.b, x2.b );
return boost::report_errors();
}

View File

@@ -0,0 +1,70 @@
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(__clang__) && defined(__has_warning)
# if __has_warning( "-Wdeprecated-copy" )
# pragma clang diagnostic ignored "-Wdeprecated-copy"
# endif
#endif
#include <boost/core/serialization.hpp>
struct X
{
int a, b;
private:
friend class boost::serialization::access;
template<class Ar> void load( Ar& ar, unsigned /*v*/ )
{
ar >> a;
ar >> b;
}
template<class Ar> void save( Ar& ar, unsigned /*v*/ ) const
{
ar << a;
ar << b;
}
template<class Ar> void serialize( Ar& ar, unsigned v )
{
boost::core::split_member( ar, *this, v );
}
};
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/core/lightweight_test.hpp>
#include <sstream>
#include <string>
int main()
{
std::ostringstream os;
X x1 = { 7, 11 };
{
boost::archive::text_oarchive ar( os );
ar << x1;
}
std::string s = os.str();
X x2 = { 0, 0 };
{
std::istringstream is( s );
boost::archive::text_iarchive ar( is );
ar >> x2;
}
BOOST_TEST_EQ( x1.a, x2.a );
BOOST_TEST_EQ( x1.b, x2.b );
return boost::report_errors();
}

42
test/size_test.cpp Normal file
View File

@@ -0,0 +1,42 @@
/*
Copyright 2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/core/size.hpp>
#include <boost/core/lightweight_test.hpp>
struct range {
std::size_t size() const {
return 4;
}
};
void test_range()
{
range c;
BOOST_TEST_EQ(boost::size(c), 4);
}
void test_array()
{
int a[4];
BOOST_TEST_EQ(boost::size(a), 4);
}
int main()
{
test_range();
test_array();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -1,5 +1,5 @@
/*
Copyright 2019 Glen Joseph Fernandes
Copyright 2019-2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -140,6 +140,14 @@ void test_range()
range<derived>&>));
}
void test_initializer_list()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
std::initializer_list<int> >));
BOOST_TEST_TRAIT_FALSE((std::is_constructible<boost::span<int>,
std::initializer_list<int> >));
}
void test_span()
{
BOOST_TEST_TRAIT_TRUE((std::is_constructible<boost::span<const int>,
@@ -187,6 +195,7 @@ int main()
test_std_array();
test_const_std_array();
test_range();
test_initializer_list();
test_span();
test_copy();
test_assign();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2019 Glen Joseph Fernandes
Copyright 2019-2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -78,6 +78,15 @@ void test_range()
BOOST_TEST_EQ(s.size(), c.size());
}
void test_initializer_list()
{
std::initializer_list<int> l{1, 2};
boost::span s(l);
BOOST_TEST_EQ(s.extent, boost::dynamic_extent);
BOOST_TEST_EQ(s.data(), l.begin());
BOOST_TEST_EQ(s.size(), l.size());
}
void test_span_dynamic()
{
int a[4];
@@ -104,6 +113,7 @@ int main()
test_std_array();
test_const_std_array();
test_range();
test_initializer_list();
test_span_dynamic();
test_span_static();
return boost::report_errors();

View File

@@ -1,5 +1,5 @@
/*
Copyright 2019 Glen Joseph Fernandes
Copyright 2019-2023 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
@@ -118,6 +118,14 @@ void test_construct_range()
BOOST_TEST_EQ(s.size(), c.size());
}
void test_construct_initializer_list()
{
std::initializer_list<int> l{1, 2};
boost::span<const int> s(l);
BOOST_TEST_EQ(s.data(), l.begin());
BOOST_TEST_EQ(s.size(), l.size());
}
void test_construct_span_dynamic()
{
int a[4];
@@ -376,6 +384,7 @@ int main()
test_construct_const_std_array_dynamic();
test_construct_const_std_array_static();
test_construct_range();
test_construct_initializer_list();
test_construct_span_dynamic();
test_construct_span_dynamic_static();
test_construct_span_static();

View File

@@ -47,10 +47,14 @@ class B
{
};
class C;
template<class T1, class T2> struct X
{
};
template<class T1, class T2> struct Y;
enum E1
{
e1
@@ -63,6 +67,8 @@ enum class E2
e2
};
enum class E3;
#endif
struct Ch
@@ -115,12 +121,14 @@ int main()
TEST(A);
TEST(B);
TEST(C);
TEST(E1);
#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
TEST(E2);
TEST(E3);
#endif
@@ -131,6 +139,10 @@ int main()
TEST(B&);
TEST(B const&);
TEST(C volatile);
TEST(C&);
TEST(C const&);
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
TEST(B&&);
@@ -141,6 +153,9 @@ int main()
TEST(A*);
TEST(B const* volatile*);
TEST(C*);
TEST(C const* volatile*);
TEST(void*);
TEST(void const* volatile*);
@@ -239,9 +254,18 @@ int main()
TEST(B(&)[1][2][3]);
TEST(B const volatile(***)[1][2][3]);
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || !defined(BOOST_MSVC)
TEST(int A::*);
TEST(int const B::*);
#else
boost::core::type_name<int A::*>();
boost::core::type_name<int const B::*>();
#endif
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
TEST(void(A::*)());
@@ -249,6 +273,13 @@ int main()
TEST(void(A::*)() volatile);
TEST(void(A::*)() const volatile);
#else
boost::core::type_name<void(A::*)()>();
boost::core::type_name<void(A::*)() const>();
boost::core::type_name<void(A::*)() volatile>();
boost::core::type_name<void(A::*)() const volatile>();
#endif
#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
@@ -274,6 +305,8 @@ int main()
TEST(std::pair<A, B>);
TEST(std::pair<A const*, B*> volatile&);
TEST(std::pair<C, C>);
TEST(std::pair<void, void>);
TEST(std::pair<std::pair<void, void>, void>);
@@ -298,6 +331,11 @@ int main()
TEST(X<A, B>);
TEST(X<A const&, B&> volatile&);
TEST(X<C, C>);
TEST(Y<A, B>);
TEST(Y<C, C>);
TEST(X<std::pair<void, void>, void>);
TEST(std::vector<int>);