MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
exception_ptr.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_EXCEPTION_EXCEPTION_PTR_HPP__
2#define MSTL_CORE_EXCEPTION_EXCEPTION_PTR_HPP__
3
10
13#include <typeinfo>
15
21
30public:
31 virtual ~exception_wrapper() = default;
32
38 virtual void rethrow() const = 0;
39
44 virtual const std::type_info& type() const noexcept = 0;
45
52 virtual unique_ptr<exception_wrapper> clone() const = 0;
53};
54
62template <typename Ex>
64 Ex exception_;
65
66public:
72 : exception_(ex) {}
73
78 typed_exception_wrapper(Ex&& ex) noexcept
79 : exception_(_MSTL move(ex)) {}
80
85 MSTL_ALWAYS_INLINE void rethrow() const override {
86 throw exception_;
87 }
88
93 MSTL_ALWAYS_INLINE const std::type_info& type() const noexcept override {
94 return typeid(Ex);
95 }
96
101 MSTL_ALWAYS_INLINE unique_ptr<exception_wrapper> clone() const override {
103 }
104};
105
106
113class exception_ptr {
114public:
121 struct ecb {
124
131
135 MSTL_ALWAYS_INLINE void add_ref() noexcept {
136 ref_count.fetch_add(1, memory_order_relaxed);
137 }
138
143 MSTL_ALWAYS_INLINE void release() noexcept {
144 if (ref_count.load(memory_order_acquire) == 1 ||
145 ref_count.fetch_sub(1, memory_order_acq_rel) == 1) {
146 delete this;
147 }
148 }
149 };
150
151private:
152 ecb* ecb_{nullptr};
153
159 explicit exception_ptr(ecb* cb) noexcept : ecb_(cb) {}
160
161 template <typename Ex>
162 friend exception_ptr make_exception_ptr(Ex) noexcept;
163
164 friend exception_ptr MSTL_API current_exception() noexcept;
165
166 friend void MSTL_API rethrow_exception(const exception_ptr &);
167
168 template <typename Ex>
169 friend exception_ptr make_exception_ptr(Ex ex) noexcept;
170
171public:
178 exception_ptr(nullptr_t np = nullptr) noexcept {}
179
186 exception_ptr(const exception_ptr& other) noexcept
187 : ecb_(other.ecb_) {
188 if (ecb_) ecb_->add_ref();
189 }
190
197 exception_ptr(exception_ptr&& other) noexcept
198 : ecb_(other.ecb_) {
199 other.ecb_ = nullptr;
200 }
201
207 ~exception_ptr() noexcept {
208 if (ecb_) {
209 ecb_->release();
210 }
211 }
212
218 exception_ptr& operator =(const exception_ptr& other) noexcept {
219 if (this != &other) {
220 exception_ptr temp(other);
221 swap(temp);
222 }
223 return *this;
224 }
225
231 exception_ptr& operator =(exception_ptr&& other) noexcept {
232 if (this != &other) {
233 exception_ptr temp(_MSTL move(other));
234 _MSTL swap(ecb_, other.ecb_);
235 }
236 return *this;
237 }
238
243 void swap(exception_ptr& other) noexcept {
244 _MSTL swap(ecb_, other.ecb_);
245 }
246
253 explicit operator bool() const noexcept {
254 return ecb_ != nullptr;
255 }
256
264 bool operator ==(const exception_ptr& rhs) const noexcept {
265 return ecb_ == rhs.ecb_;
266 }
267
273 bool operator !=(const exception_ptr& rhs) const noexcept {
274 return !(*this == rhs);
275 }
276
281 bool operator ==(nullptr_t) const noexcept {
282 return !static_cast<bool>(*this);
283 }
284
288 friend bool operator ==(nullptr_t, const exception_ptr& ptr) noexcept {
289 return !ptr;
290 }
291
296 bool operator !=(nullptr_t) const noexcept {
297 return static_cast<bool>(*this);
298 }
299
303 friend bool operator!=(nullptr_t, const exception_ptr& ptr) noexcept {
304 return static_cast<bool>(ptr);
305 }
306
313 MSTL_NODISCARD const std::type_info& exception_type() const noexcept {
314 if (!ecb_ || !ecb_->wrapper) {
315 return typeid(void);
316 }
317 return ecb_->wrapper->type();
318 }
319};
320
321
331template <typename Ex>
332exception_ptr make_exception_ptr(Ex ex) noexcept {
333 try {
335 unique_ptr<exception_ptr::ecb> control_block(new exception_ptr::ecb(_MSTL move(wrapper)));
336 exception_ptr result;
337 result.ecb_ = control_block.release();
338 return result;
339 } catch (...) {
340 return exception_ptr();
341 }
342}
343
352
361void MSTL_API rethrow_exception(const exception_ptr& p);
362
364#endif // MSTL_CORE_EXCEPTION_EXCEPTION_PTR_HPP__
MSTL原子类型完整实现
异常包装器基类
独占智能指针
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
atomic< int > atomic_int
整型原子类型
decltype(nullptr) nullptr_t
空指针类型
exception_ptr(exception_ptr &&other) noexcept
移动构造函数
typed_exception_wrapper(const Ex &ex)
拷贝构造函数
exception_ptr(const exception_ptr &other) noexcept
拷贝构造函数
typed_exception_wrapper(Ex &&ex) noexcept
移动构造函数
virtual void rethrow() const =0
重新抛出异常
~exception_ptr() noexcept
析构函数
virtual unique_ptr< exception_wrapper > clone() const =0
克隆异常包装器
atomic_int ref_count
引用计数
MSTL_ALWAYS_INLINE const std::type_info & type() const noexcept override
获取异常类型信息
MSTL_ALWAYS_INLINE void release() noexcept
减少引用计数
MSTL_ALWAYS_INLINE void rethrow() const override
重新抛出异常
virtual const std::type_info & type() const noexcept=0
获取异常类型信息
unique_ptr< exception_wrapper > wrapper
异常包装器
friend exception_ptr MSTL_API current_exception() noexcept
获取当前异常
exception_ptr make_exception_ptr(Ex ex) noexcept
创建异常指针
MSTL_ALWAYS_INLINE void add_ref() noexcept
增加引用计数
friend void MSTL_API rethrow_exception(const exception_ptr &)
重新抛出异常
MSTL_NODISCARD const std::type_info & exception_type() const noexcept
获取异常类型信息
ecb(unique_ptr< exception_wrapper > wrapper)
构造函数
friend bool operator!=(nullptr_t, const exception_ptr &ptr) noexcept
空指针与异常指针比较不等
void swap(exception_ptr &other) noexcept
交换两个异常指针
MSTL_ALWAYS_INLINE unique_ptr< exception_wrapper > clone() const override
克隆异常包装器
bool operator!=(const function< Res(Args...)> &f, nullptr_t null) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t null) noexcept
等于空指针比较
MSTL_INLINE17 constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_acquire
获取内存顺序常量
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
void swap()=delete
删除无参数的swap重载
MSTL_CONSTEXPR20 unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
MSTL独占智能指针