| // <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 | |
| #define __glibcxx_want_define_static | |
| #include <bits/version.h> | |
| #if __glibcxx_reflection >= 202603L // 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; | |
| constexpr 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) | |
| #if __has_builtin(__builtin_constexpr_diag) | |
| __builtin_constexpr_diag (2, "", | |
| "std::meta::exception message could not " | |
| "be successfully transcoded from UTF-8 to " | |
| "ordinary literal encoding"); | |
| #else | |
| __asm__(""); | |
| #endif | |
| 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 is_vararg_function(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.scope], scope identification | |
| consteval info current_function(); | |
| consteval info current_class(); | |
| consteval info current_namespace(); | |
| // [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; | |
| vector<info> annotations = {}; | |
| }; | |
| 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); | |
| #if __glibcxx_is_structural >= 202603L | |
| consteval bool is_structural_type(info); | |
| #endif | |
| 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_type(__cls) | |
| || !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 | |
| #if __has_builtin(__builtin_constexpr_diag) | |
| __builtin_constexpr_diag (2, "", | |
| "std::meta::access_context::via argument " | |
| "other than null or complete class type " | |
| "reflection"); | |
| #else | |
| __asm__(""); | |
| #endif | |
| 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 auto | |
| 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 constexpr (ranges::__static_sized_range<_Rg>) | |
| { | |
| constexpr size_t __extent = static_cast<size_t>(ranges::size(__r)); | |
| if constexpr (__extent) | |
| return span<const _Tp, | |
| __extent>(meta::extract<const _Tp*>(__array), | |
| meta::extent(__type, 0U)); | |
| else | |
| return span<const _Tp, 0>(); | |
| } | |
| else | |
| { | |
| 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) || meta::is_union_type(^^_Up)) | |
| { | |
| auto __cst = meta::reflect_constant(std::forward<_Tp>(__t)); | |
| return std::addressof(meta::extract<const _Up&>(__cst)); | |
| } | |
| else if constexpr (meta::is_array_type(^^_Up)) | |
| { | |
| auto __cst = meta::reflect_constant_array(std::forward<_Tp>(__t)); | |
| return std::addressof(meta::extract<const _Up&>(__cst)); | |
| } | |
| else | |
| return std::define_static_array(span(std::addressof(__t), 1)).data(); | |
| } | |
| _GLIBCXX_END_NAMESPACE_VERSION | |
| } // namespace std | |
| #endif // C++26 | |
| #endif // _GLIBCXX_META |