y3c-stl 0.3.3
Friendly C++ STL wrapper with automatic stacktrace
Loading...
Searching...
No Matches
shared_ptr.h
Go to the documentation of this file.
1#pragma once
2#include "y3c/terminate.h"
3#include "y3c/wrap.h"
4#include "y3c/typename.h"
5#include <memory>
6
7namespace y3c {
8
27template <typename T>
29 std::shared_ptr<T> base_;
30 std::shared_ptr<internal::life> ptr_life_;
31 internal::life life_;
32
33 const std::string &type_name() const {
34 return internal::get_type_name<shared_ptr>();
35 }
36
37 public:
41 shared_ptr(std::nullptr_t = nullptr) noexcept
42 : base_(nullptr), ptr_life_(nullptr), life_(this) {}
46 shared_ptr(const shared_ptr &other)
47 : base_(other.base_), ptr_life_(other.ptr_life_), life_(this) {}
52 if (this != std::addressof(other)) {
53 base_ = other.base_;
54 ptr_life_ = other.ptr_life_;
55 }
56 return *this;
57 }
62 : base_(std::move(other.base_)), ptr_life_(std::move(other.ptr_life_)),
63 life_(this) {}
68 if (this != std::addressof(other)) {
69 base_ = std::move(other.base_);
70 ptr_life_ = std::move(other.ptr_life_);
71 }
72 return *this;
73 }
74 ~shared_ptr() = default;
75
76 using element_type = T;
77
81 template <typename U>
82 shared_ptr(const std::shared_ptr<U> &ptr)
83 : base_(ptr), ptr_life_(std::make_shared<internal::life>(base_.get())),
84 life_(this) {}
88 template <typename U>
89 shared_ptr &operator=(const std::shared_ptr<U> &ptr) {
90 base_ = ptr;
91 ptr_life_ = std::make_shared<internal::life>(base_.get());
92 return *this;
93 }
97 template <typename U>
98 shared_ptr(std::shared_ptr<U> &&ptr)
99 : base_(std::move(ptr)),
100 ptr_life_(std::make_shared<internal::life>(base_.get())),
101 life_(this) {}
105 template <typename U>
106 shared_ptr &operator=(std::shared_ptr<U> &&ptr) {
107 base_ = std::move(ptr);
108 ptr_life_ = std::make_shared<internal::life>(base_.get());
109 return *this;
110 }
111
115 template <typename U>
117 : base_(other.base_), ptr_life_(other.ptr_life_), life_(this) {}
121 template <typename U>
123 base_ = other.base_;
124 ptr_life_ = other.ptr_life_;
125 return *this;
126 }
130 template <typename U>
132 : base_(std::move(other.base_)), ptr_life_(std::move(other.ptr_life_)),
133 life_(this) {}
137 template <typename U>
139 base_ = std::move(other.base_);
140 ptr_life_ = std::move(other.ptr_life_);
141 return *this;
142 }
143
144 template <typename U>
145 friend class shared_ptr;
146
152 void reset() noexcept {
153 base_.reset();
154 ptr_life_.reset();
155 }
159 void swap(shared_ptr &other) noexcept {
160 base_.swap(other.base_);
161 ptr_life_.swap(other.ptr_life_);
162 }
163
171 ptr<element_type> get() const noexcept {
172 if (!base_) {
173 return nullptr;
174 }
175 y3c_assert_internal(ptr_life_);
176 return ptr<element_type>(base_.get(), ptr_life_->observer());
177 }
185 template <typename E = element_type, typename = internal::skip_trace_tag>
187 if (!base_) {
188 static std::string func = type_name() + "::operator*()";
190 }
191 y3c_assert_internal(ptr_life_);
192 return y3c::wrap_ref<E>(base_.get(), ptr_life_->observer());
193 }
201 template <typename = internal::skip_trace_tag>
203 if (!base_) {
204 static std::string func = type_name() + "::operator->()";
206 }
207 y3c_assert_internal(ptr_life_);
208 return base_.get();
209 }
210 // template <typename U = T>
211 // U &operator[](std::ptrdiff_t i) const {
212 // if (i < 0 || todo)
213 // return check_()[i];
214 // }
215
223 long use_count() const noexcept { return base_.use_count(); }
229 explicit operator bool() const noexcept { return static_cast<bool>(base_); }
233 bool owner_before(const shared_ptr &arg) const {
234 return base_.owner_before(arg.base_);
235 }
236
240 operator const std::shared_ptr<T> &() const noexcept { return base_; }
241
242 operator wrap<const shared_ptr &>() const noexcept {
243 return wrap<const shared_ptr &>(this, life_.observer());
244 }
246 return wrap<const shared_ptr *>(this, life_.observer());
247 }
248};
249
250template <typename T>
251const std::shared_ptr<T> &unwrap(const shared_ptr<T> &wrapper) noexcept {
252 return static_cast<const std::shared_ptr<T> &>(wrapper);
253}
254
255template <typename T>
256void swap(shared_ptr<T> &lhs, shared_ptr<T> &rhs) noexcept {
257 lhs.swap(rhs);
258}
259
260template <typename T, typename U>
261bool operator==(const shared_ptr<T> &lhs, const shared_ptr<U> &rhs) noexcept {
262 return unwrap(lhs) == unwrap(rhs);
263}
264template <typename T, typename U>
265bool operator!=(const shared_ptr<T> &lhs, const shared_ptr<U> &rhs) noexcept {
266 return unwrap(lhs) != unwrap(rhs);
267}
268template <typename T, typename U>
269bool operator<(const shared_ptr<T> &lhs, const shared_ptr<U> &rhs) noexcept {
270 return unwrap(lhs) < unwrap(rhs);
271}
272template <typename T, typename U>
273bool operator<=(const shared_ptr<T> &lhs, const shared_ptr<U> &rhs) noexcept {
274 return unwrap(lhs) <= unwrap(rhs);
275}
276template <typename T, typename U>
277bool operator>(const shared_ptr<T> &lhs, const shared_ptr<U> &rhs) noexcept {
278 return unwrap(lhs) > unwrap(rhs);
279}
280template <typename T, typename U>
281bool operator>=(const shared_ptr<T> &lhs, const shared_ptr<U> &rhs) noexcept {
282 return unwrap(lhs) >= unwrap(rhs);
283}
284
285template <class CharT, class Traits, typename T>
286std::basic_ostream<CharT, Traits> &
287operator<<(std::basic_ostream<CharT, Traits> &os, const shared_ptr<T> &p) {
288 return os << unwrap(p);
289}
290
297template <typename T, typename... Args>
298shared_ptr<T> make_shared(Args &&...args) {
299 return shared_ptr<T>(std::make_shared<T>(std::forward<Args>(args)...));
300}
301
302} // namespace y3c
オブジェクトのライフタイムを管理するクラス
Definition life.h:207
life_observer observer() const
Definition life.h:233
所有権を共有するスマートポインタ (std::shared_ptr)
Definition shared_ptr.h:28
void reset() noexcept
所有権を放棄
Definition shared_ptr.h:152
shared_ptr(const std::shared_ptr< U > &ptr)
std::shared_ptrからのコピー
Definition shared_ptr.h:82
shared_ptr & operator=(const std::shared_ptr< U > &ptr)
std::shared_ptrからのコピー
Definition shared_ptr.h:89
ptr< element_type > get() const noexcept
ポインタを取得
Definition shared_ptr.h:171
shared_ptr & operator=(std::shared_ptr< U > &&ptr)
std::shared_ptrからの所有権の移動
Definition shared_ptr.h:106
shared_ptr & operator=(shared_ptr &&other)
ムーブ代入: 所有権を移動する
Definition shared_ptr.h:67
long use_count() const noexcept
所有権を共有しているshared_ptrの数を取得
Definition shared_ptr.h:223
shared_ptr(std::shared_ptr< U > &&ptr)
std::shared_ptrからの所有権の移動
Definition shared_ptr.h:98
shared_ptr & operator=(const shared_ptr< U > &other)
別の要素型のshared_ptrとリソースを共有する
Definition shared_ptr.h:122
~shared_ptr()=default
bool owner_before(const shared_ptr &arg) const
所有権ベースでのポインタ比較
Definition shared_ptr.h:233
shared_ptr(shared_ptr< U > &&other)
別の要素型のshared_ptrから所有権を移動
Definition shared_ptr.h:131
wrap< const shared_ptr * > operator&() const
Definition shared_ptr.h:245
element_type * operator->() const
メンバアクセス
Definition shared_ptr.h:202
T element_type
Definition shared_ptr.h:76
void swap(shared_ptr &other) noexcept
所有権を入れ替える
Definition shared_ptr.h:159
shared_ptr(const shared_ptr< U > &other)
別の要素型のshared_ptrとリソースを共有する
Definition shared_ptr.h:116
shared_ptr(shared_ptr &&other)
ムーブコンストラクタ: 所有権を移動する
Definition shared_ptr.h:61
y3c::wrap_ref< E > operator*() const
要素の間接参照
Definition shared_ptr.h:186
shared_ptr & operator=(shared_ptr< U > &&other)
別の要素型のshared_ptrから所有権を移動
Definition shared_ptr.h:138
shared_ptr(const shared_ptr &other)
コピーコンストラクタ: リソースを共有する
Definition shared_ptr.h:46
shared_ptr & operator=(const shared_ptr &other)
コピー代入: リソースを共有する
Definition shared_ptr.h:51
shared_ptr(std::nullptr_t=nullptr) noexcept
デフォルトコンストラクタ: nullptrを指す
Definition shared_ptr.h:41
ポインタ型wrap: element_type型のデータへのポインタと、 このポインタ自体の生存状態を管理するクラス
Definition wrap.h:318
参照型wrap: element_type型のデータへの参照を持つクラス
Definition wrap.h:168
値型wrap: base_type型のデータと、このデータの生存状態を管理するクラス
Definition wrap.h:26
void terminate_ub_access_nullptr(std::string func, Args &&...args)
Definition terminate.h:133
Definition array.h:8
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const shared_ptr< T > &p)
Definition shared_ptr.h:287
shared_ptr< T > make_shared(Args &&...args)
shared_ptrを構築する
Definition shared_ptr.h:298
bool operator!=(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:390
bool operator<=(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:398
void swap(array< T, N > &lhs, array< T, N > &rhs)
Definition array.h:381
bool operator==(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:386
std::array< T, N > & unwrap(array< T, N > &wrapper) noexcept
Definition array.h:372
bool operator>(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:402
bool operator<(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:394
wrap< element_type * > ptr
Definition wrap.h:487
bool operator>=(const array< T, N > &lhs, const array< T, N > &rhs)
Definition array.h:406
#define y3c_assert_internal(cond)
Definition terminate.h:148