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