Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:40:53

0001 // Copyright 2022 The Abseil Authors.
0002 //
0003 // Licensed under the Apache License, Version 2.0 (the "License");
0004 // you may not use this file except in compliance with the License.
0005 // You may obtain a copy of the License at
0006 //
0007 //      https://www.apache.org/licenses/LICENSE-2.0
0008 //
0009 // Unless required by applicable law or agreed to in writing, software
0010 // distributed under the License is distributed on an "AS IS" BASIS,
0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012 // See the License for the specific language governing permissions and
0013 // limitations under the License.
0014 //
0015 // -----------------------------------------------------------------------------
0016 // File: log/log_streamer.h
0017 // -----------------------------------------------------------------------------
0018 //
0019 // This header declares the class `LogStreamer` and convenience functions to
0020 // construct LogStreamer objects with different associated log severity levels.
0021 
0022 #ifndef ABSL_LOG_LOG_STREAMER_H_
0023 #define ABSL_LOG_LOG_STREAMER_H_
0024 
0025 #include <ios>
0026 #include <memory>
0027 #include <ostream>
0028 #include <string>
0029 #include <utility>
0030 
0031 #include "absl/base/config.h"
0032 #include "absl/base/log_severity.h"
0033 #include "absl/log/absl_log.h"
0034 #include "absl/strings/internal/ostringstream.h"
0035 #include "absl/strings/string_view.h"
0036 #include "absl/types/optional.h"
0037 #include "absl/utility/utility.h"
0038 
0039 namespace absl {
0040 ABSL_NAMESPACE_BEGIN
0041 
0042 // LogStreamer
0043 //
0044 // Although you can stream into `LOG(INFO)`, you can't pass it into a function
0045 // that takes a `std::ostream` parameter. `LogStreamer::stream()` provides a
0046 // `std::ostream` that buffers everything that's streamed in.  The buffer's
0047 // contents are logged as if by `LOG` when the `LogStreamer` is destroyed.
0048 // If nothing is streamed in, an empty message is logged.  If the specified
0049 // severity is `absl::LogSeverity::kFatal`, the program will be terminated when
0050 // the `LogStreamer` is destroyed regardless of whether any data were streamed
0051 // in.
0052 //
0053 // Factory functions corresponding to the `absl::LogSeverity` enumerators
0054 // are provided for convenience; if the desired severity is variable, invoke the
0055 // constructor directly.
0056 //
0057 // LogStreamer is movable, but not copyable.
0058 //
0059 // Examples:
0060 //
0061 //   ShaveYakAndWriteToStream(
0062 //       yak, absl::LogInfoStreamer(__FILE__, __LINE__).stream());
0063 //
0064 //   {
0065 //     // This logs a single line containing data streamed by all three function
0066 //     // calls.
0067 //     absl::LogStreamer streamer(absl::LogSeverity::kInfo, __FILE__, __LINE__);
0068 //     ShaveYakAndWriteToStream(yak1, streamer.stream());
0069 //     streamer.stream() << " ";
0070 //     ShaveYakAndWriteToStream(yak2, streamer.stream());
0071 //     streamer.stream() << " ";
0072 //     ShaveYakAndWriteToStreamPointer(yak3, &streamer.stream());
0073 //   }
0074 class LogStreamer final {
0075  public:
0076   // LogStreamer::LogStreamer()
0077   //
0078   // Creates a LogStreamer with a given `severity` that will log a message
0079   // attributed to the given `file` and `line`.
0080   explicit LogStreamer(absl::LogSeverity severity, absl::string_view file,
0081                        int line)
0082       : severity_(severity),
0083         line_(line),
0084         file_(file),
0085         stream_(absl::in_place, &buf_) {
0086     // To match `LOG`'s defaults:
0087     stream_->setf(std::ios_base::showbase | std::ios_base::boolalpha);
0088   }
0089 
0090   // A moved-from `absl::LogStreamer` does not `LOG` when destroyed,
0091   // and a program that streams into one has undefined behavior.
0092   LogStreamer(LogStreamer&& that) noexcept
0093       : severity_(that.severity_),
0094         line_(that.line_),
0095         file_(std::move(that.file_)),
0096         buf_(std::move(that.buf_)),
0097         stream_(std::move(that.stream_)) {
0098     if (stream_.has_value()) stream_->str(&buf_);
0099     that.stream_.reset();
0100   }
0101   LogStreamer& operator=(LogStreamer&& that) {
0102     ABSL_LOG_IF(LEVEL(severity_), stream_).AtLocation(file_, line_) << buf_;
0103     severity_ = that.severity_;
0104     file_ = std::move(that.file_);
0105     line_ = that.line_;
0106     buf_ = std::move(that.buf_);
0107     stream_ = std::move(that.stream_);
0108     if (stream_.has_value()) stream_->str(&buf_);
0109     that.stream_.reset();
0110     return *this;
0111   }
0112 
0113   // LogStreamer::~LogStreamer()
0114   //
0115   // Logs this LogStreamer's buffered content as if by LOG.
0116   ~LogStreamer() {
0117     ABSL_LOG_IF(LEVEL(severity_), stream_.has_value()).AtLocation(file_, line_)
0118         << buf_;
0119   }
0120 
0121   // LogStreamer::stream()
0122   //
0123   // Returns the `std::ostream` to use to write into this LogStreamer' internal
0124   // buffer.
0125   std::ostream& stream() { return *stream_; }
0126 
0127  private:
0128   absl::LogSeverity severity_;
0129   int line_;
0130   std::string file_;
0131   std::string buf_;
0132   // A disengaged `stream_` indicates a moved-from `LogStreamer` that should not
0133   // `LOG` upon destruction.
0134   absl::optional<absl::strings_internal::OStringStream> stream_;
0135 };
0136 
0137 // LogInfoStreamer()
0138 //
0139 // Returns a LogStreamer that writes at level LogSeverity::kInfo.
0140 inline LogStreamer LogInfoStreamer(absl::string_view file, int line) {
0141   return absl::LogStreamer(absl::LogSeverity::kInfo, file, line);
0142 }
0143 
0144 // LogWarningStreamer()
0145 //
0146 // Returns a LogStreamer that writes at level LogSeverity::kWarning.
0147 inline LogStreamer LogWarningStreamer(absl::string_view file, int line) {
0148   return absl::LogStreamer(absl::LogSeverity::kWarning, file, line);
0149 }
0150 
0151 // LogErrorStreamer()
0152 //
0153 // Returns a LogStreamer that writes at level LogSeverity::kError.
0154 inline LogStreamer LogErrorStreamer(absl::string_view file, int line) {
0155   return absl::LogStreamer(absl::LogSeverity::kError, file, line);
0156 }
0157 
0158 // LogFatalStreamer()
0159 //
0160 // Returns a LogStreamer that writes at level LogSeverity::kFatal.
0161 //
0162 // The program will be terminated when this `LogStreamer` is destroyed,
0163 // regardless of whether any data were streamed in.
0164 inline LogStreamer LogFatalStreamer(absl::string_view file, int line) {
0165   return absl::LogStreamer(absl::LogSeverity::kFatal, file, line);
0166 }
0167 
0168 // LogDebugFatalStreamer()
0169 //
0170 // Returns a LogStreamer that writes at level LogSeverity::kLogDebugFatal.
0171 //
0172 // In debug mode, the program will be terminated when this `LogStreamer` is
0173 // destroyed, regardless of whether any data were streamed in.
0174 inline LogStreamer LogDebugFatalStreamer(absl::string_view file, int line) {
0175   return absl::LogStreamer(absl::kLogDebugFatal, file, line);
0176 }
0177 
0178 ABSL_NAMESPACE_END
0179 }  // namespace absl
0180 
0181 #endif  // ABSL_LOG_LOG_STREAMER_H_