Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding an example that uses extract #44

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

lemire
Copy link
Member

@lemire lemire commented Sep 26, 2024

Suppose that you want to do something of the sort...

You have a function (@the-moisrex) that can be called like so...

extract(to("key1", t.key1), to("key2", t.key2));

given...

struct my_struct {
int key1;
double key2;
}

See simdjson/simdjson#2247

Right?

Now can I do it by reflection?

That is. I have my_struct x and I want to automatically, at compile time, call...

extract(to("key1", t.key1), to("key2", t.key2));

... without having to write "key1" and so forth.

See #29

The answer is positive.

All I need is a helper function which (by reflection) turns any struct into a tuple (struct_to_tuple)... that is, something that is effectively capable of the following...

std::tuple<to<int>,to<double>> struct_to_tuple(my_struct s);

... and then I can call std::apply...

my_struct x;
std::apply([](auto&&... xs){ extract(xs...);}, struct_to_tuple(x));

@the-moisrex
Copy link

the-moisrex commented Sep 26, 2024

Yes this is a good idea, and we could add a .extract that accepts tuple (we already are converting it to tuple in the implementation for MSVC) and make it official, or

... or, we could directly call .extract without constructing a tuple:

namespace simdjson {

// ...

template <typename T>
consteval auto is_convertible_type() {
  for (std::meta::info field : nonstatic_data_members_of(^T)) {
    if (deserializable(type_of(field))) return false;
  }
  return true;
}

template <typename T>
  requires (is_convertible_type<T>()) // all of its fields MUST be deserializable as well
constexpr error_code tag_invoke(deserialize_tag, auto& value, T& out) {
  return [: expand_all(nonstatic_data_members_of(^T)) :] >> [&]<auto... members>{
    simdjson::ondemand::object obj;
    if (auto error = value.get_object().get(obj); error) {
      return error;
    }
    return obj.extract(to(std::meta::identifier_of(members), out.[:members:])...);
  };
}

}

@lemire
Copy link
Member Author

lemire commented Oct 10, 2024

I have some concerns regarding the performance of extract, see simdjson/simdjson#2274

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants