blob: ecbd1eff70fe8349b2877ca30561b7ed602c4704 [file] [log] [blame]
/*
* 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/base/copyable_ptr.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
namespace base {
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<X> p1;
p1->val = 1;
ASSERT_NE(p1.get(), nullptr);
ASSERT_EQ(&*p1, p1.get());
CopyablePtr<X> 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<X> 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<X> p1;
p1->val = 1;
CopyablePtr<X> 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<X> 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<X> p1;
p1->val = 1;
CopyablePtr<X> p2;
p2->val = 2;
CopyablePtr<X> 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 base
} // namespace perfetto