Skip to content

KWSys: use allocator_traits::rebind_alloc for C++20 (hashtable.hxx)#6513

Closed
gdevenyi wants to merge 1 commit into
InsightSoftwareConsortium:release-4.14from
gdevenyi:fix-kwsys-rebind-cxx20
Closed

KWSys: use allocator_traits::rebind_alloc for C++20 (hashtable.hxx)#6513
gdevenyi wants to merge 1 commit into
InsightSoftwareConsortium:release-4.14from
gdevenyi:fix-kwsys-rebind-cxx20

Conversation

@gdevenyi

Copy link
Copy Markdown
Contributor

Problem

std::allocator::rebind was deprecated in C++17 and removed in C++20. On newer toolchains (e.g. GCC 14/15 shipping in Fedora 44) libstdc++ no longer provides std::allocator<T>::rebind, so the vendored KWSys hashtable.hxx template fails to compile:

error: no type named 'other' in 'std::allocator<...>::rebind<...>'

This breaks any consumer that pulls in itksys/hash_map.hxx / hash_set.hxx when built in C++20 mode.

Fix

Replace the three typename _Alloc::template rebind<X>::other typedefs in Modules/ThirdParty/KWSys/src/KWSys/hashtable.hxx.in with the standard C++11 replacement:

typename std::allocator_traits<_Alloc>::template rebind_alloc<X>

std::allocator_traits has been the portable way to rebind since C++11 and works across C++11 → C++20. <memory> is already included by this header, so no new include is needed. No behavior change on older standards.

Only hashtable.hxx.in uses rebind; hash_map.hxx.in / hash_set.hxx.in are unaffected.

Notes

  • This file is vendored from upstream KWSys (Kitware/KWSys); the same fix likely belongs there too, but this targets release-4.14 directly since that branch is pinned by downstream consumers (e.g. minc-toolkit-v2) and currently fails on Fedora 44.
  • Not yet verified by a full local Fedora 44 build; this is the canonical, mechanical C++20 migration of the construct.

🤖 Generated with Claude Code

std::allocator::rebind was deprecated in C++17 and removed in C++20, so
libstdc++ in newer toolchains (e.g. GCC 14/15 on Fedora 44) no longer
provides _Alloc::rebind, breaking the hash_map/hash_set hashtable
template:

  error: no type named 'other' in 'std::allocator<...>::rebind<...>'

Replace the three `typename _Alloc::template rebind<X>::other` typedefs
with the C++11 `std::allocator_traits<_Alloc>::template rebind_alloc<X>`,
which is the standard replacement and works on all supported standards.
<memory> is already included.
@github-actions github-actions Bot added the area:ThirdParty Issues affecting the ThirdParty module label Jun 25, 2026
@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a C++20 compilation failure in the vendored KWSys hashtable.hxx.in by replacing the deprecated (C++17) and removed (C++20) typename _Alloc::template rebind<X>::other pattern with the portable std::allocator_traits<_Alloc>::template rebind_alloc<X> form introduced in C++11.

  • All three rebind sites in hashtable.hxx.in are updated; <memory> is already included so no new dependency is needed.
  • hash_map.hxx.in and hash_set.hxx.in are unaffected by this change as they do not use rebind directly.

Confidence Score: 5/5

Safe to merge — the change is a mechanical, standard-compliant substitution with no behavioral difference on any supported allocator.

All three rebind usages are updated, <memory> is already included providing std::allocator_traits, and rebind_alloc is defined to consult _Alloc::rebind<X>::other first (when present) so custom allocators remain unaffected. No logic, data layout, or ABI change is introduced.

No files require special attention. The single changed template file is a clean, complete fix.

Important Files Changed

Filename Overview
Modules/ThirdParty/KWSys/src/KWSys/hashtable.hxx.in Replaces all three _Alloc::rebind<X>::other typedefs with the C++11-standard std::allocator_traits<_Alloc>::rebind_alloc<X>; fix is complete and correct — no remaining old-style rebind usages, <memory> already included.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["_Alloc (template param)"] --> B{"Standard used"}
    B -->|"C++11 - C++17 (old code)"| C["_Alloc::rebind<X>::other\n(deprecated C++17, removed C++20)"]
    B -->|"C++11 - C++20 (new code)"| D["std::allocator_traits<_Alloc>::rebind_alloc<X>\n(portable since C++11)"]
    D --> E["allocator_type = rebind_alloc<_Val>"]
    D --> F["_M_node_allocator_type = rebind_alloc<_Node>"]
    D --> G["_M_node_ptr_allocator_type = rebind_alloc<_Node*>"]
    C -->|"GCC 14+ / C++20 mode"| H["Compile error: no type named 'other'"]
    D -->|"All compilers / C++11-C++20"| I["Compiles successfully"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["_Alloc (template param)"] --> B{"Standard used"}
    B -->|"C++11 - C++17 (old code)"| C["_Alloc::rebind<X>::other\n(deprecated C++17, removed C++20)"]
    B -->|"C++11 - C++20 (new code)"| D["std::allocator_traits<_Alloc>::rebind_alloc<X>\n(portable since C++11)"]
    D --> E["allocator_type = rebind_alloc<_Val>"]
    D --> F["_M_node_allocator_type = rebind_alloc<_Node>"]
    D --> G["_M_node_ptr_allocator_type = rebind_alloc<_Node*>"]
    C -->|"GCC 14+ / C++20 mode"| H["Compile error: no type named 'other'"]
    D -->|"All compilers / C++11-C++20"| I["Compiles successfully"]
Loading

Reviews (2): Last reviewed commit: "KWSys: use allocator_traits::rebind_allo..." | Re-trigger Greptile

@dzenanz dzenanz requested a review from bradking June 25, 2026 14:29
@dzenanz

dzenanz commented Jun 25, 2026

Copy link
Copy Markdown
Member

Has something similar already been applied upstream? Should we update KWSys in 4.14 branch, instead of patching it like this?

@gdevenyi

Copy link
Copy Markdown
Contributor Author

Has something similar already been applied upstream? Should we update KWSys in 4.14 branch, instead of patching it like this?

I'm happy to do that instead, I'm not sure how to make it happen

@blowekamp

Copy link
Copy Markdown
Member

Has something similar already been applied upstream? Should we update KWSys in 4.14 branch, instead of patching it like this?

I'm happy to do that instead, I'm not sure how to make it happen

You could try using the skill: https://github.com/InsightSoftwareConsortium/ITK/tree/main/.github/skills/update-third-party

@gdevenyi gdevenyi marked this pull request as draft June 25, 2026 14:53
@gdevenyi

Copy link
Copy Markdown
Contributor Author

Has something similar already been applied upstream? Should we update KWSys in 4.14 branch, instead of patching it like this?

I'm happy to do that instead, I'm not sure how to make it happen

You could try using the skill: main/.github/skills/update-third-party

Thanks I'll take a look

@gdevenyi

Copy link
Copy Markdown
Contributor Author

Verified locally: the failure reproduces on GCC 15 / libstdc++ in C++20 mode (CachyOS), not only Fedora 44 — itksys/hashtable.hxx:252/256/258: error: no class template named 'rebind' in 'class std::allocator<char>' when a downstream target (here ITK's KWSys consumed by Convert3D) instantiates the hashtable. After applying this allocator_traits<_Alloc>::rebind_alloc change to the generated header, the compile passes. So this is a general C++20 toolchain issue, not distro-specific.

@gdevenyi

Copy link
Copy Markdown
Contributor Author

Closing pending #6515

@gdevenyi gdevenyi closed this Jun 25, 2026
@gdevenyi gdevenyi reopened this Jun 25, 2026
@gdevenyi

Copy link
Copy Markdown
Contributor Author

#6515 isn't a simple solution sadly.

@gdevenyi gdevenyi marked this pull request as ready for review June 25, 2026 15:57

@dzenanz dzenanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good on a glance.

@blowekamp

Copy link
Copy Markdown
Member

O, I missed this was targeting ITK 4.14!

@gdevenyi

Copy link
Copy Markdown
Contributor Author

O, I missed this was targeting ITK 4.14!

Yup. I have zombie projects I'm performing necromancy on to keep going.

@hjmjohnson

Copy link
Copy Markdown
Member

Thanks for keeping these old branches alive, @gdevenyi — the necromancy is appreciated.

I'm fine with the change in principle: std::allocator_traits<_Alloc>::rebind_alloc<X> is the standard-blessed replacement and is backward compatible across C++11 → C++20, so nothing built with a C++11/14/17 toolchain regresses. The one caveat worth naming is that std::allocator_traits is itself a C++11 construct — it doesn't exist in C++03 — so strictly speaking this trades the old C++03-compatible rebind<>::other for something that assumes C++11. Almost certainly academic (nobody is building release-4.14 with a pre-C++11 compiler today), but it matters given the 4.x line nominally kept a C++03 baseline.

Which is my larger question: rather than retrofitting C++03-era KWSys for C++20, why not build 4.14 with a C++ standard appropriate to its era? A downstream pinning release-4.14 (minc-toolkit-v2, Convert3D, …) can just pin -DCMAKE_CXX_STANDARD=14 (or gnu++14), which sidesteps this and the rest of the C++17/20 removals you'll otherwise keep hitting one at a time in vendored third-party code. That feels more sustainable than patching each construct as a new toolchain removes it.

If the goal really is "compile clean in C++20 mode," then I agree with @dzenanz that refreshing KWSys from upstream (#6515) is the right long-term fix rather than a local patch — though I see that turned out to be non-trivial.

@gdevenyi

Copy link
Copy Markdown
Contributor Author

A downstream pinning release-4.14 (minc-toolkit-v2, Convert3D, …) can just pin -DCMAKE_CXX_STANDARD=14 (or gnu++14),

Thanks @hjmjohnson I was able to implement this and get things working that way.

@gdevenyi gdevenyi closed this Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:ThirdParty Issues affecting the ThirdParty module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants