blob: 05380b7ca9b62f8d82966894c85139ec47482be3 [file] [log] [blame]
perkj0489e492016-10-20 00:24:01 -07001/*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "rtc_base/ref_counted_object.h"
12
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <memory>
perkj0489e492016-10-20 00:24:01 -070014#include <string>
Danil Chapovalov8df643b2021-01-22 16:11:10 +010015#include <type_traits>
Yves Gerey3e707812018-11-28 16:47:49 +010016#include <utility>
perkj0489e492016-10-20 00:24:01 -070017
Mirko Bonadeid9708072019-01-25 20:26:48 +010018#include "api/scoped_refptr.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "rtc_base/ref_count.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "test/gtest.h"
perkj0489e492016-10-20 00:24:01 -070021
22namespace rtc {
23
24namespace {
25
26class A {
27 public:
28 A() {}
29
30 private:
31 RTC_DISALLOW_COPY_AND_ASSIGN(A);
32};
33
34class RefClass : public RefCountInterface {
35 public:
36 RefClass() {}
37
38 protected:
ehmaldonadoda8dcfb2017-01-04 07:11:23 -080039 ~RefClass() override {}
perkj0489e492016-10-20 00:24:01 -070040};
41
42class RefClassWithRvalue : public RefCountInterface {
43 public:
44 explicit RefClassWithRvalue(std::unique_ptr<A> a) : a_(std::move(a)) {}
45
46 protected:
ehmaldonadoda8dcfb2017-01-04 07:11:23 -080047 ~RefClassWithRvalue() override {}
perkj0489e492016-10-20 00:24:01 -070048
49 public:
50 std::unique_ptr<A> a_;
51};
52
53class RefClassWithMixedValues : public RefCountInterface {
54 public:
55 RefClassWithMixedValues(std::unique_ptr<A> a, int b, const std::string& c)
56 : a_(std::move(a)), b_(b), c_(c) {}
57
58 protected:
ehmaldonadoda8dcfb2017-01-04 07:11:23 -080059 ~RefClassWithMixedValues() override {}
perkj0489e492016-10-20 00:24:01 -070060
61 public:
62 std::unique_ptr<A> a_;
63 int b_;
64 std::string c_;
65};
66
67} // namespace
68
Niels Möller6f72f562017-10-19 13:15:17 +020069TEST(RefCountedObject, HasOneRef) {
perkj0489e492016-10-20 00:24:01 -070070 scoped_refptr<RefCountedObject<RefClass>> aref(
71 new RefCountedObject<RefClass>());
72 EXPECT_TRUE(aref->HasOneRef());
Niels Möller6f72f562017-10-19 13:15:17 +020073 aref->AddRef();
74 EXPECT_FALSE(aref->HasOneRef());
75 EXPECT_EQ(aref->Release(), RefCountReleaseStatus::kOtherRefsRemained);
76 EXPECT_TRUE(aref->HasOneRef());
perkj0489e492016-10-20 00:24:01 -070077}
78
79TEST(RefCountedObject, SupportRValuesInCtor) {
80 std::unique_ptr<A> a(new A());
81 scoped_refptr<RefClassWithRvalue> ref(
82 new RefCountedObject<RefClassWithRvalue>(std::move(a)));
83 EXPECT_TRUE(ref->a_.get() != nullptr);
84 EXPECT_TRUE(a.get() == nullptr);
85}
86
87TEST(RefCountedObject, SupportMixedTypesInCtor) {
88 std::unique_ptr<A> a(new A());
89 int b = 9;
90 std::string c = "hello";
91 scoped_refptr<RefClassWithMixedValues> ref(
92 new RefCountedObject<RefClassWithMixedValues>(std::move(a), b, c));
93 EXPECT_TRUE(ref->a_.get() != nullptr);
94 EXPECT_TRUE(a.get() == nullptr);
95 EXPECT_EQ(b, ref->b_);
96 EXPECT_EQ(c, ref->c_);
97}
98
Danil Chapovalov8df643b2021-01-22 16:11:10 +010099TEST(FinalRefCountedObject, CanWrapIntoScopedRefptr) {
100 using WrappedTyped = FinalRefCountedObject<A>;
101 static_assert(!std::is_polymorphic<WrappedTyped>::value, "");
102 scoped_refptr<WrappedTyped> ref(new WrappedTyped());
103 EXPECT_TRUE(ref.get());
104 EXPECT_TRUE(ref->HasOneRef());
105 // Test reference counter is updated on some simple operations.
106 scoped_refptr<WrappedTyped> ref2 = ref;
107 EXPECT_FALSE(ref->HasOneRef());
108 EXPECT_FALSE(ref2->HasOneRef());
109
110 ref = nullptr;
111 EXPECT_TRUE(ref2->HasOneRef());
112}
113
perkj0489e492016-10-20 00:24:01 -0700114} // namespace rtc