Skip to content

Commit d36d4a5

Browse files
Add support for std::hash in wrap-hash directive
This commit adds support for using C++ std::hash<T> specializations directly in Python bindings via the wrap-hash directive. Changes: - Add `cpp_hash` declaration (aliased from std::hash) in generated code - Support `# wrap-hash:\n# std` syntax to automatically use std::hash<T> - Maintain backward compatibility with existing expression-based wrap-hash Usage in .pxd files: ``` cdef cppclass MyClass: # wrap-hash: # std ``` This generates: ```python def __hash__(self): cdef cpp_hash[MyClass] hasher return hasher(deref(self.inst.get())) ``` The `cpp_hash` name is used instead of `hash` to avoid conflicts with Python's built-in hash() function. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7b125a1 commit d36d4a5

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

autowrap/CodeGenerator.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -671,18 +671,33 @@ def create_wrapper_for_class(self, r_class: ResolvedClass, out_codes: CodeDict)
671671
)
672672

673673
if len(r_class.wrap_hash) != 0:
674-
class_code.add(
675-
"""
674+
hash_expr = r_class.wrap_hash[0].strip()
675+
# If hash expression is "std" or empty, use std::hash<T>
676+
if hash_expr.lower() == "std" or not hash_expr:
677+
class_code.add(
678+
"""
679+
|
680+
| def __hash__(self):
681+
| # Uses C++ std::hash<$cpp_name> specialization
682+
| cdef cpp_hash[$cy_type] hasher
683+
| return hasher(deref(self.inst.get()))
684+
|
685+
""",
686+
locals(),
687+
)
688+
else:
689+
class_code.add(
690+
"""
676691
|
677692
| def __hash__(self):
678693
| # The only required property is that objects which compare equal have
679694
| # the same hash value:
680695
| return hash(deref(self.inst.get()).%s )
681696
|
682697
"""
683-
% r_class.wrap_hash[0],
684-
locals(),
685-
)
698+
% hash_expr,
699+
locals(),
700+
)
686701

687702
if len(r_class.wrap_len) != 0:
688703
class_code.add(
@@ -2088,6 +2103,15 @@ def create_default_cimports(self):
20882103
|from libcpp.memory cimport shared_ptr
20892104
"""
20902105
)
2106+
# Add std::hash declaration for wrap-hash support (named cpp_hash to avoid conflict with Python hash)
2107+
code.add(
2108+
"""
2109+
|cdef extern from "<functional>" namespace "std" nogil:
2110+
| cdef cppclass cpp_hash "std::hash" [T]:
2111+
| cpp_hash() except +
2112+
| size_t operator()(const T&) except +
2113+
"""
2114+
)
20912115
if self.include_numpy:
20922116
code.add(
20932117
"""

0 commit comments

Comments
 (0)