1
0
forked from boostorg/core

Compare commits

...

20 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
25 changed files with 989 additions and 95 deletions

View File

@@ -359,24 +359,24 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
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

@@ -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

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

@@ -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

@@ -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 ;

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

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

@@ -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>);