#include "prx/libc/include/Api.hpp" #include #include #include #include #include static void Require(bool condition) { if (condition) return; std::fprintf(stderr, "count zeros mismatch\n"); std::abort(); } template static std::uint32_t Reference(TValue value) { std::uint32_t result = 0; for (unsigned bit = 0; bit < std::numeric_limits::digits; ++bit) { result += (value & 1) == 0; value = static_cast(value >> 1); } return result; } template static void Check(TCounter count) { constexpr unsigned width = std::numeric_limits::digits; const auto maximum = std::numeric_limits::max(); Require(count(0) == width); Require(count(maximum) == 0); if constexpr (width <= 16) { for (std::uint32_t value = 0; value <= maximum; ++value) { Require(count(static_cast(value)) == Reference(static_cast(value))); } } for (unsigned bit = 0; bit < width; ++bit) { const auto value = static_cast(TValue{1} << bit); Require(count(value) == width - 1); Require(count(static_cast(~value)) == 1); for (unsigned other = 0; other < width; ++other) { const auto pair = static_cast(value | (TValue{1} << other)); Require(count(pair) == width - (bit == other ? 1u : 2u)); } } if constexpr (width > 16) { std::uint64_t state = 0x6b82439d015af7ceULL; for (unsigned index = 0; index < 100000; ++index) { state ^= state << 13; state ^= state >> 7; state ^= state << 17; const auto value = static_cast(state); Require(count(value) == Reference(value)); const auto complement = static_cast(~value); Require(count(complement) == Reference(complement)); } } } int main(int argc, char** argv) { Require(argc == 2); const int saved = *__error_nid_postfix(); *__error_nid_postfix() = 87; if (std::strcmp(argv[1], "uc") == 0) Check(stdc_count_zeros_uc_nid_postfix); else if (std::strcmp(argv[1], "us") == 0) Check(stdc_count_zeros_us_nid_postfix); else if (std::strcmp(argv[1], "ui") == 0) Check(stdc_count_zeros_ui_nid_postfix); else if (std::strcmp(argv[1], "ul") == 0) Check(stdc_count_zeros_ul_nid_postfix); else if (std::strcmp(argv[1], "ull") == 0) Check(stdc_count_zeros_ull_nid_postfix); else Require(false); Require(*__error_nid_postfix() == 87); *__error_nid_postfix() = saved; }