]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/common/test_static_ptr.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / test / common / test_static_ptr.cc
CommitLineData
11fdf7f2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2017 Red Hat, Inc.
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
1e59de90 15#include <compare>
11fdf7f2 16#include <gtest/gtest.h>
1e59de90 17#include "common/static_ptr.h"
11fdf7f2
TL
18
19using ceph::static_ptr;
20using ceph::make_static;
21
22class base {
23public:
24 virtual int func() = 0;
25 virtual ~base() = default;
26};
27
28class sibling1 : public base {
29public:
30 int func() override { return 0; }
31};
32
33class sibling2 : public base {
34public:
35 int func() override { return 9; }
36 virtual int call(int) = 0;
37};
38
39class grandchild : public sibling2 {
40protected:
41 int val;
42public:
43 explicit grandchild(int val) : val(val) {}
44 virtual int call(int n) override { return n * val; }
45};
46
47class great_grandchild : public grandchild {
48public:
49 explicit great_grandchild(int val) : grandchild(val) {}
50 int call(int n) override { return n + val; }
51};
52
1e59de90 53#ifdef __cpp_lib_three_way_comparison
11fdf7f2
TL
54TEST(StaticPtr, EmptyCreation) {
55 static_ptr<base, sizeof(grandchild)> p;
56 EXPECT_FALSE(p);
57 EXPECT_EQ(p, nullptr);
58 EXPECT_EQ(nullptr, p);
59 EXPECT_TRUE(p.get() == nullptr);
60}
61
62TEST(StaticPtr, CreationCall) {
63 {
64 static_ptr<base, sizeof(grandchild)> p(std::in_place_type_t<sibling1>{});
65 EXPECT_TRUE(p);
66 EXPECT_FALSE(p == nullptr);
67 EXPECT_FALSE(nullptr == p);
68 EXPECT_FALSE(p.get() == nullptr);
69 EXPECT_EQ(p->func(), 0);
70 EXPECT_EQ((*p).func(), 0);
71 EXPECT_EQ((p.get())->func(), 0);
72 }
73 {
74 auto p = make_static<base, sibling1>();
75 EXPECT_TRUE(p);
76 EXPECT_FALSE(p == nullptr);
77 EXPECT_FALSE(nullptr == p);
78 EXPECT_FALSE(p.get() == nullptr);
79 EXPECT_EQ(p->func(), 0);
80 EXPECT_EQ((*p).func(), 0);
81 EXPECT_EQ((p.get())->func(), 0);
82 }
83}
84
85TEST(StaticPtr, CreateReset) {
86 {
87 static_ptr<base, sizeof(grandchild)> p(std::in_place_type_t<sibling1>{});
88 EXPECT_EQ((p.get())->func(), 0);
89 p.reset();
90 EXPECT_FALSE(p);
91 EXPECT_EQ(p, nullptr);
92 EXPECT_EQ(nullptr, p);
93 EXPECT_TRUE(p.get() == nullptr);
94 }
95 {
96 static_ptr<base, sizeof(grandchild)> p(std::in_place_type_t<sibling1>{});
97 EXPECT_EQ((p.get())->func(), 0);
98 p = nullptr;
99 EXPECT_FALSE(p);
100 EXPECT_EQ(p, nullptr);
101 EXPECT_EQ(nullptr, p);
102 EXPECT_TRUE(p.get() == nullptr);
103 }
104}
1e59de90 105#endif // __cpp_lib_three_way_comparison
11fdf7f2
TL
106
107TEST(StaticPtr, CreateEmplace) {
108 static_ptr<base, sizeof(grandchild)> p(std::in_place_type_t<sibling1>{});
109 EXPECT_EQ((p.get())->func(), 0);
110 p.emplace<grandchild>(30);
111 EXPECT_EQ(p->func(), 9);
112}
113
f67539c2 114TEST(StaticPtr, Move) {
11fdf7f2
TL
115 // Won't compile. Good.
116 // static_ptr<base, sizeof(base)> p1(std::in_place_type_t<grandchild>{}, 3);
117
118 static_ptr<base, sizeof(base)> p1(std::in_place_type_t<sibling1>{});
119 static_ptr<base, sizeof(grandchild)> p2(std::in_place_type_t<grandchild>{},
120 3);
121
11fdf7f2
TL
122 p2 = std::move(p1);
123 EXPECT_EQ(p1->func(), 0);
124}
125
126TEST(StaticPtr, ImplicitUpcast) {
127 static_ptr<base, sizeof(grandchild)> p1;
128 static_ptr<sibling2, sizeof(grandchild)> p2(std::in_place_type_t<grandchild>{}, 3);
129
11fdf7f2
TL
130 p1 = std::move(p2);
131 EXPECT_EQ(p1->func(), 9);
132
133 p2.reset();
134
135 // Doesn't compile. Good.
136 // p2 = p1;
137}
138
139TEST(StaticPtr, StaticCast) {
140 static_ptr<base, sizeof(grandchild)> p1(std::in_place_type_t<grandchild>{}, 3);
141 static_ptr<sibling2, sizeof(grandchild)> p2;
142
11fdf7f2
TL
143 p2 = ceph::static_pointer_cast<sibling2, sizeof(grandchild)>(std::move(p1));
144 EXPECT_EQ(p2->func(), 9);
145 EXPECT_EQ(p2->call(10), 30);
146}
147
148TEST(StaticPtr, DynamicCast) {
149 static constexpr auto sz = sizeof(great_grandchild);
11fdf7f2
TL
150 {
151 static_ptr<base, sz> p1(std::in_place_type_t<grandchild>{}, 3);
152 auto p2 = ceph::dynamic_pointer_cast<great_grandchild, sz>(std::move(p1));
153 EXPECT_FALSE(p2);
154 }
155
11fdf7f2
TL
156 {
157 static_ptr<base, sz> p1(std::in_place_type_t<grandchild>{}, 3);
158 auto p2 = ceph::dynamic_pointer_cast<grandchild, sz>(std::move(p1));
159 EXPECT_TRUE(p2);
160 EXPECT_EQ(p2->func(), 9);
161 EXPECT_EQ(p2->call(10), 30);
162 }
163}
164
165class constable {
166public:
167 int foo() {
168 return 2;
169 }
170 int foo() const {
171 return 5;
172 }
173};
174
175TEST(StaticPtr, ConstCast) {
176 static constexpr auto sz = sizeof(constable);
11fdf7f2
TL
177 {
178 auto p1 = make_static<const constable>();
179 EXPECT_EQ(p1->foo(), 5);
180 auto p2 = ceph::const_pointer_cast<constable, sz>(std::move(p1));
181 static_assert(!std::is_const<decltype(p2)::element_type>{},
182 "Things are more const than they ought to be.");
183 EXPECT_TRUE(p2);
184 EXPECT_EQ(p2->foo(), 2);
185 }
186}
187
188TEST(StaticPtr, ReinterpretCast) {
189 static constexpr auto sz = sizeof(grandchild);
11fdf7f2
TL
190 {
191 auto p1 = make_static<grandchild>(3);
192 auto p2 = ceph::reinterpret_pointer_cast<constable, sz>(std::move(p1));
193 static_assert(std::is_same<decltype(p2)::element_type, constable>{},
194 "Reinterpret is screwy.");
195 auto p3 = ceph::reinterpret_pointer_cast<grandchild, sz>(std::move(p2));
196 static_assert(std::is_same<decltype(p3)::element_type, grandchild>{},
197 "Reinterpret is screwy.");
198 EXPECT_EQ(p3->func(), 9);
199 EXPECT_EQ(p3->call(10), 30);
200 }
201}
202
203struct exceptional {
204 exceptional() = default;
205 exceptional(const exceptional& e) {
206 throw std::exception();
207 }
208 exceptional(exceptional&& e) {
209 throw std::exception();
210 }
211};
212
213TEST(StaticPtr, Exceptional) {
214 static_ptr<exceptional> p1(std::in_place_type_t<exceptional>{});
11fdf7f2
TL
215 EXPECT_ANY_THROW(static_ptr<exceptional> p2(std::move(p1)));
216}