Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-13 09:13:00

0001 /**
0002  * Copyright (c) 2017-present, Facebook, Inc.
0003  * All rights reserved.
0004  *
0005  * This source code is licensed under the BSD-style license found in the
0006  * LICENSE file in the root directory of this source tree.
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  * Rich logging messages
0055  *
0056  * GLOO_ENFORCE_THAT can be used with one of the "checker functions" that
0057  * capture input argument values and add it to the exception message. E.g.
0058  * `GLOO_ENFORCE_THAT(Equals(foo(x), bar(y)), "Optional additional message")`
0059  * would evaluate both foo and bar only once and if the results are not equal -
0060  * include them in the exception message.
0061  *
0062  * Some of the basic checker functions like Equals or Greater are already
0063  * defined below. Other header might define customized checkers by adding
0064  * functions to gloo::enforce_detail namespace. For example:
0065  *
0066  *   namespace gloo { namespace enforce_detail {
0067  *   inline EnforceFailMessage IsVector(const vector<TIndex>& shape) {
0068  *     if (shape.size() == 1) { return EnforceOK(); }
0069  *     return MakeString("Shape ", shape, " is not a vector");
0070  *   }
0071  *   }}
0072  *
0073  * With further usages like `GLOO_ENFORCE_THAT(IsVector(Input(0).dims()))`
0074  *
0075  * Convenient wrappers for binary operations like GLOO_ENFORCE_EQ are provided
0076  * too. Please use them instead of CHECK_EQ and friends for failures in
0077  * user-provided input.
0078  */
0079 
0080 namespace enforce_detail {
0081 
0082 struct EnforceOK {};
0083 
0084 class EnforceFailMessage {
0085  public:
0086   constexpr /* implicit */ 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   /* implicit */ 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 } // namespace gloo