forked from boostorg/core
Compare commits
20 Commits
feature/is
...
feature/pe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85527c4045 | ||
|
|
7ab05d5de0 | ||
|
|
266fbe6449 | ||
|
|
fd0de5f538 | ||
|
|
350526f7c7 | ||
|
|
06fef712c9 | ||
|
|
b7f7eb4f90 | ||
|
|
f41b8f38c4 | ||
|
|
b591214103 | ||
|
|
6b9f0cbf57 | ||
|
|
ecee9257d5 | ||
|
|
6c7edac9b1 | ||
|
|
049d3447ca | ||
|
|
b2fe98edf8 | ||
|
|
42c8898d24 | ||
|
|
f2eab6d6ff | ||
|
|
36fa78f53c | ||
|
|
97606908b7 | ||
|
|
5eb54d1d36 | ||
|
|
c91f8fabff |
@@ -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' },
|
||||
),
|
||||
]
|
||||
|
||||
180
.github/workflows/ci.yml
vendored
180
.github/workflows/ci.yml
vendored
@@ -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
|
||||
|
||||
16
doc/bit.qbk
16
doc/bit.qbk
@@ -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;`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
26
test/bit_byteswap_test.cpp
Normal file
26
test/bit_byteswap_test.cpp
Normal 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();
|
||||
}
|
||||
37
test/bit_byteswap_test_cx.cpp
Normal file
37
test/bit_byteswap_test_cx.cpp
Normal 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
|
||||
@@ -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
26
test/bit_ceil_test_cx.cpp
Normal 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
|
||||
@@ -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 );
|
||||
|
||||
41
test/bit_countl_test_cx.cpp
Normal file
41
test/bit_countl_test_cx.cpp
Normal 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
|
||||
@@ -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 );
|
||||
|
||||
41
test/bit_countr_test_cx.cpp
Normal file
41
test/bit_countr_test_cx.cpp
Normal 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
|
||||
30
test/bit_floor_test_cx.cpp
Normal file
30
test/bit_floor_test_cx.cpp
Normal 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
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
30
test/bit_popcount_test_cx.cpp
Normal file
30
test/bit_popcount_test_cx.cpp
Normal 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
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
33
test/bit_rotate_test_cx.cpp
Normal file
33
test/bit_rotate_test_cx.cpp
Normal 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
|
||||
@@ -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 );
|
||||
|
||||
30
test/bit_width_test_cx.cpp
Normal file
30
test/bit_width_test_cx.cpp
Normal 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
|
||||
@@ -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 );
|
||||
|
||||
35
test/has_single_bit_test_cx.cpp
Normal file
35
test/has_single_bit_test_cx.cpp
Normal 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
|
||||
@@ -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>);
|
||||
|
||||
Reference in New Issue
Block a user