@@ -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