bkietz commented on a change in pull request #8735: URL: https://github.com/apache/arrow/pull/8735#discussion_r530369496
########## File path: cpp/src/arrow/util/logging.h ########## @@ -202,48 +169,81 @@ class ARROW_EXPORT ArrowLog : public ArrowLogBase { private: ARROW_DISALLOW_COPY_AND_ASSIGN(ArrowLog); + std::ostream* Stream() override; + // Hide the implementation of log provider by void *. // Otherwise, lib user may define the same macro to use the correct header file. void* logging_provider_; /// True if log messages should be logged and false if they should be ignored. bool is_enabled_; static ArrowLogLevel severity_threshold_; - - protected: - std::ostream& Stream() override; }; -// This class make ARROW_CHECK compilation pass to change the << operator to void. -// This class is copied from glog. -class ARROW_EXPORT Voidify { - public: - Voidify() {} - // This has to be an operator with a precedence lower than << but - // higher than ?: - void operator&(ArrowLogBase&) {} -}; +struct ARROW_EXPORT InterceptComparison { + template <typename NotBinaryOrNotPrintable> + static ArrowLogBase&& PrintOperands(const NotBinaryOrNotPrintable&, + ArrowLogBase&& log) { + return std::move(log); + } -namespace detail { + template <typename Lhs, typename Rhs> + struct BoundLhsRhs { + explicit constexpr operator bool() const { return false; } + const Lhs& lhs; + const Rhs& rhs; + }; + + template <typename Lhs, typename Rhs> + static auto PrintOperands(const BoundLhsRhs<Lhs, Rhs>& bound, ArrowLogBase&& log) + -> decltype(std::move(log) << bound.lhs << bound.rhs) { + return std::move(log) << "\n left: " << bound.lhs << "\n right: " << bound.rhs + << "\n"; + } -/// @brief A helper for the nil log sink. -/// -/// Using this helper is analogous to sending log messages to /dev/null: -/// nothing gets logged. -class NullLog { - public: - /// The no-op output operator. - /// - /// @param [in] t - /// The object to send into the nil sink. - /// @return Reference to the updated object. - template <class T> - NullLog& operator<<(const T& t) { - return *this; + template <typename Lhs> + struct BoundLhs { + template <typename Rhs> + BoundLhsRhs<Lhs, Rhs> operator==(const Rhs& rhs) && { + return {lhs, rhs}; + } + + template <typename Rhs> + BoundLhsRhs<Lhs, Rhs> operator!=(const Rhs& rhs) && { + return {lhs, rhs}; + } + + template <typename Rhs> + BoundLhsRhs<Lhs, Rhs> operator>(const Rhs& rhs) && { + return {lhs, rhs}; + } + + template <typename Rhs> + BoundLhsRhs<Lhs, Rhs> operator>=(const Rhs& rhs) && { + return {lhs, rhs}; + } + + template <typename Rhs> + BoundLhsRhs<Lhs, Rhs> operator<(const Rhs& rhs) && { + return {lhs, rhs}; + } + + template <typename Rhs> + BoundLhsRhs<Lhs, Rhs> operator<=(const Rhs& rhs) && { + return {lhs, rhs}; + } Review comment: This is the approach used by the [Catch2](https://github.com/catchorg/Catch2) test framework's assertion macro. I'm not aware of another way to destructure a comparison's operands ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org