NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
exception_ptr.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_EXCEPTION_EXCEPTION_PTR_HPP__
2#define NEFORCE_CORE_EXCEPTION_EXCEPTION_PTR_HPP__
3
10
11#include <typeinfo>
14NEFORCE_BEGIN_NAMESPACE__
15
21
30public:
31 virtual ~exception_wrapper() = default;
32
38 NEFORCE_NORETURN virtual void rethrow() const = 0;
39
44 NEFORCE_NODISCARD virtual const std::type_info& type() const noexcept = 0;
45
52 NEFORCE_NODISCARD 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_(_NEFORCE move(ex)) {}
80
85 NEFORCE_NORETURN NEFORCE_ALWAYS_INLINE void rethrow() const override { throw exception_; }
86
91 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE const std::type_info& type() const noexcept override { return typeid(Ex); }
92
97 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE unique_ptr<exception_wrapper> clone() const override {
98 return _NEFORCE make_unique<typed_exception_wrapper>(exception_);
99 }
100};
101
102class exception_ptr;
103
112NEFORCE_NORETURN void NEFORCE_API rethrow_exception(const exception_ptr& p);
113
120class exception_ptr {
121public:
128 struct ecb {
131
138
142 NEFORCE_ALWAYS_INLINE void add_ref() noexcept { ref_count.fetch_add(1, memory_order_relaxed); }
143
148 NEFORCE_ALWAYS_INLINE void release() noexcept {
149 if (ref_count.load(memory_order_acquire) == 1 || ref_count.fetch_sub(1, memory_order_acq_rel) == 1) {
150 delete this;
151 }
152 }
153 };
154
155private:
156 ecb* ecb_{nullptr};
157
163 explicit exception_ptr(ecb* cb) noexcept :
164 ecb_(cb) {}
165
166 template <typename Ex>
167 friend exception_ptr make_exception_ptr(Ex ex) noexcept;
168
169 friend exception_ptr NEFORCE_API current_exception() noexcept;
170
171 friend void NEFORCE_API rethrow_exception(const exception_ptr&);
172
173 template <typename Ex>
174 friend exception_ptr make_exception_ptr(Ex ex) noexcept;
175
176public:
183 exception_ptr(nullptr_t np = nullptr) noexcept {}
184
191 exception_ptr(const exception_ptr& other) noexcept :
192 ecb_(other.ecb_) {
193 if (ecb_ != nullptr) {
194 ecb_->add_ref();
195 }
196 }
197
204 exception_ptr(exception_ptr&& other) noexcept :
205 ecb_(other.ecb_) {
206 other.ecb_ = nullptr;
207 }
208
214 ~exception_ptr() noexcept {
215 if (ecb_ != nullptr) {
216 ecb_->release();
217 }
218 }
219
225 exception_ptr& operator=(const exception_ptr& other) noexcept {
226 if (addressof(other) == this) {
227 return *this;
228 }
229 exception_ptr temp(other);
230 swap(temp);
231 return *this;
232 }
233
239 exception_ptr& operator=(exception_ptr&& other) noexcept {
240 if (addressof(other) == this) {
241 return *this;
242 }
243 exception_ptr temp(_NEFORCE move(other));
244 swap(temp);
245 return *this;
246 }
247
252 void swap(exception_ptr& other) noexcept { _NEFORCE swap(ecb_, other.ecb_); }
253
260 explicit operator bool() const noexcept { return ecb_ != nullptr; }
261
269 bool operator==(const exception_ptr& rhs) const noexcept { return ecb_ == rhs.ecb_; }
270
276 bool operator!=(const exception_ptr& rhs) const noexcept { return !(*this == rhs); }
277
282 bool operator==(nullptr_t) const noexcept { return !static_cast<bool>(*this); }
283
287 friend bool operator==(nullptr_t, const exception_ptr& ptr) noexcept { return !ptr; }
288
293 bool operator!=(nullptr_t) const noexcept { return static_cast<bool>(*this); }
294
298 friend bool operator!=(nullptr_t, const exception_ptr& ptr) noexcept { return static_cast<bool>(ptr); }
299
306 NEFORCE_NODISCARD const std::type_info& exception_type() const noexcept {
307 if (ecb_ == nullptr || !ecb_->wrapper) {
308 return typeid(void);
309 }
310 return ecb_->wrapper->type();
311 }
312};
313
314
324template <typename Ex>
325exception_ptr make_exception_ptr(Ex ex) noexcept {
326 try {
327 auto wrapper = _NEFORCE make_unique<typed_exception_wrapper<decay_t<Ex>>>(_NEFORCE forward<Ex>(ex));
328 unique_ptr<exception_ptr::ecb> control_block(new exception_ptr::ecb(_NEFORCE move(wrapper)));
329 exception_ptr result;
330 result.ecb_ = control_block.release();
331 return result;
332 } catch (...) {
333 return {};
334 }
335}
336
344exception_ptr NEFORCE_API current_exception() noexcept;
345 // ExceptionHandling
347
348NEFORCE_END_NAMESPACE__
349#endif // NEFORCE_CORE_EXCEPTION_EXCEPTION_PTR_HPP__
原子类型完整实现
exception_ptr(exception_ptr &&other) noexcept
移动构造函数
friend void rethrow_exception(const exception_ptr &)
重新抛出异常
exception_ptr(const exception_ptr &other) noexcept
拷贝构造函数
~exception_ptr() noexcept
析构函数
bool operator==(nullptr_t) const noexcept
与空指针比较相等
bool operator==(const exception_ptr &rhs) const noexcept
相等比较运算符
exception_ptr & operator=(const exception_ptr &other) noexcept
拷贝赋值运算符
bool operator!=(const exception_ptr &rhs) const noexcept
不等比较运算符
friend exception_ptr current_exception() noexcept
获取当前异常
const std::type_info & exception_type() const noexcept
获取异常类型信息
friend exception_ptr make_exception_ptr(Ex ex) noexcept
创建异常指针
exception_ptr & operator=(exception_ptr &&other) noexcept
移动赋值运算符
bool operator!=(nullptr_t) const noexcept
与空指针比较不等
friend bool operator==(nullptr_t, const exception_ptr &ptr) noexcept
空指针与异常指针比较相等
friend bool operator!=(nullptr_t, const exception_ptr &ptr) noexcept
空指针与异常指针比较不等
void swap(exception_ptr &other) noexcept
交换两个异常指针
异常包装器基类
virtual unique_ptr< exception_wrapper > clone() const =0
克隆异常包装器
virtual NEFORCE_NORETURN void rethrow() const =0
重新抛出异常
virtual const std::type_info & type() const noexcept=0
获取异常类型信息
typed_exception_wrapper(const Ex &ex)
拷贝构造函数
unique_ptr< exception_wrapper > clone() const override
克隆异常包装器
typed_exception_wrapper(Ex &&ex) noexcept
移动构造函数
const std::type_info & type() const noexcept override
获取异常类型信息
NEFORCE_NORETURN void rethrow() const override
重新抛出异常
独占智能指针
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr T * addressof(T &x) noexcept
获取对象的地址
decltype(nullptr) nullptr_t
空指针类型
NEFORCE_NORETURN void rethrow_exception(const exception_ptr &p)
重新抛出异常
exception_ptr current_exception() noexcept
获取当前异常
exception_ptr make_exception_ptr(Ex ex) noexcept
创建异常指针
constexpr auto memory_order_relaxed
宽松内存顺序常量
constexpr auto memory_order_acquire
获取内存顺序常量
constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
void swap()=delete
删除无参数的swap重载
constexpr unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
通用原子类型模板
atomic< int > ref_count
引用计数
void add_ref() noexcept
增加引用计数
unique_ptr< exception_wrapper > wrapper
异常包装器
void release() noexcept
减少引用计数
ecb(unique_ptr< exception_wrapper > wrapper)
构造函数
独占智能指针