Advertisement
Guest User

Untitled

a guest
Nov 19th, 2018
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.12 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <exception>
  4. #include <stdexcept>
  5. #include <variant>
  6. #include <iostream>
  7. #include <cstring>
  8.  
  9. template <class T>
  10. class Try {
  11. public:
  12. Try() = default;
  13. explicit Try(const T& rhs) {
  14. value_ = rhs;
  15. }
  16. explicit Try(const std::exception& rhs) {
  17. what_ = rhs.what();
  18. value_ = std::make_exception_ptr(rhs);
  19. }
  20. const T& Value() const {
  21. if (std::holds_alternative<T>(value_)) {
  22. return std::get<T>(value_);
  23. } else if (std::holds_alternative<std::exception_ptr>(value_)) {
  24. std::rethrow_exception(std::get<std::exception_ptr>(value_));
  25.  
  26. } else {
  27. throw std::runtime_error("Object is empty");
  28. }
  29. }
  30. void Throw() const {
  31. if (std::holds_alternative<std::exception_ptr>(value_)) {
  32. std::rethrow_exception(std::get<std::exception_ptr>(value_));
  33. } else {
  34. throw std::runtime_error("No exception");
  35. }
  36. }
  37. bool IsFailed() const {
  38. return std::holds_alternative<std::exception_ptr>(value_);
  39. }
  40.  
  41. private:
  42. enum class Flag { NONE };
  43. std::variant<Flag, T, std::exception_ptr> value_;
  44. const char* what_;
  45. };
  46.  
  47. template <>
  48. class Try<void> {
  49. public:
  50. Try() = default;
  51. explicit Try(const std::exception& rhs) {
  52. value_ = std::make_exception_ptr(rhs);
  53. }
  54. void Throw() const {
  55. if (value_ != nullptr) {
  56. std::rethrow_exception(value_);
  57. } else {
  58. throw std::runtime_error("No exception");
  59. }
  60. }
  61. bool IsFailed() const {
  62. return (value_ != nullptr);
  63. }
  64.  
  65. private:
  66. std::exception_ptr value_ = nullptr;
  67. };
  68.  
  69. template <class T>
  70. struct CallFunction {
  71. template <class Function, class... Args>
  72. Try<T> Call(Function func, Args... args) {
  73. T result;
  74. try {
  75. result = func(args...);
  76. } catch (const std::exception& exc) {
  77. return Try<T>(exc);
  78. } catch (const char* exc) {
  79. return Try<T>(std::runtime_error(exc));
  80. } catch (int exc) {
  81. return Try<T>(std::runtime_error(std::strerror(exc)));
  82. } catch (...) {
  83. return Try<T>(std::runtime_error("Unknown exception"));
  84. }
  85. return Try<T>(result);
  86. }
  87. };
  88.  
  89. template <>
  90. struct CallFunction<void> {
  91. template <class Function, class... Args>
  92. Try<void> Call(Function func, Args... args) {
  93. try {
  94. func(args...);
  95. } catch (const std::exception& exc) {
  96. return Try<void>(exc);
  97. } catch (const char* exc) {
  98. return Try<void>(std::runtime_error(exc));
  99. } catch (int exc) {
  100. return Try<void>(std::runtime_error(std::strerror(exc)));
  101. } catch (...) {
  102. return Try<void>(std::runtime_error("Unknown exception"));
  103. }
  104. return Try<void>();
  105. }
  106. };
  107.  
  108. template <class Function, class... Args>
  109. auto TryRun(Function func, Args... args) {
  110. using ReturnType = decltype(func(args...));
  111. CallFunction<ReturnType> call_function;
  112. return call_function.Call(func, args...);
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement