Concept version
http://eel.is/c++draft/concept.same
template<class T, class U>
concept same-as-impl = is_same_v<T, U>; // exposition only
template<class T, class U>
concept same_as = same-as-impl<T, U> && same-as-impl<U, T>;
constraints:
-
same_as<X, Y>
; normal form=is_same_v<T↦X, U↦Y>
∧is_same_v<T↦Y, U↦X>
-
same_as<Y, X>
; normal form=is_same_v<T↦Y, U↦X>
∧is_same_v<T↦X, U↦Y>
DNF P=same_as<X, Y>
:= P_1=(is_same_v<T↦X, U↦Y>
∧ is_same_v<T↦Y, U↦X>
)
CNF Q=same_as<Y, X>
:= Q_1=(is_same_v<T↦Y, U↦X>
), Q_2=(is_same_v<T↦X, U↦Y>
)
P_1 has P_12=(is_same_v<T↦Y, U↦X>
) which is identical to Q_11=(is_same_v<T↦Y, U↦X>
) and,
P_1 has P_11=(is_same_v<T↦X, U↦Y>
) which is identical to Q_21=(is_same_v<T↦X, U↦Y>
),
so "P=same_as<X, Y>
subsumes Q=same_as<Y, X>
"
Non-concept version
template<class T, class U>
concept same_as = is_same_v<T, U>/*1*/ && is_same_v<U, T>/*2*/;
constraints:
-
same_as<X, Y>
; normal form=is_same_v<T↦X, U↦Y>
1 ∧is_same_v<U↦Y, T↦X>
2
-
same_as<Y, X>
; normal form=is_same_v<T↦Y, U↦X>
1 ∧is_same_v<U↦X, T↦Y>
2
DNF P=same_as<X, Y>
:= P_1=(is_same_v<T↦X, U↦Y>
1 ∧ is_same_v<U↦Y, T↦X>
2)
CNF Q=same_as<Y, X>
:= Q_1=(is_same_v<T↦Y, U↦X>
1), Q_2=(is_same_v<U↦X, T↦Y>
2)
P_11=(is_same_v<T↦X, U↦Y>
1) nor P_12=(is_same_v<U↦Y, T↦X>
2) is NOT identical to Q_11=(is_same_v<T↦Y, U↦X>
1) and,
P_11=(is_same_v<T↦X, U↦Y>
1) nor P_12=(is_same_v<U↦Y, T↦X>
2) is NOT identical to Q_21=(is_same_v<U↦X, T↦Y>
2),
so "P=same_as<X, Y>
does NOT subsume Q=same_as<Y, X>
"
It works on GCC HEAD 10.0.0 20191015(experimental)
https://wandbox.org/permlink/BK26SIGGDSYfvRVq