Utility.Expected.tlh 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #pragma once
  2. #include <system_error>
  3. #include <memory>
  4. #include "Utility.Either.tlh"
  5. #include "Utility.Error.hpp"
  6. //-----------------------------------------------------------------------------
  7. // Expected
  8. // 与 C++ 23 的 std::expected 很像, 但是这里把错误类型固定成 Error::ErrorCode
  9. //-----------------------------------------------------------------------------
  10. namespace ECOM::Utility
  11. {
  12. template <typename TV>
  13. struct Expected : public Either <TV, ECOM::Utility::Error::ErrorCode>
  14. {
  15. using base = Either <TV, ECOM::Utility::Error::ErrorCode>;
  16. using value_type = TV;
  17. using error_type = ECOM::Utility::Error::ErrorCode;
  18. template<class U>
  19. using rebind = Expected <U>;
  20. constexpr Expected () = delete; // ! 不支持默认构造函数, 否则没法知道是左还是右 !
  21. //< 拷贝构造函数及移动构造函数
  22. constexpr Expected (Expected <TV> const & e) : base (e) {}
  23. constexpr Expected (Expected <TV> && e) : base (std::move (e)) {}
  24. //>
  25. //< 从 left 或 right 构造
  26. constexpr Expected (__tLeft <value_type> const & _left ) : base (_left) {}
  27. constexpr Expected (__tRight <error_type> const & _right) : base (_right) {}
  28. constexpr Expected (__tLeft <value_type> && _left ) : base (std::move (_left)) {}
  29. constexpr Expected (__tRight <error_type> && _right) : base (std::move (_right)) {}
  30. //>
  31. // 直接从 value 构造
  32. constexpr Expected (value_type const & _left) : base { _left } {}
  33. constexpr Expected (value_type && _left) : base { std::move (_left) } {}
  34. // 直接从 Error 构造
  35. constexpr Expected (error_type const & _right) : base { _right } {}
  36. constexpr Expected (error_type && _right) : base { std::move (_right) } {}
  37. constexpr bool isLeft () const = delete;
  38. constexpr bool isRight () const = delete;
  39. constexpr bool isValue () const noexcept { return base::isLeft (); }
  40. constexpr bool isError () const noexcept { return base::isRight (); }
  41. constexpr const value_type & getLeft () const = delete;
  42. constexpr const error_type & getRight () const = delete;
  43. constexpr value_type & getLeft () = delete;
  44. constexpr error_type & getRight () = delete;
  45. constexpr const value_type & value () const { return base::getLeft (); }
  46. constexpr const error_type & error () const { return base::getRight (); }
  47. constexpr value_type & value () { return base::getLeft (); }
  48. constexpr error_type & error () { return base::getRight (); }
  49. public:
  50. constexpr Expected & operator = (Expected <value_type> const & from)
  51. {
  52. base::operator = (from);
  53. return (*this);
  54. }
  55. constexpr Expected & operator = (Expected <value_type> && from)
  56. {
  57. base::operator = (std::move (from));
  58. return (*this);
  59. }
  60. public:
  61. constexpr static Expected make (value_type const & _left) { return Expected { _left }; }
  62. constexpr static Expected make (value_type && _left) { return Expected { std::move (_left) }; }
  63. constexpr static Expected make (error_type const & _right)
  64. {
  65. return Expected { _right };
  66. }
  67. constexpr static Expected make (error_type && _right)
  68. {
  69. return Expected { std::move (_right) };
  70. }
  71. };
  72. }
  73. //-----------------------------------------------------------------------------
  74. //-----------------------------------------------------------------------------
  75. //using eiResult = ECOM::Utility::Either <int, ECOM::Utility::Error::ErrorCode>;
  76. //using eiAck = ECOM::Utility::Either <ECOM::Utility::iAck , ECOM::Utility::Error::ErrorCode>;
  77. //using eiBLOBAck = ECOM::Utility::Either <ECOM::Utility::iBLOBAck, ECOM::Utility::Error::ErrorCode>;
  78. using eiResult = ECOM::Utility::Expected <int>;
  79. //< 最常用的返回值
  80. constexpr auto eiSuccess = ECOM::Utility::left <int> (1);