1*bb9ca6d0SLouis Dionne //===----------------------------------------------------------------------===//
2*bb9ca6d0SLouis Dionne //
3*bb9ca6d0SLouis Dionne //                     The LLVM Compiler Infrastructure
4*bb9ca6d0SLouis Dionne //
5*bb9ca6d0SLouis Dionne // This file is dual licensed under the MIT and the University of Illinois Open
6*bb9ca6d0SLouis Dionne // Source Licenses. See LICENSE.TXT for details.
7*bb9ca6d0SLouis Dionne //
8*bb9ca6d0SLouis Dionne //===----------------------------------------------------------------------===//
9*bb9ca6d0SLouis Dionne 
10*bb9ca6d0SLouis Dionne // <functional>
11*bb9ca6d0SLouis Dionne //
12*bb9ca6d0SLouis Dionne // template <class T>
13*bb9ca6d0SLouis Dionne // struct unwrap_reference;
14*bb9ca6d0SLouis Dionne //
15*bb9ca6d0SLouis Dionne // template <class T>
16*bb9ca6d0SLouis Dionne // using unwrap_reference_t = typename unwrap_reference<T>::type;
17*bb9ca6d0SLouis Dionne 
18*bb9ca6d0SLouis Dionne // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
19*bb9ca6d0SLouis Dionne 
20*bb9ca6d0SLouis Dionne #include <functional>
21*bb9ca6d0SLouis Dionne #include <type_traits>
22*bb9ca6d0SLouis Dionne 
23*bb9ca6d0SLouis Dionne 
24*bb9ca6d0SLouis Dionne template <typename T, typename Expected>
25*bb9ca6d0SLouis Dionne void check_equal() {
26*bb9ca6d0SLouis Dionne   static_assert(std::is_same_v<typename std::unwrap_reference<T>::type, Expected>);
27*bb9ca6d0SLouis Dionne   static_assert(std::is_same_v<typename std::unwrap_reference<T>::type, std::unwrap_reference_t<T>>);
28*bb9ca6d0SLouis Dionne }
29*bb9ca6d0SLouis Dionne 
30*bb9ca6d0SLouis Dionne template <typename T>
31*bb9ca6d0SLouis Dionne void check() {
32*bb9ca6d0SLouis Dionne   check_equal<T, T>();
33*bb9ca6d0SLouis Dionne   check_equal<T&, T&>();
34*bb9ca6d0SLouis Dionne   check_equal<T const, T const>();
35*bb9ca6d0SLouis Dionne   check_equal<T const&, T const&>();
36*bb9ca6d0SLouis Dionne 
37*bb9ca6d0SLouis Dionne   check_equal<std::reference_wrapper<T>, T&>();
38*bb9ca6d0SLouis Dionne   check_equal<std::reference_wrapper<T const>, T const&>();
39*bb9ca6d0SLouis Dionne }
40*bb9ca6d0SLouis Dionne 
41*bb9ca6d0SLouis Dionne struct T { };
42*bb9ca6d0SLouis Dionne 
43*bb9ca6d0SLouis Dionne int main() {
44*bb9ca6d0SLouis Dionne   check<T>();
45*bb9ca6d0SLouis Dionne   check<int>();
46*bb9ca6d0SLouis Dionne   check<float>();
47*bb9ca6d0SLouis Dionne 
48*bb9ca6d0SLouis Dionne   check<T*>();
49*bb9ca6d0SLouis Dionne   check<int*>();
50*bb9ca6d0SLouis Dionne   check<float*>();
51*bb9ca6d0SLouis Dionne }
52