xref: /llvm-project/libcxx/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp (revision 87cf92d9cb9379f7d3f1a601fc17d56bb2d18d80)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // type_traits
10 
11 // add_lvalue_reference
12 // If T names a referenceable type then the member typedef type
13 //    shall name T&; otherwise, type shall name T.
14 
15 #include <type_traits>
16 #include "test_macros.h"
17 
18 template <class T, class U>
test_add_lvalue_reference()19 void test_add_lvalue_reference()
20 {
21     ASSERT_SAME_TYPE(U, typename std::add_lvalue_reference<T>::type);
22 #if TEST_STD_VER > 11
23     ASSERT_SAME_TYPE(U, std::add_lvalue_reference_t<T>);
24 #endif
25 }
26 
27 template <class F>
test_function0()28 void test_function0()
29 {
30     ASSERT_SAME_TYPE(F&, typename std::add_lvalue_reference<F>::type);
31 #if TEST_STD_VER > 11
32     ASSERT_SAME_TYPE(F&, std::add_lvalue_reference_t<F>);
33 #endif
34 }
35 
36 template <class F>
test_function1()37 void test_function1()
38 {
39     ASSERT_SAME_TYPE(F, typename std::add_lvalue_reference<F>::type);
40 #if TEST_STD_VER > 11
41     ASSERT_SAME_TYPE(F, std::add_lvalue_reference_t<F>);
42 #endif
43 }
44 
45 struct Foo {};
46 
main(int,char **)47 int main(int, char**)
48 {
49     test_add_lvalue_reference<void, void>();
50     test_add_lvalue_reference<int, int&>();
51     test_add_lvalue_reference<int[3], int(&)[3]>();
52     test_add_lvalue_reference<int&, int&>();
53     test_add_lvalue_reference<const int&, const int&>();
54     test_add_lvalue_reference<int*, int*&>();
55     test_add_lvalue_reference<const int*, const int*&>();
56     test_add_lvalue_reference<Foo, Foo&>();
57 
58 //  LWG 2101 specifically talks about add_lvalue_reference and functions.
59 //  The term of art is "a referenceable type", which a cv- or ref-qualified function is not.
60     test_function0<void()>();
61     test_function1<void() const>();
62     test_function1<void() &>();
63     test_function1<void() &&>();
64     test_function1<void() const &>();
65     test_function1<void() const &&>();
66 
67 //  But a cv- or ref-qualified member function *is* "a referenceable type"
68     test_function0<void (Foo::*)()>();
69     test_function0<void (Foo::*)() const>();
70     test_function0<void (Foo::*)() &>();
71     test_function0<void (Foo::*)() &&>();
72     test_function0<void (Foo::*)() const &>();
73     test_function0<void (Foo::*)() const &&>();
74 
75   return 0;
76 }
77