MtFmt 1.0.0
MtFmt is a format library on embed. system and wrote by pure C.
载入中...
搜索中...
未找到
mm_result.hpp
浏览该文件的文档.
1// SPDX-License-Identifier: LGPL-3.0
12#if !defined(_INCLUDE_MM_RESULT_HPP_)
13#define _INCLUDE_MM_RESULT_HPP_ 1
14#include "mm_result.h"
15#include "mm_type.hpp"
16namespace mtfmt
17{
18// class decl
19template <typename T, typename E> class result;
20
21namespace details
22{
27template <typename... Targ> struct result_storager_type
28{
33 static constexpr std::size_t size =
34 max_value<sizeof(Targ)...>::value;
35
40 static constexpr std::size_t align =
41 max_value<alignof(Targ)...>::value;
42
47 using storager_t = typename std::aligned_storage<size, align>::type;
48};
49
54template <typename T, typename E> class result_non_trivial_base
55{
56 using dtor_t = typename std::add_pointer<void(void*)>::type;
58
66
72
76 static void dtor_succ_type(void* ptr) noexcept
77 {
78 return (*reinterpret_cast<T*>(ptr)).~T();
79 }
80
84 static void dtor_err_type(void* ptr) noexcept
85 {
86 return (*reinterpret_cast<E*>(ptr)).~E();
87 }
88
89public:
90 using value_type = T;
91 using error_type = E;
96
106
116
118 : type_tag(rhs.type_tag)
119 {
120 if (type_tag == TypeTag::SuccTag) {
121 const T& value = *reinterpret_cast<const T*>(&storager);
123 // 更新析构
125 }
126 else {
128 const E& value = *reinterpret_cast<const E*>(&storager);
130 // 更新析构
132 }
133 }
134
136 const result_non_trivial_base& rhs
137 )
138 {
140 if (rhs.type_tag == TypeTag::SuccTag) {
141 const T& value = *reinterpret_cast<const T*>(&rhs.storager);
143 // 更新析构
145 }
146 else {
148 const E& value = *reinterpret_cast<const E*>(&rhs.storager);
150 // 更新析构
152 }
153 return *this;
154 }
155
157 {
158 mstr_assert(dtor != nullptr);
159 dtor(reinterpret_cast<void*>(&storager));
160 dtor = nullptr;
161 }
162
163protected:
168 enum class TypeTag
169 {
170 SuccTag = 0,
171 ErrorTag = 1
172 };
173
179
181 std::is_copy_constructible<T>::value,
183 unsafe_get_succ_value() const noexcept
184 {
186 return *reinterpret_cast<const T*>(&storager);
187 }
188
190 std::is_copy_constructible<E>::value,
192 unsafe_get_err_value() const noexcept
193 {
195 return *reinterpret_cast<const E*>(&storager);
196 }
197
199 std::is_copy_constructible<T>::value,
202 {
204 return *reinterpret_cast<T*>(&storager);
205 }
206
208 std::is_copy_constructible<E>::value,
211 {
213 return *reinterpret_cast<E*>(&storager);
214 }
215
216private:
218 unsafe_set_succ_value(const T& value) noexcept
219 {
221 void* ptr = reinterpret_cast<void*>(&storager);
222 // 用placement new把对象放到 storager 里面
223 new (ptr) T(value);
224 }
225
227 unsafe_set_err_value(const E& value) noexcept
228 {
230 void* ptr = reinterpret_cast<void*>(&storager);
231 new (ptr) E(value);
232 }
233};
234
241template <typename T, typename E> class result_trivial_base
242{
243 union {
246 };
247
248public:
249 using value_type = T;
250 using error_type = E;
255
260 constexpr result_trivial_base(T succ_val)
261 : t_val(succ_val), type_tag(TypeTag::SuccTag)
262 {
263 }
264
269 constexpr result_trivial_base(E err_val)
270 : e_val(err_val), type_tag(TypeTag::ErrorTag)
271 {
272 }
273
274 //
275 // ctor为default, assign为default
276 // trivial destructor不会执行任何东东
277 // 所以都可以default啦 !!!
278 //
279
282
285 default;
286
288
289protected:
294 enum class TypeTag
295 {
296 SuccTag = 0,
297 ErrorTag = 1
298 };
299
305
311
317
323
329};
330
335template <typename T> struct is_result
336{
337 static constexpr bool value =
339};
340
345template <typename T> struct is_trivial_or_trivial_result
346{
347 static constexpr bool value = std::is_trivial<T>::value;
348};
349
354template <typename... T>
360
365template <typename T, typename E> struct is_trivial_result
366{
367 static constexpr bool value =
370};
371
376template <typename T, typename E>
377using result_base_t = typename std::conditional<
381
382} // namespace details
383
389
395
399class mtfmt_error : std::exception
400{
401public:
402 explicit mtfmt_error(error_code_t) : std::exception()
403 {
404 }
405};
406
413template <typename T, typename E>
414class result final : public details::result_base_t<T, E>
415{
416public:
418 using value_type = typename base_t::value_type;
419 using error_type = typename base_t::error_type;
420 using reference_value_type = typename base_t::reference_value_type;
421 using reference_error_type = typename base_t::reference_error_type;
423 typename base_t::const_reference_value_type;
425 typename base_t::const_reference_error_type;
426 using base_t::base_t;
427
432 bool is_succ() const noexcept
433 {
434 return base_t::type_tag == base_t::TypeTag::SuccTag;
435 }
436
441 bool is_err() const noexcept
442 {
443 return !is_succ();
444 }
445
452 {
453 return base_t::unsafe_get_succ_value();
454 }
455
462 {
463 return base_t::unsafe_get_err_value();
464 }
465
472 {
473 return base_t::unsafe_get_succ_value_mut();
474 }
475
482 {
483 return base_t::unsafe_get_err_value_mut();
484 }
485
490 result<E, T> conjugate() const noexcept
491 {
492 if (is_succ()) {
493 return unsafe_get_succ_value();
494 }
495 else {
496 return unsafe_get_err_value();
497 }
498 }
499
506 template <typename T1 = T>
510 flatten() const noexcept
511 {
512 static_assert(std::is_same<typename T1::error_type, E>::value);
513 if (is_succ()) {
514 const auto& ref_succ = unsafe_get_succ_value();
515 if (ref_succ.is_succ()) {
516 return ref_succ.unsafe_get_succ_value();
517 }
518 else {
519 return ref_succ.unsafe_get_err_value();
520 }
521 }
522 else {
523 return unsafe_get_err_value();
524 }
525 }
526
531 template <typename T1 = T>
533 flatten() const noexcept
534 {
535 return *this;
536 }
537
544 template <
545 typename F,
550 map(F map_to) const
551 {
552 if (is_succ()) {
553 return map_to(base_t::unsafe_get_succ_value());
554 }
555 else {
556 return base_t::unsafe_get_err_value();
557 }
558 }
559
565 template <
566 typename F,
571 map_err(F map_to) const
572 {
573 if (is_succ()) {
574 return base_t::unsafe_get_succ_value();
575 }
576 else {
577 return map_to(base_t::unsafe_get_err_value());
578 }
579 }
580
586 template <
587 typename F,
589 typename R = details::enable_if_t<
591 typename R1::value_type>>
595 and_then(F then_do) const
596 {
597 if (is_succ()) {
598 return then_do(base_t::unsafe_get_succ_value());
599 }
600 else {
601 return base_t::unsafe_get_err_value();
602 }
603 }
604
610 template <
611 typename F,
613 typename R = details::enable_if_t<
615 typename R1::error_type>>
619 or_else(F else_do) const
620 {
621 if (is_succ()) {
622 return base_t::unsafe_get_succ_value();
623 }
624 else {
625 return else_do(base_t::unsafe_get_err_value());
626 }
627 }
628
635 ) const noexcept
636 {
637 if (is_succ()) {
638 return base_t::unsafe_get_succ_value();
639 }
640 else {
641 return or_val;
642 }
643 }
644
651 template <
652 typename F,
654 typename R = details::
655 enable_if_t<std::is_base_of<std::exception, R1>::value, R1>>
659 or_exception(F cont) const
660 {
661 if (is_succ()) {
662 return base_t::unsafe_get_succ_value();
663 }
664 else {
665#if _MSTR_USE_CPP_EXCEPTION
666 throw cont(base_t::unsafe_get_err_value());
667#else
668 (void)cont;
669 mstr_cause_exception(base_t::unsafe_get_err_value());
670#endif // _MSTR_USE_CPP_EXCEPTION
671 }
672 }
673};
674} // namespace mtfmt
675#endif // _INCLUDE_MM_RESULT_HPP_
结果类型的基类
Definition mm_result.hpp:55
result_non_trivial_base(const result_non_trivial_base &rhs)
Definition mm_result.hpp:117
typename std::add_pointer< void(void *)>::type dtor_t
Definition mm_result.hpp:56
enable_if_t< std::is_copy_constructible< T >::value, void > unsafe_set_succ_value(const T &value) noexcept
Definition mm_result.hpp:218
const T & const_reference_value_type
Definition mm_result.hpp:94
T value_type
Definition mm_result.hpp:90
E & reference_error_type
Definition mm_result.hpp:93
static void dtor_succ_type(void *ptr) noexcept
析构函数 (T type)
Definition mm_result.hpp:76
result_non_trivial_base(const_reference_value_type succ_val)
从succ value构造
Definition mm_result.hpp:101
~result_non_trivial_base()
Definition mm_result.hpp:156
typename result_storager_type< T, E >::storager_t storager_t
Definition mm_result.hpp:57
enable_if_t< std::is_copy_constructible< T >::value, reference_value_type > unsafe_get_succ_value_mut() noexcept
Definition mm_result.hpp:201
storager_t storager
数据存放在这里
Definition mm_result.hpp:65
result_non_trivial_base(const_reference_error_type err_val)
从err value构造
Definition mm_result.hpp:111
TypeTag
类型标签
Definition mm_result.hpp:169
dtor_t dtor
这里存着析构函数
Definition mm_result.hpp:71
E error_type
Definition mm_result.hpp:91
enable_if_t< std::is_copy_constructible< E >::value, void > unsafe_set_err_value(const E &value) noexcept
Definition mm_result.hpp:227
enable_if_t< std::is_copy_constructible< E >::value, reference_error_type > unsafe_get_err_value_mut() noexcept
Definition mm_result.hpp:210
const E & const_reference_error_type
Definition mm_result.hpp:95
TypeTag type_tag
类型标签
Definition mm_result.hpp:178
result_non_trivial_base & operator=(const result_non_trivial_base &rhs)
Definition mm_result.hpp:135
static void dtor_err_type(void *ptr) noexcept
析构函数 (E type)
Definition mm_result.hpp:84
enable_if_t< std::is_copy_constructible< T >::value, const_reference_value_type > unsafe_get_succ_value() const noexcept
Definition mm_result.hpp:183
T & reference_value_type
Definition mm_result.hpp:92
enable_if_t< std::is_copy_constructible< E >::value, const_reference_error_type > unsafe_get_err_value() const noexcept
Definition mm_result.hpp:192
结果类型的基类(trivial type)
Definition mm_result.hpp:242
reference_error_type unsafe_get_err_value_mut() noexcept
Definition mm_result.hpp:324
const_reference_value_type unsafe_get_succ_value() const noexcept
Definition mm_result.hpp:306
result_trivial_base & operator=(const result_trivial_base &)=default
E error_type
Definition mm_result.hpp:250
result_trivial_base(result_trivial_base &&)=default
T t_val
Definition mm_result.hpp:244
const E & const_reference_error_type
Definition mm_result.hpp:254
constexpr result_trivial_base(T succ_val)
从succ value构造
Definition mm_result.hpp:260
E e_val
Definition mm_result.hpp:245
T value_type
Definition mm_result.hpp:249
const_reference_error_type unsafe_get_err_value() const noexcept
Definition mm_result.hpp:312
T & reference_value_type
Definition mm_result.hpp:251
reference_value_type unsafe_get_succ_value_mut() noexcept
Definition mm_result.hpp:318
TypeTag
类型标签
Definition mm_result.hpp:295
const T & const_reference_value_type
Definition mm_result.hpp:253
result_trivial_base(const result_trivial_base &)=default
constexpr result_trivial_base(E err_val)
从err value构造
Definition mm_result.hpp:269
E & reference_error_type
Definition mm_result.hpp:252
result_trivial_base & operator=(result_trivial_base &&)=default
TypeTag type_tag
类型标签
Definition mm_result.hpp:304
表示存在错误
Definition mm_result.hpp:400
mtfmt_error(error_code_t)
Definition mm_result.hpp:402
结果类
Definition mm_result.hpp:415
bool is_err() const noexcept
是否为err?
Definition mm_result.hpp:441
details::enable_if_t< details::holds_prototype< F, R, E >::value, result< T, R > > map_err(F map_to) const
在result是err的时候执行map, 转换result
Definition mm_result.hpp:571
const_reference_value_type or_value(const_reference_value_type or_val) const noexcept
如果为T则返回T, 不然返回or_val
Definition mm_result.hpp:633
typename base_t::value_type value_type
Definition mm_result.hpp:418
details::enable_if_t< details::is_result< T1 >::value, result< typename T1::value_type, E > > flatten() const noexcept
扁平化
Definition mm_result.hpp:510
bool is_succ() const noexcept
是否为succ?
Definition mm_result.hpp:432
details::enable_if_t< details::holds_prototype< F, R, T >::value, result< R, E > > map(F map_to) const
在result是succ的时候执行map, 转换result
Definition mm_result.hpp:550
details::enable_if_t< details::holds_prototype< F, result< T, R >, E >::value, result< T, R > > or_else(F else_do) const
在self是err的时候执行else_do, 否则返回succ
Definition mm_result.hpp:619
const_reference_error_type unsafe_get_err_value() const noexcept
取得err的值
Definition mm_result.hpp:461
const_reference_value_type unsafe_get_succ_value() const noexcept
取得succ的值
Definition mm_result.hpp:451
details::enable_if_t< details::holds_prototype< F, result< R, E >, T >::value, result< R, E > > and_then(F then_do) const
在self是succ的时候执行then do, 否则返回err
Definition mm_result.hpp:595
typename base_t::reference_value_type reference_value_type
Definition mm_result.hpp:420
typename base_t::error_type error_type
Definition mm_result.hpp:419
typename base_t::const_reference_value_type const_reference_value_type
Definition mm_result.hpp:423
details::enable_if_t<!details::is_result< T1 >::value, result< T1, E > > flatten() const noexcept
扁平化 (T不是result<T, E>的情况)
Definition mm_result.hpp:533
details::enable_if_t< details::holds_prototype< F, R, E >::value, const_reference_value_type > or_exception(F cont) const
如果为T则返回T, 不然抛出异常
Definition mm_result.hpp:659
reference_error_type unsafe_get_err_value_mut() noexcept
取得err的值(可变引用)
Definition mm_result.hpp:481
typename base_t::reference_error_type reference_error_type
Definition mm_result.hpp:421
reference_value_type unsafe_get_succ_value_mut() noexcept
取得succ的值(可变引用)
Definition mm_result.hpp:471
details::result_base_t< T, E > base_t
Definition mm_result.hpp:417
typename base_t::const_reference_error_type const_reference_error_type
Definition mm_result.hpp:425
result< E, T > conjugate() const noexcept
交换succ和err的情况以及值
Definition mm_result.hpp:490
#define mstr_assert(e)
Definition mm_cfg.h:396
#define mstr_cause_exception(code)
Definition mm_cfg.h:395
结果类型
enum tagMStrResult mstr_result_t
结果类型
type trait, type alias和type def
typename std::conditional< is_trivial_result< T, E >::value, result_trivial_base< T, E >, result_non_trivial_base< T, E > >::type result_base_t
result的基类
Definition mm_result.hpp:380
typename function_trait< F >::return_type_t function_return_type_t
取得函数的返回值类型
Definition mm_type.hpp:126
typename std::enable_if< cond, T >::type enable_if_t
enable_if_t, 和cpp14一样(但是这里是cpp11呜呜呜)
Definition mm_type.hpp:205
Definition mm_parser.hpp:17
mstr_result_t error_code_t
返回值的错误结果
Definition mm_result.hpp:394
取得and
Definition mm_type.hpp:232
检查函数F的类型为 ( T1, T2 ...) -> R
Definition mm_type.hpp:189
判断Ti是否为模板Tt的实例化
Definition mm_type.hpp:150
判断T是不是一个result类型
Definition mm_result.hpp:336
static constexpr bool value
Definition mm_result.hpp:337
帮助判断T是trivial或者trivial result (case1)
Definition mm_result.hpp:346
static constexpr bool value
Definition mm_result.hpp:347
帮助判断result<T, E>是不是trivial
Definition mm_result.hpp:366
static constexpr bool value
Definition mm_result.hpp:367
取得最大值
Definition mm_type.hpp:211
结果类型的stroager的types
Definition mm_result.hpp:28
static constexpr std::size_t size
存储的数据大小
Definition mm_result.hpp:33
typename std::aligned_storage< size, align >::type storager_t
借助std storager实现数据存放
Definition mm_result.hpp:47
static constexpr std::size_t align
存储的数据的内存对齐
Definition mm_result.hpp:40
单位类型
Definition mm_type.hpp:29