// Copyright 2021 The Dawn Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef SRC_DAWN_NODE_UTILS_DEBUG_H_ #define SRC_DAWN_NODE_UTILS_DEBUG_H_ #include #include #include #include #include #include #include #include "dawn/webgpu_cpp_print.h" namespace wgpu::utils { // Write() is a helper for printing container types to the std::ostream. // Write() is used by the LOG() macro below. // Forward declarations inline std::ostream& Write(std::ostream& out) { return out; } template inline std::ostream& Write(std::ostream& out, const std::optional& value); template inline std::ostream& Write(std::ostream& out, const std::vector& value); template inline std::ostream& Write(std::ostream& out, const std::unordered_map& value); template inline std::ostream& Write(std::ostream& out, const std::variant& value); template std::ostream& Write(std::ostream& out, VALUE&& value); // Write() implementations template std::ostream& Write(std::ostream& out, const std::optional& value) { if (value.has_value()) { return Write(out, value.value()); } return out << ""; } template std::ostream& Write(std::ostream& out, const std::vector& value) { out << "["; bool first = true; for (const auto& el : value) { if (!first) { out << ", "; } first = false; Write(out, el); } return out << "]"; } template std::ostream& Write(std::ostream& out, const std::unordered_map& value) { out << "{"; bool first = true; for (auto& [key, value] : value) { if (!first) { out << ", "; } first = false; Write(out, key); out << ": "; Write(out, value); } return out << "}"; } template std::ostream& Write(std::ostream& out, const std::variant& value) { std::visit([&](auto&& v) { Write(out, v); }, value); return out; } template std::ostream& Write(std::ostream& out, VALUE&& value) { return out << std::forward(value); } template inline std::ostream& Write(std::ostream& out, FIRST&& first, REST&&... rest) { Write(out, std::forward(first)); Write(out, std::forward(rest)...); return out; } // Fatal() prints a message to stdout with the given file, line, function and optional message, // then calls abort(). Fatal() is usually not called directly, but by the UNREACHABLE() and // UNIMPLEMENTED() macro below. template [[noreturn]] inline void Fatal(const char* reason, const char* file, int line, const char* function, MSG_ARGS&&... msg_args) { std::stringstream msg; msg << file << ":" << line << ": " << reason << ": " << function << "()"; if constexpr (sizeof...(msg_args) > 0) { msg << " "; Write(msg, std::forward(msg_args)...); } std::cout << msg.str() << std::endl; abort(); } // LOG() prints the current file, line and function to stdout, followed by a // string representation of all the variadic arguments. #define LOG(...) \ ::wgpu::utils::Write(std::cout << __FILE__ << ":" << __LINE__ << " " << __FUNCTION__ << ": ", \ ##__VA_ARGS__) \ << std::endl // UNIMPLEMENTED() prints 'UNIMPLEMENTED' with the current file, line and // function to stdout, along with the optional message, then calls abort(). // The macro calls Fatal(), which is annotated with [[noreturn]]. // Used to stub code that has not yet been implemented. #define UNIMPLEMENTED(...) \ ::wgpu::utils::Fatal("UNIMPLEMENTED", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) // UNREACHABLE() prints 'UNREACHABLE' with the current file, line and // function to stdout, along with the optional message, then calls abort(). // The macro calls Fatal(), which is annotated with [[noreturn]]. // Used to stub code that has not yet been implemented. #define UNREACHABLE(...) \ ::wgpu::utils::Fatal("UNREACHABLE", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) } // namespace wgpu::utils #endif // SRC_DAWN_NODE_UTILS_DEBUG_H_