mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 12:00:03 -05:00
In r15-3714-gd3a7302ec5985a I added -Wsystem-headers to the libstdc++ build flags to help catch problems in the library. This patch takes a different approach, of disabling the #pragma system_header unless _GLIBCXX_SYSHDR is defined. As a result, the testsuites will treat them as non-system-headers to get better warning coverage during regression testing of both gcc and libstdc++, not just when building the library. My rationale for the #ifdef instead of just removing the #pragma is the three G++ tests that want to test libstdc++ system header behavior, so we need a way to select it. This doesn't affect installed libraries, as they get their system-header status from the lookup path. But testsuite_flags --build-includes gives -I directives rather than -isystem. This patch doesn't change the headers in config/ because I'm not compiling with most of them, so won't see any warnings that need fixing. Adjusting them could happen later, or we can not bother. libstdc++-v3/ChangeLog: * acinclude.m4 (WARN_FLAGS): Remove -Wsystem-headers. * configure: Regenerate. * include/bits/algorithmfwd.h: #ifdef out #pragma GCC system_header. * include/bits/atomic_base.h * include/bits/atomic_futex.h * include/bits/atomic_timed_wait.h * include/bits/atomic_wait.h * include/bits/basic_ios.h * include/bits/basic_string.h * include/bits/boost_concept_check.h * include/bits/char_traits.h * include/bits/charconv.h * include/bits/chrono.h * include/bits/chrono_io.h * include/bits/codecvt.h * include/bits/concept_check.h * include/bits/cpp_type_traits.h * include/bits/elements_of.h * include/bits/enable_special_members.h * include/bits/erase_if.h * include/bits/forward_list.h * include/bits/functional_hash.h * include/bits/gslice.h * include/bits/gslice_array.h * include/bits/hashtable.h * include/bits/indirect_array.h * include/bits/invoke.h * include/bits/ios_base.h * include/bits/iterator_concepts.h * include/bits/locale_classes.h * include/bits/locale_facets.h * include/bits/locale_facets_nonio.h * include/bits/localefwd.h * include/bits/mask_array.h * include/bits/max_size_type.h * include/bits/memory_resource.h * include/bits/memoryfwd.h * include/bits/move_only_function.h * include/bits/node_handle.h * include/bits/ostream_insert.h * include/bits/out_ptr.h * include/bits/parse_numbers.h * include/bits/postypes.h * include/bits/quoted_string.h * include/bits/range_access.h * include/bits/ranges_base.h * include/bits/refwrap.h * include/bits/sat_arith.h * include/bits/semaphore_base.h * include/bits/slice_array.h * include/bits/std_abs.h * include/bits/std_function.h * include/bits/std_mutex.h * include/bits/std_thread.h * include/bits/stl_iterator_base_funcs.h * include/bits/stl_iterator_base_types.h * include/bits/stl_tree.h * include/bits/stream_iterator.h * include/bits/streambuf_iterator.h * include/bits/stringfwd.h * include/bits/this_thread_sleep.h * include/bits/unique_lock.h * include/bits/uses_allocator_args.h * include/bits/utility.h * include/bits/valarray_after.h * include/bits/valarray_array.h * include/bits/valarray_before.h * include/bits/version.h * include/c_compatibility/fenv.h * include/c_compatibility/inttypes.h * include/c_compatibility/stdint.h * include/decimal/decimal.h * include/experimental/bits/net.h * include/experimental/bits/shared_ptr.h * include/ext/aligned_buffer.h * include/ext/alloc_traits.h * include/ext/atomicity.h * include/ext/concurrence.h * include/ext/numeric_traits.h * include/ext/pod_char_traits.h * include/ext/pointer.h * include/ext/stdio_filebuf.h * include/ext/stdio_sync_filebuf.h * include/ext/string_conversions.h * include/ext/type_traits.h * include/ext/vstring.h * include/ext/vstring_fwd.h * include/ext/vstring_util.h * include/parallel/algorithmfwd.h * include/parallel/numericfwd.h * include/tr1/functional_hash.h * include/tr1/hashtable.h * include/tr1/random.h * libsupc++/exception.h * libsupc++/hash_bytes.h * include/bits/basic_ios.tcc * include/bits/basic_string.tcc * include/bits/fstream.tcc * include/bits/istream.tcc * include/bits/locale_classes.tcc * include/bits/locale_facets.tcc * include/bits/locale_facets_nonio.tcc * include/bits/ostream.tcc * include/bits/sstream.tcc * include/bits/streambuf.tcc * include/bits/string_view.tcc * include/bits/version.tpl * include/experimental/bits/string_view.tcc * include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp * include/ext/random.tcc * include/ext/vstring.tcc * include/tr2/bool_set.tcc * include/tr2/dynamic_bitset.tcc * include/bits/c++config * include/c/cassert * include/c/cctype * include/c/cerrno * include/c/cfloat * include/c/ciso646 * include/c/climits * include/c/clocale * include/c/cmath * include/c/csetjmp * include/c/csignal * include/c/cstdarg * include/c/cstddef * include/c/cstdio * include/c/cstdlib * include/c/cstring * include/c/ctime * include/c/cuchar * include/c/cwchar * include/c/cwctype * include/c_global/cassert * include/c_global/ccomplex * include/c_global/cctype * include/c_global/cerrno * include/c_global/cfenv * include/c_global/cfloat * include/c_global/cinttypes * include/c_global/ciso646 * include/c_global/climits * include/c_global/clocale * include/c_global/cmath * include/c_global/csetjmp * include/c_global/csignal * include/c_global/cstdalign * include/c_global/cstdarg * include/c_global/cstdbool * include/c_global/cstddef * include/c_global/cstdint * include/c_global/cstdio * include/c_global/cstdlib * include/c_global/cstring * include/c_global/ctgmath * include/c_global/ctime * include/c_global/cuchar * include/c_global/cwchar * include/c_global/cwctype * include/c_std/cassert * include/c_std/cctype * include/c_std/cerrno * include/c_std/cfloat * include/c_std/ciso646 * include/c_std/climits * include/c_std/clocale * include/c_std/cmath * include/c_std/csetjmp * include/c_std/csignal * include/c_std/cstdarg * include/c_std/cstddef * include/c_std/cstdio * include/c_std/cstdlib * include/c_std/cstring * include/c_std/ctime * include/c_std/cuchar * include/c_std/cwchar * include/c_std/cwctype * include/debug/array * include/debug/bitset * include/debug/deque * include/debug/forward_list * include/debug/list * include/debug/map * include/debug/set * include/debug/string * include/debug/unordered_map * include/debug/unordered_set * include/debug/vector * include/decimal/decimal * include/experimental/algorithm * include/experimental/any * include/experimental/array * include/experimental/buffer * include/experimental/chrono * include/experimental/contract * include/experimental/deque * include/experimental/executor * include/experimental/filesystem * include/experimental/forward_list * include/experimental/functional * include/experimental/internet * include/experimental/io_context * include/experimental/iterator * include/experimental/list * include/experimental/map * include/experimental/memory * include/experimental/memory_resource * include/experimental/net * include/experimental/netfwd * include/experimental/numeric * include/experimental/propagate_const * include/experimental/ratio * include/experimental/regex * include/experimental/scope * include/experimental/set * include/experimental/socket * include/experimental/string * include/experimental/string_view * include/experimental/synchronized_value * include/experimental/system_error * include/experimental/timer * include/experimental/tuple * include/experimental/type_traits * include/experimental/unordered_map * include/experimental/unordered_set * include/experimental/vector * include/ext/algorithm * include/ext/cmath * include/ext/functional * include/ext/iterator * include/ext/memory * include/ext/numeric * include/ext/random * include/ext/rb_tree * include/ext/rope * include/parallel/algorithm * include/std/algorithm * include/std/any * include/std/array * include/std/atomic * include/std/barrier * include/std/bit * include/std/bitset * include/std/charconv * include/std/chrono * include/std/codecvt * include/std/complex * include/std/concepts * include/std/condition_variable * include/std/coroutine * include/std/deque * include/std/execution * include/std/expected * include/std/filesystem * include/std/format * include/std/forward_list * include/std/fstream * include/std/functional * include/std/future * include/std/generator * include/std/iomanip * include/std/ios * include/std/iosfwd * include/std/iostream * include/std/istream * include/std/iterator * include/std/latch * include/std/limits * include/std/list * include/std/locale * include/std/map * include/std/memory * include/std/memory_resource * include/std/mutex * include/std/numbers * include/std/numeric * include/std/optional * include/std/ostream * include/std/print * include/std/queue * include/std/random * include/std/ranges * include/std/ratio * include/std/regex * include/std/scoped_allocator * include/std/semaphore * include/std/set * include/std/shared_mutex * include/std/span * include/std/spanstream * include/std/sstream * include/std/stack * include/std/stacktrace * include/std/stdexcept * include/std/streambuf * include/std/string * include/std/string_view * include/std/syncstream * include/std/system_error * include/std/text_encoding * include/std/thread * include/std/tuple * include/std/type_traits * include/std/typeindex * include/std/unordered_map * include/std/unordered_set * include/std/utility * include/std/valarray * include/std/variant * include/std/vector * include/std/version * include/tr1/array * include/tr1/cfenv * include/tr1/cinttypes * include/tr1/cmath * include/tr1/complex * include/tr1/cstdbool * include/tr1/cstdint * include/tr1/cstdio * include/tr1/cstdlib * include/tr1/cwchar * include/tr1/cwctype * include/tr1/functional * include/tr1/memory * include/tr1/random * include/tr1/regex * include/tr1/tuple * include/tr1/type_traits * include/tr1/unordered_map * include/tr1/unordered_set * include/tr1/utility * include/tr2/bool_set * include/tr2/dynamic_bitset * include/tr2/type_traits * libsupc++/atomic_lockfree_defines.h * libsupc++/compare * libsupc++/cxxabi.h * libsupc++/cxxabi_forced.h * libsupc++/cxxabi_init_exception.h * libsupc++/exception * libsupc++/initializer_list * libsupc++/new * libsupc++/typeinfo: Likewise. * testsuite/20_util/ratio/operations/ops_overflow_neg.cc * testsuite/23_containers/array/tuple_interface/get_neg.cc * testsuite/23_containers/vector/cons/destructible_debug_neg.cc * testsuite/24_iterators/operations/prev_neg.cc * testsuite/ext/type_traits/add_unsigned_floating_neg.cc * testsuite/ext/type_traits/add_unsigned_integer_neg.cc * testsuite/ext/type_traits/remove_unsigned_floating_neg.cc * testsuite/ext/type_traits/remove_unsigned_integer_neg.cc: Adjust line numbers. gcc/testsuite/ChangeLog * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C * g++.dg/diagnostic/disable.C: #define _GLIBCXX_SYSHDR.
489 lines
14 KiB
C++
489 lines
14 KiB
C++
// <bit> -*- C++ -*-
|
|
|
|
// Copyright (C) 2018-2024 Free Software Foundation, Inc.
|
|
//
|
|
// 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/bit
|
|
* This is a Standard C++ Library header.
|
|
*/
|
|
|
|
#ifndef _GLIBCXX_BIT
|
|
#define _GLIBCXX_BIT 1
|
|
|
|
#ifdef _GLIBCXX_SYSHDR
|
|
#pragma GCC system_header
|
|
#endif
|
|
|
|
#if __cplusplus >= 201402L
|
|
|
|
#include <concepts> // for std::integral
|
|
#include <type_traits>
|
|
|
|
#if _GLIBCXX_HOSTED || __has_include(<ext/numeric_traits.h>)
|
|
# include <ext/numeric_traits.h>
|
|
#else
|
|
# include <limits>
|
|
/// @cond undocumented
|
|
namespace __gnu_cxx
|
|
{
|
|
template<typename _Tp>
|
|
struct __int_traits
|
|
{
|
|
static constexpr int __digits = std::numeric_limits<_Tp>::digits;
|
|
static constexpr _Tp __max = std::numeric_limits<_Tp>::max();
|
|
};
|
|
}
|
|
/// @endcond
|
|
#endif
|
|
|
|
#define __glibcxx_want_bit_cast
|
|
#define __glibcxx_want_byteswap
|
|
#define __glibcxx_want_bitops
|
|
#define __glibcxx_want_int_pow2
|
|
#define __glibcxx_want_endian
|
|
#include <bits/version.h>
|
|
|
|
namespace std _GLIBCXX_VISIBILITY(default)
|
|
{
|
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|
|
|
/**
|
|
* @defgroup bit_manip Bit manipulation
|
|
* @ingroup numerics
|
|
*
|
|
* Utilities for examining and manipulating individual bits.
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
#ifdef __cpp_lib_bit_cast // C++ >= 20
|
|
|
|
/// Create a value of type `To` from the bits of `from`.
|
|
/**
|
|
* @tparam _To A trivially-copyable type.
|
|
* @param __from A trivially-copyable object of the same size as `_To`.
|
|
* @return An object of type `_To`.
|
|
* @since C++20
|
|
*/
|
|
template<typename _To, typename _From>
|
|
[[nodiscard]]
|
|
constexpr _To
|
|
bit_cast(const _From& __from) noexcept
|
|
#ifdef __cpp_concepts
|
|
requires (sizeof(_To) == sizeof(_From))
|
|
&& is_trivially_copyable_v<_To> && is_trivially_copyable_v<_From>
|
|
#endif
|
|
{
|
|
return __builtin_bit_cast(_To, __from);
|
|
}
|
|
#endif // __cpp_lib_bit_cast
|
|
|
|
#ifdef __cpp_lib_byteswap // C++ >= 23
|
|
|
|
/// Reverse order of bytes in the object representation of `value`.
|
|
/**
|
|
* @tparam _Tp An integral type.
|
|
* @param __value An object of integer type.
|
|
* @return An object of the same type, with the bytes reversed.
|
|
* @since C++23
|
|
*/
|
|
template<integral _Tp>
|
|
[[nodiscard]]
|
|
constexpr _Tp
|
|
byteswap(_Tp __value) noexcept
|
|
{
|
|
if constexpr (sizeof(_Tp) == 1)
|
|
return __value;
|
|
#if __cpp_if_consteval >= 202106L && __CHAR_BIT__ == 8
|
|
if !consteval
|
|
{
|
|
if constexpr (sizeof(_Tp) == 2)
|
|
return __builtin_bswap16(__value);
|
|
if constexpr (sizeof(_Tp) == 4)
|
|
return __builtin_bswap32(__value);
|
|
if constexpr (sizeof(_Tp) == 8)
|
|
return __builtin_bswap64(__value);
|
|
if constexpr (sizeof(_Tp) == 16)
|
|
#if __has_builtin(__builtin_bswap128)
|
|
return __builtin_bswap128(__value);
|
|
#else
|
|
return (__builtin_bswap64(__value >> 64)
|
|
| (static_cast<_Tp>(__builtin_bswap64(__value)) << 64));
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
// Fallback implementation that handles even __int24 etc.
|
|
using _Up = typename __make_unsigned<__remove_cv_t<_Tp>>::__type;
|
|
size_t __diff = __CHAR_BIT__ * (sizeof(_Tp) - 1);
|
|
_Up __mask1 = static_cast<unsigned char>(~0);
|
|
_Up __mask2 = __mask1 << __diff;
|
|
_Up __val = __value;
|
|
for (size_t __i = 0; __i < sizeof(_Tp) / 2; ++__i)
|
|
{
|
|
_Up __byte1 = __val & __mask1;
|
|
_Up __byte2 = __val & __mask2;
|
|
__val = (__val ^ __byte1 ^ __byte2
|
|
^ (__byte1 << __diff) ^ (__byte2 >> __diff));
|
|
__mask1 <<= __CHAR_BIT__;
|
|
__mask2 >>= __CHAR_BIT__;
|
|
__diff -= 2 * __CHAR_BIT__;
|
|
}
|
|
return __val;
|
|
}
|
|
#endif // __cpp_lib_byteswap
|
|
|
|
/// @cond undocumented
|
|
|
|
template<typename _Tp>
|
|
constexpr _Tp
|
|
__rotl(_Tp __x, int __s) noexcept
|
|
{
|
|
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
|
|
if _GLIBCXX17_CONSTEXPR ((_Nd & (_Nd - 1)) == 0)
|
|
{
|
|
// Variant for power of two _Nd which the compiler can
|
|
// easily pattern match.
|
|
constexpr unsigned __uNd = _Nd;
|
|
const unsigned __r = __s;
|
|
return (__x << (__r % __uNd)) | (__x >> ((-__r) % __uNd));
|
|
}
|
|
const int __r = __s % _Nd;
|
|
if (__r == 0)
|
|
return __x;
|
|
else if (__r > 0)
|
|
return (__x << __r) | (__x >> ((_Nd - __r) % _Nd));
|
|
else
|
|
return (__x >> -__r) | (__x << ((_Nd + __r) % _Nd)); // rotr(x, -r)
|
|
}
|
|
|
|
template<typename _Tp>
|
|
constexpr _Tp
|
|
__rotr(_Tp __x, int __s) noexcept
|
|
{
|
|
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
|
|
if _GLIBCXX17_CONSTEXPR ((_Nd & (_Nd - 1)) == 0)
|
|
{
|
|
// Variant for power of two _Nd which the compiler can
|
|
// easily pattern match.
|
|
constexpr unsigned __uNd = _Nd;
|
|
const unsigned __r = __s;
|
|
return (__x >> (__r % __uNd)) | (__x << ((-__r) % __uNd));
|
|
}
|
|
const int __r = __s % _Nd;
|
|
if (__r == 0)
|
|
return __x;
|
|
else if (__r > 0)
|
|
return (__x >> __r) | (__x << ((_Nd - __r) % _Nd));
|
|
else
|
|
return (__x << -__r) | (__x >> ((_Nd + __r) % _Nd)); // rotl(x, -r)
|
|
}
|
|
|
|
template<typename _Tp>
|
|
constexpr int
|
|
__countl_zero(_Tp __x) noexcept
|
|
{
|
|
using __gnu_cxx::__int_traits;
|
|
constexpr auto _Nd = __int_traits<_Tp>::__digits;
|
|
|
|
if (__x == 0)
|
|
return _Nd;
|
|
|
|
constexpr auto _Nd_ull = __int_traits<unsigned long long>::__digits;
|
|
constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits;
|
|
constexpr auto _Nd_u = __int_traits<unsigned>::__digits;
|
|
|
|
if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
|
|
{
|
|
constexpr int __diff = _Nd_u - _Nd;
|
|
return __builtin_clz(__x) - __diff;
|
|
}
|
|
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
|
|
{
|
|
constexpr int __diff = _Nd_ul - _Nd;
|
|
return __builtin_clzl(__x) - __diff;
|
|
}
|
|
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
|
|
{
|
|
constexpr int __diff = _Nd_ull - _Nd;
|
|
return __builtin_clzll(__x) - __diff;
|
|
}
|
|
else // (_Nd > _Nd_ull)
|
|
{
|
|
static_assert(_Nd <= (2 * _Nd_ull),
|
|
"Maximum supported integer size is 128-bit");
|
|
|
|
unsigned long long __high = __x >> _Nd_ull;
|
|
if (__high != 0)
|
|
{
|
|
constexpr int __diff = (2 * _Nd_ull) - _Nd;
|
|
return __builtin_clzll(__high) - __diff;
|
|
}
|
|
constexpr auto __max_ull = __int_traits<unsigned long long>::__max;
|
|
unsigned long long __low = __x & __max_ull;
|
|
return (_Nd - _Nd_ull) + __builtin_clzll(__low);
|
|
}
|
|
}
|
|
|
|
template<typename _Tp>
|
|
constexpr int
|
|
__countl_one(_Tp __x) noexcept
|
|
{
|
|
return std::__countl_zero<_Tp>((_Tp)~__x);
|
|
}
|
|
|
|
template<typename _Tp>
|
|
constexpr int
|
|
__countr_zero(_Tp __x) noexcept
|
|
{
|
|
using __gnu_cxx::__int_traits;
|
|
constexpr auto _Nd = __int_traits<_Tp>::__digits;
|
|
|
|
if (__x == 0)
|
|
return _Nd;
|
|
|
|
constexpr auto _Nd_ull = __int_traits<unsigned long long>::__digits;
|
|
constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits;
|
|
constexpr auto _Nd_u = __int_traits<unsigned>::__digits;
|
|
|
|
if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
|
|
return __builtin_ctz(__x);
|
|
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
|
|
return __builtin_ctzl(__x);
|
|
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
|
|
return __builtin_ctzll(__x);
|
|
else // (_Nd > _Nd_ull)
|
|
{
|
|
static_assert(_Nd <= (2 * _Nd_ull),
|
|
"Maximum supported integer size is 128-bit");
|
|
|
|
constexpr auto __max_ull = __int_traits<unsigned long long>::__max;
|
|
unsigned long long __low = __x & __max_ull;
|
|
if (__low != 0)
|
|
return __builtin_ctzll(__low);
|
|
unsigned long long __high = __x >> _Nd_ull;
|
|
return __builtin_ctzll(__high) + _Nd_ull;
|
|
}
|
|
}
|
|
|
|
template<typename _Tp>
|
|
constexpr int
|
|
__countr_one(_Tp __x) noexcept
|
|
{
|
|
return std::__countr_zero((_Tp)~__x);
|
|
}
|
|
|
|
template<typename _Tp>
|
|
constexpr int
|
|
__popcount(_Tp __x) noexcept
|
|
{
|
|
using __gnu_cxx::__int_traits;
|
|
constexpr auto _Nd = __int_traits<_Tp>::__digits;
|
|
|
|
constexpr auto _Nd_ull = __int_traits<unsigned long long>::__digits;
|
|
constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits;
|
|
constexpr auto _Nd_u = __int_traits<unsigned>::__digits;
|
|
|
|
if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
|
|
return __builtin_popcount(__x);
|
|
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
|
|
return __builtin_popcountl(__x);
|
|
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
|
|
return __builtin_popcountll(__x);
|
|
else // (_Nd > _Nd_ull)
|
|
{
|
|
static_assert(_Nd <= (2 * _Nd_ull),
|
|
"Maximum supported integer size is 128-bit");
|
|
|
|
constexpr auto __max_ull = __int_traits<unsigned long long>::__max;
|
|
unsigned long long __low = __x & __max_ull;
|
|
unsigned long long __high = __x >> _Nd_ull;
|
|
return __builtin_popcountll(__low) + __builtin_popcountll(__high);
|
|
}
|
|
}
|
|
|
|
template<typename _Tp>
|
|
constexpr bool
|
|
__has_single_bit(_Tp __x) noexcept
|
|
{ return std::__popcount(__x) == 1; }
|
|
|
|
template<typename _Tp>
|
|
constexpr _Tp
|
|
__bit_ceil(_Tp __x) noexcept
|
|
{
|
|
using __gnu_cxx::__int_traits;
|
|
constexpr auto _Nd = __int_traits<_Tp>::__digits;
|
|
if (__x == 0 || __x == 1)
|
|
return 1;
|
|
auto __shift_exponent = _Nd - std::__countl_zero((_Tp)(__x - 1u));
|
|
// If the shift exponent equals _Nd then the correct result is not
|
|
// representable as a value of _Tp, and so the result is undefined.
|
|
// Want that undefined behaviour to be detected in constant expressions,
|
|
// by UBSan, and by debug assertions.
|
|
if (!std::__is_constant_evaluated())
|
|
{
|
|
__glibcxx_assert( __shift_exponent != __int_traits<_Tp>::__digits );
|
|
}
|
|
|
|
using __promoted_type = decltype(__x << 1);
|
|
if _GLIBCXX17_CONSTEXPR (!is_same<__promoted_type, _Tp>::value)
|
|
{
|
|
// If __x undergoes integral promotion then shifting by _Nd is
|
|
// not undefined. In order to make the shift undefined, so that
|
|
// it is diagnosed in constant expressions and by UBsan, we also
|
|
// need to "promote" the shift exponent to be too large for the
|
|
// promoted type.
|
|
const int __extra_exp = sizeof(__promoted_type) / sizeof(_Tp) / 2;
|
|
__shift_exponent |= (__shift_exponent & _Nd) << __extra_exp;
|
|
}
|
|
return (_Tp)1u << __shift_exponent;
|
|
}
|
|
|
|
template<typename _Tp>
|
|
constexpr _Tp
|
|
__bit_floor(_Tp __x) noexcept
|
|
{
|
|
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
|
|
if (__x == 0)
|
|
return 0;
|
|
return (_Tp)1u << (_Nd - std::__countl_zero((_Tp)(__x >> 1)));
|
|
}
|
|
|
|
template<typename _Tp>
|
|
constexpr int
|
|
__bit_width(_Tp __x) noexcept
|
|
{
|
|
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
|
|
return _Nd - std::__countl_zero(__x);
|
|
}
|
|
|
|
/// @endcond
|
|
|
|
#ifdef __cpp_lib_bitops // C++ >= 20
|
|
|
|
/// @cond undocumented
|
|
template<typename _Tp>
|
|
concept __unsigned_integer = __is_unsigned_integer<_Tp>::value;
|
|
/// @endcond
|
|
|
|
// [bit.rot], rotating
|
|
|
|
/// Rotate `x` to the left by `s` bits.
|
|
template<__unsigned_integer _Tp>
|
|
[[nodiscard]] constexpr _Tp
|
|
rotl(_Tp __x, int __s) noexcept
|
|
{ return std::__rotl(__x, __s); }
|
|
|
|
/// Rotate `x` to the right by `s` bits.
|
|
template<__unsigned_integer _Tp>
|
|
[[nodiscard]] constexpr _Tp
|
|
rotr(_Tp __x, int __s) noexcept
|
|
{ return std::__rotr(__x, __s); }
|
|
|
|
// [bit.count], counting
|
|
|
|
/// The number of contiguous zero bits, starting from the highest bit.
|
|
template<__unsigned_integer _Tp>
|
|
constexpr int
|
|
countl_zero(_Tp __x) noexcept
|
|
{ return std::__countl_zero(__x); }
|
|
|
|
/// The number of contiguous one bits, starting from the highest bit.
|
|
template<__unsigned_integer _Tp>
|
|
constexpr int
|
|
countl_one(_Tp __x) noexcept
|
|
{ return std::__countl_one(__x); }
|
|
|
|
/// The number of contiguous zero bits, starting from the lowest bit.
|
|
template<__unsigned_integer _Tp>
|
|
constexpr int
|
|
countr_zero(_Tp __x) noexcept
|
|
{ return std::__countr_zero(__x); }
|
|
|
|
/// The number of contiguous one bits, starting from the lowest bit.
|
|
template<__unsigned_integer _Tp>
|
|
constexpr int
|
|
countr_one(_Tp __x) noexcept
|
|
{ return std::__countr_one(__x); }
|
|
|
|
/// The number of bits set in `x`.
|
|
template<__unsigned_integer _Tp>
|
|
constexpr int
|
|
popcount(_Tp __x) noexcept
|
|
{ return std::__popcount(__x); }
|
|
#endif // __cpp_lib_bitops
|
|
|
|
#ifdef __cpp_lib_int_pow2 // C++ >= 20
|
|
// [bit.pow.two], integral powers of 2
|
|
|
|
/// True if `x` is a power of two, false otherwise.
|
|
template<__unsigned_integer _Tp>
|
|
constexpr bool
|
|
has_single_bit(_Tp __x) noexcept
|
|
{ return std::__has_single_bit(__x); }
|
|
|
|
/// The smallest power-of-two not less than `x`.
|
|
template<__unsigned_integer _Tp>
|
|
constexpr _Tp
|
|
bit_ceil(_Tp __x) noexcept
|
|
{ return std::__bit_ceil(__x); }
|
|
|
|
/// The largest power-of-two not greater than `x`.
|
|
template<__unsigned_integer _Tp>
|
|
constexpr _Tp
|
|
bit_floor(_Tp __x) noexcept
|
|
{ return std::__bit_floor(__x); }
|
|
|
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
|
// 3656. Inconsistent bit operations returning a count
|
|
/// The smallest integer greater than the base-2 logarithm of `x`.
|
|
template<__unsigned_integer _Tp>
|
|
constexpr int
|
|
bit_width(_Tp __x) noexcept
|
|
{ return std::__bit_width(__x); }
|
|
#endif // defined (__cpp_lib_int_pow2)
|
|
|
|
#ifdef __cpp_lib_endian // C++ >= 20
|
|
|
|
/// Byte order constants
|
|
/**
|
|
* The platform endianness can be checked by comparing `std::endian::native`
|
|
* to one of `std::endian::big` or `std::endian::little`.
|
|
*
|
|
* @since C++20
|
|
*/
|
|
enum class endian
|
|
{
|
|
little = __ORDER_LITTLE_ENDIAN__,
|
|
big = __ORDER_BIG_ENDIAN__,
|
|
native = __BYTE_ORDER__
|
|
};
|
|
#endif // __cpp_lib_endian
|
|
|
|
/// @}
|
|
|
|
_GLIBCXX_END_NAMESPACE_VERSION
|
|
} // namespace std
|
|
|
|
#endif // C++14
|
|
#endif // _GLIBCXX_BIT
|