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
18template <class T, class U>
19void 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
27template <class F>
28void 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
36template <class F>
37void 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
45struct Foo {};
46
47int 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

source code of libcxx/test/std/utilities/meta/meta.trans/meta.trans.ref/add_lvalue_ref.pass.cpp