|
13 | 13 | #include <test/util/setup_common.h>
|
14 | 14 | #include <uint256.h>
|
15 | 15 | #include <util/bitdeque.h>
|
| 16 | +#include <util/byte_units.h> |
16 | 17 | #include <util/fs.h>
|
17 | 18 | #include <util/fs_helpers.h>
|
18 | 19 | #include <util/moneystr.h>
|
@@ -1877,4 +1878,100 @@ BOOST_AUTO_TEST_CASE(clearshrink_test)
|
1877 | 1878 | }
|
1878 | 1879 | }
|
1879 | 1880 |
|
| 1881 | +template <typename T> |
| 1882 | +void TestCheckedLeftShift() |
| 1883 | +{ |
| 1884 | + constexpr auto MAX{std::numeric_limits<T>::max()}; |
| 1885 | + |
| 1886 | + // Basic operations |
| 1887 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>(0, 1), 0); |
| 1888 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>(0, 127), 0); |
| 1889 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>(1, 1), 2); |
| 1890 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>(2, 2), 8); |
| 1891 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>(MAX >> 1, 1), MAX - 1); |
| 1892 | + |
| 1893 | + // Max left shift |
| 1894 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>(1, std::numeric_limits<T>::digits - 1), MAX / 2 + 1); |
| 1895 | + |
| 1896 | + // Overflow cases |
| 1897 | + BOOST_CHECK(!CheckedLeftShift<T>((MAX >> 1) + 1, 1)); |
| 1898 | + BOOST_CHECK(!CheckedLeftShift<T>(MAX, 1)); |
| 1899 | + BOOST_CHECK(!CheckedLeftShift<T>(1, std::numeric_limits<T>::digits)); |
| 1900 | + BOOST_CHECK(!CheckedLeftShift<T>(1, std::numeric_limits<T>::digits + 1)); |
| 1901 | + |
| 1902 | + if constexpr (std::is_signed_v<T>) { |
| 1903 | + constexpr auto MIN{std::numeric_limits<T>::min()}; |
| 1904 | + // Negative input |
| 1905 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>(-1, 1), -2); |
| 1906 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>((MIN >> 2), 1), MIN / 2); |
| 1907 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>((MIN >> 1) + 1, 1), MIN + 2); |
| 1908 | + BOOST_CHECK_EQUAL(CheckedLeftShift<T>(MIN >> 1, 1), MIN); |
| 1909 | + // Overflow negative |
| 1910 | + BOOST_CHECK(!CheckedLeftShift<T>((MIN >> 1) - 1, 1)); |
| 1911 | + BOOST_CHECK(!CheckedLeftShift<T>(MIN >> 1, 2)); |
| 1912 | + BOOST_CHECK(!CheckedLeftShift<T>(-1, 100)); |
| 1913 | + } |
| 1914 | +} |
| 1915 | + |
| 1916 | +template <typename T> |
| 1917 | +void TestSaturatingLeftShift() |
| 1918 | +{ |
| 1919 | + constexpr auto MAX{std::numeric_limits<T>::max()}; |
| 1920 | + |
| 1921 | + // Basic operations |
| 1922 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(0, 1), 0); |
| 1923 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(0, 127), 0); |
| 1924 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, 1), 2); |
| 1925 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(2, 2), 8); |
| 1926 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MAX >> 1, 1), MAX - 1); |
| 1927 | + |
| 1928 | + // Max left shift |
| 1929 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits - 1), MAX / 2 + 1); |
| 1930 | + |
| 1931 | + // Saturation cases |
| 1932 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MAX >> 1) + 1, 1), MAX); |
| 1933 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MAX, 1), MAX); |
| 1934 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits), MAX); |
| 1935 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(1, std::numeric_limits<T>::digits + 1), MAX); |
| 1936 | + |
| 1937 | + if constexpr (std::is_signed_v<T>) { |
| 1938 | + constexpr auto MIN{std::numeric_limits<T>::min()}; |
| 1939 | + // Negative input |
| 1940 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(-1, 1), -2); |
| 1941 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 2), 1), MIN / 2); |
| 1942 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 1) + 1, 1), MIN + 2); |
| 1943 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MIN >> 1, 1), MIN); |
| 1944 | + // Saturation negative |
| 1945 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>((MIN >> 1) - 1, 1), MIN); |
| 1946 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(MIN >> 1, 2), MIN); |
| 1947 | + BOOST_CHECK_EQUAL(SaturatingLeftShift<T>(-1, 100), MIN); |
| 1948 | + } |
| 1949 | +} |
| 1950 | + |
| 1951 | +BOOST_AUTO_TEST_CASE(checked_left_shift_test) |
| 1952 | +{ |
| 1953 | + TestCheckedLeftShift<uint8_t>(); |
| 1954 | + TestCheckedLeftShift<int8_t>(); |
| 1955 | + TestCheckedLeftShift<size_t>(); |
| 1956 | + TestCheckedLeftShift<uint64_t>(); |
| 1957 | + TestCheckedLeftShift<int64_t>(); |
| 1958 | +} |
| 1959 | + |
| 1960 | +BOOST_AUTO_TEST_CASE(saturating_left_shift_test) |
| 1961 | +{ |
| 1962 | + TestSaturatingLeftShift<uint8_t>(); |
| 1963 | + TestSaturatingLeftShift<int8_t>(); |
| 1964 | + TestSaturatingLeftShift<size_t>(); |
| 1965 | + TestSaturatingLeftShift<uint64_t>(); |
| 1966 | + TestSaturatingLeftShift<int64_t>(); |
| 1967 | +} |
| 1968 | + |
| 1969 | +BOOST_AUTO_TEST_CASE(mib_string_literal_test) |
| 1970 | +{ |
| 1971 | + BOOST_CHECK_EQUAL(0_MiB, 0); |
| 1972 | + BOOST_CHECK_EQUAL(1_MiB, 1024 * 1024); |
| 1973 | + const auto max_mib{std::numeric_limits<size_t>::max() >> 20}; |
| 1974 | + BOOST_CHECK_EXCEPTION(operator""_MiB(static_cast<unsigned long long>(max_mib) + 1), std::overflow_error, HasReason("MiB value too large for size_t byte conversion")); |
| 1975 | +} |
| 1976 | + |
1880 | 1977 | BOOST_AUTO_TEST_SUITE_END()
|
0 commit comments