// __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ (supporting code) // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013-2026 Niels Lohmann // SPDX-License-Identifier: MIT #pragma once #include // max #include // size_t #include // uint8_t #include // allocator #include // vector #include namespace utils { /// the allocations of the values of a JSON type that uses counting_allocator struct allocation_counts { /// bytes allocated and not yet deallocated std::size_t current = 0; /// the largest value current had std::size_t peak = 0; /// number of allocations std::size_t allocations = 0; }; /// the counts of all counting_allocators; the tests are single-threaded inline allocation_counts& counts() { static allocation_counts c; // NOLINT(misc-const-correctness) return c; } /// an allocator that counts the bytes and the number of allocations of a /// JSON type, so that a test can check how much memory a parse holds at any /// time without measuring the memory of the process template struct counting_allocator : std::allocator { using std::allocator::allocator; counting_allocator() = default; template counting_allocator(const counting_allocator& /*unused*/) noexcept {} // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) template struct rebind { using other = counting_allocator; }; T* allocate(const std::size_t n) { T* const result = std::allocator::allocate(n); allocation_counts& c = counts(); c.current += n * sizeof(T); c.peak = (std::max)(c.peak, c.current); ++c.allocations; return result; } void deallocate(T* p, const std::size_t n) { counts().current -= n * sizeof(T); std::allocator::deallocate(p, n); } }; using counted_json = nlohmann::json::with_allocator_t; /// @a count times the bytes of @a unit inline std::vector repeated(const std::vector& unit, const std::size_t count) { std::vector result; result.reserve(unit.size() * count); for (std::size_t i = 0; i < count; ++i) { result.insert(result.end(), unit.begin(), unit.end()); } return result; } } // namespace utils