4
13
nodeluna

@programming.dev

nodeluna 5 points 2 years ago

thanks! kinda, but i'm using hyprland and the foot terminal. You can control the inactive opacity on hyprland, and control foot's alpha channel, which can make it transparent

path: 0 13135321 13135493, hotness: undefined, score: 5, children: 5
nodeluna 2 points 2 years ago

very fancy and nice to use. i see

I searched for a River socket or riverctl command that would allow me to get the active workspace number, but i couldn't find a way for that currently in River. so i can't implement it for River not currently at least. unless maybe someone knows a way to get that info who could refer me to the documentation

path: 0 13135321 13135493 13144087 13153873, hotness: undefined, score: 2, children: 3
nodeluna 2 points a year ago

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

path: 0 17877809 17879151, hotness: undefined, score: 2, children: 4
nodeluna 2 points a year ago

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

path: 0 17877809 17879151 17884686 17893718, hotness: undefined, score: 2, children: 2
nodeluna 2 points a year ago

you can constrain functions with c++20 concepts to ensure the compiler is calling the correct function if you're that worried

path: 0 17828341 17828442 17841244 17841903 17844114 17844821 17876732, hotness: undefined, score: 2, children: 0
nodeluna 2 points a year ago
path: 0 18271335, hotness: undefined, score: 2, children: 0
nodeluna 2 points a year ago

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>();
path: 0 17862908 17872983, hotness: undefined, score: 2, children: 0
nodeluna 2 points a year ago

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

path: 0 17877809 17879151 17884686 17893718 17906932 17916752, hotness: undefined, score: 2, children: 0
nodeluna 2 points 2 years ago

cool! thanks for letting me know, i'll try to keep an eye on it

path: 0 13135321 13135493 13144087 13153873 13162376 13184523, hotness: undefined, score: 2, children: 1
nodeluna 1 point a year ago

** AI GENERATED SHOWCASE THAT'S REVIEWED BY ME **

Here are some cool and advanced features of the ljson library, with short code snippets for each:

  1. Seamless Construction from C++ Containers

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);
  1. Initializer-List Magic (Python/JavaScript-like Syntax)
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!
  1. Type-Safe Value Accessors and Type Queries
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() << " ";
}
  1. Type-Safe Mutation and Assignment
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
  1. Exception-Free Parsing (Error Handling Without throw)
auto result = ljson::parser::try_parse(R"({"x":1})");
if (result) {
    std::cout << "Parsed!\n";
} else {
    std::cerr << "Parse error: " << result.error().message() << "\n";
}
  1. Pretty Printing and File Output with Custom Indentation
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
  1. Operator Overloading for JSON Merge and Addition

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}
  1. Automatic Null Support
n.insert("nothing", ljson::null);
if (n.at("nothing").is_null())
    std::cout << "It's " << n.at("nothing").stringify() << "!\n"; // It's null!
  1. Direct Construction from Nested Initializer Lists
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})} };
  1. Safe and Direct Value Setting and Mutation

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");
  1. Full Traversal and Iteration Support
// 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";
  1. Type-Checked Try-Cast APIs

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";
  1. Flexible Construction from Arbitrary Types

Any supported type (string, int, bool, null, etc.) or nested containers can be used directly in construction or insertion.

  1. Custom Indentation Everywhere
n.dump_to_stdout({' ', 8}); // 8 spaces per indent
  1. Chaining Insertions and Additions
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.

path: 0 17874046, hotness: undefined, score: 1, children: 0
nodeluna 1 point a year ago

I'm so excited for C++26

path: 0 17858812, hotness: undefined, score: 1, children: 0
nodeluna 1 point a year ago

nope

path: 0 17876673, hotness: undefined, score: 1, children: 0
nodeluna 1 point a year ago

what don't u get it? why did I make this? or what is the point of this type?

if you are unfamiliar with std::expected then check out https://en.cppreference.com/...

it's basically a type that let you return either a "value" or an "error" and the caller of the function has to check which did the function return. it's a modern way of handling errors in C++ that was introduced in C++23

path: 0 17878689 17879209, hotness: undefined, score: 1, children: 0
nodeluna -2 points 7 months ago path: 0 22651296 22661249, hotness: undefined, score: -2, children: 0

thanks for using Leebra!

go to feed...