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

[FR] Unified hash and equality predicate (stateful) objects #232

Open
psiha opened this issue Feb 15, 2024 · 3 comments
Open

[FR] Unified hash and equality predicate (stateful) objects #232

psiha opened this issue Feb 15, 2024 · 3 comments

Comments

@psiha
Copy link

psiha commented Feb 15, 2024

Consider a usecase with stateful comparators and hashers where they both share the same state (IOW they are the same object providing two functions - one for hashing and one for comparison) - would you consider adding this possibility?
For example by adding an empty 'flag' comparator type SameAsHasher (or something to that effect)?

(to avoid the duplication or 'smaller' duplication where the hasher and comparator store a reference to an external object as well as the associated more complex codegen)

@cmazakas
Copy link
Member

Hmm, I think if I understand correctly, you just want something like this:

#include <boost/unordered/unordered_flat_map.hpp>
#include <memory>

template<class T>
struct unified {
    struct state;
    std::shared_ptr<state> p_;

    bool operator()(T const& lhs, T const& rhs) const {
        return lhs == rhs;
    }

    std::size_t operator()(T const&) const noexcept {
        return 0;
    }
};

int main() {
    using map_type =
        boost::unordered_flat_map<int, int, unified<int>, unified<int>>;

    map_type map;
    map.emplace(1,2);
    return map.empty() ? 255 : 0;
}

This should already be supported the library. Otherwise, I might need some pseudocode to fully understand the request.

@pdimov
Copy link
Member

pdimov commented Feb 15, 2024

Presumably the idea is to avoid the dynamic allocation of state, although since the map already allocates, it's not clear how much this would save in practice.

@psiha
Copy link
Author

psiha commented Feb 27, 2024

It isn't about avoiding allocation or shared_ptr bloat as it isn't necessary. As mentioned above it is about avoiding the:

  • boilerplate complexity ("duplication where the hasher and comparator store a reference to an external object") as is evident from cmazakas' code
  • codegen complexity (overhead/inefficiency) - an extra layer of pointer indirection (with possible locality of reference issues) and that through two pointers (to the same thing - more pressure on the compiler for alias analysis, register allocation...)

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

No branches or pull requests

3 participants