std::experi...on_reference(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– NAME πŸ’–

okay so this page is std::experi...on_reference(3) from the C++ Standard Libary manual β€” yes, the header is literally truncated like that, and yes, β€œLibary” is spelled like that on the page, we are keeping it πŸ’€πŸ’…

The NAME section literally repeats it twice: std::experimental::ranges::common_reference β€” std::experimental::ranges::common_reference. Iconic duplicate behavior, no notes.


✨ Synopsis ✨

Defined in header <experimental/ranges/type_traits>:

template< class... T >                               (ranges TS)
struct common_reference;

So common_reference determines the common reference type of the types T... β€” that is, the type to which all the types in T... can be converted or bound. If such a type exists (as determined according to the rules below), the member type names that type. Otherwise, there is no member type. And bestie, the behavior is undefined if any of the types in T... is an incomplete type other than (possibly cv-qualified) void. Undefined behavior is not the vibe 🚩

When given reference types, common_reference attempts to find a reference type to which the supplied reference types can all be bound, but may return a non-reference type if it cannot find such a reference type.

The rules, in order:

  • If sizeof...(T) is zero, there is no member type.
  • If sizeof...(T) is one (i.e., T... contains only one type T0), the member type names the same type as T0.
  • If sizeof...(T) is two (i.e., T... contains two types T1 and T2):
    • If T1 and T2 are both reference types, and the simple common reference type S of T1 and T2 (as defined below) exists, then the member type type names S;
    • Otherwise, if basic_common_reference<T1R, T2R, T1Q, T2Q>::type exists, where TiR is std::remove_cv_t<std::remove_reference_t<Ti>> and TiQ is an alias template such that TiQ<TiR> is Ti, then the member type type names that type;
    • Otherwise, if decltype(false? val<T1>() : val<T2>()), where val is a function template template<class T> T val();, denotes a valid type, then the member type type names that type;
    • Otherwise, if ranges::common_type_t<T1, T2> is a valid type, then the member type type names that type;
    • Otherwise, there is no member type.
  • If sizeof...(T) is greater than two (i.e., T... consists of the types T1, T2, R...), then if ranges::common_reference_t<T1, T2> exists, the member type denotes ranges::common_reference_t<ranges::common_reference_t<T1, T2>, R...> if such a type exists. In all other cases, there is no member type.

The simple common reference type of two reference types T1 and T2 is defined as follows:

  • If T1 is cv1 X & and T2 is cv2 Y & (i.e., both are lvalue reference types): their simple common reference type is decltype(false? std::declval<cv12 X &>() : std::declval<cv12 Y &>()), where cv12 is the union of cv1 and cv2, if that type exists and is a reference type.
  • If T1 and T2 are both rvalue reference types: if the simple common reference type of T1 & and T2 & (determined according to the previous bullet) exists, then let C denote that type's corresponding rvalue reference type. If std::is_convertible<T1, C>::value and std::is_convertible<T2, C>::value are both true, then the simple common reference type of T1 and T2 is C.
  • Otherwise, one of the two types must be an lvalue reference type A & and the other must be an rvalue reference type B && (A and B might be cv-qualified). Let D denote the simple common reference type of A & and B const &, if any. If D exists and std::is_convertible<B &&, D>::value is true, then the simple common reference type is D.
  • Otherwise, there's no simple common reference type.

🫢 Member types 🫢

  • Name: type
  • Definition: the common reference type for all T...

🧚 Helper types 🧚

template< class... T >
using common_reference_t = typename common_reference<T...>::type;
template< class T, class U, template<class> class TQual,
       template<class> class
          UQual >
struct basic_common_reference {};

The class template basic_common_reference is a customization point that allows users to influence the result of common_reference for user-defined types (typically proxy references). The primary template is empty.


πŸ”₯ Specializations πŸ”₯

A program may specialize basic_common_reference<T, U, TQual, UQual> on the first two parameters T and U if std::is_same<T, std::decay_t<T>> and std::is_same<U, std::decay_t<U>> are both true and at least one of them depends on a program-defined type.

If such a specialization has a member named type, it must be a public and unambiguous member type that names a type to which both TQual<T> and UQual<U> are convertible. Additionally, ranges::basic_common_reference<T, U, TQual, UQual>::type and ranges::basic_common_reference<U, T, UQual, TQual>::type must denote the same type.

A program may not specialize basic_common_reference on the third or fourth parameters, nor may it specialize common_reference itself. A program that adds specializations in violation of these rules has undefined behavior. Like, do not do that, bestie πŸš«πŸ’€


🌸 Notes 🌸

This section is incomplete. The page said it, not me 😭


πŸ“ Example πŸ“

This section is incomplete. Reason: no example 🫠


πŸ‘‘ See also πŸ‘‘

  • common_type β€” determines the common type of a group of types (C++11) (class template)
  • common_type β€” determine the common type of a set of types (class template)
  • CommonReference β€” specifies that two types share a common reference type (concept)

🌈 Categories 🌈

  • Todo without reason
  • Todo no example

okay that's the page πŸ’– source: http://cppreference.com, version/date: 2024.06.10, and the footer title is std::experi...on_reference(3) β€” bye bestie, go slay some common reference types βœ¨πŸ’…

πŸ“¦ where this page comes from