Skip to content

C++26 Reflection#2217

Merged
stephenberry merged 85 commits intomainfrom
reflection26
Mar 7, 2026
Merged

C++26 Reflection#2217
stephenberry merged 85 commits intomainfrom
reflection26

Conversation

@stephenberry
Copy link
Copy Markdown
Owner

@stephenberry stephenberry commented Jan 6, 2026

C++26 P2996 Reflection Support

This PR adds experimental support for C++26 static reflection (P2996) to Glaze.

Overview

When compiled with -DGLZ_REFLECTION26=1 and a P2996-compatible compiler, Glaze uses std::meta::nonstatic_data_members_of for automatic struct reflection instead of the traditional aggregate-based approach. This enables reflection of:

  • Non-aggregate types (classes with constructors)
  • Types with private members
  • Any class type without requiring glz::meta specializations

Key Changes

The specified Trait

Introduced glz::specified<T> trait and glz::is_specified<T> concept to mark types with custom Glaze serialization. This prevents P2996 from automatically reflecting types that already have explicit to/from implementations, avoiding template ambiguity.

// Mark a type as having custom serialization
template <>
struct glz::specified<MyType> : std::true_type {};

Types marked as specified:

  • Standard library: std::tuple, std::variant, std::reference_wrapper, std::complex, std::bitset
  • Chrono types: duration, time_point, year_month_day, hh_mm_ss
  • Thread-safe containers: async_vector, async_string, shared_async_vector, shared_async_map, async
  • Eigen types: Matrix, Transform, Ref

Simplified reflectable Concept

The P2996 version of reflectable is cleaner since P2996 handles the complexity:

template <class T>
concept reflectable =
   std::is_class_v<std::remove_cvref_t<T>> &&
   !(is_no_reflect<T> || glaze_t<T> || meta_keys<T> ||
     range<T> || pair_t<T> || null_t<T> || str_t<T> || bool_t<T> ||
     tuple_t<T> || func_t<T> || is_specified<T>);

CI Integration

Added GitHub Actions workflow using the vsavkov/clang-p2996 Docker image for automated testing.

Other Fixes

  • Fixed std::is_trivial_v deprecation warning for C++26
  • Extended bool_t concept to handle std::vector<bool>::const_reference
  • Adjusted tests for P2996's type naming differences (returns variant<...> instead of std::variant<...>)

Building with P2996

cmake -B build \
  -DCMAKE_CXX_FLAGS='-std=c++26 -freflection -fexpansion-statements' \
  -Dglaze_ENABLE_REFLECTION26=ON

Known Limitations

  • jsonrpc_test is excluded due to a libc++ std::expected constraint recursion bug in the experimental compiler
  • Type names from P2996 reflection may differ from traditional Glaze (no std:: prefix)

@packit-as-a-service
Copy link
Copy Markdown

One of the tests failed for 932ef26. @admin check logs None, packit dashboard https://dashboard.packit.dev/jobs/copr/3128523 and external service dashboard https://copr.fedorainfracloud.org/coprs/build/9977010/

@packit-as-a-service
Copy link
Copy Markdown

@packit-as-a-service
Copy link
Copy Markdown

@packit-as-a-service
Copy link
Copy Markdown

One of the tests failed for 4fb6b49. @admin check logs None, packit dashboard https://dashboard.packit.dev/jobs/copr/3128640 and external service dashboard https://copr.fedorainfracloud.org/coprs/build/9977197/

@packit-as-a-service
Copy link
Copy Markdown

@packit-as-a-service
Copy link
Copy Markdown

One of the tests failed for 667abce. @admin check logs None, packit dashboard https://dashboard.packit.dev/jobs/copr/3131874 and external service dashboard https://copr.fedorainfracloud.org/coprs/build/9980754/

@packit-as-a-service
Copy link
Copy Markdown

One of the tests failed for 19e3877. @admin check logs None, packit dashboard https://dashboard.packit.dev/jobs/copr/3206324 and external service dashboard https://copr.fedorainfracloud.org/coprs/build/10079343/

@packit-as-a-service
Copy link
Copy Markdown

One of the tests failed for 090c5c6. @admin check logs None, packit dashboard https://dashboard.packit.dev/jobs/copr/3206307 and external service dashboard https://copr.fedorainfracloud.org/coprs/build/10079337/

@packit-as-a-service
Copy link
Copy Markdown

One of the tests failed for dc878ec. @admin check logs None, packit dashboard https://dashboard.packit.dev/jobs/copr/3342323 and external service dashboard https://copr.fedorainfracloud.org/coprs/build/10198419/

@stephenberry stephenberry merged commit f05c756 into main Mar 7, 2026
47 of 48 checks passed
@stephenberry stephenberry deleted the reflection26 branch March 7, 2026 16:07
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.

Regression: std::optional<std::variant<>> nolonger works with GCC16 with C++26

1 participant