summaryrefslogtreecommitdiff
path: root/abseil-cpp/absl/log/log_streamer.h
diff options
context:
space:
mode:
Diffstat (limited to 'abseil-cpp/absl/log/log_streamer.h')
-rw-r--r--abseil-cpp/absl/log/log_streamer.h171
1 files changed, 171 insertions, 0 deletions
diff --git a/abseil-cpp/absl/log/log_streamer.h b/abseil-cpp/absl/log/log_streamer.h
new file mode 100644
index 0000000..2d41a07
--- /dev/null
+++ b/abseil-cpp/absl/log/log_streamer.h
@@ -0,0 +1,171 @@
+// Copyright 2022 The Abseil 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
+//
+// https://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.
+//
+// -----------------------------------------------------------------------------
+// File: log/log_streamer.h
+// -----------------------------------------------------------------------------
+//
+// This header declares the class `LogStreamer` and convenience functions to
+// construct LogStreamer objects with different associated log severity levels.
+
+#ifndef ABSL_LOG_LOG_STREAMER_H_
+#define ABSL_LOG_LOG_STREAMER_H_
+
+#include <ios>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "absl/base/config.h"
+#include "absl/base/log_severity.h"
+#include "absl/log/absl_log.h"
+#include "absl/strings/internal/ostringstream.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "absl/utility/utility.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+// LogStreamer
+//
+// Although you can stream into `LOG(INFO)`, you can't pass it into a function
+// that takes a `std::ostream` parameter. `LogStreamer::stream()` provides a
+// `std::ostream` that buffers everything that's streamed in. The buffer's
+// contents are logged as if by `LOG` when the `LogStreamer` is destroyed.
+// If nothing is streamed in, an empty message is logged. If the specified
+// severity is `absl::LogSeverity::kFatal`, the program will be terminated when
+// the `LogStreamer` is destroyed regardless of whether any data were streamed
+// in.
+//
+// Factory functions corresponding to the `absl::LogSeverity` enumerators
+// are provided for convenience; if the desired severity is variable, invoke the
+// constructor directly.
+//
+// LogStreamer is movable, but not copyable.
+//
+// Examples:
+//
+// ShaveYakAndWriteToStream(
+// yak, absl::LogInfoStreamer(__FILE__, __LINE__).stream());
+//
+// {
+// // This logs a single line containing data streamed by all three function
+// // calls.
+// absl::LogStreamer streamer(absl::LogSeverity::kInfo, __FILE__, __LINE__);
+// ShaveYakAndWriteToStream(yak1, streamer.stream());
+// streamer.stream() << " ";
+// ShaveYakAndWriteToStream(yak2, streamer.stream());
+// streamer.stream() << " ";
+// ShaveYakAndWriteToStreamPointer(yak3, &streamer.stream());
+// }
+class LogStreamer final {
+ public:
+ // LogStreamer::LogStreamer()
+ //
+ // Creates a LogStreamer with a given `severity` that will log a message
+ // attributed to the given `file` and `line`.
+ explicit LogStreamer(absl::LogSeverity severity, absl::string_view file,
+ int line)
+ : severity_(severity),
+ line_(line),
+ file_(file),
+ stream_(absl::in_place, &buf_) {
+ // To match `LOG`'s defaults:
+ stream_->setf(std::ios_base::showbase | std::ios_base::boolalpha);
+ }
+
+ // A moved-from `absl::LogStreamer` does not `LOG` when destroyed,
+ // and a program that streams into one has undefined behavior.
+ LogStreamer(LogStreamer&& that) noexcept
+ : severity_(that.severity_),
+ line_(that.line_),
+ file_(std::move(that.file_)),
+ buf_(std::move(that.buf_)),
+ stream_(std::move(that.stream_)) {
+ if (stream_.has_value()) stream_->str(&buf_);
+ that.stream_.reset();
+ }
+ LogStreamer& operator=(LogStreamer&& that) {
+ ABSL_LOG_IF(LEVEL(severity_), stream_).AtLocation(file_, line_) << buf_;
+ severity_ = that.severity_;
+ file_ = std::move(that.file_);
+ line_ = that.line_;
+ buf_ = std::move(that.buf_);
+ stream_ = std::move(that.stream_);
+ if (stream_.has_value()) stream_->str(&buf_);
+ that.stream_.reset();
+ return *this;
+ }
+
+ // LogStreamer::~LogStreamer()
+ //
+ // Logs this LogStreamer's buffered content as if by LOG.
+ ~LogStreamer() {
+ ABSL_LOG_IF(LEVEL(severity_), stream_.has_value()).AtLocation(file_, line_)
+ << buf_;
+ }
+
+ // LogStreamer::stream()
+ //
+ // Returns the `std::ostream` to use to write into this LogStreamer' internal
+ // buffer.
+ std::ostream& stream() { return *stream_; }
+
+ private:
+ absl::LogSeverity severity_;
+ int line_;
+ std::string file_;
+ std::string buf_;
+ // A disengaged `stream_` indicates a moved-from `LogStreamer` that should not
+ // `LOG` upon destruction.
+ absl::optional<absl::strings_internal::OStringStream> stream_;
+};
+
+// LogInfoStreamer()
+//
+// Returns a LogStreamer that writes at level LogSeverity::kInfo.
+inline LogStreamer LogInfoStreamer(absl::string_view file, int line) {
+ return absl::LogStreamer(absl::LogSeverity::kInfo, file, line);
+}
+
+// LogWarningStreamer()
+//
+// Returns a LogStreamer that writes at level LogSeverity::kWarning.
+inline LogStreamer LogWarningStreamer(absl::string_view file, int line) {
+ return absl::LogStreamer(absl::LogSeverity::kWarning, file, line);
+}
+
+// LogErrorStreamer()
+//
+// Returns a LogStreamer that writes at level LogSeverity::kError.
+inline LogStreamer LogErrorStreamer(absl::string_view file, int line) {
+ return absl::LogStreamer(absl::LogSeverity::kError, file, line);
+}
+
+// LogFatalStreamer()
+//
+// Returns a LogStreamer that writes at level LogSeverity::kFatal.
+//
+// The program will be terminated when this `LogStreamer` is destroyed,
+// regardless of whether any data were streamed in.
+inline LogStreamer LogFatalStreamer(absl::string_view file, int line) {
+ return absl::LogStreamer(absl::LogSeverity::kFatal, file, line);
+}
+
+ABSL_NAMESPACE_END
+} // namespace absl
+
+#endif // ABSL_LOG_LOG_STREAMER_H_