File: test_intrusive_ptr.cc

package info (click to toggle)
xgboost 3.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 13,796 kB
  • sloc: cpp: 67,502; python: 35,503; java: 4,676; ansic: 1,426; sh: 1,320; xml: 1,197; makefile: 204; javascript: 19
file content (110 lines) | stat: -rw-r--r-- 2,843 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
 * Copyright 2020-2024, XGBoost contributors
 */
#include <gtest/gtest.h>
#include <xgboost/intrusive_ptr.h>

namespace xgboost {
namespace {
class NotCopyConstructible {
 public:
  float data;

  explicit NotCopyConstructible(float d) : data{d} {}
  NotCopyConstructible(NotCopyConstructible const &that) = delete;
  NotCopyConstructible &operator=(NotCopyConstructible const &that) = delete;
  NotCopyConstructible(NotCopyConstructible&& that) = default;
};
static_assert(!std::is_trivially_copy_constructible_v<NotCopyConstructible>);
static_assert(!std::is_trivially_copy_assignable_v<NotCopyConstructible>);

class ForIntrusivePtrTest {
 public:
  mutable class IntrusivePtrCell ref;
  float data { 0 };

  friend IntrusivePtrCell &
  IntrusivePtrRefCount(ForIntrusivePtrTest const *t) noexcept {  // NOLINT
    return t->ref;
  }

  ForIntrusivePtrTest() = default;
  ForIntrusivePtrTest(float a, int32_t b) : data{a + static_cast<float>(b)} {}

  explicit ForIntrusivePtrTest(NotCopyConstructible a) : data{a.data} {}
};
}  // anonymous namespace

TEST(IntrusivePtr, Basic) {
  IntrusivePtr<ForIntrusivePtrTest> ptr {new ForIntrusivePtrTest};
  auto p = ptr.get();

  // Copy ctor
  IntrusivePtr<ForIntrusivePtrTest> ptr_1 { ptr };
  ASSERT_EQ(ptr_1.get(), p);

  ASSERT_EQ((*ptr_1).data, ptr_1->data);
  ASSERT_EQ(ptr.use_count(), 2);

  // hash
  ASSERT_EQ(std::hash<IntrusivePtr<ForIntrusivePtrTest>>{}(ptr_1),
            std::hash<ForIntrusivePtrTest*>{}(ptr_1.get()));

  // Raw ptr comparison
  ASSERT_EQ(ptr, p);
  ASSERT_EQ(ptr_1, ptr);

  ForIntrusivePtrTest* raw_ptr {nullptr};
  ASSERT_NE(ptr_1, raw_ptr);
  ASSERT_NE(raw_ptr, ptr_1);

  // Reset with raw ptr.
  auto p_1 = new ForIntrusivePtrTest;
  ptr.reset(p_1);

  ASSERT_EQ(ptr_1.use_count(), 1);
  ASSERT_EQ(ptr.use_count(), 1);

  ASSERT_TRUE(ptr);
  ASSERT_TRUE(ptr_1);

  // Swap
  std::swap(ptr, ptr_1);
  ASSERT_NE(ptr, p_1);
  ASSERT_EQ(ptr_1, p_1);

  // Reset
  ptr.reset();
  ASSERT_FALSE(ptr);
  ASSERT_EQ(ptr.use_count(), 0);

  // Comparison operators
  ASSERT_EQ(ptr < ptr_1, ptr.get() < ptr_1.get());
  ASSERT_EQ(ptr > ptr_1, ptr.get() > ptr_1.get());

  ASSERT_LE(ptr, ptr);
  ASSERT_GE(ptr, ptr);

  // Copy assign
  IntrusivePtr<ForIntrusivePtrTest> ptr_2;
  ptr_2 = ptr_1;
  ASSERT_EQ(ptr_2, ptr_1);
  ASSERT_EQ(ptr_2.use_count(), 2);

  // Move assign
  IntrusivePtr<ForIntrusivePtrTest> ptr_3;
  ptr_3 = std::move(ptr_2);
  ASSERT_EQ(ptr_2.use_count(), 0);  // NOLINT
  ASSERT_EQ(ptr_3.use_count(), 2);

  // Move ctor
  IntrusivePtr<ForIntrusivePtrTest> ptr_4 { std::move(ptr_3) };
  ASSERT_EQ(ptr_3.use_count(), 0);  // NOLINT
  ASSERT_EQ(ptr_4.use_count(), 2);

  // Comparison
  ASSERT_EQ(ptr_1 > ptr_2, ptr_1.get() > ptr_2.get());
  ASSERT_EQ(ptr_1, ptr_1);
  ASSERT_EQ(ptr_1 < ptr_2, ptr_1.get() < ptr_2.get());
}
} // namespace xgboost