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 // UNSUPPORTED: c++03
10 
11 // test forward
12 
13 #include <utility>
14 #include <type_traits>
15 #include <cassert>
16 
17 #include "test_macros.h"
18 
19 struct A
20 {
21 };
22 
source()23 A source() TEST_NOEXCEPT {return A();}
csource()24 const A csource() TEST_NOEXCEPT {return A();}
25 
26 
27 #if TEST_STD_VER > 11
test_constexpr_forward()28 constexpr bool test_constexpr_forward() {
29     int x = 42;
30     const int cx = 101;
31     return std::forward<int&>(x)        == 42
32         && std::forward<int>(x)         == 42
33         && std::forward<const int&>(x)  == 42
34         && std::forward<const int>(x)   == 42
35         && std::forward<int&&>(x)       == 42
36         && std::forward<const int&&>(x) == 42
37         && std::forward<const int&>(cx) == 101
38         && std::forward<const int>(cx)  == 101;
39 }
40 #endif
41 
main(int,char **)42 int main(int, char**)
43 {
44     A a;
45     const A ca = A();
46 
47     ((void)a); // Prevent unused warning
48     ((void)ca); // Prevent unused warning
49 
50     static_assert(std::is_same<decltype(std::forward<A&>(a)), A&>::value, "");
51     static_assert(std::is_same<decltype(std::forward<A>(a)), A&&>::value, "");
52     static_assert(std::is_same<decltype(std::forward<A>(source())), A&&>::value, "");
53     ASSERT_NOEXCEPT(std::forward<A&>(a));
54     ASSERT_NOEXCEPT(std::forward<A>(a));
55     ASSERT_NOEXCEPT(std::forward<A>(source()));
56 
57     static_assert(std::is_same<decltype(std::forward<const A&>(a)), const A&>::value, "");
58     static_assert(std::is_same<decltype(std::forward<const A>(a)), const A&&>::value, "");
59     static_assert(std::is_same<decltype(std::forward<const A>(source())), const A&&>::value, "");
60     ASSERT_NOEXCEPT(std::forward<const A&>(a));
61     ASSERT_NOEXCEPT(std::forward<const A>(a));
62     ASSERT_NOEXCEPT(std::forward<const A>(source()));
63 
64     static_assert(std::is_same<decltype(std::forward<const A&>(ca)), const A&>::value, "");
65     static_assert(std::is_same<decltype(std::forward<const A>(ca)), const A&&>::value, "");
66     static_assert(std::is_same<decltype(std::forward<const A>(csource())), const A&&>::value, "");
67     ASSERT_NOEXCEPT(std::forward<const A&>(ca));
68     ASSERT_NOEXCEPT(std::forward<const A>(ca));
69     ASSERT_NOEXCEPT(std::forward<const A>(csource()));
70 
71 #if TEST_STD_VER > 11
72     {
73     constexpr int i2 = std::forward<int>(42);
74     static_assert(std::forward<int>(42) == 42, "");
75     static_assert(std::forward<const int&>(i2) == 42, "");
76     static_assert(test_constexpr_forward(), "");
77     }
78 #endif
79 #if TEST_STD_VER == 11 && defined(_LIBCPP_VERSION)
80     // Test that std::forward is constexpr in C++11. This is an extension
81     // provided by both libc++ and libstdc++.
82     {
83     constexpr int i2 = std::forward<int>(42);
84     static_assert(std::forward<int>(42) == 42, "" );
85     static_assert(std::forward<const int&>(i2) == 42, "");
86     }
87 #endif
88 
89   return 0;
90 }
91