Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <exception>
- #include <stdexcept>
- #include <variant>
- #include <iostream>
- #include <cstring>
- template <class T>
- class Try {
- public:
- Try() = default;
- explicit Try(const T& rhs) {
- value_ = rhs;
- }
- explicit Try(const std::exception& rhs) {
- what_ = rhs.what();
- value_ = std::make_exception_ptr(rhs);
- }
- const T& Value() const {
- if (std::holds_alternative<T>(value_)) {
- return std::get<T>(value_);
- } else if (std::holds_alternative<std::exception_ptr>(value_)) {
- std::rethrow_exception(std::get<std::exception_ptr>(value_));
- } else {
- throw std::runtime_error("Object is empty");
- }
- }
- void Throw() const {
- if (std::holds_alternative<std::exception_ptr>(value_)) {
- std::rethrow_exception(std::get<std::exception_ptr>(value_));
- } else {
- throw std::runtime_error("No exception");
- }
- }
- bool IsFailed() const {
- return std::holds_alternative<std::exception_ptr>(value_);
- }
- private:
- enum class Flag { NONE };
- std::variant<Flag, T, std::exception_ptr> value_;
- const char* what_;
- };
- template <>
- class Try<void> {
- public:
- Try() = default;
- explicit Try(const std::exception& rhs) {
- value_ = std::make_exception_ptr(rhs);
- }
- void Throw() const {
- if (value_ != nullptr) {
- std::rethrow_exception(value_);
- } else {
- throw std::runtime_error("No exception");
- }
- }
- bool IsFailed() const {
- return (value_ != nullptr);
- }
- private:
- std::exception_ptr value_ = nullptr;
- };
- template <class T>
- struct CallFunction {
- template <class Function, class... Args>
- Try<T> Call(Function func, Args... args) {
- T result;
- try {
- result = func(args...);
- } catch (const std::exception& exc) {
- return Try<T>(exc);
- } catch (const char* exc) {
- return Try<T>(std::runtime_error(exc));
- } catch (int exc) {
- return Try<T>(std::runtime_error(std::strerror(exc)));
- } catch (...) {
- return Try<T>(std::runtime_error("Unknown exception"));
- }
- return Try<T>(result);
- }
- };
- template <>
- struct CallFunction<void> {
- template <class Function, class... Args>
- Try<void> Call(Function func, Args... args) {
- try {
- func(args...);
- } catch (const std::exception& exc) {
- return Try<void>(exc);
- } catch (const char* exc) {
- return Try<void>(std::runtime_error(exc));
- } catch (int exc) {
- return Try<void>(std::runtime_error(std::strerror(exc)));
- } catch (...) {
- return Try<void>(std::runtime_error("Unknown exception"));
- }
- return Try<void>();
- }
- };
- template <class Function, class... Args>
- auto TryRun(Function func, Args... args) {
- using ReturnType = decltype(func(args...));
- CallFunction<ReturnType> call_function;
- return call_function.Call(func, args...);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement