#ifndef BITCOIN_TEST_UTIL_COMMON_H
#define BITCOIN_TEST_UTIL_COMMON_H
#include <chrono>
#include <optional>
#include <ostream>
#include <string>
class HasReason
{
public:
explicit HasReason(std::string_view reason) : m_reason(reason) {}
bool operator()(std::string_view s) const { return s.find(m_reason) != std::string_view::npos; }
bool operator()(const std::exception& e) const { return (*this)(e.what()); }
private:
const std::string m_reason;
};
namespace std {
template <typename Clock, typename Duration>
inline std::ostream& operator<<(std::ostream& os, const std::chrono::time_point<Clock, Duration>& tp)
{
return os << tp.time_since_epoch().count();
}
template <typename T> requires std::is_enum_v<T>
inline std::ostream& operator<<(std::ostream& os, const T& e)
{
return os << static_cast<std::underlying_type_t<T>>(e);
}
template <typename T>
inline std::ostream& operator<<(std::ostream& os, const std::optional<T>& v)
{
return v ? os << *v
: os << "std::nullopt";
}
}
template <typename T>
concept HasToString = requires(const T& t) { t.ToString(); };
template <HasToString T>
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
return os << obj.ToString();
}
#endif