22class SharedReadablePtr final {
23 static_assert(!std::is_const_v<T>,
24 "SharedReadablePtr already adds `const` to `T`");
25 static_assert(!std::is_reference_v<T>,
26 "SharedReadablePtr does not work with references");
29 using Base = std::shared_ptr<
const T>;
30 using MutableBase = std::shared_ptr<T>;
31 using Weak =
typename Base::weak_type;
32 using Unique = std::unique_ptr<
const T>;
33 using element_type = T;
35 SharedReadablePtr(
const SharedReadablePtr& ptr)
noexcept =
default;
36 SharedReadablePtr(SharedReadablePtr&& ptr)
noexcept =
default;
38 constexpr SharedReadablePtr(std::nullptr_t)
noexcept : base_(
nullptr) {}
40 SharedReadablePtr& operator=(
const SharedReadablePtr& ptr)
noexcept =
default;
41 SharedReadablePtr& operator=(SharedReadablePtr&& ptr)
noexcept =
default;
43 SharedReadablePtr(
const Base& ptr)
noexcept : base_(ptr) {}
45 SharedReadablePtr(Base&& ptr)
noexcept : base_(std::move(ptr)) {}
47 SharedReadablePtr(
const MutableBase& ptr)
noexcept : base_(ptr) {}
49 SharedReadablePtr(MutableBase&& ptr)
noexcept : base_(std::move(ptr)) {}
51 SharedReadablePtr(Unique&& ptr)
noexcept : base_(std::move(ptr)) {}
53 SharedReadablePtr& operator=(
const Base& ptr)
noexcept {
58 SharedReadablePtr& operator=(Base&& ptr)
noexcept {
59 base_ = std::move(ptr);
63 SharedReadablePtr& operator=(
const MutableBase& ptr)
noexcept {
68 SharedReadablePtr& operator=(MutableBase&& ptr)
noexcept {
69 base_ = std::move(ptr);
73 SharedReadablePtr& operator=(std::nullptr_t)
noexcept {
78 const T* Get()
const&
noexcept {
return base_.get(); }
80 const T& operator*()
const&
noexcept {
return *base_; }
82 const T& operator*() && { ReportMisuse(); }
84 const T* operator->()
const&
noexcept {
return base_.get(); }
86 const T* operator->() && { ReportMisuse(); }
88 operator
const Base&()
const&
noexcept {
return base_; }
90 operator
const Base&() && { ReportMisuse(); }
92 operator Weak()
const&
noexcept {
return base_; }
94 operator Weak() && { ReportMisuse(); }
96 explicit operator
bool()
const noexcept {
return !!base_; }
98 bool operator==(
const SharedReadablePtr<T>& other)
const {
99 return base_ == other.base_;
102 bool operator!=(
const SharedReadablePtr<T>& other)
const {
103 return !(*
this == other);
106 void Reset()
noexcept { base_.reset(); }
109 [[noreturn]]
static void ReportMisuse() {
110 static_assert(!
sizeof(T),
"keep the pointer before using, please");
117bool operator==(
const SharedReadablePtr<T>& ptr, std::nullptr_t) {
122bool operator==(std::nullptr_t,
const SharedReadablePtr<T>& ptr) {
127bool operator!=(
const SharedReadablePtr<T>& ptr, std::nullptr_t) {
128 return !(ptr ==
nullptr);
132bool operator!=(std::nullptr_t,
const SharedReadablePtr<T>& ptr) {
133 return !(
nullptr == ptr);
136template <
typename T,
typename... Args>
137SharedReadablePtr<T> MakeSharedReadable(Args&&... args) {
138 return SharedReadablePtr<T>{std::make_shared<T>(std::forward<Args>(args)...)};