blob: 84470eef7e49d0f59728a25d8c1e024ba99555b7 [file] [log] [blame]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_DRIVER_LOGGING_CPP_INTERNAL_PANIC_H_
#define LIB_DRIVER_LOGGING_CPP_INTERNAL_PANIC_H_
#include <format>
namespace fdf_internal {
class output_iterator {
public:
using iterator_category = std::output_iterator_tag;
using value_type = char;
using difference_type = std::ptrdiff_t;
using pointer = char*;
using reference = char&;
explicit output_iterator(std::span<char> buffer) : buffer_(buffer) {}
output_iterator(output_iterator&& other) noexcept
: buffer_(other.buffer_), index_(other.index_) {}
output_iterator& operator=(output_iterator&& other) noexcept {
buffer_ = other.buffer_;
index_ = other.index_;
return *this;
}
output_iterator(const output_iterator& other) noexcept = default;
output_iterator& operator=(const output_iterator& other) noexcept = delete;
output_iterator& operator=(const char& ch) {
buffer_[index_] = ch;
return *this;
}
reference operator*() { return buffer_[index_]; }
output_iterator& operator++() {
index_++;
if (index_ == buffer_.size()) {
fwrite(buffer_.data(), 1, buffer_.size(), stderr);
index_ = 0;
}
return *this;
}
output_iterator operator++(int) {
auto tmp = *this;
++*this;
return tmp;
}
size_t index() const { return index_; }
private:
std::span<char> buffer_;
size_t index_ = 0;
};
inline void vpanic(std::string_view fmt, std::format_args args) {
constexpr size_t kBufferSize = 256;
std::array<char, kBufferSize> buffer = {};
size_t index = std::vformat_to(output_iterator(buffer), fmt, args).index();
if (index > 0) {
fwrite(buffer.data(), 1, index, stderr);
}
__builtin_trap();
}
} // namespace fdf_internal
#endif // LIB_DRIVER_LOGGING_CPP_INTERNAL_PANIC_H_