

alright then.
I see. expected is such a great library to have regardless of the standard version.
oh c++03, I’m not familiar with that standard.
I enabled support for c++11 regardless, it’s kinda cool to do so


alright then.
I see. expected is such a great library to have regardless of the standard version.
oh c++03, I’m not familiar with that standard.
I enabled support for c++11 regardless, it’s kinda cool to do so


ikr, constexpr is pretty cool. sure, no problem. I could make it fully compatible with c++14 without c++17 extensions if u wanna use it with c++14


because “if constexpr(…)” is a c++17 feature which i’m using it to allow usage of nl::unexpected() to return a nl::expected<nl::monostate, E> to nl::expected<T, E> in this copy constructor
template<class U>
expected(const expected<U, E>& other) : _has_value(other.has_value()) // a copy constructor
{
if (_has_value)
{
if constexpr (std::is_same<U, monostate>::value) // it checks if U == monostate
{
// makes an empty instance of "T"
}
else if constexpr (std::is_same<U, T>::value) // it checks if U == T
{
// otherwise copies "other._value" into _value
}
else
{
static_assert(
not std::is_same<U, T>::value, "no available conversion between the provided value types");
}
}
else
{
new (std::addressof(_error)) E(other.error());
}
}
template<class E>
expected<monostate, E> unexpected(const E& e) // then this can covert <monostate, E> to <T, E> fine because of this copy constructor
{
return expected<monostate, E>(e);
}
// example usage
nl::expected<int, std::string> meow = nl::unexpected("error");
but i could take a different approach and make 2 copy constructor one that explicitly takes
expected(const expected<monostate, E>& other)
and another
expected(const expected& other)
I was also using “std::is_same_v” which is a c++17 feature instead “std::is_same<>::value” but i made a commit and changed it. it now compiles with c++14 but with c++17 extensions


Here are some cool and advanced features of the ljson library, with short code snippets for each:
You can build JSON objects and arrays directly from standard containers (e.g., std::map, std::vector, std::set, etc.): C++
std::map<std::string, int> obj = {{"a", 1}, {"b", 2}};
std::vector<std::string> arr = {"x", "y", "z"};
ljson::node data;
data.insert("object", obj);
data.insert("array", arr);
ljson::node n = {
{"name", "Alice"},
{"age", 30},
{"active", true},
{"tags", ljson::node({"dev", "cat_lover"})},
{"profile", ljson::node({{"city", "Paris"}, {"zip", 75000}})}
};
// n is now a JSON object with nested objects and arrays!
if (n.at("age").is_integer())
std::cout << "Age: " << n.at("age").as_integer() << "\n";
if (n.at("tags").is_array()) {
for (auto& tag : *n.at("tags").as_array())
std::cout << tag.as_string() << " ";
}
n.at("name") = "Bob"; // changes value to "Bob"
n.at("age") = 31; // changes value to 31
n.at("active") = false; // changes value to false
n.at("tags").push_back("gamer"); // add "gamer" to tags array
auto result = ljson::parser::try_parse(R"({"x":1})");
if (result) {
std::cout << "Parsed!\n";
} else {
std::cerr << "Parse error: " << result.error().message() << "\n";
}
n.dump_to_stdout({'\t', 2}); // Pretty print using tabs, 2 per indent
n.write_to_file("output.json"); // Write to file
std::string s = n.dump_to_string(); // Get pretty JSON string
Concatenate arrays and objects in a natural way:
ljson::node a = {1, 2, 3};
ljson::node b = {4, 5};
ljson::node c = a + b; // [1,2,3,4,5]
ljson::node obj1 = {{"x", 1}};
ljson::node obj2 = {{"y", 2}};
ljson::node obj3 = obj1 + obj2; // {"x":1,"y":2}
n.insert("nothing", ljson::null);
if (n.at("nothing").is_null())
std::cout << "It's " << n.at("nothing").stringify() << "!\n"; // It's null!
ljson::node arr = { 1, 2, 3, ljson::node({"nested", "array"}), ljson::null };
ljson::node obj = { {"a", 1}, {"b", ljson::node({2, 3, 4})}, {"c", ljson::node({"d", 5})} };
You can set a node’s value using .set() or assignment:
n.at("val").set(123.45);
n.at("flag") = true;
n.at("sub").insert("newkey", "newval");
// Iterating an array
for (auto& item : *n.at("tags").as_array())
std::cout << item.as_string() << "\n";
// Iterating an object
for (auto& [key, value] : *n.as_object())
std::cout << key << ": " << value.stringify() << "\n";
Get error info if you try an invalid conversion:
auto res = n.at("name").try_as_integer();
if (!res) std::cerr << "Not an integer: " << res.error().message() << "\n";
Any supported type (string, int, bool, null, etc.) or nested containers can be used directly in construction or insertion.
n.dump_to_stdout({' ', 8}); // 8 spaces per indent
ljson::node obj = {
{"a", 1},
{"b", 2}
};
obj += ljson::object_pairs{
{"c", 3},
{"d", 4}
};
Summary: ljson offers a modern, expressive, and type-safe C++ JSON API with C++ types, safety, and STL integration.


thank you! if someone wants a more modern API that’s kinda similar to tomlplusplus and a little nicer to use with modern error handling then my library might come in handy. my API is inspired a lot by tomlplusplus . i was trying to make a build system that uses TOML as a config file and I needed a json library so i decided to make my own as a learning experience which was great.
I’m not familiar with simdjson, but i know a little about nlohmann and I think the exception free path using ljson::expected is a nicer/safer approach. also there is convenient operator overloads in my library to add objects/array together, but nlohmann also has that i think
// accessing values in ljson
ljson::node node = ljson::parser::parse(raw_json);
std::string val = node.at("key").as_string();
// accessing values in nlohmann
nlohmann::json::json json;
raw_json >> json;
std::string val = json["key"].get<std::string>();


I’m so excited for C++26
deleted by creator