diff --git a/src/dawn_node/utils/Debug.h b/src/dawn_node/utils/Debug.h new file mode 100644 index 0000000000..8a2f27f6f7 --- /dev/null +++ b/src/dawn_node/utils/Debug.h @@ -0,0 +1,128 @@ +// 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 DAWNNODE_UTILS_DEBUG_H_ +#define DAWNNODE_UTILS_DEBUG_H_ + +#include +#include +#include +#include +#include + +#include "dawn/webgpu_cpp_print.h" + +namespace wgpu { namespace 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 + inline std::ostream& Write(std::ostream& out, const 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 it : value) { + if (!first) { + out << ", "; + } + first = false; + Write(out, it.first); + out << ": "; + Write(out, it.second); + } + 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, const VALUE& value) { + return out << 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; + } + + // Unimplemented() prints an 'UNIMPLEMENTED' message to stdout with the given + // file, line and function, then calls abort(). + // Unimplemented() is usually not called directly, but by the UNIMPLEMENTED() + // macro below. + [[noreturn]] inline void Unimplemented(const char* file, int line, const char* function) { + std::cout << file << ":" << line << ": " + << "UNIMPLEMENTED : " << function << 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, then calls abort(). +// The macro calls Unimplemented(), which is annotated with [[noreturn]]. +// Used to stub code that has not yet been implemented. +#define UNIMPLEMENTED() ::wgpu::utils::Unimplemented(__FILE__, __LINE__, __FUNCTION__) + +}} // namespace wgpu::utils + +#endif // DAWNNODE_UTILS_DEBUG_H_