Skip to content

Instantly share code, notes, and snippets.

@yohhoy
Last active October 17, 2019 03:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yohhoy/a96021f1e0415d06bb8d4bd8eab94aec to your computer and use it in GitHub Desktop.
Save yohhoy/a96021f1e0415d06bb8d4bd8eab94aec to your computer and use it in GitHub Desktop.
same_as concept in C++20 Standard Library
//
// requires Micosoft VisualC++ 2019 16.3 Preview 2 that implements P0717R1.
//
// https://devblogs.microsoft.com/cppblog/c20-concepts-are-here-in-visual-studio-2019-version-16-3/
// https://wg21.link/p0717r1 Semantic constraint matching for concepts
#include <type_traits>
#if 1
template <class T, class U>
concept same_as_impl = std::is_same_v<T, U>;
template <class T, class U>
concept same_as = same_as_impl<T, U> && same_as_impl<U, T>;
// overload #2 selected
#else
template <class T, class U>
concept same_as = std::is_same_v<T, U> && std::is_same_v<U, T>;
// ill-formed: ambiguous overloading
#endif
template <class T, class U>
requires same_as<T, U>
constexpr int f() { return 1; } // #1
template <class T, class U>
requires same_as<U, T> && true
constexpr int f() { return 2; } // #2
int main()
{
return f<int, int>();
}

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:

    1. same_as<X, Y>; normal form=is_same_v<T↦X, U↦Y>is_same_v<T↦Y, U↦X>
    1. 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:

    1. same_as<X, Y>; normal form=is_same_v<T↦X, U↦Y>1is_same_v<U↦Y, T↦X>2
    1. same_as<Y, X>; normal form=is_same_v<T↦Y, U↦X>1is_same_v<U↦X, T↦Y>2

DNF P=same_as<X, Y> := P_1=(is_same_v<T↦X, U↦Y>1is_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>"

@yohhoy
Copy link
Author

yohhoy commented Oct 17, 2019

It works on GCC HEAD 10.0.0 20191015(experimental)
https://wandbox.org/permlink/BK26SIGGDSYfvRVq

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment