common.h raw
1 // Copyright (c) The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php.
4
5 #ifndef BITCOIN_TEST_UTIL_COMMON_H
6 #define BITCOIN_TEST_UTIL_COMMON_H
7
8 #include <chrono>
9 #include <optional>
10 #include <ostream>
11 #include <string>
12
13 /**
14 * BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
15 * Use as
16 * BOOST_CHECK_EXCEPTION(code that throws, exception type, HasReason("foo"));
17 */
18 class HasReason
19 {
20 public:
21 explicit HasReason(std::string_view reason) : m_reason(reason) {}
22 bool operator()(std::string_view s) const { return s.find(m_reason) != std::string_view::npos; }
23 bool operator()(const std::exception& e) const { return (*this)(e.what()); }
24
25 private:
26 const std::string m_reason;
27 };
28
29 // Make types usable in BOOST_CHECK_* @{
30 namespace std {
31 template <typename Clock, typename Duration>
32 inline std::ostream& operator<<(std::ostream& os, const std::chrono::time_point<Clock, Duration>& tp)
33 {
34 return os << tp.time_since_epoch().count();
35 }
36
37 template <typename T> requires std::is_enum_v<T>
38 inline std::ostream& operator<<(std::ostream& os, const T& e)
39 {
40 return os << static_cast<std::underlying_type_t<T>>(e);
41 }
42
43 template <typename T>
44 inline std::ostream& operator<<(std::ostream& os, const std::optional<T>& v)
45 {
46 return v ? os << *v
47 : os << "std::nullopt";
48 }
49 } // namespace std
50
51 template <typename T>
52 concept HasToString = requires(const T& t) { t.ToString(); };
53
54 template <HasToString T>
55 inline std::ostream& operator<<(std::ostream& os, const T& obj)
56 {
57 return os << obj.ToString();
58 }
59
60 // @}
61
62 #endif // BITCOIN_TEST_UTIL_COMMON_H
63