1bb9ca6d0SLouis Dionne //===----------------------------------------------------------------------===//
2bb9ca6d0SLouis Dionne //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bb9ca6d0SLouis Dionne //
7bb9ca6d0SLouis Dionne //===----------------------------------------------------------------------===//
8bb9ca6d0SLouis Dionne 
9bb9ca6d0SLouis Dionne // <functional>
10bb9ca6d0SLouis Dionne //
11bb9ca6d0SLouis Dionne // template <class T>
12bb9ca6d0SLouis Dionne // struct unwrap_reference;
13bb9ca6d0SLouis Dionne //
14bb9ca6d0SLouis Dionne // template <class T>
15bb9ca6d0SLouis Dionne // using unwrap_reference_t = typename unwrap_reference<T>::type;
16bb9ca6d0SLouis Dionne 
17bb9ca6d0SLouis Dionne // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
18bb9ca6d0SLouis Dionne 
19bb9ca6d0SLouis Dionne #include <functional>
20bb9ca6d0SLouis Dionne #include <type_traits>
21bb9ca6d0SLouis Dionne 
22bb9ca6d0SLouis Dionne 
23bb9ca6d0SLouis Dionne template <typename T, typename Expected>
24bb9ca6d0SLouis Dionne void check_equal() {
25bb9ca6d0SLouis Dionne   static_assert(std::is_same_v<typename std::unwrap_reference<T>::type, Expected>);
26bb9ca6d0SLouis Dionne   static_assert(std::is_same_v<typename std::unwrap_reference<T>::type, std::unwrap_reference_t<T>>);
27bb9ca6d0SLouis Dionne }
28bb9ca6d0SLouis Dionne 
29bb9ca6d0SLouis Dionne template <typename T>
30bb9ca6d0SLouis Dionne void check() {
31bb9ca6d0SLouis Dionne   check_equal<T, T>();
32bb9ca6d0SLouis Dionne   check_equal<T&, T&>();
33bb9ca6d0SLouis Dionne   check_equal<T const, T const>();
34bb9ca6d0SLouis Dionne   check_equal<T const&, T const&>();
35bb9ca6d0SLouis Dionne 
36bb9ca6d0SLouis Dionne   check_equal<std::reference_wrapper<T>, T&>();
37bb9ca6d0SLouis Dionne   check_equal<std::reference_wrapper<T const>, T const&>();
38bb9ca6d0SLouis Dionne }
39bb9ca6d0SLouis Dionne 
40bb9ca6d0SLouis Dionne struct T { };
41bb9ca6d0SLouis Dionne 
42*2df59c50SJF Bastien int main(int, char**) {
43bb9ca6d0SLouis Dionne   check<T>();
44bb9ca6d0SLouis Dionne   check<int>();
45bb9ca6d0SLouis Dionne   check<float>();
46bb9ca6d0SLouis Dionne 
47bb9ca6d0SLouis Dionne   check<T*>();
48bb9ca6d0SLouis Dionne   check<int*>();
49bb9ca6d0SLouis Dionne   check<float*>();
50*2df59c50SJF Bastien 
51*2df59c50SJF Bastien   return 0;
52bb9ca6d0SLouis Dionne }
53