/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "perfetto/protozero/copyable_ptr.h" #include "test/gtest_and_gmock.h" namespace protozero { namespace { struct X { X() = default; X(const X&) = default; X& operator=(const X&) = default; ~X() { val = -1; } friend bool operator==(const X& lhs, const X& rhs) { return lhs.val == rhs.val; } // Deliberately unusual implementation. friend bool operator!=(const X& lhs, const X& rhs) { return lhs.val == rhs.val * -1; } int val = 0; }; TEST(CopyablePtrTest, CopyOperators) { CopyablePtr p1; p1->val = 1; ASSERT_NE(p1.get(), nullptr); ASSERT_EQ(&*p1, p1.get()); CopyablePtr p2(p1); EXPECT_NE(p1.get(), nullptr); EXPECT_NE(p2.get(), nullptr); EXPECT_NE(p1.get(), p2.get()); p2->val = 2; EXPECT_EQ(p1->val, 1); EXPECT_EQ(p2->val, 2); { CopyablePtr p3; p3 = p1; EXPECT_EQ(p3->val, 1); p3 = p2; EXPECT_EQ(p3->val, 2); p3->val = 3; EXPECT_EQ(p3->val, 3); } EXPECT_EQ(p1->val, 1); EXPECT_EQ(p2->val, 2); } TEST(CopyablePtrTest, MoveOperators) { CopyablePtr p1; p1->val = 1; CopyablePtr p2(std::move(p1)); EXPECT_EQ(p2->val, 1); // The moved-from object needs to stay valid and non-null. EXPECT_EQ(p1->val, 0); { CopyablePtr p3; p3->val = 3; p1 = std::move(p3); EXPECT_EQ(p1->val, 3); EXPECT_EQ(p3->val, 0); } EXPECT_EQ(p1->val, 3); } TEST(CopyablePtrTest, DeepCompare) { CopyablePtr p1; p1->val = 1; CopyablePtr p2; p2->val = 2; CopyablePtr p3; p3->val = -2; EXPECT_NE(p1.get(), p2.get()); EXPECT_NE(p1.get(), p3.get()); EXPECT_FALSE(p1 == p2); EXPECT_FALSE(p1 == p3); EXPECT_FALSE(p2 == p3); EXPECT_FALSE(p1 != p2); // The operator!= is special, see above. EXPECT_TRUE(p2 != p3); p1->val = -2; EXPECT_TRUE(p1 != p2); EXPECT_FALSE(p1 == p2); } } // namespace } // namespace protozero