xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/std/bit (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1*627f7eb2Smrg// <bit> -*- C++ -*-
2*627f7eb2Smrg
3*627f7eb2Smrg// Copyright (C) 2018-2019 Free Software Foundation, Inc.
4*627f7eb2Smrg//
5*627f7eb2Smrg// This file is part of the GNU ISO C++ Library.  This library is free
6*627f7eb2Smrg// software; you can redistribute it and/or modify it under the
7*627f7eb2Smrg// terms of the GNU General Public License as published by the
8*627f7eb2Smrg// Free Software Foundation; either version 3, or (at your option)
9*627f7eb2Smrg// any later version.
10*627f7eb2Smrg
11*627f7eb2Smrg// This library is distributed in the hope that it will be useful,
12*627f7eb2Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
13*627f7eb2Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*627f7eb2Smrg// GNU General Public License for more details.
15*627f7eb2Smrg
16*627f7eb2Smrg// Under Section 7 of GPL version 3, you are granted additional
17*627f7eb2Smrg// permissions described in the GCC Runtime Library Exception, version
18*627f7eb2Smrg// 3.1, as published by the Free Software Foundation.
19*627f7eb2Smrg
20*627f7eb2Smrg// You should have received a copy of the GNU General Public License and
21*627f7eb2Smrg// a copy of the GCC Runtime Library Exception along with this program;
22*627f7eb2Smrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*627f7eb2Smrg// <http://www.gnu.org/licenses/>.
24*627f7eb2Smrg
25*627f7eb2Smrg/** @file include/bit
26*627f7eb2Smrg *  This is a Standard C++ Library header.
27*627f7eb2Smrg */
28*627f7eb2Smrg
29*627f7eb2Smrg#ifndef _GLIBCXX_BIT
30*627f7eb2Smrg#define _GLIBCXX_BIT 1
31*627f7eb2Smrg
32*627f7eb2Smrg#pragma GCC system_header
33*627f7eb2Smrg
34*627f7eb2Smrg#if __cplusplus >= 201402L
35*627f7eb2Smrg
36*627f7eb2Smrg#include <type_traits>
37*627f7eb2Smrg#include <limits>
38*627f7eb2Smrg
39*627f7eb2Smrgnamespace std _GLIBCXX_VISIBILITY(default)
40*627f7eb2Smrg{
41*627f7eb2Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
42*627f7eb2Smrg
43*627f7eb2Smrg  template<typename _Tp>
44*627f7eb2Smrg    constexpr _Tp
45*627f7eb2Smrg    __rotl(_Tp __x, int __s) noexcept
46*627f7eb2Smrg    {
47*627f7eb2Smrg      constexpr auto _Nd = numeric_limits<_Tp>::digits;
48*627f7eb2Smrg      const int __r = __s % _Nd;
49*627f7eb2Smrg      if (__r == 0)
50*627f7eb2Smrg	return __x;
51*627f7eb2Smrg      else if (__r > 0)
52*627f7eb2Smrg	return (__x << __r) | (__x >> ((_Nd - __r) % _Nd));
53*627f7eb2Smrg      else
54*627f7eb2Smrg	return (__x >> -__r) | (__x << ((_Nd + __r) % _Nd)); // rotr(x, -r)
55*627f7eb2Smrg    }
56*627f7eb2Smrg
57*627f7eb2Smrg  template<typename _Tp>
58*627f7eb2Smrg    constexpr _Tp
59*627f7eb2Smrg    __rotr(_Tp __x, int __s) noexcept
60*627f7eb2Smrg    {
61*627f7eb2Smrg      constexpr auto _Nd = numeric_limits<_Tp>::digits;
62*627f7eb2Smrg      const int __r = __s % _Nd;
63*627f7eb2Smrg      if (__r == 0)
64*627f7eb2Smrg	return __x;
65*627f7eb2Smrg      else if (__r > 0)
66*627f7eb2Smrg	return (__x >> __r) | (__x << ((_Nd - __r) % _Nd));
67*627f7eb2Smrg      else
68*627f7eb2Smrg	return (__x << -__r) | (__x >> ((_Nd + __r) % _Nd)); // rotl(x, -r)
69*627f7eb2Smrg    }
70*627f7eb2Smrg
71*627f7eb2Smrg  template<typename _Tp>
72*627f7eb2Smrg    constexpr int
73*627f7eb2Smrg    __countl_zero(_Tp __x) noexcept
74*627f7eb2Smrg    {
75*627f7eb2Smrg      constexpr auto _Nd = numeric_limits<_Tp>::digits;
76*627f7eb2Smrg
77*627f7eb2Smrg      if (__x == 0)
78*627f7eb2Smrg        return _Nd;
79*627f7eb2Smrg
80*627f7eb2Smrg      constexpr auto _Nd_ull = numeric_limits<unsigned long long>::digits;
81*627f7eb2Smrg      constexpr auto _Nd_ul = numeric_limits<unsigned long>::digits;
82*627f7eb2Smrg      constexpr auto _Nd_u = numeric_limits<unsigned>::digits;
83*627f7eb2Smrg
84*627f7eb2Smrg      if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
85*627f7eb2Smrg	{
86*627f7eb2Smrg	  constexpr int __diff = _Nd_u - _Nd;
87*627f7eb2Smrg	  return __builtin_clz(__x) - __diff;
88*627f7eb2Smrg	}
89*627f7eb2Smrg      else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
90*627f7eb2Smrg	{
91*627f7eb2Smrg	  constexpr int __diff = _Nd_ul - _Nd;
92*627f7eb2Smrg	  return __builtin_clzl(__x) - __diff;
93*627f7eb2Smrg	}
94*627f7eb2Smrg      else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
95*627f7eb2Smrg	{
96*627f7eb2Smrg	  constexpr int __diff = _Nd_ull - _Nd;
97*627f7eb2Smrg	  return __builtin_clzll(__x) - __diff;
98*627f7eb2Smrg	}
99*627f7eb2Smrg      else // (_Nd > _Nd_ull)
100*627f7eb2Smrg	{
101*627f7eb2Smrg	  static_assert(_Nd <= (2 * _Nd_ull),
102*627f7eb2Smrg			"Maximum supported integer size is 128-bit");
103*627f7eb2Smrg
104*627f7eb2Smrg	  unsigned long long __high = __x >> _Nd_ull;
105*627f7eb2Smrg	  if (__high != 0)
106*627f7eb2Smrg	    {
107*627f7eb2Smrg	      constexpr int __diff = (2 * _Nd_ull) - _Nd;
108*627f7eb2Smrg	      return __builtin_clzll(__high) - __diff;
109*627f7eb2Smrg	    }
110*627f7eb2Smrg	  constexpr auto __max_ull = numeric_limits<unsigned long long>::max();
111*627f7eb2Smrg	  unsigned long long __low = __x & __max_ull;
112*627f7eb2Smrg	  return (_Nd - _Nd_ull) + __builtin_clzll(__low);
113*627f7eb2Smrg	}
114*627f7eb2Smrg    }
115*627f7eb2Smrg
116*627f7eb2Smrg  template<typename _Tp>
117*627f7eb2Smrg    constexpr int
118*627f7eb2Smrg    __countl_one(_Tp __x) noexcept
119*627f7eb2Smrg    {
120*627f7eb2Smrg      if (__x == numeric_limits<_Tp>::max())
121*627f7eb2Smrg        return numeric_limits<_Tp>::digits;
122*627f7eb2Smrg      return std::__countl_zero<_Tp>((_Tp)~__x);
123*627f7eb2Smrg    }
124*627f7eb2Smrg
125*627f7eb2Smrg  template<typename _Tp>
126*627f7eb2Smrg    constexpr int
127*627f7eb2Smrg    __countr_zero(_Tp __x) noexcept
128*627f7eb2Smrg    {
129*627f7eb2Smrg      constexpr auto _Nd = numeric_limits<_Tp>::digits;
130*627f7eb2Smrg
131*627f7eb2Smrg      if (__x == 0)
132*627f7eb2Smrg        return _Nd;
133*627f7eb2Smrg
134*627f7eb2Smrg      constexpr auto _Nd_ull = numeric_limits<unsigned long long>::digits;
135*627f7eb2Smrg      constexpr auto _Nd_ul = numeric_limits<unsigned long>::digits;
136*627f7eb2Smrg      constexpr auto _Nd_u = numeric_limits<unsigned>::digits;
137*627f7eb2Smrg
138*627f7eb2Smrg      if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
139*627f7eb2Smrg	return __builtin_ctz(__x);
140*627f7eb2Smrg      else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
141*627f7eb2Smrg	return __builtin_ctzl(__x);
142*627f7eb2Smrg      else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
143*627f7eb2Smrg	return __builtin_ctzll(__x);
144*627f7eb2Smrg      else // (_Nd > _Nd_ull)
145*627f7eb2Smrg	{
146*627f7eb2Smrg	  static_assert(_Nd <= (2 * _Nd_ull),
147*627f7eb2Smrg			"Maximum supported integer size is 128-bit");
148*627f7eb2Smrg
149*627f7eb2Smrg	  constexpr auto __max_ull = numeric_limits<unsigned long long>::max();
150*627f7eb2Smrg	  unsigned long long __low = __x & __max_ull;
151*627f7eb2Smrg	  if (__low != 0)
152*627f7eb2Smrg	    return __builtin_ctzll(__low);
153*627f7eb2Smrg	  unsigned long long __high = __x >> _Nd_ull;
154*627f7eb2Smrg	  return __builtin_ctzll(__high) + _Nd_ull;
155*627f7eb2Smrg	}
156*627f7eb2Smrg    }
157*627f7eb2Smrg
158*627f7eb2Smrg  template<typename _Tp>
159*627f7eb2Smrg    constexpr int
160*627f7eb2Smrg    __countr_one(_Tp __x) noexcept
161*627f7eb2Smrg    {
162*627f7eb2Smrg      if (__x == numeric_limits<_Tp>::max())
163*627f7eb2Smrg        return numeric_limits<_Tp>::digits;
164*627f7eb2Smrg      return std::__countr_zero((_Tp)~__x);
165*627f7eb2Smrg    }
166*627f7eb2Smrg
167*627f7eb2Smrg  template<typename _Tp>
168*627f7eb2Smrg    constexpr int
169*627f7eb2Smrg    __popcount(_Tp __x) noexcept
170*627f7eb2Smrg    {
171*627f7eb2Smrg      constexpr auto _Nd = numeric_limits<_Tp>::digits;
172*627f7eb2Smrg
173*627f7eb2Smrg      if (__x == 0)
174*627f7eb2Smrg        return 0;
175*627f7eb2Smrg
176*627f7eb2Smrg      constexpr auto _Nd_ull = numeric_limits<unsigned long long>::digits;
177*627f7eb2Smrg      constexpr auto _Nd_ul = numeric_limits<unsigned long>::digits;
178*627f7eb2Smrg      constexpr auto _Nd_u = numeric_limits<unsigned>::digits;
179*627f7eb2Smrg
180*627f7eb2Smrg      if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
181*627f7eb2Smrg	return __builtin_popcount(__x);
182*627f7eb2Smrg      else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
183*627f7eb2Smrg	return __builtin_popcountl(__x);
184*627f7eb2Smrg      else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
185*627f7eb2Smrg	return __builtin_popcountll(__x);
186*627f7eb2Smrg      else // (_Nd > _Nd_ull)
187*627f7eb2Smrg	{
188*627f7eb2Smrg	  static_assert(_Nd <= (2 * _Nd_ull),
189*627f7eb2Smrg			"Maximum supported integer size is 128-bit");
190*627f7eb2Smrg
191*627f7eb2Smrg	  constexpr auto __max_ull = numeric_limits<unsigned long long>::max();
192*627f7eb2Smrg	  unsigned long long __low = __x & __max_ull;
193*627f7eb2Smrg	  unsigned long long __high = __x >> _Nd_ull;
194*627f7eb2Smrg	  return __builtin_popcountll(__low) + __builtin_popcountll(__high);
195*627f7eb2Smrg	}
196*627f7eb2Smrg    }
197*627f7eb2Smrg
198*627f7eb2Smrg  template<typename _Tp>
199*627f7eb2Smrg    constexpr bool
200*627f7eb2Smrg    __ispow2(_Tp __x) noexcept
201*627f7eb2Smrg    { return std::__popcount(__x) == 1; }
202*627f7eb2Smrg
203*627f7eb2Smrg  template<typename _Tp>
204*627f7eb2Smrg    constexpr _Tp
205*627f7eb2Smrg    __ceil2(_Tp __x) noexcept
206*627f7eb2Smrg    {
207*627f7eb2Smrg      constexpr auto _Nd = numeric_limits<_Tp>::digits;
208*627f7eb2Smrg      if (__x == 0 || __x == 1)
209*627f7eb2Smrg        return 1;
210*627f7eb2Smrg      auto __shift_exponent = _Nd - std::__countl_zero((_Tp)(__x - 1u));
211*627f7eb2Smrg      // If the shift exponent equals _Nd then the correct result is not
212*627f7eb2Smrg      // representable as a value of _Tp, and so the result is undefined.
213*627f7eb2Smrg      // Want that undefined behaviour to be detected in constant expressions,
214*627f7eb2Smrg      // by UBSan, and by debug assertions.
215*627f7eb2Smrg#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
216*627f7eb2Smrg      if (!__builtin_is_constant_evaluated())
217*627f7eb2Smrg	__glibcxx_assert( __shift_exponent != numeric_limits<_Tp>::digits );
218*627f7eb2Smrg#endif
219*627f7eb2Smrg      using __promoted_type = decltype(__x << 1);
220*627f7eb2Smrg      if _GLIBCXX17_CONSTEXPR (!is_same<__promoted_type, _Tp>::value)
221*627f7eb2Smrg	{
222*627f7eb2Smrg	  // If __x undergoes integral promotion then shifting by _Nd is
223*627f7eb2Smrg	  // not undefined. In order to make the shift undefined, so that
224*627f7eb2Smrg	  // it is diagnosed in constant expressions and by UBsan, we also
225*627f7eb2Smrg	  // need to "promote" the shift exponent to be too large for the
226*627f7eb2Smrg	  // promoted type.
227*627f7eb2Smrg	  const int __extra_exp = sizeof(__promoted_type) / sizeof(_Tp) / 2;
228*627f7eb2Smrg	  __shift_exponent |= (__shift_exponent & _Nd) << __extra_exp;
229*627f7eb2Smrg	}
230*627f7eb2Smrg      return (_Tp)1u << __shift_exponent;
231*627f7eb2Smrg    }
232*627f7eb2Smrg
233*627f7eb2Smrg  template<typename _Tp>
234*627f7eb2Smrg    constexpr _Tp
235*627f7eb2Smrg    __floor2(_Tp __x) noexcept
236*627f7eb2Smrg    {
237*627f7eb2Smrg      constexpr auto _Nd = numeric_limits<_Tp>::digits;
238*627f7eb2Smrg      if (__x == 0)
239*627f7eb2Smrg        return 0;
240*627f7eb2Smrg      return (_Tp)1u << (_Nd - std::__countl_zero((_Tp)(__x >> 1)));
241*627f7eb2Smrg    }
242*627f7eb2Smrg
243*627f7eb2Smrg  template<typename _Tp>
244*627f7eb2Smrg    constexpr _Tp
245*627f7eb2Smrg    __log2p1(_Tp __x) noexcept
246*627f7eb2Smrg    {
247*627f7eb2Smrg      constexpr auto _Nd = numeric_limits<_Tp>::digits;
248*627f7eb2Smrg      return _Nd - std::__countl_zero(__x);
249*627f7eb2Smrg    }
250*627f7eb2Smrg
251*627f7eb2Smrg#if __cplusplus > 201703L
252*627f7eb2Smrg
253*627f7eb2Smrg  template<typename _Tp, typename _Up, bool = is_integral_v<_Tp>>
254*627f7eb2Smrg    struct _If_is_unsigned_integer_type { };
255*627f7eb2Smrg
256*627f7eb2Smrg  template<typename _Up>
257*627f7eb2Smrg    struct _If_is_unsigned_integer_type<bool, _Up, true> { };
258*627f7eb2Smrg
259*627f7eb2Smrg  template<typename _Tp, typename _Up>
260*627f7eb2Smrg    struct _If_is_unsigned_integer_type<_Tp, _Up, true>
261*627f7eb2Smrg    : enable_if<is_same_v<_Tp, make_unsigned_t<_Tp>>, _Up> { };
262*627f7eb2Smrg
263*627f7eb2Smrg  template<typename _Tp, typename _Up = _Tp>
264*627f7eb2Smrg    using _If_is_unsigned_integer
265*627f7eb2Smrg      = typename _If_is_unsigned_integer_type<remove_cv_t<_Tp>, _Up>::type;
266*627f7eb2Smrg
267*627f7eb2Smrg  // [bit.rot], rotating
268*627f7eb2Smrg
269*627f7eb2Smrg  template<typename _Tp>
270*627f7eb2Smrg    [[nodiscard]] constexpr _If_is_unsigned_integer<_Tp>
271*627f7eb2Smrg    rotl(_Tp __x, int __s) noexcept
272*627f7eb2Smrg    { return std::__rotl(__x, __s); }
273*627f7eb2Smrg
274*627f7eb2Smrg  template<typename _Tp>
275*627f7eb2Smrg    [[nodiscard]] constexpr _If_is_unsigned_integer<_Tp>
276*627f7eb2Smrg    rotr(_Tp __x, int __s) noexcept
277*627f7eb2Smrg    { return std::__rotr(__x, __s); }
278*627f7eb2Smrg
279*627f7eb2Smrg  // [bit.count], counting
280*627f7eb2Smrg
281*627f7eb2Smrg  template<typename _Tp>
282*627f7eb2Smrg    constexpr _If_is_unsigned_integer<_Tp, int>
283*627f7eb2Smrg    countl_zero(_Tp __x) noexcept
284*627f7eb2Smrg    { return std::__countl_zero(__x); }
285*627f7eb2Smrg
286*627f7eb2Smrg  template<typename _Tp>
287*627f7eb2Smrg    constexpr _If_is_unsigned_integer<_Tp, int>
288*627f7eb2Smrg    countl_one(_Tp __x) noexcept
289*627f7eb2Smrg    { return std::__countl_one(__x); }
290*627f7eb2Smrg
291*627f7eb2Smrg  template<typename _Tp>
292*627f7eb2Smrg    constexpr _If_is_unsigned_integer<_Tp, int>
293*627f7eb2Smrg    countr_zero(_Tp __x) noexcept
294*627f7eb2Smrg    { return std::__countr_zero(__x); }
295*627f7eb2Smrg
296*627f7eb2Smrg  template<typename _Tp>
297*627f7eb2Smrg    constexpr _If_is_unsigned_integer<_Tp, int>
298*627f7eb2Smrg    countr_one(_Tp __x) noexcept
299*627f7eb2Smrg    { return std::__countr_one(__x); }
300*627f7eb2Smrg
301*627f7eb2Smrg  template<typename _Tp>
302*627f7eb2Smrg    constexpr _If_is_unsigned_integer<_Tp, int>
303*627f7eb2Smrg    popcount(_Tp __x) noexcept
304*627f7eb2Smrg    { return std::__popcount(__x); }
305*627f7eb2Smrg
306*627f7eb2Smrg  // [bit.pow.two], integral powers of 2
307*627f7eb2Smrg
308*627f7eb2Smrg  template<typename _Tp>
309*627f7eb2Smrg    constexpr _If_is_unsigned_integer<_Tp, bool>
310*627f7eb2Smrg    ispow2(_Tp __x) noexcept
311*627f7eb2Smrg    { return std::__ispow2(__x); }
312*627f7eb2Smrg
313*627f7eb2Smrg  template<typename _Tp>
314*627f7eb2Smrg    constexpr _If_is_unsigned_integer<_Tp>
315*627f7eb2Smrg    ceil2(_Tp __x) noexcept
316*627f7eb2Smrg    { return std::__ceil2(__x); }
317*627f7eb2Smrg
318*627f7eb2Smrg  template<typename _Tp>
319*627f7eb2Smrg    constexpr _If_is_unsigned_integer<_Tp>
320*627f7eb2Smrg    floor2(_Tp __x) noexcept
321*627f7eb2Smrg    { return std::__floor2(__x); }
322*627f7eb2Smrg
323*627f7eb2Smrg  template<typename _Tp>
324*627f7eb2Smrg    constexpr _If_is_unsigned_integer<_Tp>
325*627f7eb2Smrg    log2p1(_Tp __x) noexcept
326*627f7eb2Smrg    { return std::__log2p1(__x); }
327*627f7eb2Smrg
328*627f7eb2Smrg#define __cpp_lib_endian 201907L
329*627f7eb2Smrg
330*627f7eb2Smrg  /// Byte order
331*627f7eb2Smrg  enum class endian
332*627f7eb2Smrg  {
333*627f7eb2Smrg    little = __ORDER_LITTLE_ENDIAN__,
334*627f7eb2Smrg    big    = __ORDER_BIG_ENDIAN__,
335*627f7eb2Smrg    native = __BYTE_ORDER__
336*627f7eb2Smrg  };
337*627f7eb2Smrg#endif // C++2a
338*627f7eb2Smrg
339*627f7eb2Smrg_GLIBCXX_END_NAMESPACE_VERSION
340*627f7eb2Smrg} // namespace std
341*627f7eb2Smrg
342*627f7eb2Smrg#endif // C++14
343*627f7eb2Smrg#endif // _GLIBCXX_BIT
344