6 #if defined(OPENTELEMETRY_STL_VERSION)
7 # if OPENTELEMETRY_STL_VERSION >= 2011
8 # include "opentelemetry/std/shared_ptr.h"
9 # define OPENTELEMETRY_HAVE_STD_SHARED_PTR
13 #if !defined(OPENTELEMETRY_HAVE_STD_SHARED_PTR)
18 # include "opentelemetry/nostd/unique_ptr.h"
19 # include "opentelemetry/version.h"
35 static constexpr
size_t kMaxSize = 32;
36 static constexpr
size_t kAlignment = 8;
38 struct alignas(kAlignment) PlacementBuffer
40 char data[kMaxSize]{};
43 class shared_ptr_wrapper
46 shared_ptr_wrapper() noexcept = default;
50 virtual ~shared_ptr_wrapper() {}
52 virtual void CopyTo(PlacementBuffer &buffer)
const noexcept
54 new (buffer.data) shared_ptr_wrapper{*
this};
57 virtual void MoveTo(PlacementBuffer &buffer) noexcept
59 new (buffer.data) shared_ptr_wrapper{
std::move(this->ptr_)};
63 typename std::enable_if<std::is_convertible<pointer, U *>::value>::type * =
nullptr>
64 void MoveTo(
typename shared_ptr<U>::PlacementBuffer &buffer) noexcept
66 using other_shared_ptr_wrapper =
typename shared_ptr<U>::shared_ptr_wrapper;
67 new (buffer.data) other_shared_ptr_wrapper{
std::move(this->ptr_)};
70 virtual pointer Get() const noexcept {
return ptr_.get(); }
72 virtual void Reset() noexcept { ptr_.reset(); }
75 std::shared_ptr<T> ptr_;
78 static_assert(
sizeof(shared_ptr_wrapper) <= kMaxSize,
"Placement buffer is too small");
79 static_assert(
alignof(shared_ptr_wrapper) <= kAlignment,
"Placement buffer not properly aligned");
82 shared_ptr() noexcept {
new (buffer_.data) shared_ptr_wrapper{}; }
86 std::shared_ptr<T> ptr_(ptr);
87 new (buffer_.data) shared_ptr_wrapper{
std::move(ptr_)};
92 new (buffer_.data) shared_ptr_wrapper{
std::move(ptr)};
98 typename std::enable_if<std::is_convertible<U *, pointer>::value>::type * =
nullptr>
101 other.wrapper().template MoveTo<T>(buffer_);
108 std::shared_ptr<T> ptr_(other.release());
109 new (buffer_.data) shared_ptr_wrapper{
std::move(ptr_)};
114 std::shared_ptr<T> ptr_(other.release());
115 new (buffer_.data) shared_ptr_wrapper{
std::move(ptr_)};
122 wrapper().~shared_ptr_wrapper();
123 other.wrapper().MoveTo(buffer_);
135 wrapper().~shared_ptr_wrapper();
136 other.wrapper().CopyTo(buffer_);
144 operator bool() const noexcept {
return wrapper().Get() !=
nullptr; }
152 wrapper().MoveTo(other.buffer_);
153 tmp.wrapper().MoveTo(buffer_);
156 template <
typename U>
160 PlacementBuffer buffer_;
162 shared_ptr_wrapper &wrapper() noexcept
164 return *
reinterpret_cast<shared_ptr_wrapper *
>(buffer_.data);
167 const shared_ptr_wrapper &wrapper() const noexcept
169 return *
reinterpret_cast<const shared_ptr_wrapper *
>(buffer_.data);
173 template <
class T1,
class T2>
174 bool operator!=(
const shared_ptr<T1> &lhs,
const shared_ptr<T2> &rhs) noexcept
176 return lhs.get() != rhs.get();
179 template <
class T1,
class T2>
180 bool operator==(
const shared_ptr<T1> &lhs,
const shared_ptr<T2> &rhs) noexcept
182 return lhs.get() == rhs.get();
186 inline bool operator==(
const shared_ptr<T> &lhs, std::nullptr_t) noexcept
188 return lhs.get() ==
nullptr;
192 inline bool operator==(std::nullptr_t,
const shared_ptr<T> &rhs) noexcept
194 return nullptr == rhs.get();
198 inline bool operator!=(
const shared_ptr<T> &lhs, std::nullptr_t) noexcept
200 return lhs.get() !=
nullptr;
204 inline bool operator!=(std::nullptr_t,
const shared_ptr<T> &rhs) noexcept
206 return nullptr != rhs.get();