Skip to content

utils: +refactor No std::hash override for std::{set,vector} - #705

Merged
Adda0 merged 3 commits into
develfrom
mata-hash
Aug 20, 2026
Merged

utils: +refactor No std::hash override for std::{set,vector}#705
Adda0 merged 3 commits into
develfrom
mata-hash

Conversation

@Adda0

@Adda0 Adda0 commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Specializing std::hash for std::set<A>/std::vector<A> with an arbitrary (possibly built-in) A is undefined behavior: the standard only allows program-defined specializations of standard templates when at least one template argument is program-defined. It also means users can transparently observe mata's hasher through e.g. std::hash<std::set<unsigned>>, even without touching mata types.

Replaces the std::set/std::vector specializations with mata::utils::SetHash and mata::utils::VectorHash, usable as the explicit Hash template argument of unordered containers, and updates the two internal call sites (OrdVector's own std::hash specialization, and a local unordered_map in Nft::lookahead) accordingly.

std::hash<std::pair<A, B>> is left as-is for now: it backs the Hash argument of several public API std::unordered_map<std::pair<State, State>, State> parameters (product maps), so removing it would require changing those public signatures.

Refs #628.

@Adda0
Adda0 marked this pull request as ready for review August 20, 2026 11:29
Adda0 added 3 commits August 20, 2026 13:29
Specializing std::hash for std::set<A>/std::vector<A> with an arbitrary
(possibly built-in) A is undefined behavior: the standard only allows
program-defined specializations of standard templates when at least one
template argument is program-defined. It also means users can
transparently observe mata's hasher through e.g.
std::hash<std::set<unsigned>>, even without touching mata types.

Replace the std::set/std::vector specializations with mata::utils::SetHash
and mata::utils::VectorHash, usable as the explicit Hash template argument
of unordered containers, and update the two internal call sites
(OrdVector's own std::hash specialization, and a local unordered_map in
Nft::lookahead) accordingly.

std::hash<std::pair<A, B>> is left as-is for now: it backs the Hash
argument of several public API std::unordered_map<std::pair<State, State>,
State> parameters (product maps), so removing it would require changing
those public signatures.

Refs #628.
Specializing std::hash for std::pair<A, B> with arbitrary (possibly
built-in) A/B is undefined behavior for the same reason as std::set/
std::vector: the standard only allows program-defined specializations
of standard templates when at least one template argument is
program-defined.

Replace the std::pair specialization with mata::utils::PairHash,
usable as the explicit Hash template argument of unordered containers,
and update the public API std::unordered_map<std::pair<State, State>,
State> parameters (product maps) and their internal call sites
accordingly.

Refs #628.
…ed product maps

The Cython .pxd/.pyx declarations for intersection()/plumbing::intersection()
still declared product-map parameters as umap[pair[State, State], State],
which no longer matches the C++ signatures after
mata::utils::PairHash<State, State> became an explicit template argument.
This made the generated C++ fail to compile (mismatched pointer types, and
the pair key falling back to the now-removed std::hash<std::pair<A, B>>
specialization).

Expose mata::utils::PairHash as CPairHash in utils.pxd and pass it as the
explicit Hash argument everywhere a product map crosses the Cython/C++
boundary.
@Adda0 Adda0 linked an issue Aug 20, 2026 that may be closed by this pull request
@Adda0
Adda0 merged commit a64d576 into devel Aug 20, 2026
17 checks passed
@Adda0
Adda0 deleted the mata-hash branch August 20, 2026 11:39
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.

mata exposes std::hash functions

1 participant