39class SharedReadablePtr final {
40 static_assert(!std::is_const_v<T>,
"SharedReadablePtr already adds `const` to `T`");
41 static_assert(!std::is_reference_v<T>,
"SharedReadablePtr does not work with references");
44 using Base = std::shared_ptr<
const T>;
45 using MutableBase = std::shared_ptr<T>;
46 using Weak =
typename Base::weak_type;
47 using Unique = std::unique_ptr<
const T>;
48 using element_type = T;
50 SharedReadablePtr(
const SharedReadablePtr& ptr)
noexcept =
default;
51 SharedReadablePtr(SharedReadablePtr&& ptr)
noexcept =
default;
53 constexpr SharedReadablePtr(std::nullptr_t)
noexcept : base_(
nullptr) {}
55 SharedReadablePtr& operator=(
const SharedReadablePtr& ptr)
noexcept =
default;
56 SharedReadablePtr& operator=(SharedReadablePtr&& ptr)
noexcept =
default;
58 SharedReadablePtr(
const Base& ptr)
noexcept : base_(ptr) {}
60 SharedReadablePtr(Base&& ptr)
noexcept : base_(std::move(ptr)) {}
62 SharedReadablePtr(
const MutableBase& ptr)
noexcept : base_(ptr) {}
64 SharedReadablePtr(MutableBase&& ptr)
noexcept : base_(std::move(ptr)) {}
66 SharedReadablePtr(Unique&& ptr)
noexcept : base_(std::move(ptr)) {}
68 SharedReadablePtr& operator=(
const Base& ptr)
noexcept {
73 SharedReadablePtr& operator=(Base&& ptr)
noexcept {
74 base_ = std::move(ptr);
78 SharedReadablePtr& operator=(
const MutableBase& ptr)
noexcept {
83 SharedReadablePtr& operator=(MutableBase&& ptr)
noexcept {
84 base_ = std::move(ptr);
88 SharedReadablePtr& operator=(std::nullptr_t)
noexcept {
93 const T* Get()
const&
noexcept {
return base_.get(); }
95 const T& operator*()
const&
noexcept {
return *base_; }
97 const T& operator*() && { ReportMisuse(); }
99 const T* operator->()
const&
noexcept {
return base_.get(); }
101 const T* operator->() && { ReportMisuse(); }
103 operator
const Base&()
const&
noexcept {
return base_; }
105 operator
const Base&() && { ReportMisuse(); }
107 operator Weak()
const&
noexcept {
return base_; }
109 operator Weak() && { ReportMisuse(); }
111 explicit operator
bool()
const noexcept {
return !!base_; }
113 bool operator==(
const SharedReadablePtr<T>& other)
const {
return base_ == other.base_; }
115 bool operator!=(
const SharedReadablePtr<T>& other)
const {
return !(*
this == other); }
117 void Reset()
noexcept { base_.reset(); }
120 [[noreturn]]
static void ReportMisuse() {
static_assert(!
sizeof(T),
"keep the pointer before using, please"); }
126bool operator==(
const SharedReadablePtr<T>& ptr, std::nullptr_t) {
131bool operator==(std::nullptr_t,
const SharedReadablePtr<T>& ptr) {
136bool operator!=(
const SharedReadablePtr<T>& ptr, std::nullptr_t) {
137 return !(ptr ==
nullptr);
141bool operator!=(std::nullptr_t,
const SharedReadablePtr<T>& ptr) {
142 return !(
nullptr == ptr);
145template <
typename T,
typename... Args>
146SharedReadablePtr<T> MakeSharedReadable(Args&&... args) {
147 return SharedReadablePtr<T>{std::make_shared<T>(std::forward<Args>(args)...)};