1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <future>
#include <glaze/glaze.hpp>
#include <iostream>
#include <thread>
#include <vector>
// must be outside test(), compilation fails on gcc 13 otherwise
struct Value
{
// use a short name to reduce the number of characters written
float v;
};
void test()
{
using UT = std::uint32_t;
static_assert(sizeof(float) == sizeof(UT));
auto test_one_value = [](const UT loopvar, auto& outbuf) {
Value s;
std::memcpy(&s.v, &loopvar, sizeof(float));
if (!std::isfinite(s.v)) {
return;
}
outbuf.clear();
const auto writeec = glz::write_json(s, outbuf);
if (writeec) [[unlikely]] {
std::cerr << "failed writing " << s.v << " to json\n";
std::abort();
}
auto restored = glz::read_json<Value>(outbuf);
if (!restored) [[unlikely]] {
std::cerr << "failed parsing " << outbuf << '\n';
std::abort();
}
if (const auto r = restored.value().v; r != s.v) [[unlikely]] {
std::cerr << "failed roundtrip, got " << r << " instead of " << s.v << //
" (diff is " << r - s.v << ") when parsing " << outbuf << '\n';
std::abort();
}
};
auto test_all_in_range = [&](const UT start, const UT stop) {
std::string outbuf;
for (UT i = start; i < stop; ++i) {
test_one_value(i, outbuf);
}
};
const auto nthreads = std::thread::hardware_concurrency();
const UT step = (std::numeric_limits<UT>::max)() / nthreads;
std::vector<std::thread> threads;
threads.reserve(nthreads);
for (size_t threadi = 0; threadi < nthreads; ++threadi) {
const UT start = threadi * step;
const UT stop = (threadi == nthreads - 1) ? (std::numeric_limits<UT>::max)() : start + step;
// std::cout << "thread i=" << threadi << " goes from " << start << " to " << stop << '\n';
threads.emplace_back(test_all_in_range, start, stop);
}
// test the last value here.
{
std::string buf;
test_one_value((std::numeric_limits<UT>::max)(), buf);
}
std::cout << "started testing in " << nthreads << " threads." << std::endl;
for (auto& t : threads) {
t.join();
}
std::cout << "tested " << (std::numeric_limits<UT>::max)() << " values of float" << std::endl;
}
int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { test(); }
|