Skip to content

Commit 22ce6f7

Browse files
committed
shared_ptr improvements
- removed unnecessary virtual functions - may reduce sizeof(shared_ptr) by 50% (sizeof(shared_ptr) may be just 16 bytes - removed unused header cstdlib - rule of 0 (removed destructor) - replace unique_ptr.release() by std::move() to make it more clear/readable
1 parent 1018d87 commit 22ce6f7

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

api/include/opentelemetry/nostd/shared_ptr.h

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#endif
1212

1313
#if !defined(OPENTELEMETRY_HAVE_STD_SHARED_PTR)
14-
# include <cstdlib>
1514
# include <memory>
1615
# include <utility>
1716

@@ -32,13 +31,9 @@ class shared_ptr
3231
using pointer = element_type *;
3332

3433
private:
35-
static constexpr size_t kMaxSize = 32;
3634
static constexpr size_t kAlignment = 8;
3735

38-
struct alignas(kAlignment) PlacementBuffer
39-
{
40-
char data[kMaxSize]{};
41-
};
36+
struct alignas(kAlignment) PlacementBuffer; // fwd.
4237

4338
class shared_ptr_wrapper
4439
{
@@ -47,14 +42,12 @@ class shared_ptr
4742

4843
shared_ptr_wrapper(std::shared_ptr<T> &&ptr) noexcept : ptr_{std::move(ptr)} {}
4944

50-
virtual ~shared_ptr_wrapper() {}
51-
52-
virtual void CopyTo(PlacementBuffer &buffer) const noexcept
45+
void CopyTo(PlacementBuffer &buffer) const noexcept
5346
{
5447
new (buffer.data) shared_ptr_wrapper{*this};
5548
}
5649

57-
virtual void MoveTo(PlacementBuffer &buffer) noexcept
50+
void MoveTo(PlacementBuffer &buffer) noexcept
5851
{
5952
new (buffer.data) shared_ptr_wrapper{std::move(this->ptr_)};
6053
}
@@ -67,15 +60,19 @@ class shared_ptr
6760
new (buffer.data) other_shared_ptr_wrapper{std::move(this->ptr_)};
6861
}
6962

70-
virtual pointer Get() const noexcept { return ptr_.get(); }
63+
pointer Get() const noexcept { return ptr_.get(); }
7164

72-
virtual void Reset() noexcept { ptr_.reset(); }
65+
void Reset() noexcept { ptr_.reset(); }
7366

7467
private:
7568
std::shared_ptr<T> ptr_;
7669
};
7770

78-
static_assert(sizeof(shared_ptr_wrapper) <= kMaxSize, "Placement buffer is too small");
71+
struct alignas(kAlignment) PlacementBuffer
72+
{
73+
char data[sizeof(shared_ptr_wrapper)]{};
74+
};
75+
7976
static_assert(alignof(shared_ptr_wrapper) <= kAlignment, "Placement buffer not properly aligned");
8077

8178
public:
@@ -105,20 +102,24 @@ class shared_ptr
105102

106103
shared_ptr(unique_ptr<T> &&other) noexcept
107104
{
108-
std::shared_ptr<T> ptr_(other.release());
105+
std::shared_ptr<T> ptr_(std::move(other));
109106
new (buffer_.data) shared_ptr_wrapper{std::move(ptr_)};
110107
}
111108

112109
shared_ptr(std::unique_ptr<T> &&other) noexcept
113110
{
114-
std::shared_ptr<T> ptr_(other.release());
111+
std::shared_ptr<T> ptr_(std::move(other));
115112
new (buffer_.data) shared_ptr_wrapper{std::move(ptr_)};
116113
}
117114

118115
~shared_ptr() { wrapper().~shared_ptr_wrapper(); }
119116

120117
shared_ptr &operator=(shared_ptr &&other) noexcept
121118
{
119+
if (this == &other)
120+
{
121+
return *this;
122+
}
122123
wrapper().~shared_ptr_wrapper();
123124
other.wrapper().MoveTo(buffer_);
124125
return *this;
@@ -132,6 +133,10 @@ class shared_ptr
132133

133134
shared_ptr &operator=(const shared_ptr &other) noexcept
134135
{
136+
if (this == &other)
137+
{
138+
return *this;
139+
}
135140
wrapper().~shared_ptr_wrapper();
136141
other.wrapper().CopyTo(buffer_);
137142
return *this;

0 commit comments

Comments
 (0)