Created
September 26, 2022 15:44
-
-
Save hoxnox/2a877a810aae21c7e0f523160678abf0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sstream> | |
#include <iostream> | |
#include <variant> | |
#pragma once | |
class Error | |
{ | |
public: | |
operator bool() const | |
{ | |
return msg_.str().empty(); | |
} | |
template <class T> | |
Error &operator<<(const T &t) | |
{ | |
msg_ << t; | |
return *this; | |
} | |
Error() {} | |
Error(Error &&err) | |
{ | |
msg_.swap(err.msg_); | |
} | |
Error(const Error &err) | |
{ | |
operator=(err); | |
} | |
Error &operator=(const Error &err) | |
{ | |
msg_.str(""); | |
msg_ << err.msg_.str(); | |
return *this; | |
} | |
std::string str() const | |
{ | |
return msg_.str(); | |
} | |
bool starts_with(const std::string_view &str) const | |
{ | |
auto msg = msg_.str(); | |
if (msg.size() < str.size()) | |
return false; | |
if (msg.substr(0, str.size()) == str) | |
return true; | |
return false; | |
} | |
private: | |
std::stringstream msg_; | |
friend std::ostream &operator<<(std::ostream &, const Error &); | |
}; | |
inline std::ostream & | |
operator<<(std::ostream &os, const Error &err) | |
{ | |
os << err.msg_.str(); | |
return os; | |
} | |
#ifndef ELOG | |
#define ELOG std::cerr | |
#endif | |
template <class T> | |
using E = std::variant<Error, T>; | |
template <class T> | |
inline T operator*(E<T> &v) | |
{ | |
if (std::holds_alternative<T>(v)) | |
return std::get<T>(v); | |
ELOG << std::get<Error>(v); | |
return {}; | |
} | |
template <class T> | |
inline T operator*(E<T> &&v) | |
{ | |
if (std::holds_alternative<T>(v)) | |
return std::move(std::get<T>(v)); | |
ELOG << std::get<Error>(v); | |
return {}; | |
} | |
template <class T> | |
bool operator!(const E<T> &e) | |
{ | |
if (std::holds_alternative<Error>(e)) | |
return true; | |
return false; | |
} | |
template <class T> | |
Error error(const E<T> &e) | |
{ | |
if (std::holds_alternative<Error>(e)) | |
return std::get<Error>(e); | |
return {}; | |
} | |
template <class T> | |
inline T | |
value(std::variant<Error, T> &v) | |
{ | |
if (std::holds_alternative<T>(v)) | |
return std::get<T>(v); | |
return {}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment