cpp/experimental/ranges/type traits/common reference

Determines the common reference type of the types, that is, the type to which all the types in can be converted or bound. If such a type exists (as determined according to the rules below), the member names that type. Otherwise, there is no member. The behavior is undefined if any of the types in is an incomplete type other than (possibly cv-qualified).

When given reference types, 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.


 * If is zero, there is no member.
 * If is one (i.e.,  contains only one type ), the member  names the same type as.
 * If is two (i.e.,  contains two types  and ):
 * If and  are both reference types, and the simple common reference type  of  and  (as defined below) exists, then the member type  names ;
 * Otherwise, if exists, where  is  and  is an alias template such that  is, then the member type  names that type;
 * Otherwise, if, where is a function template , denotes a valid type, then the member type  names that type;
 * Otherwise, if is a valid type, then the member type  names that type;
 * Otherwise, there is no member type.
 * If is greater than two (i.e.,  consists of the types ), then if  exists, the member  denotes  if such a type exists. In all other cases, there is no member.

The simple common reference type of two reference types and  is defined as follows:
 * If is  and  is  (i.e., both are lvalue reference types): their simple common reference type is, where cv12 is the union of cv1 and cv2, if that type exists and is a reference type;
 * If and  are both rvalue reference types: if the simple common reference type of  and  (determined according to the previous bullet) exists, then let  denote that type's corresponding rvalue reference type. If  and  are both, then the simple common reference type of  and  is.
 * Otherwise, one of the two types must be an lvalue reference type and the other must be an rvalue reference type  ( and  might be cv-qualified). Let  denote the simple common reference type of  and, if any. If  exists and  is , then the simple common reference type is.
 * Otherwise, there's no simple common reference type.

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

Specializations
A program may specialize on the first two parameters  and  if  and  are both true and at least one of them depends on a program-defined type.

If such a specialization has a member named, it must be a public and unambiguous member type that names a type to which both and  are convertible. Additionally, and  must denote the same type.

A program may not specialize on the third or fourth parameters, nor may it specialize  itself. A program that adds specializations in violation of these rules has undefined behavior.