annotate libstdc++-v3/include/std/bit @ 158:494b0b89df80 default tip

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