Skip to content

[Serialization] [Feature] Add experimental C++26 reflection support#6859

Merged
hkaiser merged 48 commits intoTheHPXProject:masterfrom
ujjwal-shekhar:reflect-serialize
Mar 13, 2026
Merged

[Serialization] [Feature] Add experimental C++26 reflection support#6859
hkaiser merged 48 commits intoTheHPXProject:masterfrom
ujjwal-shekhar:reflect-serialize

Conversation

@ujjwal-shekhar
Copy link
Copy Markdown
Contributor

@ujjwal-shekhar ujjwal-shekhar commented Jan 24, 2026

This PR introduces support for C++26 reflection-based serialization (based on the P2996 proposal). It adds a new reflection-based dispatch mechanism in access.hpp that allows for the automatic serialization of user-defined structs without requiring manual serialize functions. The code generation pertaining to (semi-)automatic polymorphic type registration, serialization lambdas (with and without captures) and compile-time compression of qualified_name_of will be done in the next PR(s).

Proposed Changes

  • Added HPX_SERIALIZATION_WITH_ALLOW_AUTO_GENERATE to allow users to toggle reflection codegen.
  • Automatically iterates over bases and data members in refl_serialize_impl.hpp using std::meta.
  • Utilizes std::meta::access_context::unchecked() and compile-time pointer arithmetic (offset_of) to serialize private members without requiring friend declarations.
  • Added a qualified_name_of utility to generate compiler-agnostic type identifiers by walking the scope tree. This generates portable and unique names for each type*
  • Integrated the reflection path into the main serialize dispatch. Manual serialize members and ADL handlers still take precedence, ensuring full backward compatibility.
  • When reflection-based serialization is enabled, struct_serialization is superseded, as the reflection branch natively handles brace-initializable structs.
  • Added HPX_POLYMORPHIC_AUTO_REGISTER macro to enable polymorphic type registration.

Any background context you want to provide?

Current HPX serialization requires users to manually list every member in a serialize function, leading to high maintenance overhead and error-prone edits. Encapsulation is also a hurdle, as non-intrusive methods cannot access private data easily.

Goals:

  • Adding/removing members of a class requires zero changes to serialization code.
  • Generally, eliminate the need for classes to be "aware" of their serialization logic.
  • Build on existing HPX/Boost infrastructure without replacing it.

Checklist

Not all points below apply to all pull requests.

  • I have added a new feature and have added tests to go along with it.
  • I have fixed a bug and have added a regression test.
  • I have added a test using random numbers; I have made sure it uses a seed, and that random numbers generated are valid inputs for the tests.

@StellarBot
Copy link
Copy Markdown
Collaborator

Can one of the admins verify this patch?

@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented Jan 24, 2026

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
Report missing for cc3770e1 0.00%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (cc3770e) Report Missing Report Missing Report Missing
Head commit (a62e2f1) 131434 51 0.04%

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#6859) 132 0 0.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Footnotes

  1. Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

Copy link
Copy Markdown
Contributor

@hkaiser hkaiser left a comment

Choose a reason for hiding this comment

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

@ujjwal-shekhar Sorry for spamming with a long list of comments, I went over the PR from a formal standpoint for now. I have not done a deep review of the implementation yet.

Generally, thank you so much for working on this! This is marvelous.

Comment thread libs/core/config/include/hpx/config/reflection.hpp Outdated
Comment thread libs/core/config/include/hpx/config/reflection.hpp Outdated
Comment thread libs/core/serialization/include/hpx/serialization/serialization_fwd.hpp Outdated
Comment thread libs/core/serialization/include/hpx/serialization/set.hpp
Comment thread libs/core/serialization/include/hpx/serialization/unordered_map.hpp
Comment thread libs/core/serialization/CMakeLists.txt
Comment thread .github/workflows/linux_release_clang_p2996_reflection.yml Outdated
@ujjwal-shekhar
Copy link
Copy Markdown
Contributor Author

@ujjwal-shekhar Sorry for spamming with a long list of comments, I went over the PR from a formal standpoint for now. I have not done a deep review of the implementation yet.

Generally, thank you so much for working on this! This is marvelous.

Thank you! It is a really interesting feature indeed. No worries about the long list; I'll go through the comments soon and green out the failing checks as well.

Comment thread libs/core/serialization/include/hpx/serialization/input_archive.hpp Fixed
Comment thread libs/core/config/include/hpx/config/reflection.hpp Outdated
Comment thread libs/core/serialization/include/hpx/serialization/access.hpp
Comment thread libs/core/serialization/include/hpx/serialization/input_archive.hpp
Comment thread libs/core/serialization/include/hpx/serialization/input_archive.hpp Outdated
Comment thread libs/core/serialization/include/hpx/serialization/serialization_fwd.hpp Outdated
template <>
struct register_types<>
{
static void ensure_instantiated() {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think these functions can be constexpr and noexcept.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am considering shifting ensure_instantiated and other improvements to the core auto-serialization facility to a future PR (which will also include a DFS of polymorphic types for semi-automation of polymorphic types, compile-time checks to see if the user missed a register; etc).

Comment thread libs/core/serialization/include/hpx/serialization/detail/refl_serialize_impl.hpp Outdated
Comment thread libs/core/serialization/include/hpx/serialization/detail/refl_serialize_impl.hpp Outdated
Comment thread libs/core/serialization/tests/unit/refl/reflection_array.cpp Outdated
Comment thread libs/core/serialization/tests/unit/refl/reflection_array.cpp
Copy link
Copy Markdown
Contributor

@hkaiser hkaiser left a comment

Choose a reason for hiding this comment

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

This starts looking really nice! Just some mostly minor comments below...

Comment thread libs/core/serialization/include/hpx/serialization/detail/refl_serialize_impl.hpp Outdated
Comment thread libs/core/serialization/include/hpx/serialization/access.hpp Outdated
Comment thread libs/core/serialization/include/hpx/serialization/macros.hpp Outdated
@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented Feb 15, 2026

inspect and the cmake file checker are complaining about problems, please have a look. The other CircleCI problem are known and unrelated.

@ujjwal-shekhar
Copy link
Copy Markdown
Contributor Author

Thank you for the comments @hkaiser !

I have made some changes addressing most of the comments. Before wrapping up the rest, I will focus on fixing the new CI script with cpp26 reflection (as I expect there to be some bugs when testing the full suite under enabled reflection changes :p)

Comment thread libs/core/serialization/include/hpx/serialization/detail/refl_serialize_impl.hpp Outdated
Comment thread libs/core/serialization/include/hpx/serialization/detail/refl_serialize_impl.hpp Outdated
Comment thread libs/core/serialization/include/hpx/serialization/input_archive.hpp Fixed
Copy link
Copy Markdown
Contributor

@hkaiser hkaiser left a comment

Choose a reason for hiding this comment

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

Just some food for thought: what can be made consteval instead of being constexpr?

Comment thread libs/core/serialization/include/hpx/serialization/access.hpp
Comment thread libs/core/serialization/include/hpx/serialization/input_archive.hpp Outdated
@ujjwal-shekhar
Copy link
Copy Markdown
Contributor Author

Just some food for thought: what can be made consteval instead of being constexpr?

At a glance, I am inclined to believe that anything that must be evaluated within the std::meta context should be constevalable. By extension, it feels like a lot of this could be consteval. I will experiment with this:)

@ujjwal-shekhar ujjwal-shekhar force-pushed the reflect-serialize branch 2 times, most recently from d4d906d to ce9670f Compare March 8, 2026 07:03
@ujjwal-shekhar
Copy link
Copy Markdown
Contributor Author

@hkaiser, In the CI job with reflection enabled, would you recommend we run the full suite or just the serialization tests? The full suite would turn it into a long job so I have limited it to just the serialization tests for now.

@codacy-production
Copy link
Copy Markdown

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
Report missing for 358fef11 0.00%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (358fef1) Report Missing Report Missing Report Missing
Head commit (ce9670f) 131434 51 0.04%

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#6859) 131 0 0.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Footnotes

  1. Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented Mar 8, 2026

@hkaiser, In the CI job with reflection enabled, would you recommend we run the full suite or just the serialization tests? The full suite would turn it into a long job so I have limited it to just the serialization tests for now.

Just the serialization tests for now, I guess. We will soon move this repository to a new github organization where we will have access to an enterprise license. We can re-evaluate the CI situation then.

@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented Mar 8, 2026

@ujjwal-shekhar Overall, this PR seems to be almost complete - excellent work!

@ujjwal-shekhar
Copy link
Copy Markdown
Contributor Author

@ujjwal-shekhar Overall, this PR seems to be almost complete - excellent work!

@hkaiser Thanks! I'm really happy with how the reflection logic is holding up. Once we've addressed the remaining comments, I'll move this from a draft to an open PR. Super excited to get this merged!

Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
… code, macro can be improved, test CRTP serialization

Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
…tcast instead

Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
…so far)

Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
Signed-off-by: Ujjwal Shekhar <ujjwal.shekhar@research.iiit.ac.in>
@ujjwal-shekhar
Copy link
Copy Markdown
Contributor Author

The CMake build system checker reports:

Missing hpx/serialization/traits/is_serializable.hpp in libs/core/serialization/CMakeLists.txt

Could you please add that file?

Done @hkaiser ! Apologies for having missed this, I had accidentally removed this line while adding the new trait file to the CMakeList.

@codacy-production
Copy link
Copy Markdown

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
Report missing for 89914d31 0.00%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (89914d3) Report Missing Report Missing Report Missing
Head commit (b095cd4) 130899 51 0.04%

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#6859) 149 0 0.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Footnotes

  1. Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

@hkaiser hkaiser merged commit c982aff into TheHPXProject:master Mar 13, 2026
111 of 114 checks passed
@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented Mar 13, 2026

@ujjwal-shekhar thank you again for your persistence and effort! This is a major milestone for HPX!

ArivoliR pushed a commit to ArivoliR/hpx that referenced this pull request Mar 29, 2026
…ialize

[Serialization] [Feature] Add experimental C++26 reflection support
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants