On Thu, Mar 26, 2026 at 05:56:48PM +0100, Jakub Jelinek wrote: > Hi! > > This patch attempts to implement this paper. > Lightly tested so far. > > 2026-03-26 Jakub Jelinek <[email protected]> > > gcc/cp/ > * cp-trait.def (__builtin_is_structural): New trait. > * semantics.cc (trait_expr_value): Handle CPTK_IS_STRUCTURAL. > (finish_trait_expr): Likewise. > * constraint.cc (diagnose_trait_expr): Likewise. > * metafns.gperf (enum metafn_code): Add METAFN_IS_STRUCTURAL_TYPE. > (is_structural_type): New metafn. > * metafns.h: Regenerate. > * reflect.cc (eval_is_structural_type): New function. > (process_metafunction): Handle METAFN_IS_STRUCTURAL_TYPE. > gcc/testsuite/ > * g++.dg/reflect/type_trait14.C: New test. > * g++.dg/reflect/eh1.C: Add test for is_structural_type. > * g++.dg/reflect/eh2.C: Likewise. > libstdc++-v3/ > * include/bits/version.def (is_structural): New. > * include/bits/version.h: Regenerate. > * include/std/type_traits (__glibcxx_want_is_structural): Define. > (std::is_structural): New type trait. > (std::is_structural_v): New type trait variable template. > * include/std/meta (std::meta::is_structural_type): New declaration. > * src/c++23/std.cc.in: Export std::is_structural, std::is_structural_v > and std::meta::is_structural_type. > * > testsuite/20_util/is_structural/requirements/explicit_instantiation.cc: New > test. > * testsuite/20_util/is_structural/requirements/typedefs.cc: New test. > * testsuite/20_util/is_structural/value.cc: New test. > * testsuite/20_util/variable_templates_for_traits.cc: Test > is_structural_v. > > --- gcc/cp/cp-trait.def.jj 2026-01-15 16:33:46.972098555 +0100 > +++ gcc/cp/cp-trait.def 2026-03-26 16:57:51.414942417 +0100 > @@ -98,6 +98,7 @@ DEFTRAIT_EXPR (IS_REFERENCE, "__is_refer > DEFTRAIT_EXPR (IS_SAME, "__is_same", 2) > DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1) > DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1) > +DEFTRAIT_EXPR (IS_STRUCTURAL, "__builtin_is_structural", 1) > DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1) > DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2) > DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", > -1) > --- gcc/cp/semantics.cc.jj 2026-03-12 15:27:17.698072317 +0100 > +++ gcc/cp/semantics.cc 2026-03-26 16:58:37.177163606 +0100 > @@ -14173,6 +14173,9 @@ trait_expr_value (cp_trait_kind kind, tr > case CPTK_IS_CONSTEVAL_ONLY: > return consteval_only_p (type1); > > + case CPTK_IS_STRUCTURAL: > + return structural_type_p (type1); > + > /* __array_rank, __builtin_type_order and > __builtin_structured_binding_size > are handled in finish_trait_expr. */ > case CPTK_RANK: > @@ -14354,6 +14357,7 @@ finish_trait_expr (location_t loc, cp_tr > case CPTK_IS_TRIVIAL: > case CPTK_IS_TRIVIALLY_COPYABLE: > case CPTK_IS_CONSTEVAL_ONLY: > + case CPTK_IS_STRUCTURAL: > case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: > if (!check_trait_type (type1, /* kind = */ 2)) > return error_mark_node; > --- gcc/cp/constraint.cc.jj 2026-03-03 09:43:54.564370259 +0100 > +++ gcc/cp/constraint.cc 2026-03-26 16:58:06.583684262 +0100 > @@ -3357,6 +3357,10 @@ diagnose_trait_expr (location_t loc, tre > case CPTK_IS_CONSTEVAL_ONLY: > inform (decl_loc, "%qT is not consteval-only", t1); > break; > + case CPTK_IS_STRUCTURAL: > + inform (decl_loc, "%qT is not a structural type", t1); > + structural_type_p (t1, /*explain=*/true); > + break; > case CPTK_RANK: > inform (loc, "%qT cannot yield a rank", t1); > break; > --- gcc/cp/metafns.gperf.jj 2026-03-25 20:19:10.715163161 +0100 > +++ gcc/cp/metafns.gperf 2026-03-26 14:31:11.313544554 +0100 > @@ -172,6 +172,7 @@ enum metafn_code { > METAFN_IS_FINAL_TYPE, > METAFN_IS_AGGREGATE_TYPE, > METAFN_IS_CONSTEVAL_ONLY_TYPE, > + METAFN_IS_STRUCTURAL_TYPE, > METAFN_IS_SIGNED_TYPE, > METAFN_IS_UNSIGNED_TYPE, > METAFN_IS_BOUNDED_ARRAY_TYPE, > @@ -607,6 +608,7 @@ is_abstract_type, METAFN_IS_ABSTRACT_TYP > is_final_type, METAFN_IS_FINAL_TYPE, METAFN_KIND_BOOL_TINFO, > is_aggregate_type, METAFN_IS_AGGREGATE_TYPE, METAFN_KIND_BOOL_TINFO, > is_consteval_only_type, METAFN_IS_CONSTEVAL_ONLY_TYPE, > METAFN_KIND_BOOL_TINFO, > +is_structural_type, METAFN_IS_STRUCTURAL_TYPE, METAFN_KIND_BOOL_TINFO, > is_signed_type, METAFN_IS_SIGNED_TYPE, METAFN_KIND_BOOL_TINFO, > is_unsigned_type, METAFN_IS_UNSIGNED_TYPE, METAFN_KIND_BOOL_TINFO, > is_bounded_array_type, METAFN_IS_BOUNDED_ARRAY_TYPE, METAFN_KIND_BOOL_TINFO, > --- gcc/cp/reflect.cc.jj 2026-03-26 12:30:48.440143055 +0100 > +++ gcc/cp/reflect.cc 2026-03-26 14:33:07.038568698 +0100 > @@ -4362,6 +4362,17 @@ eval_is_consteval_only_type (tree type) > return boolean_false_node; > } > > +/* Process std::meta::is_structural_type. */ > + > +static tree > +eval_is_structural_type (tree type) > +{ > + if (structural_type_p (type)) > + return boolean_true_node; > + else > + return boolean_false_node; > +}
Since this patch is adding the trait, this could be just return eval_type_trait (loc, type, CPTK_IS_STRUCTURAL); Not that it matters in this case... The cp/ bits look good to me otherwise. Marek
