File indexing completed on 2025-03-13 09:13:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <climits>
0012 #include <exception>
0013 #include <functional>
0014 #include <limits>
0015 #include <vector>
0016
0017 #include "gloo/common/string.h"
0018
0019 namespace gloo {
0020
0021 class EnforceNotMet : public std::exception {
0022 public:
0023 EnforceNotMet(
0024 const char* file,
0025 const int line,
0026 const char* condition,
0027 const std::string& msg);
0028
0029 std::string msg() const;
0030
0031 inline const std::vector<std::string>& msg_stack() const {
0032 return msg_stack_;
0033 }
0034
0035 virtual const char* what() const noexcept override;
0036
0037 private:
0038 std::vector<std::string> msg_stack_;
0039 std::string full_msg_;
0040 };
0041
0042 #define GLOO_ENFORCE(condition, ...) \
0043 do { \
0044 if (!(condition)) { \
0045 throw ::gloo::EnforceNotMet( \
0046 __FILE__, \
0047 __LINE__, \
0048 #condition, \
0049 ::gloo::MakeString(__VA_ARGS__)); \
0050 } \
0051 } while (false)
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 namespace enforce_detail {
0081
0082 struct EnforceOK {};
0083
0084 class EnforceFailMessage {
0085 public:
0086 constexpr EnforceFailMessage(EnforceOK) : msg_(nullptr) {}
0087
0088 EnforceFailMessage(EnforceFailMessage&&) = default;
0089 EnforceFailMessage(const EnforceFailMessage&) = delete;
0090 EnforceFailMessage& operator=(EnforceFailMessage&&) = delete;
0091 EnforceFailMessage& operator=(const EnforceFailMessage&) = delete;
0092
0093 EnforceFailMessage(std::string&& msg) {
0094 msg_ = new std::string(std::move(msg));
0095 }
0096
0097 inline bool bad() const {
0098 return msg_;
0099 }
0100
0101 std::string get_message_and_free(std::string&& extra) const {
0102 std::string r;
0103 if (extra.empty()) {
0104 r = std::move(*msg_);
0105 } else {
0106 r = ::gloo::MakeString(std::move(*msg_), ". ", std::move(extra));
0107 }
0108 delete msg_;
0109 return r;
0110 }
0111
0112 private:
0113 std::string* msg_;
0114 };
0115
0116 #define BINARY_COMP_HELPER(name, op) \
0117 template <typename T1, typename T2> \
0118 inline EnforceFailMessage name(const T1& x, const T2& y) { \
0119 if (x op y) { \
0120 return EnforceOK(); \
0121 } \
0122 return MakeString(x, " vs ", y); \
0123 }
0124 BINARY_COMP_HELPER(Equals, ==)
0125 BINARY_COMP_HELPER(NotEquals, !=)
0126 BINARY_COMP_HELPER(Greater, >)
0127 BINARY_COMP_HELPER(GreaterEquals, >=)
0128 BINARY_COMP_HELPER(Less, <)
0129 BINARY_COMP_HELPER(LessEquals, <=)
0130 #undef BINARY_COMP_HELPER
0131
0132 #define GLOO_ENFORCE_THAT_IMPL(condition, expr, ...) \
0133 do { \
0134 using namespace ::gloo::enforce_detail; \
0135 const EnforceFailMessage& r = (condition); \
0136 if (r.bad()) { \
0137 throw EnforceNotMet( \
0138 __FILE__, \
0139 __LINE__, \
0140 expr, \
0141 r.get_message_and_free(MakeString(__VA_ARGS__))); \
0142 } \
0143 } while (false)
0144 }
0145
0146 #define GLOO_ENFORCE_THAT(condition, ...) \
0147 GLOO_ENFORCE_THAT_IMPL((condition), #condition, __VA_ARGS__)
0148
0149 #define GLOO_ENFORCE_EQ(x, y, ...) \
0150 GLOO_ENFORCE_THAT_IMPL(Equals((x), (y)), #x " == " #y, __VA_ARGS__)
0151 #define GLOO_ENFORCE_NE(x, y, ...) \
0152 GLOO_ENFORCE_THAT_IMPL(NotEquals((x), (y)), #x " != " #y, __VA_ARGS__)
0153 #define GLOO_ENFORCE_LE(x, y, ...) \
0154 GLOO_ENFORCE_THAT_IMPL(LessEquals((x), (y)), #x " <= " #y, __VA_ARGS__)
0155 #define GLOO_ENFORCE_LT(x, y, ...) \
0156 GLOO_ENFORCE_THAT_IMPL(Less((x), (y)), #x " < " #y, __VA_ARGS__)
0157 #define GLOO_ENFORCE_GE(x, y, ...) \
0158 GLOO_ENFORCE_THAT_IMPL(GreaterEquals((x), (y)), #x " >= " #y, __VA_ARGS__)
0159 #define GLOO_ENFORCE_GT(x, y, ...) \
0160 GLOO_ENFORCE_THAT_IMPL(Greater((x), (y)), #x " > " #y, __VA_ARGS__)
0161
0162 }