Files
gcc/libstdc++-v3/include/std/meta
Marek Polacek 4b0e94b394 c++: C++26 Reflection [PR120775]
This patch implements C++26 Reflection as specified by P2996R13, which allows
users to perform magic.  This patch also implements related papers:
Annotations for Reflection (P3394R4),
Splicing a base class subobject (P3293R3),
define_static_{string,object,array} (P3491R3),
Function Parameter Reflection (P3096R12).
(I already implemented consteval blocks back in July.)
(We do not yet implement P3795.)

We also implemented some CWG issues that had been approved in Kona;
e.g., CWG 3101, 3109, 3111, 3115, 3117.

All metafunctions are implemented in this patch.

The feature needs to be enabled by -std=c++26 -freflection.

Some stats: the v1 patch was over 51,200 LOC which were written in ~335
commits.  It came with over 400 tests with 11,722 static_asserts.  We still
had about 50 TODOs and FIXMEs in the code.
v2 consists of about 56,000 LOC which were created in 440 commits.  We
now have 446 tests with 40 TODOs remaining.
v3 brought another 77 commits, mostly clean-ups and various bug fixes.

I'd like to thank:
Jakub Jelinek, whose efforts can only be described as heroic and who
never ceases to amaze me even after nearly 15 years of working together,
he implemented many difficult metafunctions, annotations, mangling,
converted our metafunction dispatch to using gperf, and so on and on;
Jonathan Wakely for his libstdc++ patch review and generous & impeccable
advice even at odd hours; Dan Katz for his work on the Reflection papers,
writing Reflection tests for clang++ (many of which I've stolen^Wused),
for his advice, bug reports, and generally cheering me on; Jason Merrill
for his guidance, patch review, and, in fact, encouraging me to take on
this project in the first place; Michael Levine, Valentyn Yukhymenko, and
Alex Yesmanchyk for their nice contributions to Reflection; and Tomasz
Kamiński for providing test cases, finding bugs, and answering my C++
questions.

	PR c++/120775
	PR c++/123081
	PR c++/122634

gcc/ChangeLog:

	* attribs.cc (attribute_value_equal): Return false if either attribute
	is ATTR_UNIQUE_VALUE_P.
	(merge_attributes): Handle lists with ATTR_UNIQUE_VALUE_P values.
	* doc/invoke.texi: Document -freflection.
	* dwarf2out.cc (is_base_type) <case default>: Check
	TREE_CODE >= LAST_AND_UNUSED_TREE_CODE instead of is_cxx_auto.
	(gen_type_die_with_usage): For TREE_CODE >= LAST_AND_UNUSED_TREE_CODE
	trees use use DW_TAG_unspecified_type.
	* tree-core.h (struct tree_base): Update a comment.
	* tree.h (ATTR_UNIQUE_VALUE_P): Define.
	(BINFO_BASE_ACCESSES): Update the comment.

gcc/c-family/ChangeLog:

	* c-attribs.cc (attribute_takes_identifier_p): Return false for C++
	annotations.  Handle "old parm name".
	* c-cppbuiltin.cc (c_cpp_builtins): Define __cpp_impl_reflection.
	* c.opt (freflection): New.

gcc/cp/ChangeLog:

	* Make-lang.in: Add cp/reflect.o.  Add a rule for cp/metafns.h.
	* config-lang.in: Add reflect.cc.
	* constexpr.cc (constexpr_global_ctx): Add consteval_block and
	metafns_called members.  Initialize them.
	(cxx_constexpr_quiet_p): New.
	(cxx_constexpr_manifestly_const_eval): New.
	(cxx_constexpr_caller): New.
	(cxx_constexpr_consteval_block): New.
	(enum value_cat): Move into cp-tree.h.
	(cxx_eval_constant_expression): Move the declaration into cp-tree.h.
	No longer static.  Handle REFLECT_EXPR.  Handle conversion of
	a reflection to the meta::info type.
	(cxx_eval_cxa_builtin_fn): Override current_function_decl.
	(cxx_eval_builtin_function_call): Handle __builtin_is_string_literal.
	(is_std_allocator): Also check __new_allocator.
	(is_std_allocator_allocate): No longer static.
	(cxa_allocate_and_throw_exception): New.
	(cxx_eval_call_expression): Handle metafunctions.  Maybe set
	metafns_called.
	(reduced_constant_expression_p): Handle REFLECT_EXPR.
	(cxx_eval_binary_expression): Use compare_reflections for comparing
	reflections.
	(find_immediate_fndecl): Don't walk REFLECT_EXPR_P.
	(cxx_eval_outermost_constant_expr): Set global_ctx.consteval_block.
	Detect consteval-only smuggling.
	(potential_constant_expression_1): Return true for REFLECT_EXPR
	and SPLICE_EXPR.
	* constraint.cc (diagnose_trait_expr): Add CPTK_IS_CONSTEVAL_ONLY case.
	* cp-gimplify.cc (immediate_escalating_function_p): No longer static.
	(promote_function_to_consteval): Likewise.
	(cp_gimplify_expr) <case CALL_EXPR>: Detect any surviving consteval-only
	expressions.
	<case CP_BUILT_IN_IS_STRING_LITERAL>: Handle.
	(wipe_consteval_only_r): New.
	(cp_fold_immediate_r): Detect invalid uses of consteval-only types.
	Clear consteval-only DECL_EXPRs.
	(cp_genericize_r): Wipe consteval-only vars from BIND_EXPR_VARS and
	BLOCK_VARS.
	* cp-objcp-common.cc (cp_common_init_ts): Mark META_TYPE, SPLICE_SCOPE,
	SPLICE_EXPR, and REFLECT_EXPR.
	* cp-trait.def (IS_CONSTEVAL_ONLY): New trait.
	* cp-tree.def (REFLECT_EXPR, META_TYPE, SPLICE_EXPR, SPLICE_SCOPE): New
	trees.
	* cp-tree.h (enum cp_tree_index): Add CPTI_ANNOTATION_IDENTIFIER,
	CPTI_STD_META, and CPTI_META_INFO_TYPE.
	(std_meta_node): Define.
	(meta_info_type_node): Define.
	(annotation_identifier): Define.
	(REFLECTION_TYPE_P): Define.
	(REFLECT_EXPR_P): Define.
	(REFLECT_EXPR_HANDLE): Define.
	(enum reflect_kind): New.
	(REFLECT_EXPR_KIND): Define.
	(SET_REFLECT_EXPR_KIND): Define.
	(SPLICE_EXPR_EXPRESSION_P): Define.
	(SET_SPLICE_EXPR_EXPRESSION_P): Define.
	(SPLICE_EXPR_MEMBER_ACCESS_P): Define.
	(SET_SPLICE_EXPR_MEMBER_ACCESS_P): Define.
	(SPLICE_EXPR_ADDRESS_P): Define.
	(SET_SPLICE_EXPR_ADDRESS_P): Define.
	(SPLICE_SCOPE_EXPR): Define.
	(SPLICE_SCOPE_TYPE_P): Define.
	(WILDCARD_TYPE_P): Include SPLICE_SCOPE.
	(COMPONENT_REF_SPLICE_P): Define.
	(SCALAR_TYPE_P): Include REFLECTION_TYPE_P.
	(ENUM_BEING_DEFINED_P): Define.
	(OLD_PARM_DECL_P): Define.
	(MULTIPLE_NAMES_PARM_P): Define.
	(cp_preserve_using_decl): Declare.
	(DEF_OPERATOR, DEF_ASSN_OPERATOR): Include META.
	(struct ovl_op_info_t): Add meta_name member.
	(enum cp_built_in_function): Add CP_BUILT_IN_IS_STRING_LITERAL.
	(build_stub_type): Declare.
	(current_function_decl_without_access_scope): Declare.
	(dependent_namespace_p): Declare.
	(convert_reflect_constant_arg): Declare.
	(finish_base_specifier): Adjust declaration.
	(parsing_lambda_declarator): Declare.
	(fold_builtin_is_string_literal): Declare.
	(annotation_p): Declare.
	(finish_class_member_access_expr): Adjust declaration.
	(immediate_escalating_function_p): Declare.
	(promote_function_to_consteval): Declare.
	(is_std_allocator_allocate): Declare.
	(cxa_allocate_and_throw_exception): Declare.
	(enum value_cat): Define.
	(cxx_eval_constant_expression): Declare.
	(cxx_constexpr_quiet_p): Declare.
	(cxx_constexpr_manifestly_const_eval): Declare.
	(cxx_constexpr_caller): Declare.
	(cxx_constexpr_consteval_block): Declare.
	(init_reflection): Declare.
	(metafunction_p): Declare.
	(direct_base_parent): Declare.
	(process_metafunction): Declare.
	(get_reflection): Declare.
	(get_null_reflection): Declare.
	(splice): Declare.
	(check_out_of_consteval_use): Declare.
	(consteval_only_p): Declare.
	(compare_reflections): Declare.
	(valid_splice_type_p): Declare.
	(valid_splice_scope_p): Declare.
	(check_splice_expr): Declare.
	(make_splice_scope): Declare.
	(dependent_splice_p): Declare.
	(reflection_mangle_prefix): Declare.
	(check_consteval_only_fn): Declare.
	* cvt.cc (convert_to_void): Call check_out_of_consteval_use.
	* cxx-pretty-print.cc (cxx_pretty_printer::unary_expression): New
	REFLECT_EXPR case.
	(cxx_pretty_printer::expression): Likewise.
	(cxx_pretty_printer::simple_type_specifier): New META_TYPE case.
	(cxx_pretty_printer::type_id): Likewise.
	* decl.cc (duplicate_decls): Merge parameter names for Reflection.
	Maybe set OLD_PARM_DECL_P.
	(initialize_predefined_identifiers): Add "annotation ".
	(cxx_init_decl_processing): Add __builtin_is_string_literal.  Call
	init_reflection.
	(maybe_commonize_var): Do nothing for consteval_only_p.
	(check_initializer): Default-initialize std::meta::info.
	(make_rtl_for_nonlocal_decl): For consteval_only_p vars, set
	DECL_EXTERNAL and return early.
	(cp_finish_decl): Call check_out_of_consteval_use.  Don't go
	creating a varpool node for consteval_only_p.
	(get_tuple_size): Check the instantiation instead of the type.
	(grokfndecl): Call check_consteval_only_fn.
	(xref_basetypes): Stitch annotations onto BINFO_BASE_ACCESSES.
	(finish_enum_value_list): Clear ENUM_BEING_DEFINED_P.
	* decl2.cc (is_late_template_attribute): Handle all annotations as
	late.
	(cp_check_const_attributes): Don't handle annotations here.
	(maybe_make_one_only): Do nothing for consteval_only_p.
	(mark_needed): Likewise.
	(min_vis_expr_r): Handle reflections.
	(prune_vars_needing_no_initialization): Skip consteval_only_p.
	(no_linkage_error): Return early for metafunctions.
	(c_parse_final_cleanups): Don't write out consteval_only_p vars.  Avoid
	complaining about metafunctions.
	* error.cc (dump_type): New cases for CONST_DECL, META_TYPE, and
	SPLICE_SCOPE.
	(dump_type_prefix): New cases for META_TYPE and SPLICE_SCOPE.
	(dump_type_suffix): Likewise.
	(dump_decl): Dump SPLICE_EXPR.
	(dump_expr): Dump REFLECT_EXPR and SPLICE_EXPR.
	* init.cc (build_zero_init_1): Build a null reflection value.
	(perform_member_init): Call check_out_of_consteval_use.
	* lex.cc (DEF_OPERATOR, OPERATOR_TRANSITION): Update defines.
	* mangle.cc (write_type): Mangle META_TYPE.
	(write_expression): Handle REFLECT_EXPR.
	(write_reflection): New.
	(write_template_arg_literal): New REFLECT_EXPR case.
	(write_template_arg): Handle REFLECT_EXPR.
	* method.cc (build_stub_type): No longer static.
	* module.cc (trees_out::type_node): Handle META_TYPE.
	(trees_in::tree_node): Likewise.
	* name-lookup.cc (name_lookup::adl_type): std::meta is an associated
	namespace of std::meta::info.
	(strip_using_decl): Don't strip when cp_preserve_using_decl.
	(handle_namespace_attrs): Handle annotations.
	(do_namespace_alias): Handle SPLICE_EXPR.
	(lookup_qualified_name): When cp_preserve_using_decl, don't do
	OVL_FUNCTION.
	(finish_using_directive): Detect annotations on using directive.
	* operators.def: Update for META_NAME.
	* parser.cc: New cp_preserve_using_decl global.
	(enum required_token): Add RT_CLOSE_SPLICE.
	(get_required_cpp_ttype): Return CPP_CLOSE_SPLICE for RT_CLOSE_SPLICE.
	(cp_parser_next_tokens_start_splice_type_spec_p): New.
	(cp_parser_next_tokens_can_start_splice_scope_spec_p): New.
	(cp_parser_splice_specifier): New.
	(cp_parser_splice_type_specifier): New.
	(cp_parser_splice_expression): New.
	(cp_parser_splice_scope_specifier): New.
	(cp_parser_splice_spec_is_nns_p): New.
	(cp_parser_nth_token_starts_splice_without_nns_p): New.
	(cp_parser_primary_expression): Handle CPP_OPEN_SPLICE.  Give an
	error for ^^ outside reflection.
	(cp_parser_unqualified_id): Allow r.~typename [:R:].
	(cp_parser_nested_name_specifier_opt): Cope with splice-scope-specifier.
	(cp_parser_qualifying_entity): Parse splice-scope-specifier.
	(cp_parser_postfix_expression): Deal with [: :] after a typename.
	(cp_parser_postfix_dot_deref_expression): Parse & handle splices
	in a class member access.  Pass splice_p to
	finish_class_member_access_expr.
	(cp_parser_reflection_name): New.
	(cp_parser_reflect_expression): New.
	(cp_parser_unary_expression): Parse reflect-expression.
	(cp_parser_declaration): Parse splice-scope-specifier.
	(cp_parser_decomposition_declaration): Detect annotations on structured
	bindings.
	(cp_parser_decltype_expr): Parse splice-expression.
	(cp_parser_template_id): New parsed_templ argument.  If it's nonnull,
	don't parse the template name.  Turn an assert into a condition.
	(cp_parser_type_specifier): Handle typename [: :].
	(cp_parser_simple_type_specifier): Parse splice-type-specifier.
	(cp_parser_enum_specifier): Set ENUM_BEING_DEFINED_P.
	(cp_parser_namespace_alias_definition): Parse splice-specifier.
	(cp_parser_using_directive): Likewise.
	(cp_parser_type_id_1): New bool * parameter to distinguish between
	types and type aliases.  Set it.
	(cp_parser_type_id): Adjust the call to cp_parser_type_id_1.
	(cp_parser_template_type_arg): Likewise.
	(cp_parser_trailing_type_id): Likewise.
	(cp_parser_base_specifier): Handle annotations.  Maybe give an error
	for splice-scope-specifier.  Parse splice-type-specifier.  Pass
	annotations to finish_base_specifier.
	(cp_parser_annotation): New.
	(cp_parser_std_attribute_list): Detect mixing annotations and attributes
	in the same list.
	(cp_parser_annotation_list): New.
	(cp_parser_std_attribute_spec): Parse annotations.
	(cp_parser_skip_balanced_tokens): Also handle CPP_OPEN_SPLICE
	and CPP_CLOSE_SPLICE.
	(cp_parser_type_requirement): Parse splice-type-specifier.
	(cp_parser_lookup_name): Also consider dependent namespaces.  Don't
	call check_accessibility_of_qualified_id for USING_DECLs.
	(cp_parser_required_error): Handle RT_CLOSE_SPLICE.
	* pt.cc (current_function_decl_without_access_scope): New.
	(verify_unstripped_args_1): REFLECT_EXPR_P is OK.
	(iterative_hash_template_arg): Handle REFLECT_EXPR.
	(convert_nontype_argument): Maybe give an error for REFLECTION_TYPE_P.
	(for_each_template_parm_r): Handle SPLICE_SCOPE.
	(instantiate_class_template): Handle annotations.
	(tsubst_pack_index): Make static.
	(tsubst_decl): Handle NAMESPACE_DECL.
	(tsubst_splice_scope): New.
	(tsubst_splice_expr): New.
	(tsubst): Don't return early for NAMESPACE_DECL.   New META_TYPE case.
	Handle a splice-specifier that expanded into a NAMESPACE_DECL.  Handle
	SPLICE_SCOPE, SPLICE_EXPR, and TEMPLATE_ID_EXPR.
	(tsubst_scope): Also accept NAMESPACE_DECL.
	(tsubst_qualified_id): Check dependent_namespace_p.
	(tsubst_lambda_expr): Set LAMBDA_EXPR_CONSTEVAL_BLOCK_P.
	(tsubst_expr): Allow dependent_splice_p in an assert.  Check
	COMPONENT_REF_SPLICE_P and pass it to finish_class_member_access_expr.
	<case NAMESPACE_DECL>: Remove.
	New REFLECT_EXPR and SPLICE_EXPR cases.
	(unify): Handle META_TYPE.
	(instantiate_body): Call check_consteval_only_fn.
	(tsubst_enum): Set ENUM_BEING_DEFINED_P.
	(dependent_type_p_r): A splice-scope-specifier is dependent.
	(dependent_namespace_p): New.
	(value_dependent_expression_p): Handle REFLECT_EXPR.  Also handle
	[meta.reflection.access.context]/8.
	(type_dependent_expression_p): REFLECT_EXPR_P is not type-dependent.
	(convert_reflect_constant_arg): New.
	* search.cc (check_final_overrider): Adjust for CWG 3117.
	* semantics.cc (finish_base_specifier): Handle annotations.
	(parsing_lambda_declarator): No longer static.
	(finish_id_expression_1): Check dependent_namespace_p.
	(fold_builtin_is_string_literal): New.
	(trait_expr_value): Handle CPTK_IS_CONSTEVAL_ONLY.
	(finish_trait_expr): Likewise.
	* tree.cc (handle_annotation_attribute): New.
	(builtin_valid_in_constant_expr_p): Return true for
	CP_BUILT_IN_IS_STRING_LITERAL.
	(cp_tree_equal): Handle comparing REFLECT_EXPRs.
	(internal_attributes): Add "annotation ".
	(annotation_p): New.
	* typeck.cc (finish_class_member_access_expr): New splice_p argument.
	Handle dependent splices.  Implement splicing a base class subobject.
	Handle class member access using a splice-expression.
	(cp_build_binary_op): Handle comparing std::meta::infos.
	(check_return_expr): Call check_out_of_consteval_use.
	* metafns.gperf: New file.
	* metafns.h: New file.
	* reflect.cc: New file.

libcc1/ChangeLog:

	* libcp1plugin.cc (start_class_def): Update the call to
	finish_base_specifier.

libcpp/ChangeLog:

	* charset.cc (_cpp_destroy_iconv): Destroy narrow_cset_desc and
	utf8_cset_desc.
	(cpp_translate_string): New.
	(cpp_valid_identifier): New.
	* include/cpplib.h: Add OPEN_SPLICE, CLOSE_SPLICE, and REFLECT_OP to
	TTYPE_TABLE.
	(cpp_translate_string): Declare.
	(cpp_valid_identifier): Declare.
	* internal.h (struct cpp_reader): Add reverse_narrow_cset_desc and
	reverse_utf8_cset_desc fields.
	* lex.cc (_cpp_lex_direct): Emit CPP_CLOSE_SPLICE, CPP_REFLECT_OP,
	and CPP_OPEN_SPLICE tokens.

libstdc++-v3/ChangeLog:

	* include/Makefile.am (std_headers): Add ${std_srcdir}/meta.
	* include/Makefile.in: Regenerate.
	* include/bits/iterator_concepts.h (std::ranges::__access::__begin): Add
	constexpr.
	* include/bits/version.def (reflection): New.
	* include/bits/version.h: Regenerate.
	* include/precompiled/stdc++.h: Include <meta> for C++26.
	* include/std/meta: New file.
	* include/std/type_traits (std::is_reflection): New trait.
	(std::is_fundamental): Include is_reflection for C++26 -freflection.
	(std::is_reflection_v): New variable template.
	(std::is_consteval_only): New trait.
	(std::is_consteval_only_v): New variable template.
	* src/c++23/std.cc.in: Add <meta> exports.
	* testsuite/20_util/variable_templates_for_traits.cc: Add -freflection as
	dg-additional-options for C++26.  Add std::is_reflection_v test in that case.
	* testsuite/20_util/is_consteval_only/requirements/explicit_instantiation.cc: New test.
	* testsuite/20_util/is_consteval_only/requirements/typedefs.cc: New test.
	* testsuite/20_util/is_consteval_only/value.cc: New test.
	* testsuite/20_util/is_reflection/requirements/explicit_instantiation.cc: New test.
	* testsuite/20_util/is_reflection/requirements/typedefs.cc: New test.
	* testsuite/20_util/is_reflection/value.cc: New test.

gcc/testsuite/ChangeLog:

	* g++.dg/DRs/dr2581-1.C: Add -freflection.
	* g++.dg/DRs/dr2581-2.C: Likewise.
	* g++.dg/reflect/access_context1.C: New test.
	* g++.dg/reflect/access_context2.C: New test.
	* g++.dg/reflect/access_context3.C: New test.
	* g++.dg/reflect/adl1.C: New test.
	* g++.dg/reflect/alignment_of1.C: New test.
	* g++.dg/reflect/alignment_of2.C: New test.
	* g++.dg/reflect/annotations1.C: New test.
	* g++.dg/reflect/annotations2.C: New test.
	* g++.dg/reflect/annotations3.C: New test.
	* g++.dg/reflect/annotations4.C: New test.
	* g++.dg/reflect/annotations5.C: New test.
	* g++.dg/reflect/annotations6.C: New test.
	* g++.dg/reflect/annotations7.C: New test.
	* g++.dg/reflect/annotations8.C: New test.
	* g++.dg/reflect/anon1.C: New test.
	* g++.dg/reflect/anon2.C: New test.
	* g++.dg/reflect/anon3.C: New test.
	* g++.dg/reflect/bases_of1.C: New test.
	* g++.dg/reflect/bases_of2.C: New test.
	* g++.dg/reflect/bases_of3.C: New test.
	* g++.dg/reflect/bit_size_of1.C: New test.
	* g++.dg/reflect/bitfield1.C: New test.
	* g++.dg/reflect/can_substitute1.C: New test.
	* g++.dg/reflect/class1.C: New test.
	* g++.dg/reflect/class2.C: New test.
	* g++.dg/reflect/common_reference1.C: New test.
	* g++.dg/reflect/common_type1.C: New test.
	* g++.dg/reflect/compare1.C: New test.
	* g++.dg/reflect/compare10.C: New test.
	* g++.dg/reflect/compare2.C: New test.
	* g++.dg/reflect/compare3.C: New test.
	* g++.dg/reflect/compare4.C: New test.
	* g++.dg/reflect/compare5.C: New test.
	* g++.dg/reflect/compare6.C: New test.
	* g++.dg/reflect/compare7.C: New test.
	* g++.dg/reflect/compare8.C: New test.
	* g++.dg/reflect/compare9.C: New test.
	* g++.dg/reflect/compat1.C: New test.
	* g++.dg/reflect/complete1.C: New test.
	* g++.dg/reflect/constant_of1.C: New test.
	* g++.dg/reflect/constant_of2.C: New test.
	* g++.dg/reflect/constant_of3.C: New test.
	* g++.dg/reflect/constant_of4.C: New test.
	* g++.dg/reflect/constant_of5.C: New test.
	* g++.dg/reflect/constant_of6.C: New test.
	* g++.dg/reflect/constant_of7.C: New test.
	* g++.dg/reflect/constant_of8.C: New test.
	* g++.dg/reflect/constant_of9.C: New test.
	* g++.dg/reflect/crash1.C: New test.
	* g++.dg/reflect/crash10.C: New test.
	* g++.dg/reflect/crash11.C: New test.
	* g++.dg/reflect/crash12.C: New test.
	* g++.dg/reflect/crash13.C: New test.
	* g++.dg/reflect/crash14.C: New test.
	* g++.dg/reflect/crash15.C: New test.
	* g++.dg/reflect/crash16.C: New test.
	* g++.dg/reflect/crash17.C: New test.
	* g++.dg/reflect/crash18.C: New test.
	* g++.dg/reflect/crash2.C: New test.
	* g++.dg/reflect/crash3.C: New test.
	* g++.dg/reflect/crash4.C: New test.
	* g++.dg/reflect/crash5.C: New test.
	* g++.dg/reflect/crash6.C: New test.
	* g++.dg/reflect/crash7.C: New test.
	* g++.dg/reflect/crash8.C: New test.
	* g++.dg/reflect/crash9.C: New test.
	* g++.dg/reflect/data_member_spec1.C: New test.
	* g++.dg/reflect/data_member_spec2.C: New test.
	* g++.dg/reflect/data_member_spec3.C: New test.
	* g++.dg/reflect/data_member_spec4.C: New test.
	* g++.dg/reflect/dealias1.C: New test.
	* g++.dg/reflect/dealias2.C: New test.
	* g++.dg/reflect/dealias3.C: New test.
	* g++.dg/reflect/define_aggregate1.C: New test.
	* g++.dg/reflect/define_aggregate2.C: New test.
	* g++.dg/reflect/define_aggregate3.C: New test.
	* g++.dg/reflect/define_aggregate4.C: New test.
	* g++.dg/reflect/define_aggregate5.C: New test.
	* g++.dg/reflect/define_static_array1.C: New test.
	* g++.dg/reflect/define_static_array2.C: New test.
	* g++.dg/reflect/define_static_array3.C: New test.
	* g++.dg/reflect/define_static_array4.C: New test.
	* g++.dg/reflect/define_static_object1.C: New test.
	* g++.dg/reflect/define_static_object2.C: New test.
	* g++.dg/reflect/define_static_string1.C: New test.
	* g++.dg/reflect/dep1.C: New test.
	* g++.dg/reflect/dep10.C: New test.
	* g++.dg/reflect/dep11.C: New test.
	* g++.dg/reflect/dep2.C: New test.
	* g++.dg/reflect/dep3.C: New test.
	* g++.dg/reflect/dep4.C: New test.
	* g++.dg/reflect/dep5.C: New test.
	* g++.dg/reflect/dep6.C: New test.
	* g++.dg/reflect/dep7.C: New test.
	* g++.dg/reflect/dep8.C: New test.
	* g++.dg/reflect/dep9.C: New test.
	* g++.dg/reflect/diag1.C: New test.
	* g++.dg/reflect/diag2.C: New test.
	* g++.dg/reflect/diag3.C: New test.
	* g++.dg/reflect/diag4.C: New test.
	* g++.dg/reflect/display_string_of1.C: New test.
	* g++.dg/reflect/eh1.C: New test.
	* g++.dg/reflect/eh2.C: New test.
	* g++.dg/reflect/eh3.C: New test.
	* g++.dg/reflect/eh4.C: New test.
	* g++.dg/reflect/eh5.C: New test.
	* g++.dg/reflect/eh6.C: New test.
	* g++.dg/reflect/eh7.C: New test.
	* g++.dg/reflect/eh8.C: New test.
	* g++.dg/reflect/eh9.C: New test.
	* g++.dg/reflect/enumerators_of1.C: New test.
	* g++.dg/reflect/error1.C: New test.
	* g++.dg/reflect/error10.C: New test.
	* g++.dg/reflect/error2.C: New test.
	* g++.dg/reflect/error3.C: New test.
	* g++.dg/reflect/error4.C: New test.
	* g++.dg/reflect/error5.C: New test.
	* g++.dg/reflect/error6.C: New test.
	* g++.dg/reflect/error8.C: New test.
	* g++.dg/reflect/error9.C: New test.
	* g++.dg/reflect/expr1.C: New test.
	* g++.dg/reflect/expr10.C: New test.
	* g++.dg/reflect/expr11.C: New test.
	* g++.dg/reflect/expr12.C: New test.
	* g++.dg/reflect/expr13.C: New test.
	* g++.dg/reflect/expr14.C: New test.
	* g++.dg/reflect/expr2.C: New test.
	* g++.dg/reflect/expr3.C: New test.
	* g++.dg/reflect/expr4.C: New test.
	* g++.dg/reflect/expr5.C: New test.
	* g++.dg/reflect/expr6.C: New test.
	* g++.dg/reflect/expr7.C: New test.
	* g++.dg/reflect/expr8.C: New test.
	* g++.dg/reflect/expr9.C: New test.
	* g++.dg/reflect/extract1.C: New test.
	* g++.dg/reflect/extract2.C: New test.
	* g++.dg/reflect/extract3.C: New test.
	* g++.dg/reflect/extract4.C: New test.
	* g++.dg/reflect/extract5.C: New test.
	* g++.dg/reflect/extract6.C: New test.
	* g++.dg/reflect/extract7.C: New test.
	* g++.dg/reflect/extract8.C: New test.
	* g++.dg/reflect/extract9.C: New test.
	* g++.dg/reflect/feat1.C: New test.
	* g++.dg/reflect/feat2.C: New test.
	* g++.dg/reflect/has_c_language_linkage1.C: New test.
	* g++.dg/reflect/has_default_argument1.C: New test.
	* g++.dg/reflect/has_default_argument2.C: New test.
	* g++.dg/reflect/has_default_member_initializer1.C: New test.
	* g++.dg/reflect/has_ellipsis_parameter1.C: New test.
	* g++.dg/reflect/has_external_linkage1.C: New test.
	* g++.dg/reflect/has_external_linkage2.C: New test.
	* g++.dg/reflect/has_identifier1.C: New test.
	* g++.dg/reflect/has_identifier2.C: New test.
	* g++.dg/reflect/has_internal_linkage1.C: New test.
	* g++.dg/reflect/has_internal_linkage2.C: New test.
	* g++.dg/reflect/has_linkage1.C: New test.
	* g++.dg/reflect/has_module_linkage1.C: New test.
	* g++.dg/reflect/has_module_linkage2.C: New test.
	* g++.dg/reflect/has_parent1.C: New test.
	* g++.dg/reflect/has_template_arguments1.C: New test.
	* g++.dg/reflect/has_template_arguments2.C: New test.
	* g++.dg/reflect/has_template_arguments3.C: New test.
	* g++.dg/reflect/has_template_arguments4.C: New test.
	* g++.dg/reflect/identifier_of1.C: New test.
	* g++.dg/reflect/identifier_of2.C: New test.
	* g++.dg/reflect/init1.C: New test.
	* g++.dg/reflect/init10.C: New test.
	* g++.dg/reflect/init11.C: New test.
	* g++.dg/reflect/init12.C: New test.
	* g++.dg/reflect/init13.C: New test.
	* g++.dg/reflect/init14.C: New test.
	* g++.dg/reflect/init15.C: New test.
	* g++.dg/reflect/init16.C: New test.
	* g++.dg/reflect/init17.C: New test.
	* g++.dg/reflect/init2.C: New test.
	* g++.dg/reflect/init3.C: New test.
	* g++.dg/reflect/init4.C: New test.
	* g++.dg/reflect/init5.C: New test.
	* g++.dg/reflect/init6.C: New test.
	* g++.dg/reflect/init7.C: New test.
	* g++.dg/reflect/init8.C: New test.
	* g++.dg/reflect/init9.C: New test.
	* g++.dg/reflect/is_accessible1.C: New test.
	* g++.dg/reflect/is_accessible2.C: New test.
	* g++.dg/reflect/is_alias_template1.C: New test.
	* g++.dg/reflect/is_assignment1.C: New test.
	* g++.dg/reflect/is_bit_field1.C: New test.
	* g++.dg/reflect/is_class_member1.C: New test.
	* g++.dg/reflect/is_class_template1.C: New test.
	* g++.dg/reflect/is_complete_type1.C: New test.
	* g++.dg/reflect/is_complete_type2.C: New test.
	* g++.dg/reflect/is_concept1.C: New test.
	* g++.dg/reflect/is_const1.C: New test.
	* g++.dg/reflect/is_consteval_only1.C: New test.
	* g++.dg/reflect/is_constructible_type1.C: New test.
	* g++.dg/reflect/is_constructible_type2.C: New test.
	* g++.dg/reflect/is_constructor_template1.C: New test.
	* g++.dg/reflect/is_constuctor1.C: New test.
	* g++.dg/reflect/is_conversion_function1.C: New test.
	* g++.dg/reflect/is_conversion_function_template1.C: New test.
	* g++.dg/reflect/is_copy_assignment1.C: New test.
	* g++.dg/reflect/is_copy_constructor1.C: New test.
	* g++.dg/reflect/is_data_member_spec1.C: New test.
	* g++.dg/reflect/is_default_constructor1.C: New test.
	* g++.dg/reflect/is_defaulted1.C: New test.
	* g++.dg/reflect/is_defaulted2.C: New test.
	* g++.dg/reflect/is_deleted1.C: New test.
	* g++.dg/reflect/is_deleted2.C: New test.
	* g++.dg/reflect/is_destructor1.C: New test.
	* g++.dg/reflect/is_enumerable_type1.C: New test.
	* g++.dg/reflect/is_enumerator1.C: New test.
	* g++.dg/reflect/is_explicit1.C: New test.
	* g++.dg/reflect/is_explicit2.C: New test.
	* g++.dg/reflect/is_explicit_object_parameter1.C: New test.
	* g++.dg/reflect/is_final1.C: New test.
	* g++.dg/reflect/is_function1.C: New test.
	* g++.dg/reflect/is_function2.C: New test.
	* g++.dg/reflect/is_function3.C: New test.
	* g++.dg/reflect/is_function_parameter1.C: New test.
	* g++.dg/reflect/is_function_parameter2.C: New test.
	* g++.dg/reflect/is_function_template1.C: New test.
	* g++.dg/reflect/is_function_template2.C: New test.
	* g++.dg/reflect/is_function_type1.C: New test.
	* g++.dg/reflect/is_literal_operator1.C: New test.
	* g++.dg/reflect/is_literal_operator_template1.C: New test.
	* g++.dg/reflect/is_lrvalue_reference_qualified1.C: New test.
	* g++.dg/reflect/is_move_assignment1.C: New test.
	* g++.dg/reflect/is_move_constructor1.C: New test.
	* g++.dg/reflect/is_mutable_member1.C: New test.
	* g++.dg/reflect/is_namespace1.C: New test.
	* g++.dg/reflect/is_namespace_alias1.C: New test.
	* g++.dg/reflect/is_namespace_member1.C: New test.
	* g++.dg/reflect/is_noexcept1.C: New test.
	* g++.dg/reflect/is_noexcept2.C: New test.
	* g++.dg/reflect/is_noexcept3.C: New test.
	* g++.dg/reflect/is_noexcept4.C: New test.
	* g++.dg/reflect/is_nonstatic_data_member1.C: New test.
	* g++.dg/reflect/is_object1.C: New test.
	* g++.dg/reflect/is_object2.C: New test.
	* g++.dg/reflect/is_operator_function1.C: New test.
	* g++.dg/reflect/is_operator_function_template1.C: New test.
	* g++.dg/reflect/is_override1.C: New test.
	* g++.dg/reflect/is_pure_virtual1.C: New test.
	* g++.dg/reflect/is_special_member_function1.C: New test.
	* g++.dg/reflect/is_static_member1.C: New test.
	* g++.dg/reflect/is_string_literal1.C: New test.
	* g++.dg/reflect/is_structured_binding1.C: New test.
	* g++.dg/reflect/is_structured_binding2.C: New test.
	* g++.dg/reflect/is_template1.C: New test.
	* g++.dg/reflect/is_template2.C: New test.
	* g++.dg/reflect/is_type1.C: New test.
	* g++.dg/reflect/is_type_alias1.C: New test.
	* g++.dg/reflect/is_type_alias2.C: New test.
	* g++.dg/reflect/is_type_alias3.C: New test.
	* g++.dg/reflect/is_user_declared1.C: New test.
	* g++.dg/reflect/is_user_declared2.C: New test.
	* g++.dg/reflect/is_user_provided1.C: New test.
	* g++.dg/reflect/is_user_provided2.C: New test.
	* g++.dg/reflect/is_variable1.C: New test.
	* g++.dg/reflect/is_variable_template1.C: New test.
	* g++.dg/reflect/is_virtual1.C: New test.
	* g++.dg/reflect/is_volatile1.C: New test.
	* g++.dg/reflect/lex1.C: New test.
	* g++.dg/reflect/lex2.C: New test.
	* g++.dg/reflect/mangle1.C: New test.
	* g++.dg/reflect/member-visibility1.C: New test.
	* g++.dg/reflect/member-visibility2.C: New test.
	* g++.dg/reflect/member1.C: New test.
	* g++.dg/reflect/member10.C: New test.
	* g++.dg/reflect/member11.C: New test.
	* g++.dg/reflect/member12.C: New test.
	* g++.dg/reflect/member13.C: New test.
	* g++.dg/reflect/member14.C: New test.
	* g++.dg/reflect/member15.C: New test.
	* g++.dg/reflect/member16.C: New test.
	* g++.dg/reflect/member17.C: New test.
	* g++.dg/reflect/member18.C: New test.
	* g++.dg/reflect/member19.C: New test.
	* g++.dg/reflect/member2.C: New test.
	* g++.dg/reflect/member20.C: New test.
	* g++.dg/reflect/member3.C: New test.
	* g++.dg/reflect/member4.C: New test.
	* g++.dg/reflect/member5.C: New test.
	* g++.dg/reflect/member6.C: New test.
	* g++.dg/reflect/member7.C: New test.
	* g++.dg/reflect/member8.C: New test.
	* g++.dg/reflect/member9.C: New test.
	* g++.dg/reflect/members_of1.C: New test.
	* g++.dg/reflect/members_of2.C: New test.
	* g++.dg/reflect/members_of3.C: New test.
	* g++.dg/reflect/members_of4.C: New test.
	* g++.dg/reflect/members_of5.C: New test.
	* g++.dg/reflect/members_of6.C: New test.
	* g++.dg/reflect/members_of7.C: New test.
	* g++.dg/reflect/metafn-ptr1.C: New test.
	* g++.dg/reflect/ns1.C: New test.
	* g++.dg/reflect/ns2.C: New test.
	* g++.dg/reflect/ns3.C: New test.
	* g++.dg/reflect/ns4.C: New test.
	* g++.dg/reflect/ns5.C: New test.
	* g++.dg/reflect/ns6.C: New test.
	* g++.dg/reflect/null1.C: New test.
	* g++.dg/reflect/null2.C: New test.
	* g++.dg/reflect/null3.C: New test.
	* g++.dg/reflect/null4.C: New test.
	* g++.dg/reflect/null5.C: New test.
	* g++.dg/reflect/object_of1.C: New test.
	* g++.dg/reflect/object_of2.C: New test.
	* g++.dg/reflect/odr1.C: New test.
	* g++.dg/reflect/offset_of1.C: New test.
	* g++.dg/reflect/operator_of1.C: New test.
	* g++.dg/reflect/override1.C: New test.
	* g++.dg/reflect/p2996-1.C: New test.
	* g++.dg/reflect/p2996-10.C: New test.
	* g++.dg/reflect/p2996-11.C: New test.
	* g++.dg/reflect/p2996-12.C: New test.
	* g++.dg/reflect/p2996-13.C: New test.
	* g++.dg/reflect/p2996-14.C: New test.
	* g++.dg/reflect/p2996-15.C: New test.
	* g++.dg/reflect/p2996-16.C: New test.
	* g++.dg/reflect/p2996-17.C: New test.
	* g++.dg/reflect/p2996-18.C: New test.
	* g++.dg/reflect/p2996-19.C: New test.
	* g++.dg/reflect/p2996-2.C: New test.
	* g++.dg/reflect/p2996-20.C: New test.
	* g++.dg/reflect/p2996-21.C: New test.
	* g++.dg/reflect/p2996-3.C: New test.
	* g++.dg/reflect/p2996-4.C: New test.
	* g++.dg/reflect/p2996-5.C: New test.
	* g++.dg/reflect/p2996-6.C: New test.
	* g++.dg/reflect/p2996-7.C: New test.
	* g++.dg/reflect/p2996-8.C: New test.
	* g++.dg/reflect/p2996-9.C: New test.
	* g++.dg/reflect/p3394-1.C: New test.
	* g++.dg/reflect/p3491-1.C: New test.
	* g++.dg/reflect/p3491-2.C: New test.
	* g++.dg/reflect/p3491-3.C: New test.
	* g++.dg/reflect/pack-index1.C: New test.
	* g++.dg/reflect/parameters_of1.C: New test.
	* g++.dg/reflect/parameters_of2.C: New test.
	* g++.dg/reflect/parameters_of3.C: New test.
	* g++.dg/reflect/parameters_of4.C: New test.
	* g++.dg/reflect/parameters_of5.C: New test.
	* g++.dg/reflect/parameters_of6.C: New test.
	* g++.dg/reflect/parent_of1.C: New test.
	* g++.dg/reflect/parm1.C: New test.
	* g++.dg/reflect/parm2.C: New test.
	* g++.dg/reflect/parm3.C: New test.
	* g++.dg/reflect/parm4.C: New test.
	* g++.dg/reflect/pr122634-1.C: New test.
	* g++.dg/reflect/pr122634-2.C: New test.
	* g++.dg/reflect/qrn1.C: New test.
	* g++.dg/reflect/qrn2.C: New test.
	* g++.dg/reflect/range_args.C: New test.
	* g++.dg/reflect/reflect_constant1.C: New test.
	* g++.dg/reflect/reflect_constant2.C: New test.
	* g++.dg/reflect/reflect_constant3.C: New test.
	* g++.dg/reflect/reflect_constant4.C: New test.
	* g++.dg/reflect/reflect_constant5.C: New test.
	* g++.dg/reflect/reflect_constant6.C: New test.
	* g++.dg/reflect/reflect_constant7.C: New test.
	* g++.dg/reflect/reflect_constant8.C: New test.
	* g++.dg/reflect/reflect_constant9.C: New test.
	* g++.dg/reflect/reflect_constant_array1.C: New test.
	* g++.dg/reflect/reflect_constant_array2.C: New test.
	* g++.dg/reflect/reflect_constant_array3.C: New test.
	* g++.dg/reflect/reflect_constant_array4.C: New test.
	* g++.dg/reflect/reflect_constant_string1.C: New test.
	* g++.dg/reflect/reflect_constant_string2.C: New test.
	* g++.dg/reflect/reflect_function1.C: New test.
	* g++.dg/reflect/reflect_function2.C: New test.
	* g++.dg/reflect/reflect_object1.C: New test.
	* g++.dg/reflect/reflect_object2.C: New test.
	* g++.dg/reflect/reflect_object3.C: New test.
	* g++.dg/reflect/reflect_object4.C: New test.
	* g++.dg/reflect/return_type_of1.C: New test.
	* g++.dg/reflect/return_type_of2.C: New test.
	* g++.dg/reflect/serialize1.C: New test.
	* g++.dg/reflect/serialize2.C: New test.
	* g++.dg/reflect/size_of1.C: New test.
	* g++.dg/reflect/source_location_of1.C: New test.
	* g++.dg/reflect/source_location_of2.C: New test.
	* g++.dg/reflect/splice1.C: New test.
	* g++.dg/reflect/splice2.C: New test.
	* g++.dg/reflect/splice3.C: New test.
	* g++.dg/reflect/splice4.C: New test.
	* g++.dg/reflect/splice5.C: New test.
	* g++.dg/reflect/splice6.C: New test.
	* g++.dg/reflect/splice7.C: New test.
	* g++.dg/reflect/splicing-base1.C: New test.
	* g++.dg/reflect/splicing-base2.C: New test.
	* g++.dg/reflect/splicing-base3.C: New test.
	* g++.dg/reflect/splicing-base4.C: New test.
	* g++.dg/reflect/storage_duration1.C: New test.
	* g++.dg/reflect/storage_duration2.C: New test.
	* g++.dg/reflect/storage_duration3.C: New test.
	* g++.dg/reflect/subobjects_of1.C: New test.
	* g++.dg/reflect/substitute1.C: New test.
	* g++.dg/reflect/substitute2.C: New test.
	* g++.dg/reflect/symbol_of1.C: New test.
	* g++.dg/reflect/symbol_of2.C: New test.
	* g++.dg/reflect/template_arguments_of1.C: New test.
	* g++.dg/reflect/template_arguments_of2.C: New test.
	* g++.dg/reflect/template_arguments_of3.C: New test.
	* g++.dg/reflect/template_of1.C: New test.
	* g++.dg/reflect/template_of2.C: New test.
	* g++.dg/reflect/template_of3.C: New test.
	* g++.dg/reflect/tuple1.C: New test.
	* g++.dg/reflect/tuple2.C: New test.
	* g++.dg/reflect/type1.C: New test.
	* g++.dg/reflect/type10.C: New test.
	* g++.dg/reflect/type2.C: New test.
	* g++.dg/reflect/type3.C: New test.
	* g++.dg/reflect/type4.C: New test.
	* g++.dg/reflect/type5.C: New test.
	* g++.dg/reflect/type6.C: New test.
	* g++.dg/reflect/type7.C: New test.
	* g++.dg/reflect/type8.C: New test.
	* g++.dg/reflect/type9.C: New test.
	* g++.dg/reflect/type_of1.C: New test.
	* g++.dg/reflect/type_of2.C: New test.
	* g++.dg/reflect/type_rels1.C: New test.
	* g++.dg/reflect/type_trait1.C: New test.
	* g++.dg/reflect/type_trait10.C: New test.
	* g++.dg/reflect/type_trait11.C: New test.
	* g++.dg/reflect/type_trait12.C: New test.
	* g++.dg/reflect/type_trait13.C: New test.
	* g++.dg/reflect/type_trait2.C: New test.
	* g++.dg/reflect/type_trait3.C: New test.
	* g++.dg/reflect/type_trait4.C: New test.
	* g++.dg/reflect/type_trait5.C: New test.
	* g++.dg/reflect/type_trait6.C: New test.
	* g++.dg/reflect/type_trait8.C: New test.
	* g++.dg/reflect/type_trait9.C: New test.
	* g++.dg/reflect/u8display_string_of1.C: New test.
	* g++.dg/reflect/u8identifier_of1.C: New test.
	* g++.dg/reflect/u8symbol_of1.C: New test.
	* g++.dg/reflect/underlying_type1.C: New test.
	* g++.dg/reflect/using1.C: New test.
	* g++.dg/reflect/value_or_object1.C: New test.
	* g++.dg/reflect/variable_of1.C: New test.
	* g++.dg/reflect/variable_of2.C: New test.
	* g++.dg/reflect/variable_of3.C: New test.
	* g++.dg/reflect/variant1.C: New test.
	* g++.dg/reflect/variant2.C: New test.
	* g++.dg/reflect/vector1.C: New test.
	* g++.dg/reflect/visibility1.C: New test.

Co-authored-by: Jakub Jelinek <jakub@redhat.com>
Signed-off-by: Valentyn Yukhymenko <vyuhimenko@bloomberg.net>
Signed-off-by: Alex Yesmanchyk <ayesmanchyk@bloomberg.net>
Signed-off-by: Michael Levine <mlevine55@bloomberg.net>
Reviewed-by: Jason Merrill <jason@redhat.com>
2026-01-15 10:17:43 -05:00

654 lines
22 KiB
C++

// <meta> -*- C++ -*-
// Copyright (C) 2025-2026 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/meta
* This is a Standard C++ Library header.
*/
#ifndef _GLIBCXX_META
#define _GLIBCXX_META 1
#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif
#define __glibcxx_want_reflection
#include <bits/version.h>
#if __glibcxx_reflection >= 202506L // C++ >= 26 && __cpp_impl_reflection
#include <array>
#include <initializer_list>
#include <optional>
#include <source_location>
#include <span>
#include <string>
#include <string_view>
#include <vector>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __has_builtin(__builtin_is_string_literal)
// [meta.string.literal], checking string literals
consteval bool is_string_literal(const char* __p)
{
return __builtin_is_string_literal(__p);
}
consteval bool is_string_literal(const wchar_t* __p)
{
return __builtin_is_string_literal(__p);
}
#ifdef _GLIBCXX_USE_CHAR8_T
consteval bool is_string_literal(const char8_t* __p)
{
return __builtin_is_string_literal(__p);
}
#endif
consteval bool is_string_literal(const char16_t* __p)
{
return __builtin_is_string_literal(__p);
}
consteval bool is_string_literal(const char32_t* __p)
{
return __builtin_is_string_literal(__p);
}
#endif
namespace meta
{
using info = decltype(^^int);
// [meta.reflection.exception], class exception
class exception : public std::exception {
private:
string _M_what;
u8string _M_u8what;
info _M_from;
source_location _M_where;
public:
consteval
exception(u8string_view __what, info __from,
source_location __where = source_location::current()) noexcept
: _M_what{_S_exception_cvt_from_utf8(__what)}, _M_u8what{__what},
_M_from{__from}, _M_where{__where} {}
consteval
exception(string_view __what, info __from,
source_location __where = source_location::current()) noexcept
: _M_what{__what}, _M_u8what{_S_exception_cvt_to_utf8(__what)},
_M_from{__from}, _M_where{__where} {}
consteval exception(const exception&) = default;
consteval exception(exception&&) = default;
consteval exception& operator=(const exception&) = default;
consteval exception& operator=(exception&&) = default;
consteval const char*
what() const noexcept override
{
// If u8string is not empty and string is empty, conversion
// from UTF-8 to ordinary literal encoding failed.
// In that case what() should be non-constant.
if (_M_what.size() == 0 && _M_u8what.size() != 0)
asm("");
return _M_what.c_str();
}
consteval u8string_view u8what() const noexcept { return _M_u8what; }
consteval info from() const noexcept { return _M_from; }
consteval source_location where() const noexcept { return _M_where; }
private:
// Helper special template metafunctions to convert from UTF-8 to
// ordinary literal encoding and vice versa. On conversion failure
// they just return an empty {,u8}string_view.
template<ranges::input_range _Rg>
static consteval u8string_view _S_exception_cvt_to_utf8(_Rg&&);
template<ranges::input_range _Rg>
static consteval string_view _S_exception_cvt_from_utf8(_Rg&&);
};
// [meta.reflection.operators], operator representations
enum class operators {
op_new = 1,
op_delete,
op_array_new,
op_array_delete,
op_co_await,
op_parentheses,
op_square_brackets,
op_arrow,
op_arrow_star,
op_tilde,
op_exclamation,
op_plus,
op_minus,
op_star,
op_slash,
op_percent,
op_caret,
op_ampersand,
op_equals,
op_pipe,
op_plus_equals,
op_minus_equals,
op_star_equals,
op_slash_equals,
op_percent_equals,
op_caret_equals,
op_ampersand_equals,
op_pipe_equals,
op_equals_equals,
op_exclamation_equals,
op_less,
op_greater,
op_less_equals,
op_greater_equals,
op_spaceship,
op_ampersand_ampersand,
op_pipe_pipe,
op_less_less,
op_greater_greater,
op_less_less_equals,
op_greater_greater_equals,
op_plus_plus,
op_minus_minus,
op_comma
};
using enum operators;
consteval operators operator_of(info);
consteval string_view symbol_of(operators);
consteval u8string_view u8symbol_of(operators);
// [meta.reflection.names], reflection names and locations
consteval bool has_identifier(info);
consteval string_view identifier_of(info);
consteval u8string_view u8identifier_of(info);
consteval string_view display_string_of(info);
consteval u8string_view u8display_string_of(info);
consteval source_location source_location_of(info);
// [meta.reflection.queries], reflection queries
consteval info type_of(info);
consteval info object_of(info);
consteval info constant_of(info);
consteval bool is_public(info);
consteval bool is_protected(info);
consteval bool is_private(info);
consteval bool is_virtual(info);
consteval bool is_pure_virtual(info);
consteval bool is_override(info);
consteval bool is_final(info);
consteval bool is_deleted(info);
consteval bool is_defaulted(info);
consteval bool is_user_provided(info);
consteval bool is_user_declared(info);
consteval bool is_explicit(info);
consteval bool is_noexcept(info);
consteval bool is_bit_field(info);
consteval bool is_enumerator(info);
consteval bool is_annotation(info);
consteval bool is_const(info);
consteval bool is_volatile(info);
consteval bool is_mutable_member(info);
consteval bool is_lvalue_reference_qualified(info);
consteval bool is_rvalue_reference_qualified(info);
consteval bool has_static_storage_duration(info);
consteval bool has_thread_storage_duration(info);
consteval bool has_automatic_storage_duration(info);
consteval bool has_internal_linkage(info);
consteval bool has_module_linkage(info);
consteval bool has_external_linkage(info);
consteval bool has_c_language_linkage(info);
consteval bool has_linkage(info);
consteval bool is_complete_type(info);
consteval bool is_enumerable_type(info);
consteval bool is_variable(info);
consteval bool is_type(info);
consteval bool is_namespace(info);
consteval bool is_type_alias(info);
consteval bool is_namespace_alias(info);
consteval bool is_function(info);
consteval bool is_conversion_function(info);
consteval bool is_operator_function(info);
consteval bool is_literal_operator(info);
consteval bool is_special_member_function(info);
consteval bool is_constructor(info);
consteval bool is_default_constructor(info);
consteval bool is_copy_constructor(info);
consteval bool is_move_constructor(info);
consteval bool is_assignment(info);
consteval bool is_copy_assignment(info);
consteval bool is_move_assignment(info);
consteval bool is_destructor(info);
consteval bool is_function_parameter(info);
consteval bool is_explicit_object_parameter(info);
consteval bool has_default_argument(info);
consteval bool has_ellipsis_parameter(info);
consteval bool is_template(info);
consteval bool is_function_template(info);
consteval bool is_variable_template(info);
consteval bool is_class_template(info);
consteval bool is_alias_template(info);
consteval bool is_conversion_function_template(info);
consteval bool is_operator_function_template(info);
consteval bool is_literal_operator_template(info);
consteval bool is_constructor_template(info);
consteval bool is_concept(info);
consteval bool is_value(info);
consteval bool is_object(info);
consteval bool is_structured_binding(info);
consteval bool is_class_member(info);
consteval bool is_namespace_member(info);
consteval bool is_nonstatic_data_member(info);
consteval bool is_static_member(info);
consteval bool is_base(info);
consteval bool has_default_member_initializer(info);
consteval bool has_parent(info);
consteval info parent_of(info);
consteval info dealias(info);
consteval bool has_template_arguments(info);
consteval info template_of(info);
consteval vector<info> template_arguments_of(info);
consteval vector<info> parameters_of(info);
consteval info variable_of(info);
consteval info return_type_of(info);
// [meta.reflection.access.context], access control context
struct access_context {
private:
consteval access_context(info __scope, info __designating_class) noexcept
: _M_scope{__scope}, _M_designating_class{__designating_class} { }
public:
access_context() = delete;
consteval access_context(const access_context &) = default;
consteval access_context(access_context &&) = default;
consteval info scope() const { return _M_scope; }
consteval info designating_class() const { return _M_designating_class; }
static consteval access_context current() noexcept;
static consteval access_context unprivileged() noexcept
{ return access_context { ^^::, info {} }; }
static consteval access_context unchecked() noexcept
{ return access_context { info {}, info {} }; }
consteval access_context via(info) const;
info _M_scope;
info _M_designating_class;
};
// [meta.reflection.access.queries], member accessibility queries
consteval bool is_accessible(info, access_context);
consteval bool has_inaccessible_nonstatic_data_members(info,
access_context);
consteval bool has_inaccessible_bases(info, access_context);
consteval bool has_inaccessible_subobjects(info, access_context);
// [meta.reflection.member.queries], reflection member queries
consteval vector<info> members_of(info, access_context);
consteval vector<info> bases_of(info, access_context);
consteval vector<info> static_data_members_of(info, access_context);
consteval vector<info> nonstatic_data_members_of(info, access_context);
consteval vector<info> subobjects_of(info, access_context);
consteval vector<info> enumerators_of(info);
// [meta.reflection.layout], reflection layout queries
struct member_offset {
ptrdiff_t bytes;
ptrdiff_t bits;
constexpr ptrdiff_t
total_bits() const
{ return bytes * __CHAR_BIT__ + bits; }
auto operator<=>(const member_offset&) const = default;
};
consteval member_offset offset_of(info);
consteval size_t size_of(info);
consteval size_t alignment_of(info);
consteval size_t bit_size_of(info);
// [meta.reflection.extract], value extraction
template<class _Tp>
consteval _Tp extract(info);
// [meta.reflection.substitute], reflection substitution
template<class _Rg>
concept reflection_range = ranges::input_range<_Rg>
&& same_as<ranges::range_value_t<_Rg>, info>
&& same_as<remove_cvref_t<ranges::range_reference_t<_Rg>>, info>;
template<reflection_range _Rg = initializer_list<info>>
consteval bool can_substitute(info, _Rg&&);
template<reflection_range _Rg = initializer_list<info>>
consteval info substitute(info, _Rg&&);
// [meta.reflection.result], expression result reflection
template<typename _Tp>
requires (is_copy_constructible_v<_Tp>)
consteval info reflect_constant(_Tp);
template<typename _Tp>
requires (!is_function_v<remove_reference_t<_Tp>>)
consteval info reflect_object(_Tp&);
template<typename _Tp>
requires (is_function_v<remove_reference_t<_Tp>>)
consteval info reflect_function(_Tp&);
// [meta.reflection.array], promoting to static storage arrays
template<ranges::input_range _Rg>
consteval info reflect_constant_string(_Rg&&);
template<ranges::input_range _Rg>
consteval info reflect_constant_array(_Rg&&);
// [meta.reflection.define.aggregate], class definition generation
struct data_member_options {
struct _Name {
template<class _Tp>
requires constructible_from<u8string, _Tp>
consteval _Name(_Tp&& __n) : _M_is_u8(true), _M_u8s((_Tp&&) __n) {}
template<class _Tp>
requires constructible_from<string, _Tp>
consteval _Name(_Tp&& __n) : _M_is_u8(false), _M_s((_Tp&&) __n) {}
private:
bool _M_is_u8;
u8string _M_u8s;
string _M_s;
info _M_unused = {};
};
optional<_Name> name;
optional<int> alignment;
optional<int> bit_width;
bool no_unique_address = false;
};
consteval info data_member_spec(info, data_member_options);
consteval bool is_data_member_spec(info);
template<reflection_range _Rg = initializer_list<info>>
consteval info define_aggregate(info, _Rg&&);
// associated with [meta.unary.cat], primary type categories
consteval bool is_void_type(info);
consteval bool is_null_pointer_type(info);
consteval bool is_integral_type(info);
consteval bool is_floating_point_type(info);
consteval bool is_array_type(info);
consteval bool is_pointer_type(info);
consteval bool is_lvalue_reference_type(info);
consteval bool is_rvalue_reference_type(info);
consteval bool is_member_object_pointer_type(info);
consteval bool is_member_function_pointer_type(info);
consteval bool is_enum_type(info);
consteval bool is_union_type(info);
consteval bool is_class_type(info);
consteval bool is_function_type(info);
consteval bool is_reflection_type(info);
// associated with [meta.unary.comp], composite type categories
consteval bool is_reference_type(info);
consteval bool is_arithmetic_type(info);
consteval bool is_fundamental_type(info);
consteval bool is_object_type(info);
consteval bool is_scalar_type(info);
consteval bool is_compound_type(info);
consteval bool is_member_pointer_type(info);
// associated with [meta.unary.prop], type properties
consteval bool is_const_type(info);
consteval bool is_volatile_type(info);
consteval bool is_trivially_copyable_type(info);
consteval bool is_standard_layout_type(info);
consteval bool is_empty_type(info);
consteval bool is_polymorphic_type(info);
consteval bool is_abstract_type(info);
consteval bool is_final_type(info);
consteval bool is_aggregate_type(info);
consteval bool is_consteval_only_type(info);
consteval bool is_signed_type(info);
consteval bool is_unsigned_type(info);
consteval bool is_bounded_array_type(info);
consteval bool is_unbounded_array_type(info);
consteval bool is_scoped_enum_type(info);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_constructible_type(info, _Rg&&);
consteval bool is_default_constructible_type(info);
consteval bool is_copy_constructible_type(info);
consteval bool is_move_constructible_type(info);
consteval bool is_assignable_type(info, info);
consteval bool is_copy_assignable_type(info);
consteval bool is_move_assignable_type(info);
consteval bool is_swappable_with_type(info, info);
consteval bool is_swappable_type(info);
consteval bool is_destructible_type(info);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_trivially_constructible_type(info, _Rg&&);
consteval bool is_trivially_default_constructible_type(info);
consteval bool is_trivially_copy_constructible_type(info);
consteval bool is_trivially_move_constructible_type(info);
consteval bool is_trivially_assignable_type(info, info);
consteval bool is_trivially_copy_assignable_type(info);
consteval bool is_trivially_move_assignable_type(info);
consteval bool is_trivially_destructible_type(info);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_nothrow_constructible_type(info, _Rg&&);
consteval bool is_nothrow_default_constructible_type(info);
consteval bool is_nothrow_copy_constructible_type(info);
consteval bool is_nothrow_move_constructible_type(info);
consteval bool is_nothrow_assignable_type(info, info);
consteval bool is_nothrow_copy_assignable_type(info);
consteval bool is_nothrow_move_assignable_type(info);
consteval bool is_nothrow_swappable_with_type(info, info);
consteval bool is_nothrow_swappable_type(info);
consteval bool is_nothrow_destructible_type(info);
consteval bool is_implicit_lifetime_type(info);
consteval bool has_virtual_destructor(info);
consteval bool has_unique_object_representations(info);
consteval bool reference_constructs_from_temporary(info, info);
consteval bool reference_converts_from_temporary(info, info);
// associated with [meta.unary.prop.query], type property queries
consteval size_t rank(info);
consteval size_t extent(info, unsigned = 0);
// associated with [meta.rel], type relations
consteval bool is_same_type(info, info);
consteval bool is_base_of_type(info, info);
consteval bool is_virtual_base_of_type(info, info);
consteval bool is_convertible_type(info, info);
consteval bool is_nothrow_convertible_type(info, info);
consteval bool is_layout_compatible_type(info, info);
consteval bool is_pointer_interconvertible_base_of_type(info, info);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_invocable_type(info, _Rg&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_invocable_r_type(info, info, _Rg&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_nothrow_invocable_type(info, _Rg&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_nothrow_invocable_r_type(info, info, _Rg&&);
// associated with [meta.trans.cv], const-volatile modifications
consteval info remove_const(info);
consteval info remove_volatile(info);
consteval info remove_cv(info);
consteval info add_const(info);
consteval info add_volatile(info);
consteval info add_cv(info);
// associated with [meta.trans.ref], reference modifications
consteval info remove_reference(info);
consteval info add_lvalue_reference(info);
consteval info add_rvalue_reference(info);
// associated with [meta.trans.sign], sign modifications
consteval info make_signed(info);
consteval info make_unsigned(info);
// associated with [meta.trans.arr], array modifications
consteval info remove_extent(info);
consteval info remove_all_extents(info);
// associated with [meta.trans.ptr], pointer modifications
consteval info remove_pointer(info);
consteval info add_pointer(info);
// associated with [meta.trans.other], other transformations
consteval info remove_cvref(info);
consteval info decay(info);
template<reflection_range _Rg = initializer_list<info>>
consteval info common_type(_Rg&&);
template<reflection_range _Rg = initializer_list<info>>
consteval info common_reference(_Rg&&);
consteval info underlying_type(info);
template<reflection_range _Rg = initializer_list<info>>
consteval info invoke_result(info, _Rg&&);
consteval info unwrap_reference(info);
consteval info unwrap_ref_decay(info);
consteval size_t tuple_size(info);
consteval info tuple_element(size_t, info);
consteval size_t variant_size(info);
consteval info variant_alternative(size_t, info);
consteval strong_ordering type_order(info, info);
// [meta.reflection.annotation], annotation reflection
consteval vector<info> annotations_of(info);
consteval vector<info> annotations_of_with_type(info, info);
consteval access_context
access_context::via(info __cls) const
{
if (__cls != info {}
&& (!std::meta::is_class_type(__cls)
|| !std::meta::is_complete_type(__cls)))
{
#if __cpp_exceptions
throw std::meta::exception(u8"via argument other than null "
"or complete class type reflection",
^^access_context::via);
#else
asm("");
return *this;
#endif
}
return access_context { _M_scope, __cls };
}
} // namespace meta
// [meta.define.static], promoting to static storage strings
template<ranges::input_range _Rg>
consteval const ranges::range_value_t<_Rg>*
define_static_string(_Rg&& __r)
{
auto __str = meta::reflect_constant_string(__r);
return meta::extract<const ranges::range_value_t<_Rg>*>(__str);
}
template<ranges::input_range _Rg>
consteval span<const ranges::range_value_t<_Rg>>
define_static_array(_Rg&& __r)
{
using _Tp = ranges::range_value_t<_Rg>;
auto __array = meta::reflect_constant_array(__r);
auto __type = meta::type_of(__array);
if (meta::is_array_type(__type))
return span<const _Tp>(meta::extract<const _Tp*>(__array),
meta::extent(__type, 0U));
else
return span<const _Tp>();
}
template<class _Tp>
consteval const remove_cvref_t<_Tp>*
define_static_object(_Tp&& __t)
{
using _Up = remove_cvref_t<_Tp>;
if constexpr (meta::is_class_type(^^_Up))
{
auto __cst = meta::reflect_constant(std::forward<_Tp>(__t));
return std::addressof(meta::extract<const _Up&>(__cst));
}
else
return std::define_static_array(span<const _Up>(std::addressof(__t),
1)).data();
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++26
#endif // _GLIBCXX_META