Subclause  | Header  | |
Integer sequences  | <utility>  | |
Type traits  | <type_traits>  | |
Reflection  | <meta>  | |
Rational arithmetic  | <ratio>  | 
template<class T, T N>
  using make_integer_sequence = integer_sequence<T, see below>;
constexpr cw-fixed-value(T (&arr)[Extent]) noexcept;
Template  | Condition  | Comments  | 
T is void  | ||
T is an integral type ([basic.fundamental])  | ||
T is a floating-point type ([basic.fundamental])  | ||
T is an array type ([basic.compound]) of known or unknown extent  | ||
T is a pointer type ([basic.compound])  | Includes pointers to functions
but not pointers to non-static members.  | |
T is an lvalue reference type ([dcl.ref])  | ||
T is an rvalue reference type ([dcl.ref])  | ||
T is a pointer to data member  | ||
T is a pointer to member function  | ||
T is an enumeration type ([basic.compound])  | ||
T is a union type ([basic.compound])  | ||
T is a non-union class type ([basic.compound])  | ||
T is a function type ([basic.compound])  | ||
Template  | Condition  | Comments  | 
T is an lvalue reference or an rvalue reference  | ||
T is an arithmetic type ([basic.fundamental])  | ||
T is a fundamental type ([basic.fundamental])  | ||
T is an object type ([basic.types.general])  | ||
T is a scalar type ([basic.types.general])  | ||
T is a compound type ([basic.compound])  | ||
T is a pointer-to-member type ([basic.compound])  | 
Template  | Condition  | Preconditions  | 
T is const-qualified ([basic.type.qualifier])  | ||
T is volatile-qualified ([basic.type.qualifier])  | ||
T is a trivially copyable type ([basic.types.general])  | ||
T is a trivially relocatable type ([basic.types.general])  | ||
T is a replaceable type ([basic.types.general])  | ||
T is a standard-layout type ([basic.types.general])  | ||
T is a class type, but not a union type, with no non-static data
 members other than subobjects of zero size, no virtual member functions,
 no virtual base classes, and no base class B for
 which is_empty_v<B> is false.  | ||
T is a polymorphic class ([class.virtual])  | ||
T is an abstract class ([class.abstract])  | ||
T is an aggregate type ([dcl.init.aggr])  | ||
T is consteval-only ([basic.types.general])  | ||
If is_arithmetic_v<T> is true, the same result as
  T(-1) < T(0);
  otherwise, false  | ||
If is_arithmetic_v<T> is true, the same result as
  T(0) < T(-1);
  otherwise, false  | ||
T is an array type of known bound ([dcl.array])  | ||
T is an array type of unknown bound ([dcl.array])  | ||
T is a scoped enumeration ([dcl.enum])  | ||
For a function type T or
 for a cv void type T,
 is_constructible_v<T, Args...> is false,
 otherwise see below  | T and all types in the template parameter pack Args
 shall be complete types, cv void,
 or arrays of unknown bound.  | |
For a referenceable type T ([defns.referenceable]), the same result as
  is_constructible_v<T, const T&>, otherwise false.  | ||
The expression declval<T>() = declval<U>() is well-formed
  when treated as an unevaluated
  operand ([expr.context]).   Only the validity of the immediate context
  of the assignment expression is considered.  [Note 3:  The compilation of the
  expression can result in side effects such as the instantiation of class template
  specializations and function template specializations, the generation of
  implicitly-defined functions, and so on.  Such side effects are not in the “immediate
  context” and can result in the program being ill-formed.  — end note] | ||
The expressions swap(declval<T>(), declval<U>()) and
  swap(declval<U>(), declval<T>()) are each well-formed
  when treated as an unevaluated operand ([expr.context])
  in an overload-resolution context
  for swappable values ([swappable.requirements]).   Only the validity of the immediate context
  of the swap expressions is considered.  [Note 4:  The compilation of the expressions can result in side effects
  such as the instantiation of class template specializations and
  function template specializations,
  the generation of implicitly-defined functions, and so on.  Such side effects are not in the “immediate context” and
  can result in the program being ill-formed.  — end note] | ||
Either T is a reference type,
  or T is a complete object type
  for which the expression
  declval<U&>().~U()
  is well-formed
  when treated as an unevaluated operand ([expr.context]),
  where U is
  remove_all_extents_t<T>.  | ||
is_constructible_v<T, Args...> is true and the variable definition for is_constructible, as defined below, is known to call no operation that is not trivial ([depr.meta.types], [special]).  | T and all types in the template parameter pack Args shall be complete types,
  cv void, or arrays of unknown bound.  | |
For a referenceable type T, the same result as
 is_trivially_constructible_v<T, const T&>, otherwise false.  | ||
For a referenceable type T, the same result as
 is_trivially_constructible_v<T, T&&>, otherwise false.  | ||
is_assignable_v<T, U> is true and the assignment, as defined by
  is_assignable, is known to call no operation that is not
  trivial ([depr.meta.types], [special]).  | ||
For a referenceable type T, the same result as
 is_trivially_assignable_v<T&, const T&>, otherwise false.  | ||
is_destructible_v<T> is true and
 remove_all_extents_t<T> is either a non-class type or
 a class type with a trivial destructor.  | ||
is_constructible_v<T,  Args...> is true
 and the
 variable definition for is_constructible, as defined below, is known not to
 throw any exceptions ([expr.unary.noexcept]).  | T and all types in the template parameter pack Args
 shall be complete types, cv void,
 or arrays of unknown bound.  | |
For a referenceable type T, the same result as
 is_nothrow_constructible_v<T, const T&>, otherwise false.  | ||
is_assignable_v<T, U> is true and the assignment is known not to
  throw any exceptions ([expr.unary.noexcept]).  | ||
For a referenceable type T, the same result as
 is_nothrow_assignable_v<T&, const T&>, otherwise false.  | ||
is_swappable_with_v<T, U> is true and
  each swap expression of the definition of
  is_swappable_with<T, U> is known not to throw
  any exceptions ([expr.unary.noexcept]).  | ||
For a referenceable type T,
  the same result as is_nothrow_swappable_with_v<T&, T&>,
  otherwise false.  | ||
is_destructible_v<T> is true and the indicated destructor is known
  not to throw any exceptions ([expr.unary.noexcept]).  | ||
is_trivially_relocatable_v<T> ||
 (is_nothrow_move_constructible_v<
 remove_all_extents_t<T>> && is_nothrow_destructible_v<
 remove_all_extents_t<T>>)  | ||
T has a virtual destructor ([class.dtor])  | ||
For an array type T, the same result as
  has_unique_object_representations_v<remove_all_extents_t<T>>,
  otherwise see below.  | ||
T is a reference type, and
  the initialization T t(VAL<U>); is
  well-formed and binds t to
  a temporary object whose lifetime is extended ([class.temporary]).   Only the validity of the immediate context of
  the variable initialization is considered.  [Note 5:  The initialization can result in effects such as
  the instantiation of class template specializations and
  function template specializations,
  the generation of implicitly-defined functions, and so on.  Such effects are not in the “immediate context” and
  can result in the program being ill-formed.  — end note] | ||
T is a reference type, and
  the initialization T t = VAL<U>;
  is well-formed and binds t to
  a temporary object whose lifetime is extended ([class.temporary]).   Only the validity of the immediate context of
  the variable initialization is considered.  [Note 6:  The initialization can result in effects such as
  the instantiation of class template specializations and
  function template specializations,
  the generation of implicitly-defined functions, and so on.  Such effects are not in the “immediate context” and
  can result in the program being ill-formed.  — end note] | 
Template  | Value  | 
alignof(T).   | |
If T is not an array type, or if it has rank less
 than or equal to I, or if I is 0 and T
 has type “array of unknown bound of U”, then
 0; otherwise, the bound ([dcl.array]) of the  dimension of
T, where indexing of I is zero-based  | 
Template  | Condition  | Comments  | 
T and U name the same type with the same cv-qualifications  | ||
Base is a base class of Derived ([class.derived])
 without regard to cv-qualifiers
 or Base and Derived are not unions and
 name the same class type
 without regard to cv-qualifiers  | ||
see below  | ||
is_convertible_v<From, To> is true and
 the conversion, as defined by is_convertible,
 is known not to throw any exceptions ([expr.unary.noexcept])  | ||
Derived is unambiguously derived from Base
 without regard to cv-qualifiers,
 and each object of type Derived
 is pointer-interconvertible ([basic.compound]) with
 its Base subobject,
 or Base and Derived are not unions
 and name the same class type
 without regard to cv-qualifiers.  | If Base and Derived are non-union class types
 and are not (possibly cv-qualified versions of) the same type,
 Derived shall be a complete type.  | |
The expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) ([func.require])
 is well-formed when treated as an unevaluated operand ([expr.context])  | Fn and all types in the template parameter pack ArgTypes
 shall be complete types, cv void, or
 arrays of unknown bound.  | |
The expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...)
 is well-formed when treated as an unevaluated operand  | Fn, R, and all types in the template parameter pack ArgTypes
 shall be complete types, cv void, or
 arrays of unknown bound.  | |
is_invocable_v< Fn, ArgTypes...> is true and the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions ([expr.unary.noexcept])  | Fn and all types in the template parameter pack ArgTypes
 shall be complete types, cv void, or
 arrays of unknown bound.  | |
is_invocable_r_v< R, Fn, ArgTypes...> is true and the expression INVOKE<R>(declval<Fn>(), declval<ArgTypes>()...) is known not to throw any exceptions ([expr.unary.noexcept])  | Fn, R, and all types in the template parameter pack ArgTypes
 shall be complete types, cv void, or
 arrays of unknown bound.  | |
tuple-like<Tuple> is true and
 the expression
 INVOKE(declval<Fn>(), ELEMS-OF(Tuple)...)
 is well-formed when treated as an unevaluated operand.  | ||
is_applicable_v< Fn, Tuple> is true and the expression INVOKE(declval<Fn>(), ELEMS-OF(Tuple)...) is known not to throw any exceptions ([expr.unary.noexcept]).  | 
Template  | Comments  | 
If T is a referenceable type ([defns.referenceable]) then
 the member typedef type denotes T&;
 otherwise, type denotes T.   | |
Template  | Comments  | 
If T is a (possibly cv-qualified) signed integer
 type ([basic.fundamental]) then the member typedef
 type denotes T; otherwise,
 if T is a (possibly cv-qualified) unsigned integer
 type then type denotes the corresponding
 signed integer type, with the same cv-qualifiers as T;
 otherwise, type denotes the signed integer type with smallest
 rank ([conv.rank]) for which
 sizeof(T) == sizeof(type), with the same
 cv-qualifiers as T.   | |
If T is a (possibly cv-qualified) unsigned integer
 type ([basic.fundamental]) then the member typedef
 type denotes T; otherwise,
 if T is a (possibly cv-qualified) signed integer
 type then type denotes the corresponding
 unsigned integer type, with the same cv-qualifiers as T;
 otherwise, type denotes the unsigned integer type with smallest
 rank ([conv.rank]) for which
 sizeof(T) == sizeof(type), with the same
 cv-qualifiers as T.   | 
Template  | Comments  | 
If T has type “(possibly cv-qualified) pointer
 to T1” then the member typedef type
 denotes T1; otherwise, it denotes T.  | |
If T is a referenceable type ([defns.referenceable]) or a
 cv void type then
 the member typedef type denotes
 remove_reference_t<T>*;
 otherwise, type denotes T.  | 
Template  | Comments  | 
template<class T> struct type_identity;  | |
template<class T> struct remove_cvref;  | |
template<class T> struct decay;  | [Note 1:  This behavior is similar to the lvalue-to-rvalue ([conv.lval]),
array-to-pointer ([conv.array]), and function-to-pointer ([conv.func])
conversions applied when an lvalue is used as an rvalue, but also
strips cv-qualifiers from class types in order to more closely model by-value
argument passing.  — end note] | 
template<bool B, class T = void> struct enable_if;  | |
template<class... T> struct common_type;  | |
Unless this trait is specialized,
 there shall be no member type.  | |
template<class... T> struct common_reference;  | |
If T is an enumeration type, the member typedef type denotes
 the underlying type of T ([dcl.enum]);
 otherwise, there is no member type.   | |
If the expression INVOKE(declval<Fn>(), declval<ArgTypes>()...) ([func.require])
 is well-formed when treated as an unevaluated operand ([expr.context]),
 the member typedef type denotes the type
 decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...));
 otherwise, there shall be no member type.   Only the validity of the immediate context of the
 expression is considered.  [Note 2:  The compilation of the expression can result in side effects such as
 the instantiation of class template specializations and function
 template specializations, the generation of implicitly-defined
 functions, and so on.  Such side effects are not in the “immediate
 context” and can result in the program being ill-formed.  — end note]
 Preconditions: Fn and all types in the template parameter pack ArgTypes
 are complete types, cv void, or arrays of
 unknown bound.  | |
If tuple-like<Tuple> is true
 and the expression
 INVOKE(declval<Fn>(), ELEMS-OF(Tuple)...) ([func.require])
 is well-formed
 when treated as an unevaluated operand ([expr.context]),
 the member typedef type denotes the type
 decltype(INVOKE(declval<Fn>(), ELEMS-OF(Tuple)...));
 otherwise, there shall be no member type.   Only the validity of the immediate context of the expression is considered.  [Note 3:  The compilation of the expression can result in side effects
 such as the instantiation of class template specializations
 and function template specializations,
 the generation of implicitly-defined functions, and so on.  Such side effects are not in the “immediate context”
 and can result in the program being ill-formed.  — end note] | |
template<class T> struct unwrap_reference;  | If T is
 a specialization reference_wrapper<X> for some type X,
 the member typedef type of unwrap_reference<T>
 denotes X&,
 otherwise type denotes T.  | 
template<class T> unwrap_ref_decay;  | 
template<class... B> struct conjunction : see below { };
template<class... B> struct disjunction : see below { };
template<class B> struct negation : see below { };
template<class S, class M>
  constexpr bool is_pointer_interconvertible_with_class(M S::*m) noexcept;
template<class S1, class S2, class M1, class M2>
  constexpr bool is_corresponding_member(M1 S1::*m1, M2 S2::*m2) noexcept;
constexpr bool is_constant_evaluated() noexcept;
consteval bool is_within_lifetime(const auto* p) noexcept;
consteval bool is_string_literal(const char* p);
consteval bool is_string_literal(const wchar_t* p);
consteval bool is_string_literal(const char8_t* p);
consteval bool is_string_literal(const char16_t* p);
consteval bool is_string_literal(const char32_t* p);
template<ranges::input_range R>
  consteval info reflect_constant_string(R&& r);
template<ranges::input_range R>
  consteval info reflect_constant_array(R&& r);
template<ranges::input_range R>
  consteval const ranges::range_value_t<R>* define_static_string(R&& r);
template<ranges::input_range R>
  consteval span<const ranges::range_value_t<R>> define_static_array(R&& r);
template<class T>
  consteval const remove_cvref_t<T>* define_static_object(T&& t);
consteval exception(u8string_view what, info from,
                    source_location where = source_location::current()) noexcept;
consteval exception(string_view what, info from,
                    source_location where = source_location::current()) noexcept;
constexpr const char* what() const noexcept override;
consteval u8string_view u8what() const noexcept;
consteval info from() const noexcept;
consteval source_location where() const noexcept;
Constant  | Corresponding operator-function-id  | Operator symbol name  | 
op_new  | operator new  | new  | 
op_delete  | operator delete  | delete  | 
op_array_new  | operator new[]  | new[]  | 
op_array_delete  | operator delete[]  | delete[]  | 
op_co_await  | operator co_await  | co_await  | 
op_parentheses  | operator()  | ()  | 
op_square_brackets  | operator[]  | []  | 
op_arrow  | operator->  | ->  | 
op_arrow_star  | operator->*  | ->*  | 
op_tilde  | operator~  | ~  | 
op_exclamation  | operator!  | !  | 
op_plus  | operator+  | +  | 
op_minus  | operator-  | -  | 
op_star  | operator*  | *  | 
op_slash  | operator/  | /  | 
op_percent  | operator%  | %  | 
op_caret  | operator^  | ^  | 
op_ampersand  | operator&  | &  | 
op_equals  | operator=  | =  | 
op_pipe  | operator|  | |  | 
op_plus_equals  | operator+=  | +=  | 
op_minus_equals  | operator-=  | -=  | 
op_star_equals  | operator*=  | *=  | 
op_slash_equals  | operator/=  | /=  | 
op_percent_equals  | operator%=  | %=  | 
op_caret_equals  | operator^=  | ^=  | 
op_ampersand_equals  | operator&=  | &=  | 
op_pipe_equals  | operator|=  | |=  | 
op_equals_equals  | operator==  | ==  | 
op_exclamation_equals  | operator!=  | !=  | 
op_less  | operator<  | <  | 
op_greater  | operator>  | >  | 
op_less_equals  | operator<=  | <=  | 
op_greater_equals  | operator>=  | >=  | 
op_spaceship  | operator<=>  | <=>  | 
op_ampersand_ampersand  | operator&&  | &&  | 
op_pipe_pipe  | operator||  | ||  | 
op_less_less  | operator<<  | <<  | 
op_greater_greater  | operator>>  | >>  | 
op_less_less_equals  | operator<<=  | <<=  | 
op_greater_greater_equals  | operator>>=  | >>=  | 
op_plus_plus  | operator++  | ++  | 
op_minus_minus  | operator--  | --  | 
op_comma  | operator,  | ,  | 
consteval operators operator_of(info r);
consteval string_view symbol_of(operators op);
consteval u8string_view u8symbol_of(operators op);
consteval bool has_identifier(info r);
consteval string_view identifier_of(info r);
consteval u8string_view u8identifier_of(info r);
consteval string_view display_string_of(info r);
consteval u8string_view u8display_string_of(info r);
consteval source_location source_location_of(info r);
consteval bool has-type(info r);  // exposition only
consteval info type_of(info r);
consteval info object_of(info r);
consteval info constant_of(info r);
consteval bool is_public(info r);
consteval bool is_protected(info r);
consteval bool is_private(info r);
consteval bool is_virtual(info r);
consteval bool is_pure_virtual(info r);
consteval bool is_override(info r);
consteval bool is_final(info r);
consteval bool is_deleted(info r);
consteval bool is_defaulted(info r);
consteval bool is_user_provided(info r);
consteval bool is_user_declared(info r);
consteval bool is_explicit(info r);
consteval bool is_noexcept(info r);
consteval bool is_bit_field(info r);
consteval bool is_enumerator(info r);
consteval bool is_annotation(info r);
consteval bool is_const(info r);
consteval bool is_volatile(info r);
consteval bool is_mutable_member(info r);
consteval bool is_lvalue_reference_qualified(info r);
consteval bool is_rvalue_reference_qualified(info r);
consteval bool has_static_storage_duration(info r);
consteval bool has_thread_storage_duration(info r);
consteval bool has_automatic_storage_duration(info r);
consteval bool has_internal_linkage(info r);
consteval bool has_module_linkage(info r);
consteval bool has_external_linkage(info r);
consteval bool has_c_language_linkage(info r);
consteval bool has_linkage(info r);
consteval bool is_complete_type(info r);
consteval bool is_enumerable_type(info r);
consteval bool is_variable(info r);
consteval bool is_type(info r);
consteval bool is_namespace(info r);
consteval bool is_type_alias(info r);
consteval bool is_namespace_alias(info r);
consteval bool is_function(info r);
consteval bool is_conversion_function(info r);
consteval bool is_operator_function(info r);
consteval bool is_literal_operator(info r);
consteval bool is_special_member_function(info r);
consteval bool is_constructor(info r);
consteval bool is_default_constructor(info r);
consteval bool is_copy_constructor(info r);
consteval bool is_move_constructor(info r);
consteval bool is_assignment(info r);
consteval bool is_copy_assignment(info r);
consteval bool is_move_assignment(info r);
consteval bool is_destructor(info r);
consteval bool is_function_parameter(info r);
consteval bool is_explicit_object_parameter(info r);
consteval bool has_default_argument(info r);
consteval bool has_ellipsis_parameter(info r);
consteval bool is_template(info r);
consteval bool is_function_template(info r);
consteval bool is_variable_template(info r);
consteval bool is_class_template(info r);
consteval bool is_alias_template(info r);
consteval bool is_conversion_function_template(info r);
consteval bool is_operator_function_template(info r);
consteval bool is_literal_operator_template(info r);
consteval bool is_constructor_template(info r);
consteval bool is_concept(info r);
consteval bool is_value(info r);
consteval bool is_object(info r);
consteval bool is_structured_binding(info r);
consteval bool is_class_member(info r);
consteval bool is_namespace_member(info r);
consteval bool is_nonstatic_data_member(info r);
consteval bool is_static_member(info r);
consteval bool is_base(info r);
consteval bool has_default_member_initializer(info r);
consteval bool has_parent(info r);
consteval info parent_of(info r);
consteval info dealias(info r);
consteval bool has_template_arguments(info r);
consteval info template_of(info r);
consteval vector<info> template_arguments_of(info r);
consteval vector<info> parameters_of(info r);
consteval info variable_of(info r);
consteval info return_type_of(info r);
consteval info scope() const;
consteval info designating_class() const;
static consteval access_context unprivileged() noexcept;
consteval bool is_accessible(info r, access_context ctx);
consteval bool has_inaccessible_nonstatic_data_members(info r, access_context ctx);
consteval bool has_inaccessible_bases(info r, access_context ctx);
consteval bool has_inaccessible_subobjects(info r, access_context ctx);
consteval vector<info> members_of(info r, access_context ctx);
consteval vector<info> bases_of(info type, access_context ctx);
consteval vector<info> static_data_members_of(info type, access_context ctx);
consteval vector<info> nonstatic_data_members_of(info type, access_context ctx);
consteval vector<info> subobjects_of(info type, access_context ctx);
consteval vector<info> enumerators_of(info type_enum);
struct member_offset {
  ptrdiff_t bytes;
  ptrdiff_t bits;
  constexpr ptrdiff_t total_bits() const;
  auto operator<=>(const member_offset&) const = default;
};
constexpr ptrdiff_t member_offset::total_bits() const;
consteval member_offset offset_of(info r);
consteval size_t size_of(info r);
consteval size_t alignment_of(info r);
consteval size_t bit_size_of(info r);
consteval vector<info> annotations_of(info item);
consteval vector<info> annotations_of_with_type(info item, info type);
template<class T>
  consteval T extract-ref(info r);      // exposition only
template<class T>
  consteval T extract-member-or-function(info r);       // exposition only
template<class T>
  consteval T extract-value(info r);    // exposition only
template<class T>
  consteval T extract(info r);
template<class R>
concept reflection_range =
  ranges::input_range<R> &&
  same_as<ranges::range_value_t<R>, info> &&
  same_as<remove_cvref_t<ranges::range_reference_t<R>>, info>;
template<reflection_range R = initializer_list<info>>
  consteval bool can_substitute(info templ, R&& arguments);
template<reflection_range R = initializer_list<info>>
  consteval info substitute(info templ, R&& arguments);
template<class T>
  consteval info reflect_constant(T expr);
template<class T>
  consteval info reflect_object(T& expr);
template<class T>
  consteval info reflect_function(T& fn);
template<class T>
  requires constructible_from<u8string, T>
  consteval name-type(T&& value);
template<class T>
  requires constructible_from<string, T>
  consteval name-type(T&& value);
consteval info data_member_spec(info type, data_member_options options);
consteval bool is_data_member_spec(info r);
template<reflection_range R = initializer_list<info>>
  consteval info define_aggregate(info class_type, R&& mdescrs);
Signature and Return Type  | Returns  | 
bool meta::UNARY(info type); bool meta::UNARY_type(info type);  | std::UNARY_v<T>,
where T is the type or type alias represented by type  | 
bool meta::BINARY(info t1, info t2); bool meta::BINARY_type(info t1, info t2);  | std::BINARY_v<, >,
where  and  are the types or type aliases
represented by t1 and t2, respectively  | 
template<reflection_range R> bool meta::VARIADIC_type(info type, R&& args);  | std::VARIADIC_v<T, U...>,
where T is the type or type alias represented by type
and U... is the pack of types or type aliases
whose elements are represented by the corresponding elements of args  | 
template<reflection_range R> bool meta::VARIADIC_type(info t1, info t2, R&& args);  | std::VARIADIC_v<, , U...>,
where  and  are the types or type aliases
represented by t1 and t2, respectively,
and U... is the pack of types or type aliases
whose elements are represented by the corresponding elements of args  | 
info meta::UNARY(info type);  | A reflection representing the type denoted by
std::UNARY_t<T>,
where T is the type or type alias represented by type  | 
template<reflection_range R> info meta::VARIADIC(R&& args);  | A reflection representing the type denoted by
std::VARIADIC_t<T...>,
where T... is the pack of types or type aliases
whose elements are represented by the corresponding elements of args  | 
template<reflection_range R> info meta::VARIADIC(info type, R&& args);  | A reflection representing the type denoted by
std::VARIADIC_t<T, U...>,
where T is the type or type alias represented by type
and U... is the pack of types or type aliases
whose elements are represented by the corresponding elements of args  | 
consteval size_t rank(info type);
consteval size_t extent(info type, unsigned i = 0);
consteval size_t tuple_size(info type);
consteval info tuple_element(size_t index, info type);
consteval size_t variant_size(info type);
consteval info variant_alternative(size_t index, info type);
consteval strong_ordering type_order(info t1, info t2);
Type  | Value of X  | Value of Y  | 
ratio_add<R1, R2>  | R1::num * R2::den +  | R1::den * R2::den  | 
R2::num * R1::den  | ||
ratio_subtract<R1, R2>  | R1::num * R2::den -  | R1::den * R2::den  | 
R2::num * R1::den  | ||
ratio_multiply<R1, R2>  | R1::num * R2::num  | R1::den * R2::den  | 
ratio_divide<R1, R2>  | R1::num * R2::den  | R1::den * R2::num  | 
template<class R1, class R2>
  struct ratio_equal : bool_constant<R1::num == R2::num && R1::den == R2::den> { };
template<class R1, class R2>
  struct ratio_not_equal : bool_constant<!ratio_equal_v<R1, R2>> { };
template<class R1, class R2>
  struct ratio_less : bool_constant<see below> { };
template<class R1, class R2>
  struct ratio_less_equal : bool_constant<!ratio_less_v<R2, R1>> { };
template<class R1, class R2>
  struct ratio_greater : bool_constant<ratio_less_v<R2, R1>> { };
template<class R1, class R2>
  struct ratio_greater_equal : bool_constant<!ratio_less_v<R1, R2>> { };