]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/common/test_static_ptr.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2017 Red Hat, Inc.
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.
16 #include <gtest/gtest.h>
17 #include "common/static_ptr.h"
19 using ceph::static_ptr
;
20 using ceph::make_static
;
24 virtual int func() = 0;
25 virtual ~base() = default;
28 class sibling1
: public base
{
30 int func() override
{ return 0; }
33 class sibling2
: public base
{
35 int func() override
{ return 9; }
36 virtual int call(int) = 0;
39 class grandchild
: public sibling2
{
43 explicit grandchild(int val
) : val(val
) {}
44 virtual int call(int n
) override
{ return n
* val
; }
47 class great_grandchild
: public grandchild
{
49 explicit great_grandchild(int val
) : grandchild(val
) {}
50 int call(int n
) override
{ return n
+ val
; }
53 #ifdef __cpp_lib_three_way_comparison
54 TEST(StaticPtr
, EmptyCreation
) {
55 static_ptr
<base
, sizeof(grandchild
)> p
;
57 EXPECT_EQ(p
, nullptr);
58 EXPECT_EQ(nullptr, p
);
59 EXPECT_TRUE(p
.get() == nullptr);
62 TEST(StaticPtr
, CreationCall
) {
64 static_ptr
<base
, sizeof(grandchild
)> p(std::in_place_type_t
<sibling1
>{});
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);
74 auto p
= make_static
<base
, sibling1
>();
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);
85 TEST(StaticPtr
, CreateReset
) {
87 static_ptr
<base
, sizeof(grandchild
)> p(std::in_place_type_t
<sibling1
>{});
88 EXPECT_EQ((p
.get())->func(), 0);
91 EXPECT_EQ(p
, nullptr);
92 EXPECT_EQ(nullptr, p
);
93 EXPECT_TRUE(p
.get() == nullptr);
96 static_ptr
<base
, sizeof(grandchild
)> p(std::in_place_type_t
<sibling1
>{});
97 EXPECT_EQ((p
.get())->func(), 0);
100 EXPECT_EQ(p
, nullptr);
101 EXPECT_EQ(nullptr, p
);
102 EXPECT_TRUE(p
.get() == nullptr);
105 #endif // __cpp_lib_three_way_comparison
107 TEST(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);
114 TEST(StaticPtr
, Move
) {
115 // Won't compile. Good.
116 // static_ptr<base, sizeof(base)> p1(std::in_place_type_t<grandchild>{}, 3);
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
>{},
123 EXPECT_EQ(p1
->func(), 0);
126 TEST(StaticPtr
, ImplicitUpcast
) {
127 static_ptr
<base
, sizeof(grandchild
)> p1
;
128 static_ptr
<sibling2
, sizeof(grandchild
)> p2(std::in_place_type_t
<grandchild
>{}, 3);
131 EXPECT_EQ(p1
->func(), 9);
135 // Doesn't compile. Good.
139 TEST(StaticPtr
, StaticCast
) {
140 static_ptr
<base
, sizeof(grandchild
)> p1(std::in_place_type_t
<grandchild
>{}, 3);
141 static_ptr
<sibling2
, sizeof(grandchild
)> p2
;
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);
148 TEST(StaticPtr
, DynamicCast
) {
149 static constexpr auto sz
= sizeof(great_grandchild
);
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
));
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
));
160 EXPECT_EQ(p2
->func(), 9);
161 EXPECT_EQ(p2
->call(10), 30);
175 TEST(StaticPtr
, ConstCast
) {
176 static constexpr auto sz
= sizeof(constable
);
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.");
184 EXPECT_EQ(p2
->foo(), 2);
188 TEST(StaticPtr
, ReinterpretCast
) {
189 static constexpr auto sz
= sizeof(grandchild
);
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);
204 exceptional() = default;
205 exceptional(const exceptional
& e
) {
206 throw std::exception();
208 exceptional(exceptional
&& e
) {
209 throw std::exception();
213 TEST(StaticPtr
, Exceptional
) {
214 static_ptr
<exceptional
> p1(std::in_place_type_t
<exceptional
>{});
215 EXPECT_ANY_THROW(static_ptr
<exceptional
> p2(std::move(p1
)));