22class SharedReadablePtr final {
23 static_assert(!std::is_const_v<T>,
"SharedReadablePtr already adds `const` to `T`");
24 static_assert(!std::is_reference_v<T>,
"SharedReadablePtr does not work with references");
27 using Base = std::shared_ptr<
const T>;
28 using MutableBase = std::shared_ptr<T>;
29 using Weak =
typename Base::weak_type;
30 using Unique = std::unique_ptr<
const T>;
31 using element_type = T;
33 SharedReadablePtr(
const SharedReadablePtr& ptr)
noexcept =
default;
34 SharedReadablePtr(SharedReadablePtr&& ptr)
noexcept =
default;
36 constexpr SharedReadablePtr(std::nullptr_t)
noexcept : base_(
nullptr) {}
38 SharedReadablePtr& operator=(
const SharedReadablePtr& ptr)
noexcept =
default;
39 SharedReadablePtr& operator=(SharedReadablePtr&& ptr)
noexcept =
default;
41 SharedReadablePtr(
const Base& ptr)
noexcept : base_(ptr) {}
43 SharedReadablePtr(Base&& ptr)
noexcept : base_(std::move(ptr)) {}
45 SharedReadablePtr(
const MutableBase& ptr)
noexcept : base_(ptr) {}
47 SharedReadablePtr(MutableBase&& ptr)
noexcept : base_(std::move(ptr)) {}
49 SharedReadablePtr(Unique&& ptr)
noexcept : base_(std::move(ptr)) {}
51 SharedReadablePtr& operator=(
const Base& ptr)
noexcept {
56 SharedReadablePtr& operator=(Base&& ptr)
noexcept {
57 base_ = std::move(ptr);
61 SharedReadablePtr& operator=(
const MutableBase& ptr)
noexcept {
66 SharedReadablePtr& operator=(MutableBase&& ptr)
noexcept {
67 base_ = std::move(ptr);
71 SharedReadablePtr& operator=(std::nullptr_t)
noexcept {
76 const T* Get()
const&
noexcept {
return base_.get(); }
78 const T& operator*()
const&
noexcept {
return *base_; }
80 const T& operator*() && { ReportMisuse(); }
82 const T* operator->()
const&
noexcept {
return base_.get(); }
84 const T* operator->() && { ReportMisuse(); }
86 operator
const Base&()
const&
noexcept {
return base_; }
88 operator
const Base&() && { ReportMisuse(); }
90 operator Weak()
const&
noexcept {
return base_; }
92 operator Weak() && { ReportMisuse(); }
94 explicit operator
bool()
const noexcept {
return !!base_; }
96 bool operator==(
const SharedReadablePtr<T>& other)
const {
return base_ == other.base_; }
98 bool operator!=(
const SharedReadablePtr<T>& other)
const {
return !(*
this == other); }
100 void Reset()
noexcept { base_.reset(); }
103 [[noreturn]]
static void ReportMisuse() {
static_assert(!
sizeof(T),
"keep the pointer before using, please"); }
109bool operator==(
const SharedReadablePtr<T>& ptr, std::nullptr_t) {
114bool operator==(std::nullptr_t,
const SharedReadablePtr<T>& ptr) {
119bool operator!=(
const SharedReadablePtr<T>& ptr, std::nullptr_t) {
120 return !(ptr ==
nullptr);
124bool operator!=(std::nullptr_t,
const SharedReadablePtr<T>& ptr) {
125 return !(
nullptr == ptr);
128template <
typename T,
typename... Args>
129SharedReadablePtr<T> MakeSharedReadable(Args&&... args) {
130 return SharedReadablePtr<T>{std::make_shared<T>(std::forward<Args>(args)...)};