arximboldi / immer

Postmodern immutable and persistent data structures for C++ — value semantics at scale
https://sinusoid.es/immer
Boost Software License 1.0
2.5k stars 183 forks source link

Add maps with keys extracted from the value #198

Closed arximboldi closed 2 years ago

arximboldi commented 2 years ago

Solves the issue of:

struct something {
  id_t id;
   ...
};

using something_map = immer::map<id_t, something>;
deadb0d4 commented 2 years ago

@arximboldi Hey! Could you please provide more examples or a rough API for the requested map class?

arximboldi commented 2 years ago

With this new type one could do something like:

struct something {
  std::string id;
   ...
};

auto x = immer::object_map<something>{}
   .insert(something{"foo", ...})
   .insert(something{"bar", ...}));

static_assert(std::is_same_v<decltype(x)::key_type, std::string>);
assert(x.find("foo") != nullptr);
assert(x.at("foo") == something{"foo", ...});
assert(x.count("foo") == 1);

We could say that by default it access the id or key attribute, but an arbitrary key projection could be used by using customization points:

struct something {
  int name;
  ...
};

struct something_key {
   int operator()(const something_key& x) { return x.name; }
};

using something_map = immer::object_map<something, something_key>{};

Not sure if object_map is the best name for this construction. Happy to hear other ideas!

deadb0d4 commented 2 years ago

Cool, let me try it. It indeed seems like a good first issue here :)

arximboldi commented 2 years ago

Nice! Thank you!

deadb0d4 commented 2 years ago

I wonder if I can use this...

arximboldi commented 2 years ago

Yes, the idea is to provide a new type with an interface very similar to immer::map, and also based on detail::champ as implementation. You can achieve the right interface by customizing project_value and the other callbacks that are used with champ. It should be not too difficult if you are already familiar with templates and the Immer interface.

arximboldi commented 2 years ago

Done in #210 with some tweaks in #214. Thank you so much! @deadb0d4

arximboldi commented 2 years ago

Btw @deadb0d4, are you on Twitter? I'm gonna make an announcement about the new type, and I would be very happy to credit you with a direct mention!

deadb0d4 commented 2 years ago

@arximboldi Thank you very much for your help. It's been a pleasure working on this. No, I am not :) Feel free to just mention the issue or/and my nickname on GitHub :D