Skip to content

Commit a249355

Browse files
committed
P0553R4
1 parent 4f3e447 commit a249355

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

docs/standardization/cpp20.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,3 +1632,114 @@ int main()
16321632
delete p;
16331633
}
16341634
```
1635+
1636+
1637+
### ビット操作のための関数 [(P0553R4)](https://wg21.link/P0553R4)
1638+
ビット列の左端と右端が循環するようにシフトするビットローテーションや、1 になっているビットを数える popcount などのビット操作命令は、多くの CPU アーキテクチャに搭載されていますが、それに対応する関数は C++17 標準ライブラリには存在せず、`__builtin_popcount` (GCC, Clang) や `__popcnt` (MSVC) のような、処理系が提供する非標準の組み込み関数を使う必要がありました。C++20 では、7 種類のビット操作が標準ライブラリ関数として提供されます。
1639+
1640+
```C++
1641+
namespace std
1642+
{
1643+
template<class T>
1644+
[[nodiscard]] constexpr T rotl(T x, int s) noexcept;
1645+
1646+
template<class T>
1647+
[[nodiscard]] constexpr T rotr(T x, int s) noexcept;
1648+
1649+
template<class T>
1650+
constexpr int countl_zero(T x) noexcept;
1651+
1652+
template<class T>
1653+
constexpr int countl_one(T x) noexcept;
1654+
1655+
template<class T>
1656+
constexpr int countr_zero(T x) noexcept;
1657+
1658+
template<class T>
1659+
constexpr int countr_one(T x) noexcept;
1660+
1661+
template<class T>
1662+
constexpr int popcount(T x) noexcept;
1663+
}
1664+
```
1665+
1666+
- 引数 `x``s` だけ左にビットローテーションさせる `std::rotl(x, s)`
1667+
- `s` が負数の場合 `std::rotr(x, -s)` と同等
1668+
- 引数 `x``s` だけ右にビットローテーションさせる `std::rotr(x, s)`
1669+
- `s` が負数の場合 `std::rotl(x, -s)` と同等
1670+
- `x` の最上位ビットから数えて 0 が連続する個数を返す `std::countl_zero(x)`
1671+
- `x` の最上位ビットから数えて 1 が連続する個数を返す `std::countl_one(x)`
1672+
- `x` の最下位ビットから数えて 0 が連続する個数を返す `std::countr_zero(x)`
1673+
- `x` の最下位ビットから数えて 1 が連続する個数を返す `std::countr_one(x)`
1674+
- `x` の 2 進表現に含まれる 1 の個数を返す `std::popcount(x)`
1675+
1676+
いずれの関数も、型 `T` が符号なし整数型 (`unsigned char`, `unsigned short`, `unsigned int`, `unsigned long`, `unsigned long long`) の場合のみオーバーロード解決に参加します。
1677+
1678+
```C++
1679+
#include <iostream>
1680+
#include <cstdint>
1681+
#include <bit>
1682+
1683+
void ShowBinary(std::uint16_t x)
1684+
{
1685+
for (size_t i = 0; i < 16; ++i)
1686+
{
1687+
std::cout << ((x >> (15 - i)) & 1);
1688+
}
1689+
std::cout << '\n';
1690+
}
1691+
1692+
int main()
1693+
{
1694+
const std::uint16_t x = 0b0001'0110'1110'1111;
1695+
1696+
ShowBinary(x);
1697+
std::cout << '\n';
1698+
1699+
for (int s = -4; s <= 4; ++s)
1700+
{
1701+
ShowBinary(std::rotl(x, s));
1702+
}
1703+
std::cout << '\n';
1704+
1705+
for (int s = -4; s <= 4; ++s)
1706+
{
1707+
ShowBinary(std::rotr(x, s));
1708+
}
1709+
std::cout << '\n';
1710+
1711+
std::cout << std::countl_zero(x) << '\n'; // 3
1712+
std::cout << std::countl_one(x) << '\n'; // 0
1713+
std::cout << std::countr_zero(x) << '\n'; // 0
1714+
std::cout << std::countr_one(x) << '\n'; // 4
1715+
}
1716+
```
1717+
```
1718+
0001011011101111
1719+
1720+
1111000101101110
1721+
1110001011011101
1722+
1100010110111011
1723+
1000101101110111
1724+
0001011011101111
1725+
0010110111011110
1726+
0101101110111100
1727+
1011011101111000
1728+
0110111011110001
1729+
1730+
0110111011110001
1731+
1011011101111000
1732+
0101101110111100
1733+
0010110111011110
1734+
0001011011101111
1735+
1000101101110111
1736+
1100010110111011
1737+
1110001011011101
1738+
1111000101101110
1739+
1740+
3
1741+
0
1742+
0
1743+
4
1744+
```
1745+

0 commit comments

Comments
 (0)