nodeluna

joined 2 years ago
1
[Hyprland] (lemmy.ml)
submitted 9 months ago* (last edited 9 months ago) by nodeluna@programming.dev to c/unixporn@lemmy.ml
 

[–] nodeluna@programming.dev 0 points 10 months ago

alright then.

I see. expected is such a great library to have regardless of the standard version. damn c++03, I'm not familiar with that standard.

I enabled support for c++11 regardless, it's kinda cool to do so. and I enabled conditional support to use nl::expected with constexpr for c++20 and higher. nl::unexpected with constexpr requires c++23 tho

[–] nodeluna@programming.dev 0 points 10 months ago (2 children)

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

[–] nodeluna@programming.dev 0 points 10 months ago* (last edited 10 months ago) (4 children)

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

[–] nodeluna@programming.dev 0 points 10 months ago

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

[–] nodeluna@programming.dev 0 points 10 months ago* (last edited 10 months 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>();

1
safe enum (programming.dev)
submitted 10 months ago* (last edited 10 months ago) by nodeluna@programming.dev to c/cpp@programming.dev
 

for anyone who doesn't know, this "-Werror=switch-enum" compiler option make the compiler throw an error if all of the enum values aren't explicitly handled in a "switch" statement


enum class colors {
        blue,
        red,
        purple,
}

void func(colors c)
{
        switch(c)
        {
                case colors::blue:
                        // do something
                        break;
                case colors::red:
                        // do something
                        break;
                default:
                        // do something
                        break;
        }
}


int main()
{
        func(colors::blue);
}

this code doesn't compile on clang and gcc with the option "-Werror=switch-enum" because the "colors::purple" isn't explicitly handled. be aware that it doesn't throw a compiler error for "if" statements if one of the values isn't handled

 

It's not fully finished yet, but it's getting there, and i didn't write documentation beyond the README.md and tests/test.cpp but I'd like some feedback on it.

features

  • It's a header only library that's currently < 3000 loc
  • no 3rd-party dependencies
  • support for being imported as a module
  • supports inserting std containers into json nodes
  • highly type safe, which is made possible by using concepts
  • easy-to-use object/array iterations
  • easy-to-use type casting from json value to native c++ types which is enabled by std::variant and concepts
  • exception-free parsing and value casting.
  • modern error handling using "expected" type
  • exception-free node.try_at("key") access
  • and more

edit:

documentation link: https://nodeluna.github.io/ljson