#include #include #include #include #include #include using json = nlohmann::json; json parse_strict(const std::string& input) { // one key set per nesting depth, reused across sibling objects std::vector> keys; auto reject_duplicate_keys = [&](int depth, json::parse_event_t event, json & parsed) { if (event == json::parse_event_t::object_start) { // keys of this object are reported at depth+1 (see the event table above) const auto child_depth = static_cast(depth) + 1; if (keys.size() <= child_depth) { keys.resize(child_depth + 1); } keys[child_depth].clear(); return true; } if (event == json::parse_event_t::key) { auto& seen = keys[static_cast(depth)]; const auto& key = parsed.get_ref(); if (!seen.insert(key).second) { throw std::runtime_error("duplicate JSON object key: " + key); } return true; } return true; }; return json::parse(input, reject_duplicate_keys); } int main() { // parsing succeeds when all keys are unique json j = parse_strict(R"({"one": 1, "two": 2})"); std::cout << j << '\n'; // parsing throws when a key is repeated try { parse_strict(R"({"one": 1, "one": 2})"); } catch (const std::exception& e) { std::cout << e.what() << '\n'; } }