File: json_exhaustive_roundtrip_int.cpp

package info (click to toggle)
glaze 6.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 7,312 kB
  • sloc: cpp: 109,539; sh: 99; ansic: 26; makefile: 13
file content (99 lines) | stat: -rw-r--r-- 2,707 bytes parent folder | download | duplicates (2)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <glaze/glaze.hpp>
#include <iostream>
#include <thread>
#include <vector>

// must be outside test(), compilation fails on gcc 13 otherwise
template <typename T>
struct Value
{
   T value{};
};

template <typename T>
void test()
{
   using S = Value<T>;
   using UT = std::make_unsigned_t<T>;

   auto testone = [](const UT loopvar, auto& outbuf) {
      S s;
      std::memcpy(&s.value, &loopvar, sizeof(T));

      outbuf.clear();
      const auto writeec = glz::write_json(s, outbuf);

      if (writeec) [[unlikely]] {
         std::cerr << "failed writing " << s.value << " to json\n";
         std::abort();
      }

      auto restored = glz::read_json<S>(outbuf);
      if (!restored) [[unlikely]] {
         std::cerr << "failed parsing " << outbuf << '\n';
         std::abort();
      }

      if (const auto r = restored.value().value; r != s.value) [[unlikely]] {
         std::cerr << "failed roundtrip, got " << r << " instead of " << s.value << //
            " (diff is " << r - s.value << ") when parsing " << outbuf << '\n';
         std::abort();
      }
   };

   auto testrange = [&](const UT start, const UT stop) {
      std::string outbuf;
      for (UT i = start; i < stop; ++i) {
         testone(i, outbuf);
      }
   };

   const auto nthreads = std::thread::hardware_concurrency();
   const UT step = (std::numeric_limits<UT>::max)() / nthreads;

   // can't use jthread, does not exist in all stdlibs.
   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(testrange, start, stop);
   }
   // test the last value here.
   {
      std::string buf;
      testone((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 " << (std::is_unsigned_v<T> ? "un" : "")
             << "signed type of size " << sizeof(T) << std::endl;
}

void testonetype(int bits)
{
   switch (bits) {
   case 16:
      test<std::int16_t>();
      test<std::uint16_t>();
      break;
   case 32:
      test<std::int32_t>();
      test<std::uint32_t>();
      break;
   }
}

int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
{
   testonetype(16);
   testonetype(32);
}