1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdio.h>
6 #include <unittest/unittest.h>
7
8 #include <utility>
9
10 enum Category { CAT_LVALUE, CAT_RVALUE };
11
category(const int & arg)12 static int category(const int& arg) { return CAT_LVALUE; }
13
category(int && arg)14 static int category(int&& arg) { return CAT_RVALUE; }
15
16 template <typename T>
passing(T && t)17 static int passing(T&& t)
18 {
19 return category(t);
20 }
21
22 template <typename T>
moving(T && t)23 static int moving(T&& t)
24 {
25 return category(std::move(t));
26 }
27
28 template <typename T>
forwarding(T && t)29 static int forwarding(T&& t)
30 {
31 return category(std::forward<T>(t));
32 }
33
34 template <typename T>
forward_copy(T && t)35 static int forward_copy(T&& t)
36 {
37 return category(std::forward<T&>(t));
38 }
39
40 struct A {
AA41 A(int&& n) : category(CAT_RVALUE) {}
AA42 A(int& n) : category(CAT_LVALUE) {}
43 int category;
44 };
45
46 template <typename T, typename U>
make_object(U && u)47 static T make_object(U&& u)
48 {
49 return T(std::forward<U>(u));
50 }
51
forward_test()52 static bool forward_test()
53 {
54 BEGIN_TEST;
55 int val = 42;
56 int& ref = val;
57 const int& cref = val;
58
59 EXPECT_EQ(CAT_LVALUE, passing(42));
60 EXPECT_EQ(CAT_LVALUE, passing(val));
61 EXPECT_EQ(CAT_LVALUE, passing(ref));
62 EXPECT_EQ(CAT_LVALUE, passing(cref));
63 EXPECT_EQ(CAT_LVALUE, passing(val + 1));
64
65 EXPECT_EQ(CAT_RVALUE, moving(42));
66 EXPECT_EQ(CAT_RVALUE, moving(val));
67 EXPECT_EQ(CAT_RVALUE, moving(ref));
68 EXPECT_EQ(CAT_LVALUE, moving(cref));
69 EXPECT_EQ(CAT_RVALUE, moving(val + 1));
70
71 EXPECT_EQ(CAT_RVALUE, forwarding(42));
72 EXPECT_EQ(CAT_LVALUE, forwarding(val));
73 EXPECT_EQ(CAT_LVALUE, forwarding(ref));
74 EXPECT_EQ(CAT_LVALUE, forward_copy(cref));
75 EXPECT_EQ(CAT_RVALUE, forwarding(val + 1));
76
77 EXPECT_EQ(CAT_LVALUE, forward_copy(42));
78 EXPECT_EQ(CAT_LVALUE, forward_copy(val));
79 EXPECT_EQ(CAT_LVALUE, forward_copy(ref));
80 EXPECT_EQ(CAT_LVALUE, forward_copy(cref));
81 EXPECT_EQ(CAT_LVALUE, forward_copy(val + 1));
82
83 auto a1 = make_object<A>(42);
84 auto a2 = make_object<A>(val);
85
86 EXPECT_EQ(CAT_RVALUE, a1.category);
87 EXPECT_EQ(CAT_LVALUE, a2.category);
88
89 END_TEST;
90 }
91
92 BEGIN_TEST_CASE(forward_tests)
93 RUN_NAMED_TEST("Forward test", forward_test)
94 END_TEST_CASE(forward_tests);
95