mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
This implements LWG4550: Need new feature test macros for <stdckdint.h> and <stdbit.h>. libstdc++-v3/ChangeLog: * include/bits/version.def (stdbit_h, stdckdint_h): Define. * include/bits/version.h: Regenerate. * include/c_compatibility/stdbit.h (__cpp_lib_stdbit_h): Define and use it in guards. * include/c_compatibility/stdckdint.h (__cpp_lib_stdckdint_h): Define and use it in guards. Reviewed-by: Jonathan Wakely <jwakely@redhat.com> Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
587 lines
15 KiB
C++
587 lines
15 KiB
C++
// C compatibility header <stdbit.h> -*- C++ -*-
|
|
|
|
// Copyright The GNU Toolchain Authors.
|
|
//
|
|
// This file is part of the GNU ISO C++ Library. This library is free
|
|
// software; you can redistribute it and/or modify it under the
|
|
// terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 3, or (at your option)
|
|
// any later version.
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// Under Section 7 of GPL version 3, you are granted additional
|
|
// permissions described in the GCC Runtime Library Exception, version
|
|
// 3.1, as published by the Free Software Foundation.
|
|
|
|
// You should have received a copy of the GNU General Public License and
|
|
// a copy of the GCC Runtime Library Exception along with this program;
|
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
/** @file include/stdbit.h
|
|
* This is a Standard C++ Library header.
|
|
*/
|
|
|
|
#ifndef _GLIBCXX_STDBIT_H
|
|
#define _GLIBCXX_STDBIT_H
|
|
|
|
#define __glibcxx_want_stdbit_h
|
|
#include <bits/version.h>
|
|
|
|
#ifdef __cpp_lib_stdbit_h // C++ >= 26
|
|
|
|
#include <bit>
|
|
|
|
#define __STDC_VERSION_STDBIT_H__ 202311L
|
|
|
|
#define __STDC_ENDIAN_BIG__ __ORDER_BIG_ENDIAN__
|
|
#define __STDC_ENDIAN_LITTLE__ __ORDER_LITTLE_ENDIAN__
|
|
#define __STDC_ENDIAN_NATIVE__ __BYTE_ORDER__
|
|
|
|
#ifndef _GLIBCXX_DOXYGEN
|
|
// We define these in our own namespace, but let Doxygen think otherwise.
|
|
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
|
|
{
|
|
#endif
|
|
|
|
/** Count the number of leading zero bits
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_leading_zeros(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return std::countl_zero(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_leading_zeros_uc(unsigned char __value)
|
|
{ return stdc_leading_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_leading_zeros_us(unsigned short __value)
|
|
{ return stdc_leading_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_leading_zeros_ui(unsigned int __value)
|
|
{ return stdc_leading_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_leading_zeros_ul(unsigned long int __value)
|
|
{ return stdc_leading_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_leading_zeros_ull(unsigned long long int __value)
|
|
{ return stdc_leading_zeros(__value); }
|
|
/// @}
|
|
|
|
/** Count the number of leading one bits
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_leading_ones(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return std::countl_one(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_leading_ones_uc(unsigned char __value)
|
|
{ return stdc_leading_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_leading_ones_us(unsigned short __value)
|
|
{ return stdc_leading_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_leading_ones_ui(unsigned int __value)
|
|
{ return stdc_leading_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_leading_ones_ul(unsigned long int __value)
|
|
{ return stdc_leading_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_leading_ones_ull(unsigned long long int __value)
|
|
{ return stdc_leading_ones(__value); }
|
|
/// @}
|
|
|
|
/** Count the number of trailing zero bits
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_trailing_zeros(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return std::countr_zero(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_trailing_zeros_uc(unsigned char __value)
|
|
{ return stdc_trailing_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_trailing_zeros_us(unsigned short __value)
|
|
{ return stdc_trailing_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_trailing_zeros_ui(unsigned int __value)
|
|
{ return stdc_trailing_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_trailing_zeros_ul(unsigned long int __value)
|
|
{ return stdc_trailing_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_trailing_zeros_ull(unsigned long long int __value)
|
|
{ return stdc_trailing_zeros(__value); }
|
|
/// @}
|
|
|
|
/** Count the number of trailing one bits
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_trailing_ones(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return std::countr_one(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_trailing_ones_uc(unsigned char __value)
|
|
{ return stdc_trailing_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_trailing_ones_us(unsigned short __value)
|
|
{ return stdc_trailing_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_trailing_ones_ui(unsigned int __value)
|
|
{ return stdc_trailing_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_trailing_ones_ul(unsigned long int __value)
|
|
{ return stdc_trailing_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_trailing_ones_ull(unsigned long long int __value)
|
|
{ return stdc_trailing_ones(__value); }
|
|
/// @}
|
|
|
|
/** Find the leftmost (i.e. most significant) zero bit
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return The one-based index of the first zero bit counting from the left,
|
|
* or zero if there are no zero bits.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_first_leading_zero(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return __value == _Tp(-1) ? 0 : 1 + std::countl_one(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_zero_uc(unsigned char __value)
|
|
{ return stdc_first_leading_zero(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_zero_us(unsigned short __value)
|
|
{ return stdc_first_leading_zero(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_zero_ui(unsigned int __value)
|
|
{ return stdc_first_leading_zero(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_zero_ul(unsigned long int __value)
|
|
{ return stdc_first_leading_zero(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_zero_ull(unsigned long long int __value)
|
|
{ return stdc_first_leading_zero(__value); }
|
|
/// @}
|
|
|
|
/** Find the leftmost (i.e. most significant) one bit
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return The one-based index of the first one bit counting from the left,
|
|
* or zero if there are no one bits.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_first_leading_one(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return __value == 0 ? 0 : 1 + std::countl_zero(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_one_uc(unsigned char __value)
|
|
{ return stdc_first_leading_one(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_one_us(unsigned short __value)
|
|
{ return stdc_first_leading_one(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_one_ui(unsigned int __value)
|
|
{ return stdc_first_leading_one(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_one_ul(unsigned long int __value)
|
|
{ return stdc_first_leading_one(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_leading_one_ull(unsigned long long int __value)
|
|
{ return stdc_first_leading_one(__value); }
|
|
/// @}
|
|
|
|
/** Find the rightmost (i.e. least significant) zero bit
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return The one-based index of the first zero bit counting from the right,
|
|
* or zero if there are no zero bits.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_first_trailing_zero(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return __value == _Tp(-1) ? 0 : 1 + std::countr_one(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_zero_uc(unsigned char __value)
|
|
{ return stdc_first_trailing_zero(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_zero_us(unsigned short __value)
|
|
{ return stdc_first_trailing_zero(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_zero_ui(unsigned int __value)
|
|
{ return stdc_first_trailing_zero(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_zero_ul(unsigned long int __value)
|
|
{ return stdc_first_trailing_zero(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_zero_ull(unsigned long long int __value)
|
|
{ return stdc_first_trailing_zero(__value); }
|
|
/// @}
|
|
|
|
/** Find the rightmost (i.e. least significant) one bit
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return The one-based index of the first one bit counting from the right,
|
|
* or zero if there are no one bits.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_first_trailing_one(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return __value == 0 ? 0 : 1 + std::countr_zero(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_one_uc(unsigned char __value)
|
|
{ return stdc_first_trailing_one(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_one_us(unsigned short __value)
|
|
{ return stdc_first_trailing_one(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_one_ui(unsigned int __value)
|
|
{ return stdc_first_trailing_one(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_one_ul(unsigned long int __value)
|
|
{ return stdc_first_trailing_one(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_first_trailing_one_ull(unsigned long long int __value)
|
|
{ return stdc_first_trailing_one(__value); }
|
|
/// @}
|
|
|
|
/** Count zeros
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return The total number of zero bits in `__value`.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_count_zeros(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return std::popcount(_Tp(~__value));
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_count_zeros_uc(unsigned char __value)
|
|
{ return stdc_count_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_count_zeros_us(unsigned short __value)
|
|
{ return stdc_count_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_count_zeros_ui(unsigned int __value)
|
|
{ return stdc_count_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_count_zeros_ul(unsigned long int __value)
|
|
{ return stdc_count_zeros(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_count_zeros_ull(unsigned long long int __value)
|
|
{ return stdc_count_zeros(__value); }
|
|
/// @}
|
|
|
|
/** Count ones
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return The total number of one bits in `__value`.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_count_ones(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return std::popcount(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_count_ones_uc(unsigned char __value)
|
|
{ return stdc_count_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_count_ones_us(unsigned short __value)
|
|
{ return stdc_count_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_count_ones_ui(unsigned int __value)
|
|
{ return stdc_count_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_count_ones_ul(unsigned long int __value)
|
|
{ return stdc_count_ones(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_count_ones_ull(unsigned long long int __value)
|
|
{ return stdc_count_ones(__value); }
|
|
/// @}
|
|
|
|
/** Power of two check
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return True if the value has a single bit set, false otherwise.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline bool
|
|
stdc_has_single_bit(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return std::has_single_bit(__value);
|
|
}
|
|
|
|
inline bool
|
|
stdc_has_single_bit_uc(unsigned char __value)
|
|
{ return stdc_has_single_bit(__value); }
|
|
|
|
inline bool
|
|
stdc_has_single_bit_us(unsigned short __value)
|
|
{ return stdc_has_single_bit(__value); }
|
|
|
|
inline bool
|
|
stdc_has_single_bit_ui(unsigned int __value)
|
|
{ return stdc_has_single_bit(__value); }
|
|
|
|
inline bool
|
|
stdc_has_single_bit_ul(unsigned long int __value)
|
|
{ return stdc_has_single_bit(__value); }
|
|
|
|
inline bool
|
|
stdc_has_single_bit_ull(unsigned long long int __value)
|
|
{ return stdc_has_single_bit(__value); }
|
|
/// @}
|
|
|
|
/** Bit width
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return The minimum number of bits needed to represent `__value`.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline unsigned int
|
|
stdc_bit_width(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return std::bit_width(__value);
|
|
}
|
|
|
|
inline unsigned int
|
|
stdc_bit_width_uc(unsigned char __value)
|
|
{ return stdc_bit_width(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_bit_width_us(unsigned short __value)
|
|
{ return stdc_bit_width(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_bit_width_ui(unsigned int __value)
|
|
{ return stdc_bit_width(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_bit_width_ul(unsigned long int __value)
|
|
{ return stdc_bit_width(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_bit_width_ull(unsigned long long int __value)
|
|
{ return stdc_bit_width(__value); }
|
|
/// @}
|
|
|
|
/** Bit floor
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return The largest power of two that is not greater than `__value`.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline _Tp
|
|
stdc_bit_floor(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
return std::bit_floor(__value);
|
|
}
|
|
|
|
inline unsigned char
|
|
stdc_bit_floor_uc(unsigned char __value)
|
|
{ return stdc_bit_floor(__value); }
|
|
|
|
inline unsigned short
|
|
stdc_bit_floor_us(unsigned short __value)
|
|
{ return stdc_bit_floor(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_bit_floor_ui(unsigned int __value)
|
|
{ return stdc_bit_floor(__value); }
|
|
|
|
inline unsigned long int
|
|
stdc_bit_floor_ul(unsigned long int __value)
|
|
{ return stdc_bit_floor(__value); }
|
|
|
|
inline unsigned long long int
|
|
stdc_bit_floor_ull(unsigned long long int __value)
|
|
{ return stdc_bit_floor(__value); }
|
|
/// @}
|
|
|
|
/** Bit ceiling
|
|
*
|
|
* Unlike `std::bit_ceil`, this is defined to return zero for values which
|
|
* are not representable in the return type.
|
|
*
|
|
* @param __value An unsigned integer.
|
|
* @return The smallest power of two that is not less than `__value`.
|
|
* @since C++26
|
|
* @{
|
|
*/
|
|
template<typename _Tp>
|
|
inline _Tp
|
|
stdc_bit_ceil(_Tp __value)
|
|
{
|
|
static_assert(std::__unsigned_integer<_Tp>);
|
|
constexpr _Tp __msb = _Tp(1) << (__gnu_cxx::__int_traits<_Tp>::__digits - 1);
|
|
return (__value & __msb) ? 0 : std::bit_ceil(__value);
|
|
}
|
|
|
|
inline unsigned char
|
|
stdc_bit_ceil_uc(unsigned char __value)
|
|
{ return stdc_bit_ceil(__value); }
|
|
|
|
inline unsigned short
|
|
stdc_bit_ceil_us(unsigned short __value)
|
|
{ return stdc_bit_ceil(__value); }
|
|
|
|
inline unsigned int
|
|
stdc_bit_ceil_ui(unsigned int __value)
|
|
{ return stdc_bit_ceil(__value); }
|
|
|
|
inline unsigned long int
|
|
stdc_bit_ceil_ul(unsigned long int __value)
|
|
{ return stdc_bit_ceil(__value); }
|
|
|
|
inline unsigned long long int
|
|
stdc_bit_ceil_ull(unsigned long long int __value)
|
|
{ return stdc_bit_ceil(__value); }
|
|
/// @}
|
|
|
|
#ifndef _GLIBCXX_DOXYGEN
|
|
} // namespace __gnu_cxx
|
|
#define _GLIBCXX_STDBIT_FUNC(F) \
|
|
using __gnu_cxx::F ## _uc; \
|
|
using __gnu_cxx::F ## _us; \
|
|
using __gnu_cxx::F ## _ui; \
|
|
using __gnu_cxx::F ## _ul; \
|
|
using __gnu_cxx::F ## _ull; \
|
|
using __gnu_cxx::F
|
|
_GLIBCXX_STDBIT_FUNC(stdc_leading_zeros);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_leading_ones);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_trailing_zeros);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_trailing_ones);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_first_leading_zero);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_first_leading_one);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_first_trailing_zero);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_first_trailing_one);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_count_zeros);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_count_ones);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_has_single_bit);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_bit_width);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_bit_floor);
|
|
_GLIBCXX_STDBIT_FUNC(stdc_bit_ceil);
|
|
#undef _GLIBCXX_STDBIT_FUNC
|
|
#endif // !DOXYGEN
|
|
#endif // __cpp_lib_stdbit_h
|
|
|
|
#endif // _GLIBCXX_STDBIT_H
|